4 * Copyright (C) 1995-1997, 1999 Martin von Löwis
5 * Copyright (C) 1999 Steve Dodd
6 * Copyright (C) 1999 Joseph Malicki
7 * Copyright (C) 2001 Anton Altaparmakov (AIA)
10 #include "ntfstypes.h"
15 #include <linux/errno.h>
21 #include <linux/smp_lock.h>
22 #include <linux/bitops.h>
24 static char I30[] = "$I30";
26 /* An index record should start with INDX, and the last word in each block
27 * should contain the check value. If it passes, the original values need to
29 int ntfs_check_index_record(ntfs_inode *ino, char *record)
31 return ntfs_fixup_record(record, "INDX", ino->u.index.recordsize);
34 static inline int ntfs_is_top(ntfs_u64 stack)
39 static int ntfs_pop(ntfs_u64 *stack)
41 static int width[16] = {1,2,1,3,1,2,1,4,1,2,1,3,1,2,1,-1};
44 switch (width[*stack & 15]) {
46 res = (int)((*stack & 15) >> 1);
50 res = (int)(((*stack & 63) >> 2) + 7);
54 res = (int)(((*stack & 255) >> 3) + 23);
58 res = (int)(((*stack & 1023) >> 4) + 55);
62 ntfs_error("Unknown encoding\n");
67 static inline unsigned int ntfs_top(void)
72 static ntfs_u64 ntfs_push(ntfs_u64 stack, int i)
75 return (stack << 4) | (i << 1);
77 return (stack << 6) | ((i - 7) << 2) | 1;
79 return (stack << 8) | ((i - 23) << 3) | 3;
81 return (stack << 10) | ((i - 55) << 4) | 7;
82 ntfs_error("Too many entries\n");
83 return ~((ntfs_u64)0);
87 static void ntfs_display_stack(ntfs_u64 stack)
89 while(!ntfs_is_top(stack))
91 printf("%d ", ntfs_pop(&stack));
97 /* True if the entry points to another block of entries. */
98 static inline int ntfs_entry_has_subnodes(char *entry)
100 return (NTFS_GETU16(entry + 0xc) & 1);
103 /* True if it is not the 'end of dir' entry. */
104 static inline int ntfs_entry_is_used(char *entry)
106 return !(NTFS_GETU16(entry + 0xc) & 2);
110 * Removed RACE for allocating index blocks. But stil not too happy.
111 * There might be more races afterwards. (AIA)
113 static int ntfs_allocate_index_block(ntfs_iterate_s *walk)
115 ntfs_attribute *allocation, *bitmap = 0;
116 int error, size, i, bit;
119 ntfs_volume *vol = walk->dir->vol;
121 /* Check for allocation attribute. */
122 allocation = ntfs_find_attr(walk->dir, vol->at_index_allocation, I30);
125 /* Create index allocation attribute. */
126 error = ntfs_create_attr(walk->dir, vol->at_index_allocation,
127 I30, 0, 0, &allocation);
130 ntfs_bzero(bmp, sizeof(bmp));
131 error = ntfs_create_attr(walk->dir, vol->at_bitmap, I30, bmp,
132 sizeof(bmp), &bitmap);
136 bitmap = ntfs_find_attr(walk->dir, vol->at_bitmap, I30);
138 ntfs_error("Directory w/o bitmap\n");
143 bmap = ntfs_malloc(size);
148 io.fn_put = ntfs_put;
149 io.fn_get = ntfs_get;
153 error = ntfs_read_attr(walk->dir, vol->at_bitmap, I30, 0, &io);
154 if (error || (io.size != size && (error = -EIO, 1)))
156 /* Allocate a bit. */
157 for (bit = i = 0; i < size; i++) {
165 /* FIXME: Extend bitmap. */
169 /* Get the byte containing our bit again, now taking the BKL. */
173 error = ntfs_read_attr(walk->dir, vol->at_bitmap, I30, i, &io);
174 if (error || (io.size != 1 && (error = -EIO, 1)))
176 if (ntfs_test_and_set_bit(bmap, bit)) {
178 /* Give other process(es) a chance to finish. */
182 walk->newblock = (i * 8 + bit) * walk->dir->u.index.clusters_per_record;
184 error = ntfs_write_attr(walk->dir, vol->at_bitmap, I30, i, &io);
185 if (error || (io.size != size && (error = -EIO, 1)))
187 /* Change inode on disk, required when bitmap is resident. */
188 error = ntfs_update_inode(walk->dir);
193 /* Check whether record is out of allocated range. */
194 size = allocation->size;
195 if (walk->newblock * vol->cluster_size >= size) {
196 /* Build index record. */
198 int s1 = walk->dir->u.index.recordsize;
199 int nr_fix = (s1 >> vol->sector_size) + 1;
200 char *record = ntfs_malloc(s1);
205 ntfs_bzero(record, s1);
207 ntfs_memcpy(record, "INDX", 4);
208 /* Offset to fixups */
209 NTFS_PUTU16(record + 4, 0x28);
210 /* Number of fixups. */
211 NTFS_PUTU16(record + 6, nr_fix);
212 /* Log file sequence number - We don't do journalling so we
213 * just set it to zero which should be the Right Thing. (AIA) */
214 NTFS_PUTU64(record + 8, 0);
216 NTFS_PUTU64(record + 0x10, walk->newblock);
218 hsize = 0x10 + 2 * nr_fix;
219 hsize = (hsize + 7) & ~7; /* Align. */
220 NTFS_PUTU16(record + 0x18, hsize);
221 /* Total size of record. */
222 NTFS_PUTU32(record + 0x20, s1 - 0x18);
223 /* Writing the data will extend the attribute. */
227 error = ntfs_readwrite_attr(walk->dir, allocation, size, &io);
229 if (error || (io.size != s1 && (error = -EIO, 1)))
231 error = ntfs_update_inode(walk->dir);
244 /* Write an index block (root or allocation) back to storage.
245 * Used is the total number of bytes in buf, including all headers. */
246 static int ntfs_index_writeback(ntfs_iterate_s *walk, ntfs_u8 *buf, int block,
252 ntfs_volume *vol = walk->dir->vol;
255 io.fn_get = ntfs_get;
257 if (block == -1) { /* Index root. */
258 NTFS_PUTU16(buf + 0x14, used - 0x10);
259 /* 0x18 is a copy thereof. */
260 NTFS_PUTU16(buf + 0x18, used - 0x10);
262 error = ntfs_write_attr(walk->dir, vol->at_index_root, I30, 0,
264 if (error || (io.size != used && (error = -EIO, 1)))
266 /* Shrink if necessary. */
267 a = ntfs_find_attr(walk->dir, vol->at_index_root, I30);
268 ntfs_resize_attr(walk->dir, a, used);
270 NTFS_PUTU16(buf + 0x1C, used - 0x18);
271 io.size = walk->dir->u.index.recordsize;
272 error = ntfs_insert_fixups(buf, io.size);
274 printk(KERN_ALERT "NTFS: ntfs_index_writeback() caught "
275 "corrupt index record ntfs record "
276 "header. Refusing to write corrupt "
277 "data to disk. Unmount and run chkdsk "
281 error = ntfs_write_attr(walk->dir, vol->at_index_allocation,
282 I30, (__s64)block << vol->cluster_size_bits,
284 if (error || (io.size != walk->dir->u.index.recordsize &&
291 static int ntfs_split_record(ntfs_iterate_s *walk, char *start, int bsize,
295 ntfs_u8 *newbuf = 0, *middle = 0;
296 int error, othersize, mlen;
298 ntfs_volume *vol = walk->dir->vol;
301 error = ntfs_allocate_index_block(walk);
304 /* This should not happen. */
305 if (walk->block == -1) {
306 ntfs_error("Trying to split root");
309 entry = start + NTFS_GETU16(start + 0x18) + 0x18;
310 for (prev = entry; entry - start < usize / 2;
311 entry += NTFS_GETU16(entry + 8))
313 newbuf = ntfs_malloc(vol->index_record_size);
316 io.fn_put = ntfs_put;
317 io.fn_get = ntfs_get;
319 io.size = vol->index_record_size;
320 /* Read in old header. FIXME: Reading everything is overkill. */
321 error = ntfs_read_attr(walk->dir, vol->at_index_allocation, I30,
322 (__s64)walk->newblock << vol->cluster_size_bits, &io);
325 if (io.size != vol->index_record_size) {
329 /* FIXME: Adjust header. */
330 /* Copy everything from entry to new block. */
331 othersize = usize - (entry - start);
332 ntfs_memcpy(newbuf + NTFS_GETU16(newbuf + 0x18) + 0x18, entry,
335 NTFS_PUTU32(newbuf + 0x24, NTFS_GETU32(start + 0x24));
336 error = ntfs_index_writeback(walk, newbuf, walk->newblock,
337 othersize + NTFS_GETU16(newbuf + 0x18) + 0x18);
340 /* Move prev to walk. */
341 mlen = NTFS_GETU16(prev + 0x8);
342 /* Remember old child node. */
343 if (ntfs_entry_has_subnodes(prev))
344 oldblock = NTFS_GETU32(prev + mlen - 8);
347 /* Allow for pointer to subnode. */
348 middle = ntfs_malloc(ntfs_entry_has_subnodes(prev) ? mlen : mlen + 8);
353 ntfs_memcpy(middle, prev, mlen);
354 /* Set has_subnodes flag. */
355 NTFS_PUTU8(middle + 0xC, NTFS_GETU8(middle + 0xC) | 1);
356 /* Middle entry points to block, parent entry will point to newblock. */
357 NTFS_PUTU64(middle + mlen - 8, walk->block);
359 ntfs_error("Entry not reset");
360 walk->new_entry = middle;
361 walk->u.flags |= ITERATE_SPLIT_DONE;
362 /* Terminate old block. */
363 othersize = usize - (prev-start);
364 NTFS_PUTU64(prev, 0);
365 if (oldblock == -1) {
366 NTFS_PUTU32(prev + 8, 0x10);
367 NTFS_PUTU32(prev + 0xC, 2);
370 NTFS_PUTU32(prev + 8, 0x18);
371 NTFS_PUTU32(prev + 0xC, 3);
372 NTFS_PUTU64(prev + 0x10, oldblock);
375 /* Write back original block. */
376 error = ntfs_index_writeback(walk, start, walk->block, othersize);
385 static int ntfs_dir_insert(ntfs_iterate_s *walk, char *start, char* entry)
387 int blocksize, usedsize, error, offset;
389 offset = entry - start;
390 if (walk->block == -1) { /* index root */
391 blocksize = walk->dir->vol->mft_record_size;
392 usedsize = NTFS_GETU16(start + 0x14) + 0x10;
394 blocksize = walk->dir->u.index.recordsize;
395 usedsize = NTFS_GETU16(start + 0x1C) + 0x18;
397 if (usedsize + walk->new_entry_size > blocksize) {
398 char* s1 = ntfs_malloc(blocksize + walk->new_entry_size);
401 ntfs_memcpy(s1, start, usedsize);
403 /* Adjust entry to s1. */
404 entry = s1 + (entry - start);
407 ntfs_memmove(entry + walk->new_entry_size, entry, usedsize - offset);
408 ntfs_memcpy(entry, walk->new_entry, walk->new_entry_size);
409 usedsize += walk->new_entry_size;
410 ntfs_free(walk->new_entry);
413 error = ntfs_split_record(walk, start, blocksize, usedsize);
416 error = ntfs_index_writeback(walk, start, walk->block,usedsize);
423 /* Try to split INDEX_ROOT attributes. Return -E2BIG if nothing changed. */
424 int ntfs_split_indexroot(ntfs_inode *ino)
427 ntfs_u8 *root = 0, *index = 0;
429 int error, off, i, bsize, isize;
432 ra = ntfs_find_attr(ino, ino->vol->at_index_root, I30);
435 bsize = ino->vol->mft_record_size;
436 root = ntfs_malloc(bsize);
439 io.fn_put = ntfs_put;
442 error = ntfs_read_attr(ino, ino->vol->at_index_root, I30, 0, &io);
446 /* Count number of entries. */
447 for (i = 0; ntfs_entry_is_used(root + off); i++)
448 off += NTFS_GETU16(root + off + 8);
450 /* We don't split small index roots. */
454 index = ntfs_malloc(ino->vol->index_record_size);
461 walk.result = walk.new_entry = 0;
463 error = ntfs_allocate_index_block(&walk);
466 /* Write old root to new index block. */
468 io.size = ino->vol->index_record_size;
469 error = ntfs_read_attr(ino, ino->vol->at_index_allocation, I30,
470 (__s64)walk.newblock << ino->vol->cluster_size_bits, &io);
473 isize = NTFS_GETU16(root + 0x18) - 0x10;
474 ntfs_memcpy(index + NTFS_GETU16(index + 0x18) + 0x18, root+0x20, isize);
476 NTFS_PUTU32(index + 0x24, NTFS_GETU32(root + 0x1C));
477 error = ntfs_index_writeback(&walk, index, walk.newblock,
478 isize + NTFS_GETU16(index + 0x18) + 0x18);
481 /* Mark root as split. */
482 NTFS_PUTU32(root + 0x1C, 1);
483 /* Truncate index root. */
484 NTFS_PUTU64(root + 0x20, 0);
485 NTFS_PUTU32(root + 0x28, 0x18);
486 NTFS_PUTU32(root + 0x2C, 3);
487 NTFS_PUTU64(root + 0x30, walk.newblock);
488 error = ntfs_index_writeback(&walk, root, -1, 0x38);
495 /* The entry has been found. Copy the result in the caller's buffer */
496 static int ntfs_copyresult(char *dest, char *source)
498 int length = NTFS_GETU16(source + 8);
499 ntfs_memcpy(dest, source, length);
503 /* Use $UpCase some day. */
504 static inline unsigned short ntfs_my_toupper(ntfs_volume *vol, ntfs_u16 x)
506 /* We should read any pending rest of $UpCase here. */
507 if (x >= vol->upcase_length)
509 return vol->upcase[x];
512 /* Everything passed in walk and entry. */
513 static int ntfs_my_strcmp(ntfs_iterate_s *walk, const unsigned char *entry)
515 int lu = *(entry + 0x50);
518 ntfs_u16* name = (ntfs_u16*)(entry + 0x52);
519 ntfs_volume *vol = walk->dir->vol;
520 for (i = 0; i < lu && i < walk->namelen; i++)
521 if (ntfs_my_toupper(vol, NTFS_GETU16(name + i)) !=
522 ntfs_my_toupper(vol, NTFS_GETU16(walk->name + i)))
524 if (i == lu && i == walk->namelen)
528 if (i == walk->namelen)
530 if (ntfs_my_toupper(vol, NTFS_GETU16(name + i)) <
531 ntfs_my_toupper(vol, NTFS_GETU16(walk->name + i)))
536 /* Necessary forward declaration. */
537 static int ntfs_getdir_iterate(ntfs_iterate_s *walk, char *start, char *entry);
539 /* Parse a block of entries. Load the block, fix it up, and iterate over the
540 * entries. The block is given as virtual cluster number. */
541 static int ntfs_getdir_record(ntfs_iterate_s *walk, int block)
543 int length = walk->dir->u.index.recordsize;
544 char *record = (char*)ntfs_malloc(length);
552 io.fn_put = ntfs_put;
555 /* Read the block from the index allocation attribute. */
556 error = ntfs_read_attr(walk->dir, walk->dir->vol->at_index_allocation,
557 I30, (__s64)block << walk->dir->vol->cluster_size_bits, &io);
558 if (error || io.size != length) {
559 ntfs_error("read failed\n");
563 if (!ntfs_check_index_record(walk->dir, record)) {
564 ntfs_error("%x is not an index record\n", block);
568 offset = record + NTFS_GETU16(record + 0x18) + 0x18;
569 oldblock = walk->block;
571 retval = ntfs_getdir_iterate(walk, record, offset);
572 walk->block = oldblock;
577 /* Go down to the next block of entries. These collate before the current
579 static int ntfs_descend(ntfs_iterate_s *walk, ntfs_u8 *start, ntfs_u8 *entry)
581 int length = NTFS_GETU16(entry + 8);
582 int nextblock = NTFS_GETU32(entry + length - 8);
585 if (!ntfs_entry_has_subnodes(entry)) {
586 ntfs_error("illegal ntfs_descend call\n");
589 error = ntfs_getdir_record(walk, nextblock);
590 if (!error && walk->type == DIR_INSERT &&
591 (walk->u.flags & ITERATE_SPLIT_DONE)) {
592 /* Split has occurred. Adjust entry, insert new_entry. */
593 NTFS_PUTU32(entry + length - 8, walk->newblock);
594 /* Reset flags, as the current block might be split again. */
595 walk->u.flags &= ~ITERATE_SPLIT_DONE;
596 error = ntfs_dir_insert(walk, start, entry);
601 static int ntfs_getdir_iterate_byposition(ntfs_iterate_s *walk, char* start,
605 int curpos = 0, destpos = 0;
607 if (walk->u.pos != 0) {
608 if (ntfs_is_top(walk->u.pos))
610 destpos = ntfs_pop(&walk->u.pos);
613 if (walk->u.pos == 0) {
614 if (ntfs_entry_has_subnodes(entry))
615 ntfs_descend(walk, start, entry);
617 walk->u.pos = ntfs_top();
618 if (ntfs_is_top(walk->u.pos) &&
619 !ntfs_entry_is_used(entry))
621 walk->u.pos = ntfs_push(walk->u.pos, curpos);
624 if (curpos == destpos) {
625 if (!ntfs_is_top(walk->u.pos) &&
626 ntfs_entry_has_subnodes(entry)) {
627 retval = ntfs_descend(walk, start, entry);
629 walk->u.pos = ntfs_push(walk->u.pos,
633 if (!ntfs_entry_is_used(entry))
637 if (ntfs_entry_is_used(entry)) {
638 retval = ntfs_copyresult(walk->result, entry);
641 walk->u.pos = ntfs_top();
646 if (!ntfs_entry_is_used(entry))
648 length = NTFS_GETU16(entry + 8);
650 ntfs_error("infinite loop\n");
658 /* Iterate over a list of entries, either from an index block, or from the
660 * If searching BY_POSITION, pop the top index from the position. If the
661 * position stack is empty then, return the item at the index and set the
662 * position to the next entry. If the position stack is not empty,
663 * recursively proceed for subnodes. If the entry at the position is the
664 * 'end of dir' entry, return 'not found' and the empty stack.
665 * If searching BY_NAME, walk through the items until found or until
666 * one item is collated after the requested item. In the former case, return
667 * the result. In the latter case, recursively proceed to the subnodes.
668 * If 'end of dir' is reached, the name is not in the directory */
669 static int ntfs_getdir_iterate(ntfs_iterate_s *walk, char *start, char *entry)
674 if (walk->type == BY_POSITION)
675 return ntfs_getdir_iterate_byposition(walk, start, entry);
677 /* If the current entry is a real one, compare with the
678 * requested item. If the current entry is the last item, it
679 * is always larger than the requested item. */
680 cmp = ntfs_entry_is_used(entry) ?
681 ntfs_my_strcmp(walk,entry) : -1;
682 switch (walk->type) {
686 return ntfs_entry_has_subnodes(entry) ?
687 ntfs_descend(walk, start, entry) : 0;
689 return ntfs_copyresult(walk->result, entry);
697 return ntfs_entry_has_subnodes(entry) ?
698 ntfs_descend(walk, start, entry) :
699 ntfs_dir_insert(walk, start, entry);
707 ntfs_error("TODO\n"); /* FIXME: ? */
709 if (!ntfs_entry_is_used(entry))
711 length = NTFS_GETU16(entry + 8);
713 ntfs_error("infinite loop\n");
721 /* Tree walking is done using position numbers. The following numbers have a
726 * All other numbers encode sequences of indices. The sequence a, b, c is
727 * encoded as <stop><c><b><a>, where <foo> is the encoding of foo. The
728 * first few integers are encoded as follows:
729 * 0: 0000 1: 0010 2: 0100 3: 0110
730 * 4: 1000 5: 1010 6: 1100 stop: 1110
731 * 7: 000001 8: 000101 9: 001001 10: 001101
732 * The least significant bits give the width of this encoding, the other bits
733 * encode the value, starting from the first value of the interval.
734 * tag width first value last value
739 * More values are hopefully not needed, as the file position has currently
740 * 64 bits in total. */
742 /* Find an entry in the directory. Return 0 if not found, otherwise copy the
743 * entry to the result buffer. */
744 int ntfs_getdir(ntfs_iterate_s *walk)
746 int length = walk->dir->vol->mft_record_size;
748 /* Start at the index root. */
749 char *root = ntfs_malloc(length);
754 io.fn_put = ntfs_put;
757 error = ntfs_read_attr(walk->dir, walk->dir->vol->at_index_root, I30,
760 ntfs_error("Not a directory\n");
764 /* FIXME: Move these to walk. */
765 walk->dir->u.index.recordsize = NTFS_GETU32(root + 0x8);
766 walk->dir->u.index.clusters_per_record = NTFS_GETU32(root + 0xC);
767 /* FIXME: Consistency check. */
769 retval = ntfs_getdir_iterate(walk, root, root + 0x20);
774 /* Find an entry in the directory by its position stack. Iteration starts
775 * if the stack is 0, in which case the position is set to the first item
776 * in the directory. If the position is nonzero, return the item at the
777 * position and change the position to the next item. The position is -1
778 * if there are no more items. */
779 int ntfs_getdir_byposition(ntfs_iterate_s *walk)
781 walk->type = BY_POSITION;
782 return ntfs_getdir(walk);
785 /* Find an entry in the directory by its name. Return 0 if not found. */
786 int ntfs_getdir_byname(ntfs_iterate_s *walk)
788 walk->type = BY_NAME;
789 return ntfs_getdir(walk);
792 int ntfs_getdir_unsorted(ntfs_inode *ino, u32 *p_high, u32 *p_low,
793 int (*cb)(ntfs_u8 *, void *), void *param)
796 char *buf = 0, *entry = 0;
797 ntfs_attribute *attr;
799 int byte, bit, err = 0;
800 u32 start, finish, ibs, max_size;
805 ntfs_error("%s(): No inode! Returning -EINVAL.\n",__FUNCTION__);
810 ntfs_error("%s(): Inode 0x%lx has no volume. Returning "
811 "-EINVAL.\n", __FUNCTION__, ino->i_number);
814 ntfs_debug(DEBUG_DIR3, "%s(): Unsorted 1: Entering for inode 0x%lx, "
815 "p_high = 0x%x, p_low = 0x%x.\n", __FUNCTION__,
816 ino->i_number, *p_high, *p_low);
818 /* We are still in the index root. */
819 buf = ntfs_malloc(io.size = vol->mft_record_size);
822 io.fn_put = ntfs_put;
824 err = ntfs_read_attr(ino, vol->at_index_root, I30, 0, &io);
827 ino->u.index.recordsize = ibs = NTFS_GETU32(buf + 0x8);
828 ino->u.index.clusters_per_record = NTFS_GETU32(buf + 0xC);
830 ntfs_debug(DEBUG_DIR3, "%s(): Unsorted 2: In index root.\n",
832 ibs_bits = ffs(ibs) - 1;
833 /* Compensate for faked "." and "..". */
835 } else { /* We are in an index record. */
836 io.size = ibs = ino->u.index.recordsize;
837 buf = ntfs_malloc(ibs);
840 ibs_bits = ffs(ibs) - 1;
841 io.fn_put = ntfs_put;
844 * 0 is index root, index allocation starts at 1 and works in
845 * units of index block size (ibs).
847 ib_ofs = (s64)(*p_high - 1) << ibs_bits;
848 err = ntfs_read_attr(ino, vol->at_index_allocation, I30, ib_ofs,
850 if (err || io.size != ibs)
852 if (!ntfs_check_index_record(ino, buf)) {
853 ntfs_error("%s(): Index block 0x%x is not an index "
854 "record. Returning -ENOTDIR.\n",
855 __FUNCTION__, *p_high - 1);
859 entry = buf + 0x18 + NTFS_GETU16(buf + 0x18);
860 ntfs_debug(DEBUG_DIR3, "%s(): Unsorted 3: In index "
861 "allocation.\n", __FUNCTION__);
864 /* Process the entries. */
866 for (; entry < (buf + ibs) && ntfs_entry_is_used(entry);
867 entry += NTFS_GETU16(entry + 8)) {
868 if (start < finish) {
869 /* Skip entries that were already processed. */
870 ntfs_debug(DEBUG_DIR3, "%s(): Unsorted 4: Skipping "
871 "already processed entry p_high 0x%x, "
872 "p_low 0x%x.\n", __FUNCTION__, *p_high,
877 ntfs_debug(DEBUG_DIR3, "%s(): Unsorted 5: Processing entry "
878 "p_high 0x%x, p_low 0x%x.\n", __FUNCTION__,
880 if ((err = cb(entry, param))) {
881 /* filldir signalled us to stop. */
882 ntfs_debug(DEBUG_DIR3, "%s(): Unsorted 6: cb returned "
883 "%i, returning 0, p_high 0x%x, "
884 "p_low 0x%x.\n", __FUNCTION__, err,
891 ntfs_debug(DEBUG_DIR3, "%s(): Unsorted 7: After processing entries, "
892 "p_high 0x%x, p_low 0x%x.\n", __FUNCTION__, *p_high,
894 /* We have to locate the next record. */
898 attr = ntfs_find_attr(ino, vol->at_bitmap, I30);
900 /* Directory does not have index bitmap and index allocation. */
902 ntfs_debug(DEBUG_DIR3, "%s(): Unsorted 8: No index allocation. "
903 "Returning 0, p_high 0x7fff, p_low 0x0.\n",
907 max_size = attr->size;
908 if (max_size > 0x7fff >> 3) {
909 ntfs_error("%s(): Directory too large. Visible "
910 "length is truncated.\n", __FUNCTION__);
911 max_size = 0x7fff >> 3;
913 buf = ntfs_malloc(max_size);
918 err = ntfs_read_attr(ino, vol->at_bitmap, I30, 0, &io);
919 if (err || io.size != max_size)
921 attr = ntfs_find_attr(ino, vol->at_index_allocation, I30);
924 ntfs_debug(DEBUG_DIR3, "%s(): Unsorted 9: Find attr failed. "
925 "Returning -EIO.\n", __FUNCTION__);
928 if (attr->resident) {
930 ntfs_debug(DEBUG_DIR3, "%s(): Unsorted 9.5: IA is resident. Not"
931 " allowed. Returning EINVAL.\n", __FUNCTION__);
934 /* Loop while going through non-allocated index records. */
937 if (++*p_high >= 0x7fff) {
938 ntfs_error("%s(): Unsorted 10: Directory "
939 "inode 0x%lx overflowed the maximum "
940 "number of index allocation buffers "
941 "the driver can cope with. Pretending "
942 "to be at end of directory.\n",
943 __FUNCTION__, ino->i_number);
946 if (*p_high > max_size || (s64)*p_high << ibs_bits >
949 /* No more index records. */
953 ntfs_debug(DEBUG_DIR3, "%s(): Unsorted 10.5: No more "
954 "index records. Returning 0, p_high "
955 "0x7fff, p_low 0.\n", __FUNCTION__);
958 byte = (ntfs_cluster_t)(*p_high - 1);
959 bit = 1 << (byte & 7);
961 if ((buf[byte] & bit))
964 ntfs_debug(DEBUG_DIR3, "%s(): Unsorted 11: Done. Returning 0, p_high "
965 "0x%x, p_low 0x%x.\n", __FUNCTION__, *p_high, *p_low);
971 ntfs_error("%s(): Read failed. Returning error code %i.\n",
977 int ntfs_dir_add(ntfs_inode *dir, ntfs_inode *new, ntfs_attribute *name)
981 ntfs_u8* entry, *ndata;
984 walk.type = DIR_INSERT;
988 ndata = name->d.data;
989 walk.name = (ntfs_u16*)(ndata + 0x42);
990 walk.namelen = NTFS_GETU8(ndata + 0x40);
991 walk.new_entry_size = esize = (nsize + 0x10 + 7) & ~7;
992 walk.new_entry = entry = ntfs_malloc(esize);
995 NTFS_PUTINUM(entry, new);
996 NTFS_PUTU16(entry + 0x8, esize); /* Size of entry. */
997 NTFS_PUTU16(entry + 0xA, nsize); /* Size of original name attribute. */
998 NTFS_PUTU16(entry + 0xC, 0); /* Flags. */
999 NTFS_PUTU16(entry + 0xE, 0); /* Reserved. */
1000 ntfs_memcpy(entry + 0x10, ndata, nsize);
1001 ntfs_bzero(entry + 0x10 + nsize, esize - 0x10 - nsize);
1002 error = ntfs_getdir(&walk);
1004 ntfs_free(walk.new_entry);
1009 int ntfs_dir_add1(ntfs_inode *dir, const char* name, int namelen,
1012 ntfs_iterate_s walk;
1016 ntfs_attribute *name_attr;
1017 error = ntfs_decodeuni(dir->vol, name, namelen, &walk.name,
1021 /* FIXME: Set flags. */
1022 walk.type = DIR_INSERT;
1024 /* walk.new = ino; */
1025 /* Prepare new entry. */
1026 /* Round up to a multiple of 8. */
1027 walk.new_entry_size = nsize = ((0x52 + 2 * walk.namelen + 7) / 8) * 8;
1028 walk.new_entry = entry = ntfs_malloc(nsize);
1031 ntfs_bzero(entry, nsize);
1032 NTFS_PUTINUM(entry, ino);
1033 NTFS_PUTU16(entry + 8, nsize);
1034 NTFS_PUTU16(entry + 0xA, 0x42 + 2 * namelen); /* FIXME: Size of name
1036 NTFS_PUTU32(entry + 0xC, 0); /* FIXME: D-F? */
1037 name_attr = ntfs_find_attr(ino, vol->at_file_name, 0);
1038 /* FIXME: multiple names */
1039 if (!name_attr || !name_attr->resident)
1041 /* Directory, file stamps, sizes, filename. */
1042 ntfs_memcpy(entry + 0x10, name_attr->d.data, 0x42 + 2 * namelen);
1043 error = ntfs_getdir(&walk);
1044 ntfs_free(walk.name);
1049 /* Fills out and creates an INDEX_ROOT attribute. */
1050 int ntfs_add_index_root(ntfs_inode *ino, int type)
1053 ntfs_u8 data[0x30]; /* 0x20 header, 0x10 last entry. */
1056 NTFS_PUTU32(data, type);
1057 /* Collation rule. 1 == COLLATION_FILENAME */
1058 NTFS_PUTU32(data + 4, 1);
1059 NTFS_PUTU32(data + 8, ino->vol->index_record_size);
1060 NTFS_PUTU32(data + 0xC, ino->vol->index_clusters_per_record);
1061 /* Byte offset to first INDEX_ENTRY. */
1062 NTFS_PUTU32(data + 0x10, 0x10);
1063 /* Size of entries, including header. */
1064 NTFS_PUTU32(data + 0x14, 0x20);
1065 NTFS_PUTU32(data + 0x18, 0x20);
1066 /* No index allocation, yet. */
1067 NTFS_PUTU32(data + 0x1C, 0);
1068 /* Add last entry. */
1069 /* Indexed MFT record. */
1070 NTFS_PUTU64(data + 0x20, 0);
1071 /* Size of entry. */
1072 NTFS_PUTU32(data + 0x28, 0x10);
1073 /* Flags: Last entry, no child nodes. */
1074 NTFS_PUTU32(data + 0x2C, 2);
1076 ntfs_indexname(name, type);
1077 return ntfs_create_attr(ino, ino->vol->at_index_root, name,
1078 data, sizeof(data), &da);
1081 int ntfs_mkdir(ntfs_inode *dir, const char *name, int namelen,
1086 error = ntfs_alloc_inode(dir, result, name, namelen, NTFS_AFLAG_DIR);
1089 error = ntfs_add_index_root(result, 0x30);
1092 /* Set directory bit. */
1093 result->attr[0x16] |= 2;
1094 error = ntfs_update_inode(dir);
1097 error = ntfs_update_inode(result);