return volume set dirty functionality to ntfsfix on Yura's request. Anton

edge.strict_endians
antona 2005-10-05 13:01:10 +00:00
parent ce52b49c36
commit aa7e3cc98e
2 changed files with 131 additions and 2 deletions

View File

@ -55,7 +55,6 @@ xx/xx/2005 - 1.12.0-WIP
set a flag, it overwrites the flags! Rename it to
ntfs_volume_write_flags() and clean it up a lot. Update all
callers. (Anton)
- Change ntfsfix to no longer set the volume dirty. (Anton)
- Change everything to supply an ntfs_inode and NULL for mft record
when calling ntfs_attr_get_search_ctx() except a very few cases which
genuinely need this functionality as they work on a too low level.

View File

@ -1,7 +1,7 @@
/**
* NtfsFix - Part of the Linux-NTFS project.
*
* Copyright (c) 2000-2003 Anton Altaparmakov.
* Copyright (c) 2000-2005 Anton Altaparmakov.
*
* This utility will attempt to fix a partition that has been damaged by the
* current Linux-NTFS driver. It should be run after dismounting an NTFS
@ -87,6 +87,7 @@ GEN_PRINTF(Qprintf, stdout, NULL, FALSE)
static const char *EXEC_NAME = "ntfsfix";
static const char *OK = "OK";
static const char *FAILED = "FAILED";
static BOOL vol_is_dirty = FALSE;
static BOOL journal_is_empty = FALSE;
struct {
@ -159,6 +160,128 @@ static void parse_options(int argc, char **argv)
}
}
static int OLD_ntfs_volume_set_flags(ntfs_volume *vol, const u16 flags)
{
MFT_RECORD *m = NULL;
ATTR_RECORD *a;
VOLUME_INFORMATION *c;
ntfs_attr_search_ctx *ctx;
int ret = -1; /* failure */
if (!vol) {
errno = EINVAL;
return -1;
}
if (ntfs_file_record_read(vol, FILE_Volume, &m, NULL)) {
Dperror("Failed to read $Volume");
return -1;
}
/* Sanity check */
if (!(m->flags & MFT_RECORD_IN_USE)) {
Dprintf("Error: $Volume has been deleted. Cannot "
"handle this yet. Run chkdsk to fix this.\n");
errno = EIO;
goto err_exit;
}
/* Get a pointer to the volume information attribute. */
ctx = ntfs_attr_get_search_ctx(NULL, m);
if (!ctx) {
Dperror("Failed to allocate attribute search context");
goto err_exit;
}
if (ntfs_attr_lookup(AT_VOLUME_INFORMATION, AT_UNNAMED, 0, 0, 0, NULL,
0, ctx)) {
Dputs("Error: Attribute $VOLUME_INFORMATION was not found in "
"$Volume!");
goto err_out;
}
a = ctx->attr;
/* Sanity check. */
if (a->non_resident) {
Dputs("Error: Attribute $VOLUME_INFORMATION must be resident "
"(and it isn't)!");
errno = EIO;
goto err_out;
}
/* Get a pointer to the value of the attribute. */
c = (VOLUME_INFORMATION*)(le16_to_cpu(a->value_offset) + (char*)a);
/* Sanity checks. */
if ((char*)c + le32_to_cpu(a->value_length) >
le16_to_cpu(m->bytes_in_use) + (char*)m ||
le16_to_cpu(a->value_offset) +
le32_to_cpu(a->value_length) > le32_to_cpu(a->length)) {
Dputs("Error: Attribute $VOLUME_INFORMATION in $Volume is "
"corrupt!");
errno = EIO;
goto err_out;
}
/* Set the volume flags. */
vol->flags = c->flags = cpu_to_le16(flags);
if (ntfs_mft_record_write(vol, FILE_Volume, m)) {
Dperror("Error writing $Volume");
goto err_out;
}
ret = 0; /* success */
err_out:
ntfs_attr_put_search_ctx(ctx);
err_exit:
if (m)
free(m);
return ret;
}
static int set_dirty_flag(ntfs_volume *vol)
{
u16 flags;
if (vol_is_dirty == TRUE)
return 0;
printf("Setting required flags on partition... ");
/*
* Set chkdsk flag, i.e. mark the partition dirty so chkdsk will run
* and fix it for us.
*/
flags = vol->flags | VOLUME_IS_DIRTY;
/* If NTFS volume version >= 2.0 then set mounted on NT4 flag. */
if (vol->major_ver >= 2)
flags |= VOLUME_MOUNTED_ON_NT4;
if (OLD_ntfs_volume_set_flags(vol, flags)) {
puts(FAILED);
fprintf(stderr, "Error setting volume flags.\n");
return -1;
}
puts(OK);
vol_is_dirty = TRUE;
return 0;
}
static int set_dirty_flag_mount(ntfs_volume *vol)
{
u16 flags;
if (vol_is_dirty == TRUE)
return 0;
printf("Setting required flags on partition... ");
/*
* Set chkdsk flag, i.e. mark the partition dirty so chkdsk will run
* and fix it for us.
*/
flags = vol->flags | VOLUME_IS_DIRTY;
/* If NTFS volume version >= 2.0 then set mounted on NT4 flag. */
if (vol->major_ver >= 2)
flags |= VOLUME_MOUNTED_ON_NT4;
if (ntfs_volume_write_flags(vol, flags)) {
puts(FAILED);
fprintf(stderr, "Error setting volume flags.\n");
return -1;
}
puts(OK);
vol_is_dirty = TRUE;
return 0;
}
static int empty_journal(ntfs_volume *vol)
{
if (journal_is_empty == TRUE)
@ -336,6 +459,10 @@ int main(int argc, char **argv)
printf("Processing of $MFT and $MFTMirr completed successfully.\n");
/* FIXME: Will this fail? Probably... */
if (set_dirty_flag(vol) < 0)
goto error_exit;
if (empty_journal(vol) < 0)
goto error_exit;
@ -358,6 +485,9 @@ mount_ok:
goto error_exit;
}
if (set_dirty_flag_mount(vol) < 0)
goto error_exit;
if (empty_journal(vol) < 0)
goto error_exit;