1 /**
2 * dir.c - Directory handling code. Part of the Linux-NTFS project.
3 *
4 * Copyright (c) 2002-2005 Anton Altaparmakov
5 * Copyright (c) 2005-2007 Yura Pakhuchiy
6 * Copyright (c) 2004-2005 Richard Russon
7 *
8 * This program/include file is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as published
10 * by the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program/include file is distributed in the hope that it will be
14 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
15 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program (in the main directory of the Linux-NTFS
20 * distribution in the file COPYING); if not, write to the Free Software
21 * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #ifdef HAVE_STDLIB_H
29 #include <stdlib.h>
30 #endif
31 #ifdef HAVE_ERRNO_H
32 #include <errno.h>
33 #endif
34 #ifdef HAVE_STRING_H
35 #include <string.h>
36 #endif
37 #ifdef HAVE_SYS_STAT_H
38 #include <sys/stat.h>
39 #endif
40
41 #ifdef HAVE_SYS_SYSMACROS_H
42 #include <sys/sysmacros.h>
43 #endif
44
45 #include "compat.h"
46 #include "types.h"
47 #include "debug.h"
48 #include "attrib.h"
49 #include "inode.h"
50 #include "dir.h"
51 #include "volume.h"
52 #include "mft.h"
53 #include "index.h"
54 #include "ntfstime.h"
55 #include "lcnalloc.h"
56 #include "logging.h"
57
58 /*
59 * The little endian Unicode strings "$I30", "$SII", "$SDH", "$O"
60 * and "$Q" as global constants.
61 */
62 ntfschar NTFS_INDEX_I30[5] = { const_cpu_to_le16('$'), const_cpu_to_le16('I'),
63 const_cpu_to_le16('3'), const_cpu_to_le16('0'),
64 const_cpu_to_le16('\0') };
65 ntfschar NTFS_INDEX_SII[5] = { const_cpu_to_le16('$'), const_cpu_to_le16('S'),
66 const_cpu_to_le16('I'), const_cpu_to_le16('I'),
67 const_cpu_to_le16('\0') };
68 ntfschar NTFS_INDEX_SDH[5] = { const_cpu_to_le16('$'), const_cpu_to_le16('S'),
69 const_cpu_to_le16('D'), const_cpu_to_le16('H'),
70 const_cpu_to_le16('\0') };
71 ntfschar NTFS_INDEX_O[3] = { const_cpu_to_le16('$'), const_cpu_to_le16('O'),
72 const_cpu_to_le16('\0') };
73 ntfschar NTFS_INDEX_Q[3] = { const_cpu_to_le16('$'), const_cpu_to_le16('Q'),
74 const_cpu_to_le16('\0') };
75 ntfschar NTFS_INDEX_R[3] = { const_cpu_to_le16('$'), const_cpu_to_le16('R'),
76 const_cpu_to_le16('\0') };
77
78 /**
79 * ntfs_inode_lookup_by_name - find an inode in a directory given its name
80 * @dir_ni: ntfs inode of the directory in which to search for the name
81 * @uname: Unicode name for which to search in the directory
82 * @uname_len: length of the name @uname in Unicode characters
83 *
84 * Look for an inode with name @uname in the directory with inode @dir_ni.
85 * ntfs_inode_lookup_by_name() walks the contents of the directory looking for
86 * the Unicode name. If the name is found in the directory, the corresponding
87 * inode number (>= 0) is returned as a mft reference in cpu format, i.e. it
88 * is a 64-bit number containing the sequence number.
89 *
90 * On error, return -1 with errno set to the error code. If the inode is is not
91 * found errno is ENOENT.
92 *
93 * Note, @uname_len does not include the (optional) terminating NULL character.
94 *
95 * Note, we look for a case sensitive match first but we also look for a case
96 * insensitive match at the same time. If we find a case insensitive match, we
97 * save that for the case that we don't find an exact match, where we return
98 * the mft reference of the case insensitive match.
99 *
100 * If the volume is mounted with the case sensitive flag set, then we only
101 * allow exact matches.
102 */
ntfs_inode_lookup_by_name(ntfs_inode * dir_ni,const ntfschar * uname,const int uname_len)103 u64 ntfs_inode_lookup_by_name(ntfs_inode *dir_ni, const ntfschar *uname,
104 const int uname_len)
105 {
106 VCN vcn;
107 u64 mref = 0;
108 s64 br;
109 ntfs_volume *vol = dir_ni->vol;
110 ntfs_attr_search_ctx *ctx;
111 INDEX_ROOT *ir;
112 INDEX_ENTRY *ie;
113 INDEX_ALLOCATION *ia;
114 u8 *index_end;
115 ntfs_attr *ia_na;
116 int eo, rc;
117 u32 index_block_size, index_vcn_size;
118 u8 index_vcn_size_bits;
119
120 if (!dir_ni || !dir_ni->mrec || !uname || uname_len <= 0) {
121 errno = EINVAL;
122 return -1;
123 }
124
125 ctx = ntfs_attr_get_search_ctx(dir_ni, NULL);
126 if (!ctx)
127 return -1;
128
129 /* Find the index root attribute in the mft record. */
130 if (ntfs_attr_lookup(AT_INDEX_ROOT, NTFS_INDEX_I30, 4, CASE_SENSITIVE,
131 0, NULL, 0, ctx)) {
132 ntfs_log_perror("Index root attribute missing in directory "
133 "inode 0x%llx", (unsigned long long)dir_ni->
134 mft_no);
135 goto put_err_out;
136 }
137 /* Get to the index root value. */
138 ir = (INDEX_ROOT*)((u8*)ctx->attr +
139 le16_to_cpu(ctx->attr->u.res.value_offset));
140 index_block_size = le32_to_cpu(ir->index_block_size);
141 if (index_block_size < NTFS_BLOCK_SIZE ||
142 index_block_size & (index_block_size - 1)) {
143 ntfs_log_debug("Index block size %u is invalid.\n",
144 (unsigned)index_block_size);
145 goto put_err_out;
146 }
147 index_end = (u8*)&ir->index + le32_to_cpu(ir->index.index_length);
148 /* The first index entry. */
149 ie = (INDEX_ENTRY*)((u8*)&ir->index +
150 le32_to_cpu(ir->index.entries_offset));
151 /*
152 * Loop until we exceed valid memory (corruption case) or until we
153 * reach the last entry.
154 */
155 for (;; ie = (INDEX_ENTRY*)((u8*)ie + le16_to_cpu(ie->length))) {
156 /* Bounds checks. */
157 if ((u8*)ie < (u8*)ctx->mrec || (u8*)ie +
158 sizeof(INDEX_ENTRY_HEADER) > index_end ||
159 (u8*)ie + le16_to_cpu(ie->key_length) >
160 index_end)
161 goto put_err_out;
162 /*
163 * The last entry cannot contain a name. It can however contain
164 * a pointer to a child node in the B+tree so we just break out.
165 */
166 if (ie->flags & INDEX_ENTRY_END)
167 break;
168 /*
169 * We perform a case sensitive comparison and if that matches
170 * we are done and return the mft reference of the inode (i.e.
171 * the inode number together with the sequence number for
172 * consistency checking). We convert it to cpu format before
173 * returning.
174 */
175 if (ntfs_names_are_equal(uname, uname_len,
176 (ntfschar*)&ie->key.file_name.file_name,
177 ie->key.file_name.file_name_length,
178 CASE_SENSITIVE, vol->upcase, vol->upcase_len)) {
179 found_it:
180 /*
181 * We have a perfect match, so we don't need to care
182 * about having matched imperfectly before.
183 */
184 mref = le64_to_cpu(ie->u.indexed_file);
185 ntfs_attr_put_search_ctx(ctx);
186 return mref;
187 }
188 /*
189 * For a case insensitive mount, we also perform a case
190 * insensitive comparison. If the comparison matches, we cache
191 * the mft reference in mref. Use first case insensitive match
192 * in case if no name matches case sensitive, but several names
193 * matches case insensitive.
194 */
195 if (!mref && !NVolCaseSensitive(vol) &&
196 ntfs_names_are_equal(uname, uname_len,
197 (ntfschar*)&ie->key.file_name.file_name,
198 ie->key.file_name.file_name_length,
199 IGNORE_CASE, vol->upcase, vol->upcase_len))
200 mref = le64_to_cpu(ie->u.indexed_file);
201 /*
202 * Not a perfect match, need to do full blown collation so we
203 * know which way in the B+tree we have to go.
204 */
205 rc = ntfs_names_collate(uname, uname_len,
206 (ntfschar*)&ie->key.file_name.file_name,
207 ie->key.file_name.file_name_length, 1,
208 IGNORE_CASE, vol->upcase, vol->upcase_len);
209 /*
210 * If uname collates before the name of the current entry, there
211 * is definitely no such name in this index but we might need to
212 * descend into the B+tree so we just break out of the loop.
213 */
214 if (rc == -1)
215 break;
216 /* The names are not equal, continue the search. */
217 if (rc)
218 continue;
219 /*
220 * Names match with case insensitive comparison, now try the
221 * case sensitive comparison, which is required for proper
222 * collation.
223 */
224 rc = ntfs_names_collate(uname, uname_len,
225 (ntfschar*)&ie->key.file_name.file_name,
226 ie->key.file_name.file_name_length, 1,
227 CASE_SENSITIVE, vol->upcase, vol->upcase_len);
228 if (rc == -1)
229 break;
230 if (rc)
231 continue;
232 /*
233 * Perfect match, this will never happen as the
234 * ntfs_are_names_equal() call will have gotten a match but we
235 * still treat it correctly.
236 */
237 goto found_it;
238 }
239 /*
240 * We have finished with this index without success. Check for the
241 * presence of a child node and if not present return error code
242 * ENOENT, unless we have got the mft reference of a matching name
243 * cached in mref in which case return mref.
244 */
245 if (!(ie->flags & INDEX_ENTRY_NODE)) {
246 ntfs_attr_put_search_ctx(ctx);
247 if (mref)
248 return mref;
249 ntfs_log_debug("Entry not found.\n");
250 errno = ENOENT;
251 return -1;
252 } /* Child node present, descend into it. */
253
254 /* Open the index allocation attribute. */
255 ia_na = ntfs_attr_open(dir_ni, AT_INDEX_ALLOCATION, NTFS_INDEX_I30, 4);
256 if (!ia_na) {
257 ntfs_log_perror("Failed to open index allocation attribute. "
258 "Directory inode 0x%llx is corrupt or driver "
259 "bug", (unsigned long long)dir_ni->mft_no);
260 goto put_err_out;
261 }
262
263 /* Allocate a buffer for the current index block. */
264 ia = (INDEX_ALLOCATION*)malloc(index_block_size);
265 if (!ia) {
266 ntfs_log_perror("Failed to allocate buffer for index block");
267 ntfs_attr_close(ia_na);
268 goto put_err_out;
269 }
270
271 /* Determine the size of a vcn in the directory index. */
272 if (vol->cluster_size <= index_block_size) {
273 index_vcn_size = vol->cluster_size;
274 index_vcn_size_bits = vol->cluster_size_bits;
275 } else {
276 index_vcn_size = vol->sector_size;
277 index_vcn_size_bits = vol->sector_size_bits;
278 }
279
280 /* Get the starting vcn of the index_block holding the child node. */
281 vcn = sle64_to_cpup((u8*)ie + le16_to_cpu(ie->length) - 8);
282
283 descend_into_child_node:
284
285 /* Read the index block starting at vcn. */
286 br = ntfs_attr_mst_pread(ia_na, vcn << index_vcn_size_bits, 1,
287 index_block_size, ia);
288 if (br != 1) {
289 if (br != -1)
290 errno = EIO;
291 ntfs_log_perror("Failed to read vcn 0x%llx",
292 (unsigned long long)vcn);
293 goto close_err_out;
294 }
295
296 if (sle64_to_cpu(ia->index_block_vcn) != vcn) {
297 ntfs_log_debug("Actual VCN (0x%llx) of index buffer is "
298 "different from expected VCN (0x%llx).\n",
299 (long long)sle64_to_cpu(ia->index_block_vcn),
300 (long long)vcn);
301 errno = EIO;
302 goto close_err_out;
303 }
304 if (le32_to_cpu(ia->index.allocated_size) + 0x18 != index_block_size) {
305 ntfs_log_debug("Index buffer (VCN 0x%llx) of directory inode "
306 "0x%llx has a size (%u) differing from the "
307 "directory specified size (%u).\n",
308 (long long)vcn, (unsigned long long)dir_ni->
309 mft_no, (unsigned)le32_to_cpu(ia->index.
310 allocated_size) + 0x18, (unsigned)
311 index_block_size);
312 errno = EIO;
313 goto close_err_out;
314 }
315 index_end = (u8*)&ia->index + le32_to_cpu(ia->index.index_length);
316 if (index_end > (u8*)ia + index_block_size) {
317 ntfs_log_debug("Size of index buffer (VCN 0x%llx) of directory "
318 "inode 0x%llx exceeds maximum size.\n",
319 (long long)vcn, (unsigned long long)dir_ni->
320 mft_no);
321 errno = EIO;
322 goto close_err_out;
323 }
324
325 /* The first index entry. */
326 ie = (INDEX_ENTRY*)((u8*)&ia->index +
327 le32_to_cpu(ia->index.entries_offset));
328 /*
329 * Iterate similar to above big loop but applied to index buffer, thus
330 * loop until we exceed valid memory (corruption case) or until we
331 * reach the last entry.
332 */
333 for (;; ie = (INDEX_ENTRY*)((u8*)ie + le16_to_cpu(ie->length))) {
334 /* Bounds check. */
335 if ((u8*)ie < (u8*)ia || (u8*)ie +
336 sizeof(INDEX_ENTRY_HEADER) > index_end ||
337 (u8*)ie + le16_to_cpu(ie->key_length) >
338 index_end) {
339 ntfs_log_debug("Index entry out of bounds in directory "
340 "inode 0x%llx.\n",
341 (unsigned long long)dir_ni->mft_no);
342 errno = EIO;
343 goto close_err_out;
344 }
345 /*
346 * The last entry cannot contain a name. It can however contain
347 * a pointer to a child node in the B+tree so we just break out.
348 */
349 if (ie->flags & INDEX_ENTRY_END)
350 break;
351 /*
352 * We perform a case sensitive comparison and if that matches
353 * we are done and return the mft reference of the inode (i.e.
354 * the inode number together with the sequence number for
355 * consistency checking). We convert it to cpu format before
356 * returning.
357 */
358 if (ntfs_names_are_equal(uname, uname_len,
359 (ntfschar*)&ie->key.file_name.file_name,
360 ie->key.file_name.file_name_length,
361 CASE_SENSITIVE, vol->upcase, vol->upcase_len)) {
362 found_it2:
363 /*
364 * We have a perfect match, so we don't need to care
365 * about having matched imperfectly before.
366 */
367 mref = le64_to_cpu(ie->u.indexed_file);
368 free(ia);
369 ntfs_attr_close(ia_na);
370 ntfs_attr_put_search_ctx(ctx);
371 return mref;
372 }
373 /*
374 * For a case insensitive mount, we also perform a case
375 * insensitive comparison. If the comparison matches, we cache
376 * the mft reference in mref. Use first case insensitive match
377 * in case if no name matches case sensitive, but several names
378 * matches case insensitive.
379 */
380 if (!mref && !NVolCaseSensitive(vol) &&
381 ntfs_names_are_equal(uname, uname_len,
382 (ntfschar*)&ie->key.file_name.file_name,
383 ie->key.file_name.file_name_length,
384 IGNORE_CASE, vol->upcase, vol->upcase_len))
385 mref = le64_to_cpu(ie->u.indexed_file);
386 /*
387 * Not a perfect match, need to do full blown collation so we
388 * know which way in the B+tree we have to go.
389 */
390 rc = ntfs_names_collate(uname, uname_len,
391 (ntfschar*)&ie->key.file_name.file_name,
392 ie->key.file_name.file_name_length, 1,
393 IGNORE_CASE, vol->upcase, vol->upcase_len);
394 /*
395 * If uname collates before the name of the current entry, there
396 * is definitely no such name in this index but we might need to
397 * descend into the B+tree so we just break out of the loop.
398 */
399 if (rc == -1)
400 break;
401 /* The names are not equal, continue the search. */
402 if (rc)
403 continue;
404 /*
405 * Names match with case insensitive comparison, now try the
406 * case sensitive comparison, which is required for proper
407 * collation.
408 */
409 rc = ntfs_names_collate(uname, uname_len,
410 (ntfschar*)&ie->key.file_name.file_name,
411 ie->key.file_name.file_name_length, 1,
412 CASE_SENSITIVE, vol->upcase, vol->upcase_len);
413 if (rc == -1)
414 break;
415 if (rc)
416 continue;
417 /*
418 * Perfect match, this will never happen as the
419 * ntfs_are_names_equal() call will have gotten a match but we
420 * still treat it correctly.
421 */
422 goto found_it2;
423 }
424 /*
425 * We have finished with this index buffer without success. Check for
426 * the presence of a child node.
427 */
428 if (ie->flags & INDEX_ENTRY_NODE) {
429 if ((ia->index.flags & NODE_MASK) == LEAF_NODE) {
430 ntfs_log_debug("Index entry with child node found in a "
431 "leaf node in directory inode "
432 "0x%llx.\n",
433 (unsigned long long)dir_ni->mft_no);
434 errno = EIO;
435 goto close_err_out;
436 }
437 /* Child node present, descend into it. */
438 vcn = sle64_to_cpup((u8*)ie + le16_to_cpu(ie->length) - 8);
439 if (vcn >= 0)
440 goto descend_into_child_node;
441 ntfs_log_debug("Negative child node vcn in directory inode "
442 "0x%llx.\n", (unsigned long long)dir_ni->
443 mft_no);
444 errno = EIO;
445 goto close_err_out;
446 }
447 free(ia);
448 ntfs_attr_close(ia_na);
449 ntfs_attr_put_search_ctx(ctx);
450 /*
451 * No child node present, return error code ENOENT, unless we have got
452 * the mft reference of a matching name cached in mref in which case
453 * return mref.
454 */
455 if (mref)
456 return mref;
457 ntfs_log_debug("Entry not found.\n");
458 errno = ENOENT;
459 return -1;
460 put_err_out:
461 eo = EIO;
462 ntfs_log_debug("Corrupt directory. Aborting lookup.\n");
463 eo_put_err_out:
464 ntfs_attr_put_search_ctx(ctx);
465 errno = eo;
466 return -1;
467 close_err_out:
468 eo = errno;
469 free(ia);
470 ntfs_attr_close(ia_na);
471 goto eo_put_err_out;
472 }
473
474 /**
475 * ntfs_pathname_to_inode_num - find the inode number which represents the
476 * given pathname
477 * @vol: An ntfs volume obtained from ntfs_mount
478 * @parent: A directory inode to begin the search (may be NULL)
479 * @pathname: Pathname to be located
480 *
481 * Take an ASCII pathname and find the inode that represents it. The function
482 * splits the path and then descends the directory tree. If @parent is NULL,
483 * then the root directory '.' will be used as the base for the search.
484 *
485 * Return: -1 Error, the pathname was invalid, or some other error occurred
486 * else Success, the pathname was valid
487 */
ntfs_pathname_to_inode_num(ntfs_volume * vol,ntfs_inode * parent,const char * pathname)488 u64 ntfs_pathname_to_inode_num(ntfs_volume *vol, ntfs_inode *parent,
489 const char *pathname)
490 {
491 u64 inum, result;
492 int len, err = 0;
493 char *p, *q;
494 ntfs_inode *ni = NULL;
495 ntfschar *unicode = NULL;
496 char *ascii = NULL;
497
498 inum = result = (u64)-1;
499 if (!vol || !pathname) {
500 err = EINVAL;
501 goto close;
502 }
503 ntfs_log_trace("Path: '%s'\n", pathname);
504 if (parent) {
505 ni = parent;
506 } else
507 inum = FILE_root;
508 unicode = calloc(1, MAX_PATH);
509 ascii = strdup(pathname);
510 if (!unicode || !ascii) {
511 ntfs_log_error("Out of memory.\n");
512 err = ENOMEM;
513 goto close;
514 }
515 p = ascii;
516 /* Remove leading /'s. */
517 while (p && *p == PATH_SEP)
518 p++;
519 while (p && *p) {
520 if (!ni) {
521 ni = ntfs_inode_open(vol, inum);
522 if (!ni) {
523 ntfs_log_debug("Cannot open inode %llu.\n",
524 (unsigned long long)inum);
525 err = EIO;
526 goto close;
527 }
528 }
529 /* Find the end of the first token. */
530 q = strchr(p, PATH_SEP);
531 if (q != NULL) {
532 *q = 0;
533 q++;
534 }
535 len = ntfs_mbstoucs(p, &unicode, MAX_PATH);
536 if (len < 0) {
537 ntfs_log_debug("Couldn't convert name to Unicode: "
538 "%s.\n", p);
539 err = EILSEQ;
540 goto close;
541 }
542 inum = ntfs_inode_lookup_by_name(ni, unicode, len);
543 if (inum == (u64)-1) {
544 ntfs_log_debug("Couldn't find name '%s' in pathname "
545 "'%s'.\n", p, pathname);
546 err = ENOENT;
547 goto close;
548 }
549 inum = MREF(inum);
550 if (ni != parent)
551 ntfs_inode_close(ni);
552 ni = NULL;
553 p = q;
554 while (p && *p == PATH_SEP)
555 p++;
556 }
557 result = inum;
558 close:
559 if (ni && (ni != parent))
560 ntfs_inode_close(ni);
561 free(ascii);
562 free(unicode);
563 if (err)
564 errno = err;
565 return result;
566 }
567
568 /**
569 * ntfs_pathname_to_inode - Find the inode which represents the given pathname
570 * @vol: An ntfs volume obtained from ntfs_mount
571 * @parent: A directory inode to begin the search (may be NULL)
572 * @pathname: Pathname to be located
573 *
574 * Take an ASCII pathname and find the inode that represents it. The function
575 * splits the path and then descends the directory tree. If @parent is NULL,
576 * then the root directory '.' will be used as the base for the search.
577 *
578 * Return: inode Success, the pathname was valid
579 * NULL Error, the pathname was invalid, or some other error occurred
580 */
ntfs_pathname_to_inode(ntfs_volume * vol,ntfs_inode * parent,const char * pathname)581 ntfs_inode *ntfs_pathname_to_inode(ntfs_volume *vol, ntfs_inode *parent,
582 const char *pathname)
583 {
584 u64 inum;
585
586 inum = ntfs_pathname_to_inode_num(vol, parent, pathname);
587 if (inum == (u64)-1)
588 return NULL;
589 return ntfs_inode_open(vol, inum);
590 }
591
592 /*
593 * The little endian Unicode string ".." for ntfs_readdir().
594 */
595 static const ntfschar dotdot[3] = { const_cpu_to_le16('.'),
596 const_cpu_to_le16('.'),
597 const_cpu_to_le16('\0') };
598
599 /**
600 * ntfs_filldir - ntfs specific filldir method
601 * @vol: ntfs volume with wjich we are working
602 * @pos: current position in directory
603 * @ie: current index entry
604 * @dirent: context for filldir callback supplied by the caller
605 * @filldir: filldir callback supplied by the caller
606 *
607 * Pass information specifying the current directory entry @ie to the @filldir
608 * callback.
609 */
ntfs_filldir(ntfs_volume * vol,s64 * pos,INDEX_ENTRY * ie,void * dirent,ntfs_filldir_t filldir)610 static int ntfs_filldir(ntfs_volume *vol, s64 *pos, INDEX_ENTRY *ie,
611 void *dirent, ntfs_filldir_t filldir)
612 {
613 FILE_NAME_ATTR *fn = &ie->key.file_name;
614 unsigned dt_type;
615
616 ntfs_log_trace("Entering.\n");
617
618 /* Skip root directory self reference entry. */
619 if (MREF_LE(ie->u.indexed_file) == FILE_root)
620 return 0;
621 if (ie->key.file_name.file_attributes & FILE_ATTR_I30_INDEX_PRESENT)
622 dt_type = NTFS_DT_DIR;
623 else {
624 if (NVolInterix(vol) && fn->file_attributes & FILE_ATTR_SYSTEM)
625 dt_type = NTFS_DT_UNKNOWN;
626 else
627 dt_type = NTFS_DT_REG;
628 }
629 return filldir(dirent, fn->file_name, fn->file_name_length,
630 fn->file_name_type, *pos,
631 le64_to_cpu(ie->u.indexed_file), dt_type);
632 }
633
634 /**
635 * ntfs_mft_get_parent_ref - find mft reference of parent directory of an inode
636 * @ni: ntfs inode whose parent directory to find
637 *
638 * Find the parent directory of the ntfs inode @ni. To do this, find the first
639 * file name attribute in the mft record of @ni and return the parent mft
640 * reference from that.
641 *
642 * Note this only makes sense for directories, since files can be hard linked
643 * from multiple directories and there is no way for us to tell which one is
644 * being looked for.
645 *
646 * Technically directories can have hard links, too, but we consider that as
647 * illegal as Linux/UNIX do not support directory hard links.
648 *
649 * Return the mft reference of the parent directory on success or -1 on error
650 * with errno set to the error code.
651 */
ntfs_mft_get_parent_ref(ntfs_inode * ni)652 static MFT_REF ntfs_mft_get_parent_ref(ntfs_inode *ni)
653 {
654 MFT_REF mref;
655 ntfs_attr_search_ctx *ctx;
656 FILE_NAME_ATTR *fn;
657 int eo;
658
659 ntfs_log_trace("Entering.\n");
660
661 if (!ni) {
662 errno = EINVAL;
663 return ERR_MREF(-1);
664 }
665
666 ctx = ntfs_attr_get_search_ctx(ni, NULL);
667 if (!ctx)
668 return ERR_MREF(-1);
669 if (ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0, 0, 0, NULL, 0, ctx)) {
670 ntfs_log_debug("No file name found in inode 0x%llx. Corrupt "
671 "inode.\n", (unsigned long long)ni->mft_no);
672 goto err_out;
673 }
674 if (ctx->attr->non_resident) {
675 ntfs_log_debug("File name attribute must be resident. "
676 "Corrupt inode 0x%llx.\n",
677 (unsigned long long)ni->mft_no);
678 goto io_err_out;
679 }
680 fn = (FILE_NAME_ATTR*)((u8*)ctx->attr +
681 le16_to_cpu(ctx->attr->u.res.value_offset));
682 if ((u8*)fn + le32_to_cpu(ctx->attr->u.res.value_length) >
683 (u8*)ctx->attr + le32_to_cpu(ctx->attr->length)) {
684 ntfs_log_debug("Corrupt file name attribute in inode 0x%llx.\n",
685 (unsigned long long)ni->mft_no);
686 goto io_err_out;
687 }
688 mref = le64_to_cpu(fn->parent_directory);
689 ntfs_attr_put_search_ctx(ctx);
690 return mref;
691 io_err_out:
692 errno = EIO;
693 err_out:
694 eo = errno;
695 ntfs_attr_put_search_ctx(ctx);
696 errno = eo;
697 return ERR_MREF(-1);
698 }
699
700 /**
701 * ntfs_readdir - read the contents of an ntfs directory
702 * @dir_ni: ntfs inode of current directory
703 * @pos: current position in directory
704 * @dirent: context for filldir callback supplied by the caller
705 * @filldir: filldir callback supplied by the caller
706 *
707 * Parse the index root and the index blocks that are marked in use in the
708 * index bitmap and hand each found directory entry to the @filldir callback
709 * supplied by the caller.
710 *
711 * Return 0 on success or -1 on error with errno set to the error code.
712 *
713 * Note: Index blocks are parsed in ascending vcn order, from which follows
714 * that the directory entries are not returned sorted.
715 */
ntfs_readdir(ntfs_inode * dir_ni,s64 * pos,void * dirent,ntfs_filldir_t filldir)716 int ntfs_readdir(ntfs_inode *dir_ni, s64 *pos,
717 void *dirent, ntfs_filldir_t filldir)
718 {
719 s64 i_size, br, ia_pos, bmp_pos, ia_start;
720 ntfs_volume *vol;
721 ntfs_attr *ia_na, *bmp_na = NULL;
722 ntfs_attr_search_ctx *ctx = NULL;
723 u8 *index_end, *bmp = NULL;
724 INDEX_ROOT *ir;
725 INDEX_ENTRY *ie;
726 INDEX_ALLOCATION *ia = NULL;
727 int rc, ir_pos, bmp_buf_size, bmp_buf_pos, eo;
728 u32 index_block_size, index_vcn_size;
729 u8 index_block_size_bits, index_vcn_size_bits;
730
731 ntfs_log_trace("Entering.\n");
732
733 if (!dir_ni || !pos || !filldir) {
734 errno = EINVAL;
735 return -1;
736 }
737
738 if (!(dir_ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)) {
739 errno = ENOTDIR;
740 return -1;
741 }
742
743 vol = dir_ni->vol;
744
745 ntfs_log_trace("Entering for inode 0x%llx, *pos 0x%llx.\n",
746 (unsigned long long)dir_ni->mft_no, (long long)*pos);
747
748 /* Open the index allocation attribute. */
749 ia_na = ntfs_attr_open(dir_ni, AT_INDEX_ALLOCATION, NTFS_INDEX_I30, 4);
750 if (!ia_na) {
751 if (errno != ENOENT) {
752 ntfs_log_perror("Failed to open index allocation "
753 "attribute. Directory inode 0x%llx is "
754 "corrupt or bug", (unsigned long long)
755 dir_ni->mft_no);
756 return -1;
757 }
758 i_size = 0;
759 } else
760 i_size = ia_na->data_size;
761
762 rc = 0;
763
764 /* Are we at end of dir yet? */
765 if (*pos >= i_size + vol->mft_record_size)
766 goto done;
767
768 /* Emulate . and .. for all directories. */
769 if (!*pos) {
770 rc = filldir(dirent, dotdot, 1, FILE_NAME_POSIX, *pos,
771 MK_MREF(dir_ni->mft_no,
772 le16_to_cpu(dir_ni->mrec->sequence_number)),
773 NTFS_DT_DIR);
774 if (rc)
775 goto err_out;
776 ++*pos;
777 }
778 if (*pos == 1) {
779 MFT_REF parent_mref;
780
781 parent_mref = ntfs_mft_get_parent_ref(dir_ni);
782 if (parent_mref == ERR_MREF(-1)) {
783 ntfs_log_perror("Parent directory not found");
784 goto dir_err_out;
785 }
786
787 rc = filldir(dirent, dotdot, 2, FILE_NAME_POSIX, *pos,
788 parent_mref, NTFS_DT_DIR);
789 if (rc)
790 goto err_out;
791 ++*pos;
792 }
793
794 ctx = ntfs_attr_get_search_ctx(dir_ni, NULL);
795 if (!ctx)
796 goto err_out;
797
798 /* Get the offset into the index root attribute. */
799 ir_pos = (int)*pos;
800 /* Find the index root attribute in the mft record. */
801 if (ntfs_attr_lookup(AT_INDEX_ROOT, NTFS_INDEX_I30, 4, CASE_SENSITIVE,
802 0, NULL, 0, ctx)) {
803 ntfs_log_debug("Index root attribute missing in directory "
804 "inode 0x%llx.\n", (unsigned long long)dir_ni->
805 mft_no);
806 goto dir_err_out;
807 }
808 /* Get to the index root value. */
809 ir = (INDEX_ROOT*)((u8*)ctx->attr +
810 le16_to_cpu(ctx->attr->u.res.value_offset));
811
812 /* Determine the size of a vcn in the directory index. */
813 index_block_size = le32_to_cpu(ir->index_block_size);
814 if (index_block_size < NTFS_BLOCK_SIZE ||
815 index_block_size & (index_block_size - 1)) {
816 ntfs_log_debug("Index block size %u is invalid.\n",
817 (unsigned)index_block_size);
818 goto dir_err_out;
819 }
820 index_block_size_bits = ffs(index_block_size) - 1;
821 if (vol->cluster_size <= index_block_size) {
822 index_vcn_size = vol->cluster_size;
823 index_vcn_size_bits = vol->cluster_size_bits;
824 } else {
825 index_vcn_size = vol->sector_size;
826 index_vcn_size_bits = vol->sector_size_bits;
827 }
828
829 /* Are we jumping straight into the index allocation attribute? */
830 if (*pos >= vol->mft_record_size) {
831 ntfs_attr_put_search_ctx(ctx);
832 ctx = NULL;
833 goto skip_index_root;
834 }
835
836 index_end = (u8*)&ir->index + le32_to_cpu(ir->index.index_length);
837 /* The first index entry. */
838 ie = (INDEX_ENTRY*)((u8*)&ir->index +
839 le32_to_cpu(ir->index.entries_offset));
840 /*
841 * Loop until we exceed valid memory (corruption case) or until we
842 * reach the last entry or until filldir tells us it has had enough
843 * or signals an error (both covered by the rc test).
844 */
845 for (;; ie = (INDEX_ENTRY*)((u8*)ie + le16_to_cpu(ie->length))) {
846 ntfs_log_debug("In index root, offset 0x%x.\n",
847 (u8*)ie - (u8*)ir);
848 /* Bounds checks. */
849 if ((u8*)ie < (u8*)ctx->mrec || (u8*)ie +
850 sizeof(INDEX_ENTRY_HEADER) > index_end ||
851 (u8*)ie + le16_to_cpu(ie->key_length) >
852 index_end)
853 goto dir_err_out;
854 /* The last entry cannot contain a name. */
855 if (ie->flags & INDEX_ENTRY_END)
856 break;
857 /* Skip index root entry if continuing previous readdir. */
858 if (ir_pos > (u8*)ie - (u8*)ir)
859 continue;
860 /* Advance the position even if going to skip the entry. */
861 *pos = (u8*)ie - (u8*)ir;
862 /*
863 * Submit the directory entry to ntfs_filldir(), which will
864 * invoke the filldir() callback as appropriate.
865 */
866 rc = ntfs_filldir(vol, pos, ie, dirent, filldir);
867 if (rc)
868 goto err_out;
869 }
870 ntfs_attr_put_search_ctx(ctx);
871 ctx = NULL;
872
873 /* If there is no index allocation attribute we are finished. */
874 if (!ia_na)
875 goto EOD;
876
877 /* Advance *pos to the beginning of the index allocation. */
878 *pos = vol->mft_record_size;
879
880 skip_index_root:
881
882 if (!ia_na)
883 goto done;
884
885 /* Allocate a buffer for the current index block. */
886 ia = (INDEX_ALLOCATION*)malloc(index_block_size);
887 if (!ia) {
888 ntfs_log_perror("Failed to allocate buffer for index block");
889 goto err_out;
890 }
891
892 bmp_na = ntfs_attr_open(dir_ni, AT_BITMAP, NTFS_INDEX_I30, 4);
893 if (!bmp_na) {
894 ntfs_log_perror("Failed to open index bitmap attribute");
895 goto dir_err_out;
896 }
897
898 /* Get the offset into the index allocation attribute. */
899 ia_pos = *pos - vol->mft_record_size;
900
901 bmp_pos = ia_pos >> index_block_size_bits;
902 if (bmp_pos >> 3 >= bmp_na->data_size) {
903 ntfs_log_debug("Current index position exceeds index bitmap "
904 "size.\n");
905 goto dir_err_out;
906 }
907
908 bmp_buf_size = min(bmp_na->data_size - (bmp_pos >> 3), 4096);
909 bmp = (u8*)malloc(bmp_buf_size);
910 if (!bmp) {
911 ntfs_log_perror("Failed to allocate bitmap buffer");
912 goto err_out;
913 }
914
915 br = ntfs_attr_pread(bmp_na, bmp_pos >> 3, bmp_buf_size, bmp);
916 if (br != bmp_buf_size) {
917 if (br != -1)
918 errno = EIO;
919 ntfs_log_perror("Failed to read from index bitmap attribute");
920 goto err_out;
921 }
922
923 bmp_buf_pos = 0;
924 /* If the index block is not in use find the next one that is. */
925 while (!(bmp[bmp_buf_pos >> 3] & (1 << (bmp_buf_pos & 7)))) {
926 find_next_index_buffer:
927 bmp_pos++;
928 bmp_buf_pos++;
929 /* If we have reached the end of the bitmap, we are done. */
930 if (bmp_pos >> 3 >= bmp_na->data_size)
931 goto EOD;
932 ia_pos = bmp_pos << index_block_size_bits;
933 if (bmp_buf_pos >> 3 < bmp_buf_size)
934 continue;
935 /* Read next chunk from the index bitmap. */
936 if ((bmp_pos >> 3) + bmp_buf_size > bmp_na->data_size)
937 bmp_buf_size = bmp_na->data_size - (bmp_pos >> 3);
938 br = ntfs_attr_pread(bmp_na, bmp_pos >> 3, bmp_buf_size, bmp);
939 if (br != bmp_buf_size) {
940 if (br != -1)
941 errno = EIO;
942 ntfs_log_perror("Failed to read from index bitmap "
943 "attribute");
944 goto err_out;
945 }
946 }
947
948 ntfs_log_debug("Handling index block 0x%llx.\n", (long long)bmp_pos);
949
950 /* Read the index block starting at bmp_pos. */
951 br = ntfs_attr_mst_pread(ia_na, bmp_pos << index_block_size_bits, 1,
952 index_block_size, ia);
953 if (br != 1) {
954 if (br != -1)
955 errno = EIO;
956 ntfs_log_perror("Failed to read index block");
957 goto err_out;
958 }
959
960 ia_start = ia_pos & ~(s64)(index_block_size - 1);
961 if (sle64_to_cpu(ia->index_block_vcn) != ia_start >>
962 index_vcn_size_bits) {
963 ntfs_log_debug("Actual VCN (0x%llx) of index buffer is "
964 "different from expected VCN (0x%llx) in "
965 "inode 0x%llx.\n",
966 (long long)sle64_to_cpu(ia->index_block_vcn),
967 (long long)ia_start >> index_vcn_size_bits,
968 (unsigned long long)dir_ni->mft_no);
969 goto dir_err_out;
970 }
971 if (le32_to_cpu(ia->index.allocated_size) + 0x18 != index_block_size) {
972 ntfs_log_debug("Index buffer (VCN 0x%llx) of directory inode "
973 "0x%llx has a size (%u) differing from the "
974 "directory specified size (%u).\n",
975 (long long)ia_start >> index_vcn_size_bits,
976 (unsigned long long)dir_ni->mft_no,
977 (unsigned) le32_to_cpu(ia->index.allocated_size)
978 + 0x18, (unsigned)index_block_size);
979 goto dir_err_out;
980 }
981 index_end = (u8*)&ia->index + le32_to_cpu(ia->index.index_length);
982 if (index_end > (u8*)ia + index_block_size) {
983 ntfs_log_debug("Size of index buffer (VCN 0x%llx) of directory "
984 "inode 0x%llx exceeds maximum size.\n",
985 (long long)ia_start >> index_vcn_size_bits,
986 (unsigned long long)dir_ni->mft_no);
987 goto dir_err_out;
988 }
989 /* The first index entry. */
990 ie = (INDEX_ENTRY*)((u8*)&ia->index +
991 le32_to_cpu(ia->index.entries_offset));
992 /*
993 * Loop until we exceed valid memory (corruption case) or until we
994 * reach the last entry or until ntfs_filldir tells us it has had
995 * enough or signals an error (both covered by the rc test).
996 */
997 for (;; ie = (INDEX_ENTRY*)((u8*)ie + le16_to_cpu(ie->length))) {
998 ntfs_log_debug("In index allocation, offset 0x%llx.\n",
999 (long long)ia_start + ((u8*)ie - (u8*)ia));
1000 /* Bounds checks. */
1001 if ((u8*)ie < (u8*)ia || (u8*)ie +
1002 sizeof(INDEX_ENTRY_HEADER) > index_end ||
1003 (u8*)ie + le16_to_cpu(ie->key_length) >
1004 index_end) {
1005 ntfs_log_debug("Index entry out of bounds in directory "
1006 "inode 0x%llx.\n", (unsigned long long)
1007 dir_ni->mft_no);
1008 goto dir_err_out;
1009 }
1010 /* The last entry cannot contain a name. */
1011 if (ie->flags & INDEX_ENTRY_END)
1012 break;
1013 /* Skip index entry if continuing previous readdir. */
1014 if (ia_pos - ia_start > (u8*)ie - (u8*)ia)
1015 continue;
1016 /* Advance the position even if going to skip the entry. */
1017 *pos = (u8*)ie - (u8*)ia + (sle64_to_cpu(
1018 ia->index_block_vcn) << index_vcn_size_bits) +
1019 dir_ni->vol->mft_record_size;
1020 /*
1021 * Submit the directory entry to ntfs_filldir(), which will
1022 * invoke the filldir() callback as appropriate.
1023 */
1024 rc = ntfs_filldir(vol, pos, ie, dirent, filldir);
1025 if (rc)
1026 goto err_out;
1027 }
1028 goto find_next_index_buffer;
1029 EOD:
1030 /* We are finished, set *pos to EOD. */
1031 *pos = i_size + vol->mft_record_size;
1032 done:
1033 free(ia);
1034 free(bmp);
1035 if (bmp_na)
1036 ntfs_attr_close(bmp_na);
1037 if (ia_na)
1038 ntfs_attr_close(ia_na);
1039 ntfs_log_debug("EOD, *pos 0x%llx, returning 0.\n", (long long)*pos);
1040 return 0;
1041 dir_err_out:
1042 errno = EIO;
1043 err_out:
1044 eo = errno;
1045 if (rc)
1046 ntfs_log_trace("filldir returned %i, *pos 0x%llx.", rc,
1047 (long long)*pos);
1048 ntfs_log_trace("Failed.\n");
1049 if (ctx)
1050 ntfs_attr_put_search_ctx(ctx);
1051 free(ia);
1052 free(bmp);
1053 if (bmp_na)
1054 ntfs_attr_close(bmp_na);
1055 if (ia_na)
1056 ntfs_attr_close(ia_na);
1057 errno = eo;
1058 return -1;
1059 }
1060
1061 /**
1062 * __ntfs_create - create object on ntfs volume
1063 * @dir_ni: ntfs inode for directory in which create new object
1064 * @name: unicode name of new object
1065 * @name_len: length of the name in unicode characters
1066 * @type: type of the object to create
1067 * @dev: major and minor device numbers (obtained from makedev())
1068 * @target: target in unicode (only for symlinks)
1069 * @target_len: length of target in unicode characters
1070 *
1071 * Internal, use ntfs_create{,_device,_symlink} wrappers instead.
1072 *
1073 * @type can be:
1074 * S_IFREG to create regular file
1075 * S_IFDIR to create directory
1076 * S_IFBLK to create block device
1077 * S_IFCHR to create character device
1078 * S_IFLNK to create symbolic link
1079 * S_IFIFO to create FIFO
1080 * S_IFSOCK to create socket
1081 * other values are invalid.
1082 *
1083 * @dev is used only if @type is S_IFBLK or S_IFCHR, in other cases its value
1084 * ignored.
1085 *
1086 * @target and @target_len are used only if @type is S_IFLNK, in other cases
1087 * their value ignored.
1088 *
1089 * Return opened ntfs inode that describes created object on success or NULL
1090 * on error with errno set to the error code.
1091 */
__ntfs_create(ntfs_inode * dir_ni,ntfschar * name,u8 name_len,dev_t type,dev_t dev,ntfschar * target,u8 target_len)1092 static ntfs_inode *__ntfs_create(ntfs_inode *dir_ni,
1093 ntfschar *name, u8 name_len, dev_t type, dev_t dev,
1094 ntfschar *target, u8 target_len)
1095 {
1096 ntfs_inode *ni;
1097 int rollback_data = 0, rollback_sd = 0;
1098 FILE_NAME_ATTR *fn = NULL;
1099 STANDARD_INFORMATION *si = NULL;
1100 SECURITY_DESCRIPTOR_ATTR *sd = NULL;
1101 ACL *acl;
1102 ACCESS_ALLOWED_ACE *ace;
1103 SID *sid;
1104 int err, fn_len, si_len, sd_len;
1105
1106 ntfs_log_trace("Entering.\n");
1107
1108 /* Sanity checks. */
1109 if (!dir_ni || !name || !name_len) {
1110 ntfs_log_error("Invalid arguments.\n");
1111 errno = EINVAL;
1112 return NULL;
1113 }
1114 /* FIXME: Reparse points requires special handling. */
1115 if (dir_ni->flags & FILE_ATTR_REPARSE_POINT) {
1116 errno = EOPNOTSUPP;
1117 return NULL;
1118 }
1119 /* Allocate MFT record for new file. */
1120 ni = ntfs_mft_record_alloc(dir_ni->vol, NULL);
1121 if (!ni) {
1122 ntfs_log_error("Failed to allocate new MFT record: %s.\n",
1123 strerror(errno));
1124 return NULL;
1125 }
1126 /*
1127 * Create STANDARD_INFORMATION attribute. Write STANDARD_INFORMATION
1128 * version 1.2, windows will upgrade it to version 3 if needed.
1129 */
1130 si_len = offsetof(STANDARD_INFORMATION, u.v12.v1_end);
1131 si = calloc(1, si_len);
1132 if (!si) {
1133 err = errno;
1134 ntfs_log_error("Not enough memory.\n");
1135 goto err_out;
1136 }
1137 si->creation_time = utc2ntfs(ni->creation_time);
1138 si->last_data_change_time = utc2ntfs(ni->last_data_change_time);
1139 si->last_mft_change_time = utc2ntfs(ni->last_mft_change_time);
1140 si->last_access_time = utc2ntfs(ni->last_access_time);
1141 if (!S_ISREG(type) && !S_ISDIR(type)) {
1142 si->file_attributes = FILE_ATTR_SYSTEM;
1143 ni->flags = FILE_ATTR_SYSTEM;
1144 }
1145 /* Add STANDARD_INFORMATION to inode. */
1146 if (ntfs_attr_add(ni, AT_STANDARD_INFORMATION, AT_UNNAMED, 0,
1147 (u8*)si, si_len)) {
1148 err = errno;
1149 ntfs_log_error("Failed to add STANDARD_INFORMATION "
1150 "attribute.\n");
1151 goto err_out;
1152 }
1153 /* Create SECURITY_DESCRIPTOR attribute (everyone has full access). */
1154 /*
1155 * Calculate security descriptor length. We have 2 sub-authorities in
1156 * owner and group SIDs, but structure SID contain only one, so add
1157 * 4 bytes to every SID.
1158 */
1159 sd_len = sizeof(SECURITY_DESCRIPTOR_ATTR) + 2 * (sizeof(SID) + 4) +
1160 sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE);
1161 sd = calloc(1, sd_len);
1162 if (!sd) {
1163 err = errno;
1164 ntfs_log_error("Not enough memory.\n");
1165 goto err_out;
1166 }
1167 sd->revision = 1;
1168 sd->control = SE_DACL_PRESENT | SE_SELF_RELATIVE;
1169 sid = (SID*)((u8*)sd + sizeof(SECURITY_DESCRIPTOR_ATTR));
1170 sd->owner = cpu_to_le32((u8*)sid - (u8*)sd);
1171 sid->revision = 1;
1172 sid->sub_authority_count = 2;
1173 sid->sub_authority[0] = cpu_to_le32(32);
1174 sid->sub_authority[1] = cpu_to_le32(544);
1175 sid->identifier_authority.value[5] = 5;
1176 sid = (SID*)((u8*)sid + sizeof(SID) + 4);
1177 sd->group = cpu_to_le32((u8*)sid - (u8*)sd);
1178 sid->revision = 1;
1179 sid->sub_authority_count = 2;
1180 sid->sub_authority[0] = cpu_to_le32(32);
1181 sid->sub_authority[1] = cpu_to_le32(544);
1182 sid->identifier_authority.value[5] = 5;
1183 acl = (ACL*)((u8*)sid + sizeof(SID) + 4);
1184 sd->dacl = cpu_to_le32((u8*)acl - (u8*)sd);
1185 acl->revision = 2;
1186 acl->size = cpu_to_le16(sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE));
1187 acl->ace_count = cpu_to_le16(1);
1188 ace = (ACCESS_ALLOWED_ACE*)((u8*)acl + sizeof(ACL));
1189 ace->type = ACCESS_ALLOWED_ACE_TYPE;
1190 ace->flags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
1191 ace->size = cpu_to_le16(sizeof(ACCESS_ALLOWED_ACE));
1192 ace->mask = cpu_to_le32(0x1f01ff); /* FIXME */
1193 ace->sid.revision = 1;
1194 ace->sid.sub_authority_count = 1;
1195 ace->sid.sub_authority[0] = 0;
1196 ace->sid.identifier_authority.value[5] = 1;
1197 /* Add SECURITY_DESCRIPTOR attribute to inode. */
1198 if (ntfs_attr_add(ni, AT_SECURITY_DESCRIPTOR, AT_UNNAMED, 0,
1199 (u8*)sd, sd_len)) {
1200 err = errno;
1201 ntfs_log_error("Failed to add SECURITY_DESCRIPTOR "
1202 "attribute.\n");
1203 goto err_out;
1204 }
1205 rollback_sd = 1;
1206 /* Add DATA/INDEX_ROOT attribute. */
1207 if (S_ISDIR(type)) {
1208 INDEX_ROOT *ir = NULL;
1209 INDEX_ENTRY *ie;
1210 int ir_len, index_len;
1211
1212 /* Create INDEX_ROOT attribute. */
1213 index_len = sizeof(INDEX_HEADER) + sizeof(INDEX_ENTRY_HEADER);
1214 ir_len = offsetof(INDEX_ROOT, index) + index_len;
1215 ir = calloc(1, ir_len);
1216 if (!ir) {
1217 err = errno;
1218 ntfs_log_error("Not enough memory.\n");
1219 goto err_out;
1220 }
1221 ir->type = AT_FILE_NAME;
1222 ir->collation_rule = COLLATION_FILE_NAME;
1223 ir->index_block_size = cpu_to_le32(ni->vol->indx_record_size);
1224 if (ni->vol->cluster_size <= ni->vol->indx_record_size)
1225 ir->clusters_per_index_block =
1226 ni->vol->indx_record_size >>
1227 ni->vol->cluster_size_bits;
1228 else
1229 ir->clusters_per_index_block =
1230 ni->vol->indx_record_size >>
1231 ni->vol->sector_size_bits;
1232 ir->index.entries_offset = cpu_to_le32(sizeof(INDEX_HEADER));
1233 ir->index.index_length = cpu_to_le32(index_len);
1234 ir->index.allocated_size = cpu_to_le32(index_len);
1235 ie = (INDEX_ENTRY*)((u8*)ir + sizeof(INDEX_ROOT));
1236 ie->length = cpu_to_le16(sizeof(INDEX_ENTRY_HEADER));
1237 ie->key_length = 0;
1238 ie->flags = INDEX_ENTRY_END;
1239 /* Add INDEX_ROOT attribute to inode. */
1240 if (ntfs_attr_add(ni, AT_INDEX_ROOT, NTFS_INDEX_I30, 4,
1241 (u8*)ir, ir_len)) {
1242 err = errno;
1243 free(ir);
1244 ntfs_log_error("Failed to add INDEX_ROOT attribute.\n");
1245 goto err_out;
1246 }
1247 free(ir);
1248 } else {
1249 INTX_FILE *data;
1250 int data_len;
1251
1252 switch (type) {
1253 case S_IFBLK:
1254 case S_IFCHR:
1255 data_len = offsetof(INTX_FILE, u.s.device_end);
1256 data = ntfs_malloc(data_len);
1257 if (!data) {
1258 err = errno;
1259 goto err_out;
1260 }
1261 data->u.s.major = cpu_to_le64(major(dev));
1262 data->u.s.minor = cpu_to_le64(minor(dev));
1263 if (type == S_IFBLK)
1264 data->magic = INTX_BLOCK_DEVICE;
1265 if (type == S_IFCHR)
1266 data->magic = INTX_CHARACTER_DEVICE;
1267 break;
1268 case S_IFLNK:
1269 data_len = sizeof(INTX_FILE_TYPES) +
1270 target_len * sizeof(ntfschar);
1271 data = ntfs_malloc(data_len);
1272 if (!data) {
1273 err = errno;
1274 goto err_out;
1275 }
1276 data->magic = INTX_SYMBOLIC_LINK;
1277 memcpy(data->u.target, target,
1278 target_len * sizeof(ntfschar));
1279 break;
1280 case S_IFSOCK:
1281 data = NULL;
1282 data_len = 1;
1283 break;
1284 default: /* FIFO or regular file. */
1285 data = NULL;
1286 data_len = 0;
1287 break;
1288 }
1289 /* Add DATA attribute to inode. */
1290 if (ntfs_attr_add(ni, AT_DATA, AT_UNNAMED, 0, (u8*)data,
1291 data_len)) {
1292 err = errno;
1293 free(data);
1294 ntfs_log_error("Failed to add DATA attribute.\n");
1295 goto err_out;
1296 }
1297 rollback_data = 1;
1298 free(data);
1299 }
1300 /* Create FILE_NAME attribute. */
1301 fn_len = sizeof(FILE_NAME_ATTR) + name_len * sizeof(ntfschar);
1302 fn = ntfs_calloc(fn_len);
1303 if (!fn) {
1304 err = errno;
1305 goto err_out;
1306 }
1307 fn->parent_directory = MK_LE_MREF(dir_ni->mft_no,
1308 le16_to_cpu(dir_ni->mrec->sequence_number));
1309 fn->file_name_length = name_len;
1310 fn->file_name_type = FILE_NAME_POSIX;
1311 if (S_ISDIR(type))
1312 fn->file_attributes = FILE_ATTR_I30_INDEX_PRESENT;
1313 if (!S_ISREG(type) && !S_ISDIR(type))
1314 fn->file_attributes = FILE_ATTR_SYSTEM;
1315 fn->creation_time = utc2ntfs(ni->creation_time);
1316 fn->last_data_change_time = utc2ntfs(ni->last_data_change_time);
1317 fn->last_mft_change_time = utc2ntfs(ni->last_mft_change_time);
1318 fn->last_access_time = utc2ntfs(ni->last_access_time);
1319 memcpy(fn->file_name, name, name_len * sizeof(ntfschar));
1320 /* Add FILE_NAME attribute to inode. */
1321 if (ntfs_attr_add(ni, AT_FILE_NAME, AT_UNNAMED, 0, (u8*)fn, fn_len)) {
1322 err = errno;
1323 ntfs_log_error("Failed to add FILE_NAME attribute.\n");
1324 goto err_out;
1325 }
1326 /* Add FILE_NAME attribute to index. */
1327 if (ntfs_index_add_filename(dir_ni, fn, MK_MREF(ni->mft_no,
1328 le16_to_cpu(ni->mrec->sequence_number)))) {
1329 err = errno;
1330 ntfs_log_perror("Failed to add entry to the index");
1331 goto err_out;
1332 }
1333 /* Set hard links count and directory flag. */
1334 ni->mrec->link_count = cpu_to_le16(1);
1335 if (S_ISDIR(type))
1336 ni->mrec->flags |= MFT_RECORD_IS_DIRECTORY;
1337 ntfs_inode_mark_dirty(ni);
1338 /* Done! */
1339 free(fn);
1340 free(si);
1341 free(sd);
1342 ntfs_log_trace("Done.\n");
1343 return ni;
1344 err_out:
1345 ntfs_log_trace("Failed.\n");
1346 if (rollback_sd) {
1347 ntfs_attr *na;
1348
1349 na = ntfs_attr_open(ni, AT_SECURITY_DESCRIPTOR, AT_UNNAMED, 0);
1350 if (!na)
1351 ntfs_log_perror("Failed to open SD (0x50) attribute of "
1352 " inode 0x%llx. Run chkdsk.\n",
1353 (unsigned long long)ni->mft_no);
1354 else if (ntfs_attr_rm(na))
1355 ntfs_log_perror("Failed to remove SD (0x50) attribute "
1356 "of inode 0x%llx. Run chkdsk.\n",
1357 (unsigned long long)ni->mft_no);
1358 }
1359 if (rollback_data) {
1360 ntfs_attr *na;
1361
1362 na = ntfs_attr_open(ni, AT_DATA, AT_UNNAMED, 0);
1363 if (!na)
1364 ntfs_log_perror("Failed to open data attribute of "
1365 " inode 0x%llx. Run chkdsk.\n",
1366 (unsigned long long)ni->mft_no);
1367 else if (ntfs_attr_rm(na))
1368 ntfs_log_perror("Failed to remove data attribute of "
1369 "inode 0x%llx. Run chkdsk.\n",
1370 (unsigned long long)ni->mft_no);
1371 }
1372 /*
1373 * Free extent MFT records (should not exist any with current
1374 * ntfs_create implementation, but for any case if something will be
1375 * changed in the future).
1376 */
1377 while (ni->nr_extents)
1378 if (ntfs_mft_record_free(ni->vol, *(ni->u.extent_nis))) {
1379 err = errno;
1380 ntfs_log_error("Failed to free extent MFT record. "
1381 "Leaving inconsistent metadata.\n");
1382 }
1383 if (ntfs_mft_record_free(ni->vol, ni))
1384 ntfs_log_error("Failed to free MFT record. "
1385 "Leaving inconsistent metadata. Run chkdsk.\n");
1386 free(fn);
1387 free(si);
1388 free(sd);
1389 errno = err;
1390 return NULL;
1391 }
1392
1393 /**
1394 * Some wrappers around __ntfs_create() ...
1395 */
1396
ntfs_create(ntfs_inode * dir_ni,ntfschar * name,u8 name_len,dev_t type)1397 ntfs_inode *ntfs_create(ntfs_inode *dir_ni, ntfschar *name, u8 name_len,
1398 dev_t type)
1399 {
1400 if (type != S_IFREG && type != S_IFDIR && type != S_IFIFO &&
1401 type != S_IFSOCK) {
1402 ntfs_log_error("Invalid arguments.\n");
1403 return NULL;
1404 }
1405 return __ntfs_create(dir_ni, name, name_len, type, 0, NULL, 0);
1406 }
1407
ntfs_create_device(ntfs_inode * dir_ni,ntfschar * name,u8 name_len,dev_t type,dev_t dev)1408 ntfs_inode *ntfs_create_device(ntfs_inode *dir_ni, ntfschar *name, u8 name_len,
1409 dev_t type, dev_t dev)
1410 {
1411 if (type != S_IFCHR && type != S_IFBLK) {
1412 ntfs_log_error("Invalid arguments.\n");
1413 return NULL;
1414 }
1415 return __ntfs_create(dir_ni, name, name_len, type, dev, NULL, 0);
1416 }
1417
ntfs_create_symlink(ntfs_inode * dir_ni,ntfschar * name,u8 name_len,ntfschar * target,u8 target_len)1418 ntfs_inode *ntfs_create_symlink(ntfs_inode *dir_ni, ntfschar *name, u8 name_len,
1419 ntfschar *target, u8 target_len)
1420 {
1421 if (!target || !target_len) {
1422 ntfs_log_error("Invalid arguments.\n");
1423 return NULL;
1424 }
1425 return __ntfs_create(dir_ni, name, name_len, S_IFLNK, 0,
1426 target, target_len);
1427 }
1428
1429 /**
1430 * ntfs_delete - delete file or directory from ntfs volume
1431 * @pni: ntfs inode for object to delete
1432 * @dir_ni: ntfs inode for directory in which delete object
1433 * @name: unicode name of the object to delete
1434 * @name_len: length of the name in unicode characters
1435 *
1436 * @pni is pointer to pointer to ntfs_inode structure. Upon successful
1437 * completion and if inode is really deleted (there are no more links left to
1438 * it) this function will close @*pni and set it to NULL, in the other cases
1439 * @*pni will stay opened.
1440 *
1441 * Return 0 on success or -1 on error with errno set to the error code.
1442 */
ntfs_delete(ntfs_inode ** pni,ntfs_inode * dir_ni,ntfschar * name,u8 name_len)1443 int ntfs_delete(ntfs_inode **pni, ntfs_inode *dir_ni, ntfschar *name,
1444 u8 name_len)
1445 {
1446 ntfs_attr_search_ctx *actx = NULL;
1447 ntfs_index_context *ictx = NULL;
1448 ntfs_inode *ni;
1449 FILE_NAME_ATTR *fn = NULL;
1450 BOOL looking_for_dos_name = FALSE, looking_for_win32_name = FALSE;
1451 BOOL case_sensitive_match = TRUE;
1452 int err = 0;
1453
1454 ntfs_log_trace("Entering.\n");
1455
1456 if (!pni || !(ni = *pni) || !dir_ni || !name || !name_len ||
1457 ni->nr_extents == -1 || dir_ni->nr_extents == -1) {
1458 ntfs_log_error("Invalid arguments.\n");
1459 errno = EINVAL;
1460 goto err_out;
1461 }
1462 if (ni->nr_references > 1 && le16_to_cpu(ni->mrec->link_count) == 1) {
1463 ntfs_log_error("Trying to deleting inode with left "
1464 "references.\n");
1465 errno = EINVAL;
1466 goto err_out;
1467 }
1468 /*
1469 * Search for FILE_NAME attribute with such name. If it's in POSIX or
1470 * WIN32_AND_DOS namespace, then simply remove it from index and inode.
1471 * If filename in DOS or in WIN32 namespace, then remove DOS name first,
1472 * only then remove WIN32 name. Mark WIN32 name as POSIX name to prevent
1473 * chkdsk to complain about DOS name absence in case if DOS name had
1474 * been successfully deleted, but WIN32 name remove failed.
1475 */
1476 actx = ntfs_attr_get_search_ctx(ni, NULL);
1477 if (!actx)
1478 goto err_out;
1479 search:
1480 while (!ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0, CASE_SENSITIVE,
1481 0, NULL, 0, actx)) {
1482 errno = 0;
1483 fn = (FILE_NAME_ATTR*)((u8*)actx->attr +
1484 le16_to_cpu(actx->attr->u.res.value_offset));
1485 ntfs_log_trace("Found filename with instance number %d.\n",
1486 le16_to_cpu(actx->attr->instance));
1487 if (looking_for_dos_name) {
1488 if (fn->file_name_type == FILE_NAME_DOS)
1489 break;
1490 else
1491 continue;
1492 }
1493 if (looking_for_win32_name) {
1494 if (fn->file_name_type == FILE_NAME_WIN32)
1495 break;
1496 else
1497 continue;
1498 }
1499 if (dir_ni->mft_no == MREF_LE(fn->parent_directory) &&
1500 ntfs_names_are_equal(fn->file_name,
1501 fn->file_name_length, name,
1502 name_len, case_sensitive_match ?
1503 CASE_SENSITIVE : IGNORE_CASE, ni->vol->upcase,
1504 ni->vol->upcase_len)) {
1505 if (fn->file_name_type == FILE_NAME_WIN32) {
1506 looking_for_dos_name = TRUE;
1507 ntfs_attr_reinit_search_ctx(actx);
1508 ntfs_log_trace("Restart search. "
1509 "Looking for DOS name.\n");
1510 continue;
1511 }
1512 if (fn->file_name_type == FILE_NAME_DOS)
1513 looking_for_dos_name = TRUE;
1514 break;
1515 }
1516 }
1517 if (errno) {
1518 /*
1519 * If case sensitive search failed and volume mounted case
1520 * insensitive, then try once again ignoring case.
1521 */
1522 if (errno == ENOENT && !NVolCaseSensitive(ni->vol) &&
1523 case_sensitive_match) {
1524 case_sensitive_match = FALSE;
1525 ntfs_attr_reinit_search_ctx(actx);
1526 ntfs_log_trace("Restart search. Ignore case.");
1527 goto search;
1528 }
1529 ntfs_log_error("Failed to find requested filename in FILE_NAME "
1530 "attributes that belong to this inode.\n");
1531 goto err_out;
1532 }
1533 /* If deleting directory check it to be empty. */
1534 if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY) {
1535 ntfs_attr *na;
1536
1537 na = ntfs_attr_open(ni, AT_INDEX_ROOT, NTFS_INDEX_I30, 4);
1538 if (!na) {
1539 ntfs_log_error("Corrupt directory or library bug.\n");
1540 errno = EIO;
1541 goto err_out;
1542 }
1543 /*
1544 * Do not allow non-empty directory deletion if hard links count
1545 * is 1 (always) or 2 (in case if filename in DOS namespace,
1546 * because we delete it first in file which have both WIN32 and
1547 * DOS names).
1548 */
1549 if ((na->data_size != sizeof(INDEX_ROOT) + sizeof(
1550 INDEX_ENTRY_HEADER)) && (le16_to_cpu(
1551 ni->mrec->link_count) == 1 ||
1552 (le16_to_cpu(ni->mrec->link_count) == 2 &&
1553 fn->file_name_type == FILE_NAME_DOS))) {
1554 ntfs_attr_close(na);
1555 ntfs_log_error("Directory is not empty.\n");
1556 errno = ENOTEMPTY;
1557 goto err_out;
1558 }
1559 ntfs_attr_close(na);
1560 }
1561 /* One more sanity check. */
1562 if (ni->nr_references > 1 && looking_for_dos_name &&
1563 le16_to_cpu(ni->mrec->link_count) == 2) {
1564 ntfs_log_error("Trying to deleting inode with left "
1565 "references.\n");
1566 errno = EINVAL;
1567 goto err_out;
1568 }
1569 ntfs_log_trace("Found!\n");
1570 /* Search for such FILE_NAME in index. */
1571 ictx = ntfs_index_ctx_get(dir_ni, NTFS_INDEX_I30, 4);
1572 if (!ictx)
1573 goto err_out;
1574 if (ntfs_index_lookup(fn, le32_to_cpu(actx->attr->u.res.value_length), ictx))
1575 goto err_out;
1576 /* Set namespace to POSIX for WIN32 name. */
1577 if (fn->file_name_type == FILE_NAME_WIN32) {
1578 fn->file_name_type = FILE_NAME_POSIX;
1579 ntfs_inode_mark_dirty(actx->ntfs_ino);
1580 ((FILE_NAME_ATTR*)ictx->data)->file_name_type = FILE_NAME_POSIX;
1581 ntfs_index_entry_mark_dirty(ictx);
1582 }
1583 /* Do not support reparse point deletion yet. */
1584 if (((FILE_NAME_ATTR*)ictx->data)->file_attributes &
1585 FILE_ATTR_REPARSE_POINT) {
1586 errno = EOPNOTSUPP;
1587 goto err_out;
1588 }
1589 /* Remove FILE_NAME from index. */
1590 if (ntfs_index_rm(ictx))
1591 goto err_out;
1592
1593 /* Remove FILE_NAME from inode. */
1594 if (ntfs_attr_record_rm(actx))
1595 goto err_out;
1596 /* Decrement hard link count. */
1597 ni->mrec->link_count = cpu_to_le16(le16_to_cpu(
1598 ni->mrec->link_count) - 1);
1599 ntfs_inode_mark_dirty(ni);
1600 if (looking_for_dos_name) {
1601 looking_for_dos_name = FALSE;
1602 looking_for_win32_name = TRUE;
1603 ntfs_attr_reinit_search_ctx(actx);
1604 ntfs_log_trace("DOS name deleted. "
1605 "Now search for WIN32 name.\n");
1606 goto search;
1607 } else
1608 ntfs_log_trace("Deleted.\n");
1609 /* TODO: Update object id, quota and security indexes if required. */
1610 /*
1611 * If hard link count is not equal to zero then we are done. In other
1612 * case there are no reference to this inode left, so we should free all
1613 * non-resident attributes and mark all MFT record as not in use.
1614 */
1615 if (ni->mrec->link_count)
1616 goto out;
1617 ntfs_attr_reinit_search_ctx(actx);
1618 while (!ntfs_attrs_walk(actx)) {
1619 if (actx->attr->non_resident) {
1620 runlist *rl;
1621
1622 rl = ntfs_mapping_pairs_decompress(ni->vol, actx->attr,
1623 NULL);
1624 if (!rl) {
1625 err = errno;
1626 ntfs_log_error("Failed to decompress runlist. "
1627 "Leaving inconsistent "
1628 "metadata.\n");
1629 continue;
1630 }
1631 if (ntfs_cluster_free_from_rl(ni->vol, rl)) {
1632 err = errno;
1633 ntfs_log_error("Failed to free clusters. "
1634 "Leaving inconsistent "
1635 "metadata.\n");
1636 continue;
1637 }
1638 free(rl);
1639 }
1640 }
1641 if (errno != ENOENT) {
1642 err = errno;
1643 ntfs_log_error("Attribute enumeration failed. "
1644 "Probably leaving inconsistent metadata.\n");
1645 }
1646 /* All extents should be attached after attribute walk. */
1647 while (ni->nr_extents)
1648 if (ntfs_mft_record_free(ni->vol, *(ni->u.extent_nis))) {
1649 err = errno;
1650 ntfs_log_error("Failed to free extent MFT record. "
1651 "Leaving inconsistent metadata.\n");
1652 }
1653 if (ntfs_mft_record_free(ni->vol, ni)) {
1654 err = errno;
1655 ntfs_log_error("Failed to free base MFT record. "
1656 "Leaving inconsistent metadata.\n");
1657 }
1658 *pni = NULL;
1659 out:
1660 if (actx)
1661 ntfs_attr_put_search_ctx(actx);
1662 if (ictx)
1663 ntfs_index_ctx_put(ictx);
1664 if (err) {
1665 ntfs_log_error("%s(): Failed.\n", "ntfs_delete");
1666 errno = err;
1667 return -1;
1668 }
1669 ntfs_log_trace("Done.\n");
1670 return 0;
1671 err_out:
1672 err = errno;
1673 goto out;
1674 }
1675
1676 /**
1677 * ntfs_link - create hard link for file or directory
1678 * @ni: ntfs inode for object to create hard link
1679 * @dir_ni: ntfs inode for directory in which new link should be placed
1680 * @name: unicode name of the new link
1681 * @name_len: length of the name in unicode characters
1682 *
1683 * NOTE: At present we allow creating hard links to directories, we use them
1684 * in a temporary state during rename. But it's definitely bad idea to have
1685 * hard links to directories as a result of operation.
1686 * FIXME: Create internal __ntfs_link that allows hard links to a directories
1687 * and external ntfs_link that do not. Write ntfs_rename that uses __ntfs_link.
1688 *
1689 * Return 0 on success or -1 on error with errno set to the error code.
1690 */
ntfs_link(ntfs_inode * ni,ntfs_inode * dir_ni,ntfschar * name,u8 name_len)1691 int ntfs_link(ntfs_inode *ni, ntfs_inode *dir_ni, ntfschar *name, u8 name_len)
1692 {
1693 FILE_NAME_ATTR *fn = NULL;
1694 int fn_len, err;
1695
1696 ntfs_log_trace("Entering.\n");
1697
1698 if (!ni || !dir_ni || !name || !name_len ||
1699 ni->mft_no == dir_ni->mft_no) {
1700 err = EINVAL;
1701 ntfs_log_error("Invalid arguments.");
1702 goto err_out;
1703 }
1704 /* FIXME: Reparse points requires special handling. */
1705 if (ni->flags & FILE_ATTR_REPARSE_POINT) {
1706 err = EOPNOTSUPP;
1707 goto err_out;
1708 }
1709 /* Create FILE_NAME attribute. */
1710 fn_len = sizeof(FILE_NAME_ATTR) + name_len * sizeof(ntfschar);
1711 fn = ntfs_calloc(fn_len);
1712 if (!fn) {
1713 err = errno;
1714 goto err_out;
1715 }
1716 fn->parent_directory = MK_LE_MREF(dir_ni->mft_no,
1717 le16_to_cpu(dir_ni->mrec->sequence_number));
1718 fn->file_name_length = name_len;
1719 fn->file_name_type = FILE_NAME_POSIX;
1720 fn->file_attributes = ni->flags;
1721 if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)
1722 fn->file_attributes |= FILE_ATTR_I30_INDEX_PRESENT;
1723 fn->allocated_size = cpu_to_sle64(ni->allocated_size);
1724 fn->data_size = cpu_to_sle64(ni->data_size);
1725 fn->creation_time = utc2ntfs(ni->creation_time);
1726 fn->last_data_change_time = utc2ntfs(ni->last_data_change_time);
1727 fn->last_mft_change_time = utc2ntfs(ni->last_mft_change_time);
1728 fn->last_access_time = utc2ntfs(ni->last_access_time);
1729 memcpy(fn->file_name, name, name_len * sizeof(ntfschar));
1730 /* Add FILE_NAME attribute to index. */
1731 if (ntfs_index_add_filename(dir_ni, fn, MK_MREF(ni->mft_no,
1732 le16_to_cpu(ni->mrec->sequence_number)))) {
1733 err = errno;
1734 ntfs_log_error("Failed to add entry to the index.\n");
1735 goto err_out;
1736 }
1737 /* Add FILE_NAME attribute to inode. */
1738 if (ntfs_attr_add(ni, AT_FILE_NAME, AT_UNNAMED, 0, (u8*)fn, fn_len)) {
1739 ntfs_index_context *ictx;
1740
1741 err = errno;
1742 ntfs_log_error("Failed to add FILE_NAME attribute.\n");
1743 /* Try to remove just added attribute from index. */
1744 ictx = ntfs_index_ctx_get(dir_ni, NTFS_INDEX_I30, 4);
1745 if (!ictx)
1746 goto rollback_failed;
1747 if (ntfs_index_lookup(fn, fn_len, ictx)) {
1748 ntfs_index_ctx_put(ictx);
1749 goto rollback_failed;
1750 }
1751 if (ntfs_index_rm(ictx)) {
1752 ntfs_index_ctx_put(ictx);
1753 goto rollback_failed;
1754 }
1755 goto err_out;
1756 }
1757 /* Increment hard links count. */
1758 ni->mrec->link_count = cpu_to_le16(le16_to_cpu(
1759 ni->mrec->link_count) + 1);
1760 /* Done! */
1761 ntfs_inode_mark_dirty(ni);
1762 free(fn);
1763 ntfs_log_trace("Done.\n");
1764 return 0;
1765 rollback_failed:
1766 ntfs_log_error("Rollback failed. Leaving inconsistent metadata.\n");
1767 err_out:
1768 ntfs_log_error("%s(): Failed.\n", "ntfs_link");
1769 free(fn);
1770 errno = err;
1771 return -1;
1772 }
1773
1774