public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [2.6.14-rc2-git] NTFS: Even more bug fixes!
@ 2005-09-26 13:31 Anton Altaparmakov
  2005-09-26 13:32 ` [PATCH 1/4] NTFS: Fix sparse warnings that have crept in over time Anton Altaparmakov
  0 siblings, 1 reply; 12+ messages in thread
From: Anton Altaparmakov @ 2005-09-26 13:31 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-ntfs-dev

Hi Linus, please pull from

rsync://rsync.kernel.org/pub/scm/linux/kernel/git/aia21/ntfs-2.6.git/HEAD

 fs/ntfs/ChangeLog  |   26 +++++++++++++++++---------
 fs/ntfs/Makefile   |    4 ++--
 fs/ntfs/layout.h   |    9 +++++----
 fs/ntfs/lcnalloc.c |   31 +++++++++++++------------------
 fs/ntfs/lcnalloc.h |   27 +++++++++++++--------------
 fs/ntfs/logfile.c  |   30 +++++++++++++++++++++++++-----
 fs/ntfs/logfile.h  |    2 +-
 fs/ntfs/mft.c      |    2 +-
 8 files changed, 77 insertions(+), 54 deletions(-)

This contains more bugfixes for NTFS that need to go in before 2.6.14
is released.  -  Please apply.  Thanks!  -  There should really not be any 
more for 2.6.14!  Famous last, last words...

Diff style patches generated with git format-patch follow as replies to 
this email.

Best regards,

	Anton
-- 
Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @)
Unix Support, Computing Service, University of Cambridge, CB2 3QH, UK
Linux NTFS maintainer / IRC: #ntfs on irc.freenode.net
WWW: http://linux-ntfs.sf.net/ & http://www-stu.christs.cam.ac.uk/~aia21/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 1/4] NTFS: Fix sparse warnings that have crept in over time.
  2005-09-26 13:31 [2.6.14-rc2-git] NTFS: Even more bug fixes! Anton Altaparmakov
@ 2005-09-26 13:32 ` Anton Altaparmakov
  2005-09-26 13:33   ` [PATCH 2/4] NTFS: Change ntfs_cluster_free() to require a write locked runlist on entry Anton Altaparmakov
  2005-09-26 14:57   ` [PATCH 1/4] NTFS: Fix sparse warnings that have crept in over time Linus Torvalds
  0 siblings, 2 replies; 12+ messages in thread
From: Anton Altaparmakov @ 2005-09-26 13:32 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-ntfs-dev

NTFS: Fix sparse warnings that have crept in over time.

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

---

 fs/ntfs/ChangeLog |    4 ++++
 fs/ntfs/layout.h  |    7 ++++---
 fs/ntfs/logfile.h |    2 +-
 3 files changed, 9 insertions(+), 4 deletions(-)

91fbc6edfa7086b5fcdb74ea82ab747104541f1f
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -22,6 +22,10 @@ ToDo/Notes:
 	- Enable the code for setting the NT4 compatibility flag when we start
 	  making NTFS 1.2 specific modifications.
 
+2.1.25-WIP
+
+	- Fix sparse warnings that have crept in over time.
+
 2.1.24 - Lots of bug fixes and support more clean journal states.
 
 	- Support journals ($LogFile) which have been modified by chkdsk.  This
diff --git a/fs/ntfs/layout.h b/fs/ntfs/layout.h
--- a/fs/ntfs/layout.h
+++ b/fs/ntfs/layout.h
@@ -317,12 +317,13 @@ typedef u64 MFT_REF;
 typedef le64 leMFT_REF;
 
 #define MK_MREF(m, s)	((MFT_REF)(((MFT_REF)(s) << 48) |		\
-					((MFT_REF)(m) & MFT_REF_MASK_CPU)))
+					((MFT_REF)(m) & (u64)MFT_REF_MASK_CPU)))
 #define MK_LE_MREF(m, s) cpu_to_le64(MK_MREF(m, s))
 
-#define MREF(x)		((unsigned long)((x) & MFT_REF_MASK_CPU))
+#define MREF(x)		((unsigned long)((x) & (u64)MFT_REF_MASK_CPU))
 #define MSEQNO(x)	((u16)(((x) >> 48) & 0xffff))
-#define MREF_LE(x)	((unsigned long)(le64_to_cpu(x) & MFT_REF_MASK_CPU))
+#define MREF_LE(x)	((unsigned long)(le64_to_cpu(x) &		\
+					(u64)MFT_REF_MASK_CPU))
 #define MSEQNO_LE(x)	((u16)((le64_to_cpu(x) >> 48) & 0xffff))
 
 #define IS_ERR_MREF(x)	(((x) & 0x0000800000000000ULL) ? 1 : 0)
diff --git a/fs/ntfs/logfile.h b/fs/ntfs/logfile.h
--- a/fs/ntfs/logfile.h
+++ b/fs/ntfs/logfile.h
@@ -113,7 +113,7 @@ typedef struct {
  */
 enum {
 	RESTART_VOLUME_IS_CLEAN	= const_cpu_to_le16(0x0002),
-	RESTART_SPACE_FILLER	= 0xffff, /* gcc: Force enum bit width to 16. */
+	RESTART_SPACE_FILLER	= const_cpu_to_le16(0xffff), /* gcc: Force enum bit width to 16. */
 } __attribute__ ((__packed__));
 
 typedef le16 RESTART_AREA_FLAGS;

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 2/4] NTFS: Change ntfs_cluster_free() to require a write locked runlist on entry
  2005-09-26 13:32 ` [PATCH 1/4] NTFS: Fix sparse warnings that have crept in over time Anton Altaparmakov
@ 2005-09-26 13:33   ` Anton Altaparmakov
  2005-09-26 13:33     ` [PATCH 3/4] NTFS: Fix the definition of the CHKD ntfs record magic Anton Altaparmakov
  2005-09-26 14:57   ` [PATCH 1/4] NTFS: Fix sparse warnings that have crept in over time Linus Torvalds
  1 sibling, 1 reply; 12+ messages in thread
From: Anton Altaparmakov @ 2005-09-26 13:33 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-ntfs-dev

NTFS: Change ntfs_cluster_free() to require a write locked runlist on entry
      since we otherwise get into a lock reversal deadlock if a read locked
      runlist is passed in. In the process also change it to take an ntfs
      inode instead of a vfs inode as parameter.

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

---

 fs/ntfs/ChangeLog  |    4 ++++
 fs/ntfs/Makefile   |    2 +-
 fs/ntfs/lcnalloc.c |   31 +++++++++++++------------------
 fs/ntfs/lcnalloc.h |   27 +++++++++++++--------------
 fs/ntfs/mft.c      |    2 +-
 5 files changed, 32 insertions(+), 34 deletions(-)

715dc636b64b57aee7aee7e8b5bf4f5267a6df48
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -25,6 +25,10 @@ ToDo/Notes:
 2.1.25-WIP
 
 	- Fix sparse warnings that have crept in over time.
+	- Change ntfs_cluster_free() to require a write locked runlist on entry
+	  since we otherwise get into a lock reversal deadlock if a read locked
+	  runlist is passed in. In the process also change it to take an ntfs
+	  inode instead of a vfs inode as parameter.
 
 2.1.24 - Lots of bug fixes and support more clean journal states.
 
diff --git a/fs/ntfs/Makefile b/fs/ntfs/Makefile
--- a/fs/ntfs/Makefile
+++ b/fs/ntfs/Makefile
@@ -6,7 +6,7 @@ ntfs-objs := aops.o attrib.o collate.o c
 	     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.24\"
+EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.25-WIP\"
 
 ifeq ($(CONFIG_NTFS_DEBUG),y)
 EXTRA_CFLAGS += -DDEBUG
diff --git a/fs/ntfs/lcnalloc.c b/fs/ntfs/lcnalloc.c
--- a/fs/ntfs/lcnalloc.c
+++ b/fs/ntfs/lcnalloc.c
@@ -779,14 +779,13 @@ out:
 
 /**
  * __ntfs_cluster_free - free clusters on an ntfs volume
- * @vi:		vfs inode whose runlist describes the clusters to free
- * @start_vcn:	vcn in the runlist of @vi at which to start freeing clusters
+ * @ni:		ntfs inode whose runlist describes the clusters to free
+ * @start_vcn:	vcn in the runlist of @ni at which to start freeing clusters
  * @count:	number of clusters to free or -1 for all clusters
- * @write_locked:	true if the runlist is locked for writing
  * @is_rollback:	true if this is a rollback operation
  *
  * Free @count clusters starting at the cluster @start_vcn in the runlist
- * described by the vfs inode @vi.
+ * described by the vfs inode @ni.
  *
  * If @count is -1, all clusters from @start_vcn to the end of the runlist are
  * deallocated.  Thus, to completely free all clusters in a runlist, use
@@ -801,31 +800,28 @@ out:
  * Return the number of deallocated clusters (not counting sparse ones) on
  * success and -errno on error.
  *
- * Locking: - The runlist described by @vi must be locked on entry and is
- *	      locked on return.  Note if the runlist is locked for reading the
- *	      lock may be dropped and reacquired.  Note the runlist may be
- *	      modified when needed runlist fragments need to be mapped.
+ * Locking: - The runlist described by @ni must be locked for writing on entry
+ *	      and is locked on return.  Note the runlist may be modified when
+ *	      needed runlist fragments need to be mapped.
  *	    - The volume lcn bitmap must be unlocked on entry and is unlocked
  *	      on return.
  *	    - This function takes the volume lcn bitmap lock for writing and
  *	      modifies the bitmap contents.
  */
-s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn, s64 count,
-		const BOOL write_locked, const BOOL is_rollback)
+s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, s64 count,
+		const BOOL is_rollback)
 {
 	s64 delta, to_free, total_freed, real_freed;
-	ntfs_inode *ni;
 	ntfs_volume *vol;
 	struct inode *lcnbmp_vi;
 	runlist_element *rl;
 	int err;
 
-	BUG_ON(!vi);
+	BUG_ON(!ni);
 	ntfs_debug("Entering for i_ino 0x%lx, start_vcn 0x%llx, count "
-			"0x%llx.%s", vi->i_ino, (unsigned long long)start_vcn,
+			"0x%llx.%s", ni->mft_no, (unsigned long long)start_vcn,
 			(unsigned long long)count,
 			is_rollback ? " (rollback)" : "");
-	ni = NTFS_I(vi);
 	vol = ni->vol;
 	lcnbmp_vi = vol->lcnbmp_ino;
 	BUG_ON(!lcnbmp_vi);
@@ -843,7 +839,7 @@ s64 __ntfs_cluster_free(struct inode *vi
 
 	total_freed = real_freed = 0;
 
-	rl = ntfs_attr_find_vcn_nolock(ni, start_vcn, write_locked);
+	rl = ntfs_attr_find_vcn_nolock(ni, start_vcn, TRUE);
 	if (IS_ERR(rl)) {
 		if (!is_rollback)
 			ntfs_error(vol->sb, "Failed to find first runlist "
@@ -897,7 +893,7 @@ s64 __ntfs_cluster_free(struct inode *vi
 
 			/* Attempt to map runlist. */
 			vcn = rl->vcn;
-			rl = ntfs_attr_find_vcn_nolock(ni, vcn, write_locked);
+			rl = ntfs_attr_find_vcn_nolock(ni, vcn, TRUE);
 			if (IS_ERR(rl)) {
 				err = PTR_ERR(rl);
 				if (!is_rollback)
@@ -965,8 +961,7 @@ err_out:
 	 * If rollback fails, set the volume errors flag, emit an error
 	 * message, and return the error code.
 	 */
-	delta = __ntfs_cluster_free(vi, start_vcn, total_freed, write_locked,
-			TRUE);
+	delta = __ntfs_cluster_free(ni, start_vcn, total_freed, TRUE);
 	if (delta < 0) {
 		ntfs_error(vol->sb, "Failed to rollback (error %i).  Leaving "
 				"inconsistent metadata!  Unmount and run "
diff --git a/fs/ntfs/lcnalloc.h b/fs/ntfs/lcnalloc.h
--- a/fs/ntfs/lcnalloc.h
+++ b/fs/ntfs/lcnalloc.h
@@ -2,7 +2,7 @@
  * lcnalloc.h - Exports for NTFS kernel cluster (de)allocation.  Part of the
  *		Linux-NTFS project.
  *
- * Copyright (c) 2004 Anton Altaparmakov
+ * Copyright (c) 2004-2005 Anton Altaparmakov
  *
  * This program/include file is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as published
@@ -28,6 +28,7 @@
 #include <linux/fs.h>
 
 #include "types.h"
+#include "inode.h"
 #include "runlist.h"
 #include "volume.h"
 
@@ -42,18 +43,17 @@ extern runlist_element *ntfs_cluster_all
 		const VCN start_vcn, const s64 count, const LCN start_lcn,
 		const NTFS_CLUSTER_ALLOCATION_ZONES zone);
 
-extern s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn,
-		s64 count, const BOOL write_locked, const BOOL is_rollback);
+extern s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn,
+		s64 count, const BOOL is_rollback);
 
 /**
  * ntfs_cluster_free - free clusters on an ntfs volume
- * @vi:		vfs inode whose runlist describes the clusters to free
- * @start_vcn:	vcn in the runlist of @vi at which to start freeing clusters
+ * @ni:		ntfs inode whose runlist describes the clusters to free
+ * @start_vcn:	vcn in the runlist of @ni at which to start freeing clusters
  * @count:	number of clusters to free or -1 for all clusters
- * @write_locked:	true if the runlist is locked for writing
  *
  * Free @count clusters starting at the cluster @start_vcn in the runlist
- * described by the vfs inode @vi.
+ * described by the ntfs inode @ni.
  *
  * If @count is -1, all clusters from @start_vcn to the end of the runlist are
  * deallocated.  Thus, to completely free all clusters in a runlist, use
@@ -65,19 +65,18 @@ extern s64 __ntfs_cluster_free(struct in
  * Return the number of deallocated clusters (not counting sparse ones) on
  * success and -errno on error.
  *
- * Locking: - The runlist described by @vi must be locked on entry and is
- *	      locked on return.  Note if the runlist is locked for reading the
- *	      lock may be dropped and reacquired.  Note the runlist may be
- *	      modified when needed runlist fragments need to be mapped.
+ * Locking: - The runlist described by @ni must be locked for writing on entry
+ *	      and is locked on return.  Note the runlist may be modified when
+ *	      needed runlist fragments need to be mapped.
  *	    - The volume lcn bitmap must be unlocked on entry and is unlocked
  *	      on return.
  *	    - This function takes the volume lcn bitmap lock for writing and
  *	      modifies the bitmap contents.
  */
-static inline s64 ntfs_cluster_free(struct inode *vi, const VCN start_vcn,
-		s64 count, const BOOL write_locked)
+static inline s64 ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn,
+		s64 count)
 {
-	return __ntfs_cluster_free(vi, start_vcn, count, write_locked, FALSE);
+	return __ntfs_cluster_free(ni, start_vcn, count, FALSE);
 }
 
 extern int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol,
diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c
--- a/fs/ntfs/mft.c
+++ b/fs/ntfs/mft.c
@@ -1953,7 +1953,7 @@ restore_undo_alloc:
 	a = ctx->attr;
 	a->data.non_resident.highest_vcn = cpu_to_sle64(old_last_vcn - 1);
 undo_alloc:
-	if (ntfs_cluster_free(vol->mft_ino, old_last_vcn, -1, TRUE) < 0) {
+	if (ntfs_cluster_free(mft_ni, old_last_vcn, -1) < 0) {
 		ntfs_error(vol->sb, "Failed to free clusters from mft data "
 				"attribute.%s", es);
 		NVolSetErrors(vol);

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 3/4] NTFS: Fix the definition of the CHKD ntfs record magic.
  2005-09-26 13:33   ` [PATCH 2/4] NTFS: Change ntfs_cluster_free() to require a write locked runlist on entry Anton Altaparmakov
@ 2005-09-26 13:33     ` Anton Altaparmakov
  2005-09-26 13:34       ` [PATCH 4/4] NTFS: More $LogFile handling fixes: when chkdsk has been run, it can leave the Anton Altaparmakov
  0 siblings, 1 reply; 12+ messages in thread
From: Anton Altaparmakov @ 2005-09-26 13:33 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-ntfs-dev

NTFS: Fix the definition of the CHKD ntfs record magic.  It had an off by
      two error causing it to be CHKB instead of CHKD.

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

---

 fs/ntfs/layout.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

838bf9675a3d1ede01408aa105357b9ab43faf1b
diff --git a/fs/ntfs/layout.h b/fs/ntfs/layout.h
--- a/fs/ntfs/layout.h
+++ b/fs/ntfs/layout.h
@@ -123,7 +123,7 @@ enum {
 	magic_RCRD = const_cpu_to_le32(0x44524352), /* Log record page. */
 
 	/* Found in $LogFile/$DATA.  (May be found in $MFT/$DATA, also?) */
-	magic_CHKD = const_cpu_to_le32(0x424b4843), /* Modified by chkdsk. */
+	magic_CHKD = const_cpu_to_le32(0x444b4843), /* Modified by chkdsk. */
 
 	/* Found in all ntfs record containing records. */
 	magic_BAAD = const_cpu_to_le32(0x44414142), /* Failed multi sector

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 4/4] NTFS: More $LogFile handling fixes: when chkdsk has been run, it can leave the
  2005-09-26 13:33     ` [PATCH 3/4] NTFS: Fix the definition of the CHKD ntfs record magic Anton Altaparmakov
@ 2005-09-26 13:34       ` Anton Altaparmakov
  0 siblings, 0 replies; 12+ messages in thread
From: Anton Altaparmakov @ 2005-09-26 13:34 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-ntfs-dev

NTFS: More $LogFile handling fixes: when chkdsk has been run, it can leave the
      restart pages in the journal without multi sector transfer protection
      fixups (i.e. the update sequence array is empty and in fact does not
      exist).

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

---

 fs/ntfs/ChangeLog |   18 +++++++++---------
 fs/ntfs/Makefile  |    2 +-
 fs/ntfs/logfile.c |   30 +++++++++++++++++++++++++-----
 3 files changed, 35 insertions(+), 15 deletions(-)

5a8c0cc32bb6e029cd9c36f655c6b0955b0d9967
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -22,14 +22,6 @@ ToDo/Notes:
 	- Enable the code for setting the NT4 compatibility flag when we start
 	  making NTFS 1.2 specific modifications.
 
-2.1.25-WIP
-
-	- Fix sparse warnings that have crept in over time.
-	- Change ntfs_cluster_free() to require a write locked runlist on entry
-	  since we otherwise get into a lock reversal deadlock if a read locked
-	  runlist is passed in. In the process also change it to take an ntfs
-	  inode instead of a vfs inode as parameter.
-
 2.1.24 - Lots of bug fixes and support more clean journal states.
 
 	- Support journals ($LogFile) which have been modified by chkdsk.  This
@@ -37,7 +29,8 @@ ToDo/Notes:
 	  The Windows boot will run chkdsk and then reboot.  The user can then
 	  immediately boot into Linux rather than having to do a full Windows
 	  boot first before rebooting into Linux and we will recognize such a
-	  journal and empty it as it is clean by definition.
+	  journal and empty it as it is clean by definition.  Note, this only
+	  works if chkdsk left the journal in an obviously clean state.
 	- Support journals ($LogFile) with only one restart page as well as
 	  journals with two different restart pages.  We sanity check both and
 	  either use the only sane one or the more recent one of the two in the
@@ -102,6 +95,13 @@ ToDo/Notes:
 	  my ways.
 	- Fix various bugs in the runlist merging code.  (Based on libntfs
 	  changes by Richard Russon.)
+	- Fix sparse warnings that have crept in over time.
+	- Change ntfs_cluster_free() to require a write locked runlist on entry
+	  since we otherwise get into a lock reversal deadlock if a read locked
+	  runlist is passed in. In the process also change it to take an ntfs
+	  inode instead of a vfs inode as parameter.
+	- Fix the definition of the CHKD ntfs record magic.  It had an off by
+	  two error causing it to be CHKB instead of CHKD.
 
 2.1.23 - Implement extension of resident files and make writing safe as well as
 	 many bug fixes, cleanups, and enhancements...
diff --git a/fs/ntfs/Makefile b/fs/ntfs/Makefile
--- a/fs/ntfs/Makefile
+++ b/fs/ntfs/Makefile
@@ -6,7 +6,7 @@ ntfs-objs := aops.o attrib.o collate.o c
 	     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-WIP\"
+EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.24\"
 
 ifeq ($(CONFIG_NTFS_DEBUG),y)
 EXTRA_CFLAGS += -DDEBUG
diff --git a/fs/ntfs/logfile.c b/fs/ntfs/logfile.c
--- a/fs/ntfs/logfile.c
+++ b/fs/ntfs/logfile.c
@@ -51,7 +51,8 @@ static BOOL ntfs_check_restart_page_head
 		RESTART_PAGE_HEADER *rp, s64 pos)
 {
 	u32 logfile_system_page_size, logfile_log_page_size;
-	u16 usa_count, usa_ofs, usa_end, ra_ofs;
+	u16 ra_ofs, usa_count, usa_ofs, usa_end = 0;
+	BOOL have_usa = TRUE;
 
 	ntfs_debug("Entering.");
 	/*
@@ -86,6 +87,14 @@ static BOOL ntfs_check_restart_page_head
 				(int)sle16_to_cpu(rp->minor_ver));
 		return FALSE;
 	}
+	/*
+	 * If chkdsk has been run the restart page may not be protected by an
+	 * update sequence array.
+	 */
+	if (ntfs_is_chkd_record(rp->magic) && !le16_to_cpu(rp->usa_count)) {
+		have_usa = FALSE;
+		goto skip_usa_checks;
+	}
 	/* Verify the size of the update sequence array. */
 	usa_count = 1 + (logfile_system_page_size >> NTFS_BLOCK_SIZE_BITS);
 	if (usa_count != le16_to_cpu(rp->usa_count)) {
@@ -102,6 +111,7 @@ static BOOL ntfs_check_restart_page_head
 				"inconsistent update sequence array offset.");
 		return FALSE;
 	}
+skip_usa_checks:
 	/*
 	 * Verify the position of the restart area.  It must be:
 	 *	- aligned to 8-byte boundary,
@@ -109,7 +119,8 @@ static BOOL ntfs_check_restart_page_head
 	 *	- within the system page size.
 	 */
 	ra_ofs = le16_to_cpu(rp->restart_area_offset);
-	if (ra_ofs & 7 || ra_ofs < usa_end ||
+	if (ra_ofs & 7 || (have_usa ? ra_ofs < usa_end :
+			ra_ofs < sizeof(RESTART_PAGE_HEADER)) ||
 			ra_ofs > logfile_system_page_size) {
 		ntfs_error(vi->i_sb, "$LogFile restart page specifies "
 				"inconsistent restart area offset.");
@@ -402,8 +413,12 @@ static int ntfs_check_and_load_restart_p
 			idx++;
 		} while (to_read > 0);
 	}
-	/* Perform the multi sector transfer deprotection on the buffer. */
-	if (post_read_mst_fixup((NTFS_RECORD*)trp,
+	/*
+	 * Perform the multi sector transfer deprotection on the buffer if the
+	 * restart page is protected.
+	 */
+	if ((!ntfs_is_chkd_record(trp->magic) || le16_to_cpu(trp->usa_count))
+			&& post_read_mst_fixup((NTFS_RECORD*)trp,
 			le32_to_cpu(rp->system_page_size))) {
 		/*
 		 * A multi sector tranfer error was detected.  We only need to
@@ -615,11 +630,16 @@ is_empty:
 		 * Otherwise just throw it away.
 		 */
 		if (rstr2_lsn > rstr1_lsn) {
+			ntfs_debug("Using second restart page as it is more "
+					"recent.");
 			ntfs_free(rstr1_ph);
 			rstr1_ph = rstr2_ph;
 			/* rstr1_lsn = rstr2_lsn; */
-		} else
+		} else {
+			ntfs_debug("Using first restart page as it is more "
+					"recent.");
 			ntfs_free(rstr2_ph);
+		}
 		rstr2_ph = NULL;
 	}
 	/* All consistency checks passed. */

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/4] NTFS: Fix sparse warnings that have crept in over time.
  2005-09-26 13:32 ` [PATCH 1/4] NTFS: Fix sparse warnings that have crept in over time Anton Altaparmakov
  2005-09-26 13:33   ` [PATCH 2/4] NTFS: Change ntfs_cluster_free() to require a write locked runlist on entry Anton Altaparmakov
@ 2005-09-26 14:57   ` Linus Torvalds
  2005-09-26 16:09     ` Anton Altaparmakov
  2005-09-26 16:44     ` Al Viro
  1 sibling, 2 replies; 12+ messages in thread
From: Linus Torvalds @ 2005-09-26 14:57 UTC (permalink / raw)
  To: Anton Altaparmakov; +Cc: linux-kernel, linux-ntfs-dev



On Mon, 26 Sep 2005, Anton Altaparmakov wrote:
>
> NTFS: Fix sparse warnings that have crept in over time.

I think this is wrong.

What was the warning that caused this (and the two other things that look 
the same)?

>  #define MK_MREF(m, s)	((MFT_REF)(((MFT_REF)(s) << 48) |		\
> -					((MFT_REF)(m) & MFT_REF_MASK_CPU)))
> +					((MFT_REF)(m) & (u64)MFT_REF_MASK_CPU)))

Also, side note: how you defined "MFT_REF_MASK_CPU" is pretty debatable in 
the first place:

	typedef enum {
	        MFT_REF_MASK_CPU        = 0x0000ffffffffffffULL,
	        MFT_REF_MASK_LE         = const_cpu_to_le64(0x0000ffffffffffffULL),
	} MFT_REF_CONSTS;

and this just _happens_ to work with gcc, but it's not real C.

The issue? "enum" is really an integer type. As in "int". Trying to put a 
larger value than one that fits in "int" is not guaranteed to work.

There's another issue, namely that the type of the snum is not only of 
undefined size (is it the same size as an "int"? Is it an "unsigned long 
long"?) but the "endianness" of it is also now totally undefined. You have 
two different endiannesses inside the _same_ enum. What is the type of the 
enum?

You _really_ probably should use just

	#define MFT_REF_MASK_CPU 0x0000ffffffffffffULL
	#define MFT_REF_MASK_LE const_cpu_to_le64(MFT_REF_MASK_CPU)

instead. That way the type of that thing is well-defined.

Depending on what warning you're trying to shut up, that may well fix it 
too. Because now "MFT_REF_MASK_CPU" is clearly a regular constant, while 
MFT_REF_MASK_LE is clearly a little-endian constant. Before, they were of 
the same enum type, which made it very unclear what the hell they were.

		Linus

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/4] NTFS: Fix sparse warnings that have crept in over time.
  2005-09-26 14:57   ` [PATCH 1/4] NTFS: Fix sparse warnings that have crept in over time Linus Torvalds
@ 2005-09-26 16:09     ` Anton Altaparmakov
  2005-09-26 16:41       ` Linus Torvalds
  2005-09-26 16:44     ` Al Viro
  1 sibling, 1 reply; 12+ messages in thread
From: Anton Altaparmakov @ 2005-09-26 16:09 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-ntfs-dev

On Mon, 26 Sep 2005, Linus Torvalds wrote:
> On Mon, 26 Sep 2005, Anton Altaparmakov wrote:
> >
> > NTFS: Fix sparse warnings that have crept in over time.
> 
> I think this is wrong.
> 
> What was the warning that caused this (and the two other things that look 
> the same)?

fs/ntfs/mft.c:2577:24: warning: incompatible types for operation (&)
fs/ntfs/mft.c:2577:24:    left side has type unsigned long long [unsigned] 
[usertype] <noident>
fs/ntfs/mft.c:2577:24:    right side has type bad type enum MFT_REF_CONSTS 
[toplevel] MFT_REF_MASK_CPU
fs/ntfs/mft.c:2577:24: warning: cast from unknown type

> >  #define MK_MREF(m, s)	((MFT_REF)(((MFT_REF)(s) << 48) |		\
> > -					((MFT_REF)(m) & MFT_REF_MASK_CPU)))
> > +					((MFT_REF)(m) & (u64)MFT_REF_MASK_CPU)))
> 
> Also, side note: how you defined "MFT_REF_MASK_CPU" is pretty debatable in 
> the first place:
> 
> 	typedef enum {
> 	        MFT_REF_MASK_CPU        = 0x0000ffffffffffffULL,
> 	        MFT_REF_MASK_LE         = const_cpu_to_le64(0x0000ffffffffffffULL),
> 	} MFT_REF_CONSTS;
> 
> and this just _happens_ to work with gcc, but it's not real C.
> 
> The issue? "enum" is really an integer type. As in "int". Trying to put a 
> larger value than one that fits in "int" is not guaranteed to work.

Yes, that is true but as you say it does work with gcc.

> There's another issue, namely that the type of the snum is not only of 
> undefined size (is it the same size as an "int"? Is it an "unsigned long 
> long"?) but the "endianness" of it is also now totally undefined. You have 
> two different endiannesses inside the _same_ enum. What is the type of the 
> enum?

Good question.  "confused"?  (-;

> You _really_ probably should use just
> 
> 	#define MFT_REF_MASK_CPU 0x0000ffffffffffffULL
> 	#define MFT_REF_MASK_LE const_cpu_to_le64(MFT_REF_MASK_CPU)
> 
> instead. That way the type of that thing is well-defined.

Yes, that is probably better given it is not possible to have them both be 
the same type (by definition).

> Depending on what warning you're trying to shut up, that may well fix it 
> too. Because now "MFT_REF_MASK_CPU" is clearly a regular constant, while 
> MFT_REF_MASK_LE is clearly a little-endian constant. Before, they were of 
> the same enum type, which made it very unclear what the hell they were.

Yes, I would expect it to fix it.

In fact I just did it and yes, it fixes it, too.  The repository I asked 
you to pull from is now updated with the below patch added which reverts 
the wrong layout.h parts and changes the enum to two defines as per your 
suggestion.

rsync://rsync.kernel.org/pub/scm/linux/kernel/git/aia21/ntfs-2.6.git/HEAD

Thanks for the comments.  (-:

Best regards,

	Anton
-- 
Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @)
Unix Support, Computing Service, University of Cambridge, CB2 3QH, UK
Linux NTFS maintainer / IRC: #ntfs on irc.freenode.net
WWW: http://linux-ntfs.sf.net/ & http://www-stu.christs.cam.ac.uk/~aia21/

---

NTFS: Re-fix sparse warnings in a more correct way, i.e. don't use an enum with
      different types in it but #define the two constants instead.

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

---

 fs/ntfs/layout.h |   13 +++++--------
 1 files changed, 5 insertions(+), 8 deletions(-)

e2fcc61ef0d654887b651bd99ffcb52f7344b836
diff --git a/fs/ntfs/layout.h b/fs/ntfs/layout.h
--- a/fs/ntfs/layout.h
+++ b/fs/ntfs/layout.h
@@ -308,22 +308,19 @@ typedef le16 MFT_RECORD_FLAGS;
  * The _LE versions are to be applied on little endian MFT_REFs.
  * Note: The _LE versions will return a CPU endian formatted value!
  */
-typedef enum {
-	MFT_REF_MASK_CPU	= 0x0000ffffffffffffULL,
-	MFT_REF_MASK_LE		= const_cpu_to_le64(0x0000ffffffffffffULL),
-} MFT_REF_CONSTS;
+#define MFT_REF_MASK_CPU 0x0000ffffffffffffULL
+#define MFT_REF_MASK_LE const_cpu_to_le64(0x0000ffffffffffffULL)
 
 typedef u64 MFT_REF;
 typedef le64 leMFT_REF;
 
 #define MK_MREF(m, s)	((MFT_REF)(((MFT_REF)(s) << 48) |		\
-					((MFT_REF)(m) & (u64)MFT_REF_MASK_CPU)))
+					((MFT_REF)(m) & MFT_REF_MASK_CPU)))
 #define MK_LE_MREF(m, s) cpu_to_le64(MK_MREF(m, s))
 
-#define MREF(x)		((unsigned long)((x) & (u64)MFT_REF_MASK_CPU))
+#define MREF(x)		((unsigned long)((x) & MFT_REF_MASK_CPU))
 #define MSEQNO(x)	((u16)(((x) >> 48) & 0xffff))
-#define MREF_LE(x)	((unsigned long)(le64_to_cpu(x) &		\
-					(u64)MFT_REF_MASK_CPU))
+#define MREF_LE(x)	((unsigned long)(le64_to_cpu(x) & MFT_REF_MASK_CPU))
 #define MSEQNO_LE(x)	((u16)((le64_to_cpu(x) >> 48) & 0xffff))
 
 #define IS_ERR_MREF(x)	(((x) & 0x0000800000000000ULL) ? 1 : 0)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/4] NTFS: Fix sparse warnings that have crept in over time.
  2005-09-26 16:09     ` Anton Altaparmakov
@ 2005-09-26 16:41       ` Linus Torvalds
  2005-09-26 16:46         ` Al Viro
  2005-09-26 19:08         ` Anton Altaparmakov
  0 siblings, 2 replies; 12+ messages in thread
From: Linus Torvalds @ 2005-09-26 16:41 UTC (permalink / raw)
  To: Anton Altaparmakov; +Cc: linux-kernel, linux-ntfs-dev



On Mon, 26 Sep 2005, Anton Altaparmakov wrote:
> > 
> > What was the warning that caused this (and the two other things that look 
> > the same)?
> 
> fs/ntfs/mft.c:2577:24: warning: incompatible types for operation (&)
> fs/ntfs/mft.c:2577:24:    left side has type unsigned long long [unsigned] [usertype] <noident>
> fs/ntfs/mft.c:2577:24:    right side has type bad type enum MFT_REF_CONSTS [toplevel] MFT_REF_MASK_CPU
> fs/ntfs/mft.c:2577:24: warning: cast from unknown type

Ok, not the most wonderful of error messages, I do have to admit ;)

That's sparse being very verbose and not saying a lot, but what happens is
that the "enum" doesn't have a well-defined type, since the different 
constants in the enum don't have compatible types.

So it's type ends up being a "bad type enum MFT_REF_CONSTS"

(It also prints out the name of the symbol with that type, which is why
you also see the MFT_REF_MASK_CPU - the "[toplevel]" is just an internal 
sparse bit saying that it was declared outside of any block scope).

I'm actually a bit surprised that the cast even shut sparse up. It
probably shouldn't have, and it should have complained about casting an
unknown type even _with_ your added cast (ie I think it should have cut
your four lines of warning down to one).

Did it?

> > The issue? "enum" is really an integer type. As in "int". Trying to put a 
> > larger value than one that fits in "int" is not guaranteed to work.
> 
> Yes, that is true but as you say it does work with gcc.

Yes, and sparse will actually conform to gcc behaviour. I think we had a 
warning about it, but it's sadly quite common in the kernel ;p

So if the size of the constants was the only problem, sparse wouldn't 
actually have complained.

The reason it ended up complaining was that it couldn't promote the 
different enum values to the same type. 

I suspect it might be more readable had it complained at enum declaration
time instead, since at that point it would have been able to describe
_why_ it didn't like that enum a bit better. But the problem with that 
approach is that then it complains whether the thing is used or not (and a 
lot of things are bad only at usage time, so sparse tends to try to 
delay any complaints as long as computerly possible).

> > There's another issue, namely that the type of the snum is not only of 
> > undefined size (is it the same size as an "int"? Is it an "unsigned long 
> > long"?) but the "endianness" of it is also now totally undefined. You have 
> > two different endiannesses inside the _same_ enum. What is the type of the 
> > enum?
> 
> Good question.  "confused"?  (-;

Well, in gcc it's clear: it's "unsigned long long".  Because gcc doesn't 
know about little-endian vs big-endian.

In sparse, it's not actually confused either, it's "enum of type
bad_ctype". But the error message isn't very helpful unless you understand
how sparse does that internally (that's why sparse says "right side has
type bad type enum ..." - that "bad type enum" is the magic code-word)

		Linus

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/4] NTFS: Fix sparse warnings that have crept in over time.
  2005-09-26 14:57   ` [PATCH 1/4] NTFS: Fix sparse warnings that have crept in over time Linus Torvalds
  2005-09-26 16:09     ` Anton Altaparmakov
@ 2005-09-26 16:44     ` Al Viro
  1 sibling, 0 replies; 12+ messages in thread
From: Al Viro @ 2005-09-26 16:44 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Anton Altaparmakov, linux-kernel, linux-ntfs-dev

On Mon, Sep 26, 2005 at 07:57:09AM -0700, Linus Torvalds wrote:
> 	#define MFT_REF_MASK_CPU 0x0000ffffffffffffULL
> 	#define MFT_REF_MASK_LE const_cpu_to_le64(MFT_REF_MASK_CPU)
> 
> instead. That way the type of that thing is well-defined.

Or just make those two different enums.  Basically, gcc is hopelessly
b0rken in version-dependent way when it comes to multi-element enums
that get outside of int range.  Single-element ones at least have
kinda-sorta consistent semantics; anything beyond that and you are
walking into very nasty areas.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/4] NTFS: Fix sparse warnings that have crept in over time.
  2005-09-26 16:41       ` Linus Torvalds
@ 2005-09-26 16:46         ` Al Viro
  2005-09-26 19:08         ` Anton Altaparmakov
  1 sibling, 0 replies; 12+ messages in thread
From: Al Viro @ 2005-09-26 16:46 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Anton Altaparmakov, linux-kernel, linux-ntfs-dev

On Mon, Sep 26, 2005 at 09:41:14AM -0700, Linus Torvalds wrote:
> Yes, and sparse will actually conform to gcc behaviour. I think we had a 
> warning about it, but it's sadly quite common in the kernel ;p
 
No, they are not.  unsigned _is_ common (mostly from 1U<<31).  Going
beyond 32 bits is done in a handful of cases, NTFS ones being at least
half of the entire pile.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/4] NTFS: Fix sparse warnings that have crept in over time.
  2005-09-26 16:41       ` Linus Torvalds
  2005-09-26 16:46         ` Al Viro
@ 2005-09-26 19:08         ` Anton Altaparmakov
  2005-09-26 20:43           ` Linus Torvalds
  1 sibling, 1 reply; 12+ messages in thread
From: Anton Altaparmakov @ 2005-09-26 19:08 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-ntfs-dev

On Mon, 26 Sep 2005, Linus Torvalds wrote:
> On Mon, 26 Sep 2005, Anton Altaparmakov wrote:
> > > What was the warning that caused this (and the two other things that look 
> > > the same)?
> > 
> > fs/ntfs/mft.c:2577:24: warning: incompatible types for operation (&)
> > fs/ntfs/mft.c:2577:24:    left side has type unsigned long long [unsigned] [usertype] <noident>
> > fs/ntfs/mft.c:2577:24:    right side has type bad type enum MFT_REF_CONSTS [toplevel] MFT_REF_MASK_CPU
> > fs/ntfs/mft.c:2577:24: warning: cast from unknown type
> 
> Ok, not the most wonderful of error messages, I do have to admit ;)
> 
> That's sparse being very verbose and not saying a lot, but what happens is
> that the "enum" doesn't have a well-defined type, since the different 
> constants in the enum don't have compatible types.
> 
> So it's type ends up being a "bad type enum MFT_REF_CONSTS"
> 
> (It also prints out the name of the symbol with that type, which is why
> you also see the MFT_REF_MASK_CPU - the "[toplevel]" is just an internal 
> sparse bit saying that it was declared outside of any block scope).
> 
> I'm actually a bit surprised that the cast even shut sparse up. It
> probably shouldn't have, and it should have complained about casting an
> unknown type even _with_ your added cast (ie I think it should have cut
> your four lines of warning down to one).
> 
> Did it?

No, the warnings completely disappeared with the cast.

This is using: make CHECKFLAGS=-Wbitwise C=2 modules

> > > The issue? "enum" is really an integer type. As in "int". Trying to put a 
> > > larger value than one that fits in "int" is not guaranteed to work.
> > 
> > Yes, that is true but as you say it does work with gcc.
> 
> Yes, and sparse will actually conform to gcc behaviour. I think we had a 
> warning about it, but it's sadly quite common in the kernel ;p
> 
> So if the size of the constants was the only problem, sparse wouldn't 
> actually have complained.
> 
> The reason it ended up complaining was that it couldn't promote the 
> different enum values to the same type. 
> 
> I suspect it might be more readable had it complained at enum declaration
> time instead, since at that point it would have been able to describe
> _why_ it didn't like that enum a bit better. But the problem with that 
> approach is that then it complains whether the thing is used or not (and a 
> lot of things are bad only at usage time, so sparse tends to try to 
> delay any complaints as long as computerly possible).
> 
> > > There's another issue, namely that the type of the snum is not only of 
> > > undefined size (is it the same size as an "int"? Is it an "unsigned long 
> > > long"?) but the "endianness" of it is also now totally undefined. You have 
> > > two different endiannesses inside the _same_ enum. What is the type of the 
> > > enum?
> > 
> > Good question.  "confused"?  (-;
> 
> Well, in gcc it's clear: it's "unsigned long long".  Because gcc doesn't 
> know about little-endian vs big-endian.
> 
> In sparse, it's not actually confused either, it's "enum of type
> bad_ctype". But the error message isn't very helpful unless you understand
> how sparse does that internally (that's why sparse says "right side has
> type bad type enum ..." - that "bad type enum" is the magic code-word)

Thanks for the explanation.

Best regards,

	Anton
-- 
Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @)
Unix Support, Computing Service, University of Cambridge, CB2 3QH, UK
Linux NTFS maintainer / IRC: #ntfs on irc.freenode.net
WWW: http://linux-ntfs.sf.net/ & http://www-stu.christs.cam.ac.uk/~aia21/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/4] NTFS: Fix sparse warnings that have crept in over time.
  2005-09-26 19:08         ` Anton Altaparmakov
@ 2005-09-26 20:43           ` Linus Torvalds
  0 siblings, 0 replies; 12+ messages in thread
From: Linus Torvalds @ 2005-09-26 20:43 UTC (permalink / raw)
  To: Anton Altaparmakov; +Cc: linux-kernel, linux-ntfs-dev



On Mon, 26 Sep 2005, Anton Altaparmakov wrote:
> > 
> > I'm actually a bit surprised that the cast even shut sparse up. It
> > probably shouldn't have, and it should have complained about casting an
> > unknown type even _with_ your added cast (ie I think it should have cut
> > your four lines of warning down to one).
> > 
> > Did it?
> 
> No, the warnings completely disappeared with the cast.

Ok, it turns out that a bad enum type ends up being seen as just its 
integer type, and anything that doesn't care about anything else than its 
size (namely, a cast) won't even complain.

That's very arguably a bug. Oh, well. Not a big one.

		Linus

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2005-09-26 20:43 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-09-26 13:31 [2.6.14-rc2-git] NTFS: Even more bug fixes! Anton Altaparmakov
2005-09-26 13:32 ` [PATCH 1/4] NTFS: Fix sparse warnings that have crept in over time Anton Altaparmakov
2005-09-26 13:33   ` [PATCH 2/4] NTFS: Change ntfs_cluster_free() to require a write locked runlist on entry Anton Altaparmakov
2005-09-26 13:33     ` [PATCH 3/4] NTFS: Fix the definition of the CHKD ntfs record magic Anton Altaparmakov
2005-09-26 13:34       ` [PATCH 4/4] NTFS: More $LogFile handling fixes: when chkdsk has been run, it can leave the Anton Altaparmakov
2005-09-26 14:57   ` [PATCH 1/4] NTFS: Fix sparse warnings that have crept in over time Linus Torvalds
2005-09-26 16:09     ` Anton Altaparmakov
2005-09-26 16:41       ` Linus Torvalds
2005-09-26 16:46         ` Al Viro
2005-09-26 19:08         ` Anton Altaparmakov
2005-09-26 20:43           ` Linus Torvalds
2005-09-26 16:44     ` Al Viro

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox