NTFS: Do more detailed reporting of why we cannot mount read-write by
Anton Altaparmakov [Fri, 24 Feb 2006 10:48:14 +0000 (10:48 +0000)]
     special casing the VOLUME_MODIFIED_BY_CHKDSK flag.

Signed-off-by: Anton Altaparmakov <aia21@cantab.net>

Documentation/filesystems/ntfs.txt
fs/ntfs/ChangeLog
fs/ntfs/Makefile
fs/ntfs/super.c
fs/ntfs/upcase.c
fs/ntfs/volume.h

index 614de31..2511685 100644 (file)
@@ -457,6 +457,12 @@ ChangeLog
 
 Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog.
 
+2.1.26:
+       - Implement support for sector sizes above 512 bytes (up to the maximum
+         supported by NTFS which is 4096 bytes).
+       - Enhance support for NTFS volumes which were supported by Windows but
+         not by Linux due to invalid attribute list attribute flags.
+       - A few minor updates and bug fixes.
 2.1.25:
        - Write support is now extended with write(2) being able to both
          overwrite existing file data and to extend files.  Also, if a write
index e66b4ac..9d8ffa8 100644 (file)
@@ -29,6 +29,8 @@ ToDo/Notes:
          kmem_cache_t.  (Pekka Enberg)
        - Implement support for sector sizes above 512 bytes (up to the maximum
          supported by NTFS which is 4096 bytes).
+       - Do more detailed reporting of why we cannot mount read-write by
+         special casing the VOLUME_MODIFIED_BY_CHKDSK flag.
        - Miscellaneous updates to layout.h.
        - Cope with attribute list attribute having invalid flags.  Windows
          copes with this and even chkdsk does not detect or fix this so we
index d0d45d1..d95fac7 100644 (file)
@@ -6,7 +6,7 @@ ntfs-objs := aops.o attrib.o collate.o compress.o debug.o dir.o file.o \
             index.o inode.o mft.o mst.o namei.o runlist.o super.o sysctl.o \
             unistr.o upcase.o
 
-EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.25\"
+EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.26\"
 
 ifeq ($(CONFIG_NTFS_DEBUG),y)
 EXTRA_CFLAGS += -DDEBUG
index 489f704..368a8ec 100644 (file)
@@ -472,9 +472,16 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt)
                        ntfs_error(sb, "Volume is dirty and read-only%s", es);
                        return -EROFS;
                }
+               if (vol->vol_flags & VOLUME_MODIFIED_BY_CHKDSK) {
+                       ntfs_error(sb, "Volume has been modified by chkdsk "
+                                       "and is read-only%s", es);
+                       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);
+                       ntfs_error(sb, "Volume has unsupported flags set "
+                                       "(0x%x) and is read-only%s",
+                                       (unsigned)le16_to_cpu(vol->vol_flags),
+                                       es);
                        return -EROFS;
                }
                if (ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY)) {
@@ -1845,11 +1852,24 @@ get_ctx_vol_failed:
        /* Make sure that no unsupported volume flags are set. */
        if (vol->vol_flags & VOLUME_MUST_MOUNT_RO_MASK) {
                static const char *es1a = "Volume is dirty";
-               static const char *es1b = "Volume has unsupported flags set";
-               static const char *es2 = ".  Run chkdsk and mount in Windows.";
-               const char *es1;
-               
-               es1 = vol->vol_flags & VOLUME_IS_DIRTY ? es1a : es1b;
+               static const char *es1b = "Volume has been modified by chkdsk";
+               static const char *es1c = "Volume has unsupported flags set";
+               static const char *es2a = ".  Run chkdsk and mount in Windows.";
+               static const char *es2b = ".  Mount in Windows.";
+               const char *es1, *es2;
+
+               es2 = es2a;
+               if (vol->vol_flags & VOLUME_IS_DIRTY)
+                       es1 = es1a;
+               else if (vol->vol_flags & VOLUME_MODIFIED_BY_CHKDSK) {
+                       es1 = es1b;
+                       es2 = es2b;
+               } else {
+                       es1 = es1c;
+                       ntfs_warning(sb, "Unsupported volume flags 0x%x "
+                                       "encountered.",
+                                       (unsigned)le16_to_cpu(vol->vol_flags));
+               }
                /* 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 |
index 879cdf1..9101807 100644 (file)
@@ -3,10 +3,7 @@
  *           Part of the Linux-NTFS project.
  *
  * Copyright (c) 2001 Richard Russon <ntfs@flatcap.org>
- * Copyright (c) 2001-2004 Anton Altaparmakov
- *
- * Modified for mkntfs inclusion 9 June 2001 by Anton Altaparmakov.
- * Modified for kernel inclusion 10 September 2001 by Anton Altparmakov.
+ * Copyright (c) 2001-2006 Anton Altaparmakov
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -75,12 +72,13 @@ ntfschar *generate_default_upcase(void)
        if (!uc)
                return uc;
        memset(uc, 0, default_upcase_len * sizeof(ntfschar));
+       /* Generate the little endian Unicode upcase table used by ntfs. */
        for (i = 0; i < default_upcase_len; i++)
                uc[i] = cpu_to_le16(i);
        for (r = 0; uc_run_table[r][0]; r++)
                for (i = uc_run_table[r][0]; i < uc_run_table[r][1]; i++)
-                       uc[i] = cpu_to_le16((le16_to_cpu(uc[i]) +
-                                       uc_run_table[r][2]));
+                       uc[i] = cpu_to_le16(le16_to_cpu(uc[i]) +
+                                       uc_run_table[r][2]);
        for (r = 0; uc_dup_table[r][0]; r++)
                for (i = uc_dup_table[r][0]; i < uc_dup_table[r][1]; i += 2)
                        uc[i + 1] = cpu_to_le16(le16_to_cpu(uc[i + 1]) - 1);
index 375cd20..406ab55 100644 (file)
@@ -2,7 +2,7 @@
  * volume.h - Defines for volume structures in NTFS Linux kernel driver. Part
  *           of the Linux-NTFS project.
  *
- * Copyright (c) 2001-2005 Anton Altaparmakov
+ * Copyright (c) 2001-2006 Anton Altaparmakov
  * Copyright (c) 2002 Richard Russon
  *
  * This program/include file is free software; you can redistribute it and/or
@@ -41,10 +41,8 @@ typedef struct {
         * structure has stabilized... (AIA)
         */
        /* Device specifics. */
-       struct super_block *sb;         /* Pointer back to the super_block,
-                                          so we don't have to get the offset
-                                          every time. */
-       LCN nr_blocks;                  /* Number of NTFS_BLOCK_SIZE bytes
+       struct super_block *sb;         /* Pointer back to the super_block. */
+       LCN nr_blocks;                  /* Number of sb->s_blocksize bytes
                                           sized blocks on the device. */
        /* Configuration provided by user at mount time. */
        unsigned long flags;            /* Miscellaneous flags, see below. */
@@ -141,8 +139,8 @@ typedef enum {
        NV_ShowSystemFiles,     /* 1: Return system files in ntfs_readdir(). */
        NV_CaseSensitive,       /* 1: Treat file names as case sensitive and
                                      create filenames in the POSIX namespace.
-                                     Otherwise be case insensitive and create
-                                     file names in WIN32 namespace. */
+                                     Otherwise be case insensitive but still
+                                     create file names in POSIX namespace. */
        NV_LogFileEmpty,        /* 1: $LogFile journal is empty. */
        NV_QuotaOutOfDate,      /* 1: $Quota is out of date. */
        NV_UsnJrnlStamped,      /* 1: $UsnJrnl has been stamped. */
@@ -153,7 +151,7 @@ typedef enum {
  * Macro tricks to expand the NVolFoo(), NVolSetFoo(), and NVolClearFoo()
  * functions.
  */
-#define NVOL_FNS(flag)                                 \
+#define DEFINE_NVOL_BIT_OPS(flag)                                      \
 static inline int NVol##flag(ntfs_volume *vol)         \
 {                                                      \
        return test_bit(NV_##flag, &(vol)->flags);      \
@@ -168,12 +166,12 @@ static inline void NVolClear##flag(ntfs_volume *vol)      \
 }
 
 /* Emit the ntfs volume bitops functions. */
-NVOL_FNS(Errors)
-NVOL_FNS(ShowSystemFiles)
-NVOL_FNS(CaseSensitive)
-NVOL_FNS(LogFileEmpty)
-NVOL_FNS(QuotaOutOfDate)
-NVOL_FNS(UsnJrnlStamped)
-NVOL_FNS(SparseEnabled)
+DEFINE_NVOL_BIT_OPS(Errors)
+DEFINE_NVOL_BIT_OPS(ShowSystemFiles)
+DEFINE_NVOL_BIT_OPS(CaseSensitive)
+DEFINE_NVOL_BIT_OPS(LogFileEmpty)
+DEFINE_NVOL_BIT_OPS(QuotaOutOfDate)
+DEFINE_NVOL_BIT_OPS(UsnJrnlStamped)
+DEFINE_NVOL_BIT_OPS(SparseEnabled)
 
 #endif /* _LINUX_NTFS_VOLUME_H */