rpms/kernel/F-8 linux-2.6-xfs-features2-fixup-fix.patch, NONE, 1.1 linux-2.6-xfs-features2-fixup.patch, NONE, 1.1 kernel.spec, 1.417, 1.418

Eric Sandeen (sandeen) fedora-extras-commits at redhat.com
Thu Apr 3 01:52:00 UTC 2008


Author: sandeen

Update of /cvs/pkgs/rpms/kernel/F-8
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv30713

Modified Files:
	kernel.spec 
Added Files:
	linux-2.6-xfs-features2-fixup-fix.patch 
	linux-2.6-xfs-features2-fixup.patch 
Log Message:
* Wed Apr 02 2008 Eric Sandeen <sandeen at redhat.com> 2.6.24.4-72
- Fix mis-read of xfs attr2 superblock flag which was causing
  corruption in some cases. (#437968)


linux-2.6-xfs-features2-fixup-fix.patch:

--- NEW FILE linux-2.6-xfs-features2-fixup-fix.patch ---
Sent to xfs list & preliminarily reviewed by sgi folks.
Should make it to cvs.

http://oss.sgi.com/archives/xfs/2008-04/msg00047.html

Ensure "both" features2 slots are consistent, and set mp attr2 flag.

Since older kernels may look in the sb_bad_features2 slot for
flags, rather than zeroing it out on fixup, we should make it 
equal to the sb_features2 value.

Also, if the ATTR2 flag was not found prior to features2
fixup, it was not set in the mount flags, so re-check after the
fixup so that the current session will use the feature.

Also fix up the comments to reflect these changes.

Signed-off-by: Eric Sandeen <sandeen at sandeen.net>
---

Index: linux-2.6.24.x86_64/fs/xfs/xfs_mount.c
===================================================================
--- linux-2.6.24.x86_64.orig/fs/xfs/xfs_mount.c
+++ linux-2.6.24.x86_64/fs/xfs/xfs_mount.c
@@ -979,23 +979,33 @@ xfs_mountfs(
 	xfs_mount_common(mp, sbp);
 
 	/*
-	 * Check for a bad features2 field alignment. This happened on
-	 * some platforms due to xfs_sb_t not being 64bit size aligned
-	 * when sb_features was added and hence the compiler put it in
-	 * the wrong place.
+	 * Check for a mismatched features2 values.  Older kernels
+	 * read & wrote into the wrong sb offset for sb_features2
+	 * on some platforms due to xfs_sb_t not being 64bit size aligned
+	 * when sb_features2 was added, which made older superblock
+	 * reading/writing routines swap it as a 64-bit value.
 	 *
-	 * If we detect a bad field, we or the set bits into the existing
-	 * features2 field in case it has already been modified and we
-	 * don't want to lose any features. Zero the bad one and mark
-	 * the two fields as needing updates once the transaction subsystem
-	 * is online.
+	 * For backwards compatibility, we make both slots equal.
+	 *
+	 * If we detect a mismatched field, we OR the set bits into the
+	 * existing features2 field in case it has already been modified; we
+	 * don't want to lose any features.  We then update the bad location
+	 * with the ORed value so that older kernels will see any features2
+	 * flags, and mark the two fields as needing updates once the
+	 * transaction subsystem is online.
 	 */
-	if (xfs_sb_has_bad_features2(sbp)) {
+	if (xfs_sb_has_mismatched_features2(sbp)) {
 		cmn_err(CE_WARN,
 			"XFS: correcting sb_features alignment problem");
 		sbp->sb_features2 |= sbp->sb_bad_features2;
-		sbp->sb_bad_features2 = 0;
+		sbp->sb_bad_features2 = sbp->sb_features2;
 		update_flags |= XFS_SB_FEATURES2 | XFS_SB_BAD_FEATURES2;
+
+		/*
+		 * Re-check for ATTR2 from the bad_features2 slot.
+		 */
+		if (xfs_sb_version_hasattr2(sbp))
+			mp->m_flags |= XFS_MOUNT_ATTR2;
 	}
 
 	/*
@@ -1905,7 +1917,8 @@ xfs_uuid_unmount(
 
 /*
  * Used to log changes to the superblock unit and width fields which could
- * be altered by the mount options. Only the first superblock is updated.
+ * be altered by the mount options, as well as any potential sb_features2
+ * fixup. Only the first superblock is updated.
  */
 STATIC void
 xfs_mount_log_sb(
Index: linux-2.6.24.x86_64/fs/xfs/xfs_sb.h
===================================================================
--- linux-2.6.24.x86_64.orig/fs/xfs/xfs_sb.h
+++ linux-2.6.24.x86_64/fs/xfs/xfs_sb.h
@@ -321,11 +321,12 @@ static inline int xfs_sb_good_version(xf
 #endif /* __KERNEL__ */
 
 /*
- * Detect a bad features2 field
+ * Detect a mismatched features2 field.  Older kernels read/wrote
+ * this into the wrong slot, so to be safe we keep them in sync.
  */
-static inline int xfs_sb_has_bad_features2(xfs_sb_t *sbp)
+static inline int xfs_sb_has_mismatched_features2(xfs_sb_t *sbp)
 {
-	return (sbp->sb_bad_features2 != 0);
+	return (sbp->sb_bad_features2 != sbp->sb_features2);
 }
 
 #define	XFS_SB_VERSION_TONEW(v)	xfs_sb_version_tonew(v)


linux-2.6-xfs-features2-fixup.patch:

--- NEW FILE linux-2.6-xfs-features2-fixup.patch ---
NOTE: This patch is in xfs cvs, will probably appear 2.6.26

Minor changes made for 2.6.24 backport
========


XFS: correcting sb_features alignment problem

in dmesg and corrects the problem so that everything is OK.
it also blacklists the bad field in the superblock so it does
not get used for something else later on.


Date:  Fri Feb 22 17:39:13 AEDT 2008
Workarea:  chook.melbourne.sgi.com:/build/dgc/isms/2.6.x-xfs
Inspected by:  sandeen at sandeen.net,hch at infradead.org

The following file(s) were checked into:
  longdrop.melbourne.sgi.com:/isms/linux/2.6.x-xfs-melb


Modid:  xfs-linux-melb:xfs-kern:30539a
fs/xfs/xfs_sb.h - 1.71 - changed
http://oss.sgi.com/cgi-bin/cvsweb.cgi/xfs-linux/xfs_sb.h.diff?r1=text&tr1=1.71&r2=text&tr2=1.70&f=h
	- Detect and correct the features2 field of the superblock
	  being misaligned. Blacklist the misaligned field so it
	  does not get reused in future.

fs/xfs/xfs_mount.c - 1.419 - changed
http://oss.sgi.com/cgi-bin/cvsweb.cgi/xfs-linux/xfs_mount.c.diff?r1=text&tr1=1.419&r2=text&tr2=1.418&f=h
	- Detect and correct the features2 field of the superblock
	  being misaligned. Blacklist the misaligned field so it
	  does not get reused in future.


Index: linux-2.6.24.x86_64/fs/xfs/xfs_sb.h
===================================================================
--- linux-2.6.24.x86_64.orig/fs/xfs/xfs_sb.h
+++ linux-2.6.24.x86_64/fs/xfs/xfs_sb.h
@@ -89,6 +89,7 @@ struct xfs_mount;
 
 /*
  * Superblock - in core version.  Must match the ondisk version below.
+ * Must be padded to 64 bit alignment.
  */
 typedef struct xfs_sb {
 	__uint32_t	sb_magicnum;	/* magic number == XFS_SB_MAGIC */
@@ -145,10 +146,21 @@ typedef struct xfs_sb {
 	__uint16_t	sb_logsectsize;	/* sector size for the log, bytes */
 	__uint32_t	sb_logsunit;	/* stripe unit size for the log */
 	__uint32_t	sb_features2;	/* additional feature bits */
+
+	/*
+	 * bad features2 field as a result of failing to pad the sb
+	 * structure to 64 bits. Some machines will be using this field
+	 * for features2 bits. Easiest just to mark it bad and not use
+	 * it for anything else.
+	 */
+	__uint32_t	sb_bad_features2;
+
+	/* must be padded to 64 bit alignment */
 } xfs_sb_t;
 
 /*
- * Superblock - on disk version.  Must match the in core version below.
+ * Superblock - on disk version.  Must match the in core version above.
+ * Must be padded to 64 bit alignment.
  */
 typedef struct xfs_dsb {
 	__be32		sb_magicnum;	/* magic number == XFS_SB_MAGIC */
@@ -205,6 +217,15 @@ typedef struct xfs_dsb {
 	__be16		sb_logsectsize;	/* sector size for the log, bytes */
 	__be32		sb_logsunit;	/* stripe unit size for the log */
 	__be32		sb_features2;	/* additional feature bits */
+	/*
+	 * bad features2 field as a result of failing to pad the sb
+	 * structure to 64 bits. Some machines will be using this field
+	 * for features2 bits. Easiest just to mark it bad and not use
+	 * it for anything else.
+	 */
+	__be32	sb_bad_features2;
+
+	/* must be padded to 64 bit alignment */
 } xfs_dsb_t;
 
 /*
@@ -223,7 +244,7 @@ typedef enum {
 	XFS_SBS_GQUOTINO, XFS_SBS_QFLAGS, XFS_SBS_FLAGS, XFS_SBS_SHARED_VN,
 	XFS_SBS_INOALIGNMT, XFS_SBS_UNIT, XFS_SBS_WIDTH, XFS_SBS_DIRBLKLOG,
 	XFS_SBS_LOGSECTLOG, XFS_SBS_LOGSECTSIZE, XFS_SBS_LOGSUNIT,
-	XFS_SBS_FEATURES2,
+	XFS_SBS_FEATURES2, XFS_SBS_BAD_FEATURES2,
 	XFS_SBS_FIELDCOUNT
 } xfs_sb_field_t;
 
@@ -248,13 +269,15 @@ typedef enum {
 #define XFS_SB_IFREE		XFS_SB_MVAL(IFREE)
 #define XFS_SB_FDBLOCKS		XFS_SB_MVAL(FDBLOCKS)
 #define XFS_SB_FEATURES2	XFS_SB_MVAL(FEATURES2)
+#define XFS_SB_BAD_FEATURES2	XFS_SB_MVAL(BAD_FEATURES2)
 #define	XFS_SB_NUM_BITS		((int)XFS_SBS_FIELDCOUNT)
 #define	XFS_SB_ALL_BITS		((1LL << XFS_SB_NUM_BITS) - 1)
 #define	XFS_SB_MOD_BITS		\
 	(XFS_SB_UUID | XFS_SB_ROOTINO | XFS_SB_RBMINO | XFS_SB_RSUMINO | \
 	 XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | XFS_SB_GQUOTINO | \
 	 XFS_SB_QFLAGS | XFS_SB_SHARED_VN | XFS_SB_UNIT | XFS_SB_WIDTH | \
-	 XFS_SB_ICOUNT | XFS_SB_IFREE | XFS_SB_FDBLOCKS | XFS_SB_FEATURES2)
+	 XFS_SB_ICOUNT | XFS_SB_IFREE | XFS_SB_FDBLOCKS | XFS_SB_FEATURES2 | \
+	 XFS_SB_BAD_FEATURES2)
 
 
 /*
@@ -297,6 +320,14 @@ static inline int xfs_sb_good_version(xf
 }
 #endif /* __KERNEL__ */
 
+/*
+ * Detect a bad features2 field
+ */
+static inline int xfs_sb_has_bad_features2(xfs_sb_t *sbp)
+{
+	return (sbp->sb_bad_features2 != 0);
+}
+
 #define	XFS_SB_VERSION_TONEW(v)	xfs_sb_version_tonew(v)
 static inline unsigned xfs_sb_version_tonew(unsigned v)
 {
Index: linux-2.6.24.x86_64/fs/xfs/xfs_mount.c
===================================================================
--- linux-2.6.24.x86_64.orig/fs/xfs/xfs_mount.c
+++ linux-2.6.24.x86_64/fs/xfs/xfs_mount.c
@@ -44,7 +44,7 @@
 #include "xfs_quota.h"
 #include "xfs_fsops.h"
 
-STATIC void	xfs_mount_log_sbunit(xfs_mount_t *, __int64_t);
+STATIC void	xfs_mount_log_sb(xfs_mount_t *, __int64_t);
 STATIC int	xfs_uuid_mount(xfs_mount_t *);
 STATIC void	xfs_uuid_unmount(xfs_mount_t *mp);
 STATIC void	xfs_unmountfs_wait(xfs_mount_t *);
@@ -119,6 +119,7 @@ static const struct {
     { offsetof(xfs_sb_t, sb_logsectsize),0 },
     { offsetof(xfs_sb_t, sb_logsunit),	 0 },
     { offsetof(xfs_sb_t, sb_features2),	 0 },
+    { offsetof(xfs_sb_t, sb_bad_features2), 0 },
     { sizeof(xfs_sb_t),			 0 }
 };
 
@@ -455,6 +456,7 @@ xfs_sb_from_disk(
 	to->sb_logsectsize = be16_to_cpu(from->sb_logsectsize);
 	to->sb_logsunit = be32_to_cpu(from->sb_logsunit);
 	to->sb_features2 = be32_to_cpu(from->sb_features2);
+	to->sb_bad_features2 = be32_to_cpu(from->sb_bad_features2);
 }
 
 /*
@@ -977,6 +979,26 @@ xfs_mountfs(
 	xfs_mount_common(mp, sbp);
 
 	/*
+	 * Check for a bad features2 field alignment. This happened on
+	 * some platforms due to xfs_sb_t not being 64bit size aligned
+	 * when sb_features was added and hence the compiler put it in
+	 * the wrong place.
+	 *
+	 * If we detect a bad field, we or the set bits into the existing
+	 * features2 field in case it has already been modified and we
+	 * don't want to lose any features. Zero the bad one and mark
+	 * the two fields as needing updates once the transaction subsystem
+	 * is online.
+	 */
+	if (xfs_sb_has_bad_features2(sbp)) {
+		cmn_err(CE_WARN,
+			"XFS: correcting sb_features alignment problem");
+		sbp->sb_features2 |= sbp->sb_bad_features2;
+		sbp->sb_bad_features2 = 0;
+		update_flags |= XFS_SB_FEATURES2 | XFS_SB_BAD_FEATURES2;
+	}
+
+	/*
 	 * Check if sb_agblocks is aligned at stripe boundary
 	 * If sb_agblocks is NOT aligned turn off m_dalign since
 	 * allocator alignment is within an ag, therefore ag has
@@ -1165,11 +1187,10 @@ xfs_mountfs(
 	}
 
 	/*
-	 * If fs is not mounted readonly, then update the superblock
-	 * unit and width changes.
+	 * If fs is not mounted readonly, then update the superblock changes.
 	 */
 	if (update_flags && !(mp->m_flags & XFS_MOUNT_RDONLY))
-		xfs_mount_log_sbunit(mp, update_flags);
+		xfs_mount_log_sb(mp, update_flags);
 
 	/*
 	 * Initialise the XFS quota management subsystem for this mount
@@ -1887,13 +1908,14 @@ xfs_uuid_unmount(
  * be altered by the mount options. Only the first superblock is updated.
  */
 STATIC void
-xfs_mount_log_sbunit(
+xfs_mount_log_sb(
 	xfs_mount_t	*mp,
 	__int64_t	fields)
 {
 	xfs_trans_t	*tp;
 
-	ASSERT(fields & (XFS_SB_UNIT|XFS_SB_WIDTH|XFS_SB_UUID));
+	ASSERT(fields & (XFS_SB_UNIT | XFS_SB_WIDTH | XFS_SB_UUID |
+			 XFS_SB_FEATURES2 | XFS_SB_BAD_FEATURES2));
 
 	tp = xfs_trans_alloc(mp, XFS_TRANS_SB_UNIT);
 	if (xfs_trans_reserve(tp, 0, mp->m_sb.sb_sectsize + 128, 0, 0,


Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/F-8/kernel.spec,v
retrieving revision 1.417
retrieving revision 1.418
diff -u -r1.417 -r1.418
--- kernel.spec	2 Apr 2008 23:04:19 -0000	1.417
+++ kernel.spec	3 Apr 2008 01:51:15 -0000	1.418
@@ -707,6 +707,8 @@
 Patch1504: linux-2.6-xfs-optimize-away-realtime-tests.patch
 Patch1509: linux-2.6-xfs-setfattr-32bit-compat.patch
 Patch1510: linux-2.6-xfs-xfs_mount-refactor.patch
+Patch1511: linux-2.6-xfs-features2-fixup.patch
+Patch1512: linux-2.6-xfs-features2-fixup-fix.patch
 
 Patch1515: linux-2.6-lirc.patch
 Patch1520: linux-2.6-dcdbas-autoload.patch
@@ -1350,6 +1352,8 @@
 ApplyPatch linux-2.6-xfs-optimize-away-realtime-tests.patch
 ApplyPatch linux-2.6-xfs-setfattr-32bit-compat.patch
 ApplyPatch linux-2.6-xfs-xfs_mount-refactor.patch
+ApplyPatch linux-2.6-xfs-features2-fixup.patch
+ApplyPatch linux-2.6-xfs-features2-fixup-fix.patch
 
 #
 # misc small stuff to make things compile
@@ -2004,6 +2008,10 @@
 
 
 %changelog
+* Wed Apr 02 2008 Eric Sandeen <sandeen at redhat.com> 2.6.24.4-72
+- Fix mis-read of xfs attr2 superblock flag which was causing
+  corruption in some cases. (#437968)
+
 * Wed Apr 02 2008 Chuck Ebbert <cebbert at redhat.com> 2.6.24.4-71
 - Disable the VIA Padlock SHA crypto hardware driver
   because it prevents module loading. (#438322)




More information about the fedora-extras-commits mailing list