Updates from Szaka

(Logical change 1.191)
edge.strict_endians
flatcap.org!ntfs 2003-10-09 07:56:06 +00:00
parent b9d2243a6b
commit d0cc759878
5 changed files with 113 additions and 60 deletions

View File

@ -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)

View File

@ -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.

View File

@ -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.
*

View File

@ -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 <inode1> -o -inum <inode2> ...'.
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 <linux-ntfs-dev@lists.sourceforge.net>
@ -117,8 +140,9 @@ If you find otherwise, please report it to <linux-ntfs-dev@lists.sourceforge.net
.B MAKE SURE YOU HAVE A BACKUP
of your important data in case of an unexpected failure.
.PP
Future work is planned to include support resizing fragmented NTFS volumes.
Please note, Windows 2000, XP and .NET have built in NTFS defragmenter.
Future work is planned to include support for resizing fragmented NTFS volumes.
Please note, Windows 2000, XP and Windows Server 2003 have built in NTFS
defragmenter.
.SH AUTHOR
.B ntfsresize
has been written by
@ -143,5 +167,6 @@ http://mlf.linux.rulez.org/mlf/ezaz/ntfsresize.html
.BR sfdisk (8),
.BR parted (8),
.BR mkntfs (8),
.BR ntfsclone (8),
.BR ntfsprogs (8)

View File

@ -64,8 +64,7 @@ static const char *resize_important_msg =
"Otherwise you may lose your data or can't boot your computer from the disk!\n";
static const char *fragmented_volume_msg =
"The volume end is fragmented, this case is not yet supported. Defragment it\n"
"(Windows 2000, XP and .NET have built in defragmentation tool) and try again.\n";
"The volume end is fragmented, this case is not yet supported.\n";
struct {
int verbose;
@ -473,11 +472,48 @@ s64 nr_clusters_to_bitmap_byte_size(s64 nr_clusters)
return bm_bsize;
}
int str2unicode(char *aname, uchar_t **ustr, int *len)
{
if (aname && ((*len = ntfs_mbstoucs(aname, ustr, 0)) == -1))
return -1;
if (!*ustr || !*len) {
*ustr = AT_UNNAMED;
*len = 0;
}
return 0;
}
int has_bad_sectors(ntfs_resize_t *resize)
{
int len, ret = 0;
uchar_t *ustr = NULL;
ATTR_RECORD *a = resize->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);