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