diff -urNp /cygdrive/d/Temp/ntfsprogs-2.0.0-old/ntfsprogs/ntfsmove.c /cygdrive/d/Temp/ntfsprogs-2.0.0-new/ntfsprogs/ntfsmove.c --- /cygdrive/d/Temp/ntfsprogs-2.0.0-old/ntfsprogs/ntfsmove.c 2007-09-19 22:21:09.000000000 +0530 +++ /cygdrive/d/Temp/ntfsprogs-2.0.0-new/ntfsprogs/ntfsmove.c 2010-06-16 13:03:58.620351200 +0530 @@ -382,8 +382,8 @@ static void dump_runs(u8 *buffer, int le /** * find_unused */ -static runlist * find_unused(ntfs_volume *vol, s64 size, u64 loc - __attribute__((unused)), int flags __attribute__((unused))) +static runlist * find_unused(ntfs_volume *vol, s64 size, u64 loc, + int flags __attribute__((unused))) { const int bufsize = 8192; u8 *buffer; @@ -407,38 +407,89 @@ static runlist * find_unused(ntfs_volume clus = vol->lcnbmp_na->allocated_size / bufsize; //ntfs_log_info("clus = %d\n", clus); - for (i = 0; i < clus; i++) { - int bytes_read, j; - - bytes_read = ntfs_attr_pread(vol->lcnbmp_na, i*bufsize, - bufsize, buffer); - if (bytes_read != bufsize) { - ntfs_log_info("!read\n"); - return NULL; + if (loc == NTFS_MOVE_LOC_START || loc == NTFS_MOVE_LOC_BEST) + { + for (i = 0; i < clus; i++) { + int bytes_read, j; + + bytes_read = ntfs_attr_pread(vol->lcnbmp_na, i*bufsize, + bufsize, buffer); + if (bytes_read != bufsize) { + ntfs_log_info("!read\n"); + return NULL; + } + for (j = 0; j < bufsize*8; j++) { + bit = !!test_bit(j & 7, buffer[j>>3]); + if (curr == bit) { + count++; + if ((!bit) && (count >= size)) { + //res = calloc(2, sizeof(*res)); + res = calloc(1, 4096); + if (res) { + res[0].vcn = 0; + res[0].lcn = start; + res[0].length = size; + res[1].lcn = LCN_ENOENT; + } + goto done; + } + } else { + //ntfs_log_info("%d * %d\n", curr, count); + curr = bit; + count = 1; + start = i*bufsize*8 + j; + } + } } - for (j = 0; j < bufsize*8; j++) { - bit = !!test_bit(j & 7, buffer[j>>3]); - if (curr == bit) { - count++; - if ((!bit) && (count >= size)) { - //res = calloc(2, sizeof(*res)); - res = calloc(1, 4096); - if (res) { - res[0].vcn = 0; - res[0].lcn = start; - res[0].length = size; - res[1].lcn = LCN_ENOENT; + } + else if (loc == NTFS_MOVE_LOC_END) + { + for (i = clus - 1; i >= 0; i--) { + int bytes_read, j; + + //ntfs_log_info("reading %d/%lld\n", i*bufsize, vol->lcnbmp_na->allocated_size); + bytes_read = ntfs_attr_pread(vol->lcnbmp_na, i*bufsize, + bufsize, buffer); + if (bytes_read != bufsize) { + ntfs_log_info("!read\n"); + return NULL; + } + for (j = (bufsize*8) - 1; j >= 0 ; j--) { + bit = !!test_bit(j & 7, buffer[j>>3]); + if (curr == bit) { + count++; + if ((!bit) && (count >= size)) { + start = i*bufsize*8 + j; + //res = calloc(2, sizeof(*res)); + res = calloc(1, 4096); + if (res) { + res[0].vcn = 0; + res[0].lcn = start; + res[0].length = size; + res[1].lcn = LCN_ENOENT; + } + goto done; } - goto done; + } else { + //ntfs_log_info("%d * %d\n", curr, count); + curr = bit; + count = 1; } - } else { - //ntfs_log_info("%d * %d\n", curr, count); - curr = bit; - count = 1; - start = i*bufsize*8 + j; } + } + } + else + { + res = calloc(1, 4096); + if (res) { + res[0].vcn = 0; + res[0].lcn = loc; + res[0].length = size; + res[1].lcn = LCN_ENOENT; } + goto done; } + done: //ntfs_log_info("%d * %d\n", curr, count); @@ -678,6 +729,28 @@ static s64 move_datarun(ntfs_volume *vol return -1; } + if (loc == NTFS_MOVE_LOC_START || loc == NTFS_MOVE_LOC_BEST) + { + if (to->lcn >= run->lcn) + { + ntfs_log_info("clusters are already in start of the volume\n"); + return -1; + } + } + else if (loc == NTFS_MOVE_LOC_END) + { + if (to->lcn <= run->lcn) + { + ntfs_log_info("clusters are already in end of the volume\n"); + return -1; + } + } + else if (to->lcn == run->lcn) + { + ntfs_log_info("clusters are already in the given position\n"); + return -1; + } + to->vcn = run->vcn; // copy original runlist