Commit d14e09af authored by Anton Altaparmakov's avatar Anton Altaparmakov

NTFS: 2.1.10 - Force read-only (re)mounting of volumes with unsupported flags.

parent 9d41ab4c
...@@ -273,6 +273,9 @@ ChangeLog ...@@ -273,6 +273,9 @@ ChangeLog
Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog. Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog.
2.1.10:
- Force read-only (re)mounting of volumes with unsupported volume
flags and various cleanups.
2.1.9: 2.1.9:
- Fix two bugs in handling of corner cases in the decompression engine. - Fix two bugs in handling of corner cases in the decompression engine.
2.1.8: 2.1.8:
......
...@@ -19,9 +19,23 @@ ToDo: ...@@ -19,9 +19,23 @@ ToDo:
sufficient for synchronisation here. We then just need to make sure sufficient for synchronisation here. We then just need to make sure
ntfs_readpage/writepage/truncate interoperate properly with us. ntfs_readpage/writepage/truncate interoperate properly with us.
2.1.10 - . 2.1.10 - Force read-only (re)mounting of volumes with unsupported volume flags.
- Finish off the white space cleanups (remove trailing spaces, etc). - Finish off the white space cleanups (remove trailing spaces, etc).
- Clean up ntfs_fill_super() and ntfs_read_inode_mount() by removing
the kludges around the first iget(). Instead of (re)setting ->s_op
we have the $MFT inode set up by explicit new_inode() / set ->i_ino /
insert_inode_hash() / call ntfs_read_inode_mount() directly. This
kills the need for second super_operations and allows to return error
from ntfs_read_inode_mount() without resorting to ugly "poisoning"
tricks. (Al Viro)
- Force read-only (re)mounting if any of the following bits are set in
the volume information flags:
VOLUME_IS_DIRTY, VOLUME_RESIZE_LOG_FILE,
VOLUME_UPGRADE_ON_MOUNT, VOLUME_DELETE_USN_UNDERWAY,
VOLUME_REPAIR_OBJECT_ID, VOLUME_MODIFIED_BY_CHKDSK
To make this easier we define VOLUME_MUST_MOUNT_RO_MASK with all the
above bits set so the test is made easy.
2.1.9 - Fix two bugs in decompression engine. 2.1.9 - Fix two bugs in decompression engine.
......
...@@ -5,7 +5,7 @@ obj-$(CONFIG_NTFS_FS) += ntfs.o ...@@ -5,7 +5,7 @@ obj-$(CONFIG_NTFS_FS) += ntfs.o
ntfs-objs := aops.o attrib.o compress.o debug.o dir.o file.o inode.o logfile.o \ ntfs-objs := aops.o attrib.o compress.o debug.o dir.o file.o inode.o logfile.o \
mft.o mst.o namei.o super.o sysctl.o unistr.o upcase.o mft.o mst.o namei.o super.o sysctl.o unistr.o upcase.o
EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.10-WIP\" EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.10\"
ifeq ($(CONFIG_NTFS_DEBUG),y) ifeq ($(CONFIG_NTFS_DEBUG),y)
EXTRA_CFLAGS += -DDEBUG EXTRA_CFLAGS += -DDEBUG
......
...@@ -1090,7 +1090,7 @@ typedef enum { /* Identifier authority. */ ...@@ -1090,7 +1090,7 @@ typedef enum { /* Identifier authority. */
SECURITY_NULL_RID = 0, /* S-1-0 */ SECURITY_NULL_RID = 0, /* S-1-0 */
SECURITY_WORLD_RID = 0, /* S-1-1 */ SECURITY_WORLD_RID = 0, /* S-1-1 */
SECURITY_LOCAL_RID = 0, /* S-1-2 */ SECURITY_LOCAL_RID = 0, /* S-1-2 */
SECURITY_CREATOR_OWNER_RID = 0, /* S-1-3 */ SECURITY_CREATOR_OWNER_RID = 0, /* S-1-3 */
SECURITY_CREATOR_GROUP_RID = 1, /* S-1-3 */ SECURITY_CREATOR_GROUP_RID = 1, /* S-1-3 */
...@@ -1110,10 +1110,10 @@ typedef enum { /* Identifier authority. */ ...@@ -1110,10 +1110,10 @@ typedef enum { /* Identifier authority. */
SECURITY_AUTHENTICATED_USER_RID = 0xb, SECURITY_AUTHENTICATED_USER_RID = 0xb,
SECURITY_RESTRICTED_CODE_RID = 0xc, SECURITY_RESTRICTED_CODE_RID = 0xc,
SECURITY_TERMINAL_SERVER_RID = 0xd, SECURITY_TERMINAL_SERVER_RID = 0xd,
SECURITY_LOGON_IDS_RID = 5, SECURITY_LOGON_IDS_RID = 5,
SECURITY_LOGON_IDS_RID_COUNT = 3, SECURITY_LOGON_IDS_RID_COUNT = 3,
SECURITY_LOCAL_SYSTEM_RID = 0x12, SECURITY_LOCAL_SYSTEM_RID = 0x12,
SECURITY_NT_NON_UNIQUE = 0x15, SECURITY_NT_NON_UNIQUE = 0x15,
...@@ -1123,12 +1123,12 @@ typedef enum { /* Identifier authority. */ ...@@ -1123,12 +1123,12 @@ typedef enum { /* Identifier authority. */
/* /*
* Well-known domain relative sub-authority values (RIDs). * Well-known domain relative sub-authority values (RIDs).
*/ */
/* Users. */ /* Users. */
DOMAIN_USER_RID_ADMIN = 0x1f4, DOMAIN_USER_RID_ADMIN = 0x1f4,
DOMAIN_USER_RID_GUEST = 0x1f5, DOMAIN_USER_RID_GUEST = 0x1f5,
DOMAIN_USER_RID_KRBTGT = 0x1f6, DOMAIN_USER_RID_KRBTGT = 0x1f6,
/* Groups. */ /* Groups. */
DOMAIN_GROUP_RID_ADMINS = 0x200, DOMAIN_GROUP_RID_ADMINS = 0x200,
DOMAIN_GROUP_RID_USERS = 0x201, DOMAIN_GROUP_RID_USERS = 0x201,
...@@ -1145,12 +1145,12 @@ typedef enum { /* Identifier authority. */ ...@@ -1145,12 +1145,12 @@ typedef enum { /* Identifier authority. */
DOMAIN_ALIAS_RID_USERS = 0x221, DOMAIN_ALIAS_RID_USERS = 0x221,
DOMAIN_ALIAS_RID_GUESTS = 0x222, DOMAIN_ALIAS_RID_GUESTS = 0x222,
DOMAIN_ALIAS_RID_POWER_USERS = 0x223, DOMAIN_ALIAS_RID_POWER_USERS = 0x223,
DOMAIN_ALIAS_RID_ACCOUNT_OPS = 0x224, DOMAIN_ALIAS_RID_ACCOUNT_OPS = 0x224,
DOMAIN_ALIAS_RID_SYSTEM_OPS = 0x225, DOMAIN_ALIAS_RID_SYSTEM_OPS = 0x225,
DOMAIN_ALIAS_RID_PRINT_OPS = 0x226, DOMAIN_ALIAS_RID_PRINT_OPS = 0x226,
DOMAIN_ALIAS_RID_BACKUP_OPS = 0x227, DOMAIN_ALIAS_RID_BACKUP_OPS = 0x227,
DOMAIN_ALIAS_RID_REPLICATOR = 0x228, DOMAIN_ALIAS_RID_REPLICATOR = 0x228,
DOMAIN_ALIAS_RID_RAS_SERVERS = 0x229, DOMAIN_ALIAS_RID_RAS_SERVERS = 0x229,
DOMAIN_ALIAS_RID_PREW2KCOMPACCESS = 0x22a, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS = 0x22a,
...@@ -1258,7 +1258,7 @@ typedef enum { ...@@ -1258,7 +1258,7 @@ typedef enum {
ACCESS_ALLOWED_COMPOUND_ACE_TYPE= 4, ACCESS_ALLOWED_COMPOUND_ACE_TYPE= 4,
ACCESS_MAX_MS_V3_ACE_TYPE = 4, ACCESS_MAX_MS_V3_ACE_TYPE = 4,
/* The following are Win2k only. */ /* The following are Win2k only. */
ACCESS_MIN_MS_OBJECT_ACE_TYPE = 5, ACCESS_MIN_MS_OBJECT_ACE_TYPE = 5,
ACCESS_ALLOWED_OBJECT_ACE_TYPE = 5, ACCESS_ALLOWED_OBJECT_ACE_TYPE = 5,
...@@ -1325,33 +1325,33 @@ typedef enum { ...@@ -1325,33 +1325,33 @@ typedef enum {
*/ */
/* Specific rights for files and directories are as follows: */ /* Specific rights for files and directories are as follows: */
/* Right to read data from the file. (FILE) */ /* Right to read data from the file. (FILE) */
FILE_READ_DATA = const_cpu_to_le32(0x00000001), FILE_READ_DATA = const_cpu_to_le32(0x00000001),
/* Right to list contents of a directory. (DIRECTORY) */ /* Right to list contents of a directory. (DIRECTORY) */
FILE_LIST_DIRECTORY = const_cpu_to_le32(0x00000001), FILE_LIST_DIRECTORY = const_cpu_to_le32(0x00000001),
/* Right to write data to the file. (FILE) */ /* Right to write data to the file. (FILE) */
FILE_WRITE_DATA = const_cpu_to_le32(0x00000002), FILE_WRITE_DATA = const_cpu_to_le32(0x00000002),
/* Right to create a file in the directory. (DIRECTORY) */ /* Right to create a file in the directory. (DIRECTORY) */
FILE_ADD_FILE = const_cpu_to_le32(0x00000002), FILE_ADD_FILE = const_cpu_to_le32(0x00000002),
/* Right to append data to the file. (FILE) */ /* Right to append data to the file. (FILE) */
FILE_APPEND_DATA = const_cpu_to_le32(0x00000004), FILE_APPEND_DATA = const_cpu_to_le32(0x00000004),
/* Right to create a subdirectory. (DIRECTORY) */ /* Right to create a subdirectory. (DIRECTORY) */
FILE_ADD_SUBDIRECTORY = const_cpu_to_le32(0x00000004), FILE_ADD_SUBDIRECTORY = const_cpu_to_le32(0x00000004),
/* Right to read extended attributes. (FILE/DIRECTORY) */ /* Right to read extended attributes. (FILE/DIRECTORY) */
FILE_READ_EA = const_cpu_to_le32(0x00000008), FILE_READ_EA = const_cpu_to_le32(0x00000008),
/* Right to write extended attributes. (FILE/DIRECTORY) */ /* Right to write extended attributes. (FILE/DIRECTORY) */
FILE_WRITE_EA = const_cpu_to_le32(0x00000010), FILE_WRITE_EA = const_cpu_to_le32(0x00000010),
/* Right to execute a file. (FILE) */ /* Right to execute a file. (FILE) */
FILE_EXECUTE = const_cpu_to_le32(0x00000020), FILE_EXECUTE = const_cpu_to_le32(0x00000020),
/* Right to traverse the directory. (DIRECTORY) */ /* Right to traverse the directory. (DIRECTORY) */
FILE_TRAVERSE = const_cpu_to_le32(0x00000020), FILE_TRAVERSE = const_cpu_to_le32(0x00000020),
/* /*
* Right to delete a directory and all the files it contains (its * Right to delete a directory and all the files it contains (its
* children), even if the files are read-only. (DIRECTORY) * children), even if the files are read-only. (DIRECTORY)
...@@ -1360,10 +1360,10 @@ typedef enum { ...@@ -1360,10 +1360,10 @@ typedef enum {
/* Right to read file attributes. (FILE/DIRECTORY) */ /* Right to read file attributes. (FILE/DIRECTORY) */
FILE_READ_ATTRIBUTES = const_cpu_to_le32(0x00000080), FILE_READ_ATTRIBUTES = const_cpu_to_le32(0x00000080),
/* Right to change file attributes. (FILE/DIRECTORY) */ /* Right to change file attributes. (FILE/DIRECTORY) */
FILE_WRITE_ATTRIBUTES = const_cpu_to_le32(0x00000100), FILE_WRITE_ATTRIBUTES = const_cpu_to_le32(0x00000100),
/* /*
* The standard rights (bits 16 to 23). Are independent of the type of * The standard rights (bits 16 to 23). Are independent of the type of
* object being secured. * object being secured.
...@@ -1396,15 +1396,15 @@ typedef enum { ...@@ -1396,15 +1396,15 @@ typedef enum {
* The following STANDARD_RIGHTS_* are combinations of the above for * The following STANDARD_RIGHTS_* are combinations of the above for
* convenience and are defined by the Win32 API. * convenience and are defined by the Win32 API.
*/ */
/* These are currently defined to READ_CONTROL. */ /* These are currently defined to READ_CONTROL. */
STANDARD_RIGHTS_READ = const_cpu_to_le32(0x00020000), STANDARD_RIGHTS_READ = const_cpu_to_le32(0x00020000),
STANDARD_RIGHTS_WRITE = const_cpu_to_le32(0x00020000), STANDARD_RIGHTS_WRITE = const_cpu_to_le32(0x00020000),
STANDARD_RIGHTS_EXECUTE = const_cpu_to_le32(0x00020000), STANDARD_RIGHTS_EXECUTE = const_cpu_to_le32(0x00020000),
/* Combines DELETE, READ_CONTROL, WRITE_DAC, and WRITE_OWNER access. */ /* Combines DELETE, READ_CONTROL, WRITE_DAC, and WRITE_OWNER access. */
STANDARD_RIGHTS_REQUIRED = const_cpu_to_le32(0x000f0000), STANDARD_RIGHTS_REQUIRED = const_cpu_to_le32(0x000f0000),
/* /*
* Combines DELETE, READ_CONTROL, WRITE_DAC, WRITE_OWNER, and * Combines DELETE, READ_CONTROL, WRITE_DAC, WRITE_OWNER, and
* SYNCHRONIZE access. * SYNCHRONIZE access.
...@@ -1790,6 +1790,9 @@ typedef enum { ...@@ -1790,6 +1790,9 @@ typedef enum {
VOLUME_REPAIR_OBJECT_ID = const_cpu_to_le16(0x0020), VOLUME_REPAIR_OBJECT_ID = const_cpu_to_le16(0x0020),
VOLUME_MODIFIED_BY_CHKDSK = const_cpu_to_le16(0x8000), VOLUME_MODIFIED_BY_CHKDSK = const_cpu_to_le16(0x8000),
VOLUME_FLAGS_MASK = const_cpu_to_le16(0x803f), VOLUME_FLAGS_MASK = const_cpu_to_le16(0x803f),
/* To make our life easier when checking if we must mount read-only. */
VOLUME_MUST_MOUNT_RO_MASK = const_cpu_to_le16(0x8037),
} __attribute__ ((__packed__)) VOLUME_FLAGS; } __attribute__ ((__packed__)) VOLUME_FLAGS;
/* /*
...@@ -1973,7 +1976,7 @@ typedef enum { ...@@ -1973,7 +1976,7 @@ typedef enum {
QUOTA_FLAG_USER_MASK = const_cpu_to_le32(0x00000007), QUOTA_FLAG_USER_MASK = const_cpu_to_le32(0x00000007),
/* Bit mask for user quota flags. */ /* Bit mask for user quota flags. */
/* These flags are only present in the quota defaults index entry, /* These flags are only present in the quota defaults index entry,
i.e. in the entry where owner_id = QUOTA_DEFAULTS_ID. */ i.e. in the entry where owner_id = QUOTA_DEFAULTS_ID. */
QUOTA_FLAG_TRACKING_ENABLED = const_cpu_to_le32(0x00000010), QUOTA_FLAG_TRACKING_ENABLED = const_cpu_to_le32(0x00000010),
...@@ -2177,7 +2180,7 @@ typedef enum { ...@@ -2177,7 +2180,7 @@ typedef enum {
IO_REPARSE_TAG_IS_ALIAS = const_cpu_to_le32(0x20000000), IO_REPARSE_TAG_IS_ALIAS = const_cpu_to_le32(0x20000000),
IO_REPARSE_TAG_IS_HIGH_LATENCY = const_cpu_to_le32(0x40000000), IO_REPARSE_TAG_IS_HIGH_LATENCY = const_cpu_to_le32(0x40000000),
IO_REPARSE_TAG_IS_MICROSOFT = const_cpu_to_le32(0x80000000), IO_REPARSE_TAG_IS_MICROSOFT = const_cpu_to_le32(0x80000000),
IO_REPARSE_TAG_RESERVED_ZERO = const_cpu_to_le32(0x00000000), IO_REPARSE_TAG_RESERVED_ZERO = const_cpu_to_le32(0x00000000),
IO_REPARSE_TAG_RESERVED_ONE = const_cpu_to_le32(0x00000001), IO_REPARSE_TAG_RESERVED_ONE = const_cpu_to_le32(0x00000001),
IO_REPARSE_TAG_RESERVED_RANGE = const_cpu_to_le32(0x00000001), IO_REPARSE_TAG_RESERVED_RANGE = const_cpu_to_le32(0x00000001),
......
...@@ -28,8 +28,6 @@ ...@@ -28,8 +28,6 @@
#include "inode.h" #include "inode.h"
extern int format_mft_record(ntfs_inode *ni, MFT_RECORD *m); extern int format_mft_record(ntfs_inode *ni, MFT_RECORD *m);
//extern int format_mft_record2(struct super_block *vfs_sb,
// const unsigned long inum, MFT_RECORD *m);
extern MFT_RECORD *map_mft_record(ntfs_inode *ni); extern MFT_RECORD *map_mft_record(ntfs_inode *ni);
extern void unmap_mft_record(ntfs_inode *ni); extern void unmap_mft_record(ntfs_inode *ni);
......
...@@ -314,7 +314,9 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt) ...@@ -314,7 +314,9 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt)
#else /* ! NTFS_RW */ #else /* ! NTFS_RW */
/* /*
* For the read-write compiled driver, if we are remounting read-write, * For the read-write compiled driver, if we are remounting read-write,
* make sure there aren't any volume errors and empty the lofgile. * make sure there are no volume errors and that no unsupported volume
* flags are set. Also, empty the logfile journal as it would become
* stale as soon as something is written to the volume.
*/ */
if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) { if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) {
static const char *es = ". Cannot remount read-write."; static const char *es = ". Cannot remount read-write.";
...@@ -324,6 +326,11 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt) ...@@ -324,6 +326,11 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt)
es); es);
return -EROFS; return -EROFS;
} }
if (vol->vol_flags & VOLUME_MUST_MOUNT_RO_MASK) {
ntfs_error(sb, "Volume has unsupported flags set and "
"is read-only%s", es);
return -EROFS;
}
if (!ntfs_empty_logfile(vol->logfile_ino)) { if (!ntfs_empty_logfile(vol->logfile_ino)) {
ntfs_error(sb, "Failed to empty journal $LogFile%s", ntfs_error(sb, "Failed to empty journal $LogFile%s",
es); es);
...@@ -1133,6 +1140,31 @@ static BOOL load_system_files(ntfs_volume *vol) ...@@ -1133,6 +1140,31 @@ static BOOL load_system_files(ntfs_volume *vol)
printk(KERN_INFO "NTFS volume version %i.%i.\n", vol->major_ver, printk(KERN_INFO "NTFS volume version %i.%i.\n", vol->major_ver,
vol->minor_ver); vol->minor_ver);
#ifdef NTFS_RW #ifdef NTFS_RW
/* Make sure that no unsupported volume flags are set. */
if (vol->vol_flags & VOLUME_MUST_MOUNT_RO_MASK) {
static const char *es1 = "Volume has unsupported flags set ";
static const char *es2 = ". Run chkdsk and mount in Windows.";
/* If a read-write mount, convert it to a read-only mount. */
if (!(sb->s_flags & MS_RDONLY)) {
if (!(vol->on_errors & (ON_ERRORS_REMOUNT_RO |
ON_ERRORS_CONTINUE))) {
ntfs_error(sb, "%s and neither on_errors="
"continue nor on_errors="
"remount-ro was specified%s",
es1, es2);
goto iput_vol_err_out;
}
sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
ntfs_error(sb, "%s. Mounting read-only%s", es1, es2);
} else
ntfs_warning(sb, "%s. Will not be able to remount "
"read-write%s", es1, es2);
/*
* Do not set NVolErrors() because ntfs_remount() re-checks the
* flags which we need to do in case any flags have changed.
*/
}
/* /*
* Get the inode for the logfile, check it and determine if the volume * Get the inode for the logfile, check it and determine if the volume
* was shutdown cleanly. * was shutdown cleanly.
...@@ -1240,6 +1272,7 @@ static BOOL load_system_files(ntfs_volume *vol) ...@@ -1240,6 +1272,7 @@ static BOOL load_system_files(ntfs_volume *vol)
#ifdef NTFS_RW #ifdef NTFS_RW
if (vol->logfile_ino) if (vol->logfile_ino)
iput(vol->logfile_ino); iput(vol->logfile_ino);
iput_vol_err_out:
#endif /* NTFS_RW */ #endif /* NTFS_RW */
iput(vol->vol_ino); iput(vol->vol_ino);
iput_lcnbmp_err_out: iput_lcnbmp_err_out:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment