Enabled fallback to read-only mount when volume is hibernated

When a volume is found hibernated (or prepared for fast restarting),
it is force-mounted as read-only.
pull/2/head
Jean-Pierre André 2016-04-06 09:51:47 +02:00
parent 887d8f8294
commit 8a1358fff4
4 changed files with 37 additions and 10 deletions

View File

@ -60,6 +60,7 @@ typedef struct _ntfs_volume ntfs_volume;
enum {
NTFS_MNT_NONE = 0x00000000,
NTFS_MNT_RDONLY = 0x00000001,
NTFS_MNT_MAY_RDONLY = 0x02000000, /* Allow fallback to ro */
NTFS_MNT_FORENSIC = 0x04000000, /* No modification during
* mount. */
NTFS_MNT_EXCLUSIVE = 0x08000000,

View File

@ -97,6 +97,11 @@ static const char *hibernated_volume_msg =
"Windows fully (no hibernation or fast restarting), or mount the volume\n"
"read-only with the 'ro' mount option.\n";
static const char *fallback_readonly_msg =
"Falling back to read-only mount because the NTFS partition is in an\n"
"unsafe state. Please resume and shutdown Windows fully (no hibernation\n"
"or fast restarting.)\n";
static const char *unclean_journal_msg =
"Write access is denied because the disk wasn't safely powered\n"
"off and the 'norecover' mount option was specified.\n";
@ -914,7 +919,9 @@ ntfs_volume *ntfs_device_mount(struct ntfs_device *dev, ntfs_mount_flags flags)
int i, j, eo;
unsigned int k;
u32 u;
BOOL need_fallback_ro;
need_fallback_ro = FALSE;
vol = ntfs_volume_startup(dev, flags);
if (!vol)
return NULL;
@ -1233,20 +1240,35 @@ ntfs_volume *ntfs_device_mount(struct ntfs_device *dev, ntfs_mount_flags flags)
*/
if (!(flags & (NTFS_MNT_RDONLY | NTFS_MNT_FORENSIC))) {
if (!(flags & NTFS_MNT_IGNORE_HIBERFILE) &&
ntfs_volume_check_hiberfile(vol, 1) < 0)
goto error_exit;
ntfs_volume_check_hiberfile(vol, 1) < 0) {
if (flags & NTFS_MNT_MAY_RDONLY)
need_fallback_ro = TRUE;
else
goto error_exit;
}
if (ntfs_volume_check_logfile(vol) < 0) {
/* Always reject cached metadata for now */
if (!(flags & NTFS_MNT_RECOVER) || (errno == EPERM))
goto error_exit;
ntfs_log_info("The file system wasn't safely "
"closed on Windows. Fixing.\n");
if (ntfs_logfile_reset(vol))
goto error_exit;
if (!(flags & NTFS_MNT_RECOVER) || (errno == EPERM)) {
if (flags & NTFS_MNT_MAY_RDONLY)
need_fallback_ro = TRUE;
else
goto error_exit;
} else {
ntfs_log_info("The file system wasn't safely "
"closed on Windows. Fixing.\n");
if (ntfs_logfile_reset(vol))
goto error_exit;
}
}
/* make $TXF_DATA resident if present on the root directory */
if (fix_txf_data(vol))
goto error_exit;
if (!(flags & NTFS_MNT_RDONLY) && !need_fallback_ro) {
if (fix_txf_data(vol))
goto error_exit;
}
}
if (need_fallback_ro) {
NVolSetReadOnly(vol);
ntfs_log_error("%s", fallback_readonly_msg);
}
return vol;

View File

@ -3940,6 +3940,8 @@ static int ntfs_open(const char *device)
flags |= NTFS_MNT_EXCLUSIVE;
if (ctx->ro)
flags |= NTFS_MNT_RDONLY;
else
flags |= NTFS_MNT_MAY_RDONLY;
if (ctx->recover)
flags |= NTFS_MNT_RECOVER;
if (ctx->hiberfile)

View File

@ -3744,6 +3744,8 @@ static int ntfs_open(const char *device)
flags |= NTFS_MNT_EXCLUSIVE;
if (ctx->ro)
flags |= NTFS_MNT_RDONLY;
else
flags |= NTFS_MNT_MAY_RDONLY;
if (ctx->recover)
flags |= NTFS_MNT_RECOVER;
if (ctx->hiberfile)