xref: /haiku/src/add-ons/kernel/file_systems/ntfs/libntfs/dir.c (revision 7ee53ed3bd2222305c93a4959f8c587c373ed97c)
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  * ntfs_filldir - ntfs specific filldir method
872  * @dir_ni:	ntfs inode of current directory
873  * @pos:	current position in directory
874  * @ivcn_bits:	log(2) of index vcn size
875  * @index_type:	specifies whether @iu is an index root or an index allocation
876  * @iu:		index root or index block to which @ie belongs
877  * @ie:		current index entry
878  * @dirent:	context for filldir callback supplied by the caller
879  * @filldir:	filldir callback supplied by the caller
880  *
881  * Pass information specifying the current directory entry @ie to the @filldir
882  * callback.
883  */
884 static int ntfs_filldir(ntfs_inode *dir_ni, s64 *pos, u8 ivcn_bits,
885 		const INDEX_TYPE index_type, index_union iu, INDEX_ENTRY *ie,
886 		void *dirent, ntfs_filldir_t filldir)
887 {
888 	FILE_NAME_ATTR *fn = &ie->key.file_name;
889 	unsigned dt_type;
890 	BOOL metadata;
891 	ntfschar *loname;
892 	int res;
893 	MFT_REF mref;
894 
895 	ntfs_log_trace("Entering.\n");
896 
897 	/* Advance the position even if going to skip the entry. */
898 	if (index_type == INDEX_TYPE_ALLOCATION)
899 		*pos = (u8*)ie - (u8*)iu.ia + (sle64_to_cpu(
900 				iu.ia->index_block_vcn) << ivcn_bits) +
901 				dir_ni->vol->mft_record_size;
902 	else /* if (index_type == INDEX_TYPE_ROOT) */
903 		*pos = (u8*)ie - (u8*)iu.ir;
904 	/* Skip root directory self reference entry. */
905 	if (MREF_LE(ie->indexed_file) == FILE_root)
906 		return 0;
907 	if (ie->key.file_name.file_attributes & FILE_ATTR_I30_INDEX_PRESENT)
908 		dt_type = NTFS_DT_DIR;
909 	else if (fn->file_attributes & FILE_ATTR_SYSTEM)
910 		dt_type = NTFS_DT_UNKNOWN;
911 	else
912 		dt_type = NTFS_DT_REG;
913 
914 		/* return metadata files and hidden files if requested */
915 	mref = le64_to_cpu(ie->indexed_file);
916         metadata = (MREF(mref) != FILE_root) && (MREF(mref) < FILE_first_user);
917         if ((!metadata && (NVolShowHidFiles(dir_ni->vol)
918 				|| !(fn->file_attributes & FILE_ATTR_HIDDEN)))
919             || (NVolShowSysFiles(dir_ni->vol) && (NVolShowHidFiles(dir_ni->vol)
920 				|| metadata))) {
921 		if (NVolCaseSensitive(dir_ni->vol)) {
922 			res = filldir(dirent, fn->file_name,
923 					fn->file_name_length,
924 					fn->file_name_type, *pos,
925 					mref, dt_type);
926 		} else {
927 			loname = (ntfschar*)ntfs_malloc(2*fn->file_name_length);
928 			if (loname) {
929 				memcpy(loname, fn->file_name,
930 					2*fn->file_name_length);
931 				ntfs_name_locase(loname, fn->file_name_length,
932 					dir_ni->vol->locase,
933 					dir_ni->vol->upcase_len);
934 				res = filldir(dirent, loname,
935 					fn->file_name_length,
936 					fn->file_name_type, *pos,
937 					mref, dt_type);
938 				free(loname);
939 			} else
940 				res = -1;
941 		}
942 	} else
943 		res = 0;
944 	return (res);
945 }
946 
947 /**
948  * ntfs_mft_get_parent_ref - find mft reference of parent directory of an inode
949  * @ni:		ntfs inode whose parent directory to find
950  *
951  * Find the parent directory of the ntfs inode @ni. To do this, find the first
952  * file name attribute in the mft record of @ni and return the parent mft
953  * reference from that.
954  *
955  * Note this only makes sense for directories, since files can be hard linked
956  * from multiple directories and there is no way for us to tell which one is
957  * being looked for.
958  *
959  * Technically directories can have hard links, too, but we consider that as
960  * illegal as Linux/UNIX do not support directory hard links.
961  *
962  * Return the mft reference of the parent directory on success or -1 on error
963  * with errno set to the error code.
964  */
965 static MFT_REF ntfs_mft_get_parent_ref(ntfs_inode *ni)
966 {
967 	MFT_REF mref;
968 	ntfs_attr_search_ctx *ctx;
969 	FILE_NAME_ATTR *fn;
970 	int eo;
971 
972 	ntfs_log_trace("Entering.\n");
973 
974 	if (!ni) {
975 		errno = EINVAL;
976 		return ERR_MREF(-1);
977 	}
978 
979 	ctx = ntfs_attr_get_search_ctx(ni, NULL);
980 	if (!ctx)
981 		return ERR_MREF(-1);
982 	if (ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0, 0, 0, NULL, 0, ctx)) {
983 		ntfs_log_error("No file name found in inode %lld\n",
984 			       (unsigned long long)ni->mft_no);
985 		goto err_out;
986 	}
987 	if (ctx->attr->non_resident) {
988 		ntfs_log_error("File name attribute must be resident (inode "
989 			       "%lld)\n", (unsigned long long)ni->mft_no);
990 		goto io_err_out;
991 	}
992 	fn = (FILE_NAME_ATTR*)((u8*)ctx->attr +
993 			le16_to_cpu(ctx->attr->value_offset));
994 	if ((u8*)fn +	le32_to_cpu(ctx->attr->value_length) >
995 			(u8*)ctx->attr + le32_to_cpu(ctx->attr->length)) {
996 		ntfs_log_error("Corrupt file name attribute in inode %lld.\n",
997 			       (unsigned long long)ni->mft_no);
998 		goto io_err_out;
999 	}
1000 	mref = le64_to_cpu(fn->parent_directory);
1001 	ntfs_attr_put_search_ctx(ctx);
1002 	return mref;
1003 io_err_out:
1004 	errno = EIO;
1005 err_out:
1006 	eo = errno;
1007 	ntfs_attr_put_search_ctx(ctx);
1008 	errno = eo;
1009 	return ERR_MREF(-1);
1010 }
1011 
1012 /**
1013  * ntfs_readdir - read the contents of an ntfs directory
1014  * @dir_ni:	ntfs inode of current directory
1015  * @pos:	current position in directory
1016  * @dirent:	context for filldir callback supplied by the caller
1017  * @filldir:	filldir callback supplied by the caller
1018  *
1019  * Parse the index root and the index blocks that are marked in use in the
1020  * index bitmap and hand each found directory entry to the @filldir callback
1021  * supplied by the caller.
1022  *
1023  * Return 0 on success or -1 on error with errno set to the error code.
1024  *
1025  * Note: Index blocks are parsed in ascending vcn order, from which follows
1026  * that the directory entries are not returned sorted.
1027  */
1028 int ntfs_readdir(ntfs_inode *dir_ni, s64 *pos,
1029 		void *dirent, ntfs_filldir_t filldir)
1030 {
1031 	s64 i_size, br, ia_pos, bmp_pos, ia_start;
1032 	ntfs_volume *vol;
1033 	ntfs_attr *ia_na, *bmp_na = NULL;
1034 	ntfs_attr_search_ctx *ctx = NULL;
1035 	u8 *index_end, *bmp = NULL;
1036 	INDEX_ROOT *ir;
1037 	INDEX_ENTRY *ie;
1038 	INDEX_ALLOCATION *ia = NULL;
1039 	int rc, ir_pos, bmp_buf_size, bmp_buf_pos, eo;
1040 	u32 index_block_size;
1041 	u8 index_block_size_bits, index_vcn_size_bits;
1042 
1043 	ntfs_log_trace("Entering.\n");
1044 
1045 	if (!dir_ni || !pos || !filldir) {
1046 		errno = EINVAL;
1047 		return -1;
1048 	}
1049 
1050 	if (!(dir_ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)) {
1051 		errno = ENOTDIR;
1052 		return -1;
1053 	}
1054 
1055 	vol = dir_ni->vol;
1056 
1057 	ntfs_log_trace("Entering for inode %lld, *pos 0x%llx.\n",
1058 			(unsigned long long)dir_ni->mft_no, (long long)*pos);
1059 
1060 	/* Open the index allocation attribute. */
1061 	ia_na = ntfs_attr_open(dir_ni, AT_INDEX_ALLOCATION, NTFS_INDEX_I30, 4);
1062 	if (!ia_na) {
1063 		if (errno != ENOENT) {
1064 			ntfs_log_perror("Failed to open index allocation attribute. "
1065 				"Directory inode %lld is corrupt or bug",
1066 				(unsigned long long)dir_ni->mft_no);
1067 			return -1;
1068 		}
1069 		i_size = 0;
1070 	} else
1071 		i_size = ia_na->data_size;
1072 
1073 	rc = 0;
1074 
1075 	/* Are we at end of dir yet? */
1076 	if (*pos >= i_size + vol->mft_record_size)
1077 		goto done;
1078 
1079 	/* Emulate . and .. for all directories. */
1080 	if (!*pos) {
1081 		rc = filldir(dirent, dotdot, 1, FILE_NAME_POSIX, *pos,
1082 				MK_MREF(dir_ni->mft_no,
1083 				le16_to_cpu(dir_ni->mrec->sequence_number)),
1084 				NTFS_DT_DIR);
1085 		if (rc)
1086 			goto err_out;
1087 		++*pos;
1088 	}
1089 	if (*pos == 1) {
1090 		MFT_REF parent_mref;
1091 
1092 		parent_mref = ntfs_mft_get_parent_ref(dir_ni);
1093 		if (parent_mref == ERR_MREF(-1)) {
1094 			ntfs_log_perror("Parent directory not found");
1095 			goto dir_err_out;
1096 		}
1097 
1098 		rc = filldir(dirent, dotdot, 2, FILE_NAME_POSIX, *pos,
1099 				parent_mref, NTFS_DT_DIR);
1100 		if (rc)
1101 			goto err_out;
1102 		++*pos;
1103 	}
1104 
1105 	ctx = ntfs_attr_get_search_ctx(dir_ni, NULL);
1106 	if (!ctx)
1107 		goto err_out;
1108 
1109 	/* Get the offset into the index root attribute. */
1110 	ir_pos = (int)*pos;
1111 	/* Find the index root attribute in the mft record. */
1112 	if (ntfs_attr_lookup(AT_INDEX_ROOT, NTFS_INDEX_I30, 4, CASE_SENSITIVE, 0, NULL,
1113 			0, ctx)) {
1114 		ntfs_log_perror("Index root attribute missing in directory inode "
1115 				"%lld", (unsigned long long)dir_ni->mft_no);
1116 		goto dir_err_out;
1117 	}
1118 	/* Get to the index root value. */
1119 	ir = (INDEX_ROOT*)((u8*)ctx->attr +
1120 			le16_to_cpu(ctx->attr->value_offset));
1121 
1122 	/* Determine the size of a vcn in the directory index. */
1123 	index_block_size = le32_to_cpu(ir->index_block_size);
1124 	if (index_block_size < NTFS_BLOCK_SIZE ||
1125 			index_block_size & (index_block_size - 1)) {
1126 		ntfs_log_error("Index block size %u is invalid.\n",
1127 				(unsigned)index_block_size);
1128 		goto dir_err_out;
1129 	}
1130 	index_block_size_bits = ffs(index_block_size) - 1;
1131 	if (vol->cluster_size <= index_block_size) {
1132 		index_vcn_size_bits = vol->cluster_size_bits;
1133 	} else {
1134 		index_vcn_size_bits = NTFS_BLOCK_SIZE_BITS;
1135 	}
1136 
1137 	/* Are we jumping straight into the index allocation attribute? */
1138 	if (*pos >= vol->mft_record_size) {
1139 		ntfs_attr_put_search_ctx(ctx);
1140 		ctx = NULL;
1141 		goto skip_index_root;
1142 	}
1143 
1144 	index_end = (u8*)&ir->index + le32_to_cpu(ir->index.index_length);
1145 	/* The first index entry. */
1146 	ie = (INDEX_ENTRY*)((u8*)&ir->index +
1147 			le32_to_cpu(ir->index.entries_offset));
1148 	/*
1149 	 * Loop until we exceed valid memory (corruption case) or until we
1150 	 * reach the last entry or until filldir tells us it has had enough
1151 	 * or signals an error (both covered by the rc test).
1152 	 */
1153 	for (;; ie = (INDEX_ENTRY*)((u8*)ie + le16_to_cpu(ie->length))) {
1154 		ntfs_log_debug("In index root, offset %d.\n", (int)((u8*)ie - (u8*)ir));
1155 		/* Bounds checks. */
1156 		if ((u8*)ie < (u8*)ctx->mrec || (u8*)ie +
1157 				sizeof(INDEX_ENTRY_HEADER) > index_end ||
1158 				(u8*)ie + le16_to_cpu(ie->key_length) >
1159 				index_end)
1160 			goto dir_err_out;
1161 		/* The last entry cannot contain a name. */
1162 		if (ie->ie_flags & INDEX_ENTRY_END)
1163 			break;
1164 
1165 		if (!le16_to_cpu(ie->length))
1166 			goto dir_err_out;
1167 
1168 		/* Skip index root entry if continuing previous readdir. */
1169 		if (ir_pos > (u8*)ie - (u8*)ir)
1170 			continue;
1171 		/*
1172 		 * Submit the directory entry to ntfs_filldir(), which will
1173 		 * invoke the filldir() callback as appropriate.
1174 		 */
1175 		rc = ntfs_filldir(dir_ni, pos, index_vcn_size_bits,
1176 				INDEX_TYPE_ROOT, ir, ie, dirent, filldir);
1177 		if (rc) {
1178 			ntfs_attr_put_search_ctx(ctx);
1179 			ctx = NULL;
1180 			goto err_out;
1181 		}
1182 	}
1183 	ntfs_attr_put_search_ctx(ctx);
1184 	ctx = NULL;
1185 
1186 	/* If there is no index allocation attribute we are finished. */
1187 	if (!ia_na)
1188 		goto EOD;
1189 
1190 	/* Advance *pos to the beginning of the index allocation. */
1191 	*pos = vol->mft_record_size;
1192 
1193 skip_index_root:
1194 
1195 	if (!ia_na)
1196 		goto done;
1197 
1198 	/* Allocate a buffer for the current index block. */
1199 	ia = ntfs_malloc(index_block_size);
1200 	if (!ia)
1201 		goto err_out;
1202 
1203 	bmp_na = ntfs_attr_open(dir_ni, AT_BITMAP, NTFS_INDEX_I30, 4);
1204 	if (!bmp_na) {
1205 		ntfs_log_perror("Failed to open index bitmap attribute");
1206 		goto dir_err_out;
1207 	}
1208 
1209 	/* Get the offset into the index allocation attribute. */
1210 	ia_pos = *pos - vol->mft_record_size;
1211 
1212 	bmp_pos = ia_pos >> index_block_size_bits;
1213 	if (bmp_pos >> 3 >= bmp_na->data_size) {
1214 		ntfs_log_error("Current index position exceeds index bitmap "
1215 				"size.\n");
1216 		goto dir_err_out;
1217 	}
1218 
1219 	bmp_buf_size = min(bmp_na->data_size - (bmp_pos >> 3), 4096);
1220 	bmp = ntfs_malloc(bmp_buf_size);
1221 	if (!bmp)
1222 		goto err_out;
1223 
1224 	br = ntfs_attr_pread(bmp_na, bmp_pos >> 3, bmp_buf_size, bmp);
1225 	if (br != bmp_buf_size) {
1226 		if (br != -1)
1227 			errno = EIO;
1228 		ntfs_log_perror("Failed to read from index bitmap attribute");
1229 		goto err_out;
1230 	}
1231 
1232 	bmp_buf_pos = 0;
1233 	/* If the index block is not in use find the next one that is. */
1234 	while (!(bmp[bmp_buf_pos >> 3] & (1 << (bmp_buf_pos & 7)))) {
1235 find_next_index_buffer:
1236 		bmp_pos++;
1237 		bmp_buf_pos++;
1238 		/* If we have reached the end of the bitmap, we are done. */
1239 		if (bmp_pos >> 3 >= bmp_na->data_size)
1240 			goto EOD;
1241 		ia_pos = bmp_pos << index_block_size_bits;
1242 		if (bmp_buf_pos >> 3 < bmp_buf_size)
1243 			continue;
1244 		/* Read next chunk from the index bitmap. */
1245 		bmp_buf_pos = 0;
1246 		if ((bmp_pos >> 3) + bmp_buf_size > bmp_na->data_size)
1247 			bmp_buf_size = bmp_na->data_size - (bmp_pos >> 3);
1248 		br = ntfs_attr_pread(bmp_na, bmp_pos >> 3, bmp_buf_size, bmp);
1249 		if (br != bmp_buf_size) {
1250 			if (br != -1)
1251 				errno = EIO;
1252 			ntfs_log_perror("Failed to read from index bitmap attribute");
1253 			goto err_out;
1254 		}
1255 	}
1256 
1257 	ntfs_log_debug("Handling index block 0x%llx.\n", (long long)bmp_pos);
1258 
1259 	/* Read the index block starting at bmp_pos. */
1260 	br = ntfs_attr_mst_pread(ia_na, bmp_pos << index_block_size_bits, 1,
1261 			index_block_size, ia);
1262 	if (br != 1) {
1263 		if (br != -1)
1264 			errno = EIO;
1265 		ntfs_log_perror("Failed to read index block");
1266 		goto err_out;
1267 	}
1268 
1269 	ia_start = ia_pos & ~(s64)(index_block_size - 1);
1270 	if (sle64_to_cpu(ia->index_block_vcn) != ia_start >>
1271 			index_vcn_size_bits) {
1272 		ntfs_log_error("Actual VCN (0x%llx) of index buffer is different "
1273 				"from expected VCN (0x%llx) in inode 0x%llx.\n",
1274 				(long long)sle64_to_cpu(ia->index_block_vcn),
1275 				(long long)ia_start >> index_vcn_size_bits,
1276 				(unsigned long long)dir_ni->mft_no);
1277 		goto dir_err_out;
1278 	}
1279 	if (le32_to_cpu(ia->index.allocated_size) + 0x18 != index_block_size) {
1280 		ntfs_log_error("Index buffer (VCN 0x%llx) of directory inode %lld "
1281 				"has a size (%u) differing from the directory "
1282 				"specified size (%u).\n", (long long)ia_start >>
1283 				index_vcn_size_bits,
1284 				(unsigned long long)dir_ni->mft_no,
1285 				(unsigned) le32_to_cpu(ia->index.allocated_size)
1286 				+ 0x18, (unsigned)index_block_size);
1287 		goto dir_err_out;
1288 	}
1289 	index_end = (u8*)&ia->index + le32_to_cpu(ia->index.index_length);
1290 	if (index_end > (u8*)ia + index_block_size) {
1291 		ntfs_log_error("Size of index buffer (VCN 0x%llx) of directory inode "
1292 				"%lld exceeds maximum size.\n",
1293 				(long long)ia_start >> index_vcn_size_bits,
1294 				(unsigned long long)dir_ni->mft_no);
1295 		goto dir_err_out;
1296 	}
1297 	/* The first index entry. */
1298 	ie = (INDEX_ENTRY*)((u8*)&ia->index +
1299 			le32_to_cpu(ia->index.entries_offset));
1300 	/*
1301 	 * Loop until we exceed valid memory (corruption case) or until we
1302 	 * reach the last entry or until ntfs_filldir tells us it has had
1303 	 * enough or signals an error (both covered by the rc test).
1304 	 */
1305 	for (;; ie = (INDEX_ENTRY*)((u8*)ie + le16_to_cpu(ie->length))) {
1306 		ntfs_log_debug("In index allocation, offset 0x%llx.\n",
1307 				(long long)ia_start + ((u8*)ie - (u8*)ia));
1308 		/* Bounds checks. */
1309 		if ((u8*)ie < (u8*)ia || (u8*)ie +
1310 				sizeof(INDEX_ENTRY_HEADER) > index_end ||
1311 				(u8*)ie + le16_to_cpu(ie->key_length) >
1312 				index_end) {
1313 			ntfs_log_error("Index entry out of bounds in directory inode "
1314 				"%lld.\n", (unsigned long long)dir_ni->mft_no);
1315 			goto dir_err_out;
1316 		}
1317 		/* The last entry cannot contain a name. */
1318 		if (ie->ie_flags & INDEX_ENTRY_END)
1319 			break;
1320 
1321 		if (!le16_to_cpu(ie->length))
1322 			goto dir_err_out;
1323 
1324 		/* Skip index entry if continuing previous readdir. */
1325 		if (ia_pos - ia_start > (u8*)ie - (u8*)ia)
1326 			continue;
1327 		/*
1328 		 * Submit the directory entry to ntfs_filldir(), which will
1329 		 * invoke the filldir() callback as appropriate.
1330 		 */
1331 		rc = ntfs_filldir(dir_ni, pos, index_vcn_size_bits,
1332 				INDEX_TYPE_ALLOCATION, ia, ie, dirent, filldir);
1333 		if (rc)
1334 			goto err_out;
1335 	}
1336 	goto find_next_index_buffer;
1337 EOD:
1338 	/* We are finished, set *pos to EOD. */
1339 	*pos = i_size + vol->mft_record_size;
1340 done:
1341 	free(ia);
1342 	free(bmp);
1343 	if (bmp_na)
1344 		ntfs_attr_close(bmp_na);
1345 	if (ia_na)
1346 		ntfs_attr_close(ia_na);
1347 	ntfs_log_debug("EOD, *pos 0x%llx, returning 0.\n", (long long)*pos);
1348 	return 0;
1349 dir_err_out:
1350 	errno = EIO;
1351 err_out:
1352 	eo = errno;
1353 	ntfs_log_trace("failed.\n");
1354 	if (ctx)
1355 		ntfs_attr_put_search_ctx(ctx);
1356 	free(ia);
1357 	free(bmp);
1358 	if (bmp_na)
1359 		ntfs_attr_close(bmp_na);
1360 	if (ia_na)
1361 		ntfs_attr_close(ia_na);
1362 	errno = eo;
1363 	return -1;
1364 }
1365 
1366 
1367 /**
1368  * __ntfs_create - create object on ntfs volume
1369  * @dir_ni:	ntfs inode for directory in which create new object
1370  * @securid:	id of inheritable security descriptor, 0 if none
1371  * @name:	unicode name of new object
1372  * @name_len:	length of the name in unicode characters
1373  * @type:	type of the object to create
1374  * @dev:	major and minor device numbers (obtained from makedev())
1375  * @target:	target in unicode (only for symlinks)
1376  * @target_len:	length of target in unicode characters
1377  *
1378  * Internal, use ntfs_create{,_device,_symlink} wrappers instead.
1379  *
1380  * @type can be:
1381  *	S_IFREG		to create regular file
1382  *	S_IFDIR		to create directory
1383  *	S_IFBLK		to create block device
1384  *	S_IFCHR		to create character device
1385  *	S_IFLNK		to create symbolic link
1386  *	S_IFIFO		to create FIFO
1387  *	S_IFSOCK	to create socket
1388  * other values are invalid.
1389  *
1390  * @dev is used only if @type is S_IFBLK or S_IFCHR, in other cases its value
1391  * ignored.
1392  *
1393  * @target and @target_len are used only if @type is S_IFLNK, in other cases
1394  * their value ignored.
1395  *
1396  * Return opened ntfs inode that describes created object on success or NULL
1397  * on error with errno set to the error code.
1398  */
1399 static ntfs_inode *__ntfs_create(ntfs_inode *dir_ni, le32 securid,
1400 		ntfschar *name, u8 name_len, mode_t type, dev_t dev,
1401 		ntfschar *target, int target_len)
1402 {
1403 	ntfs_inode *ni;
1404 	int rollback_data = 0, rollback_sd = 0;
1405 	FILE_NAME_ATTR *fn = NULL;
1406 	STANDARD_INFORMATION *si = NULL;
1407 	int err, fn_len, si_len;
1408 
1409 	ntfs_log_trace("Entering.\n");
1410 
1411 	/* Sanity checks. */
1412 	if (!dir_ni || !name || !name_len) {
1413 		ntfs_log_error("Invalid arguments.\n");
1414 		errno = EINVAL;
1415 		return NULL;
1416 	}
1417 
1418 	if (dir_ni->flags & FILE_ATTR_REPARSE_POINT) {
1419 		errno = EOPNOTSUPP;
1420 		return NULL;
1421 	}
1422 
1423 	ni = ntfs_mft_record_alloc(dir_ni->vol, NULL);
1424 	if (!ni)
1425 		return NULL;
1426 #if CACHE_NIDATA_SIZE
1427 	ntfs_inode_invalidate(dir_ni->vol, ni->mft_no);
1428 #endif
1429 	/*
1430 	 * Create STANDARD_INFORMATION attribute.
1431 	 * JPA Depending on available inherited security descriptor,
1432 	 * Write STANDARD_INFORMATION v1.2 (no inheritance) or v3
1433 	 */
1434 	if (securid)
1435 		si_len = sizeof(STANDARD_INFORMATION);
1436 	else
1437 		si_len = offsetof(STANDARD_INFORMATION, v1_end);
1438 	si = ntfs_calloc(si_len);
1439 	if (!si) {
1440 		err = errno;
1441 		goto err_out;
1442 	}
1443 	si->creation_time = ni->creation_time;
1444 	si->last_data_change_time = ni->last_data_change_time;
1445 	si->last_mft_change_time = ni->last_mft_change_time;
1446 	si->last_access_time = ni->last_access_time;
1447 	if (securid) {
1448 		set_nino_flag(ni, v3_Extensions);
1449 		ni->owner_id = si->owner_id = 0;
1450 		ni->security_id = si->security_id = securid;
1451 		ni->quota_charged = si->quota_charged = const_cpu_to_le64(0);
1452 		ni->usn = si->usn = const_cpu_to_le64(0);
1453 	} else
1454 		clear_nino_flag(ni, v3_Extensions);
1455 	if (!S_ISREG(type) && !S_ISDIR(type)) {
1456 		si->file_attributes = FILE_ATTR_SYSTEM;
1457 		ni->flags = FILE_ATTR_SYSTEM;
1458 	}
1459 	ni->flags |= FILE_ATTR_ARCHIVE;
1460 	if (NVolHideDotFiles(dir_ni->vol)
1461 	    && (name_len > 1)
1462 	    && (name[0] == const_cpu_to_le16('.'))
1463 	    && (name[1] != const_cpu_to_le16('.')))
1464 		ni->flags |= FILE_ATTR_HIDDEN;
1465 		/*
1466 		 * Set compression flag according to parent directory
1467 		 * unless NTFS version < 3.0 or cluster size > 4K
1468 		 * or compression has been disabled
1469 		 */
1470 	if ((dir_ni->flags & FILE_ATTR_COMPRESSED)
1471 	   && (dir_ni->vol->major_ver >= 3)
1472 	   && NVolCompression(dir_ni->vol)
1473 	   && (dir_ni->vol->cluster_size <= MAX_COMPRESSION_CLUSTER_SIZE)
1474 	   && (S_ISREG(type) || S_ISDIR(type)))
1475 		ni->flags |= FILE_ATTR_COMPRESSED;
1476 	/* Add STANDARD_INFORMATION to inode. */
1477 	if (ntfs_attr_add(ni, AT_STANDARD_INFORMATION, AT_UNNAMED, 0,
1478 			(u8*)si, si_len)) {
1479 		err = errno;
1480 		ntfs_log_error("Failed to add STANDARD_INFORMATION "
1481 				"attribute.\n");
1482 		goto err_out;
1483 	}
1484 
1485 	if (!securid) {
1486 		if (ntfs_sd_add_everyone(ni)) {
1487 			err = errno;
1488 			goto err_out;
1489 		}
1490 	}
1491 	rollback_sd = 1;
1492 
1493 	if (S_ISDIR(type)) {
1494 		INDEX_ROOT *ir = NULL;
1495 		INDEX_ENTRY *ie;
1496 		int ir_len, index_len;
1497 
1498 		/* Create INDEX_ROOT attribute. */
1499 		index_len = sizeof(INDEX_HEADER) + sizeof(INDEX_ENTRY_HEADER);
1500 		ir_len = offsetof(INDEX_ROOT, index) + index_len;
1501 		ir = ntfs_calloc(ir_len);
1502 		if (!ir) {
1503 			err = errno;
1504 			goto err_out;
1505 		}
1506 		ir->type = AT_FILE_NAME;
1507 		ir->collation_rule = COLLATION_FILE_NAME;
1508 		ir->index_block_size = cpu_to_le32(ni->vol->indx_record_size);
1509 		if (ni->vol->cluster_size <= ni->vol->indx_record_size)
1510 			ir->clusters_per_index_block =
1511 					ni->vol->indx_record_size >>
1512 					ni->vol->cluster_size_bits;
1513 		else
1514 			ir->clusters_per_index_block =
1515 					ni->vol->indx_record_size >>
1516 					NTFS_BLOCK_SIZE_BITS;
1517 		ir->index.entries_offset = cpu_to_le32(sizeof(INDEX_HEADER));
1518 		ir->index.index_length = cpu_to_le32(index_len);
1519 		ir->index.allocated_size = cpu_to_le32(index_len);
1520 		ie = (INDEX_ENTRY*)((u8*)ir + sizeof(INDEX_ROOT));
1521 		ie->length = cpu_to_le16(sizeof(INDEX_ENTRY_HEADER));
1522 		ie->key_length = 0;
1523 		ie->ie_flags = INDEX_ENTRY_END;
1524 		/* Add INDEX_ROOT attribute to inode. */
1525 		if (ntfs_attr_add(ni, AT_INDEX_ROOT, NTFS_INDEX_I30, 4,
1526 				(u8*)ir, ir_len)) {
1527 			err = errno;
1528 			free(ir);
1529 			ntfs_log_error("Failed to add INDEX_ROOT attribute.\n");
1530 			goto err_out;
1531 		}
1532 		free(ir);
1533 	} else {
1534 		INTX_FILE *data;
1535 		int data_len;
1536 
1537 		switch (type) {
1538 			case S_IFBLK:
1539 			case S_IFCHR:
1540 				data_len = offsetof(INTX_FILE, device_end);
1541 				data = ntfs_malloc(data_len);
1542 				if (!data) {
1543 					err = errno;
1544 					goto err_out;
1545 				}
1546 				data->major = cpu_to_le64(major(dev));
1547 				data->minor = cpu_to_le64(minor(dev));
1548 				if (type == S_IFBLK)
1549 					data->magic = INTX_BLOCK_DEVICE;
1550 				if (type == S_IFCHR)
1551 					data->magic = INTX_CHARACTER_DEVICE;
1552 				break;
1553 			case S_IFLNK:
1554 				data_len = sizeof(INTX_FILE_TYPES) +
1555 						target_len * sizeof(ntfschar);
1556 				data = ntfs_malloc(data_len);
1557 				if (!data) {
1558 					err = errno;
1559 					goto err_out;
1560 				}
1561 				data->magic = INTX_SYMBOLIC_LINK;
1562 				memcpy(data->target, target,
1563 						target_len * sizeof(ntfschar));
1564 				break;
1565 			case S_IFSOCK:
1566 				data = NULL;
1567 				data_len = 1;
1568 				break;
1569 			default: /* FIFO or regular file. */
1570 				data = NULL;
1571 				data_len = 0;
1572 				break;
1573 		}
1574 		/* Add DATA attribute to inode. */
1575 		if (ntfs_attr_add(ni, AT_DATA, AT_UNNAMED, 0, (u8*)data,
1576 				data_len)) {
1577 			err = errno;
1578 			ntfs_log_error("Failed to add DATA attribute.\n");
1579 			free(data);
1580 			goto err_out;
1581 		}
1582 		rollback_data = 1;
1583 		free(data);
1584 	}
1585 	/* Create FILE_NAME attribute. */
1586 	fn_len = sizeof(FILE_NAME_ATTR) + name_len * sizeof(ntfschar);
1587 	fn = ntfs_calloc(fn_len);
1588 	if (!fn) {
1589 		err = errno;
1590 		goto err_out;
1591 	}
1592 	fn->parent_directory = MK_LE_MREF(dir_ni->mft_no,
1593 			le16_to_cpu(dir_ni->mrec->sequence_number));
1594 	fn->file_name_length = name_len;
1595 	fn->file_name_type = FILE_NAME_POSIX;
1596 	if (S_ISDIR(type))
1597 		fn->file_attributes = FILE_ATTR_I30_INDEX_PRESENT;
1598 	if (!S_ISREG(type) && !S_ISDIR(type))
1599 		fn->file_attributes = FILE_ATTR_SYSTEM;
1600 	else
1601 		fn->file_attributes |= ni->flags & FILE_ATTR_COMPRESSED;
1602 	fn->file_attributes |= FILE_ATTR_ARCHIVE;
1603 	fn->file_attributes |= ni->flags & FILE_ATTR_HIDDEN;
1604 	fn->creation_time = ni->creation_time;
1605 	fn->last_data_change_time = ni->last_data_change_time;
1606 	fn->last_mft_change_time = ni->last_mft_change_time;
1607 	fn->last_access_time = ni->last_access_time;
1608 	if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)
1609 		fn->data_size = fn->allocated_size = const_cpu_to_le64(0);
1610 	else {
1611 		fn->data_size = cpu_to_sle64(ni->data_size);
1612 		fn->allocated_size = cpu_to_sle64(ni->allocated_size);
1613 	}
1614 	memcpy(fn->file_name, name, name_len * sizeof(ntfschar));
1615 	/* Add FILE_NAME attribute to inode. */
1616 	if (ntfs_attr_add(ni, AT_FILE_NAME, AT_UNNAMED, 0, (u8*)fn, fn_len)) {
1617 		err = errno;
1618 		ntfs_log_error("Failed to add FILE_NAME attribute.\n");
1619 		goto err_out;
1620 	}
1621 	/* Add FILE_NAME attribute to index. */
1622 	if (ntfs_index_add_filename(dir_ni, fn, MK_MREF(ni->mft_no,
1623 			le16_to_cpu(ni->mrec->sequence_number)))) {
1624 		err = errno;
1625 		ntfs_log_perror("Failed to add entry to the index");
1626 		goto err_out;
1627 	}
1628 	/* Set hard links count and directory flag. */
1629 	ni->mrec->link_count = cpu_to_le16(1);
1630 	if (S_ISDIR(type))
1631 		ni->mrec->flags |= MFT_RECORD_IS_DIRECTORY;
1632 	ntfs_inode_mark_dirty(ni);
1633 	/* Done! */
1634 	free(fn);
1635 	free(si);
1636 	ntfs_log_trace("Done.\n");
1637 	return ni;
1638 err_out:
1639 	ntfs_log_trace("Failed.\n");
1640 
1641 	if (rollback_sd)
1642 		ntfs_attr_remove(ni, AT_SECURITY_DESCRIPTOR, AT_UNNAMED, 0);
1643 
1644 	if (rollback_data)
1645 		ntfs_attr_remove(ni, AT_DATA, AT_UNNAMED, 0);
1646 	/*
1647 	 * Free extent MFT records (should not exist any with current
1648 	 * ntfs_create implementation, but for any case if something will be
1649 	 * changed in the future).
1650 	 */
1651 	while (ni->nr_extents)
1652 		if (ntfs_mft_record_free(ni->vol, *(ni->extent_nis))) {
1653 			err = errno;
1654 			ntfs_log_error("Failed to free extent MFT record.  "
1655 					"Leaving inconsistent metadata.\n");
1656 		}
1657 	if (ntfs_mft_record_free(ni->vol, ni))
1658 		ntfs_log_error("Failed to free MFT record.  "
1659 				"Leaving inconsistent metadata. Run chkdsk.\n");
1660 	free(fn);
1661 	free(si);
1662 	errno = err;
1663 	return NULL;
1664 }
1665 
1666 /**
1667  * Some wrappers around __ntfs_create() ...
1668  */
1669 
1670 ntfs_inode *ntfs_create(ntfs_inode *dir_ni, le32 securid, ntfschar *name,
1671 		u8 name_len, mode_t type)
1672 {
1673 	if (type != S_IFREG && type != S_IFDIR && type != S_IFIFO &&
1674 			type != S_IFSOCK) {
1675 		ntfs_log_error("Invalid arguments.\n");
1676 		return NULL;
1677 	}
1678 	return __ntfs_create(dir_ni, securid, name, name_len, type, 0, NULL, 0);
1679 }
1680 
1681 ntfs_inode *ntfs_create_device(ntfs_inode *dir_ni, le32 securid,
1682 		ntfschar *name, u8 name_len, mode_t type, dev_t dev)
1683 {
1684 	if (type != S_IFCHR && type != S_IFBLK) {
1685 		ntfs_log_error("Invalid arguments.\n");
1686 		return NULL;
1687 	}
1688 	return __ntfs_create(dir_ni, securid, name, name_len, type, dev, NULL, 0);
1689 }
1690 
1691 ntfs_inode *ntfs_create_symlink(ntfs_inode *dir_ni, le32 securid,
1692 		ntfschar *name, u8 name_len, ntfschar *target, int target_len)
1693 {
1694 	if (!target || !target_len) {
1695 		ntfs_log_error("%s: Invalid argument (%p, %d)\n", __FUNCTION__,
1696 			       target, target_len);
1697 		return NULL;
1698 	}
1699 	return __ntfs_create(dir_ni, securid, name, name_len, S_IFLNK, 0,
1700 			target, target_len);
1701 }
1702 
1703 int ntfs_check_empty_dir(ntfs_inode *ni)
1704 {
1705 	ntfs_attr *na;
1706 	int ret = 0;
1707 
1708 	if (!(ni->mrec->flags & MFT_RECORD_IS_DIRECTORY))
1709 		return 0;
1710 
1711 	na = ntfs_attr_open(ni, AT_INDEX_ROOT, NTFS_INDEX_I30, 4);
1712 	if (!na) {
1713 		errno = EIO;
1714 		ntfs_log_perror("Failed to open directory");
1715 		return -1;
1716 	}
1717 
1718 	/* Non-empty directory? */
1719 	if ((na->data_size != sizeof(INDEX_ROOT) + sizeof(INDEX_ENTRY_HEADER))){
1720 		/* Both ENOTEMPTY and EEXIST are ok. We use the more common. */
1721 		errno = ENOTEMPTY;
1722 		ntfs_log_debug("Directory is not empty\n");
1723 		ret = -1;
1724 	}
1725 
1726 	ntfs_attr_close(na);
1727 	return ret;
1728 }
1729 
1730 static int ntfs_check_unlinkable_dir(ntfs_inode *ni, FILE_NAME_ATTR *fn)
1731 {
1732 	int link_count = le16_to_cpu(ni->mrec->link_count);
1733 	int ret;
1734 
1735 	ret = ntfs_check_empty_dir(ni);
1736 	if (!ret || errno != ENOTEMPTY)
1737 		return ret;
1738 	/*
1739 	 * Directory is non-empty, so we can unlink only if there is more than
1740 	 * one "real" hard link, i.e. links aren't different DOS and WIN32 names
1741 	 */
1742 	if ((link_count == 1) ||
1743 	    (link_count == 2 && fn->file_name_type == FILE_NAME_DOS)) {
1744 		errno = ENOTEMPTY;
1745 		ntfs_log_debug("Non-empty directory without hard links\n");
1746 		goto no_hardlink;
1747 	}
1748 
1749 	ret = 0;
1750 no_hardlink:
1751 	return ret;
1752 }
1753 
1754 /**
1755  * ntfs_delete - delete file or directory from ntfs volume
1756  * @ni:		ntfs inode for object to delte
1757  * @dir_ni:	ntfs inode for directory in which delete object
1758  * @name:	unicode name of the object to delete
1759  * @name_len:	length of the name in unicode characters
1760  *
1761  * @ni is always closed after the call to this function (even if it failed),
1762  * user does not need to call ntfs_inode_close himself.
1763  *
1764  * Return 0 on success or -1 on error with errno set to the error code.
1765  */
1766 int ntfs_delete(ntfs_volume *vol, const char *pathname,
1767 		ntfs_inode *ni, ntfs_inode *dir_ni, ntfschar *name, u8 name_len)
1768 {
1769 	ntfs_attr_search_ctx *actx = NULL;
1770 	FILE_NAME_ATTR *fn = NULL;
1771 	BOOL looking_for_dos_name = FALSE, looking_for_win32_name = FALSE;
1772 	BOOL case_sensitive_match = TRUE;
1773 	int err = 0;
1774 #if CACHE_NIDATA_SIZE
1775 	int i;
1776 #endif
1777 #if CACHE_INODE_SIZE
1778 	struct CACHED_INODE item;
1779 	const char *p;
1780 	u64 inum = (u64)-1;
1781 	int count;
1782 #endif
1783 #if CACHE_LOOKUP_SIZE
1784 	struct CACHED_LOOKUP lkitem;
1785 #endif
1786 
1787 	ntfs_log_trace("Entering.\n");
1788 
1789 	if (!ni || !dir_ni || !name || !name_len) {
1790 		ntfs_log_error("Invalid arguments.\n");
1791 		errno = EINVAL;
1792 		goto err_out;
1793 	}
1794 	if (ni->nr_extents == -1)
1795 		ni = ni->base_ni;
1796 	if (dir_ni->nr_extents == -1)
1797 		dir_ni = dir_ni->base_ni;
1798 	/*
1799 	 * Search for FILE_NAME attribute with such name. If it's in POSIX or
1800 	 * WIN32_AND_DOS namespace, then simply remove it from index and inode.
1801 	 * If filename in DOS or in WIN32 namespace, then remove DOS name first,
1802 	 * only then remove WIN32 name.
1803 	 */
1804 	actx = ntfs_attr_get_search_ctx(ni, NULL);
1805 	if (!actx)
1806 		goto err_out;
1807 search:
1808 	while (!ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0, CASE_SENSITIVE,
1809 			0, NULL, 0, actx)) {
1810 		char *s;
1811 		IGNORE_CASE_BOOL case_sensitive = IGNORE_CASE;
1812 
1813 		errno = 0;
1814 		fn = (FILE_NAME_ATTR*)((u8*)actx->attr +
1815 				le16_to_cpu(actx->attr->value_offset));
1816 		s = ntfs_attr_name_get(fn->file_name, fn->file_name_length);
1817 		ntfs_log_trace("name: '%s'  type: %d  dos: %d  win32: %d  "
1818 			       "case: %d\n", s, fn->file_name_type,
1819 			       looking_for_dos_name, looking_for_win32_name,
1820 			       case_sensitive_match);
1821 		ntfs_attr_name_free(&s);
1822 		if (looking_for_dos_name) {
1823 			if (fn->file_name_type == FILE_NAME_DOS)
1824 				break;
1825 			else
1826 				continue;
1827 		}
1828 		if (looking_for_win32_name) {
1829 			if  (fn->file_name_type == FILE_NAME_WIN32)
1830 				break;
1831 			else
1832 				continue;
1833 		}
1834 
1835 		/* Ignore hard links from other directories */
1836 		if (dir_ni->mft_no != MREF_LE(fn->parent_directory)) {
1837 			ntfs_log_debug("MFT record numbers don't match "
1838 				       "(%llu != %llu)\n",
1839 				       (long long unsigned)dir_ni->mft_no,
1840 				       (long long unsigned)MREF_LE(fn->parent_directory));
1841 			continue;
1842 		}
1843 		if (case_sensitive_match
1844 		    || ((fn->file_name_type == FILE_NAME_POSIX)
1845 			&& NVolCaseSensitive(ni->vol)))
1846 			case_sensitive = CASE_SENSITIVE;
1847 
1848 		if (ntfs_names_are_equal(fn->file_name, fn->file_name_length,
1849 					 name, name_len, case_sensitive,
1850 					 ni->vol->upcase, ni->vol->upcase_len)){
1851 
1852 			if (fn->file_name_type == FILE_NAME_WIN32) {
1853 				looking_for_dos_name = TRUE;
1854 				ntfs_attr_reinit_search_ctx(actx);
1855 				continue;
1856 			}
1857 			if (fn->file_name_type == FILE_NAME_DOS)
1858 				looking_for_dos_name = TRUE;
1859 			break;
1860 		}
1861 	}
1862 	if (errno) {
1863 		/*
1864 		 * If case sensitive search failed, then try once again
1865 		 * ignoring case.
1866 		 */
1867 		if (errno == ENOENT && case_sensitive_match) {
1868 			case_sensitive_match = FALSE;
1869 			ntfs_attr_reinit_search_ctx(actx);
1870 			goto search;
1871 		}
1872 		goto err_out;
1873 	}
1874 
1875 	if (ntfs_check_unlinkable_dir(ni, fn) < 0)
1876 		goto err_out;
1877 
1878 	if (ntfs_index_remove(dir_ni, ni, fn, le32_to_cpu(actx->attr->value_length)))
1879 		goto err_out;
1880 
1881 	if (ntfs_attr_record_rm(actx))
1882 		goto err_out;
1883 
1884 	ni->mrec->link_count = cpu_to_le16(le16_to_cpu(
1885 			ni->mrec->link_count) - 1);
1886 
1887 	ntfs_inode_mark_dirty(ni);
1888 	if (looking_for_dos_name) {
1889 		looking_for_dos_name = FALSE;
1890 		looking_for_win32_name = TRUE;
1891 		ntfs_attr_reinit_search_ctx(actx);
1892 		goto search;
1893 	}
1894 	/* TODO: Update object id, quota and securiry indexes if required. */
1895 	/*
1896 	 * If hard link count is not equal to zero then we are done. In other
1897 	 * case there are no reference to this inode left, so we should free all
1898 	 * non-resident attributes and mark all MFT record as not in use.
1899 	 */
1900 #if CACHE_LOOKUP_SIZE
1901 			/* invalidate entry in lookup cache */
1902 	lkitem.name = (const char*)NULL;
1903 	lkitem.namesize = 0;
1904 	lkitem.inum = ni->mft_no;
1905 	lkitem.parent = dir_ni->mft_no;
1906 	ntfs_invalidate_cache(vol->lookup_cache, GENERIC(&lkitem),
1907 			lookup_cache_inv_compare, CACHE_NOHASH);
1908 #endif
1909 #if CACHE_INODE_SIZE
1910 	inum = ni->mft_no;
1911 	if (pathname) {
1912 			/* invalide cache entry, even if there was an error */
1913 		/* Remove leading /'s. */
1914 		p = pathname;
1915 		while (*p == PATH_SEP)
1916 			p++;
1917 		if (p[0] && (p[strlen(p)-1] == PATH_SEP))
1918 			ntfs_log_error("Unnormalized path %s\n",pathname);
1919 		item.pathname = p;
1920 		item.varsize = strlen(p);
1921 	} else {
1922 		item.pathname = (const char*)NULL;
1923 		item.varsize = 0;
1924 	}
1925 	item.inum = inum;
1926 	count = ntfs_invalidate_cache(vol->xinode_cache, GENERIC(&item),
1927 				inode_cache_inv_compare, CACHE_NOHASH);
1928 	if (pathname && !count)
1929 		ntfs_log_error("Could not delete inode cache entry for %s\n",
1930 			pathname);
1931 #endif
1932 	if (ni->mrec->link_count) {
1933 		ntfs_inode_update_times(ni, NTFS_UPDATE_CTIME);
1934 		goto ok;
1935 	}
1936 	if (ntfs_delete_reparse_index(ni)) {
1937 		/*
1938 		 * Failed to remove the reparse index : proceed anyway
1939 		 * This is not a critical error, the entry is useless
1940 		 * because of sequence_number, and stopping file deletion
1941 		 * would be much worse as the file is not referenced now.
1942 		 */
1943 		err = errno;
1944 	}
1945 	if (ntfs_delete_object_id_index(ni)) {
1946 		/*
1947 		 * Failed to remove the object id index : proceed anyway
1948 		 * This is not a critical error.
1949 		 */
1950 		err = errno;
1951 	}
1952 	ntfs_attr_reinit_search_ctx(actx);
1953 	while (!ntfs_attrs_walk(actx)) {
1954 		if (actx->attr->non_resident) {
1955 			runlist *rl;
1956 
1957 			rl = ntfs_mapping_pairs_decompress(ni->vol, actx->attr,
1958 					NULL);
1959 			if (!rl) {
1960 				err = errno;
1961 				ntfs_log_error("Failed to decompress runlist.  "
1962 						"Leaving inconsistent metadata.\n");
1963 				continue;
1964 			}
1965 			if (ntfs_cluster_free_from_rl(ni->vol, rl)) {
1966 				err = errno;
1967 				ntfs_log_error("Failed to free clusters.  "
1968 						"Leaving inconsistent metadata.\n");
1969 				continue;
1970 			}
1971 			free(rl);
1972 		}
1973 	}
1974 	if (errno != ENOENT) {
1975 		err = errno;
1976 		ntfs_log_error("Attribute enumeration failed.  "
1977 				"Probably leaving inconsistent metadata.\n");
1978 	}
1979 	/* All extents should be attached after attribute walk. */
1980 #if CACHE_NIDATA_SIZE
1981 		/*
1982 		 * Disconnect extents before deleting them, so they are
1983 		 * not wrongly moved to cache through the chainings
1984 		 */
1985 	for (i=ni->nr_extents-1; i>=0; i--) {
1986 		ni->extent_nis[i]->base_ni = (ntfs_inode*)NULL;
1987 		ni->extent_nis[i]->nr_extents = 0;
1988 		if (ntfs_mft_record_free(ni->vol, ni->extent_nis[i])) {
1989 			err = errno;
1990 			ntfs_log_error("Failed to free extent MFT record.  "
1991 					"Leaving inconsistent metadata.\n");
1992 		}
1993 	}
1994 	free(ni->extent_nis);
1995 	ni->nr_extents = 0;
1996 	ni->extent_nis = (ntfs_inode**)NULL;
1997 #else
1998 	while (ni->nr_extents)
1999 		if (ntfs_mft_record_free(ni->vol, *(ni->extent_nis))) {
2000 			err = errno;
2001 			ntfs_log_error("Failed to free extent MFT record.  "
2002 					"Leaving inconsistent metadata.\n");
2003 		}
2004 #endif
2005 	if (ntfs_mft_record_free(ni->vol, ni)) {
2006 		err = errno;
2007 		ntfs_log_error("Failed to free base MFT record.  "
2008 				"Leaving inconsistent metadata.\n");
2009 	}
2010 	ni = NULL;
2011 ok:
2012 	ntfs_inode_update_times(dir_ni, NTFS_UPDATE_MCTIME);
2013 out:
2014 	if (actx)
2015 		ntfs_attr_put_search_ctx(actx);
2016 	if (ntfs_inode_close(dir_ni) && !err)
2017 		err = errno;
2018 	if (ntfs_inode_close(ni) && !err)
2019 		err = errno;
2020 	if (err) {
2021 		errno = err;
2022 		ntfs_log_debug("Could not delete file: %s\n", strerror(errno));
2023 		return -1;
2024 	}
2025 	ntfs_log_trace("Done.\n");
2026 	return 0;
2027 err_out:
2028 	err = errno;
2029 	goto out;
2030 }
2031 
2032 /**
2033  * ntfs_link - create hard link for file or directory
2034  * @ni:		ntfs inode for object to create hard link
2035  * @dir_ni:	ntfs inode for directory in which new link should be placed
2036  * @name:	unicode name of the new link
2037  * @name_len:	length of the name in unicode characters
2038  *
2039  * NOTE: At present we allow creating hardlinks to directories, we use them
2040  * in a temporary state during rename. But it's defenitely bad idea to have
2041  * hard links to directories as a result of operation.
2042  * FIXME: Create internal  __ntfs_link that allows hard links to a directories
2043  * and external ntfs_link that do not. Write ntfs_rename that uses __ntfs_link.
2044  *
2045  * Return 0 on success or -1 on error with errno set to the error code.
2046  */
2047 static int ntfs_link_i(ntfs_inode *ni, ntfs_inode *dir_ni, ntfschar *name,
2048 			 u8 name_len, FILE_NAME_TYPE_FLAGS nametype)
2049 {
2050 	FILE_NAME_ATTR *fn = NULL;
2051 	int fn_len, err;
2052 
2053 	ntfs_log_trace("Entering.\n");
2054 
2055 	if (!ni || !dir_ni || !name || !name_len ||
2056 			ni->mft_no == dir_ni->mft_no) {
2057 		err = EINVAL;
2058 		ntfs_log_perror("ntfs_link wrong arguments");
2059 		goto err_out;
2060 	}
2061 
2062 	if ((ni->flags & FILE_ATTR_REPARSE_POINT)
2063 	   && !ntfs_possible_symlink(ni)) {
2064 		err = EOPNOTSUPP;
2065 		goto err_out;
2066 	}
2067 
2068 	/* Create FILE_NAME attribute. */
2069 	fn_len = sizeof(FILE_NAME_ATTR) + name_len * sizeof(ntfschar);
2070 	fn = ntfs_calloc(fn_len);
2071 	if (!fn) {
2072 		err = errno;
2073 		goto err_out;
2074 	}
2075 	fn->parent_directory = MK_LE_MREF(dir_ni->mft_no,
2076 			le16_to_cpu(dir_ni->mrec->sequence_number));
2077 	fn->file_name_length = name_len;
2078 	fn->file_name_type = nametype;
2079 	fn->file_attributes = ni->flags;
2080 	if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY) {
2081 		fn->file_attributes |= FILE_ATTR_I30_INDEX_PRESENT;
2082 		fn->data_size = fn->allocated_size = const_cpu_to_le64(0);
2083 	} else {
2084 		fn->allocated_size = cpu_to_sle64(ni->allocated_size);
2085 		fn->data_size = cpu_to_sle64(ni->data_size);
2086 	}
2087 	fn->creation_time = ni->creation_time;
2088 	fn->last_data_change_time = ni->last_data_change_time;
2089 	fn->last_mft_change_time = ni->last_mft_change_time;
2090 	fn->last_access_time = ni->last_access_time;
2091 	memcpy(fn->file_name, name, name_len * sizeof(ntfschar));
2092 	/* Add FILE_NAME attribute to index. */
2093 	if (ntfs_index_add_filename(dir_ni, fn, MK_MREF(ni->mft_no,
2094 			le16_to_cpu(ni->mrec->sequence_number)))) {
2095 		err = errno;
2096 		ntfs_log_perror("Failed to add filename to the index");
2097 		goto err_out;
2098 	}
2099 	/* Add FILE_NAME attribute to inode. */
2100 	if (ntfs_attr_add(ni, AT_FILE_NAME, AT_UNNAMED, 0, (u8*)fn, fn_len)) {
2101 		ntfs_log_error("Failed to add FILE_NAME attribute.\n");
2102 		err = errno;
2103 		/* Try to remove just added attribute from index. */
2104 		if (ntfs_index_remove(dir_ni, ni, fn, fn_len))
2105 			goto rollback_failed;
2106 		goto err_out;
2107 	}
2108 	/* Increment hard links count. */
2109 	ni->mrec->link_count = cpu_to_le16(le16_to_cpu(
2110 			ni->mrec->link_count) + 1);
2111 	/* Done! */
2112 	ntfs_inode_mark_dirty(ni);
2113 	free(fn);
2114 	ntfs_log_trace("Done.\n");
2115 	return 0;
2116 rollback_failed:
2117 	ntfs_log_error("Rollback failed. Leaving inconsistent metadata.\n");
2118 err_out:
2119 	free(fn);
2120 	errno = err;
2121 	return -1;
2122 }
2123 
2124 int ntfs_link(ntfs_inode *ni, ntfs_inode *dir_ni, ntfschar *name, u8 name_len)
2125 {
2126 	return (ntfs_link_i(ni, dir_ni, name, name_len, FILE_NAME_POSIX));
2127 }
2128 
2129 /*
2130  *		Get a parent directory from an inode entry
2131  *
2132  *	This is only used in situations where the path used to access
2133  *	the current file is not known for sure. The result may be different
2134  *	from the path when the file is linked in several parent directories.
2135  *
2136  *	Currently this is only used for translating ".." in the target
2137  *	of a Vista relative symbolic link
2138  */
2139 
2140 ntfs_inode *ntfs_dir_parent_inode(ntfs_inode *ni)
2141 {
2142 	ntfs_inode *dir_ni = (ntfs_inode*)NULL;
2143 	u64 inum;
2144 	FILE_NAME_ATTR *fn;
2145 	ntfs_attr_search_ctx *ctx;
2146 
2147 	if (ni->mft_no != FILE_root) {
2148 			/* find the name in the attributes */
2149 		ctx = ntfs_attr_get_search_ctx(ni, NULL);
2150 		if (!ctx)
2151 			return ((ntfs_inode*)NULL);
2152 
2153 		if (!ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0,
2154 				CASE_SENSITIVE,	0, NULL, 0, ctx)) {
2155 			/* We know this will always be resident. */
2156 			fn = (FILE_NAME_ATTR*)((u8*)ctx->attr +
2157 					le16_to_cpu(ctx->attr->value_offset));
2158 			inum = le64_to_cpu(fn->parent_directory);
2159 			if (inum != (u64)-1) {
2160 				dir_ni = ntfs_inode_open(ni->vol, MREF(inum));
2161 			}
2162 		}
2163 		ntfs_attr_put_search_ctx(ctx);
2164 	}
2165 	return (dir_ni);
2166 }
2167 
2168 #ifdef HAVE_SETXATTR
2169 
2170 #define MAX_DOS_NAME_LENGTH	 12
2171 
2172 /*
2173  *		Get a DOS name for a file in designated directory
2174  *
2175  *	Returns size if found
2176  *		0 if not found
2177  *		-1 if there was an error (described by errno)
2178  */
2179 
2180 static int get_dos_name(ntfs_inode *ni, u64 dnum, ntfschar *dosname)
2181 {
2182 	size_t outsize = 0;
2183 	FILE_NAME_ATTR *fn;
2184 	ntfs_attr_search_ctx *ctx;
2185 
2186 		/* find the name in the attributes */
2187 	ctx = ntfs_attr_get_search_ctx(ni, NULL);
2188 	if (!ctx)
2189 		return -1;
2190 
2191 	while (!ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0, CASE_SENSITIVE,
2192 			0, NULL, 0, ctx)) {
2193 		/* We know this will always be resident. */
2194 		fn = (FILE_NAME_ATTR*)((u8*)ctx->attr +
2195 				le16_to_cpu(ctx->attr->value_offset));
2196 
2197 		if ((fn->file_name_type & FILE_NAME_DOS)
2198 		    && (MREF_LE(fn->parent_directory) == dnum)) {
2199 				/*
2200 				 * Found a DOS or WIN32+DOS name for the entry
2201 				 * copy name, after truncation for safety
2202 				 */
2203 			outsize = fn->file_name_length;
2204 /* TODO : reject if name is too long ? */
2205 			if (outsize > MAX_DOS_NAME_LENGTH)
2206 				outsize = MAX_DOS_NAME_LENGTH;
2207 			memcpy(dosname,fn->file_name,outsize*sizeof(ntfschar));
2208 		}
2209 	}
2210 	ntfs_attr_put_search_ctx(ctx);
2211 	return (outsize);
2212 }
2213 
2214 
2215 /*
2216  *		Get a long name for a file in designated directory
2217  *
2218  *	Returns size if found
2219  *		0 if not found
2220  *		-1 if there was an error (described by errno)
2221  */
2222 
2223 static int get_long_name(ntfs_inode *ni, u64 dnum, ntfschar *longname)
2224 {
2225 	size_t outsize = 0;
2226 	FILE_NAME_ATTR *fn;
2227 	ntfs_attr_search_ctx *ctx;
2228 
2229 		/* find the name in the attributes */
2230 	ctx = ntfs_attr_get_search_ctx(ni, NULL);
2231 	if (!ctx)
2232 		return -1;
2233 
2234 		/* first search for WIN32 or DOS+WIN32 names */
2235 	while (!ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0, CASE_SENSITIVE,
2236 			0, NULL, 0, ctx)) {
2237 		/* We know this will always be resident. */
2238 		fn = (FILE_NAME_ATTR*)((u8*)ctx->attr +
2239 				le16_to_cpu(ctx->attr->value_offset));
2240 
2241 		if ((fn->file_name_type & FILE_NAME_WIN32)
2242 		    && (MREF_LE(fn->parent_directory) == dnum)) {
2243 				/*
2244 				 * Found a WIN32 or WIN32+DOS name for the entry
2245 				 * copy name
2246 				 */
2247 			outsize = fn->file_name_length;
2248 			memcpy(longname,fn->file_name,outsize*sizeof(ntfschar));
2249 		}
2250 	}
2251 		/* if not found search for POSIX names */
2252 	if (!outsize) {
2253 		ntfs_attr_reinit_search_ctx(ctx);
2254 	while (!ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0, CASE_SENSITIVE,
2255 			0, NULL, 0, ctx)) {
2256 		/* We know this will always be resident. */
2257 		fn = (FILE_NAME_ATTR*)((u8*)ctx->attr +
2258 				le16_to_cpu(ctx->attr->value_offset));
2259 
2260 		if ((fn->file_name_type == FILE_NAME_POSIX)
2261 		    && (MREF_LE(fn->parent_directory) == dnum)) {
2262 				/*
2263 				 * Found a POSIX name for the entry
2264 				 * copy name
2265 				 */
2266 			outsize = fn->file_name_length;
2267 			memcpy(longname,fn->file_name,outsize*sizeof(ntfschar));
2268 		}
2269 	}
2270 	}
2271 	ntfs_attr_put_search_ctx(ctx);
2272 	return (outsize);
2273 }
2274 
2275 
2276 /*
2277  *		Get the ntfs DOS name into an extended attribute
2278  */
2279 
2280 int ntfs_get_ntfs_dos_name(ntfs_inode *ni, ntfs_inode *dir_ni,
2281 			char *value, size_t size)
2282 {
2283 	int outsize = 0;
2284 	char *outname = (char*)NULL;
2285 	u64 dnum;
2286 	int doslen;
2287 	ntfschar dosname[MAX_DOS_NAME_LENGTH];
2288 
2289 	dnum = dir_ni->mft_no;
2290 	doslen = get_dos_name(ni, dnum, dosname);
2291 	if (doslen > 0) {
2292 			/*
2293 			 * Found a DOS name for the entry, make
2294 			 * uppercase and encode into the buffer
2295 			 * if there is enough space
2296 			 */
2297 		ntfs_name_upcase(dosname, doslen,
2298 				ni->vol->upcase, ni->vol->upcase_len);
2299 		if (ntfs_ucstombs(dosname, doslen, &outname, size) < 0) {
2300 			ntfs_log_error("Cannot represent dosname in current locale.\n");
2301 			outsize = -errno;
2302 		} else {
2303 			outsize = strlen(outname);
2304 			if (value && (outsize <= (int)size))
2305 				memcpy(value, outname, outsize);
2306 			else
2307 				if (size && (outsize > (int)size))
2308 					outsize = -ERANGE;
2309 			free(outname);
2310 		}
2311 	} else {
2312 		if (doslen == 0)
2313 			errno = ENODATA;
2314 		outsize = -errno;
2315 	}
2316 	return (outsize);
2317 }
2318 
2319 /*
2320  *		Change the name space of an existing file or directory
2321  *
2322  *	Returns the old namespace if successful
2323  *		-1 if an error occurred (described by errno)
2324  */
2325 
2326 static int set_namespace(ntfs_inode *ni, ntfs_inode *dir_ni,
2327 			ntfschar *name, int len,
2328 			FILE_NAME_TYPE_FLAGS nametype)
2329 {
2330 	ntfs_attr_search_ctx *actx;
2331 	ntfs_index_context *icx;
2332 	FILE_NAME_ATTR *fnx;
2333 	FILE_NAME_ATTR *fn = NULL;
2334 	BOOL found;
2335 	int lkup;
2336 	int ret;
2337 
2338 	ret = -1;
2339 	actx = ntfs_attr_get_search_ctx(ni, NULL);
2340 	if (actx) {
2341 		found = FALSE;
2342 		do {
2343 			lkup = ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0,
2344 	                        CASE_SENSITIVE, 0, NULL, 0, actx);
2345 			if (!lkup) {
2346 				fn = (FILE_NAME_ATTR*)((u8*)actx->attr +
2347 				     le16_to_cpu(actx->attr->value_offset));
2348 				found = (MREF_LE(fn->parent_directory)
2349 						== dir_ni->mft_no)
2350 					&& !memcmp(fn->file_name, name,
2351 						len*sizeof(ntfschar));
2352 			}
2353 		} while (!lkup && !found);
2354 		if (found) {
2355 			icx = ntfs_index_ctx_get(dir_ni, NTFS_INDEX_I30, 4);
2356 			if (icx) {
2357 				lkup = ntfs_index_lookup((char*)fn, len, icx);
2358 				if (!lkup && icx->data && icx->data_len) {
2359 					fnx = (FILE_NAME_ATTR*)icx->data;
2360 					ret = fn->file_name_type;
2361 					fn->file_name_type = nametype;
2362 					fnx->file_name_type = nametype;
2363 					ntfs_inode_mark_dirty(ni);
2364 					ntfs_index_entry_mark_dirty(icx);
2365 				}
2366 			ntfs_index_ctx_put(icx);
2367 			}
2368 		}
2369 		ntfs_attr_put_search_ctx(actx);
2370 	}
2371 	return (ret);
2372 }
2373 
2374 /*
2375  *		Set a DOS name to a file and adjust name spaces
2376  *
2377  *	If the new names are collapsible (same uppercased chars) :
2378  *
2379  * - the existing DOS name or DOS+Win32 name is made Posix
2380  * - if it was a real DOS name, the existing long name is made DOS+Win32
2381  *        and the existing DOS name is deleted
2382  * - finally the existing long name is made DOS+Win32 unless already done
2383  *
2384  *	If the new names are not collapsible :
2385  *
2386  * - insert the short name as a DOS name
2387  * - delete the old long name or existing short name
2388  * - insert the new long name (as a Win32 or DOS+Win32 name)
2389  *
2390  * Deleting the old long name will not delete the file
2391  * provided the old name was in the Posix name space,
2392  * because the alternate name has been set before.
2393  *
2394  * The inodes of file and parent directory are always closed
2395  *
2396  * Returns 0 if successful
2397  *	   -1 if failed
2398  */
2399 
2400 static int set_dos_name(ntfs_inode *ni, ntfs_inode *dir_ni,
2401 			ntfschar *shortname, int shortlen,
2402 			ntfschar *longname, int longlen,
2403 			ntfschar *deletename, int deletelen, BOOL existed)
2404 {
2405 	unsigned int linkcount;
2406 	ntfs_volume *vol;
2407 	BOOL collapsible;
2408 	BOOL deleted;
2409 	BOOL done;
2410 	FILE_NAME_TYPE_FLAGS oldnametype;
2411 	u64 dnum;
2412 	u64 fnum;
2413 	int res;
2414 
2415 	res = -1;
2416 	vol = ni->vol;
2417 	dnum = dir_ni->mft_no;
2418 	fnum = ni->mft_no;
2419 				/* save initial link count */
2420 	linkcount = le16_to_cpu(ni->mrec->link_count);
2421 
2422 		/* check whether the same name may be used as DOS and WIN32 */
2423 	collapsible = ntfs_collapsible_chars(ni->vol, shortname, shortlen,
2424 						longname, longlen);
2425 	if (collapsible) {
2426 		deleted = FALSE;
2427 		done = FALSE;
2428 		if (existed) {
2429 			oldnametype = set_namespace(ni, dir_ni, deletename,
2430 					deletelen, FILE_NAME_POSIX);
2431 			if (oldnametype == FILE_NAME_DOS) {
2432 				if (set_namespace(ni, dir_ni, longname, longlen,
2433 						FILE_NAME_WIN32_AND_DOS) >= 0) {
2434 					if (!ntfs_delete(vol,
2435 						(const char*)NULL, ni, dir_ni,
2436 						deletename, deletelen))
2437 						res = 0;
2438 					deleted = TRUE;
2439 				} else
2440 					done = TRUE;
2441 			}
2442 		}
2443 		if (!deleted) {
2444 			if (!done && (set_namespace(ni, dir_ni,
2445 					longname, longlen,
2446 					FILE_NAME_WIN32_AND_DOS) >= 0))
2447 				res = 0;
2448 			ntfs_inode_update_times(ni, NTFS_UPDATE_CTIME);
2449 			ntfs_inode_update_times(dir_ni, NTFS_UPDATE_MCTIME);
2450 			if (ntfs_inode_close_in_dir(ni,dir_ni) && !res)
2451 				res = -1;
2452 			if (ntfs_inode_close(dir_ni) && !res)
2453 				res = -1;
2454 		}
2455 	} else {
2456 		if (!ntfs_link_i(ni, dir_ni, shortname, shortlen,
2457 				FILE_NAME_DOS)
2458 			/* make sure a new link was recorded */
2459 		    && (le16_to_cpu(ni->mrec->link_count) > linkcount)) {
2460 			/* delete the existing long name or short name */
2461 // is it ok to not provide the path ?
2462 			if (!ntfs_delete(vol, (char*)NULL, ni, dir_ni,
2463 				 deletename, deletelen)) {
2464 			/* delete closes the inodes, so have to open again */
2465 				dir_ni = ntfs_inode_open(vol, dnum);
2466 				if (dir_ni) {
2467 					ni = ntfs_inode_open(vol, fnum);
2468 					if (ni) {
2469 						if (!ntfs_link_i(ni, dir_ni,
2470 							longname, longlen,
2471 							FILE_NAME_WIN32))
2472 							res = 0;
2473 						if (ntfs_inode_close_in_dir(ni,
2474 							dir_ni)
2475 						    && !res)
2476 							res = -1;
2477 					}
2478 				if (ntfs_inode_close(dir_ni) && !res)
2479 					res = -1;
2480 				}
2481 			}
2482 		} else {
2483 			ntfs_inode_close_in_dir(ni,dir_ni);
2484 			ntfs_inode_close(dir_ni);
2485 		}
2486 	}
2487 	return (res);
2488 }
2489 
2490 
2491 /*
2492  *		Set the ntfs DOS name into an extended attribute
2493  *
2494  *  The DOS name will be added as another file name attribute
2495  *  using the existing file name information from the original
2496  *  name or overwriting the DOS Name if one exists.
2497  *
2498  *  	The inode of the file is always closed
2499  */
2500 
2501 int ntfs_set_ntfs_dos_name(ntfs_inode *ni, ntfs_inode *dir_ni,
2502 			const char *value, size_t size,	int flags)
2503 {
2504 	int res = 0;
2505 	int longlen = 0;
2506 	int shortlen = 0;
2507 	char newname[3*MAX_DOS_NAME_LENGTH + 1];
2508 	ntfschar oldname[MAX_DOS_NAME_LENGTH];
2509 	int oldlen;
2510 	u64 dnum;
2511 	BOOL closed = FALSE;
2512 	ntfschar *shortname = NULL;
2513 	ntfschar longname[NTFS_MAX_NAME_LEN];
2514 
2515 		/* copy the string to insert a null char, and truncate */
2516 	if (size > 3*MAX_DOS_NAME_LENGTH)
2517 		size = 3*MAX_DOS_NAME_LENGTH;
2518 	strncpy(newname, value, size);
2519 		/* a long name may be truncated badly and be untranslatable */
2520 	newname[size] = 0;
2521 		/* convert the string to the NTFS wide chars, and truncate */
2522 	shortlen = ntfs_mbstoucs(newname, &shortname);
2523 	if (shortlen > MAX_DOS_NAME_LENGTH)
2524 		shortlen = MAX_DOS_NAME_LENGTH;
2525 			/* make sure the short name has valid chars */
2526 	if ((shortlen < 0) || ntfs_forbidden_chars(shortname,shortlen)) {
2527 		ntfs_inode_close_in_dir(ni,dir_ni);
2528 		ntfs_inode_close(dir_ni);
2529 		res = -errno;
2530 		return res;
2531 	}
2532 	dnum = dir_ni->mft_no;
2533 	longlen = get_long_name(ni, dnum, longname);
2534 	if (longlen > 0) {
2535 		oldlen = get_dos_name(ni, dnum, oldname);
2536 		if ((oldlen >= 0)
2537 		    && !ntfs_forbidden_chars(longname, longlen)) {
2538 			if (oldlen > 0) {
2539 				if (flags & XATTR_CREATE) {
2540 					res = -1;
2541 					errno = EEXIST;
2542 				} else
2543 					if ((shortlen == oldlen)
2544 					    && !memcmp(shortname,oldname,
2545 						     oldlen*sizeof(ntfschar)))
2546 						/* already set, done */
2547 						res = 0;
2548 					else {
2549 						res = set_dos_name(ni, dir_ni,
2550 							shortname, shortlen,
2551 							longname, longlen,
2552 							oldname, oldlen, TRUE);
2553 						closed = TRUE;
2554 					}
2555 			} else {
2556 				if (flags & XATTR_REPLACE) {
2557 					res = -1;
2558 					errno = ENODATA;
2559 				} else {
2560 					res = set_dos_name(ni, dir_ni,
2561 						shortname, shortlen,
2562 						longname, longlen,
2563 						longname, longlen, FALSE);
2564 					closed = TRUE;
2565 				}
2566 			}
2567 		} else
2568 			res = -1;
2569 	} else {
2570 		res = -1;
2571 		errno = ENOENT;
2572 	}
2573 	free(shortname);
2574 	if (!closed) {
2575 		ntfs_inode_close_in_dir(ni,dir_ni);
2576 		ntfs_inode_close(dir_ni);
2577 	}
2578 	return (res ? -1 : 0);
2579 }
2580 
2581 /*
2582  *		Delete the ntfs DOS name
2583  */
2584 
2585 int ntfs_remove_ntfs_dos_name(ntfs_inode *ni, ntfs_inode *dir_ni)
2586 {
2587 	int res;
2588 	int oldnametype;
2589 	int longlen = 0;
2590 	int shortlen;
2591 	u64 dnum;
2592 	ntfs_volume *vol;
2593 	BOOL deleted = FALSE;
2594 	ntfschar shortname[MAX_DOS_NAME_LENGTH];
2595 	ntfschar longname[NTFS_MAX_NAME_LEN];
2596 
2597 	res = -1;
2598 	vol = ni->vol;
2599 	dnum = dir_ni->mft_no;
2600 	longlen = get_long_name(ni, dnum, longname);
2601 	if (longlen > 0) {
2602 		shortlen = get_dos_name(ni, dnum, shortname);
2603 		if (shortlen >= 0) {
2604 				/* migrate the long name as Posix */
2605 			oldnametype = set_namespace(ni,dir_ni,longname,longlen,
2606 					FILE_NAME_POSIX);
2607 			switch (oldnametype) {
2608 			case FILE_NAME_WIN32_AND_DOS :
2609 				/* name was Win32+DOS : done */
2610 				res = 0;
2611 				break;
2612 			case FILE_NAME_DOS :
2613 				/* name was DOS, make it back to DOS */
2614 				set_namespace(ni,dir_ni,longname,longlen,
2615 						FILE_NAME_DOS);
2616 				errno = ENOENT;
2617 				break;
2618 			case FILE_NAME_WIN32 :
2619 				/* name was Win32, make it Posix and delete */
2620 				if (set_namespace(ni,dir_ni,shortname,shortlen,
2621 						FILE_NAME_POSIX) >= 0) {
2622 					if (!ntfs_delete(vol,
2623 							(const char*)NULL, ni,
2624 							dir_ni, shortname,
2625 							shortlen))
2626 						res = 0;
2627 					deleted = TRUE;
2628 				} else {
2629 					/*
2630 					 * DOS name has been found, but cannot
2631 					 * migrate to Posix : something bad
2632 					 * has happened
2633 					 */
2634 					errno = EIO;
2635 					ntfs_log_error("Could not change"
2636 						" DOS name of inode %lld to Posix\n",
2637 						(long long)ni->mft_no);
2638 				}
2639 				break;
2640 			default :
2641 				/* name was Posix or not found : error */
2642 				errno = ENOENT;
2643 				break;
2644 			}
2645 		}
2646 	} else {
2647 		errno = ENOENT;
2648 		res = -1;
2649 	}
2650 	if (!deleted) {
2651 		ntfs_inode_close_in_dir(ni,dir_ni);
2652 		ntfs_inode_close(dir_ni);
2653 	}
2654 	return (res);
2655 }
2656 
2657 #endif
2658