aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);