2 * dir.c - Directory handling code. Originated from the Linux-NTFS project.
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
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.
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.
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
39 #ifdef HAVE_SYS_STAT_H
43 #ifdef HAVE_SYS_SYSMACROS_H
44 #include <sys/sysmacros.h>
63 #include "object_id.h"
66 #include <sys/xattr.h>
70 * The little endian Unicode strings "$I30", "$SII", "$SDH", "$O"
71 * and "$Q" as global constants.
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') };
94 * Based on first char and second char (which may be '\0')
97 int ntfs_dir_inode_hash(const struct CACHED_GENERIC
*cached
)
100 const unsigned char *name
;
102 path
= (const char*)cached
->variable
;
104 ntfs_log_error("Bad inode cache entry\n");
107 name
= (const unsigned char*)strrchr(path
,'/');
109 name
= (const unsigned char*)path
;
110 return (((name
[0] << 1) + name
[1] + strlen((const char*)name
))
111 % (2*CACHE_INODE_SIZE
));
115 * Pathname comparing for entering/fetching from cache
118 static int inode_cache_compare(const struct CACHED_GENERIC
*cached
,
119 const struct CACHED_GENERIC
*wanted
)
121 return (!cached
->variable
122 || strcmp(cached
->variable
, wanted
->variable
));
126 * Pathname comparing for invalidating entries in cache
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
133 * Only use associated with a CACHE_NOHASH flag
136 static int inode_cache_inv_compare(const struct CACHED_GENERIC
*cached
,
137 const struct CACHED_GENERIC
*wanted
)
141 const struct CACHED_INODE
*w
;
142 const struct CACHED_INODE
*c
;
144 w
= (const struct CACHED_INODE
*)wanted
;
145 c
= (const struct CACHED_INODE
*)cached
;
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
] != '/'))));
154 different
= !c
->pathname
155 || (w
->inum
!= MREF(c
->inum
));
161 #if CACHE_LOOKUP_SIZE
164 * File name comparing for entering/fetching from lookup cache
167 static int lookup_cache_compare(const struct CACHED_GENERIC
*cached
,
168 const struct CACHED_GENERIC
*wanted
)
170 const struct CACHED_LOOKUP
*c
= (const struct CACHED_LOOKUP
*) cached
;
171 const struct CACHED_LOOKUP
*w
= (const struct CACHED_LOOKUP
*) wanted
;
173 || (c
->parent
!= w
->parent
)
174 || (c
->namesize
!= w
->namesize
)
175 || memcmp(c
->name
, w
->name
, c
->namesize
));
179 * Inode number comparing for invalidating lookup cache
181 * All entries with designated inode number are invalidated
183 * Only use associated with a CACHE_NOHASH flag
186 static int lookup_cache_inv_compare(const struct CACHED_GENERIC
*cached
,
187 const struct CACHED_GENERIC
*wanted
)
189 const struct CACHED_LOOKUP
*c
= (const struct CACHED_LOOKUP
*) cached
;
190 const struct CACHED_LOOKUP
*w
= (const struct CACHED_LOOKUP
*) wanted
;
192 || (c
->parent
!= w
->parent
)
193 || (MREF(c
->inum
) != MREF(w
->inum
)));
199 * Based on first, second and and last char
202 int ntfs_dir_lookup_hash(const struct CACHED_GENERIC
*cached
)
204 const unsigned char *name
;
208 name
= (const unsigned char*)cached
->variable
;
209 count
= cached
->varsize
;
210 if (!name
|| !count
) {
211 ntfs_log_error("Bad lookup cache entry\n");
214 val
= (name
[0] << 2) + (name
[1] << 1) + name
[count
- 1] + count
;
215 return (val
% (2*CACHE_LOOKUP_SIZE
));
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
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.
232 * On error, return -1 with errno set to the error code. If the inode is is not
233 * found errno is ENOENT.
235 * Note, @uname_len does not include the (optional) terminating NULL character.
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.
242 * If the volume is mounted with the case sensitive flag set, then we only
243 * allow exact matches.
245 u64
ntfs_inode_lookup_by_name(ntfs_inode
*dir_ni
,
246 const ntfschar
*uname
, const int uname_len
)
251 ntfs_volume
*vol
= dir_ni
->vol
;
252 ntfs_attr_search_ctx
*ctx
;
255 INDEX_ALLOCATION
*ia
;
256 IGNORE_CASE_BOOL case_sensitivity
;
260 u32 index_block_size
;
261 u8 index_vcn_size_bits
;
263 ntfs_log_trace("Entering\n");
265 if (!dir_ni
|| !dir_ni
->mrec
|| !uname
|| uname_len
<= 0) {
270 ctx
= ntfs_attr_get_search_ctx(dir_ni
, NULL
);
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
,
277 ntfs_log_perror("Index root attribute missing in directory inode "
278 "%lld", (unsigned long long)dir_ni
->mft_no
);
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
);
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
));
297 * Loop until we exceed valid memory (corruption case) or until we
298 * reach the last entry.
300 for (;; ie
= (INDEX_ENTRY
*)((u8
*)ie
+ le16_to_cpu(ie
->length
))) {
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
) >
306 ntfs_log_error("Index entry out of bounds in inode %lld"
307 "\n", (unsigned long long)dir_ni
->mft_no
);
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.
314 if (ie
->ie_flags
& INDEX_ENTRY_END
)
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
);
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.
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
);
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.
337 /* The names are not equal, continue the search. */
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.
345 mref
= le64_to_cpu(ie
->indexed_file
);
346 ntfs_attr_put_search_ctx(ctx
);
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.
355 if (!(ie
->ie_flags
& INDEX_ENTRY_NODE
)) {
356 ntfs_attr_put_search_ctx(ctx
);
359 ntfs_log_debug("Entry not found - between root entries.\n");
362 } /* Child node present, descend into it. */
364 /* Open the index allocation attribute. */
365 ia_na
= ntfs_attr_open(dir_ni
, AT_INDEX_ALLOCATION
, NTFS_INDEX_I30
, 4);
367 ntfs_log_perror("Failed to open index allocation (inode %lld)",
368 (unsigned long long)dir_ni
->mft_no
);
372 /* Allocate a buffer for the current index block. */
373 ia
= ntfs_malloc(index_block_size
);
375 ntfs_attr_close(ia_na
);
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
;
383 index_vcn_size_bits
= NTFS_BLOCK_SIZE_BITS
;
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);
389 descend_into_child_node
:
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
);
397 ntfs_log_perror("Failed to read vcn 0x%llx",
398 (unsigned long long)vcn
);
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
),
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
);
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
);
429 /* The first index entry. */
430 ie
= (INDEX_ENTRY
*)((u8
*)&ia
->index
+
431 le32_to_cpu(ia
->index
.entries_offset
));
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.
437 for (;; ie
= (INDEX_ENTRY
*)((u8
*)ie
+ le16_to_cpu(ie
->length
))) {
439 if ((u8
*)ie
< (u8
*)ia
|| (u8
*)ie
+
440 sizeof(INDEX_ENTRY_HEADER
) > index_end
||
441 (u8
*)ie
+ le16_to_cpu(ie
->key_length
) >
443 ntfs_log_error("Index entry out of bounds in directory "
445 (unsigned long long)dir_ni
->mft_no
);
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.
453 if (ie
->ie_flags
& INDEX_ENTRY_END
)
456 if (!le16_to_cpu(ie
->length
)) {
458 ntfs_log_error("Zero length index entry in inode %lld"
459 "\n", (unsigned long long)dir_ni
->mft_no
);
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.
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
);
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.
477 /* The names are not equal, continue the search. */
480 mref
= le64_to_cpu(ie
->indexed_file
);
482 ntfs_attr_close(ia_na
);
483 ntfs_attr_put_search_ctx(ctx
);
487 * We have finished with this index buffer without success. Check for
488 * the presence of a child node.
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
);
498 /* Child node present, descend into it. */
499 vcn
= sle64_to_cpup((u8
*)ie
+ le16_to_cpu(ie
->length
) - 8);
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
);
508 ntfs_attr_close(ia_na
);
509 ntfs_attr_put_search_ctx(ctx
);
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
517 ntfs_log_debug("Entry not found.\n");
522 ntfs_log_debug("Corrupt directory. Aborting lookup.\n");
524 ntfs_attr_put_search_ctx(ctx
);
530 ntfs_attr_close(ia_na
);
535 * Lookup a file in a directory from its UTF-8 name
537 * The name is first fetched from cache if one is defined
539 * Returns the inode number
540 * or -1 if not possible (errno tells why)
543 u64
ntfs_inode_lookup_by_mbsname(ntfs_inode
*dir_ni
, const char *name
)
546 ntfschar
*uname
= (ntfschar
*)NULL
;
549 const char *const_name
;
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
;
556 cached_name
= (char*)NULL
;
560 #if CACHE_LOOKUP_SIZE
563 * fetch inode from cache
566 if (dir_ni
->vol
->lookup_cache
) {
567 struct CACHED_LOOKUP item
;
568 struct CACHED_LOOKUP
*cached
;
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
);
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
,
587 /* enter into cache, even if not found */
588 ntfs_enter_cache(dir_ni
->vol
->lookup_cache
,
590 lookup_cache_compare
);
598 /* Generate unicode name. */
599 uname_len
= ntfs_mbstoucs(cached_name
, &uname
);
601 inum
= ntfs_inode_lookup_by_name(dir_ni
,
614 * Update a cache lookup record when a name has been defined
616 * The UTF-8 name is required
619 void ntfs_inode_update_mbsname(ntfs_inode
*dir_ni
, const char *name
, u64 inum
)
621 #if CACHE_LOOKUP_SIZE
622 struct CACHED_LOOKUP item
;
623 struct CACHED_LOOKUP
*cached
;
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
;
632 cached_name
= (char*)NULL
;
636 item
.namesize
= strlen(item
.name
) + 1;
637 item
.parent
= dir_ni
->mft_no
;
639 cached
= (struct CACHED_LOOKUP
*)ntfs_enter_cache(
640 dir_ni
->vol
->lookup_cache
,
641 GENERIC(&item
), lookup_cache_compare
);
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
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.
661 * Return: inode Success, the pathname was valid
662 * NULL Error, the pathname was invalid, or some other error occurred
664 ntfs_inode
*ntfs_pathname_to_inode(ntfs_volume
*vol
, ntfs_inode
*parent
,
665 const char *pathname
)
671 ntfs_inode
*result
= NULL
;
672 ntfschar
*unicode
= NULL
;
675 struct CACHED_INODE item
;
676 struct CACHED_INODE
*cached
;
680 if (!vol
|| !pathname
) {
685 ntfs_log_trace("path: '%s'\n", pathname
);
687 ascii
= strdup(pathname
);
689 ntfs_log_error("Out of memory.\n");
695 /* Remove leading /'s. */
696 while (p
&& *p
&& *p
== PATH_SEP
)
700 if (p
[0] && (p
[strlen(p
)-1] == PATH_SEP
))
701 ntfs_log_error("Unnormalized path %s\n",ascii
);
708 * fetch inode for full path from cache
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
);
717 cached
= (struct CACHED_INODE
*)NULL
;
720 * return opened inode if found in cache
722 inum
= MREF(cached
->inum
);
723 ni
= ntfs_inode_open(vol
, inum
);
725 ntfs_log_debug("Cannot open inode %llu: %s.\n",
726 (unsigned long long)inum
, p
);
733 ni
= ntfs_inode_open(vol
, FILE_root
);
735 ntfs_log_debug("Couldn't open the inode of the root "
738 result
= (ntfs_inode
*)NULL
;
744 /* Find the end of the first token. */
745 q
= strchr(p
, PATH_SEP
);
751 * fetch inode for partial path from cache
753 cached
= (struct CACHED_INODE
*)NULL
;
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
);
765 * if not in cache, translate, search, then
766 * insert into cache if found
769 len
= ntfs_mbstoucs(p
, &unicode
);
771 ntfs_log_perror("Could not convert filename to Unicode:"
775 } else if (len
> NTFS_MAX_NAME_LEN
) {
779 inum
= ntfs_inode_lookup_by_name(ni
, unicode
, len
);
780 if (!parent
&& (inum
!= (u64
) -1)) {
782 ntfs_enter_cache(vol
->xinode_cache
,
784 inode_cache_compare
);
788 len
= ntfs_mbstoucs(p
, &unicode
);
790 ntfs_log_perror("Could not convert filename to Unicode:"
794 } else if (len
> NTFS_MAX_NAME_LEN
) {
798 inum
= ntfs_inode_lookup_by_name(ni
, unicode
, len
);
800 if (inum
== (u64
) -1) {
801 ntfs_log_debug("Couldn't find name '%s' in pathname "
802 "'%s'.\n", p
, pathname
);
808 if (ntfs_inode_close(ni
)) {
814 ni
= ntfs_inode_open(vol
, inum
);
816 ntfs_log_debug("Cannot open inode %llu: %s.\n",
817 (unsigned long long)inum
, p
);
825 if (q
) *q
++ = PATH_SEP
; /* JPA */
827 while (p
&& *p
&& *p
== PATH_SEP
)
834 if (ni
&& (ni
!= parent
))
835 if (ntfs_inode_close(ni
) && !err
)
846 * The little endian Unicode string ".." for ntfs_readdir().
848 static const ntfschar dotdot
[3] = { const_cpu_to_le16('.'),
849 const_cpu_to_le16('.'),
850 const_cpu_to_le16('\0') };
853 * union index_union -
854 * More helpers for ntfs_readdir().
858 INDEX_ALLOCATION
*ia
;
859 } index_union
__attribute__((__transparent_union__
));
863 * More helpers for ntfs_readdir().
866 INDEX_TYPE_ROOT
, /* index root */
867 INDEX_TYPE_ALLOCATION
, /* index allocation */
871 * Decode Interix file types
873 * Non-Interix types are returned as plain files, because a
874 * Windows user may force patterns very similar to Interix,
875 * and most metadata files have such similar patters.
878 static u32
ntfs_interix_types(ntfs_inode
*ni
)
884 dt_type
= NTFS_DT_UNKNOWN
;
885 na
= ntfs_attr_open(ni
, AT_DATA
, NULL
, 0);
887 /* Unrecognized patterns (eg HID + SYST) are plain files */
888 dt_type
= NTFS_DT_REG
;
889 if (na
->data_size
<= 1) {
890 if (!(ni
->flags
& FILE_ATTR_HIDDEN
))
891 dt_type
= (na
->data_size
?
892 NTFS_DT_SOCK
: NTFS_DT_FIFO
);
894 if ((na
->data_size
>= (s64
)sizeof(magic
))
895 && (ntfs_attr_pread(na
, 0, sizeof(magic
), &magic
)
897 if (magic
== INTX_SYMBOLIC_LINK
)
898 dt_type
= NTFS_DT_LNK
;
899 else if (magic
== INTX_BLOCK_DEVICE
)
900 dt_type
= NTFS_DT_BLK
;
901 else if (magic
== INTX_CHARACTER_DEVICE
)
902 dt_type
= NTFS_DT_CHR
;
913 * Better only use for Interix types and junctions,
914 * unneeded complexity when used for plain files or directories
916 * Error cases are logged and returned as unknown.
919 static u32
ntfs_dir_entry_type(ntfs_inode
*dir_ni
, MFT_REF mref
,
920 FILE_ATTR_FLAGS attributes
)
925 dt_type
= NTFS_DT_UNKNOWN
;
926 ni
= ntfs_inode_open(dir_ni
->vol
, mref
);
928 if ((attributes
& FILE_ATTR_REPARSE_POINT
)
929 && ntfs_possible_symlink(ni
))
930 dt_type
= NTFS_DT_LNK
;
932 if ((attributes
& FILE_ATTR_SYSTEM
)
933 && !(attributes
& FILE_ATTR_I30_INDEX_PRESENT
))
934 dt_type
= ntfs_interix_types(ni
);
936 dt_type
= (attributes
937 & FILE_ATTR_I30_INDEX_PRESENT
938 ? NTFS_DT_DIR
: NTFS_DT_REG
);
939 if (ntfs_inode_close(ni
)) {
940 /* anything special worth doing ? */
941 ntfs_log_error("Failed to close inode %lld\n",
942 (long long)MREF(mref
));
945 if (dt_type
== NTFS_DT_UNKNOWN
)
946 ntfs_log_error("Could not decode the type of inode %lld\n",
947 (long long)MREF(mref
));
952 * ntfs_filldir - ntfs specific filldir method
953 * @dir_ni: ntfs inode of current directory
954 * @pos: current position in directory
955 * @ivcn_bits: log(2) of index vcn size
956 * @index_type: specifies whether @iu is an index root or an index allocation
957 * @iu: index root or index block to which @ie belongs
958 * @ie: current index entry
959 * @dirent: context for filldir callback supplied by the caller
960 * @filldir: filldir callback supplied by the caller
962 * Pass information specifying the current directory entry @ie to the @filldir
965 static int ntfs_filldir(ntfs_inode
*dir_ni
, s64
*pos
, u8 ivcn_bits
,
966 const INDEX_TYPE index_type
, index_union iu
, INDEX_ENTRY
*ie
,
967 void *dirent
, ntfs_filldir_t filldir
)
969 FILE_NAME_ATTR
*fn
= &ie
->key
.file_name
;
976 ntfs_log_trace("Entering.\n");
978 /* Advance the position even if going to skip the entry. */
979 if (index_type
== INDEX_TYPE_ALLOCATION
)
980 *pos
= (u8
*)ie
- (u8
*)iu
.ia
+ (sle64_to_cpu(
981 iu
.ia
->index_block_vcn
) << ivcn_bits
) +
982 dir_ni
->vol
->mft_record_size
;
983 else /* if (index_type == INDEX_TYPE_ROOT) */
984 *pos
= (u8
*)ie
- (u8
*)iu
.ir
;
985 mref
= le64_to_cpu(ie
->indexed_file
);
986 metadata
= (MREF(mref
) != FILE_root
) && (MREF(mref
) < FILE_first_user
);
987 /* Skip root directory self reference entry. */
988 if (MREF_LE(ie
->indexed_file
) == FILE_root
)
990 if ((ie
->key
.file_name
.file_attributes
991 & (FILE_ATTR_REPARSE_POINT
| FILE_ATTR_SYSTEM
))
993 dt_type
= ntfs_dir_entry_type(dir_ni
, mref
,
994 ie
->key
.file_name
.file_attributes
);
995 else if (ie
->key
.file_name
.file_attributes
996 & FILE_ATTR_I30_INDEX_PRESENT
)
997 dt_type
= NTFS_DT_DIR
;
999 dt_type
= NTFS_DT_REG
;
1001 /* return metadata files and hidden files if requested */
1002 if ((!metadata
&& (NVolShowHidFiles(dir_ni
->vol
)
1003 || !(fn
->file_attributes
& FILE_ATTR_HIDDEN
)))
1004 || (NVolShowSysFiles(dir_ni
->vol
) && (NVolShowHidFiles(dir_ni
->vol
)
1006 if (NVolCaseSensitive(dir_ni
->vol
)) {
1007 res
= filldir(dirent
, fn
->file_name
,
1008 fn
->file_name_length
,
1009 fn
->file_name_type
, *pos
,
1012 loname
= (ntfschar
*)ntfs_malloc(2*fn
->file_name_length
);
1014 memcpy(loname
, fn
->file_name
,
1015 2*fn
->file_name_length
);
1016 ntfs_name_locase(loname
, fn
->file_name_length
,
1017 dir_ni
->vol
->locase
,
1018 dir_ni
->vol
->upcase_len
);
1019 res
= filldir(dirent
, loname
,
1020 fn
->file_name_length
,
1021 fn
->file_name_type
, *pos
,
1033 * ntfs_mft_get_parent_ref - find mft reference of parent directory of an inode
1034 * @ni: ntfs inode whose parent directory to find
1036 * Find the parent directory of the ntfs inode @ni. To do this, find the first
1037 * file name attribute in the mft record of @ni and return the parent mft
1038 * reference from that.
1040 * Note this only makes sense for directories, since files can be hard linked
1041 * from multiple directories and there is no way for us to tell which one is
1044 * Technically directories can have hard links, too, but we consider that as
1045 * illegal as Linux/UNIX do not support directory hard links.
1047 * Return the mft reference of the parent directory on success or -1 on error
1048 * with errno set to the error code.
1050 static MFT_REF
ntfs_mft_get_parent_ref(ntfs_inode
*ni
)
1053 ntfs_attr_search_ctx
*ctx
;
1057 ntfs_log_trace("Entering.\n");
1061 return ERR_MREF(-1);
1064 ctx
= ntfs_attr_get_search_ctx(ni
, NULL
);
1066 return ERR_MREF(-1);
1067 if (ntfs_attr_lookup(AT_FILE_NAME
, AT_UNNAMED
, 0, 0, 0, NULL
, 0, ctx
)) {
1068 ntfs_log_error("No file name found in inode %lld\n",
1069 (unsigned long long)ni
->mft_no
);
1072 if (ctx
->attr
->non_resident
) {
1073 ntfs_log_error("File name attribute must be resident (inode "
1074 "%lld)\n", (unsigned long long)ni
->mft_no
);
1077 fn
= (FILE_NAME_ATTR
*)((u8
*)ctx
->attr
+
1078 le16_to_cpu(ctx
->attr
->value_offset
));
1079 if ((u8
*)fn
+ le32_to_cpu(ctx
->attr
->value_length
) >
1080 (u8
*)ctx
->attr
+ le32_to_cpu(ctx
->attr
->length
)) {
1081 ntfs_log_error("Corrupt file name attribute in inode %lld.\n",
1082 (unsigned long long)ni
->mft_no
);
1085 mref
= le64_to_cpu(fn
->parent_directory
);
1086 ntfs_attr_put_search_ctx(ctx
);
1092 ntfs_attr_put_search_ctx(ctx
);
1094 return ERR_MREF(-1);
1098 * ntfs_readdir - read the contents of an ntfs directory
1099 * @dir_ni: ntfs inode of current directory
1100 * @pos: current position in directory
1101 * @dirent: context for filldir callback supplied by the caller
1102 * @filldir: filldir callback supplied by the caller
1104 * Parse the index root and the index blocks that are marked in use in the
1105 * index bitmap and hand each found directory entry to the @filldir callback
1106 * supplied by the caller.
1108 * Return 0 on success or -1 on error with errno set to the error code.
1110 * Note: Index blocks are parsed in ascending vcn order, from which follows
1111 * that the directory entries are not returned sorted.
1113 int ntfs_readdir(ntfs_inode
*dir_ni
, s64
*pos
,
1114 void *dirent
, ntfs_filldir_t filldir
)
1116 s64 i_size
, br
, ia_pos
, bmp_pos
, ia_start
;
1118 ntfs_attr
*ia_na
, *bmp_na
= NULL
;
1119 ntfs_attr_search_ctx
*ctx
= NULL
;
1120 u8
*index_end
, *bmp
= NULL
;
1123 INDEX_ALLOCATION
*ia
= NULL
;
1124 int rc
, ir_pos
, bmp_buf_size
, bmp_buf_pos
, eo
;
1125 u32 index_block_size
;
1126 u8 index_block_size_bits
, index_vcn_size_bits
;
1128 ntfs_log_trace("Entering.\n");
1130 if (!dir_ni
|| !pos
|| !filldir
) {
1135 if (!(dir_ni
->mrec
->flags
& MFT_RECORD_IS_DIRECTORY
)) {
1142 ntfs_log_trace("Entering for inode %lld, *pos 0x%llx.\n",
1143 (unsigned long long)dir_ni
->mft_no
, (long long)*pos
);
1145 /* Open the index allocation attribute. */
1146 ia_na
= ntfs_attr_open(dir_ni
, AT_INDEX_ALLOCATION
, NTFS_INDEX_I30
, 4);
1148 if (errno
!= ENOENT
) {
1149 ntfs_log_perror("Failed to open index allocation attribute. "
1150 "Directory inode %lld is corrupt or bug",
1151 (unsigned long long)dir_ni
->mft_no
);
1156 i_size
= ia_na
->data_size
;
1160 /* Are we at end of dir yet? */
1161 if (*pos
>= i_size
+ vol
->mft_record_size
)
1164 /* Emulate . and .. for all directories. */
1166 rc
= filldir(dirent
, dotdot
, 1, FILE_NAME_POSIX
, *pos
,
1167 MK_MREF(dir_ni
->mft_no
,
1168 le16_to_cpu(dir_ni
->mrec
->sequence_number
)),
1175 MFT_REF parent_mref
;
1177 parent_mref
= ntfs_mft_get_parent_ref(dir_ni
);
1178 if (parent_mref
== ERR_MREF(-1)) {
1179 ntfs_log_perror("Parent directory not found");
1183 rc
= filldir(dirent
, dotdot
, 2, FILE_NAME_POSIX
, *pos
,
1184 parent_mref
, NTFS_DT_DIR
);
1190 ctx
= ntfs_attr_get_search_ctx(dir_ni
, NULL
);
1194 /* Get the offset into the index root attribute. */
1196 /* Find the index root attribute in the mft record. */
1197 if (ntfs_attr_lookup(AT_INDEX_ROOT
, NTFS_INDEX_I30
, 4, CASE_SENSITIVE
, 0, NULL
,
1199 ntfs_log_perror("Index root attribute missing in directory inode "
1200 "%lld", (unsigned long long)dir_ni
->mft_no
);
1203 /* Get to the index root value. */
1204 ir
= (INDEX_ROOT
*)((u8
*)ctx
->attr
+
1205 le16_to_cpu(ctx
->attr
->value_offset
));
1207 /* Determine the size of a vcn in the directory index. */
1208 index_block_size
= le32_to_cpu(ir
->index_block_size
);
1209 if (index_block_size
< NTFS_BLOCK_SIZE
||
1210 index_block_size
& (index_block_size
- 1)) {
1211 ntfs_log_error("Index block size %u is invalid.\n",
1212 (unsigned)index_block_size
);
1215 index_block_size_bits
= ffs(index_block_size
) - 1;
1216 if (vol
->cluster_size
<= index_block_size
) {
1217 index_vcn_size_bits
= vol
->cluster_size_bits
;
1219 index_vcn_size_bits
= NTFS_BLOCK_SIZE_BITS
;
1222 /* Are we jumping straight into the index allocation attribute? */
1223 if (*pos
>= vol
->mft_record_size
) {
1224 ntfs_attr_put_search_ctx(ctx
);
1226 goto skip_index_root
;
1229 index_end
= (u8
*)&ir
->index
+ le32_to_cpu(ir
->index
.index_length
);
1230 /* The first index entry. */
1231 ie
= (INDEX_ENTRY
*)((u8
*)&ir
->index
+
1232 le32_to_cpu(ir
->index
.entries_offset
));
1234 * Loop until we exceed valid memory (corruption case) or until we
1235 * reach the last entry or until filldir tells us it has had enough
1236 * or signals an error (both covered by the rc test).
1238 for (;; ie
= (INDEX_ENTRY
*)((u8
*)ie
+ le16_to_cpu(ie
->length
))) {
1239 ntfs_log_debug("In index root, offset %d.\n", (int)((u8
*)ie
- (u8
*)ir
));
1240 /* Bounds checks. */
1241 if ((u8
*)ie
< (u8
*)ctx
->mrec
|| (u8
*)ie
+
1242 sizeof(INDEX_ENTRY_HEADER
) > index_end
||
1243 (u8
*)ie
+ le16_to_cpu(ie
->key_length
) >
1246 /* The last entry cannot contain a name. */
1247 if (ie
->ie_flags
& INDEX_ENTRY_END
)
1250 if (!le16_to_cpu(ie
->length
))
1253 /* Skip index root entry if continuing previous readdir. */
1254 if (ir_pos
> (u8
*)ie
- (u8
*)ir
)
1257 * Submit the directory entry to ntfs_filldir(), which will
1258 * invoke the filldir() callback as appropriate.
1260 rc
= ntfs_filldir(dir_ni
, pos
, index_vcn_size_bits
,
1261 INDEX_TYPE_ROOT
, ir
, ie
, dirent
, filldir
);
1263 ntfs_attr_put_search_ctx(ctx
);
1268 ntfs_attr_put_search_ctx(ctx
);
1271 /* If there is no index allocation attribute we are finished. */
1275 /* Advance *pos to the beginning of the index allocation. */
1276 *pos
= vol
->mft_record_size
;
1283 /* Allocate a buffer for the current index block. */
1284 ia
= ntfs_malloc(index_block_size
);
1288 bmp_na
= ntfs_attr_open(dir_ni
, AT_BITMAP
, NTFS_INDEX_I30
, 4);
1290 ntfs_log_perror("Failed to open index bitmap attribute");
1294 /* Get the offset into the index allocation attribute. */
1295 ia_pos
= *pos
- vol
->mft_record_size
;
1297 bmp_pos
= ia_pos
>> index_block_size_bits
;
1298 if (bmp_pos
>> 3 >= bmp_na
->data_size
) {
1299 ntfs_log_error("Current index position exceeds index bitmap "
1304 bmp_buf_size
= min(bmp_na
->data_size
- (bmp_pos
>> 3), 4096);
1305 bmp
= ntfs_malloc(bmp_buf_size
);
1309 br
= ntfs_attr_pread(bmp_na
, bmp_pos
>> 3, bmp_buf_size
, bmp
);
1310 if (br
!= bmp_buf_size
) {
1313 ntfs_log_perror("Failed to read from index bitmap attribute");
1318 /* If the index block is not in use find the next one that is. */
1319 while (!(bmp
[bmp_buf_pos
>> 3] & (1 << (bmp_buf_pos
& 7)))) {
1320 find_next_index_buffer
:
1323 /* If we have reached the end of the bitmap, we are done. */
1324 if (bmp_pos
>> 3 >= bmp_na
->data_size
)
1326 ia_pos
= bmp_pos
<< index_block_size_bits
;
1327 if (bmp_buf_pos
>> 3 < bmp_buf_size
)
1329 /* Read next chunk from the index bitmap. */
1331 if ((bmp_pos
>> 3) + bmp_buf_size
> bmp_na
->data_size
)
1332 bmp_buf_size
= bmp_na
->data_size
- (bmp_pos
>> 3);
1333 br
= ntfs_attr_pread(bmp_na
, bmp_pos
>> 3, bmp_buf_size
, bmp
);
1334 if (br
!= bmp_buf_size
) {
1337 ntfs_log_perror("Failed to read from index bitmap attribute");
1342 ntfs_log_debug("Handling index block 0x%llx.\n", (long long)bmp_pos
);
1344 /* Read the index block starting at bmp_pos. */
1345 br
= ntfs_attr_mst_pread(ia_na
, bmp_pos
<< index_block_size_bits
, 1,
1346 index_block_size
, ia
);
1350 ntfs_log_perror("Failed to read index block");
1354 ia_start
= ia_pos
& ~(s64
)(index_block_size
- 1);
1355 if (sle64_to_cpu(ia
->index_block_vcn
) != ia_start
>>
1356 index_vcn_size_bits
) {
1357 ntfs_log_error("Actual VCN (0x%llx) of index buffer is different "
1358 "from expected VCN (0x%llx) in inode 0x%llx.\n",
1359 (long long)sle64_to_cpu(ia
->index_block_vcn
),
1360 (long long)ia_start
>> index_vcn_size_bits
,
1361 (unsigned long long)dir_ni
->mft_no
);
1364 if (le32_to_cpu(ia
->index
.allocated_size
) + 0x18 != index_block_size
) {
1365 ntfs_log_error("Index buffer (VCN 0x%llx) of directory inode %lld "
1366 "has a size (%u) differing from the directory "
1367 "specified size (%u).\n", (long long)ia_start
>>
1368 index_vcn_size_bits
,
1369 (unsigned long long)dir_ni
->mft_no
,
1370 (unsigned) le32_to_cpu(ia
->index
.allocated_size
)
1371 + 0x18, (unsigned)index_block_size
);
1374 index_end
= (u8
*)&ia
->index
+ le32_to_cpu(ia
->index
.index_length
);
1375 if (index_end
> (u8
*)ia
+ index_block_size
) {
1376 ntfs_log_error("Size of index buffer (VCN 0x%llx) of directory inode "
1377 "%lld exceeds maximum size.\n",
1378 (long long)ia_start
>> index_vcn_size_bits
,
1379 (unsigned long long)dir_ni
->mft_no
);
1382 /* The first index entry. */
1383 ie
= (INDEX_ENTRY
*)((u8
*)&ia
->index
+
1384 le32_to_cpu(ia
->index
.entries_offset
));
1386 * Loop until we exceed valid memory (corruption case) or until we
1387 * reach the last entry or until ntfs_filldir tells us it has had
1388 * enough or signals an error (both covered by the rc test).
1390 for (;; ie
= (INDEX_ENTRY
*)((u8
*)ie
+ le16_to_cpu(ie
->length
))) {
1391 ntfs_log_debug("In index allocation, offset 0x%llx.\n",
1392 (long long)ia_start
+ ((u8
*)ie
- (u8
*)ia
));
1393 /* Bounds checks. */
1394 if ((u8
*)ie
< (u8
*)ia
|| (u8
*)ie
+
1395 sizeof(INDEX_ENTRY_HEADER
) > index_end
||
1396 (u8
*)ie
+ le16_to_cpu(ie
->key_length
) >
1398 ntfs_log_error("Index entry out of bounds in directory inode "
1399 "%lld.\n", (unsigned long long)dir_ni
->mft_no
);
1402 /* The last entry cannot contain a name. */
1403 if (ie
->ie_flags
& INDEX_ENTRY_END
)
1406 if (!le16_to_cpu(ie
->length
))
1409 /* Skip index entry if continuing previous readdir. */
1410 if (ia_pos
- ia_start
> (u8
*)ie
- (u8
*)ia
)
1413 * Submit the directory entry to ntfs_filldir(), which will
1414 * invoke the filldir() callback as appropriate.
1416 rc
= ntfs_filldir(dir_ni
, pos
, index_vcn_size_bits
,
1417 INDEX_TYPE_ALLOCATION
, ia
, ie
, dirent
, filldir
);
1421 goto find_next_index_buffer
;
1423 /* We are finished, set *pos to EOD. */
1424 *pos
= i_size
+ vol
->mft_record_size
;
1429 ntfs_attr_close(bmp_na
);
1431 ntfs_attr_close(ia_na
);
1432 ntfs_log_debug("EOD, *pos 0x%llx, returning 0.\n", (long long)*pos
);
1438 ntfs_log_trace("failed.\n");
1440 ntfs_attr_put_search_ctx(ctx
);
1444 ntfs_attr_close(bmp_na
);
1446 ntfs_attr_close(ia_na
);
1453 * __ntfs_create - create object on ntfs volume
1454 * @dir_ni: ntfs inode for directory in which create new object
1455 * @securid: id of inheritable security descriptor, 0 if none
1456 * @name: unicode name of new object
1457 * @name_len: length of the name in unicode characters
1458 * @type: type of the object to create
1459 * @dev: major and minor device numbers (obtained from makedev())
1460 * @target: target in unicode (only for symlinks)
1461 * @target_len: length of target in unicode characters
1463 * Internal, use ntfs_create{,_device,_symlink} wrappers instead.
1466 * S_IFREG to create regular file
1467 * S_IFDIR to create directory
1468 * S_IFBLK to create block device
1469 * S_IFCHR to create character device
1470 * S_IFLNK to create symbolic link
1471 * S_IFIFO to create FIFO
1472 * S_IFSOCK to create socket
1473 * other values are invalid.
1475 * @dev is used only if @type is S_IFBLK or S_IFCHR, in other cases its value
1478 * @target and @target_len are used only if @type is S_IFLNK, in other cases
1479 * their value ignored.
1481 * Return opened ntfs inode that describes created object on success or NULL
1482 * on error with errno set to the error code.
1484 static ntfs_inode
*__ntfs_create(ntfs_inode
*dir_ni
, le32 securid
,
1485 const ntfschar
*name
, u8 name_len
, mode_t type
, dev_t dev
,
1486 const ntfschar
*target
, int target_len
)
1489 int rollback_data
= 0, rollback_sd
= 0;
1490 FILE_NAME_ATTR
*fn
= NULL
;
1491 STANDARD_INFORMATION
*si
= NULL
;
1492 int err
, fn_len
, si_len
;
1494 ntfs_log_trace("Entering.\n");
1496 /* Sanity checks. */
1497 if (!dir_ni
|| !name
|| !name_len
) {
1498 ntfs_log_error("Invalid arguments.\n");
1503 if (dir_ni
->flags
& FILE_ATTR_REPARSE_POINT
) {
1508 ni
= ntfs_mft_record_alloc(dir_ni
->vol
, NULL
);
1511 #if CACHE_NIDATA_SIZE
1512 ntfs_inode_invalidate(dir_ni
->vol
, ni
->mft_no
);
1515 * Create STANDARD_INFORMATION attribute.
1516 * JPA Depending on available inherited security descriptor,
1517 * Write STANDARD_INFORMATION v1.2 (no inheritance) or v3
1520 si_len
= sizeof(STANDARD_INFORMATION
);
1522 si_len
= offsetof(STANDARD_INFORMATION
, v1_end
);
1523 si
= ntfs_calloc(si_len
);
1528 si
->creation_time
= ni
->creation_time
;
1529 si
->last_data_change_time
= ni
->last_data_change_time
;
1530 si
->last_mft_change_time
= ni
->last_mft_change_time
;
1531 si
->last_access_time
= ni
->last_access_time
;
1533 set_nino_flag(ni
, v3_Extensions
);
1534 ni
->owner_id
= si
->owner_id
= 0;
1535 ni
->security_id
= si
->security_id
= securid
;
1536 ni
->quota_charged
= si
->quota_charged
= const_cpu_to_le64(0);
1537 ni
->usn
= si
->usn
= const_cpu_to_le64(0);
1539 clear_nino_flag(ni
, v3_Extensions
);
1540 if (!S_ISREG(type
) && !S_ISDIR(type
)) {
1541 si
->file_attributes
= FILE_ATTR_SYSTEM
;
1542 ni
->flags
= FILE_ATTR_SYSTEM
;
1544 ni
->flags
|= FILE_ATTR_ARCHIVE
;
1545 if (NVolHideDotFiles(dir_ni
->vol
)
1547 && (name
[0] == const_cpu_to_le16('.'))
1548 && (name
[1] != const_cpu_to_le16('.')))
1549 ni
->flags
|= FILE_ATTR_HIDDEN
;
1551 * Set compression flag according to parent directory
1552 * unless NTFS version < 3.0 or cluster size > 4K
1553 * or compression has been disabled
1555 if ((dir_ni
->flags
& FILE_ATTR_COMPRESSED
)
1556 && (dir_ni
->vol
->major_ver
>= 3)
1557 && NVolCompression(dir_ni
->vol
)
1558 && (dir_ni
->vol
->cluster_size
<= MAX_COMPRESSION_CLUSTER_SIZE
)
1559 && (S_ISREG(type
) || S_ISDIR(type
)))
1560 ni
->flags
|= FILE_ATTR_COMPRESSED
;
1561 /* Add STANDARD_INFORMATION to inode. */
1562 if (ntfs_attr_add(ni
, AT_STANDARD_INFORMATION
, AT_UNNAMED
, 0,
1565 ntfs_log_error("Failed to add STANDARD_INFORMATION "
1571 if (ntfs_sd_add_everyone(ni
)) {
1578 if (S_ISDIR(type
)) {
1579 INDEX_ROOT
*ir
= NULL
;
1581 int ir_len
, index_len
;
1583 /* Create INDEX_ROOT attribute. */
1584 index_len
= sizeof(INDEX_HEADER
) + sizeof(INDEX_ENTRY_HEADER
);
1585 ir_len
= offsetof(INDEX_ROOT
, index
) + index_len
;
1586 ir
= ntfs_calloc(ir_len
);
1591 ir
->type
= AT_FILE_NAME
;
1592 ir
->collation_rule
= COLLATION_FILE_NAME
;
1593 ir
->index_block_size
= cpu_to_le32(ni
->vol
->indx_record_size
);
1594 if (ni
->vol
->cluster_size
<= ni
->vol
->indx_record_size
)
1595 ir
->clusters_per_index_block
=
1596 ni
->vol
->indx_record_size
>>
1597 ni
->vol
->cluster_size_bits
;
1599 ir
->clusters_per_index_block
=
1600 ni
->vol
->indx_record_size
>>
1601 NTFS_BLOCK_SIZE_BITS
;
1602 ir
->index
.entries_offset
= cpu_to_le32(sizeof(INDEX_HEADER
));
1603 ir
->index
.index_length
= cpu_to_le32(index_len
);
1604 ir
->index
.allocated_size
= cpu_to_le32(index_len
);
1605 ie
= (INDEX_ENTRY
*)((u8
*)ir
+ sizeof(INDEX_ROOT
));
1606 ie
->length
= cpu_to_le16(sizeof(INDEX_ENTRY_HEADER
));
1608 ie
->ie_flags
= INDEX_ENTRY_END
;
1609 /* Add INDEX_ROOT attribute to inode. */
1610 if (ntfs_attr_add(ni
, AT_INDEX_ROOT
, NTFS_INDEX_I30
, 4,
1614 ntfs_log_error("Failed to add INDEX_ROOT attribute.\n");
1625 data_len
= offsetof(INTX_FILE
, device_end
);
1626 data
= ntfs_malloc(data_len
);
1631 data
->major
= cpu_to_le64(major(dev
));
1632 data
->minor
= cpu_to_le64(minor(dev
));
1633 if (type
== S_IFBLK
)
1634 data
->magic
= INTX_BLOCK_DEVICE
;
1635 if (type
== S_IFCHR
)
1636 data
->magic
= INTX_CHARACTER_DEVICE
;
1639 data_len
= sizeof(INTX_FILE_TYPES
) +
1640 target_len
* sizeof(ntfschar
);
1641 data
= ntfs_malloc(data_len
);
1646 data
->magic
= INTX_SYMBOLIC_LINK
;
1647 memcpy(data
->target
, target
,
1648 target_len
* sizeof(ntfschar
));
1654 default: /* FIFO or regular file. */
1659 /* Add DATA attribute to inode. */
1660 if (ntfs_attr_add(ni
, AT_DATA
, AT_UNNAMED
, 0, (u8
*)data
,
1663 ntfs_log_error("Failed to add DATA attribute.\n");
1670 /* Create FILE_NAME attribute. */
1671 fn_len
= sizeof(FILE_NAME_ATTR
) + name_len
* sizeof(ntfschar
);
1672 fn
= ntfs_calloc(fn_len
);
1677 fn
->parent_directory
= MK_LE_MREF(dir_ni
->mft_no
,
1678 le16_to_cpu(dir_ni
->mrec
->sequence_number
));
1679 fn
->file_name_length
= name_len
;
1680 fn
->file_name_type
= FILE_NAME_POSIX
;
1682 fn
->file_attributes
= FILE_ATTR_I30_INDEX_PRESENT
;
1683 if (!S_ISREG(type
) && !S_ISDIR(type
))
1684 fn
->file_attributes
= FILE_ATTR_SYSTEM
;
1686 fn
->file_attributes
|= ni
->flags
& FILE_ATTR_COMPRESSED
;
1687 fn
->file_attributes
|= FILE_ATTR_ARCHIVE
;
1688 fn
->file_attributes
|= ni
->flags
& FILE_ATTR_HIDDEN
;
1689 fn
->creation_time
= ni
->creation_time
;
1690 fn
->last_data_change_time
= ni
->last_data_change_time
;
1691 fn
->last_mft_change_time
= ni
->last_mft_change_time
;
1692 fn
->last_access_time
= ni
->last_access_time
;
1693 if (ni
->mrec
->flags
& MFT_RECORD_IS_DIRECTORY
)
1694 fn
->data_size
= fn
->allocated_size
= const_cpu_to_le64(0);
1696 fn
->data_size
= cpu_to_sle64(ni
->data_size
);
1697 fn
->allocated_size
= cpu_to_sle64(ni
->allocated_size
);
1699 memcpy(fn
->file_name
, name
, name_len
* sizeof(ntfschar
));
1700 /* Add FILE_NAME attribute to inode. */
1701 if (ntfs_attr_add(ni
, AT_FILE_NAME
, AT_UNNAMED
, 0, (u8
*)fn
, fn_len
)) {
1703 ntfs_log_error("Failed to add FILE_NAME attribute.\n");
1706 /* Add FILE_NAME attribute to index. */
1707 if (ntfs_index_add_filename(dir_ni
, fn
, MK_MREF(ni
->mft_no
,
1708 le16_to_cpu(ni
->mrec
->sequence_number
)))) {
1710 ntfs_log_perror("Failed to add entry to the index");
1713 /* Set hard links count and directory flag. */
1714 ni
->mrec
->link_count
= cpu_to_le16(1);
1716 ni
->mrec
->flags
|= MFT_RECORD_IS_DIRECTORY
;
1717 ntfs_inode_mark_dirty(ni
);
1721 ntfs_log_trace("Done.\n");
1724 ntfs_log_trace("Failed.\n");
1727 ntfs_attr_remove(ni
, AT_SECURITY_DESCRIPTOR
, AT_UNNAMED
, 0);
1730 ntfs_attr_remove(ni
, AT_DATA
, AT_UNNAMED
, 0);
1732 * Free extent MFT records (should not exist any with current
1733 * ntfs_create implementation, but for any case if something will be
1734 * changed in the future).
1736 while (ni
->nr_extents
)
1737 if (ntfs_mft_record_free(ni
->vol
, *(ni
->extent_nis
))) {
1739 ntfs_log_error("Failed to free extent MFT record. "
1740 "Leaving inconsistent metadata.\n");
1742 if (ntfs_mft_record_free(ni
->vol
, ni
))
1743 ntfs_log_error("Failed to free MFT record. "
1744 "Leaving inconsistent metadata. Run chkdsk.\n");
1752 * Some wrappers around __ntfs_create() ...
1755 ntfs_inode
*ntfs_create(ntfs_inode
*dir_ni
, le32 securid
, const ntfschar
*name
,
1756 u8 name_len
, mode_t type
)
1758 if (type
!= S_IFREG
&& type
!= S_IFDIR
&& type
!= S_IFIFO
&&
1760 ntfs_log_error("Invalid arguments.\n");
1763 return __ntfs_create(dir_ni
, securid
, name
, name_len
, type
, 0, NULL
, 0);
1766 ntfs_inode
*ntfs_create_device(ntfs_inode
*dir_ni
, le32 securid
,
1767 const ntfschar
*name
, u8 name_len
, mode_t type
, dev_t dev
)
1769 if (type
!= S_IFCHR
&& type
!= S_IFBLK
) {
1770 ntfs_log_error("Invalid arguments.\n");
1773 return __ntfs_create(dir_ni
, securid
, name
, name_len
, type
, dev
, NULL
, 0);
1776 ntfs_inode
*ntfs_create_symlink(ntfs_inode
*dir_ni
, le32 securid
,
1777 const ntfschar
*name
, u8 name_len
, const ntfschar
*target
,
1780 if (!target
|| !target_len
) {
1781 ntfs_log_error("%s: Invalid argument (%p, %d)\n", __FUNCTION__
,
1782 target
, target_len
);
1785 return __ntfs_create(dir_ni
, securid
, name
, name_len
, S_IFLNK
, 0,
1786 target
, target_len
);
1789 int ntfs_check_empty_dir(ntfs_inode
*ni
)
1794 if (!(ni
->mrec
->flags
& MFT_RECORD_IS_DIRECTORY
))
1797 na
= ntfs_attr_open(ni
, AT_INDEX_ROOT
, NTFS_INDEX_I30
, 4);
1800 ntfs_log_perror("Failed to open directory");
1804 /* Non-empty directory? */
1805 if ((na
->data_size
!= sizeof(INDEX_ROOT
) + sizeof(INDEX_ENTRY_HEADER
))){
1806 /* Both ENOTEMPTY and EEXIST are ok. We use the more common. */
1808 ntfs_log_debug("Directory is not empty\n");
1812 ntfs_attr_close(na
);
1816 static int ntfs_check_unlinkable_dir(ntfs_inode
*ni
, FILE_NAME_ATTR
*fn
)
1818 int link_count
= le16_to_cpu(ni
->mrec
->link_count
);
1821 ret
= ntfs_check_empty_dir(ni
);
1822 if (!ret
|| errno
!= ENOTEMPTY
)
1825 * Directory is non-empty, so we can unlink only if there is more than
1826 * one "real" hard link, i.e. links aren't different DOS and WIN32 names
1828 if ((link_count
== 1) ||
1829 (link_count
== 2 && fn
->file_name_type
== FILE_NAME_DOS
)) {
1831 ntfs_log_debug("Non-empty directory without hard links\n");
1841 * ntfs_delete - delete file or directory from ntfs volume
1842 * @ni: ntfs inode for object to delte
1843 * @dir_ni: ntfs inode for directory in which delete object
1844 * @name: unicode name of the object to delete
1845 * @name_len: length of the name in unicode characters
1847 * @ni is always closed after the call to this function (even if it failed),
1848 * user does not need to call ntfs_inode_close himself.
1850 * Return 0 on success or -1 on error with errno set to the error code.
1852 int ntfs_delete(ntfs_volume
*vol
, const char *pathname
,
1853 ntfs_inode
*ni
, ntfs_inode
*dir_ni
, const ntfschar
*name
,
1856 ntfs_attr_search_ctx
*actx
= NULL
;
1857 FILE_NAME_ATTR
*fn
= NULL
;
1858 BOOL looking_for_dos_name
= FALSE
, looking_for_win32_name
= FALSE
;
1859 BOOL case_sensitive_match
= TRUE
;
1861 #if CACHE_NIDATA_SIZE
1864 #if CACHE_INODE_SIZE
1865 struct CACHED_INODE item
;
1870 #if CACHE_LOOKUP_SIZE
1871 struct CACHED_LOOKUP lkitem
;
1874 ntfs_log_trace("Entering.\n");
1876 if (!ni
|| !dir_ni
|| !name
|| !name_len
) {
1877 ntfs_log_error("Invalid arguments.\n");
1881 if (ni
->nr_extents
== -1)
1883 if (dir_ni
->nr_extents
== -1)
1884 dir_ni
= dir_ni
->base_ni
;
1886 * Search for FILE_NAME attribute with such name. If it's in POSIX or
1887 * WIN32_AND_DOS namespace, then simply remove it from index and inode.
1888 * If filename in DOS or in WIN32 namespace, then remove DOS name first,
1889 * only then remove WIN32 name.
1891 actx
= ntfs_attr_get_search_ctx(ni
, NULL
);
1895 while (!ntfs_attr_lookup(AT_FILE_NAME
, AT_UNNAMED
, 0, CASE_SENSITIVE
,
1896 0, NULL
, 0, actx
)) {
1898 IGNORE_CASE_BOOL case_sensitive
= IGNORE_CASE
;
1901 fn
= (FILE_NAME_ATTR
*)((u8
*)actx
->attr
+
1902 le16_to_cpu(actx
->attr
->value_offset
));
1903 s
= ntfs_attr_name_get(fn
->file_name
, fn
->file_name_length
);
1904 ntfs_log_trace("name: '%s' type: %d dos: %d win32: %d "
1905 "case: %d\n", s
, fn
->file_name_type
,
1906 looking_for_dos_name
, looking_for_win32_name
,
1907 case_sensitive_match
);
1908 ntfs_attr_name_free(&s
);
1909 if (looking_for_dos_name
) {
1910 if (fn
->file_name_type
== FILE_NAME_DOS
)
1915 if (looking_for_win32_name
) {
1916 if (fn
->file_name_type
== FILE_NAME_WIN32
)
1922 /* Ignore hard links from other directories */
1923 if (dir_ni
->mft_no
!= MREF_LE(fn
->parent_directory
)) {
1924 ntfs_log_debug("MFT record numbers don't match "
1926 (long long unsigned)dir_ni
->mft_no
,
1927 (long long unsigned)MREF_LE(fn
->parent_directory
));
1930 if (case_sensitive_match
1931 || ((fn
->file_name_type
== FILE_NAME_POSIX
)
1932 && NVolCaseSensitive(ni
->vol
)))
1933 case_sensitive
= CASE_SENSITIVE
;
1935 if (ntfs_names_are_equal(fn
->file_name
, fn
->file_name_length
,
1936 name
, name_len
, case_sensitive
,
1937 ni
->vol
->upcase
, ni
->vol
->upcase_len
)){
1939 if (fn
->file_name_type
== FILE_NAME_WIN32
) {
1940 looking_for_dos_name
= TRUE
;
1941 ntfs_attr_reinit_search_ctx(actx
);
1944 if (fn
->file_name_type
== FILE_NAME_DOS
)
1945 looking_for_dos_name
= TRUE
;
1951 * If case sensitive search failed, then try once again
1954 if (errno
== ENOENT
&& case_sensitive_match
) {
1955 case_sensitive_match
= FALSE
;
1956 ntfs_attr_reinit_search_ctx(actx
);
1962 if (ntfs_check_unlinkable_dir(ni
, fn
) < 0)
1965 if (ntfs_index_remove(dir_ni
, ni
, fn
, le32_to_cpu(actx
->attr
->value_length
)))
1969 * Keep the last name in place, this is useful for undeletion
1970 * (Windows also does so), however delete the name if it were
1971 * in an extent, to avoid leaving an attribute list.
1973 if ((ni
->mrec
->link_count
== cpu_to_le16(1)) && !actx
->base_ntfs_ino
) {
1974 /* make sure to not loop to another search */
1975 looking_for_dos_name
= FALSE
;
1977 if (ntfs_attr_record_rm(actx
))
1981 ni
->mrec
->link_count
= cpu_to_le16(le16_to_cpu(
1982 ni
->mrec
->link_count
) - 1);
1984 ntfs_inode_mark_dirty(ni
);
1985 if (looking_for_dos_name
) {
1986 looking_for_dos_name
= FALSE
;
1987 looking_for_win32_name
= TRUE
;
1988 ntfs_attr_reinit_search_ctx(actx
);
1991 /* TODO: Update object id, quota and securiry indexes if required. */
1993 * If hard link count is not equal to zero then we are done. In other
1994 * case there are no reference to this inode left, so we should free all
1995 * non-resident attributes and mark all MFT record as not in use.
1997 #if CACHE_LOOKUP_SIZE
1998 /* invalidate entry in lookup cache */
1999 lkitem
.name
= (const char*)NULL
;
2000 lkitem
.namesize
= 0;
2001 lkitem
.inum
= ni
->mft_no
;
2002 lkitem
.parent
= dir_ni
->mft_no
;
2003 ntfs_invalidate_cache(vol
->lookup_cache
, GENERIC(&lkitem
),
2004 lookup_cache_inv_compare
, CACHE_NOHASH
);
2006 #if CACHE_INODE_SIZE
2009 /* invalide cache entry, even if there was an error */
2010 /* Remove leading /'s. */
2012 while (*p
== PATH_SEP
)
2014 if (p
[0] && (p
[strlen(p
)-1] == PATH_SEP
))
2015 ntfs_log_error("Unnormalized path %s\n",pathname
);
2017 item
.varsize
= strlen(p
);
2019 item
.pathname
= (const char*)NULL
;
2023 count
= ntfs_invalidate_cache(vol
->xinode_cache
, GENERIC(&item
),
2024 inode_cache_inv_compare
, CACHE_NOHASH
);
2025 if (pathname
&& !count
)
2026 ntfs_log_error("Could not delete inode cache entry for %s\n",
2029 if (ni
->mrec
->link_count
) {
2030 ntfs_inode_update_times(ni
, NTFS_UPDATE_CTIME
);
2033 if (ntfs_delete_reparse_index(ni
)) {
2035 * Failed to remove the reparse index : proceed anyway
2036 * This is not a critical error, the entry is useless
2037 * because of sequence_number, and stopping file deletion
2038 * would be much worse as the file is not referenced now.
2042 if (ntfs_delete_object_id_index(ni
)) {
2044 * Failed to remove the object id index : proceed anyway
2045 * This is not a critical error.
2049 ntfs_attr_reinit_search_ctx(actx
);
2050 while (!ntfs_attrs_walk(actx
)) {
2051 if (actx
->attr
->non_resident
) {
2054 rl
= ntfs_mapping_pairs_decompress(ni
->vol
, actx
->attr
,
2058 ntfs_log_error("Failed to decompress runlist. "
2059 "Leaving inconsistent metadata.\n");
2062 if (ntfs_cluster_free_from_rl(ni
->vol
, rl
)) {
2064 ntfs_log_error("Failed to free clusters. "
2065 "Leaving inconsistent metadata.\n");
2071 if (errno
!= ENOENT
) {
2073 ntfs_log_error("Attribute enumeration failed. "
2074 "Probably leaving inconsistent metadata.\n");
2076 /* All extents should be attached after attribute walk. */
2077 #if CACHE_NIDATA_SIZE
2079 * Disconnect extents before deleting them, so they are
2080 * not wrongly moved to cache through the chainings
2082 for (i
=ni
->nr_extents
-1; i
>=0; i
--) {
2083 ni
->extent_nis
[i
]->base_ni
= (ntfs_inode
*)NULL
;
2084 ni
->extent_nis
[i
]->nr_extents
= 0;
2085 if (ntfs_mft_record_free(ni
->vol
, ni
->extent_nis
[i
])) {
2087 ntfs_log_error("Failed to free extent MFT record. "
2088 "Leaving inconsistent metadata.\n");
2091 free(ni
->extent_nis
);
2093 ni
->extent_nis
= (ntfs_inode
**)NULL
;
2095 while (ni
->nr_extents
)
2096 if (ntfs_mft_record_free(ni
->vol
, *(ni
->extent_nis
))) {
2098 ntfs_log_error("Failed to free extent MFT record. "
2099 "Leaving inconsistent metadata.\n");
2102 debug_double_inode(ni
->mft_no
,0);
2103 if (ntfs_mft_record_free(ni
->vol
, ni
)) {
2105 ntfs_log_error("Failed to free base MFT record. "
2106 "Leaving inconsistent metadata.\n");
2110 ntfs_inode_update_times(dir_ni
, NTFS_UPDATE_MCTIME
);
2113 ntfs_attr_put_search_ctx(actx
);
2114 if (ntfs_inode_close(dir_ni
) && !err
)
2116 if (ntfs_inode_close(ni
) && !err
)
2120 ntfs_log_debug("Could not delete file: %s\n", strerror(errno
));
2123 ntfs_log_trace("Done.\n");
2131 * ntfs_link - create hard link for file or directory
2132 * @ni: ntfs inode for object to create hard link
2133 * @dir_ni: ntfs inode for directory in which new link should be placed
2134 * @name: unicode name of the new link
2135 * @name_len: length of the name in unicode characters
2137 * NOTE: At present we allow creating hardlinks to directories, we use them
2138 * in a temporary state during rename. But it's defenitely bad idea to have
2139 * hard links to directories as a result of operation.
2140 * FIXME: Create internal __ntfs_link that allows hard links to a directories
2141 * and external ntfs_link that do not. Write ntfs_rename that uses __ntfs_link.
2143 * Return 0 on success or -1 on error with errno set to the error code.
2145 static int ntfs_link_i(ntfs_inode
*ni
, ntfs_inode
*dir_ni
, const ntfschar
*name
,
2146 u8 name_len
, FILE_NAME_TYPE_FLAGS nametype
)
2148 FILE_NAME_ATTR
*fn
= NULL
;
2151 ntfs_log_trace("Entering.\n");
2153 if (!ni
|| !dir_ni
|| !name
|| !name_len
||
2154 ni
->mft_no
== dir_ni
->mft_no
) {
2156 ntfs_log_perror("ntfs_link wrong arguments");
2160 if ((ni
->flags
& FILE_ATTR_REPARSE_POINT
)
2161 && !ntfs_possible_symlink(ni
)) {
2165 if (NVolHideDotFiles(dir_ni
->vol
)) {
2166 /* Set hidden flag according to the latest name */
2168 && (name
[0] == const_cpu_to_le16('.'))
2169 && (name
[1] != const_cpu_to_le16('.')))
2170 ni
->flags
|= FILE_ATTR_HIDDEN
;
2172 ni
->flags
&= ~FILE_ATTR_HIDDEN
;
2175 /* Create FILE_NAME attribute. */
2176 fn_len
= sizeof(FILE_NAME_ATTR
) + name_len
* sizeof(ntfschar
);
2177 fn
= ntfs_calloc(fn_len
);
2182 fn
->parent_directory
= MK_LE_MREF(dir_ni
->mft_no
,
2183 le16_to_cpu(dir_ni
->mrec
->sequence_number
));
2184 fn
->file_name_length
= name_len
;
2185 fn
->file_name_type
= nametype
;
2186 fn
->file_attributes
= ni
->flags
;
2187 if (ni
->mrec
->flags
& MFT_RECORD_IS_DIRECTORY
) {
2188 fn
->file_attributes
|= FILE_ATTR_I30_INDEX_PRESENT
;
2189 fn
->data_size
= fn
->allocated_size
= const_cpu_to_le64(0);
2191 fn
->allocated_size
= cpu_to_sle64(ni
->allocated_size
);
2192 fn
->data_size
= cpu_to_sle64(ni
->data_size
);
2194 fn
->creation_time
= ni
->creation_time
;
2195 fn
->last_data_change_time
= ni
->last_data_change_time
;
2196 fn
->last_mft_change_time
= ni
->last_mft_change_time
;
2197 fn
->last_access_time
= ni
->last_access_time
;
2198 memcpy(fn
->file_name
, name
, name_len
* sizeof(ntfschar
));
2199 /* Add FILE_NAME attribute to index. */
2200 if (ntfs_index_add_filename(dir_ni
, fn
, MK_MREF(ni
->mft_no
,
2201 le16_to_cpu(ni
->mrec
->sequence_number
)))) {
2203 ntfs_log_perror("Failed to add filename to the index");
2206 /* Add FILE_NAME attribute to inode. */
2207 if (ntfs_attr_add(ni
, AT_FILE_NAME
, AT_UNNAMED
, 0, (u8
*)fn
, fn_len
)) {
2208 ntfs_log_error("Failed to add FILE_NAME attribute.\n");
2210 /* Try to remove just added attribute from index. */
2211 if (ntfs_index_remove(dir_ni
, ni
, fn
, fn_len
))
2212 goto rollback_failed
;
2215 /* Increment hard links count. */
2216 ni
->mrec
->link_count
= cpu_to_le16(le16_to_cpu(
2217 ni
->mrec
->link_count
) + 1);
2219 ntfs_inode_mark_dirty(ni
);
2221 ntfs_log_trace("Done.\n");
2224 ntfs_log_error("Rollback failed. Leaving inconsistent metadata.\n");
2231 int ntfs_link(ntfs_inode
*ni
, ntfs_inode
*dir_ni
, const ntfschar
*name
,
2234 return (ntfs_link_i(ni
, dir_ni
, name
, name_len
, FILE_NAME_POSIX
));
2238 * Get a parent directory from an inode entry
2240 * This is only used in situations where the path used to access
2241 * the current file is not known for sure. The result may be different
2242 * from the path when the file is linked in several parent directories.
2244 * Currently this is only used for translating ".." in the target
2245 * of a Vista relative symbolic link
2248 ntfs_inode
*ntfs_dir_parent_inode(ntfs_inode
*ni
)
2250 ntfs_inode
*dir_ni
= (ntfs_inode
*)NULL
;
2253 ntfs_attr_search_ctx
*ctx
;
2255 if (ni
->mft_no
!= FILE_root
) {
2256 /* find the name in the attributes */
2257 ctx
= ntfs_attr_get_search_ctx(ni
, NULL
);
2259 return ((ntfs_inode
*)NULL
);
2261 if (!ntfs_attr_lookup(AT_FILE_NAME
, AT_UNNAMED
, 0,
2262 CASE_SENSITIVE
, 0, NULL
, 0, ctx
)) {
2263 /* We know this will always be resident. */
2264 fn
= (FILE_NAME_ATTR
*)((u8
*)ctx
->attr
+
2265 le16_to_cpu(ctx
->attr
->value_offset
));
2266 inum
= le64_to_cpu(fn
->parent_directory
);
2267 if (inum
!= (u64
)-1) {
2268 dir_ni
= ntfs_inode_open(ni
->vol
, MREF(inum
));
2271 ntfs_attr_put_search_ctx(ctx
);
2276 #ifdef HAVE_SETXATTR
2278 #define MAX_DOS_NAME_LENGTH 12
2281 * Get a DOS name for a file in designated directory
2283 * Not allowed if there are several non-dos names (EMLINK)
2285 * Returns size if found
2287 * -1 if there was an error (described by errno)
2290 static int get_dos_name(ntfs_inode
*ni
, u64 dnum
, ntfschar
*dosname
)
2295 ntfs_attr_search_ctx
*ctx
;
2297 /* find the name in the attributes */
2298 ctx
= ntfs_attr_get_search_ctx(ni
, NULL
);
2302 while (!ntfs_attr_lookup(AT_FILE_NAME
, AT_UNNAMED
, 0, CASE_SENSITIVE
,
2304 /* We know this will always be resident. */
2305 fn
= (FILE_NAME_ATTR
*)((u8
*)ctx
->attr
+
2306 le16_to_cpu(ctx
->attr
->value_offset
));
2308 if (fn
->file_name_type
!= FILE_NAME_DOS
)
2310 if ((fn
->file_name_type
& FILE_NAME_DOS
)
2311 && (MREF_LE(fn
->parent_directory
) == dnum
)) {
2313 * Found a DOS or WIN32+DOS name for the entry
2314 * copy name, after truncation for safety
2316 outsize
= fn
->file_name_length
;
2317 /* TODO : reject if name is too long ? */
2318 if (outsize
> MAX_DOS_NAME_LENGTH
)
2319 outsize
= MAX_DOS_NAME_LENGTH
;
2320 memcpy(dosname
,fn
->file_name
,outsize
*sizeof(ntfschar
));
2323 ntfs_attr_put_search_ctx(ctx
);
2324 if ((outsize
> 0) && (namecount
> 1)) {
2326 errno
= EMLINK
; /* this error implies there is a dos name */
2333 * Get a long name for a file in designated directory
2335 * Not allowed if there are several non-dos names (EMLINK)
2337 * Returns size if found
2339 * -1 if there was an error (described by errno)
2342 static int get_long_name(ntfs_inode
*ni
, u64 dnum
, ntfschar
*longname
)
2347 ntfs_attr_search_ctx
*ctx
;
2349 /* find the name in the attributes */
2350 ctx
= ntfs_attr_get_search_ctx(ni
, NULL
);
2354 /* first search for WIN32 or DOS+WIN32 names */
2355 while (!ntfs_attr_lookup(AT_FILE_NAME
, AT_UNNAMED
, 0, CASE_SENSITIVE
,
2357 /* We know this will always be resident. */
2358 fn
= (FILE_NAME_ATTR
*)((u8
*)ctx
->attr
+
2359 le16_to_cpu(ctx
->attr
->value_offset
));
2361 if (fn
->file_name_type
!= FILE_NAME_DOS
)
2363 if ((fn
->file_name_type
& FILE_NAME_WIN32
)
2364 && (MREF_LE(fn
->parent_directory
) == dnum
)) {
2366 * Found a WIN32 or WIN32+DOS name for the entry
2369 outsize
= fn
->file_name_length
;
2370 memcpy(longname
,fn
->file_name
,outsize
*sizeof(ntfschar
));
2373 if (namecount
> 1) {
2374 ntfs_attr_put_search_ctx(ctx
);
2378 /* if not found search for POSIX names */
2380 ntfs_attr_reinit_search_ctx(ctx
);
2381 while (!ntfs_attr_lookup(AT_FILE_NAME
, AT_UNNAMED
, 0, CASE_SENSITIVE
,
2383 /* We know this will always be resident. */
2384 fn
= (FILE_NAME_ATTR
*)((u8
*)ctx
->attr
+
2385 le16_to_cpu(ctx
->attr
->value_offset
));
2387 if ((fn
->file_name_type
== FILE_NAME_POSIX
)
2388 && (MREF_LE(fn
->parent_directory
) == dnum
)) {
2390 * Found a POSIX name for the entry
2393 outsize
= fn
->file_name_length
;
2394 memcpy(longname
,fn
->file_name
,outsize
*sizeof(ntfschar
));
2398 ntfs_attr_put_search_ctx(ctx
);
2404 * Get the ntfs DOS name into an extended attribute
2407 int ntfs_get_ntfs_dos_name(ntfs_inode
*ni
, ntfs_inode
*dir_ni
,
2408 char *value
, size_t size
)
2411 char *outname
= (char*)NULL
;
2414 ntfschar dosname
[MAX_DOS_NAME_LENGTH
];
2416 dnum
= dir_ni
->mft_no
;
2417 doslen
= get_dos_name(ni
, dnum
, dosname
);
2420 * Found a DOS name for the entry, make
2421 * uppercase and encode into the buffer
2422 * if there is enough space
2424 ntfs_name_upcase(dosname
, doslen
,
2425 ni
->vol
->upcase
, ni
->vol
->upcase_len
);
2426 if (ntfs_ucstombs(dosname
, doslen
, &outname
, size
) < 0) {
2427 ntfs_log_error("Cannot represent dosname in current locale.\n");
2430 outsize
= strlen(outname
);
2431 if (value
&& (outsize
<= (int)size
))
2432 memcpy(value
, outname
, outsize
);
2434 if (size
&& (outsize
> (int)size
))
2447 * Change the name space of an existing file or directory
2449 * Returns the old namespace if successful
2450 * -1 if an error occurred (described by errno)
2453 static int set_namespace(ntfs_inode
*ni
, ntfs_inode
*dir_ni
,
2454 const ntfschar
*name
, int len
,
2455 FILE_NAME_TYPE_FLAGS nametype
)
2457 ntfs_attr_search_ctx
*actx
;
2458 ntfs_index_context
*icx
;
2459 FILE_NAME_ATTR
*fnx
;
2460 FILE_NAME_ATTR
*fn
= NULL
;
2466 actx
= ntfs_attr_get_search_ctx(ni
, NULL
);
2470 lkup
= ntfs_attr_lookup(AT_FILE_NAME
, AT_UNNAMED
, 0,
2471 CASE_SENSITIVE
, 0, NULL
, 0, actx
);
2473 fn
= (FILE_NAME_ATTR
*)((u8
*)actx
->attr
+
2474 le16_to_cpu(actx
->attr
->value_offset
));
2475 found
= (MREF_LE(fn
->parent_directory
)
2477 && !memcmp(fn
->file_name
, name
,
2478 len
*sizeof(ntfschar
));
2480 } while (!lkup
&& !found
);
2482 icx
= ntfs_index_ctx_get(dir_ni
, NTFS_INDEX_I30
, 4);
2484 lkup
= ntfs_index_lookup((char*)fn
, len
, icx
);
2485 if (!lkup
&& icx
->data
&& icx
->data_len
) {
2486 fnx
= (FILE_NAME_ATTR
*)icx
->data
;
2487 ret
= fn
->file_name_type
;
2488 fn
->file_name_type
= nametype
;
2489 fnx
->file_name_type
= nametype
;
2490 ntfs_inode_mark_dirty(ni
);
2491 ntfs_index_entry_mark_dirty(icx
);
2493 ntfs_index_ctx_put(icx
);
2496 ntfs_attr_put_search_ctx(actx
);
2502 * Set a DOS name to a file and adjust name spaces
2504 * If the new names are collapsible (same uppercased chars) :
2506 * - the existing DOS name or DOS+Win32 name is made Posix
2507 * - if it was a real DOS name, the existing long name is made DOS+Win32
2508 * and the existing DOS name is deleted
2509 * - finally the existing long name is made DOS+Win32 unless already done
2511 * If the new names are not collapsible :
2513 * - insert the short name as a DOS name
2514 * - delete the old long name or existing short name
2515 * - insert the new long name (as a Win32 or DOS+Win32 name)
2517 * Deleting the old long name will not delete the file
2518 * provided the old name was in the Posix name space,
2519 * because the alternate name has been set before.
2521 * The inodes of file and parent directory are always closed
2523 * Returns 0 if successful
2527 static int set_dos_name(ntfs_inode
*ni
, ntfs_inode
*dir_ni
,
2528 const ntfschar
*shortname
, int shortlen
,
2529 const ntfschar
*longname
, int longlen
,
2530 const ntfschar
*deletename
, int deletelen
, BOOL existed
)
2532 unsigned int linkcount
;
2537 FILE_NAME_TYPE_FLAGS oldnametype
;
2544 dnum
= dir_ni
->mft_no
;
2546 /* save initial link count */
2547 linkcount
= le16_to_cpu(ni
->mrec
->link_count
);
2549 /* check whether the same name may be used as DOS and WIN32 */
2550 collapsible
= ntfs_collapsible_chars(ni
->vol
, shortname
, shortlen
,
2556 oldnametype
= set_namespace(ni
, dir_ni
, deletename
,
2557 deletelen
, FILE_NAME_POSIX
);
2558 if (oldnametype
== FILE_NAME_DOS
) {
2559 if (set_namespace(ni
, dir_ni
, longname
, longlen
,
2560 FILE_NAME_WIN32_AND_DOS
) >= 0) {
2561 if (!ntfs_delete(vol
,
2562 (const char*)NULL
, ni
, dir_ni
,
2563 deletename
, deletelen
))
2571 if (!done
&& (set_namespace(ni
, dir_ni
,
2573 FILE_NAME_WIN32_AND_DOS
) >= 0))
2575 ntfs_inode_update_times(ni
, NTFS_UPDATE_CTIME
);
2576 ntfs_inode_update_times(dir_ni
, NTFS_UPDATE_MCTIME
);
2577 if (ntfs_inode_close_in_dir(ni
,dir_ni
) && !res
)
2579 if (ntfs_inode_close(dir_ni
) && !res
)
2583 if (!ntfs_link_i(ni
, dir_ni
, shortname
, shortlen
,
2585 /* make sure a new link was recorded */
2586 && (le16_to_cpu(ni
->mrec
->link_count
) > linkcount
)) {
2587 /* delete the existing long name or short name */
2588 // is it ok to not provide the path ?
2589 if (!ntfs_delete(vol
, (char*)NULL
, ni
, dir_ni
,
2590 deletename
, deletelen
)) {
2591 /* delete closes the inodes, so have to open again */
2592 dir_ni
= ntfs_inode_open(vol
, dnum
);
2594 ni
= ntfs_inode_open(vol
, fnum
);
2596 if (!ntfs_link_i(ni
, dir_ni
,
2600 if (ntfs_inode_close_in_dir(ni
,
2605 if (ntfs_inode_close(dir_ni
) && !res
)
2610 ntfs_inode_close_in_dir(ni
,dir_ni
);
2611 ntfs_inode_close(dir_ni
);
2619 * Set the ntfs DOS name into an extended attribute
2621 * The DOS name will be added as another file name attribute
2622 * using the existing file name information from the original
2623 * name or overwriting the DOS Name if one exists.
2625 * The inode of the file is always closed
2628 int ntfs_set_ntfs_dos_name(ntfs_inode
*ni
, ntfs_inode
*dir_ni
,
2629 const char *value
, size_t size
, int flags
)
2634 char newname
[3*MAX_DOS_NAME_LENGTH
+ 1];
2635 ntfschar oldname
[MAX_DOS_NAME_LENGTH
];
2638 BOOL closed
= FALSE
;
2639 ntfschar
*shortname
= NULL
;
2640 ntfschar longname
[NTFS_MAX_NAME_LEN
];
2642 /* copy the string to insert a null char, and truncate */
2643 if (size
> 3*MAX_DOS_NAME_LENGTH
)
2644 size
= 3*MAX_DOS_NAME_LENGTH
;
2645 strncpy(newname
, value
, size
);
2646 /* a long name may be truncated badly and be untranslatable */
2648 /* convert the string to the NTFS wide chars, and truncate */
2649 shortlen
= ntfs_mbstoucs(newname
, &shortname
);
2650 if (shortlen
> MAX_DOS_NAME_LENGTH
)
2651 shortlen
= MAX_DOS_NAME_LENGTH
;
2652 /* make sure the short name has valid chars */
2653 if ((shortlen
< 0) || ntfs_forbidden_chars(shortname
,shortlen
)) {
2654 ntfs_inode_close_in_dir(ni
,dir_ni
);
2655 ntfs_inode_close(dir_ni
);
2659 dnum
= dir_ni
->mft_no
;
2660 longlen
= get_long_name(ni
, dnum
, longname
);
2662 oldlen
= get_dos_name(ni
, dnum
, oldname
);
2664 && !ntfs_forbidden_chars(longname
, longlen
)) {
2666 if (flags
& XATTR_CREATE
) {
2670 if ((shortlen
== oldlen
)
2671 && !memcmp(shortname
,oldname
,
2672 oldlen
*sizeof(ntfschar
)))
2673 /* already set, done */
2676 res
= set_dos_name(ni
, dir_ni
,
2677 shortname
, shortlen
,
2679 oldname
, oldlen
, TRUE
);
2683 if (flags
& XATTR_REPLACE
) {
2687 res
= set_dos_name(ni
, dir_ni
,
2688 shortname
, shortlen
,
2690 longname
, longlen
, FALSE
);
2703 ntfs_inode_close_in_dir(ni
,dir_ni
);
2704 ntfs_inode_close(dir_ni
);
2706 return (res
? -1 : 0);
2710 * Delete the ntfs DOS name
2713 int ntfs_remove_ntfs_dos_name(ntfs_inode
*ni
, ntfs_inode
*dir_ni
)
2721 BOOL deleted
= FALSE
;
2722 ntfschar shortname
[MAX_DOS_NAME_LENGTH
];
2723 ntfschar longname
[NTFS_MAX_NAME_LEN
];
2727 dnum
= dir_ni
->mft_no
;
2728 longlen
= get_long_name(ni
, dnum
, longname
);
2730 shortlen
= get_dos_name(ni
, dnum
, shortname
);
2731 if (shortlen
>= 0) {
2732 /* migrate the long name as Posix */
2733 oldnametype
= set_namespace(ni
,dir_ni
,longname
,longlen
,
2735 switch (oldnametype
) {
2736 case FILE_NAME_WIN32_AND_DOS
:
2737 /* name was Win32+DOS : done */
2740 case FILE_NAME_DOS
:
2741 /* name was DOS, make it back to DOS */
2742 set_namespace(ni
,dir_ni
,longname
,longlen
,
2746 case FILE_NAME_WIN32
:
2747 /* name was Win32, make it Posix and delete */
2748 if (set_namespace(ni
,dir_ni
,shortname
,shortlen
,
2749 FILE_NAME_POSIX
) >= 0) {
2750 if (!ntfs_delete(vol
,
2751 (const char*)NULL
, ni
,
2758 * DOS name has been found, but cannot
2759 * migrate to Posix : something bad
2763 ntfs_log_error("Could not change"
2764 " DOS name of inode %lld to Posix\n",
2765 (long long)ni
->mft_no
);
2769 /* name was Posix or not found : error */
2780 ntfs_inode_close_in_dir(ni
,dir_ni
);
2781 ntfs_inode_close(dir_ni
);