From d0cc75987881889ec37e98e96e230d426f272b82 Mon Sep 17 00:00:00 2001 From: "flatcap.org!ntfs" Date: Thu, 9 Oct 2003 07:56:06 +0000 Subject: [PATCH] Updates from Szaka (Logical change 1.191) --- include/volume.h | 2 +- libntfs/attrib.c | 2 +- libntfs/volume.c | 2 +- ntfsprogs/ntfsresize.8.in | 53 +++++++++++++----- ntfsprogs/ntfsresize.c | 114 ++++++++++++++++++++++++-------------- 5 files changed, 113 insertions(+), 60 deletions(-) diff --git a/include/volume.h b/include/volume.h index 0ef8ee63..edcc4e18 100644 --- a/include/volume.h +++ b/include/volume.h @@ -80,7 +80,7 @@ typedef enum { * NTFS version 1.1 and 1.2 are used by Windows NT4. * NTFS version 2.x is used by Windows 2000 Beta * NTFS version 3.0 is used by Windows 2000. - * NTFS version 3.1 is used by Windows XP and .NET. + * NTFS version 3.1 is used by Windows XP and Windows Server 2003. */ #define NTFS_V1_1(major, minor) ((major) == 1 && (minor) == 1) diff --git a/libntfs/attrib.c b/libntfs/attrib.c index f216a1dd..df0a59f6 100644 --- a/libntfs/attrib.c +++ b/libntfs/attrib.c @@ -2785,7 +2785,7 @@ put_err_out: * and do clear the partial run. The latter approach would be more inline with * what windows would do, even though windows wouldn't even make the attribute * sparse, it would just allocate clusters instead. TODO: Check what happens on - * WinXP and .NET. FIXME: Make sure to check what NT4 does with an NTFS1.2 + * WinXP and 2003. FIXME: Make sure to check what NT4 does with an NTFS1.2 * volume that has sparse files. I suspect it will blow up so we will need to * perform allocations of clusters, like NT4 would do for NTFS1.2 while we can * use sparse attributes on NTFS3.x. diff --git a/libntfs/volume.c b/libntfs/volume.c index f068e40e..17d32d4b 100644 --- a/libntfs/volume.c +++ b/libntfs/volume.c @@ -1100,7 +1100,7 @@ int ntfs_check_if_mounted(const char *file, unsigned long *mnt_flags) * Version 1.1 and 1.2 are used by Windows NT4. * Version 2.x is used by Windows 2000 Beta's * Version 3.0 is used by Windows 2000. - * Version 3.1 is used by Windows XP and .NET. + * Version 3.1 is used by Windows XP and Windows Server 2003. * * Return 0 if NTFS version is supported otherwise -1 with errno set. * diff --git a/ntfsprogs/ntfsresize.8.in b/ntfsprogs/ntfsresize.8.in index 23fe0a7b..2206722d 100644 --- a/ntfsprogs/ntfsresize.8.in +++ b/ntfsprogs/ntfsresize.8.in @@ -1,7 +1,7 @@ .\" -*- nroff -*- .\" Copyright 2002-2003 by Szabolcs Szakacsits All Rights Reserved. .\" -.TH NTFSRESIZE 8 "Jan 2003" "ntfsprogs @VERSION@" +.TH NTFSRESIZE 8 "Oct 2003" "ntfsprogs @VERSION@" .SH NAME ntfsresize \- resize an NTFS filesystem .SH SYNOPSIS @@ -12,8 +12,8 @@ ntfsresize \- resize an NTFS filesystem .SH DESCRIPTION The .B ntfsresize -program non-destructively resizes Windows NT4, 2000, XP or .NET -NTFS filesystems. At present it can be used to enlarge or shrink a +program non-destructively resizes Windows NT4, 2000, XP or Windows Server 2003 +NTFS filesystems. At present it can be used to enlarge any or shrink a defragmented NTFS filesystem located on an unmounted .I device (usually a disk partition). The new volume will have @@ -28,12 +28,29 @@ parameter is given in kilo-, mega- or gigabytes respectively. .B ntfsresize conforms to the SI, ATA, IEEE standards and the disk manufacturers by using k=10^3, M=10^6 and G=10^9. -The options + +If both +.B -i +and +.B -s +are omitted then the +NTFS filesystem will be enlarged to the device size. + +If the options .B -i and .B -s -are mutually exclusive. If both of them are omitted then the -NTFS filesystem will be enlarged to the device size. +are used together then list inodes (files) using space over +.I size\fR. At present +.B ntfsresize +can not relocate the files listed to the beginning +of the partition thus it refuses to resize at +.I size +if there is any. +To convert the inodes to meaningful file names, you must mount +the partition and run for instance + 'find /mount/point -inum -o -inum ...'. + Before a real resize operation, always make a read-only test run using the .B -n @@ -45,9 +62,9 @@ program doesn't manipulate the size of partitions. To do that you have to use a disk partitioning tool, for example .BR fdisk (8). .PP -If you wish to enlarge an NTFS filesystem, -you must first make sure you can expand the size of the -underlying partition first. This can be done using +If you wish to enlarge an NTFS filesystem then +first you must enlarge the size of the +underlying partition. This can be done using .BR fdisk (8) by deleting the partition and recreating it with a larger size. Then you may use @@ -78,7 +95,7 @@ computer from the disk! .PP Note, .B ntfsresize -schedules 'chkdsk' to make an NTFS consistency check +schedules an NTFS consistency check when you will boot Windows. Windows may force a reboot after the successful consistency check. @@ -96,7 +113,9 @@ Display help and exit. .TP .B -i Using this option you can calculate the smallest shrunken volume size supported. -This option will not make any changes to the filesystem. +This option will not make any changes to the filesystem. +You can use this option with +.B -s\fR. See the meaning of this case above. .TP .B -n Use this option to make a test run before doing the real resize operation. @@ -109,7 +128,11 @@ Resize volume to \fIsize\fR[\fBk\fR|\fBM\fR|\fBG\fR] bytes. The optional modifiers \fBk\fR, \fBM\fR, \fBG\fR mean the .I size parameter is given in kilo-, mega- or gigabytes respectively. -Conforming to standards, k=10^3, M=10^6 and G=10^9. +Conforming to standards, k=10^3, M=10^6 and G=10^9. You can also use this option +with +.B -i\fR. See the meaning of this case above. +.SH EXIT CODES +The exit code is 0 on success, non-zero otherwise. .SH BUGS No bugs are known or has been reported so far in the current version. If you find otherwise, please report it to @@ -117,8 +140,9 @@ If you find otherwise, please report it to ctx->attr; + + if (resize->ni->mft_no != 8) + return 0; + + if (str2unicode("$Bad", &ustr, &len) == -1) + return -1; + + if (ustr && ntfs_names_are_equal(ustr, len, + (uchar_t*)((char*)a + le16_to_cpu(a->name_offset)), + a->name_length, 0, NULL, 0)) + ret = 1; + + if (ustr != AT_UNNAMED) + free(ustr); + + return ret; +} + void collect_shrink_constraints(ntfs_resize_t *resize, s64 last_lcn) { s64 inode; ATTR_FLAGS flags; - struct llcn_t *llcn; + struct llcn_t *llcn = NULL; + int ret; inode = resize->ni->mft_no; flags = resize->ctx->attr->flags; @@ -491,7 +527,12 @@ void collect_shrink_constraints(ntfs_resize_t *resize, s64 last_lcn) else if (flags & ATTR_IS_COMPRESSED) llcn = &resize->last_compressed; - else if (inode == 0) + else if ((ret = has_bad_sectors(resize)) != 0) { + if (ret == -1) + perr_exit("Couldn't convert string to Unicode."); + err_exit("Device has bad sectors, not supported yet.\n"); + + } else if (inode == 0) llcn = &resize->last_mft; else if (inode == 1) @@ -633,6 +674,7 @@ void compare_bitmaps(struct bitmap *a) { s64 i, pos, count; int mismatch = 0; + int backup_boot = 0; u8 bm[NTFS_BUF_SIZE]; printf("Accounting clusters ...\n"); @@ -664,6 +706,15 @@ void compare_bitmaps(struct bitmap *a) if (bit == ntfs_bit_get(bm, i * 8 + cl % 8)) continue; + if (!mismatch && !bit && !backup_boot && + cl == vol->nr_clusters / 2) { + /* FIXME: call also boot sector check */ + backup_boot = 1; + printf("Found backup boot sector in " + "the middle of the volume.\n"); + continue; + } + if (++mismatch > 10) continue; @@ -679,7 +730,7 @@ void compare_bitmaps(struct bitmap *a) mismatch); err_exit("Filesystem check failed! Windows wasn't shutdown " "properly or inconsistent\nfilesystem. Please run " - "chkdsk on Windows.\n"); + "chkdsk /f on Windows.\n"); } } @@ -767,7 +818,7 @@ void print_hint(const char *s, struct llcn_t llcn) runs_b = llcn.lcn * vol->cluster_size; runs_mb = rounded_up_division(runs_b, NTFS_MBYTE); - printf("%-19s: %6Ld MB %8Ld\n", s, runs_mb, llcn.inode); + printf("%-19s: %9Ld MB %8Ld\n", s, runs_mb, llcn.inode); } /** @@ -788,7 +839,7 @@ void advise_on_resize(ntfs_resize_t *resize) old_b = vol->nr_clusters * vol->cluster_size; old_mb = rounded_up_division(old_b, NTFS_MBYTE); - printf("File feature Last used Last inode\n"); + printf("File feature Last used at By inode\n"); print_hint("$MFT", resize->last_mft); print_hint("$MFTMirr", resize->last_mftmir); print_hint("Compressed", resize->last_compressed); @@ -828,27 +879,6 @@ void advise_on_resize(ntfs_resize_t *resize) printf(").\n"); } -/** - * look_for_bad_sector - * - * Read through the metadata file $BadClus looking for bad sectors on the disk. - */ -void look_for_bad_sector(ATTR_RECORD *a) -{ - runlist *rl; - int i; - - rl = ntfs_mapping_pairs_decompress(vol, a, NULL); - if (!rl) - perr_exit("ntfs_mapping_pairs_decompress"); - - for (i = 0; rl[i].length; i++) - if (rl[i].lcn != LCN_HOLE) - err_exit("Device has bad sectors, not supported\n"); - - free(rl); -} - /** * rl_set * @@ -1101,14 +1131,9 @@ void lookup_data_attr(MFT_REF mref, char *aname, ntfs_attr_search_ctx **ctx) if (!(*ctx = ntfs_attr_get_search_ctx(ni, NULL))) perr_exit("ntfs_get_attr_search_ctx"); - if (aname && ((len = ntfs_mbstoucs(aname, &ustr, 0)) == -1)) + if (str2unicode(aname, &ustr, &len) == -1) perr_exit("Unable to convert string to Unicode"); - if (!ustr || !len) { - ustr = AT_UNNAMED; - len = 0; - } - if (ntfs_attr_lookup(AT_DATA, ustr, len, 0, 0, NULL, 0, *ctx)) perr_exit("ntfs_lookup_attr"); @@ -1145,7 +1170,6 @@ void truncate_badclust_file(s64 nr_clusters) printf("Updating $BadClust file ...\n"); lookup_data_attr((MFT_REF)FILE_BadClus, "$Bad", &ctx); - look_for_bad_sector(ctx->attr); /* FIXME: sanity_check_attr(ctx->attr); */ truncate_badclust_bad_attr(ctx->attr, nr_clusters); @@ -1247,11 +1271,10 @@ void print_volume_size(char *str, s64 bytes) */ void print_disk_usage(ntfs_resize_t *resize) { - s64 total, used, free, relocations; + s64 total, used, relocations; total = vol->nr_clusters * vol->cluster_size; used = resize->inuse * vol->cluster_size; - free = total - used; relocations = resize->relocations * vol->cluster_size; printf("Space in use : %lld MB (%.1f%%)\n", @@ -1275,9 +1298,12 @@ void mount_volume() { unsigned long mntflag; - if (ntfs_check_if_mounted(opt.volume, &mntflag)) - perr_exit("Failed to check '%s' mount state", opt.volume); - + if (ntfs_check_if_mounted(opt.volume, &mntflag)) { + perr_printf("Failed to check '%s' mount state", opt.volume); + printf("Probably /etc/mtab is missing. It's too risky to" + "continue.\nYou might try an another Linux distro.\n"); + exit(1); + } if (mntflag & NTFS_MF_MOUNTED) { if (!(mntflag & NTFS_MF_READONLY)) err_exit("Device %s is mounted read-write. " @@ -1303,7 +1329,7 @@ void mount_volume() if (vol->flags & VOLUME_IS_DIRTY) if (opt.force-- <= 0) - err_exit("Volume is dirty. Run chkdsk and " + err_exit("Volume is dirty. Run chkdsk /f and " "please try again (or see -f option).\n"); printf("NTFS volume version: %d.%d\n", vol->major_ver, vol->minor_ver); @@ -1383,7 +1409,9 @@ int main(int argc, char **argv) if (opt.bytes) { if (device_size < opt.bytes) err_exit("New size can't be bigger than the " - "device size (%Ld bytes).\n", device_size); + "device size (%Ld bytes).\nIf you want to " + "enlarge NTFS then first enlarge the device " + "size by e.g. fdisk.\n", device_size); } else if (!opt.info) opt.bytes = device_size; @@ -1424,7 +1452,7 @@ int main(int argc, char **argv) resize.multi_ref); err_exit("Filesystem check failed! Windows wasn't shutdown " "properly or inconsistent\nfilesystem. Please run " - "chkdsk on Windows.\n"); + "chkdsk /f on Windows.\n"); } compare_bitmaps(&lcn_bitmap);