You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ntfs-3g/ntfsprogs-ntfsfix-cleanups-...

153 lines
4.5 KiB

diff -up ntfs-3g_ntfsprogs-2011.4.12/ntfsprogs/ntfsfix.c.ntfsfixfixes ntfs-3g_ntfsprogs-2011.4.12/ntfsprogs/ntfsfix.c
--- ntfs-3g_ntfsprogs-2011.4.12/ntfsprogs/ntfsfix.c.ntfsfixfixes 2011-04-10 14:04:41.000000000 -0400
+++ ntfs-3g_ntfsprogs-2011.4.12/ntfsprogs/ntfsfix.c 2011-09-07 10:18:48.367406438 -0400
@@ -93,6 +93,7 @@ static const char FAILED[] = "FAILED\n
static struct {
char *volume;
BOOL no_action;
+ BOOL clear_bad_sectors;
} opt;
/**
@@ -106,9 +107,10 @@ static void usage(void)
"Usage: %s [options] device\n"
" Attempt to fix an NTFS partition.\n"
"\n"
- " -h, --help Display this help\n"
- " -n, --no-action Do not write anything\n"
- " -V, --version Display version information\n"
+ " -b, --clear-bad-sectors Clear the bad sector list\n"
+ " -h, --help Display this help\n"
+ " -n, --no-action Do not write anything\n"
+ " -V, --version Display version information\n"
"\n"
"For example: %s /dev/hda6\n\n",
EXEC_NAME, VERSION, EXEC_NAME,
@@ -127,7 +129,8 @@ static void version(void)
"Attempt to fix an NTFS partition.\n\n"
"Copyright (c) 2000-2006 Anton Altaparmakov\n"
"Copyright (c) 2002-2006 Szabolcs Szakacsits\n"
- "Copyright (c) 2007 Yura Pakhuchiy\n\n",
+ "Copyright (c) 2007 Yura Pakhuchiy\n\n"
+ "Copyright (c) 2011 Jean-Pierre Andre\n\n",
EXEC_NAME, VERSION);
ntfs_log_info("%s\n%s%s", ntfs_gpl, ntfs_bugs, ntfs_home);
exit(1);
@@ -139,12 +142,13 @@ static void version(void)
static void parse_options(int argc, char **argv)
{
int c;
- static const char *sopt = "-hnV";
+ static const char *sopt = "-bhnV";
static const struct option lopt[] = {
- { "help", no_argument, NULL, 'h' },
- { "no-action", no_argument, NULL, 'n' },
- { "version", no_argument, NULL, 'V' },
- { NULL, 0, NULL, 0 }
+ { "help", no_argument, NULL, 'h' },
+ { "no-action", no_argument, NULL, 'n' },
+ { "clear-bad-sectors", no_argument, NULL, 'b' },
+ { "version", no_argument, NULL, 'V' },
+ { NULL, 0, NULL, 0 }
};
memset(&opt, 0, sizeof(opt));
@@ -159,6 +163,9 @@ static void parse_options(int argc, char
usage();
}
break;
+ case 'b':
+ opt.clear_bad_sectors = TRUE;
+ break;
case 'n':
opt.no_action = TRUE;
break;
@@ -306,6 +313,57 @@ static int empty_journal(ntfs_volume *vo
}
/**
+ * Clear the bad cluster marks (option)
+ */
+static int clear_badclus(ntfs_volume *vol)
+{
+ static ntfschar badstream[] = {
+ const_cpu_to_le16('$'), const_cpu_to_le16('B'),
+ const_cpu_to_le16('a'), const_cpu_to_le16('d')
+ } ;
+ ntfs_inode *ni;
+ ntfs_attr *na;
+ BOOL ok;
+
+ ok = FALSE;
+ ntfs_log_info("Going to un-mark the bad clusters ($BadClus)... ");
+ ni = ntfs_inode_open(vol, FILE_BadClus);
+ if (ni) {
+ na = ntfs_attr_open(ni, AT_DATA, badstream, 4);
+ if (na) {
+ if (na->initialized_size) {
+ /*
+ * Truncate the stream to free all its clusters,
+ * then reallocate a sparse stream to full size
+ * of volume.
+ */
+ if (!ntfs_attr_truncate(na,0)
+ && !ntfs_attr_truncate(na,vol->nr_clusters
+ << vol->cluster_size_bits)) {
+ ni->flags |= FILE_ATTR_SPARSE_FILE;
+ NInoFileNameSetDirty(ni);
+ ok = TRUE;
+ } else {
+ ntfs_log_perror("Failed to un-mark the bad clusters");
+ }
+ } else {
+ ntfs_log_info("No bad clusters...");
+ ok = TRUE;
+ }
+ ntfs_attr_close(na);
+ } else {
+ ntfs_log_perror("Failed to open $BadClus::$Bad");
+ }
+ ntfs_inode_close(ni);
+ } else {
+ ntfs_log_perror("Failed to open inode FILE_BadClus");
+ }
+ if (ok)
+ ntfs_log_info(OK);
+ return (ok ? 0 : -1);
+}
+
+/**
* fix_mftmirr
*/
static int fix_mftmirr(ntfs_volume *vol)
@@ -767,6 +825,7 @@ static int fix_startup(struct ntfs_devic
errno = 0;
res = -1;
dev_open = FALSE;
+ full_bs = (char*)NULL;
if (!dev || !dev->d_ops || !dev->d_name) {
errno = EINVAL;
ntfs_log_perror("%s: dev = %p", __FUNCTION__, dev);
@@ -847,7 +906,7 @@ error_exit:
}
}
eo = errno;
- free(bs);
+ free(full_bs);
if (vol) {
free(vol->upcase);
free(vol);
@@ -985,6 +1044,12 @@ int main(int argc, char **argv)
ntfs_log_error("Error: Unknown NTFS version.\n");
goto error_exit;
}
+ if (opt.clear_bad_sectors && !opt.no_action) {
+ if (clear_badclus(vol)) {
+ ntfs_log_error("Error: Failed to un-mark bad sectors.\n");
+ goto error_exit;
+ }
+ }
if (vol->major_ver >= 3) {
/*
* FIXME: If on NTFS 3.0+, check for presence of the usn