Changes by: szaka
Update of /cvsroot/linux-ntfs/ntfsprogs/ntfsprogs
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28771/ntfsprogs
Modified Files:
ntfsresize.c
Log Message:
Check and report bad sectors before cluster allocation check because
chkdsk doesn't always fix $Bitmap with bad sectors
Index: ntfsresize.c
===================================================================
RCS file: /cvsroot/linux-ntfs/ntfsprogs/ntfsprogs/ntfsresize.c,v
retrieving revision 1.99
retrieving revision 1.100
diff -u -p -r1.99 -r1.100
--- ntfsresize.c 16 Oct 2005 11:12:08 -0000 1.99
+++ ntfsresize.c 16 Oct 2005 18:50:56 -0000 1.100
@@ -692,13 +692,6 @@ static void collect_resize_constraints(n
if ((ret = has_bad_sectors(resize, 1)) != 0) {
if (ret == -1)
exit(1);
- if (NInoAttrList(resize->ni))
- err_exit("Hopelessly many bad sectors! Not supported.");
- if (resize->badclusters == 0)
- printf("WARNING: The disk has bad sector! "
- "This can cause reliability problems!\n");
- resize->badclusters += last_lcn - rl->lcn + 1;
- Vprintf("Bad clusters: %8lld - %lld\n", rl->lcn, last_lcn);
return;
}
@@ -1773,7 +1766,7 @@ static void relocate_inodes(ntfs_resize_
if (highest_vcn == resize->mft_highest_vcn)
err_exit("Sanity check failed! Highest_vcn = %lld. "
- "Please report!", highest_vcn);
+ "Please report!\n", highest_vcn);
}
done:
if (resize->mrec)
@@ -2039,6 +2032,56 @@ static void lookup_data_attr(ntfs_volume
free(ustr);
}
+static int check_bad_sectors(ntfs_volume *vol)
+{
+ ntfs_attr_search_ctx *ctx;
+ runlist *rl;
+ s64 i, badclusters = 0;
+
+ Vprintf("Checking for bad sectors ...\n");
+
+ lookup_data_attr(vol, FILE_BadClus, "$Bad", &ctx);
+
+ if (NInoAttrList(ctx->ntfs_ino))
+ err_exit("Hopelessly many bad sectors! Please report to "
+ "lin...@li...\n");
+
+ if (!ctx->attr->non_resident)
+ err_exit("Resident attribute in $BadClust! Please report to "
+ "lin...@li...\n");
+
+ if (!(rl = ntfs_mapping_pairs_decompress(vol, ctx->attr, NULL)))
+ perr_exit("Decompressing $BadClust:$Bad mapping pairs failed");
+
+ for (i = 0; rl[i].length; i++) {
+ /* CHECKME: LCN_RL_NOT_MAPPED check isn't needed */
+ if (rl[i].lcn == LCN_HOLE || rl[i].lcn == LCN_RL_NOT_MAPPED)
+ continue;
+
+ badclusters += rl[i].length;
+ Vprintf("Bad cluster: %8lld - %lld\n", rl[i].lcn,
+ rl[i].lcn + rl[i].length - 1);
+ }
+
+ if (badclusters) {
+ printf("%sThis software has detected that the disk has at least"
+ " %lld bad sector%s.\n",
+ !opt.badsectors ? NERR_PREFIX : "WARNING: ",
+ badclusters, badclusters - 1 ? "s" : "");
+ if (!opt.badsectors) {
+ printf("%s", bad_sectors_warning_msg);
+ exit(1);
+ } else
+ printf("WARNING: Bad sectors can cause reliability "
+ "problems and massive data loss!!!\n");
+ }
+
+ free(rl);
+ ntfs_attr_put_search_ctx(ctx);
+
+ return badclusters;
+}
+
/**
* truncate_badclust_file
*
@@ -2293,17 +2336,6 @@ static void check_resize_constraints(ntf
{
s64 new_size = resize->new_volume_size;
- if (resize->badclusters) {
- printf("%sThe NTFS volume has at least %lld bad sector%s.\n",
- !opt.badsectors ? NERR_PREFIX : "",
- resize->badclusters,
- resize->badclusters - 1 ? "s" : "");
- if (!opt.badsectors) {
- printf("%s", bad_sectors_warning_msg);
- exit(1);
- }
- }
-
/* FIXME: resize.shrink true also if only -i is used */
if (!resize->shrink)
return;
@@ -2412,22 +2444,28 @@ int main(int argc, char **argv)
printf("Nothing to do: NTFS volume size is already OK.\n");
exit(0);
}
-
+
+ memset(&resize, 0, sizeof(resize));
+ resize.vol = vol;
+ resize.new_volume_size = new_size;
+ /* This is also true if --info was used w/o --size (new_size = 0) */
+ if (new_size < vol->nr_clusters)
+ resize.shrink = 1;
+ if (opt.show_progress)
+ resize.progress.flags |= NTFS_PROGBAR;
+ /*
+ * Checking and __reporting__ of bad sectors must be done before cluster
+ * allocation check because chkdsk doesn't fix $Bitmap's w/ bad sectors
+ * thus users would (were) quite confused why chkdsk doesn't work.
+ */
+ resize.badclusters = check_bad_sectors(vol);
+
check_cluster_allocation(vol, &fsck);
print_disk_usage(vol, fsck.inuse);
- memset(&resize, 0, sizeof(resize));
- resize.new_volume_size = new_size;
resize.inuse = fsck.inuse;
resize.lcn_bitmap = fsck.lcn_bitmap;
- resize.vol = vol;
- if (opt.show_progress)
- resize.progress.flags |= NTFS_PROGBAR;
-
- /* This is also true if --info was used w/o --size (new_size = 0) */
- if (new_size < vol->nr_clusters)
- resize.shrink = 1;
set_resize_constraints(&resize);
set_disk_usage_constraint(&resize);
|