aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Altaparmakov <anton@tuxera.com>2017-07-17 02:08:05 +0100
committerAnton Altaparmakov <anton@tuxera.com>2017-07-17 02:08:05 +0100
commite10d104af52def41e75debd30a9e1ba45156bcf3 (patch)
treee24ad2fd823b40f149bc692585429f7e23c77494
parent23f5cbcc20d6faf57edd9a92de10da73ef24e43f (diff)
downloadntfs-master.tar.gz
Relax hibernation check by both checking for lower case "hibr" andHEADmaster
upper case "HIBR" hibernation file magic and by not checking the first four kilobytes of the hibernation file against being zero. This relaxed checking followed the equivalent relaxation in NTFS-3g in commit 64f9f0dc1a7ed9766dac431b1f300536c394ec91. Signed-off-by: Anton Altaparmakov <anton@tuxera.com>
-rw-r--r--fs/ntfs/super.c51
1 files changed, 19 insertions, 32 deletions
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index ecb49870a680c..1ba9af7c2ab4f 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -1,7 +1,7 @@
/*
* super.c - NTFS kernel super block handling. Part of the Linux-NTFS project.
*
- * Copyright (c) 2001-2012 Anton Altaparmakov and Tuxera Inc.
+ * Copyright (c) 2001-2017 Anton Altaparmakov and Tuxera Inc.
* Copyright (c) 2001,2002 Richard Russon
*
* This program/include file is free software; you can redistribute it and/or
@@ -1239,6 +1239,12 @@ static bool load_and_check_logfile(ntfs_volume *vol,
#define NTFS_HIBERFIL_HEADER_SIZE 4096
+/* Magic identifiers present at the beginning of hiberfil.sys. */
+enum {
+ magic_hibr = cpu_to_le32(0x72626968), /* 'hibr' */
+ magic_HIBR = cpu_to_le32(0x52424948) /* 'HIBR' */
+};
+
/**
* check_windows_hibernation_status - check if Windows is suspended on a volume
* @vol: ntfs super block of device to check
@@ -1253,22 +1259,18 @@ static bool load_and_check_logfile(ntfs_volume *vol,
* for now this should do fine.
*
* If hiberfil.sys exists and is larger than 4kiB in size, we need to read the
- * hiberfil header (which is the first 4kiB). If this begins with "hibr",
- * Windows is definitely suspended. If it is completely full of zeroes,
- * Windows is definitely not hibernated. Any other case is treated as if
- * Windows is suspended. This caters for the above mentioned caveat of a
- * system with many volumes where no "hibr" magic would be present and there is
- * no zero header.
+ * hiberfil header (which is the first 4kiB). If this begins with "HIBR",
+ * Windows is suspended. If not then Windows is not suspended.
*
- * Return 0 if Windows is not hibernated on the volume, >0 if Windows is
- * hibernated on the volume, and -errno on error.
+ * Return 0 if Windows is not hibernated, >0 if Windows is hibernated and
+ * -errno on error.
*/
static int check_windows_hibernation_status(ntfs_volume *vol)
{
MFT_REF mref;
struct inode *vi;
struct page *page;
- u32 *kaddr, *kend;
+ u32 *kaddr;
ntfs_name *name = NULL;
int ret = 1;
static const ntfschar hiberfil[13] = { cpu_to_le16('h'),
@@ -1293,7 +1295,7 @@ static int check_windows_hibernation_status(ntfs_volume *vol)
/* If the file does not exist, Windows is not hibernated. */
if (ret == -ENOENT) {
ntfs_debug("hiberfil.sys not present. Windows is not "
- "hibernated on the volume.");
+ "hibernated.");
return 0;
}
/* A real error occurred. */
@@ -1313,8 +1315,7 @@ static int check_windows_hibernation_status(ntfs_volume *vol)
}
if (unlikely(i_size_read(vi) < NTFS_HIBERFIL_HEADER_SIZE)) {
ntfs_debug("hiberfil.sys is smaller than 4kiB (0x%llx). "
- "Windows is hibernated on the volume. This "
- "is not the system volume.", i_size_read(vi));
+ "Windows is hibernated.", i_size_read(vi));
goto iput_out;
}
page = ntfs_map_page(vi->i_mapping, 0);
@@ -1324,27 +1325,13 @@ static int check_windows_hibernation_status(ntfs_volume *vol)
goto iput_out;
}
kaddr = (u32*)page_address(page);
- if (*(le32*)kaddr == cpu_to_le32(0x72626968)/*'hibr'*/) {
- ntfs_debug("Magic \"hibr\" found in hiberfil.sys. Windows is "
- "hibernated on the volume. This is the "
- "system volume.");
+ if (*(le32*)kaddr == magic_hibr || *(le32*)kaddr == magic_HIBR) {
+ ntfs_debug("Magic \"%s\" found in hiberfil.sys. Windows is "
+ "hibernated.", (*(le32*)kaddr == magic_HIBR) ?
+ "HIBR" : "hibr");
goto unm_iput_out;
}
- kend = kaddr + NTFS_HIBERFIL_HEADER_SIZE/sizeof(*kaddr);
- do {
- if (unlikely(*kaddr)) {
- ntfs_debug("hiberfil.sys is larger than 4kiB "
- "(0x%llx), does not contain the "
- "\"hibr\" magic, and does not have a "
- "zero header. Windows is hibernated "
- "on the volume. This is not the "
- "system volume.", i_size_read(vi));
- goto unm_iput_out;
- }
- } while (++kaddr < kend);
- ntfs_debug("hiberfil.sys contains a zero header. Windows is not "
- "hibernated on the volume. This is the system "
- "volume.");
+ ntfs_debug("Windows is not hibernated.");
ret = 0;
unm_iput_out:
ntfs_unmap_page(page);