xref: /haiku/src/add-ons/kernel/file_systems/ntfs/libntfs/dir.c (revision 71452e98334eaac603bf542d159e24788a46bebb)
1 /**
2  * dir.c - Directory handling code. Originated from the Linux-NTFS project.
3  *
4  * Copyright (c) 2002-2005 Anton Altaparmakov
5  * Copyright (c) 2004-2005 Richard Russon
6  * Copyright (c) 2004-2008 Szabolcs Szakacsits
7  * Copyright (c) 2005-2007 Yura Pakhuchiy
8  * Copyright (c) 2008-2010 Jean-Pierre Andre
9  *
10  * This program/include file is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License as published
12  * by the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program/include file is distributed in the hope that it will be
16  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
17  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program (in the main directory of the NTFS-3G
22  * distribution in the file COPYING); if not, write to the Free Software
23  * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24  */
25 
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29 
30 #ifdef HAVE_STDLIB_H
31 #include <stdlib.h>
32 #endif
33 #ifdef HAVE_ERRNO_H
34 #include <errno.h>
35 #endif
36 #ifdef HAVE_STRING_H
37 #include <string.h>
38 #endif
39 #ifdef HAVE_SYS_STAT_H
40 #include <sys/stat.h>
41 #endif
42 
43 #ifdef HAVE_SYS_SYSMACROS_H
44 #include <sys/sysmacros.h>
45 #endif
46 
47 #include "param.h"
48 #include "types.h"
49 #include "debug.h"
50 #include "attrib.h"
51 #include "inode.h"
52 #include "dir.h"
53 #include "volume.h"
54 #include "mft.h"
55 #include "index.h"
56 #include "ntfstime.h"
57 #include "lcnalloc.h"
58 #include "logging.h"
59 #include "cache.h"
60 #include "misc.h"
61 #include "security.h"
62 #include "reparse.h"
63 #include "object_id.h"
64 
65 #ifdef HAVE_SETXATTR
66 #include <sys/xattr.h>
67 #endif
68 
69 /*
70  * The little endian Unicode strings "$I30", "$SII", "$SDH", "$O"
71  *  and "$Q" as global constants.
72  */
73 ntfschar NTFS_INDEX_I30[5] = { const_cpu_to_le16('$'), const_cpu_to_le16('I'),
74 		const_cpu_to_le16('3'), const_cpu_to_le16('0'),
75 		const_cpu_to_le16('\0') };
76 ntfschar NTFS_INDEX_SII[5] = { const_cpu_to_le16('$'), const_cpu_to_le16('S'),
77 		const_cpu_to_le16('I'), const_cpu_to_le16('I'),
78 		const_cpu_to_le16('\0') };
79 ntfschar NTFS_INDEX_SDH[5] = { const_cpu_to_le16('$'), const_cpu_to_le16('S'),
80 		const_cpu_to_le16('D'), const_cpu_to_le16('H'),
81 		const_cpu_to_le16('\0') };
82 ntfschar NTFS_INDEX_O[3] = { const_cpu_to_le16('$'), const_cpu_to_le16('O'),
83 		const_cpu_to_le16('\0') };
84 ntfschar NTFS_INDEX_Q[3] = { const_cpu_to_le16('$'), const_cpu_to_le16('Q'),
85 		const_cpu_to_le16('\0') };
86 ntfschar NTFS_INDEX_R[3] = { const_cpu_to_le16('$'), const_cpu_to_le16('R'),
87 		const_cpu_to_le16('\0') };
88 
89 #if CACHE_INODE_SIZE
90 
91 /*
92  *		Pathname hashing
93  *
94  *	Based on first char and second char (which may be '\0')
95  */
96 
97 int ntfs_dir_inode_hash(const struct CACHED_GENERIC *cached)
98 {
99 	const char *path;
100 	const unsigned char *name;
101 
102 	path = (const char*)cached->variable;
103 	if (!path) {
104 		ntfs_log_error("Bad inode cache entry\n");
105 		return (-1);
106 	}
107 	name = (const unsigned char*)strrchr(path,'/');
108 	if (!name)
109 		name = (const unsigned char*)path;
110 	return (((name[0] << 1) + name[1] + strlen((const char*)name))
111 				% (2*CACHE_INODE_SIZE));
112 }
113 
114 /*
115  *		Pathname comparing for entering/fetching from cache
116  */
117 
118 static int inode_cache_compare(const struct CACHED_GENERIC *cached,
119 			const struct CACHED_GENERIC *wanted)
120 {
121 	return (!cached->variable
122 		    || strcmp(cached->variable, wanted->variable));
123 }
124 
125 /*
126  *		Pathname comparing for invalidating entries in cache
127  *
128  *	A partial path is compared in order to invalidate all paths
129  *	related to a renamed directory
130  *	inode numbers are also checked, as deleting a long name may
131  *	imply deleting a short name and conversely
132  *
133  *	Only use associated with a CACHE_NOHASH flag
134  */
135 
136 static int inode_cache_inv_compare(const struct CACHED_GENERIC *cached,
137 			const struct CACHED_GENERIC *wanted)
138 {
139 	int len;
140 	BOOL different;
141 	const struct CACHED_INODE *w;
142 	const struct CACHED_INODE *c;
143 
144 	w = (const struct CACHED_INODE*)wanted;
145 	c = (const struct CACHED_INODE*)cached;
146 	if (w->pathname) {
147 		len = strlen(w->pathname);
148 		different = !cached->variable
149 			|| ((w->inum != MREF(c->inum))
150 			   && (strncmp(c->pathname, w->pathname, len)
151 				|| ((c->pathname[len] != '\0')
152 				   && (c->pathname[len] != '/'))));
153 	} else
154 		different = !c->pathname
155 			|| (w->inum != MREF(c->inum));
156 	return (different);
157 }
158 
159 #endif
160 
161 #if CACHE_LOOKUP_SIZE
162 
163 /*
164  *		File name comparing for entering/fetching from lookup cache
165  */
166 
167 static int lookup_cache_compare(const struct CACHED_GENERIC *cached,
168 			const struct CACHED_GENERIC *wanted)
169 {
170 	const struct CACHED_LOOKUP *c = (const struct CACHED_LOOKUP*) cached;
171 	const struct CACHED_LOOKUP *w = (const struct CACHED_LOOKUP*) wanted;
172 	return (!c->name
173 		    || (c->parent != w->parent)
174 		    || (c->namesize != w->namesize)
175 		    || memcmp(c->name, w->name, c->namesize));
176 }
177 
178 /*
179  *		Inode number comparing for invalidating lookup cache
180  *
181  *	All entries with designated inode number are invalidated
182  *
183  *	Only use associated with a CACHE_NOHASH flag
184  */
185 
186 static int lookup_cache_inv_compare(const struct CACHED_GENERIC *cached,
187 			const struct CACHED_GENERIC *wanted)
188 {
189 	const struct CACHED_LOOKUP *c = (const struct CACHED_LOOKUP*) cached;
190 	const struct CACHED_LOOKUP *w = (const struct CACHED_LOOKUP*) wanted;
191 	return (!c->name
192 		    || (c->parent != w->parent)
193 		    || (MREF(c->inum) != MREF(w->inum)));
194 }
195 
196 /*
197  *		Lookup hashing
198  *
199  *	Based on first, second and and last char
200  */
201 
202 int ntfs_dir_lookup_hash(const struct CACHED_GENERIC *cached)
203 {
204 	const unsigned char *name;
205 	int count;
206 	unsigned int val;
207 
208 	name = (const unsigned char*)cached->variable;
209 	count = cached->varsize;
210 	if (!name || !count) {
211 		ntfs_log_error("Bad lookup cache entry\n");
212 		return (-1);
213 	}
214 	val = (name[0] << 2) + (name[1] << 1) + name[count - 1] + count;
215 	return (val % (2*CACHE_LOOKUP_SIZE));
216 }
217 
218 #endif
219 
220 /**
221  * ntfs_inode_lookup_by_name - find an inode in a directory given its name
222  * @dir_ni:	ntfs inode of the directory in which to search for the name
223  * @uname:	Unicode name for which to search in the directory
224  * @uname_len:	length of the name @uname in Unicode characters
225  *
226  * Look for an inode with name @uname in the directory with inode @dir_ni.
227  * ntfs_inode_lookup_by_name() walks the contents of the directory looking for
228  * the Unicode name. If the name is found in the directory, the corresponding
229  * inode number (>= 0) is returned as a mft reference in cpu format, i.e. it
230  * is a 64-bit number containing the sequence number.
231  *
232  * On error, return -1 with errno set to the error code. If the inode is is not
233  * found errno is ENOENT.
234  *
235  * Note, @uname_len does not include the (optional) terminating NULL character.
236  *
237  * Note, we look for a case sensitive match first but we also look for a case
238  * insensitive match at the same time. If we find a case insensitive match, we
239  * save that for the case that we don't find an exact match, where we return
240  * the mft reference of the case insensitive match.
241  *
242  * If the volume is mounted with the case sensitive flag set, then we only
243  * allow exact matches.
244  */
245 u64 ntfs_inode_lookup_by_name(ntfs_inode *dir_ni,
246 		const ntfschar *uname, const int uname_len)
247 {
248 	VCN vcn;
249 	u64 mref = 0;
250 	s64 br;
251 	ntfs_volume *vol = dir_ni->vol;
252 	ntfs_attr_search_ctx *ctx;
253 	INDEX_ROOT *ir;
254 	INDEX_ENTRY *ie;
255 	INDEX_ALLOCATION *ia;
256 	IGNORE_CASE_BOOL case_sensitivity;
257 	u8 *index_end;
258 	ntfs_attr *ia_na;
259 	int eo, rc;
260 	u32 index_block_size;
261 	u8 index_vcn_size_bits;
262 
263 	ntfs_log_trace("Entering\n");
264 
265 	if (!dir_ni || !dir_ni->mrec || !uname || uname_len <= 0) {
266 		errno = EINVAL;
267 		return -1;
268 	}
269 
270 	ctx = ntfs_attr_get_search_ctx(dir_ni, NULL);
271 	if (!ctx)
272 		return -1;
273 
274 	/* Find the index root attribute in the mft record. */
275 	if (ntfs_attr_lookup(AT_INDEX_ROOT, NTFS_INDEX_I30, 4, CASE_SENSITIVE, 0, NULL,
276 			0, ctx)) {
277 		ntfs_log_perror("Index root attribute missing in directory inode "
278 				"%lld", (unsigned long long)dir_ni->mft_no);
279 		goto put_err_out;
280 	}
281 	case_sensitivity = (NVolCaseSensitive(vol) ? CASE_SENSITIVE : IGNORE_CASE);
282 	/* Get to the index root value. */
283 	ir = (INDEX_ROOT*)((u8*)ctx->attr +
284 			le16_to_cpu(ctx->attr->value_offset));
285 	index_block_size = le32_to_cpu(ir->index_block_size);
286 	if (index_block_size < NTFS_BLOCK_SIZE ||
287 			index_block_size & (index_block_size - 1)) {
288 		ntfs_log_error("Index block size %u is invalid.\n",
289 				(unsigned)index_block_size);
290 		goto put_err_out;
291 	}
292 	index_end = (u8*)&ir->index + le32_to_cpu(ir->index.index_length);
293 	/* The first index entry. */
294 	ie = (INDEX_ENTRY*)((u8*)&ir->index +
295 			le32_to_cpu(ir->index.entries_offset));
296 	/*
297 	 * Loop until we exceed valid memory (corruption case) or until we
298 	 * reach the last entry.
299 	 */
300 	for (;; ie = (INDEX_ENTRY*)((u8*)ie + le16_to_cpu(ie->length))) {
301 		/* Bounds checks. */
302 		if ((u8*)ie < (u8*)ctx->mrec || (u8*)ie +
303 				sizeof(INDEX_ENTRY_HEADER) > index_end ||
304 				(u8*)ie + le16_to_cpu(ie->key_length) >
305 				index_end) {
306 			ntfs_log_error("Index entry out of bounds in inode %lld"
307 				       "\n", (unsigned long long)dir_ni->mft_no);
308 			goto put_err_out;
309 		}
310 		/*
311 		 * The last entry cannot contain a name. It can however contain
312 		 * a pointer to a child node in the B+tree so we just break out.
313 		 */
314 		if (ie->ie_flags & INDEX_ENTRY_END)
315 			break;
316 
317 		if (!le16_to_cpu(ie->length)) {
318 			ntfs_log_error("Zero length index entry in inode %lld"
319 				       "\n", (unsigned long long)dir_ni->mft_no);
320 			goto put_err_out;
321 		}
322 		/*
323 		 * Not a perfect match, need to do full blown collation so we
324 		 * know which way in the B+tree we have to go.
325 		 */
326 		rc = ntfs_names_full_collate(uname, uname_len,
327 				(ntfschar*)&ie->key.file_name.file_name,
328 				ie->key.file_name.file_name_length,
329 				case_sensitivity, vol->upcase, vol->upcase_len);
330 		/*
331 		 * If uname collates before the name of the current entry, there
332 		 * is definitely no such name in this index but we might need to
333 		 * descend into the B+tree so we just break out of the loop.
334 		 */
335 		if (rc == -1)
336 			break;
337 		/* The names are not equal, continue the search. */
338 		if (rc)
339 			continue;
340 		/*
341 		 * Perfect match, this will never happen as the
342 		 * ntfs_are_names_equal() call will have gotten a match but we
343 		 * still treat it correctly.
344 		 */
345 		mref = le64_to_cpu(ie->indexed_file);
346 		ntfs_attr_put_search_ctx(ctx);
347 		return mref;
348 	}
349 	/*
350 	 * We have finished with this index without success. Check for the
351 	 * presence of a child node and if not present return error code
352 	 * ENOENT, unless we have got the mft reference of a matching name
353 	 * cached in mref in which case return mref.
354 	 */
355 	if (!(ie->ie_flags & INDEX_ENTRY_NODE)) {
356 		ntfs_attr_put_search_ctx(ctx);
357 		if (mref)
358 			return mref;
359 		ntfs_log_debug("Entry not found - between root entries.\n");
360 		errno = ENOENT;
361 		return -1;
362 	} /* Child node present, descend into it. */
363 
364 	/* Open the index allocation attribute. */
365 	ia_na = ntfs_attr_open(dir_ni, AT_INDEX_ALLOCATION, NTFS_INDEX_I30, 4);
366 	if (!ia_na) {
367 		ntfs_log_perror("Failed to open index allocation (inode %lld)",
368 				(unsigned long long)dir_ni->mft_no);
369 		goto put_err_out;
370 	}
371 
372 	/* Allocate a buffer for the current index block. */
373 	ia = ntfs_malloc(index_block_size);
374 	if (!ia) {
375 		ntfs_attr_close(ia_na);
376 		goto put_err_out;
377 	}
378 
379 	/* Determine the size of a vcn in the directory index. */
380 	if (vol->cluster_size <= index_block_size) {
381 		index_vcn_size_bits = vol->cluster_size_bits;
382 	} else {
383 		index_vcn_size_bits = NTFS_BLOCK_SIZE_BITS;
384 	}
385 
386 	/* Get the starting vcn of the index_block holding the child node. */
387 	vcn = sle64_to_cpup((u8*)ie + le16_to_cpu(ie->length) - 8);
388 
389 descend_into_child_node:
390 
391 	/* Read the index block starting at vcn. */
392 	br = ntfs_attr_mst_pread(ia_na, vcn << index_vcn_size_bits, 1,
393 			index_block_size, ia);
394 	if (br != 1) {
395 		if (br != -1)
396 			errno = EIO;
397 		ntfs_log_perror("Failed to read vcn 0x%llx",
398 			       	(unsigned long long)vcn);
399 		goto close_err_out;
400 	}
401 
402 	if (sle64_to_cpu(ia->index_block_vcn) != vcn) {
403 		ntfs_log_error("Actual VCN (0x%llx) of index buffer is different "
404 				"from expected VCN (0x%llx).\n",
405 				(long long)sle64_to_cpu(ia->index_block_vcn),
406 				(long long)vcn);
407 		errno = EIO;
408 		goto close_err_out;
409 	}
410 	if (le32_to_cpu(ia->index.allocated_size) + 0x18 != index_block_size) {
411 		ntfs_log_error("Index buffer (VCN 0x%llx) of directory inode 0x%llx "
412 				"has a size (%u) differing from the directory "
413 				"specified size (%u).\n", (long long)vcn,
414 				(unsigned long long)dir_ni->mft_no,
415 				(unsigned) le32_to_cpu(ia->index.allocated_size) + 0x18,
416 				(unsigned)index_block_size);
417 		errno = EIO;
418 		goto close_err_out;
419 	}
420 	index_end = (u8*)&ia->index + le32_to_cpu(ia->index.index_length);
421 	if (index_end > (u8*)ia + index_block_size) {
422 		ntfs_log_error("Size of index buffer (VCN 0x%llx) of directory inode "
423 				"0x%llx exceeds maximum size.\n",
424 				(long long)vcn, (unsigned long long)dir_ni->mft_no);
425 		errno = EIO;
426 		goto close_err_out;
427 	}
428 
429 	/* The first index entry. */
430 	ie = (INDEX_ENTRY*)((u8*)&ia->index +
431 			le32_to_cpu(ia->index.entries_offset));
432 	/*
433 	 * Iterate similar to above big loop but applied to index buffer, thus
434 	 * loop until we exceed valid memory (corruption case) or until we
435 	 * reach the last entry.
436 	 */
437 	for (;; ie = (INDEX_ENTRY*)((u8*)ie + le16_to_cpu(ie->length))) {
438 		/* Bounds check. */
439 		if ((u8*)ie < (u8*)ia || (u8*)ie +
440 				sizeof(INDEX_ENTRY_HEADER) > index_end ||
441 				(u8*)ie + le16_to_cpu(ie->key_length) >
442 				index_end) {
443 			ntfs_log_error("Index entry out of bounds in directory "
444 				       "inode %lld.\n",
445 				       (unsigned long long)dir_ni->mft_no);
446 			errno = EIO;
447 			goto close_err_out;
448 		}
449 		/*
450 		 * The last entry cannot contain a name. It can however contain
451 		 * a pointer to a child node in the B+tree so we just break out.
452 		 */
453 		if (ie->ie_flags & INDEX_ENTRY_END)
454 			break;
455 
456 		if (!le16_to_cpu(ie->length)) {
457 			errno = EIO;
458 			ntfs_log_error("Zero length index entry in inode %lld"
459 				       "\n", (unsigned long long)dir_ni->mft_no);
460 			goto close_err_out;
461 		}
462 		/*
463 		 * Not a perfect match, need to do full blown collation so we
464 		 * know which way in the B+tree we have to go.
465 		 */
466 		rc = ntfs_names_full_collate(uname, uname_len,
467 				(ntfschar*)&ie->key.file_name.file_name,
468 				ie->key.file_name.file_name_length,
469 				case_sensitivity, vol->upcase, vol->upcase_len);
470 		/*
471 		 * If uname collates before the name of the current entry, there
472 		 * is definitely no such name in this index but we might need to
473 		 * descend into the B+tree so we just break out of the loop.
474 		 */
475 		if (rc == -1)
476 			break;
477 		/* The names are not equal, continue the search. */
478 		if (rc)
479 			continue;
480 		mref = le64_to_cpu(ie->indexed_file);
481 		free(ia);
482 		ntfs_attr_close(ia_na);
483 		ntfs_attr_put_search_ctx(ctx);
484 		return mref;
485 	}
486 	/*
487 	 * We have finished with this index buffer without success. Check for
488 	 * the presence of a child node.
489 	 */
490 	if (ie->ie_flags & INDEX_ENTRY_NODE) {
491 		if ((ia->index.ih_flags & NODE_MASK) == LEAF_NODE) {
492 			ntfs_log_error("Index entry with child node found in a leaf "
493 					"node in directory inode %lld.\n",
494 					(unsigned long long)dir_ni->mft_no);
495 			errno = EIO;
496 			goto close_err_out;
497 		}
498 		/* Child node present, descend into it. */
499 		vcn = sle64_to_cpup((u8*)ie + le16_to_cpu(ie->length) - 8);
500 		if (vcn >= 0)
501 			goto descend_into_child_node;
502 		ntfs_log_error("Negative child node vcn in directory inode "
503 			       "0x%llx.\n", (unsigned long long)dir_ni->mft_no);
504 		errno = EIO;
505 		goto close_err_out;
506 	}
507 	free(ia);
508 	ntfs_attr_close(ia_na);
509 	ntfs_attr_put_search_ctx(ctx);
510 	/*
511 	 * No child node present, return error code ENOENT, unless we have got
512 	 * the mft reference of a matching name cached in mref in which case
513 	 * return mref.
514 	 */
515 	if (mref)
516 		return mref;
517 	ntfs_log_debug("Entry not found.\n");
518 	errno = ENOENT;
519 	return -1;
520 put_err_out:
521 	eo = EIO;
522 	ntfs_log_debug("Corrupt directory. Aborting lookup.\n");
523 eo_put_err_out:
524 	ntfs_attr_put_search_ctx(ctx);
525 	errno = eo;
526 	return -1;
527 close_err_out:
528 	eo = errno;
529 	free(ia);
530 	ntfs_attr_close(ia_na);
531 	goto eo_put_err_out;
532 }
533 
534 /*
535  *		Lookup a file in a directory from its UTF-8 name
536  *
537  *	The name is first fetched from cache if one is defined
538  *
539  *	Returns the inode number
540  *		or -1 if not possible (errno tells why)
541  */
542 
543 u64 ntfs_inode_lookup_by_mbsname(ntfs_inode *dir_ni, const char *name)
544 {
545 	int uname_len;
546 	ntfschar *uname = (ntfschar*)NULL;
547 	u64 inum;
548 	char *cached_name;
549 	const char *const_name;
550 
551 	if (!NVolCaseSensitive(dir_ni->vol)) {
552 		cached_name = ntfs_uppercase_mbs(name,
553 			dir_ni->vol->upcase, dir_ni->vol->upcase_len);
554 		const_name = cached_name;
555 	} else {
556 		cached_name = (char*)NULL;
557 		const_name = name;
558 	}
559 	if (const_name) {
560 #if CACHE_LOOKUP_SIZE
561 
562 		/*
563 		 * fetch inode from cache
564 		 */
565 
566 		if (dir_ni->vol->lookup_cache) {
567 			struct CACHED_LOOKUP item;
568 			struct CACHED_LOOKUP *cached;
569 
570 			item.name = const_name;
571 			item.namesize = strlen(const_name) + 1;
572 			item.parent = dir_ni->mft_no;
573 			cached = (struct CACHED_LOOKUP*)ntfs_fetch_cache(
574 					dir_ni->vol->lookup_cache,
575 					GENERIC(&item), lookup_cache_compare);
576 			if (cached) {
577 				inum = cached->inum;
578 				if (inum == (u64)-1)
579 					errno = ENOENT;
580 			} else {
581 				/* Generate unicode name. */
582 				uname_len = ntfs_mbstoucs(name, &uname);
583 				if (uname_len >= 0) {
584 					inum = ntfs_inode_lookup_by_name(dir_ni,
585 							uname, uname_len);
586 					item.inum = inum;
587 				/* enter into cache, even if not found */
588 					ntfs_enter_cache(dir_ni->vol->lookup_cache,
589 							GENERIC(&item),
590 							lookup_cache_compare);
591 					free(uname);
592 				} else
593 					inum = (s64)-1;
594 			}
595 		} else
596 #endif
597 			{
598 				/* Generate unicode name. */
599 			uname_len = ntfs_mbstoucs(cached_name, &uname);
600 			if (uname_len >= 0)
601 				inum = ntfs_inode_lookup_by_name(dir_ni,
602 						uname, uname_len);
603 			else
604 				inum = (s64)-1;
605 		}
606 		if (cached_name)
607 			free(cached_name);
608 	} else
609 		inum = (s64)-1;
610 	return (inum);
611 }
612 
613 /*
614  *		Update a cache lookup record when a name has been defined
615  *
616  *	The UTF-8 name is required
617  */
618 
619 void ntfs_inode_update_mbsname(ntfs_inode *dir_ni, const char *name, u64 inum)
620 {
621 #if CACHE_LOOKUP_SIZE
622 	struct CACHED_LOOKUP item;
623 	struct CACHED_LOOKUP *cached;
624 	char *cached_name;
625 
626 	if (dir_ni->vol->lookup_cache) {
627 		if (!NVolCaseSensitive(dir_ni->vol)) {
628 			cached_name = ntfs_uppercase_mbs(name,
629 				dir_ni->vol->upcase, dir_ni->vol->upcase_len);
630 			item.name = cached_name;
631 		} else {
632 			cached_name = (char*)NULL;
633 			item.name = name;
634 		}
635 		if (item.name) {
636 			item.namesize = strlen(item.name) + 1;
637 			item.parent = dir_ni->mft_no;
638 			item.inum = inum;
639 			cached = (struct CACHED_LOOKUP*)ntfs_enter_cache(
640 					dir_ni->vol->lookup_cache,
641 					GENERIC(&item), lookup_cache_compare);
642 			if (cached)
643 				cached->inum = inum;
644 			if (cached_name)
645 				free(cached_name);
646 		}
647 	}
648 #endif
649 }
650 
651 /**
652  * ntfs_pathname_to_inode - Find the inode which represents the given pathname
653  * @vol:       An ntfs volume obtained from ntfs_mount
654  * @parent:    A directory inode to begin the search (may be NULL)
655  * @pathname:  Pathname to be located
656  *
657  * Take an ASCII pathname and find the inode that represents it.  The function
658  * splits the path and then descends the directory tree.  If @parent is NULL,
659  * then the root directory '.' will be used as the base for the search.
660  *
661  * Return:  inode  Success, the pathname was valid
662  *	    NULL   Error, the pathname was invalid, or some other error occurred
663  */
664 ntfs_inode *ntfs_pathname_to_inode(ntfs_volume *vol, ntfs_inode *parent,
665 		const char *pathname)
666 {
667 	u64 inum;
668 	int len, err = 0;
669 	char *p, *q;
670 	ntfs_inode *ni;
671 	ntfs_inode *result = NULL;
672 	ntfschar *unicode = NULL;
673 	char *ascii = NULL;
674 #if CACHE_INODE_SIZE
675 	struct CACHED_INODE item;
676 	struct CACHED_INODE *cached;
677 	char *fullname;
678 #endif
679 
680 	if (!vol || !pathname) {
681 		errno = EINVAL;
682 		return NULL;
683 	}
684 
685 	ntfs_log_trace("path: '%s'\n", pathname);
686 
687 	ascii = strdup(pathname);
688 	if (!ascii) {
689 		ntfs_log_error("Out of memory.\n");
690 		err = ENOMEM;
691 		goto out;
692 	}
693 
694 	p = ascii;
695 	/* Remove leading /'s. */
696 	while (p && *p && *p == PATH_SEP)
697 		p++;
698 #if CACHE_INODE_SIZE
699 	fullname = p;
700 	if (p[0] && (p[strlen(p)-1] == PATH_SEP))
701 		ntfs_log_error("Unnormalized path %s\n",ascii);
702 #endif
703 	if (parent) {
704 		ni = parent;
705 	} else {
706 #if CACHE_INODE_SIZE
707 			/*
708 			 * fetch inode for full path from cache
709 			 */
710 		if (*fullname) {
711 			item.pathname = fullname;
712 			item.varsize = strlen(fullname) + 1;
713 			cached = (struct CACHED_INODE*)ntfs_fetch_cache(
714 				vol->xinode_cache, GENERIC(&item),
715 				inode_cache_compare);
716 		} else
717 			cached = (struct CACHED_INODE*)NULL;
718 		if (cached) {
719 			/*
720 			 * return opened inode if found in cache
721 			 */
722 			inum = MREF(cached->inum);
723 			ni = ntfs_inode_open(vol, inum);
724 			if (!ni) {
725 				ntfs_log_debug("Cannot open inode %llu: %s.\n",
726 						(unsigned long long)inum, p);
727 				err = EIO;
728 			}
729 			result = ni;
730 			goto out;
731 		}
732 #endif
733 		ni = ntfs_inode_open(vol, FILE_root);
734 		if (!ni) {
735 			ntfs_log_debug("Couldn't open the inode of the root "
736 					"directory.\n");
737 			err = EIO;
738 			result = (ntfs_inode*)NULL;
739 			goto out;
740 		}
741 	}
742 
743 	while (p && *p) {
744 		/* Find the end of the first token. */
745 		q = strchr(p, PATH_SEP);
746 		if (q != NULL) {
747 			*q = '\0';
748 		}
749 #if CACHE_INODE_SIZE
750 			/*
751 			 * fetch inode for partial path from cache
752 			 */
753 		cached = (struct CACHED_INODE*)NULL;
754 		if (!parent) {
755 			item.pathname = fullname;
756 			item.varsize = strlen(fullname) + 1;
757 			cached = (struct CACHED_INODE*)ntfs_fetch_cache(
758 					vol->xinode_cache, GENERIC(&item),
759 					inode_cache_compare);
760 			if (cached) {
761 				inum = cached->inum;
762 			}
763 		}
764 			/*
765 			 * if not in cache, translate, search, then
766 			 * insert into cache if found
767 			 */
768 		if (!cached) {
769 			len = ntfs_mbstoucs(p, &unicode);
770 			if (len < 0) {
771 				ntfs_log_perror("Could not convert filename to Unicode:"
772 					" '%s'", p);
773 				err = errno;
774 				goto close;
775 			} else if (len > NTFS_MAX_NAME_LEN) {
776 				err = ENAMETOOLONG;
777 				goto close;
778 			}
779 			inum = ntfs_inode_lookup_by_name(ni, unicode, len);
780 			if (!parent && (inum != (u64) -1)) {
781 				item.inum = inum;
782 				ntfs_enter_cache(vol->xinode_cache,
783 						GENERIC(&item),
784 						inode_cache_compare);
785 			}
786 		}
787 #else
788 		len = ntfs_mbstoucs(p, &unicode);
789 		if (len < 0) {
790 			ntfs_log_perror("Could not convert filename to Unicode:"
791 					" '%s'", p);
792 			err = errno;
793 			goto close;
794 		} else if (len > NTFS_MAX_NAME_LEN) {
795 			err = ENAMETOOLONG;
796 			goto close;
797 		}
798 		inum = ntfs_inode_lookup_by_name(ni, unicode, len);
799 #endif
800 		if (inum == (u64) -1) {
801 			ntfs_log_debug("Couldn't find name '%s' in pathname "
802 					"'%s'.\n", p, pathname);
803 			err = ENOENT;
804 			goto close;
805 		}
806 
807 		if (ni != parent)
808 			if (ntfs_inode_close(ni)) {
809 				err = errno;
810 				goto out;
811 			}
812 
813 		inum = MREF(inum);
814 		ni = ntfs_inode_open(vol, inum);
815 		if (!ni) {
816 			ntfs_log_debug("Cannot open inode %llu: %s.\n",
817 					(unsigned long long)inum, p);
818 			err = EIO;
819 			goto close;
820 		}
821 
822 		free(unicode);
823 		unicode = NULL;
824 
825 		if (q) *q++ = PATH_SEP; /* JPA */
826 		p = q;
827 		while (p && *p && *p == PATH_SEP)
828 			p++;
829 	}
830 
831 	result = ni;
832 	ni = NULL;
833 close:
834 	if (ni && (ni != parent))
835 		if (ntfs_inode_close(ni) && !err)
836 			err = errno;
837 out:
838 	free(ascii);
839 	free(unicode);
840 	if (err)
841 		errno = err;
842 	return result;
843 }
844 
845 /*
846  * The little endian Unicode string ".." for ntfs_readdir().
847  */
848 static const ntfschar dotdot[3] = { const_cpu_to_le16('.'),
849 				   const_cpu_to_le16('.'),
850 				   const_cpu_to_le16('\0') };
851 
852 /*
853  * union index_union -
854  * More helpers for ntfs_readdir().
855  */
856 typedef union {
857 	INDEX_ROOT *ir;
858 	INDEX_ALLOCATION *ia;
859 } index_union __attribute__((__transparent_union__));
860 
861 /**
862  * enum INDEX_TYPE -
863  * More helpers for ntfs_readdir().
864  */
865 typedef enum {
866 	INDEX_TYPE_ROOT,	/* index root */
867 	INDEX_TYPE_ALLOCATION,	/* index allocation */
868 } INDEX_TYPE;
869 
870 /*
871  *		Decode Interix file types
872  *
873  *	Non-Interix types are returned as plain files, because a
874  *	Windows user may force patterns very similar to Interix,
875  *	and most metadata files have such similar patters.
876  */
877 
878 static u32 ntfs_interix_types(ntfs_inode *ni)
879 {
880 	ntfs_attr *na;
881 	u32 dt_type;
882 	le64 magic;
883 
884 	dt_type = NTFS_DT_UNKNOWN;
885 	na = ntfs_attr_open(ni, AT_DATA, NULL, 0);
886 	if (na) {
887 		/* Unrecognized patterns (eg HID + SYST) are plain files */
888 		dt_type = NTFS_DT_REG;
889 		if (na->data_size <= 1) {
890 			if (!(ni->flags & FILE_ATTR_HIDDEN))
891 				dt_type = (na->data_size ?
892 						NTFS_DT_SOCK : NTFS_DT_FIFO);
893 		} else {
894 			if ((na->data_size >= (s64)sizeof(magic))
895 			    && (ntfs_attr_pread(na, 0, sizeof(magic), &magic)
896 				== sizeof(magic))) {
897 				if (magic == INTX_SYMBOLIC_LINK)
898 					dt_type = NTFS_DT_LNK;
899 				else if (magic == INTX_BLOCK_DEVICE)
900 					dt_type = NTFS_DT_BLK;
901 				else if (magic == INTX_CHARACTER_DEVICE)
902 					dt_type = NTFS_DT_CHR;
903 			}
904 		}
905 		ntfs_attr_close(na);
906 	}
907 	return (dt_type);
908 }
909 
910 /*
911  *		Decode file types
912  *
913  *	Better only use for Interix types and junctions,
914  *	unneeded complexity when used for plain files or directories
915  *
916  *	Error cases are logged and returned as unknown.
917  */
918 
919 static u32 ntfs_dir_entry_type(ntfs_inode *dir_ni, MFT_REF mref,
920 					FILE_ATTR_FLAGS attributes)
921 {
922 	ntfs_inode *ni;
923 	u32 dt_type;
924 
925 	dt_type = NTFS_DT_UNKNOWN;
926 	ni = ntfs_inode_open(dir_ni->vol, mref);
927 	if (ni) {
928 		if ((attributes & FILE_ATTR_REPARSE_POINT)
929 		    && ntfs_possible_symlink(ni))
930 			dt_type = NTFS_DT_LNK;
931 		else
932 			if ((attributes & FILE_ATTR_SYSTEM)
933 			   && !(attributes & FILE_ATTR_I30_INDEX_PRESENT))
934 				dt_type = ntfs_interix_types(ni);
935 			else
936 				dt_type = (attributes
937 						& FILE_ATTR_I30_INDEX_PRESENT
938 					? NTFS_DT_DIR : NTFS_DT_REG);
939 		if (ntfs_inode_close(ni)) {
940 				 /* anything special worth doing ? */
941 			ntfs_log_error("Failed to close inode %lld\n",
942 				(long long)MREF(mref));
943 		}
944 	}
945 	if (dt_type == NTFS_DT_UNKNOWN)
946 		ntfs_log_error("Could not decode the type of inode %lld\n",
947 				(long long)MREF(mref));
948 	return (dt_type);
949 }
950 
951 /**
952  * ntfs_filldir - ntfs specific filldir method
953  * @dir_ni:	ntfs inode of current directory
954  * @pos:	current position in directory
955  * @ivcn_bits:	log(2) of index vcn size
956  * @index_type:	specifies whether @iu is an index root or an index allocation
957  * @iu:		index root or index block to which @ie belongs
958  * @ie:		current index entry
959  * @dirent:	context for filldir callback supplied by the caller
960  * @filldir:	filldir callback supplied by the caller
961  *
962  * Pass information specifying the current directory entry @ie to the @filldir
963  * callback.
964  */
965 static int ntfs_filldir(ntfs_inode *dir_ni, s64 *pos, u8 ivcn_bits,
966 		const INDEX_TYPE index_type, index_union iu, INDEX_ENTRY *ie,
967 		void *dirent, ntfs_filldir_t filldir)
968 {
969 	FILE_NAME_ATTR *fn = &ie->key.file_name;
970 	unsigned dt_type;
971 	BOOL metadata;
972 	ntfschar *loname;
973 	int res;
974 	MFT_REF mref;
975 
976 	ntfs_log_trace("Entering.\n");
977 
978 	/* Advance the position even if going to skip the entry. */
979 	if (index_type == INDEX_TYPE_ALLOCATION)
980 		*pos = (u8*)ie - (u8*)iu.ia + (sle64_to_cpu(
981 				iu.ia->index_block_vcn) << ivcn_bits) +
982 				dir_ni->vol->mft_record_size;
983 	else /* if (index_type == INDEX_TYPE_ROOT) */
984 		*pos = (u8*)ie - (u8*)iu.ir;
985 	mref = le64_to_cpu(ie->indexed_file);
986 	metadata = (MREF(mref) != FILE_root) && (MREF(mref) < FILE_first_user);
987 	/* Skip root directory self reference entry. */
988 	if (MREF_LE(ie->indexed_file) == FILE_root)
989 		return 0;
990 	if ((ie->key.file_name.file_attributes
991 		     & (FILE_ATTR_REPARSE_POINT | FILE_ATTR_SYSTEM))
992 	    && !metadata)
993 		dt_type = ntfs_dir_entry_type(dir_ni, mref,
994 					ie->key.file_name.file_attributes);
995 	else if (ie->key.file_name.file_attributes
996 		     & FILE_ATTR_I30_INDEX_PRESENT)
997 		dt_type = NTFS_DT_DIR;
998 	else
999 		dt_type = NTFS_DT_REG;
1000 
1001 		/* return metadata files and hidden files if requested */
1002         if ((!metadata && (NVolShowHidFiles(dir_ni->vol)
1003 				|| !(fn->file_attributes & FILE_ATTR_HIDDEN)))
1004             || (NVolShowSysFiles(dir_ni->vol) && (NVolShowHidFiles(dir_ni->vol)
1005 				|| metadata))) {
1006 		if (NVolCaseSensitive(dir_ni->vol)) {
1007 			res = filldir(dirent, fn->file_name,
1008 					fn->file_name_length,
1009 					fn->file_name_type, *pos,
1010 					mref, dt_type);
1011 		} else {
1012 			loname = (ntfschar*)ntfs_malloc(2*fn->file_name_length);
1013 			if (loname) {
1014 				memcpy(loname, fn->file_name,
1015 					2*fn->file_name_length);
1016 				ntfs_name_locase(loname, fn->file_name_length,
1017 					dir_ni->vol->locase,
1018 					dir_ni->vol->upcase_len);
1019 				res = filldir(dirent, loname,
1020 					fn->file_name_length,
1021 					fn->file_name_type, *pos,
1022 					mref, dt_type);
1023 				free(loname);
1024 			} else
1025 				res = -1;
1026 		}
1027 	} else
1028 		res = 0;
1029 	return (res);
1030 }
1031 
1032 /**
1033  * ntfs_mft_get_parent_ref - find mft reference of parent directory of an inode
1034  * @ni:		ntfs inode whose parent directory to find
1035  *
1036  * Find the parent directory of the ntfs inode @ni. To do this, find the first
1037  * file name attribute in the mft record of @ni and return the parent mft
1038  * reference from that.
1039  *
1040  * Note this only makes sense for directories, since files can be hard linked
1041  * from multiple directories and there is no way for us to tell which one is
1042  * being looked for.
1043  *
1044  * Technically directories can have hard links, too, but we consider that as
1045  * illegal as Linux/UNIX do not support directory hard links.
1046  *
1047  * Return the mft reference of the parent directory on success or -1 on error
1048  * with errno set to the error code.
1049  */
1050 #ifndef __HAIKU__
1051 static
1052 #endif
1053 MFT_REF ntfs_mft_get_parent_ref(ntfs_inode *ni)
1054 {
1055 	MFT_REF mref;
1056 	ntfs_attr_search_ctx *ctx;
1057 	FILE_NAME_ATTR *fn;
1058 	int eo;
1059 
1060 	ntfs_log_trace("Entering.\n");
1061 
1062 	if (!ni) {
1063 		errno = EINVAL;
1064 		return ERR_MREF(-1);
1065 	}
1066 
1067 	ctx = ntfs_attr_get_search_ctx(ni, NULL);
1068 	if (!ctx)
1069 		return ERR_MREF(-1);
1070 	if (ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0, 0, 0, NULL, 0, ctx)) {
1071 		ntfs_log_error("No file name found in inode %lld\n",
1072 			       (unsigned long long)ni->mft_no);
1073 		goto err_out;
1074 	}
1075 	if (ctx->attr->non_resident) {
1076 		ntfs_log_error("File name attribute must be resident (inode "
1077 			       "%lld)\n", (unsigned long long)ni->mft_no);
1078 		goto io_err_out;
1079 	}
1080 	fn = (FILE_NAME_ATTR*)((u8*)ctx->attr +
1081 			le16_to_cpu(ctx->attr->value_offset));
1082 	if ((u8*)fn +	le32_to_cpu(ctx->attr->value_length) >
1083 			(u8*)ctx->attr + le32_to_cpu(ctx->attr->length)) {
1084 		ntfs_log_error("Corrupt file name attribute in inode %lld.\n",
1085 			       (unsigned long long)ni->mft_no);
1086 		goto io_err_out;
1087 	}
1088 	mref = le64_to_cpu(fn->parent_directory);
1089 	ntfs_attr_put_search_ctx(ctx);
1090 	return mref;
1091 io_err_out:
1092 	errno = EIO;
1093 err_out:
1094 	eo = errno;
1095 	ntfs_attr_put_search_ctx(ctx);
1096 	errno = eo;
1097 	return ERR_MREF(-1);
1098 }
1099 
1100 /**
1101  * ntfs_readdir - read the contents of an ntfs directory
1102  * @dir_ni:	ntfs inode of current directory
1103  * @pos:	current position in directory
1104  * @dirent:	context for filldir callback supplied by the caller
1105  * @filldir:	filldir callback supplied by the caller
1106  *
1107  * Parse the index root and the index blocks that are marked in use in the
1108  * index bitmap and hand each found directory entry to the @filldir callback
1109  * supplied by the caller.
1110  *
1111  * Return 0 on success or -1 on error with errno set to the error code.
1112  *
1113  * Note: Index blocks are parsed in ascending vcn order, from which follows
1114  * that the directory entries are not returned sorted.
1115  */
1116 int ntfs_readdir(ntfs_inode *dir_ni, s64 *pos,
1117 		void *dirent, ntfs_filldir_t filldir)
1118 {
1119 	s64 i_size, br, ia_pos, bmp_pos, ia_start;
1120 	ntfs_volume *vol;
1121 	ntfs_attr *ia_na, *bmp_na = NULL;
1122 	ntfs_attr_search_ctx *ctx = NULL;
1123 	u8 *index_end, *bmp = NULL;
1124 	INDEX_ROOT *ir;
1125 	INDEX_ENTRY *ie;
1126 	INDEX_ALLOCATION *ia = NULL;
1127 	int rc, ir_pos, bmp_buf_size, bmp_buf_pos, eo;
1128 	u32 index_block_size;
1129 	u8 index_block_size_bits, index_vcn_size_bits;
1130 
1131 	ntfs_log_trace("Entering.\n");
1132 
1133 	if (!dir_ni || !pos || !filldir) {
1134 		errno = EINVAL;
1135 		return -1;
1136 	}
1137 
1138 	if (!(dir_ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)) {
1139 		errno = ENOTDIR;
1140 		return -1;
1141 	}
1142 
1143 	vol = dir_ni->vol;
1144 
1145 	ntfs_log_trace("Entering for inode %lld, *pos 0x%llx.\n",
1146 			(unsigned long long)dir_ni->mft_no, (long long)*pos);
1147 
1148 	/* Open the index allocation attribute. */
1149 	ia_na = ntfs_attr_open(dir_ni, AT_INDEX_ALLOCATION, NTFS_INDEX_I30, 4);
1150 	if (!ia_na) {
1151 		if (errno != ENOENT) {
1152 			ntfs_log_perror("Failed to open index allocation attribute. "
1153 				"Directory inode %lld is corrupt or bug",
1154 				(unsigned long long)dir_ni->mft_no);
1155 			return -1;
1156 		}
1157 		i_size = 0;
1158 	} else
1159 		i_size = ia_na->data_size;
1160 
1161 	rc = 0;
1162 
1163 	/* Are we at end of dir yet? */
1164 	if (*pos >= i_size + vol->mft_record_size)
1165 		goto done;
1166 
1167 	/* Emulate . and .. for all directories. */
1168 	if (!*pos) {
1169 		rc = filldir(dirent, dotdot, 1, FILE_NAME_POSIX, *pos,
1170 				MK_MREF(dir_ni->mft_no,
1171 				le16_to_cpu(dir_ni->mrec->sequence_number)),
1172 				NTFS_DT_DIR);
1173 		if (rc)
1174 			goto err_out;
1175 		++*pos;
1176 	}
1177 	if (*pos == 1) {
1178 		MFT_REF parent_mref;
1179 
1180 		parent_mref = ntfs_mft_get_parent_ref(dir_ni);
1181 		if (parent_mref == ERR_MREF(-1)) {
1182 			ntfs_log_perror("Parent directory not found");
1183 			goto dir_err_out;
1184 		}
1185 
1186 		rc = filldir(dirent, dotdot, 2, FILE_NAME_POSIX, *pos,
1187 				parent_mref, NTFS_DT_DIR);
1188 		if (rc)
1189 			goto err_out;
1190 		++*pos;
1191 	}
1192 
1193 	ctx = ntfs_attr_get_search_ctx(dir_ni, NULL);
1194 	if (!ctx)
1195 		goto err_out;
1196 
1197 	/* Get the offset into the index root attribute. */
1198 	ir_pos = (int)*pos;
1199 	/* Find the index root attribute in the mft record. */
1200 	if (ntfs_attr_lookup(AT_INDEX_ROOT, NTFS_INDEX_I30, 4, CASE_SENSITIVE, 0, NULL,
1201 			0, ctx)) {
1202 		ntfs_log_perror("Index root attribute missing in directory inode "
1203 				"%lld", (unsigned long long)dir_ni->mft_no);
1204 		goto dir_err_out;
1205 	}
1206 	/* Get to the index root value. */
1207 	ir = (INDEX_ROOT*)((u8*)ctx->attr +
1208 			le16_to_cpu(ctx->attr->value_offset));
1209 
1210 	/* Determine the size of a vcn in the directory index. */
1211 	index_block_size = le32_to_cpu(ir->index_block_size);
1212 	if (index_block_size < NTFS_BLOCK_SIZE ||
1213 			index_block_size & (index_block_size - 1)) {
1214 		ntfs_log_error("Index block size %u is invalid.\n",
1215 				(unsigned)index_block_size);
1216 		goto dir_err_out;
1217 	}
1218 	index_block_size_bits = ffs(index_block_size) - 1;
1219 	if (vol->cluster_size <= index_block_size) {
1220 		index_vcn_size_bits = vol->cluster_size_bits;
1221 	} else {
1222 		index_vcn_size_bits = NTFS_BLOCK_SIZE_BITS;
1223 	}
1224 
1225 	/* Are we jumping straight into the index allocation attribute? */
1226 	if (*pos >= vol->mft_record_size) {
1227 		ntfs_attr_put_search_ctx(ctx);
1228 		ctx = NULL;
1229 		goto skip_index_root;
1230 	}
1231 
1232 	index_end = (u8*)&ir->index + le32_to_cpu(ir->index.index_length);
1233 	/* The first index entry. */
1234 	ie = (INDEX_ENTRY*)((u8*)&ir->index +
1235 			le32_to_cpu(ir->index.entries_offset));
1236 	/*
1237 	 * Loop until we exceed valid memory (corruption case) or until we
1238 	 * reach the last entry or until filldir tells us it has had enough
1239 	 * or signals an error (both covered by the rc test).
1240 	 */
1241 	for (;; ie = (INDEX_ENTRY*)((u8*)ie + le16_to_cpu(ie->length))) {
1242 		ntfs_log_debug("In index root, offset %d.\n", (int)((u8*)ie - (u8*)ir));
1243 		/* Bounds checks. */
1244 		if ((u8*)ie < (u8*)ctx->mrec || (u8*)ie +
1245 				sizeof(INDEX_ENTRY_HEADER) > index_end ||
1246 				(u8*)ie + le16_to_cpu(ie->key_length) >
1247 				index_end)
1248 			goto dir_err_out;
1249 		/* The last entry cannot contain a name. */
1250 		if (ie->ie_flags & INDEX_ENTRY_END)
1251 			break;
1252 
1253 		if (!le16_to_cpu(ie->length))
1254 			goto dir_err_out;
1255 
1256 		/* Skip index root entry if continuing previous readdir. */
1257 		if (ir_pos > (u8*)ie - (u8*)ir)
1258 			continue;
1259 		/*
1260 		 * Submit the directory entry to ntfs_filldir(), which will
1261 		 * invoke the filldir() callback as appropriate.
1262 		 */
1263 		rc = ntfs_filldir(dir_ni, pos, index_vcn_size_bits,
1264 				INDEX_TYPE_ROOT, ir, ie, dirent, filldir);
1265 		if (rc) {
1266 			ntfs_attr_put_search_ctx(ctx);
1267 			ctx = NULL;
1268 			goto err_out;
1269 		}
1270 	}
1271 	ntfs_attr_put_search_ctx(ctx);
1272 	ctx = NULL;
1273 
1274 	/* If there is no index allocation attribute we are finished. */
1275 	if (!ia_na)
1276 		goto EOD;
1277 
1278 	/* Advance *pos to the beginning of the index allocation. */
1279 	*pos = vol->mft_record_size;
1280 
1281 skip_index_root:
1282 
1283 	if (!ia_na)
1284 		goto done;
1285 
1286 	/* Allocate a buffer for the current index block. */
1287 	ia = ntfs_malloc(index_block_size);
1288 	if (!ia)
1289 		goto err_out;
1290 
1291 	bmp_na = ntfs_attr_open(dir_ni, AT_BITMAP, NTFS_INDEX_I30, 4);
1292 	if (!bmp_na) {
1293 		ntfs_log_perror("Failed to open index bitmap attribute");
1294 		goto dir_err_out;
1295 	}
1296 
1297 	/* Get the offset into the index allocation attribute. */
1298 	ia_pos = *pos - vol->mft_record_size;
1299 
1300 	bmp_pos = ia_pos >> index_block_size_bits;
1301 	if (bmp_pos >> 3 >= bmp_na->data_size) {
1302 		ntfs_log_error("Current index position exceeds index bitmap "
1303 				"size.\n");
1304 		goto dir_err_out;
1305 	}
1306 
1307 	bmp_buf_size = min(bmp_na->data_size - (bmp_pos >> 3), 4096);
1308 	bmp = ntfs_malloc(bmp_buf_size);
1309 	if (!bmp)
1310 		goto err_out;
1311 
1312 	br = ntfs_attr_pread(bmp_na, bmp_pos >> 3, bmp_buf_size, bmp);
1313 	if (br != bmp_buf_size) {
1314 		if (br != -1)
1315 			errno = EIO;
1316 		ntfs_log_perror("Failed to read from index bitmap attribute");
1317 		goto err_out;
1318 	}
1319 
1320 	bmp_buf_pos = 0;
1321 	/* If the index block is not in use find the next one that is. */
1322 	while (!(bmp[bmp_buf_pos >> 3] & (1 << (bmp_buf_pos & 7)))) {
1323 find_next_index_buffer:
1324 		bmp_pos++;
1325 		bmp_buf_pos++;
1326 		/* If we have reached the end of the bitmap, we are done. */
1327 		if (bmp_pos >> 3 >= bmp_na->data_size)
1328 			goto EOD;
1329 		ia_pos = bmp_pos << index_block_size_bits;
1330 		if (bmp_buf_pos >> 3 < bmp_buf_size)
1331 			continue;
1332 		/* Read next chunk from the index bitmap. */
1333 		bmp_buf_pos = 0;
1334 		if ((bmp_pos >> 3) + bmp_buf_size > bmp_na->data_size)
1335 			bmp_buf_size = bmp_na->data_size - (bmp_pos >> 3);
1336 		br = ntfs_attr_pread(bmp_na, bmp_pos >> 3, bmp_buf_size, bmp);
1337 		if (br != bmp_buf_size) {
1338 			if (br != -1)
1339 				errno = EIO;
1340 			ntfs_log_perror("Failed to read from index bitmap attribute");
1341 			goto err_out;
1342 		}
1343 	}
1344 
1345 	ntfs_log_debug("Handling index block 0x%llx.\n", (long long)bmp_pos);
1346 
1347 	/* Read the index block starting at bmp_pos. */
1348 	br = ntfs_attr_mst_pread(ia_na, bmp_pos << index_block_size_bits, 1,
1349 			index_block_size, ia);
1350 	if (br != 1) {
1351 		if (br != -1)
1352 			errno = EIO;
1353 		ntfs_log_perror("Failed to read index block");
1354 		goto err_out;
1355 	}
1356 
1357 	ia_start = ia_pos & ~(s64)(index_block_size - 1);
1358 	if (sle64_to_cpu(ia->index_block_vcn) != ia_start >>
1359 			index_vcn_size_bits) {
1360 		ntfs_log_error("Actual VCN (0x%llx) of index buffer is different "
1361 				"from expected VCN (0x%llx) in inode 0x%llx.\n",
1362 				(long long)sle64_to_cpu(ia->index_block_vcn),
1363 				(long long)ia_start >> index_vcn_size_bits,
1364 				(unsigned long long)dir_ni->mft_no);
1365 		goto dir_err_out;
1366 	}
1367 	if (le32_to_cpu(ia->index.allocated_size) + 0x18 != index_block_size) {
1368 		ntfs_log_error("Index buffer (VCN 0x%llx) of directory inode %lld "
1369 				"has a size (%u) differing from the directory "
1370 				"specified size (%u).\n", (long long)ia_start >>
1371 				index_vcn_size_bits,
1372 				(unsigned long long)dir_ni->mft_no,
1373 				(unsigned) le32_to_cpu(ia->index.allocated_size)
1374 				+ 0x18, (unsigned)index_block_size);
1375 		goto dir_err_out;
1376 	}
1377 	index_end = (u8*)&ia->index + le32_to_cpu(ia->index.index_length);
1378 	if (index_end > (u8*)ia + index_block_size) {
1379 		ntfs_log_error("Size of index buffer (VCN 0x%llx) of directory inode "
1380 				"%lld exceeds maximum size.\n",
1381 				(long long)ia_start >> index_vcn_size_bits,
1382 				(unsigned long long)dir_ni->mft_no);
1383 		goto dir_err_out;
1384 	}
1385 	/* The first index entry. */
1386 	ie = (INDEX_ENTRY*)((u8*)&ia->index +
1387 			le32_to_cpu(ia->index.entries_offset));
1388 	/*
1389 	 * Loop until we exceed valid memory (corruption case) or until we
1390 	 * reach the last entry or until ntfs_filldir tells us it has had
1391 	 * enough or signals an error (both covered by the rc test).
1392 	 */
1393 	for (;; ie = (INDEX_ENTRY*)((u8*)ie + le16_to_cpu(ie->length))) {
1394 		ntfs_log_debug("In index allocation, offset 0x%llx.\n",
1395 				(long long)ia_start + ((u8*)ie - (u8*)ia));
1396 		/* Bounds checks. */
1397 		if ((u8*)ie < (u8*)ia || (u8*)ie +
1398 				sizeof(INDEX_ENTRY_HEADER) > index_end ||
1399 				(u8*)ie + le16_to_cpu(ie->key_length) >
1400 				index_end) {
1401 			ntfs_log_error("Index entry out of bounds in directory inode "
1402 				"%lld.\n", (unsigned long long)dir_ni->mft_no);
1403 			goto dir_err_out;
1404 		}
1405 		/* The last entry cannot contain a name. */
1406 		if (ie->ie_flags & INDEX_ENTRY_END)
1407 			break;
1408 
1409 		if (!le16_to_cpu(ie->length))
1410 			goto dir_err_out;
1411 
1412 		/* Skip index entry if continuing previous readdir. */
1413 		if (ia_pos - ia_start > (u8*)ie - (u8*)ia)
1414 			continue;
1415 		/*
1416 		 * Submit the directory entry to ntfs_filldir(), which will
1417 		 * invoke the filldir() callback as appropriate.
1418 		 */
1419 		rc = ntfs_filldir(dir_ni, pos, index_vcn_size_bits,
1420 				INDEX_TYPE_ALLOCATION, ia, ie, dirent, filldir);
1421 		if (rc)
1422 			goto err_out;
1423 	}
1424 	goto find_next_index_buffer;
1425 EOD:
1426 	/* We are finished, set *pos to EOD. */
1427 	*pos = i_size + vol->mft_record_size;
1428 done:
1429 	free(ia);
1430 	free(bmp);
1431 	if (bmp_na)
1432 		ntfs_attr_close(bmp_na);
1433 	if (ia_na)
1434 		ntfs_attr_close(ia_na);
1435 	ntfs_log_debug("EOD, *pos 0x%llx, returning 0.\n", (long long)*pos);
1436 	return 0;
1437 dir_err_out:
1438 	errno = EIO;
1439 err_out:
1440 	eo = errno;
1441 	ntfs_log_trace("failed.\n");
1442 	if (ctx)
1443 		ntfs_attr_put_search_ctx(ctx);
1444 	free(ia);
1445 	free(bmp);
1446 	if (bmp_na)
1447 		ntfs_attr_close(bmp_na);
1448 	if (ia_na)
1449 		ntfs_attr_close(ia_na);
1450 	errno = eo;
1451 	return -1;
1452 }
1453 
1454 
1455 /**
1456  * __ntfs_create - create object on ntfs volume
1457  * @dir_ni:	ntfs inode for directory in which create new object
1458  * @securid:	id of inheritable security descriptor, 0 if none
1459  * @name:	unicode name of new object
1460  * @name_len:	length of the name in unicode characters
1461  * @type:	type of the object to create
1462  * @dev:	major and minor device numbers (obtained from makedev())
1463  * @target:	target in unicode (only for symlinks)
1464  * @target_len:	length of target in unicode characters
1465  *
1466  * Internal, use ntfs_create{,_device,_symlink} wrappers instead.
1467  *
1468  * @type can be:
1469  *	S_IFREG		to create regular file
1470  *	S_IFDIR		to create directory
1471  *	S_IFBLK		to create block device
1472  *	S_IFCHR		to create character device
1473  *	S_IFLNK		to create symbolic link
1474  *	S_IFIFO		to create FIFO
1475  *	S_IFSOCK	to create socket
1476  * other values are invalid.
1477  *
1478  * @dev is used only if @type is S_IFBLK or S_IFCHR, in other cases its value
1479  * ignored.
1480  *
1481  * @target and @target_len are used only if @type is S_IFLNK, in other cases
1482  * their value ignored.
1483  *
1484  * Return opened ntfs inode that describes created object on success or NULL
1485  * on error with errno set to the error code.
1486  */
1487 static ntfs_inode *__ntfs_create(ntfs_inode *dir_ni, le32 securid,
1488 		const ntfschar *name, u8 name_len, mode_t type, dev_t dev,
1489 		const ntfschar *target, int target_len)
1490 {
1491 	ntfs_inode *ni;
1492 	int rollback_data = 0, rollback_sd = 0;
1493 	FILE_NAME_ATTR *fn = NULL;
1494 	STANDARD_INFORMATION *si = NULL;
1495 	int err, fn_len, si_len;
1496 
1497 	ntfs_log_trace("Entering.\n");
1498 
1499 	/* Sanity checks. */
1500 	if (!dir_ni || !name || !name_len) {
1501 		ntfs_log_error("Invalid arguments.\n");
1502 		errno = EINVAL;
1503 		return NULL;
1504 	}
1505 
1506 	if (dir_ni->flags & FILE_ATTR_REPARSE_POINT) {
1507 		errno = EOPNOTSUPP;
1508 		return NULL;
1509 	}
1510 
1511 	ni = ntfs_mft_record_alloc(dir_ni->vol, NULL);
1512 	if (!ni)
1513 		return NULL;
1514 #if CACHE_NIDATA_SIZE
1515 	ntfs_inode_invalidate(dir_ni->vol, ni->mft_no);
1516 #endif
1517 	/*
1518 	 * Create STANDARD_INFORMATION attribute.
1519 	 * JPA Depending on available inherited security descriptor,
1520 	 * Write STANDARD_INFORMATION v1.2 (no inheritance) or v3
1521 	 */
1522 	if (securid)
1523 		si_len = sizeof(STANDARD_INFORMATION);
1524 	else
1525 		si_len = offsetof(STANDARD_INFORMATION, v1_end);
1526 	si = ntfs_calloc(si_len);
1527 	if (!si) {
1528 		err = errno;
1529 		goto err_out;
1530 	}
1531 	si->creation_time = ni->creation_time;
1532 	si->last_data_change_time = ni->last_data_change_time;
1533 	si->last_mft_change_time = ni->last_mft_change_time;
1534 	si->last_access_time = ni->last_access_time;
1535 	if (securid) {
1536 		set_nino_flag(ni, v3_Extensions);
1537 		ni->owner_id = si->owner_id = 0;
1538 		ni->security_id = si->security_id = securid;
1539 		ni->quota_charged = si->quota_charged = const_cpu_to_le64(0);
1540 		ni->usn = si->usn = const_cpu_to_le64(0);
1541 	} else
1542 		clear_nino_flag(ni, v3_Extensions);
1543 	if (!S_ISREG(type) && !S_ISDIR(type)) {
1544 		si->file_attributes = FILE_ATTR_SYSTEM;
1545 		ni->flags = FILE_ATTR_SYSTEM;
1546 	}
1547 	ni->flags |= FILE_ATTR_ARCHIVE;
1548 	if (NVolHideDotFiles(dir_ni->vol)
1549 	    && (name_len > 1)
1550 	    && (name[0] == const_cpu_to_le16('.'))
1551 	    && (name[1] != const_cpu_to_le16('.')))
1552 		ni->flags |= FILE_ATTR_HIDDEN;
1553 		/*
1554 		 * Set compression flag according to parent directory
1555 		 * unless NTFS version < 3.0 or cluster size > 4K
1556 		 * or compression has been disabled
1557 		 */
1558 	if ((dir_ni->flags & FILE_ATTR_COMPRESSED)
1559 	   && (dir_ni->vol->major_ver >= 3)
1560 	   && NVolCompression(dir_ni->vol)
1561 	   && (dir_ni->vol->cluster_size <= MAX_COMPRESSION_CLUSTER_SIZE)
1562 	   && (S_ISREG(type) || S_ISDIR(type)))
1563 		ni->flags |= FILE_ATTR_COMPRESSED;
1564 	/* Add STANDARD_INFORMATION to inode. */
1565 	if (ntfs_attr_add(ni, AT_STANDARD_INFORMATION, AT_UNNAMED, 0,
1566 			(u8*)si, si_len)) {
1567 		err = errno;
1568 		ntfs_log_error("Failed to add STANDARD_INFORMATION "
1569 				"attribute.\n");
1570 		goto err_out;
1571 	}
1572 
1573 	if (!securid) {
1574 		if (ntfs_sd_add_everyone(ni)) {
1575 			err = errno;
1576 			goto err_out;
1577 		}
1578 	}
1579 	rollback_sd = 1;
1580 
1581 	if (S_ISDIR(type)) {
1582 		INDEX_ROOT *ir = NULL;
1583 		INDEX_ENTRY *ie;
1584 		int ir_len, index_len;
1585 
1586 		/* Create INDEX_ROOT attribute. */
1587 		index_len = sizeof(INDEX_HEADER) + sizeof(INDEX_ENTRY_HEADER);
1588 		ir_len = offsetof(INDEX_ROOT, index) + index_len;
1589 		ir = ntfs_calloc(ir_len);
1590 		if (!ir) {
1591 			err = errno;
1592 			goto err_out;
1593 		}
1594 		ir->type = AT_FILE_NAME;
1595 		ir->collation_rule = COLLATION_FILE_NAME;
1596 		ir->index_block_size = cpu_to_le32(ni->vol->indx_record_size);
1597 		if (ni->vol->cluster_size <= ni->vol->indx_record_size)
1598 			ir->clusters_per_index_block =
1599 					ni->vol->indx_record_size >>
1600 					ni->vol->cluster_size_bits;
1601 		else
1602 			ir->clusters_per_index_block =
1603 					ni->vol->indx_record_size >>
1604 					NTFS_BLOCK_SIZE_BITS;
1605 		ir->index.entries_offset = cpu_to_le32(sizeof(INDEX_HEADER));
1606 		ir->index.index_length = cpu_to_le32(index_len);
1607 		ir->index.allocated_size = cpu_to_le32(index_len);
1608 		ie = (INDEX_ENTRY*)((u8*)ir + sizeof(INDEX_ROOT));
1609 		ie->length = cpu_to_le16(sizeof(INDEX_ENTRY_HEADER));
1610 		ie->key_length = 0;
1611 		ie->ie_flags = INDEX_ENTRY_END;
1612 		/* Add INDEX_ROOT attribute to inode. */
1613 		if (ntfs_attr_add(ni, AT_INDEX_ROOT, NTFS_INDEX_I30, 4,
1614 				(u8*)ir, ir_len)) {
1615 			err = errno;
1616 			free(ir);
1617 			ntfs_log_error("Failed to add INDEX_ROOT attribute.\n");
1618 			goto err_out;
1619 		}
1620 		free(ir);
1621 	} else {
1622 		INTX_FILE *data;
1623 		int data_len;
1624 
1625 		switch (type) {
1626 			case S_IFBLK:
1627 			case S_IFCHR:
1628 				data_len = offsetof(INTX_FILE, device_end);
1629 				data = ntfs_malloc(data_len);
1630 				if (!data) {
1631 					err = errno;
1632 					goto err_out;
1633 				}
1634 				data->major = cpu_to_le64(major(dev));
1635 				data->minor = cpu_to_le64(minor(dev));
1636 				if (type == S_IFBLK)
1637 					data->magic = INTX_BLOCK_DEVICE;
1638 				if (type == S_IFCHR)
1639 					data->magic = INTX_CHARACTER_DEVICE;
1640 				break;
1641 			case S_IFLNK:
1642 				data_len = sizeof(INTX_FILE_TYPES) +
1643 						target_len * sizeof(ntfschar);
1644 				data = ntfs_malloc(data_len);
1645 				if (!data) {
1646 					err = errno;
1647 					goto err_out;
1648 				}
1649 				data->magic = INTX_SYMBOLIC_LINK;
1650 				memcpy(data->target, target,
1651 						target_len * sizeof(ntfschar));
1652 				break;
1653 			case S_IFSOCK:
1654 				data = NULL;
1655 				data_len = 1;
1656 				break;
1657 			default: /* FIFO or regular file. */
1658 				data = NULL;
1659 				data_len = 0;
1660 				break;
1661 		}
1662 		/* Add DATA attribute to inode. */
1663 		if (ntfs_attr_add(ni, AT_DATA, AT_UNNAMED, 0, (u8*)data,
1664 				data_len)) {
1665 			err = errno;
1666 			ntfs_log_error("Failed to add DATA attribute.\n");
1667 			free(data);
1668 			goto err_out;
1669 		}
1670 		rollback_data = 1;
1671 		free(data);
1672 	}
1673 	/* Create FILE_NAME attribute. */
1674 	fn_len = sizeof(FILE_NAME_ATTR) + name_len * sizeof(ntfschar);
1675 	fn = ntfs_calloc(fn_len);
1676 	if (!fn) {
1677 		err = errno;
1678 		goto err_out;
1679 	}
1680 	fn->parent_directory = MK_LE_MREF(dir_ni->mft_no,
1681 			le16_to_cpu(dir_ni->mrec->sequence_number));
1682 	fn->file_name_length = name_len;
1683 	fn->file_name_type = FILE_NAME_POSIX;
1684 	if (S_ISDIR(type))
1685 		fn->file_attributes = FILE_ATTR_I30_INDEX_PRESENT;
1686 	if (!S_ISREG(type) && !S_ISDIR(type))
1687 		fn->file_attributes = FILE_ATTR_SYSTEM;
1688 	else
1689 		fn->file_attributes |= ni->flags & FILE_ATTR_COMPRESSED;
1690 	fn->file_attributes |= FILE_ATTR_ARCHIVE;
1691 	fn->file_attributes |= ni->flags & FILE_ATTR_HIDDEN;
1692 	fn->creation_time = ni->creation_time;
1693 	fn->last_data_change_time = ni->last_data_change_time;
1694 	fn->last_mft_change_time = ni->last_mft_change_time;
1695 	fn->last_access_time = ni->last_access_time;
1696 	if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)
1697 		fn->data_size = fn->allocated_size = const_cpu_to_le64(0);
1698 	else {
1699 		fn->data_size = cpu_to_sle64(ni->data_size);
1700 		fn->allocated_size = cpu_to_sle64(ni->allocated_size);
1701 	}
1702 	memcpy(fn->file_name, name, name_len * sizeof(ntfschar));
1703 	/* Add FILE_NAME attribute to inode. */
1704 	if (ntfs_attr_add(ni, AT_FILE_NAME, AT_UNNAMED, 0, (u8*)fn, fn_len)) {
1705 		err = errno;
1706 		ntfs_log_error("Failed to add FILE_NAME attribute.\n");
1707 		goto err_out;
1708 	}
1709 	/* Add FILE_NAME attribute to index. */
1710 	if (ntfs_index_add_filename(dir_ni, fn, MK_MREF(ni->mft_no,
1711 			le16_to_cpu(ni->mrec->sequence_number)))) {
1712 		err = errno;
1713 		ntfs_log_perror("Failed to add entry to the index");
1714 		goto err_out;
1715 	}
1716 	/* Set hard links count and directory flag. */
1717 	ni->mrec->link_count = cpu_to_le16(1);
1718 	if (S_ISDIR(type))
1719 		ni->mrec->flags |= MFT_RECORD_IS_DIRECTORY;
1720 	ntfs_inode_mark_dirty(ni);
1721 	/* Done! */
1722 	free(fn);
1723 	free(si);
1724 	ntfs_log_trace("Done.\n");
1725 	return ni;
1726 err_out:
1727 	ntfs_log_trace("Failed.\n");
1728 
1729 	if (rollback_sd)
1730 		ntfs_attr_remove(ni, AT_SECURITY_DESCRIPTOR, AT_UNNAMED, 0);
1731 
1732 	if (rollback_data)
1733 		ntfs_attr_remove(ni, AT_DATA, AT_UNNAMED, 0);
1734 	/*
1735 	 * Free extent MFT records (should not exist any with current
1736 	 * ntfs_create implementation, but for any case if something will be
1737 	 * changed in the future).
1738 	 */
1739 	while (ni->nr_extents)
1740 		if (ntfs_mft_record_free(ni->vol, *(ni->extent_nis))) {
1741 			err = errno;
1742 			ntfs_log_error("Failed to free extent MFT record.  "
1743 					"Leaving inconsistent metadata.\n");
1744 		}
1745 	if (ntfs_mft_record_free(ni->vol, ni))
1746 		ntfs_log_error("Failed to free MFT record.  "
1747 				"Leaving inconsistent metadata. Run chkdsk.\n");
1748 	free(fn);
1749 	free(si);
1750 	errno = err;
1751 	return NULL;
1752 }
1753 
1754 /**
1755  * Some wrappers around __ntfs_create() ...
1756  */
1757 
1758 ntfs_inode *ntfs_create(ntfs_inode *dir_ni, le32 securid, const ntfschar *name,
1759 		u8 name_len, mode_t type)
1760 {
1761 	if (type != S_IFREG && type != S_IFDIR && type != S_IFIFO &&
1762 			type != S_IFSOCK) {
1763 		ntfs_log_error("Invalid arguments.\n");
1764 		return NULL;
1765 	}
1766 	return __ntfs_create(dir_ni, securid, name, name_len, type, 0, NULL, 0);
1767 }
1768 
1769 ntfs_inode *ntfs_create_device(ntfs_inode *dir_ni, le32 securid,
1770 		const ntfschar *name, u8 name_len, mode_t type, dev_t dev)
1771 {
1772 	if (type != S_IFCHR && type != S_IFBLK) {
1773 		ntfs_log_error("Invalid arguments.\n");
1774 		return NULL;
1775 	}
1776 	return __ntfs_create(dir_ni, securid, name, name_len, type, dev, NULL, 0);
1777 }
1778 
1779 ntfs_inode *ntfs_create_symlink(ntfs_inode *dir_ni, le32 securid,
1780 		const ntfschar *name, u8 name_len, const ntfschar *target,
1781 		int target_len)
1782 {
1783 	if (!target || !target_len) {
1784 		ntfs_log_error("%s: Invalid argument (%p, %d)\n", __FUNCTION__,
1785 			       target, target_len);
1786 		return NULL;
1787 	}
1788 	return __ntfs_create(dir_ni, securid, name, name_len, S_IFLNK, 0,
1789 			target, target_len);
1790 }
1791 
1792 int ntfs_check_empty_dir(ntfs_inode *ni)
1793 {
1794 	ntfs_attr *na;
1795 	int ret = 0;
1796 
1797 	if (!(ni->mrec->flags & MFT_RECORD_IS_DIRECTORY))
1798 		return 0;
1799 
1800 	na = ntfs_attr_open(ni, AT_INDEX_ROOT, NTFS_INDEX_I30, 4);
1801 	if (!na) {
1802 		errno = EIO;
1803 		ntfs_log_perror("Failed to open directory");
1804 		return -1;
1805 	}
1806 
1807 	/* Non-empty directory? */
1808 	if ((na->data_size != sizeof(INDEX_ROOT) + sizeof(INDEX_ENTRY_HEADER))){
1809 		/* Both ENOTEMPTY and EEXIST are ok. We use the more common. */
1810 		errno = ENOTEMPTY;
1811 		ntfs_log_debug("Directory is not empty\n");
1812 		ret = -1;
1813 	}
1814 
1815 	ntfs_attr_close(na);
1816 	return ret;
1817 }
1818 
1819 static int ntfs_check_unlinkable_dir(ntfs_inode *ni, FILE_NAME_ATTR *fn)
1820 {
1821 	int link_count = le16_to_cpu(ni->mrec->link_count);
1822 	int ret;
1823 
1824 	ret = ntfs_check_empty_dir(ni);
1825 	if (!ret || errno != ENOTEMPTY)
1826 		return ret;
1827 	/*
1828 	 * Directory is non-empty, so we can unlink only if there is more than
1829 	 * one "real" hard link, i.e. links aren't different DOS and WIN32 names
1830 	 */
1831 	if ((link_count == 1) ||
1832 	    (link_count == 2 && fn->file_name_type == FILE_NAME_DOS)) {
1833 		errno = ENOTEMPTY;
1834 		ntfs_log_debug("Non-empty directory without hard links\n");
1835 		goto no_hardlink;
1836 	}
1837 
1838 	ret = 0;
1839 no_hardlink:
1840 	return ret;
1841 }
1842 
1843 /**
1844  * ntfs_delete - delete file or directory from ntfs volume
1845  * @ni:		ntfs inode for object to delte
1846  * @dir_ni:	ntfs inode for directory in which delete object
1847  * @name:	unicode name of the object to delete
1848  * @name_len:	length of the name in unicode characters
1849  *
1850  * @ni is always closed after the call to this function (even if it failed),
1851  * user does not need to call ntfs_inode_close himself.
1852  *
1853  * Return 0 on success or -1 on error with errno set to the error code.
1854  */
1855 int ntfs_delete(ntfs_volume *vol, const char *pathname,
1856 		ntfs_inode *ni, ntfs_inode *dir_ni, const ntfschar *name,
1857 		u8 name_len)
1858 {
1859 	ntfs_attr_search_ctx *actx = NULL;
1860 	FILE_NAME_ATTR *fn = NULL;
1861 	BOOL looking_for_dos_name = FALSE, looking_for_win32_name = FALSE;
1862 	BOOL case_sensitive_match = TRUE;
1863 	int err = 0;
1864 #if CACHE_NIDATA_SIZE
1865 	int i;
1866 #endif
1867 #if CACHE_INODE_SIZE
1868 	struct CACHED_INODE item;
1869 	const char *p;
1870 	u64 inum = (u64)-1;
1871 	int count;
1872 #endif
1873 #if CACHE_LOOKUP_SIZE
1874 	struct CACHED_LOOKUP lkitem;
1875 #endif
1876 
1877 	ntfs_log_trace("Entering.\n");
1878 
1879 	if (!ni || !dir_ni || !name || !name_len) {
1880 		ntfs_log_error("Invalid arguments.\n");
1881 		errno = EINVAL;
1882 		goto err_out;
1883 	}
1884 	if (ni->nr_extents == -1)
1885 		ni = ni->base_ni;
1886 	if (dir_ni->nr_extents == -1)
1887 		dir_ni = dir_ni->base_ni;
1888 	/*
1889 	 * Search for FILE_NAME attribute with such name. If it's in POSIX or
1890 	 * WIN32_AND_DOS namespace, then simply remove it from index and inode.
1891 	 * If filename in DOS or in WIN32 namespace, then remove DOS name first,
1892 	 * only then remove WIN32 name.
1893 	 */
1894 	actx = ntfs_attr_get_search_ctx(ni, NULL);
1895 	if (!actx)
1896 		goto err_out;
1897 search:
1898 	while (!ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0, CASE_SENSITIVE,
1899 			0, NULL, 0, actx)) {
1900 		char *s;
1901 		IGNORE_CASE_BOOL case_sensitive = IGNORE_CASE;
1902 
1903 		errno = 0;
1904 		fn = (FILE_NAME_ATTR*)((u8*)actx->attr +
1905 				le16_to_cpu(actx->attr->value_offset));
1906 		s = ntfs_attr_name_get(fn->file_name, fn->file_name_length);
1907 		ntfs_log_trace("name: '%s'  type: %d  dos: %d  win32: %d  "
1908 			       "case: %d\n", s, fn->file_name_type,
1909 			       looking_for_dos_name, looking_for_win32_name,
1910 			       case_sensitive_match);
1911 		ntfs_attr_name_free(&s);
1912 		if (looking_for_dos_name) {
1913 			if (fn->file_name_type == FILE_NAME_DOS)
1914 				break;
1915 			else
1916 				continue;
1917 		}
1918 		if (looking_for_win32_name) {
1919 			if  (fn->file_name_type == FILE_NAME_WIN32)
1920 				break;
1921 			else
1922 				continue;
1923 		}
1924 
1925 		/* Ignore hard links from other directories */
1926 		if (dir_ni->mft_no != MREF_LE(fn->parent_directory)) {
1927 			ntfs_log_debug("MFT record numbers don't match "
1928 				       "(%llu != %llu)\n",
1929 				       (long long unsigned)dir_ni->mft_no,
1930 				       (long long unsigned)MREF_LE(fn->parent_directory));
1931 			continue;
1932 		}
1933 		if (case_sensitive_match
1934 		    || ((fn->file_name_type == FILE_NAME_POSIX)
1935 			&& NVolCaseSensitive(ni->vol)))
1936 			case_sensitive = CASE_SENSITIVE;
1937 
1938 		if (ntfs_names_are_equal(fn->file_name, fn->file_name_length,
1939 					 name, name_len, case_sensitive,
1940 					 ni->vol->upcase, ni->vol->upcase_len)){
1941 
1942 			if (fn->file_name_type == FILE_NAME_WIN32) {
1943 				looking_for_dos_name = TRUE;
1944 				ntfs_attr_reinit_search_ctx(actx);
1945 				continue;
1946 			}
1947 			if (fn->file_name_type == FILE_NAME_DOS)
1948 				looking_for_dos_name = TRUE;
1949 			break;
1950 		}
1951 	}
1952 	if (errno) {
1953 		/*
1954 		 * If case sensitive search failed, then try once again
1955 		 * ignoring case.
1956 		 */
1957 		if (errno == ENOENT && case_sensitive_match) {
1958 			case_sensitive_match = FALSE;
1959 			ntfs_attr_reinit_search_ctx(actx);
1960 			goto search;
1961 		}
1962 		goto err_out;
1963 	}
1964 
1965 	if (ntfs_check_unlinkable_dir(ni, fn) < 0)
1966 		goto err_out;
1967 
1968 	if (ntfs_index_remove(dir_ni, ni, fn, le32_to_cpu(actx->attr->value_length)))
1969 		goto err_out;
1970 
1971 	/*
1972 	 * Keep the last name in place, this is useful for undeletion
1973 	 * (Windows also does so), however delete the name if it were
1974 	 * in an extent, to avoid leaving an attribute list.
1975 	 */
1976 	if ((ni->mrec->link_count == cpu_to_le16(1)) && !actx->base_ntfs_ino) {
1977 			/* make sure to not loop to another search */
1978 		looking_for_dos_name = FALSE;
1979 	} else {
1980 		if (ntfs_attr_record_rm(actx))
1981 			goto err_out;
1982 	}
1983 
1984 	ni->mrec->link_count = cpu_to_le16(le16_to_cpu(
1985 			ni->mrec->link_count) - 1);
1986 
1987 	ntfs_inode_mark_dirty(ni);
1988 	if (looking_for_dos_name) {
1989 		looking_for_dos_name = FALSE;
1990 		looking_for_win32_name = TRUE;
1991 		ntfs_attr_reinit_search_ctx(actx);
1992 		goto search;
1993 	}
1994 	/* TODO: Update object id, quota and securiry indexes if required. */
1995 	/*
1996 	 * If hard link count is not equal to zero then we are done. In other
1997 	 * case there are no reference to this inode left, so we should free all
1998 	 * non-resident attributes and mark all MFT record as not in use.
1999 	 */
2000 #if CACHE_LOOKUP_SIZE
2001 			/* invalidate entry in lookup cache */
2002 	lkitem.name = (const char*)NULL;
2003 	lkitem.namesize = 0;
2004 	lkitem.inum = ni->mft_no;
2005 	lkitem.parent = dir_ni->mft_no;
2006 	ntfs_invalidate_cache(vol->lookup_cache, GENERIC(&lkitem),
2007 			lookup_cache_inv_compare, CACHE_NOHASH);
2008 #endif
2009 #if CACHE_INODE_SIZE
2010 	inum = ni->mft_no;
2011 	if (pathname) {
2012 			/* invalide cache entry, even if there was an error */
2013 		/* Remove leading /'s. */
2014 		p = pathname;
2015 		while (*p == PATH_SEP)
2016 			p++;
2017 		if (p[0] && (p[strlen(p)-1] == PATH_SEP))
2018 			ntfs_log_error("Unnormalized path %s\n",pathname);
2019 		item.pathname = p;
2020 		item.varsize = strlen(p);
2021 	} else {
2022 		item.pathname = (const char*)NULL;
2023 		item.varsize = 0;
2024 	}
2025 	item.inum = inum;
2026 	count = ntfs_invalidate_cache(vol->xinode_cache, GENERIC(&item),
2027 				inode_cache_inv_compare, CACHE_NOHASH);
2028 	if (pathname && !count)
2029 		ntfs_log_error("Could not delete inode cache entry for %s\n",
2030 			pathname);
2031 #endif
2032 	if (ni->mrec->link_count) {
2033 		ntfs_inode_update_times(ni, NTFS_UPDATE_CTIME);
2034 		goto ok;
2035 	}
2036 	if (ntfs_delete_reparse_index(ni)) {
2037 		/*
2038 		 * Failed to remove the reparse index : proceed anyway
2039 		 * This is not a critical error, the entry is useless
2040 		 * because of sequence_number, and stopping file deletion
2041 		 * would be much worse as the file is not referenced now.
2042 		 */
2043 		err = errno;
2044 	}
2045 	if (ntfs_delete_object_id_index(ni)) {
2046 		/*
2047 		 * Failed to remove the object id index : proceed anyway
2048 		 * This is not a critical error.
2049 		 */
2050 		err = errno;
2051 	}
2052 	ntfs_attr_reinit_search_ctx(actx);
2053 	while (!ntfs_attrs_walk(actx)) {
2054 		if (actx->attr->non_resident) {
2055 			runlist *rl;
2056 
2057 			rl = ntfs_mapping_pairs_decompress(ni->vol, actx->attr,
2058 					NULL);
2059 			if (!rl) {
2060 				err = errno;
2061 				ntfs_log_error("Failed to decompress runlist.  "
2062 						"Leaving inconsistent metadata.\n");
2063 				continue;
2064 			}
2065 			if (ntfs_cluster_free_from_rl(ni->vol, rl)) {
2066 				err = errno;
2067 				ntfs_log_error("Failed to free clusters.  "
2068 						"Leaving inconsistent metadata.\n");
2069 				continue;
2070 			}
2071 			free(rl);
2072 		}
2073 	}
2074 	if (errno != ENOENT) {
2075 		err = errno;
2076 		ntfs_log_error("Attribute enumeration failed.  "
2077 				"Probably leaving inconsistent metadata.\n");
2078 	}
2079 	/* All extents should be attached after attribute walk. */
2080 #if CACHE_NIDATA_SIZE
2081 		/*
2082 		 * Disconnect extents before deleting them, so they are
2083 		 * not wrongly moved to cache through the chainings
2084 		 */
2085 	for (i=ni->nr_extents-1; i>=0; i--) {
2086 		ni->extent_nis[i]->base_ni = (ntfs_inode*)NULL;
2087 		ni->extent_nis[i]->nr_extents = 0;
2088 		if (ntfs_mft_record_free(ni->vol, ni->extent_nis[i])) {
2089 			err = errno;
2090 			ntfs_log_error("Failed to free extent MFT record.  "
2091 					"Leaving inconsistent metadata.\n");
2092 		}
2093 	}
2094 	free(ni->extent_nis);
2095 	ni->nr_extents = 0;
2096 	ni->extent_nis = (ntfs_inode**)NULL;
2097 #else
2098 	while (ni->nr_extents)
2099 		if (ntfs_mft_record_free(ni->vol, *(ni->extent_nis))) {
2100 			err = errno;
2101 			ntfs_log_error("Failed to free extent MFT record.  "
2102 					"Leaving inconsistent metadata.\n");
2103 		}
2104 #endif
2105 	debug_double_inode(ni->mft_no,0);
2106 	if (ntfs_mft_record_free(ni->vol, ni)) {
2107 		err = errno;
2108 		ntfs_log_error("Failed to free base MFT record.  "
2109 				"Leaving inconsistent metadata.\n");
2110 	}
2111 	ni = NULL;
2112 ok:
2113 	ntfs_inode_update_times(dir_ni, NTFS_UPDATE_MCTIME);
2114 out:
2115 	if (actx)
2116 		ntfs_attr_put_search_ctx(actx);
2117 	if (ntfs_inode_close(dir_ni) && !err)
2118 		err = errno;
2119 	if (ntfs_inode_close(ni) && !err)
2120 		err = errno;
2121 	if (err) {
2122 		errno = err;
2123 		ntfs_log_debug("Could not delete file: %s\n", strerror(errno));
2124 		return -1;
2125 	}
2126 	ntfs_log_trace("Done.\n");
2127 	return 0;
2128 err_out:
2129 	err = errno;
2130 	goto out;
2131 }
2132 
2133 /**
2134  * ntfs_link - create hard link for file or directory
2135  * @ni:		ntfs inode for object to create hard link
2136  * @dir_ni:	ntfs inode for directory in which new link should be placed
2137  * @name:	unicode name of the new link
2138  * @name_len:	length of the name in unicode characters
2139  *
2140  * NOTE: At present we allow creating hardlinks to directories, we use them
2141  * in a temporary state during rename. But it's defenitely bad idea to have
2142  * hard links to directories as a result of operation.
2143  * FIXME: Create internal  __ntfs_link that allows hard links to a directories
2144  * and external ntfs_link that do not. Write ntfs_rename that uses __ntfs_link.
2145  *
2146  * Return 0 on success or -1 on error with errno set to the error code.
2147  */
2148 static int ntfs_link_i(ntfs_inode *ni, ntfs_inode *dir_ni, const ntfschar *name,
2149 			 u8 name_len, FILE_NAME_TYPE_FLAGS nametype)
2150 {
2151 	FILE_NAME_ATTR *fn = NULL;
2152 	int fn_len, err;
2153 
2154 	ntfs_log_trace("Entering.\n");
2155 
2156 	if (!ni || !dir_ni || !name || !name_len ||
2157 			ni->mft_no == dir_ni->mft_no) {
2158 		err = EINVAL;
2159 		ntfs_log_perror("ntfs_link wrong arguments");
2160 		goto err_out;
2161 	}
2162 
2163 	if ((ni->flags & FILE_ATTR_REPARSE_POINT)
2164 	   && !ntfs_possible_symlink(ni)) {
2165 		err = EOPNOTSUPP;
2166 		goto err_out;
2167 	}
2168 	if (NVolHideDotFiles(dir_ni->vol)) {
2169 		/* Set hidden flag according to the latest name */
2170 		if ((name_len > 1)
2171 		    && (name[0] == const_cpu_to_le16('.'))
2172 		    && (name[1] != const_cpu_to_le16('.')))
2173 			ni->flags |= FILE_ATTR_HIDDEN;
2174 		else
2175 			ni->flags &= ~FILE_ATTR_HIDDEN;
2176 	}
2177 
2178 	/* Create FILE_NAME attribute. */
2179 	fn_len = sizeof(FILE_NAME_ATTR) + name_len * sizeof(ntfschar);
2180 	fn = ntfs_calloc(fn_len);
2181 	if (!fn) {
2182 		err = errno;
2183 		goto err_out;
2184 	}
2185 	fn->parent_directory = MK_LE_MREF(dir_ni->mft_no,
2186 			le16_to_cpu(dir_ni->mrec->sequence_number));
2187 	fn->file_name_length = name_len;
2188 	fn->file_name_type = nametype;
2189 	fn->file_attributes = ni->flags;
2190 	if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY) {
2191 		fn->file_attributes |= FILE_ATTR_I30_INDEX_PRESENT;
2192 		fn->data_size = fn->allocated_size = const_cpu_to_le64(0);
2193 	} else {
2194 		fn->allocated_size = cpu_to_sle64(ni->allocated_size);
2195 		fn->data_size = cpu_to_sle64(ni->data_size);
2196 	}
2197 	fn->creation_time = ni->creation_time;
2198 	fn->last_data_change_time = ni->last_data_change_time;
2199 	fn->last_mft_change_time = ni->last_mft_change_time;
2200 	fn->last_access_time = ni->last_access_time;
2201 	memcpy(fn->file_name, name, name_len * sizeof(ntfschar));
2202 	/* Add FILE_NAME attribute to index. */
2203 	if (ntfs_index_add_filename(dir_ni, fn, MK_MREF(ni->mft_no,
2204 			le16_to_cpu(ni->mrec->sequence_number)))) {
2205 		err = errno;
2206 		ntfs_log_perror("Failed to add filename to the index");
2207 		goto err_out;
2208 	}
2209 	/* Add FILE_NAME attribute to inode. */
2210 	if (ntfs_attr_add(ni, AT_FILE_NAME, AT_UNNAMED, 0, (u8*)fn, fn_len)) {
2211 		ntfs_log_error("Failed to add FILE_NAME attribute.\n");
2212 		err = errno;
2213 		/* Try to remove just added attribute from index. */
2214 		if (ntfs_index_remove(dir_ni, ni, fn, fn_len))
2215 			goto rollback_failed;
2216 		goto err_out;
2217 	}
2218 	/* Increment hard links count. */
2219 	ni->mrec->link_count = cpu_to_le16(le16_to_cpu(
2220 			ni->mrec->link_count) + 1);
2221 	/* Done! */
2222 	ntfs_inode_mark_dirty(ni);
2223 	free(fn);
2224 	ntfs_log_trace("Done.\n");
2225 	return 0;
2226 rollback_failed:
2227 	ntfs_log_error("Rollback failed. Leaving inconsistent metadata.\n");
2228 err_out:
2229 	free(fn);
2230 	errno = err;
2231 	return -1;
2232 }
2233 
2234 int ntfs_link(ntfs_inode *ni, ntfs_inode *dir_ni, const ntfschar *name,
2235 		u8 name_len)
2236 {
2237 	return (ntfs_link_i(ni, dir_ni, name, name_len, FILE_NAME_POSIX));
2238 }
2239 
2240 /*
2241  *		Get a parent directory from an inode entry
2242  *
2243  *	This is only used in situations where the path used to access
2244  *	the current file is not known for sure. The result may be different
2245  *	from the path when the file is linked in several parent directories.
2246  *
2247  *	Currently this is only used for translating ".." in the target
2248  *	of a Vista relative symbolic link
2249  */
2250 
2251 ntfs_inode *ntfs_dir_parent_inode(ntfs_inode *ni)
2252 {
2253 	ntfs_inode *dir_ni = (ntfs_inode*)NULL;
2254 	u64 inum;
2255 	FILE_NAME_ATTR *fn;
2256 	ntfs_attr_search_ctx *ctx;
2257 
2258 	if (ni->mft_no != FILE_root) {
2259 			/* find the name in the attributes */
2260 		ctx = ntfs_attr_get_search_ctx(ni, NULL);
2261 		if (!ctx)
2262 			return ((ntfs_inode*)NULL);
2263 
2264 		if (!ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0,
2265 				CASE_SENSITIVE,	0, NULL, 0, ctx)) {
2266 			/* We know this will always be resident. */
2267 			fn = (FILE_NAME_ATTR*)((u8*)ctx->attr +
2268 					le16_to_cpu(ctx->attr->value_offset));
2269 			inum = le64_to_cpu(fn->parent_directory);
2270 			if (inum != (u64)-1) {
2271 				dir_ni = ntfs_inode_open(ni->vol, MREF(inum));
2272 			}
2273 		}
2274 		ntfs_attr_put_search_ctx(ctx);
2275 	}
2276 	return (dir_ni);
2277 }
2278 
2279 #ifdef HAVE_SETXATTR
2280 
2281 #define MAX_DOS_NAME_LENGTH	 12
2282 
2283 /*
2284  *		Get a DOS name for a file in designated directory
2285  *
2286  *	Not allowed if there are several non-dos names (EMLINK)
2287  *
2288  *	Returns size if found
2289  *		0 if not found
2290  *		-1 if there was an error (described by errno)
2291  */
2292 
2293 static int get_dos_name(ntfs_inode *ni, u64 dnum, ntfschar *dosname)
2294 {
2295 	size_t outsize = 0;
2296 	int namecount = 0;
2297 	FILE_NAME_ATTR *fn;
2298 	ntfs_attr_search_ctx *ctx;
2299 
2300 		/* find the name in the attributes */
2301 	ctx = ntfs_attr_get_search_ctx(ni, NULL);
2302 	if (!ctx)
2303 		return -1;
2304 
2305 	while (!ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0, CASE_SENSITIVE,
2306 			0, NULL, 0, ctx)) {
2307 		/* We know this will always be resident. */
2308 		fn = (FILE_NAME_ATTR*)((u8*)ctx->attr +
2309 				le16_to_cpu(ctx->attr->value_offset));
2310 
2311 		if (fn->file_name_type != FILE_NAME_DOS)
2312 			namecount++;
2313 		if ((fn->file_name_type & FILE_NAME_DOS)
2314 		    && (MREF_LE(fn->parent_directory) == dnum)) {
2315 				/*
2316 				 * Found a DOS or WIN32+DOS name for the entry
2317 				 * copy name, after truncation for safety
2318 				 */
2319 			outsize = fn->file_name_length;
2320 /* TODO : reject if name is too long ? */
2321 			if (outsize > MAX_DOS_NAME_LENGTH)
2322 				outsize = MAX_DOS_NAME_LENGTH;
2323 			memcpy(dosname,fn->file_name,outsize*sizeof(ntfschar));
2324 		}
2325 	}
2326 	ntfs_attr_put_search_ctx(ctx);
2327 	if ((outsize > 0) && (namecount > 1)) {
2328 		outsize = -1;
2329 		errno = EMLINK; /* this error implies there is a dos name */
2330 	}
2331 	return (outsize);
2332 }
2333 
2334 
2335 /*
2336  *		Get a long name for a file in designated directory
2337  *
2338  *	Not allowed if there are several non-dos names (EMLINK)
2339  *
2340  *	Returns size if found
2341  *		0 if not found
2342  *		-1 if there was an error (described by errno)
2343  */
2344 
2345 static int get_long_name(ntfs_inode *ni, u64 dnum, ntfschar *longname)
2346 {
2347 	size_t outsize = 0;
2348 	int namecount = 0;
2349 	FILE_NAME_ATTR *fn;
2350 	ntfs_attr_search_ctx *ctx;
2351 
2352 		/* find the name in the attributes */
2353 	ctx = ntfs_attr_get_search_ctx(ni, NULL);
2354 	if (!ctx)
2355 		return -1;
2356 
2357 		/* first search for WIN32 or DOS+WIN32 names */
2358 	while (!ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0, CASE_SENSITIVE,
2359 			0, NULL, 0, ctx)) {
2360 		/* We know this will always be resident. */
2361 		fn = (FILE_NAME_ATTR*)((u8*)ctx->attr +
2362 				le16_to_cpu(ctx->attr->value_offset));
2363 
2364 		if (fn->file_name_type != FILE_NAME_DOS)
2365 			namecount++;
2366 		if ((fn->file_name_type & FILE_NAME_WIN32)
2367 		    && (MREF_LE(fn->parent_directory) == dnum)) {
2368 				/*
2369 				 * Found a WIN32 or WIN32+DOS name for the entry
2370 				 * copy name
2371 				 */
2372 			outsize = fn->file_name_length;
2373 			memcpy(longname,fn->file_name,outsize*sizeof(ntfschar));
2374 		}
2375 	}
2376 	if (namecount > 1) {
2377 		ntfs_attr_put_search_ctx(ctx);
2378 		errno = EMLINK;
2379 		return -1;
2380 	}
2381 		/* if not found search for POSIX names */
2382 	if (!outsize) {
2383 		ntfs_attr_reinit_search_ctx(ctx);
2384 	while (!ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0, CASE_SENSITIVE,
2385 			0, NULL, 0, ctx)) {
2386 		/* We know this will always be resident. */
2387 		fn = (FILE_NAME_ATTR*)((u8*)ctx->attr +
2388 				le16_to_cpu(ctx->attr->value_offset));
2389 
2390 		if ((fn->file_name_type == FILE_NAME_POSIX)
2391 		    && (MREF_LE(fn->parent_directory) == dnum)) {
2392 				/*
2393 				 * Found a POSIX name for the entry
2394 				 * copy name
2395 				 */
2396 			outsize = fn->file_name_length;
2397 			memcpy(longname,fn->file_name,outsize*sizeof(ntfschar));
2398 		}
2399 	}
2400 	}
2401 	ntfs_attr_put_search_ctx(ctx);
2402 	return (outsize);
2403 }
2404 
2405 
2406 /*
2407  *		Get the ntfs DOS name into an extended attribute
2408  */
2409 
2410 int ntfs_get_ntfs_dos_name(ntfs_inode *ni, ntfs_inode *dir_ni,
2411 			char *value, size_t size)
2412 {
2413 	int outsize = 0;
2414 	char *outname = (char*)NULL;
2415 	u64 dnum;
2416 	int doslen;
2417 	ntfschar dosname[MAX_DOS_NAME_LENGTH];
2418 
2419 	dnum = dir_ni->mft_no;
2420 	doslen = get_dos_name(ni, dnum, dosname);
2421 	if (doslen > 0) {
2422 			/*
2423 			 * Found a DOS name for the entry, make
2424 			 * uppercase and encode into the buffer
2425 			 * if there is enough space
2426 			 */
2427 		ntfs_name_upcase(dosname, doslen,
2428 				ni->vol->upcase, ni->vol->upcase_len);
2429 		if (ntfs_ucstombs(dosname, doslen, &outname, size) < 0) {
2430 			ntfs_log_error("Cannot represent dosname in current locale.\n");
2431 			outsize = -errno;
2432 		} else {
2433 			outsize = strlen(outname);
2434 			if (value && (outsize <= (int)size))
2435 				memcpy(value, outname, outsize);
2436 			else
2437 				if (size && (outsize > (int)size))
2438 					outsize = -ERANGE;
2439 			free(outname);
2440 		}
2441 	} else {
2442 		if (doslen == 0)
2443 			errno = ENODATA;
2444 		outsize = -errno;
2445 	}
2446 	return (outsize);
2447 }
2448 
2449 /*
2450  *		Change the name space of an existing file or directory
2451  *
2452  *	Returns the old namespace if successful
2453  *		-1 if an error occurred (described by errno)
2454  */
2455 
2456 static int set_namespace(ntfs_inode *ni, ntfs_inode *dir_ni,
2457 			const ntfschar *name, int len,
2458 			FILE_NAME_TYPE_FLAGS nametype)
2459 {
2460 	ntfs_attr_search_ctx *actx;
2461 	ntfs_index_context *icx;
2462 	FILE_NAME_ATTR *fnx;
2463 	FILE_NAME_ATTR *fn = NULL;
2464 	BOOL found;
2465 	int lkup;
2466 	int ret;
2467 
2468 	ret = -1;
2469 	actx = ntfs_attr_get_search_ctx(ni, NULL);
2470 	if (actx) {
2471 		found = FALSE;
2472 		do {
2473 			lkup = ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0,
2474 	                        CASE_SENSITIVE, 0, NULL, 0, actx);
2475 			if (!lkup) {
2476 				fn = (FILE_NAME_ATTR*)((u8*)actx->attr +
2477 				     le16_to_cpu(actx->attr->value_offset));
2478 				found = (MREF_LE(fn->parent_directory)
2479 						== dir_ni->mft_no)
2480 					&& !memcmp(fn->file_name, name,
2481 						len*sizeof(ntfschar));
2482 			}
2483 		} while (!lkup && !found);
2484 		if (found) {
2485 			icx = ntfs_index_ctx_get(dir_ni, NTFS_INDEX_I30, 4);
2486 			if (icx) {
2487 				lkup = ntfs_index_lookup((char*)fn, len, icx);
2488 				if (!lkup && icx->data && icx->data_len) {
2489 					fnx = (FILE_NAME_ATTR*)icx->data;
2490 					ret = fn->file_name_type;
2491 					fn->file_name_type = nametype;
2492 					fnx->file_name_type = nametype;
2493 					ntfs_inode_mark_dirty(ni);
2494 					ntfs_index_entry_mark_dirty(icx);
2495 				}
2496 			ntfs_index_ctx_put(icx);
2497 			}
2498 		}
2499 		ntfs_attr_put_search_ctx(actx);
2500 	}
2501 	return (ret);
2502 }
2503 
2504 /*
2505  *		Set a DOS name to a file and adjust name spaces
2506  *
2507  *	If the new names are collapsible (same uppercased chars) :
2508  *
2509  * - the existing DOS name or DOS+Win32 name is made Posix
2510  * - if it was a real DOS name, the existing long name is made DOS+Win32
2511  *        and the existing DOS name is deleted
2512  * - finally the existing long name is made DOS+Win32 unless already done
2513  *
2514  *	If the new names are not collapsible :
2515  *
2516  * - insert the short name as a DOS name
2517  * - delete the old long name or existing short name
2518  * - insert the new long name (as a Win32 or DOS+Win32 name)
2519  *
2520  * Deleting the old long name will not delete the file
2521  * provided the old name was in the Posix name space,
2522  * because the alternate name has been set before.
2523  *
2524  * The inodes of file and parent directory are always closed
2525  *
2526  * Returns 0 if successful
2527  *	   -1 if failed
2528  */
2529 
2530 static int set_dos_name(ntfs_inode *ni, ntfs_inode *dir_ni,
2531 			const ntfschar *shortname, int shortlen,
2532 			const ntfschar *longname, int longlen,
2533 			const ntfschar *deletename, int deletelen, BOOL existed)
2534 {
2535 	unsigned int linkcount;
2536 	ntfs_volume *vol;
2537 	BOOL collapsible;
2538 	BOOL deleted;
2539 	BOOL done;
2540 	FILE_NAME_TYPE_FLAGS oldnametype;
2541 	u64 dnum;
2542 	u64 fnum;
2543 	int res;
2544 
2545 	res = -1;
2546 	vol = ni->vol;
2547 	dnum = dir_ni->mft_no;
2548 	fnum = ni->mft_no;
2549 				/* save initial link count */
2550 	linkcount = le16_to_cpu(ni->mrec->link_count);
2551 
2552 		/* check whether the same name may be used as DOS and WIN32 */
2553 	collapsible = ntfs_collapsible_chars(ni->vol, shortname, shortlen,
2554 						longname, longlen);
2555 	if (collapsible) {
2556 		deleted = FALSE;
2557 		done = FALSE;
2558 		if (existed) {
2559 			oldnametype = set_namespace(ni, dir_ni, deletename,
2560 					deletelen, FILE_NAME_POSIX);
2561 			if (oldnametype == FILE_NAME_DOS) {
2562 				if (set_namespace(ni, dir_ni, longname, longlen,
2563 						FILE_NAME_WIN32_AND_DOS) >= 0) {
2564 					if (!ntfs_delete(vol,
2565 						(const char*)NULL, ni, dir_ni,
2566 						deletename, deletelen))
2567 						res = 0;
2568 					deleted = TRUE;
2569 				} else
2570 					done = TRUE;
2571 			}
2572 		}
2573 		if (!deleted) {
2574 			if (!done && (set_namespace(ni, dir_ni,
2575 					longname, longlen,
2576 					FILE_NAME_WIN32_AND_DOS) >= 0))
2577 				res = 0;
2578 			ntfs_inode_update_times(ni, NTFS_UPDATE_CTIME);
2579 			ntfs_inode_update_times(dir_ni, NTFS_UPDATE_MCTIME);
2580 			if (ntfs_inode_close_in_dir(ni,dir_ni) && !res)
2581 				res = -1;
2582 			if (ntfs_inode_close(dir_ni) && !res)
2583 				res = -1;
2584 		}
2585 	} else {
2586 		if (!ntfs_link_i(ni, dir_ni, shortname, shortlen,
2587 				FILE_NAME_DOS)
2588 			/* make sure a new link was recorded */
2589 		    && (le16_to_cpu(ni->mrec->link_count) > linkcount)) {
2590 			/* delete the existing long name or short name */
2591 // is it ok to not provide the path ?
2592 			if (!ntfs_delete(vol, (char*)NULL, ni, dir_ni,
2593 				 deletename, deletelen)) {
2594 			/* delete closes the inodes, so have to open again */
2595 				dir_ni = ntfs_inode_open(vol, dnum);
2596 				if (dir_ni) {
2597 					ni = ntfs_inode_open(vol, fnum);
2598 					if (ni) {
2599 						if (!ntfs_link_i(ni, dir_ni,
2600 							longname, longlen,
2601 							FILE_NAME_WIN32))
2602 							res = 0;
2603 						if (ntfs_inode_close_in_dir(ni,
2604 							dir_ni)
2605 						    && !res)
2606 							res = -1;
2607 					}
2608 				if (ntfs_inode_close(dir_ni) && !res)
2609 					res = -1;
2610 				}
2611 			}
2612 		} else {
2613 			ntfs_inode_close_in_dir(ni,dir_ni);
2614 			ntfs_inode_close(dir_ni);
2615 		}
2616 	}
2617 	return (res);
2618 }
2619 
2620 
2621 /*
2622  *		Set the ntfs DOS name into an extended attribute
2623  *
2624  *  The DOS name will be added as another file name attribute
2625  *  using the existing file name information from the original
2626  *  name or overwriting the DOS Name if one exists.
2627  *
2628  *  	The inode of the file is always closed
2629  */
2630 
2631 int ntfs_set_ntfs_dos_name(ntfs_inode *ni, ntfs_inode *dir_ni,
2632 			const char *value, size_t size,	int flags)
2633 {
2634 	int res = 0;
2635 	int longlen = 0;
2636 	int shortlen = 0;
2637 	char newname[3*MAX_DOS_NAME_LENGTH + 1];
2638 	ntfschar oldname[MAX_DOS_NAME_LENGTH];
2639 	int oldlen;
2640 	u64 dnum;
2641 	BOOL closed = FALSE;
2642 	ntfschar *shortname = NULL;
2643 	ntfschar longname[NTFS_MAX_NAME_LEN];
2644 
2645 		/* copy the string to insert a null char, and truncate */
2646 	if (size > 3*MAX_DOS_NAME_LENGTH)
2647 		size = 3*MAX_DOS_NAME_LENGTH;
2648 	strncpy(newname, value, size);
2649 		/* a long name may be truncated badly and be untranslatable */
2650 	newname[size] = 0;
2651 		/* convert the string to the NTFS wide chars, and truncate */
2652 	shortlen = ntfs_mbstoucs(newname, &shortname);
2653 	if (shortlen > MAX_DOS_NAME_LENGTH)
2654 		shortlen = MAX_DOS_NAME_LENGTH;
2655 			/* make sure the short name has valid chars */
2656 	if ((shortlen < 0) || ntfs_forbidden_chars(shortname,shortlen)) {
2657 		ntfs_inode_close_in_dir(ni,dir_ni);
2658 		ntfs_inode_close(dir_ni);
2659 		res = -errno;
2660 		return res;
2661 	}
2662 	dnum = dir_ni->mft_no;
2663 	longlen = get_long_name(ni, dnum, longname);
2664 	if (longlen > 0) {
2665 		oldlen = get_dos_name(ni, dnum, oldname);
2666 		if ((oldlen >= 0)
2667 		    && !ntfs_forbidden_chars(longname, longlen)) {
2668 			if (oldlen > 0) {
2669 				if (flags & XATTR_CREATE) {
2670 					res = -1;
2671 					errno = EEXIST;
2672 				} else
2673 					if ((shortlen == oldlen)
2674 					    && !memcmp(shortname,oldname,
2675 						     oldlen*sizeof(ntfschar)))
2676 						/* already set, done */
2677 						res = 0;
2678 					else {
2679 						res = set_dos_name(ni, dir_ni,
2680 							shortname, shortlen,
2681 							longname, longlen,
2682 							oldname, oldlen, TRUE);
2683 						closed = TRUE;
2684 					}
2685 			} else {
2686 				if (flags & XATTR_REPLACE) {
2687 					res = -1;
2688 					errno = ENODATA;
2689 				} else {
2690 					res = set_dos_name(ni, dir_ni,
2691 						shortname, shortlen,
2692 						longname, longlen,
2693 						longname, longlen, FALSE);
2694 					closed = TRUE;
2695 				}
2696 			}
2697 		} else
2698 			res = -1;
2699 	} else {
2700 		res = -1;
2701 		if (!longlen)
2702 			errno = ENOENT;
2703 	}
2704 	free(shortname);
2705 	if (!closed) {
2706 		ntfs_inode_close_in_dir(ni,dir_ni);
2707 		ntfs_inode_close(dir_ni);
2708 	}
2709 	return (res ? -1 : 0);
2710 }
2711 
2712 /*
2713  *		Delete the ntfs DOS name
2714  */
2715 
2716 int ntfs_remove_ntfs_dos_name(ntfs_inode *ni, ntfs_inode *dir_ni)
2717 {
2718 	int res;
2719 	int oldnametype;
2720 	int longlen = 0;
2721 	int shortlen;
2722 	u64 dnum;
2723 	ntfs_volume *vol;
2724 	BOOL deleted = FALSE;
2725 	ntfschar shortname[MAX_DOS_NAME_LENGTH];
2726 	ntfschar longname[NTFS_MAX_NAME_LEN];
2727 
2728 	res = -1;
2729 	vol = ni->vol;
2730 	dnum = dir_ni->mft_no;
2731 	longlen = get_long_name(ni, dnum, longname);
2732 	if (longlen > 0) {
2733 		shortlen = get_dos_name(ni, dnum, shortname);
2734 		if (shortlen >= 0) {
2735 				/* migrate the long name as Posix */
2736 			oldnametype = set_namespace(ni,dir_ni,longname,longlen,
2737 					FILE_NAME_POSIX);
2738 			switch (oldnametype) {
2739 			case FILE_NAME_WIN32_AND_DOS :
2740 				/* name was Win32+DOS : done */
2741 				res = 0;
2742 				break;
2743 			case FILE_NAME_DOS :
2744 				/* name was DOS, make it back to DOS */
2745 				set_namespace(ni,dir_ni,longname,longlen,
2746 						FILE_NAME_DOS);
2747 				errno = ENOENT;
2748 				break;
2749 			case FILE_NAME_WIN32 :
2750 				/* name was Win32, make it Posix and delete */
2751 				if (set_namespace(ni,dir_ni,shortname,shortlen,
2752 						FILE_NAME_POSIX) >= 0) {
2753 					if (!ntfs_delete(vol,
2754 							(const char*)NULL, ni,
2755 							dir_ni, shortname,
2756 							shortlen))
2757 						res = 0;
2758 					deleted = TRUE;
2759 				} else {
2760 					/*
2761 					 * DOS name has been found, but cannot
2762 					 * migrate to Posix : something bad
2763 					 * has happened
2764 					 */
2765 					errno = EIO;
2766 					ntfs_log_error("Could not change"
2767 						" DOS name of inode %lld to Posix\n",
2768 						(long long)ni->mft_no);
2769 				}
2770 				break;
2771 			default :
2772 				/* name was Posix or not found : error */
2773 				errno = ENOENT;
2774 				break;
2775 			}
2776 		}
2777 	} else {
2778 		if (!longlen)
2779 			errno = ENOENT;
2780 		res = -1;
2781 	}
2782 	if (!deleted) {
2783 		ntfs_inode_close_in_dir(ni,dir_ni);
2784 		ntfs_inode_close(dir_ni);
2785 	}
2786 	return (res);
2787 }
2788 
2789 #endif
2790