All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/10] xfs: feature flag rework
@ 2018-08-20  4:48 Dave Chinner
  2018-08-20  4:48 ` [PATCH 01/10] xfs: reflect sb features in xfs_mount Dave Chinner
                   ` (10 more replies)
  0 siblings, 11 replies; 27+ messages in thread
From: Dave Chinner @ 2018-08-20  4:48 UTC (permalink / raw)
  To: linux-xfs

Hi folks,

This series reworks how the kernel code handles feature bits. It
seemed to me to be a bit crazy to repeatedly have to check multiple
values in the superblock to check whether a feature is supported.
e.g. to check if reflink is available, we first mask the version
number to extract it from the superblock field, then we check it
against the v5 value, then we load and check the feature bit from
the superblock.

This could all just be a single flag check - a flag that is set at
mount time after doing all of the above, and so it's just a single
operation to check.

I'm also tired of typing "xfs_sb_version_hasfoo" everytime a check
needs to be done. Not to mention having a different mechanism to
check mount option based features.

And then there's the conflation of mount option feature flags and
runtime state in the one set of flags. The flags field is not
updated atomically, so there no guarantee that a change of a state
flag does race with anything else and we lose it.

So this patch set moves all the feature flags into a new m_features
field in the struct xfs_mount. It doesn't matter if they are mount
options or superblock feature bits - they all end up in the one
place whether they are [almost entirely] read only. These are now
checked by "xfs_has_foo(mp)" functions (following the ext4 feature
check syntax), and for the very few features that can be dynamically
added or removed there are also xfs_feat_add/remove_foo(mp) helpers.
IOWs, both superblock and mount option features are checked the same
way.

The state flags (clean mount, unmounting, shutdown, etc) are all
moved to a new m_state field, which is manipulated entirely by
atomic bitops to avoid update races. THere are a couple of wrappers
for the common checks - xfs_is_read_only(mp) and
xfs_is_shut_down(mp). The latter replaces the XFS_FORCED_SHUTDOWN()
macro.

There's a bit of extra work around the attr2 feature bit - we've got
the superblock bit, and then "attr2" and "noattr2" mount options and
somewhat convoluted interactions. This patchset changes the
behaviour of all these now - the attr2 bit on disk and mount option
now mean the same thing, and noattr2 will turn off the superblock
bit if it is set and prevent attr2 inodes from being created. This
simplifies the mount time checking and clearing of these features.

Also, it gives us a clean separation of "inode32 mount option" and
"inode32 allocation is active". The former is a feature bit (i.e.
SMALL_INUMS), and the latter is a state bit (32BITINODES) that is
set if the filesystem size requires the allocator to limit
allocation to 32 bit inode space.

This also allows us to get rid of all the xfs_sb_version_hasfoo()
inline functions. THere is a single function to populate m_features
from the superblock bits, and the low level checks that are purely
superblock based (i.e. on disk conversion and verifiers) directly
check the superblock fields rather than use wrappers.

Overall, this doesn't change the amount of code. If does reduce the
built binary size by about 3.2kB, mainly through replacing the
xfs_sb_version...() checks with a single m_features flag check. It
makes the code a bit simpler, easier to read, and less shouty and
separates runtime state from filesystem features.

-Dave.

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

* [PATCH 01/10] xfs: reflect sb features in xfs_mount
  2018-08-20  4:48 [PATCH 0/10] xfs: feature flag rework Dave Chinner
@ 2018-08-20  4:48 ` Dave Chinner
  2018-08-21 13:21   ` Brian Foster
  2018-08-20  4:48 ` [PATCH 02/10] xfs: replace xfs_sb_version checks with feature flag checks Dave Chinner
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 27+ messages in thread
From: Dave Chinner @ 2018-08-20  4:48 UTC (permalink / raw)
  To: linux-xfs

From: Dave Chinner <dchinner@redhat.com>

Currently on-disk feature checks require decoding the superblock
fileds and so can be non-trivial. We have almost 400 hundred
individual feature checks in the XFS code, so this is a significant
amount of code. To reduce runtime check overhead, pre-process all
the version flags into a features field in the xfs_mount at mount
time so we can convert all the feature checks to a simple flag
check.

There is also a need to convert the dynamic feature flags to update
the m_features field. This is required for attr, attr2 and quota
features. New xfs_mount based wrappers are added for this.

Before:

$ size -t fs/xfs/built-in.a
   text	   data	    bss	    dec	    hex	filename
....
1294873	 182766	   1036	1478675	 169013	(TOTALS

Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
 fs/xfs/libxfs/xfs_format.h |  2 +-
 fs/xfs/libxfs/xfs_sb.c     | 61 +++++++++++++++++++++++++++++
 fs/xfs/libxfs/xfs_sb.h     |  1 +
 fs/xfs/xfs_log_recover.c   |  1 +
 fs/xfs/xfs_mount.c         |  1 +
 fs/xfs/xfs_mount.h         | 79 ++++++++++++++++++++++++++++++++++++++
 6 files changed, 144 insertions(+), 1 deletion(-)

diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
index 059bc44c27e8..c7b5a43af910 100644
--- a/fs/xfs/libxfs/xfs_format.h
+++ b/fs/xfs/libxfs/xfs_format.h
@@ -416,7 +416,7 @@ static inline bool xfs_sb_version_hasprojid32bit(struct xfs_sb *sbp)
 		(sbp->sb_features2 & XFS_SB_VERSION2_PROJID32BIT));
 }
 
-static inline void xfs_sb_version_addprojid32bit(struct xfs_sb *sbp)
+static inline void xfs_sb_version_addprojid32(struct xfs_sb *sbp)
 {
 	sbp->sb_versionnum |= XFS_SB_VERSION_MOREBITSBIT;
 	sbp->sb_features2 |= XFS_SB_VERSION2_PROJID32BIT;
diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c
index 081f46e30556..f9c8e1e9d8e3 100644
--- a/fs/xfs/libxfs/xfs_sb.c
+++ b/fs/xfs/libxfs/xfs_sb.c
@@ -96,6 +96,67 @@ xfs_perag_put(
 	trace_xfs_perag_put(pag->pag_mount, pag->pag_agno, ref, _RET_IP_);
 }
 
+uint64_t
+xfs_sb_version_to_features(
+	struct xfs_sb	*sbp)
+{
+	uint64_t	features = 0;
+
+	/* optional V4 features */
+	if (sbp->sb_rblocks > 0)
+		features |= XFS_FEAT_REALTIME;
+	if (sbp->sb_versionnum & XFS_SB_VERSION_ATTRBIT)
+		features |= XFS_FEAT_ATTR;
+	if (sbp->sb_versionnum & XFS_SB_VERSION_QUOTABIT)
+		features |= XFS_FEAT_QUOTA;
+	if (sbp->sb_versionnum & XFS_SB_VERSION_ALIGNBIT)
+		features |= XFS_FEAT_ALIGN;
+	if (sbp->sb_versionnum & XFS_SB_VERSION_LOGV2BIT)
+		features |= XFS_FEAT_LOGV2;
+	if (sbp->sb_versionnum & XFS_SB_VERSION_DALIGNBIT)
+		features |= XFS_FEAT_DALIGN;
+	if (sbp->sb_versionnum & XFS_SB_VERSION_EXTFLGBIT)
+		features |= XFS_FEAT_EXTFLG;
+	if (sbp->sb_versionnum & XFS_SB_VERSION_SECTORBIT)
+		features |= XFS_FEAT_SECTOR;
+	if (sbp->sb_versionnum & XFS_SB_VERSION_BORGBIT)
+		features |= XFS_FEAT_ASCIICI;
+	if (sbp->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT) {
+		if (sbp->sb_features2 & XFS_SB_VERSION2_LAZYSBCOUNTBIT)
+			features |= XFS_FEAT_LAZYSBCOUNT;
+		if (sbp->sb_features2 & XFS_SB_VERSION2_ATTR2BIT)
+			features |= XFS_FEAT_ATTR2;
+		if (sbp->sb_features2 & XFS_SB_VERSION2_PROJID32BIT)
+			features |= XFS_FEAT_PROJID32;
+		if (sbp->sb_features2 & XFS_SB_VERSION2_FTYPE)
+			features |= XFS_FEAT_FTYPE;
+	}
+
+	if (XFS_SB_VERSION_NUM(sbp) != XFS_SB_VERSION_5)
+		return features;
+
+	/* Always on V5 features */
+	features |= XFS_FEAT_ALIGN | XFS_FEAT_LOGV2 |
+		    XFS_FEAT_EXTFLG | XFS_FEAT_LAZYSBCOUNT |
+		    XFS_FEAT_ATTR2 | XFS_FEAT_PROJID32 |
+		    XFS_FEAT_CRC | XFS_FEAT_PQUOTINO;
+
+	/* Optional V5 features */
+	if (sbp->sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_FINOBT)
+		features |= XFS_FEAT_FINOBT;
+	if (sbp->sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_RMAPBT)
+		features |= XFS_FEAT_RMAPBT;
+	if (sbp->sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_REFLINK)
+		features |= XFS_FEAT_REFLINK;
+	if (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_FTYPE)
+		features |= XFS_FEAT_FTYPE;
+	if (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_SPINODES)
+		features |= XFS_FEAT_SPINODES;
+	if (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_META_UUID)
+		features |= XFS_FEAT_META_UUID;
+	return features;
+}
+
 /* Check all the superblock fields we care about when reading one in. */
 STATIC int
 xfs_validate_sb_read(
diff --git a/fs/xfs/libxfs/xfs_sb.h b/fs/xfs/libxfs/xfs_sb.h
index 13564d69800a..640a438402aa 100644
--- a/fs/xfs/libxfs/xfs_sb.h
+++ b/fs/xfs/libxfs/xfs_sb.h
@@ -29,6 +29,7 @@ extern void	xfs_sb_mount_common(struct xfs_mount *mp, struct xfs_sb *sbp);
 extern void	xfs_sb_from_disk(struct xfs_sb *to, struct xfs_dsb *from);
 extern void	xfs_sb_to_disk(struct xfs_dsb *to, struct xfs_sb *from);
 extern void	xfs_sb_quota_from_disk(struct xfs_sb *sbp);
+extern uint64_t	xfs_sb_version_to_features(struct xfs_sb *sbp);
 
 extern int	xfs_update_secondary_sbs(struct xfs_mount *mp);
 
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index a21dc61ec09e..5d0438ec07dd 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -5723,6 +5723,7 @@ xlog_do_recover(
 	xfs_buf_relse(bp);
 
 	/* re-initialise in-core superblock and geometry structures */
+	mp->m_features |= xfs_sb_version_to_features(sbp);
 	xfs_reinit_percpu_counters(mp);
 	error = xfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi);
 	if (error) {
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 02d15098dbee..fc567ca8b9d3 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -342,6 +342,7 @@ xfs_readsb(
 		goto reread;
 	}
 
+	mp->m_features |= xfs_sb_version_to_features(sbp);
 	xfs_reinit_percpu_counters(mp);
 
 	/* no need to be quiet anymore, so reset the buf ops */
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 7964513c3128..92d947f17c69 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -127,6 +127,7 @@ typedef struct xfs_mount {
 	struct mutex		m_growlock;	/* growfs mutex */
 	int			m_fixedfsid[2];	/* unchanged for life of FS */
 	uint64_t		m_flags;	/* global mount flags */
+	uint64_t		m_features;	/* active filesystem features */
 	bool			m_inotbt_nores; /* no per-AG finobt resv. */
 	int			m_ialloc_inos;	/* inodes in inode allocation */
 	int			m_ialloc_blks;	/* blocks in inode allocation */
@@ -195,6 +196,84 @@ typedef struct xfs_mount {
 #endif
 } xfs_mount_t;
 
+/*
+ * Flags for m_features.
+ *
+ * These are all the active features in the filesystem, regardless of how
+ * they are configured.
+ */
+#define	XFS_FEAT_ATTR		(1ULL << 0)	/* xattrs present in fs */
+#define	XFS_FEAT_NLINK		(1ULL << 1)	/* 32 bit link counts */
+#define	XFS_FEAT_QUOTA		(1ULL << 2)	/* quota active */
+#define	XFS_FEAT_ALIGN		(1ULL << 3)	/* inode alignment */
+#define	XFS_FEAT_DALIGN		(1ULL << 4)	/* data alignment */
+#define XFS_FEAT_LOGV2		(1ULL << 5)	/* version 2 logs */
+#define XFS_FEAT_SECTOR		(1ULL << 6)	/* sector size > 512 bytes */
+#define	XFS_FEAT_EXTFLG		(1ULL << 7)	/* unwritten extents */
+#define	XFS_FEAT_ASCIICI	(1ULL << 8)	/* ASCII only case-insens. */
+#define XFS_FEAT_LAZYSBCOUNT	(1ULL << 9)	/* Superblk counters */
+#define XFS_FEAT_ATTR2		(1ULL << 10)	/* dynamic attr fork */
+#define XFS_FEAT_PARENT		(1ULL << 11)	/* parent pointers */
+#define XFS_FEAT_PROJID32	(1ULL << 12)	/* 32 bit project id */
+#define XFS_FEAT_CRC		(1ULL << 13)	/* metadata CRCs */
+#define XFS_FEAT_PQUOTINO	(1ULL << 14)	/* non-shared proj/grp quotas */
+#define XFS_FEAT_FTYPE		(1ULL << 15)	/* inode type in dir */
+#define XFS_FEAT_FINOBT		(1ULL << 16)	/* free inode btree */
+#define XFS_FEAT_RMAPBT		(1ULL << 17)	/* reverse map btree */
+#define XFS_FEAT_REFLINK	(1ULL << 18)	/* reflinked files */
+#define XFS_FEAT_SPINODES	(1ULL << 19)	/* sparse inode chunks */
+#define XFS_FEAT_META_UUID	(1ULL << 20)	/* metadata UUID */
+#define XFS_FEAT_REALTIME	(1ULL << 21)	/* realtime device present */
+
+#define __XFS_HAS_FEAT(name, NAME) \
+static inline bool xfs_has_ ## name (struct xfs_mount *mp) \
+{ \
+	return mp->m_features & XFS_FEAT_ ## NAME; \
+}
+
+/* Some features can be added dynamically so they need a set wrapper, too. */
+#define __XFS_HAS_ADDFEAT(name, NAME) \
+	__XFS_HAS_FEAT(name, NAME); \
+static inline void xfs_feat_add_ ## name (struct xfs_mount *mp) \
+{ \
+	mp->m_features |= XFS_FEAT_ ## NAME; \
+	xfs_sb_version_add ## name(&mp->m_sb); \
+}
+
+/* Some features can be cleared dynamically so they need a clear wrapper */
+#define __XFS_HAS_REMOVEFEAT(name, NAME) \
+	__XFS_HAS_ADDFEAT(name, NAME); \
+static inline void xfs_feat_remove_ ## name (struct xfs_mount *mp) \
+{ \
+	mp->m_features &= ~XFS_FEAT_ ## NAME; \
+	xfs_sb_version_remove ## name(&mp->m_sb); \
+}
+
+
+__XFS_HAS_ADDFEAT(attr, ATTR)
+__XFS_HAS_FEAT(nlink, NLINK)
+__XFS_HAS_ADDFEAT(quota, QUOTA)
+__XFS_HAS_FEAT(align, ALIGN)
+__XFS_HAS_FEAT(dalign, DALIGN)
+__XFS_HAS_FEAT(logv2, LOGV2)
+__XFS_HAS_FEAT(sector, SECTOR)
+__XFS_HAS_FEAT(extflg, EXTFLG)
+__XFS_HAS_FEAT(asciici, ASCIICI)
+__XFS_HAS_FEAT(lazysbcount, LAZYSBCOUNT)
+__XFS_HAS_REMOVEFEAT(attr2, ATTR2)
+__XFS_HAS_FEAT(parent, PARENT)
+__XFS_HAS_ADDFEAT(projid32, PROJID32)
+__XFS_HAS_FEAT(crc, CRC)
+__XFS_HAS_FEAT(pquotino, PQUOTINO)
+__XFS_HAS_FEAT(ftype, FTYPE)
+__XFS_HAS_FEAT(finobt, FINOBT)
+__XFS_HAS_FEAT(rmapbt, RMAPBT)
+__XFS_HAS_FEAT(reflink, REFLINK)
+__XFS_HAS_FEAT(sparseinodes, SPINODES)
+__XFS_HAS_FEAT(metauuid, META_UUID)
+__XFS_HAS_FEAT(realtime, REALTIME)
+
+
 /*
  * Flags for m_flags.
  */
-- 
2.17.0

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

* [PATCH 02/10] xfs: replace xfs_sb_version checks with feature flag checks
  2018-08-20  4:48 [PATCH 0/10] xfs: feature flag rework Dave Chinner
  2018-08-20  4:48 ` [PATCH 01/10] xfs: reflect sb features in xfs_mount Dave Chinner
@ 2018-08-20  4:48 ` Dave Chinner
  2018-08-20  4:48 ` [PATCH 03/10] xfs: consolidate mount option features in m_features Dave Chinner
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 27+ messages in thread
From: Dave Chinner @ 2018-08-20  4:48 UTC (permalink / raw)
  To: linux-xfs

From: Dave Chinner <dchinner@redhat.com>

Convert the xfs_sb_version_hasfoo() to checks against
mp->m_features. Checks of the superblock itself during disk
operations (e.g. in the read/write verifiers and the to/from disk
formatters) are not converted - they operate purely on the
superblock state. Everything else should use the mount features.

Large parts of this conversion were done with sed with commands like
this:

for f in `git grep -l xfs_sb_version_has fs/xfs/*.c`; do
	sed -i -e 's/xfs_sb_version_has\(.*\)(&\(.*\)->m_sb)/xfs_has_\1(\2)/' $f
done

With manual cleanups for things like "xfs_has_extflgbit" and other
little inconsistencies in naming.

The result is ia lot less typing to check features and an XFS binary
size reduced by a bit over 3kB:

$ size -t fs/xfs/built-in.a
	text	   data	    bss	    dec	    hex	filenam
before	1294873	 182766	   1036	1478675	 169013	(TOTALS)
after	1291658	 182766	   1036	1475460	 168384	(TOTALS)

Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
 fs/xfs/libxfs/xfs_ag.c             | 20 +++++++--------
 fs/xfs/libxfs/xfs_alloc.c          | 40 +++++++++++++++---------------
 fs/xfs/libxfs/xfs_alloc_btree.c    |  2 +-
 fs/xfs/libxfs/xfs_alloc_btree.h    |  2 +-
 fs/xfs/libxfs/xfs_attr_leaf.c      | 16 ++++++------
 fs/xfs/libxfs/xfs_attr_remote.c    | 12 ++++-----
 fs/xfs/libxfs/xfs_bmap.c           | 20 +++++++--------
 fs/xfs/libxfs/xfs_bmap_btree.c     |  4 +--
 fs/xfs/libxfs/xfs_bmap_btree.h     |  2 +-
 fs/xfs/libxfs/xfs_btree.c          | 20 +++++++--------
 fs/xfs/libxfs/xfs_da_btree.c       |  6 ++---
 fs/xfs/libxfs/xfs_da_format.c      |  6 ++---
 fs/xfs/libxfs/xfs_da_format.h      |  2 +-
 fs/xfs/libxfs/xfs_dir2.c           |  2 +-
 fs/xfs/libxfs/xfs_dir2_block.c     |  8 +++---
 fs/xfs/libxfs/xfs_dir2_data.c      |  8 +++---
 fs/xfs/libxfs/xfs_dir2_leaf.c      |  8 +++---
 fs/xfs/libxfs/xfs_dir2_node.c      | 10 ++++----
 fs/xfs/libxfs/xfs_dir2_sf.c        |  2 +-
 fs/xfs/libxfs/xfs_dquot_buf.c      |  6 ++---
 fs/xfs/libxfs/xfs_format.h         | 14 +++++------
 fs/xfs/libxfs/xfs_ialloc.c         | 28 ++++++++++-----------
 fs/xfs/libxfs/xfs_ialloc_btree.c   |  6 ++---
 fs/xfs/libxfs/xfs_ialloc_btree.h   |  2 +-
 fs/xfs/libxfs/xfs_inode_buf.c      | 12 ++++-----
 fs/xfs/libxfs/xfs_log_format.h     |  4 +--
 fs/xfs/libxfs/xfs_log_rlimit.c     |  2 +-
 fs/xfs/libxfs/xfs_refcount.c       |  8 +++---
 fs/xfs/libxfs/xfs_refcount_btree.c |  4 +--
 fs/xfs/libxfs/xfs_rmap.c           |  6 ++---
 fs/xfs/libxfs/xfs_rmap_btree.c     |  6 ++---
 fs/xfs/libxfs/xfs_sb.c             | 16 ++++++------
 fs/xfs/libxfs/xfs_symlink_remote.c | 10 ++++----
 fs/xfs/libxfs/xfs_trans_resv.c     | 14 +++++------
 fs/xfs/libxfs/xfs_trans_space.h    |  4 +--
 fs/xfs/libxfs/xfs_types.c          |  2 +-
 fs/xfs/scrub/agheader.c            | 12 ++++-----
 fs/xfs/scrub/agheader_repair.c     | 20 +++++++--------
 fs/xfs/scrub/attr.c                |  2 +-
 fs/xfs/scrub/bmap.c                |  8 +++---
 fs/xfs/scrub/common.c              |  8 +++---
 fs/xfs/scrub/dabtree.c             |  4 +--
 fs/xfs/scrub/dir.c                 | 10 ++++----
 fs/xfs/scrub/ialloc.c              |  2 +-
 fs/xfs/scrub/inode.c               |  6 ++---
 fs/xfs/scrub/quota.c               |  2 +-
 fs/xfs/scrub/repair.c              | 14 +++++------
 fs/xfs/scrub/scrub.c               |  4 +--
 fs/xfs/xfs_bmap_util.c             | 10 ++++----
 fs/xfs/xfs_buf.c                   |  2 +-
 fs/xfs/xfs_buf_item.c              |  2 +-
 fs/xfs/xfs_dir2_readdir.c          |  2 +-
 fs/xfs/xfs_dquot.c                 |  4 +--
 fs/xfs/xfs_fsmap.c                 |  4 +--
 fs/xfs/xfs_ioctl.c                 |  8 +++---
 fs/xfs/xfs_iops.c                  |  6 ++---
 fs/xfs/xfs_log.c                   | 20 +++++++--------
 fs/xfs/xfs_log_recover.c           | 30 +++++++++++-----------
 fs/xfs/xfs_mount.c                 | 23 +++++++++--------
 fs/xfs/xfs_qm.c                    | 10 ++++----
 fs/xfs/xfs_qm_bhv.c                |  2 +-
 fs/xfs/xfs_qm_syscalls.c           |  2 +-
 fs/xfs/xfs_reflink.c               |  6 ++---
 fs/xfs/xfs_super.c                 | 16 ++++++------
 fs/xfs/xfs_symlink.c               |  2 +-
 fs/xfs/xfs_trans.c                 | 14 +++++------
 66 files changed, 295 insertions(+), 294 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_ag.c b/fs/xfs/libxfs/xfs_ag.c
index 9345802c99f7..41c53f7a0cf3 100644
--- a/fs/xfs/libxfs/xfs_ag.c
+++ b/fs/xfs/libxfs/xfs_ag.c
@@ -139,7 +139,7 @@ xfs_rmaproot_init(
 	rrec->rm_offset = 0;
 
 	/* account for refc btree root */
-	if (xfs_sb_version_hasreflink(&mp->m_sb)) {
+	if (xfs_has_reflink(mp)) {
 		rrec = XFS_RMAP_REC_ADDR(block, 5);
 		rrec->rm_startblock = cpu_to_be32(xfs_refc_block(mp));
 		rrec->rm_blockcount = cpu_to_be32(1);
@@ -186,7 +186,7 @@ xfs_agfblock_init(
 	agf->agf_roots[XFS_BTNUM_CNTi] = cpu_to_be32(XFS_CNT_BLOCK(mp));
 	agf->agf_levels[XFS_BTNUM_BNOi] = cpu_to_be32(1);
 	agf->agf_levels[XFS_BTNUM_CNTi] = cpu_to_be32(1);
-	if (xfs_sb_version_hasrmapbt(&mp->m_sb)) {
+	if (xfs_has_rmapbt(mp)) {
 		agf->agf_roots[XFS_BTNUM_RMAPi] =
 					cpu_to_be32(XFS_RMAP_BLOCK(mp));
 		agf->agf_levels[XFS_BTNUM_RMAPi] = cpu_to_be32(1);
@@ -199,9 +199,9 @@ xfs_agfblock_init(
 	tmpsize = id->agsize - mp->m_ag_prealloc_blocks;
 	agf->agf_freeblks = cpu_to_be32(tmpsize);
 	agf->agf_longest = cpu_to_be32(tmpsize);
-	if (xfs_sb_version_hascrc(&mp->m_sb))
+	if (xfs_has_crc(mp))
 		uuid_copy(&agf->agf_uuid, &mp->m_sb.sb_meta_uuid);
-	if (xfs_sb_version_hasreflink(&mp->m_sb)) {
+	if (xfs_has_reflink(mp)) {
 		agf->agf_refcount_root = cpu_to_be32(
 				xfs_refc_block(mp));
 		agf->agf_refcount_level = cpu_to_be32(1);
@@ -219,7 +219,7 @@ xfs_agflblock_init(
 	__be32			*agfl_bno;
 	int			bucket;
 
-	if (xfs_sb_version_hascrc(&mp->m_sb)) {
+	if (xfs_has_crc(mp)) {
 		agfl->agfl_magicnum = cpu_to_be32(XFS_AGFL_MAGIC);
 		agfl->agfl_seqno = cpu_to_be32(id->agno);
 		uuid_copy(&agfl->agfl_uuid, &mp->m_sb.sb_meta_uuid);
@@ -249,9 +249,9 @@ xfs_agiblock_init(
 	agi->agi_freecount = 0;
 	agi->agi_newino = cpu_to_be32(NULLAGINO);
 	agi->agi_dirino = cpu_to_be32(NULLAGINO);
-	if (xfs_sb_version_hascrc(&mp->m_sb))
+	if (xfs_has_crc(mp))
 		uuid_copy(&agi->agi_uuid, &mp->m_sb.sb_meta_uuid);
-	if (xfs_sb_version_hasfinobt(&mp->m_sb)) {
+	if (xfs_has_finobt(mp)) {
 		agi->agi_free_root = cpu_to_be32(XFS_FIBT_BLOCK(mp));
 		agi->agi_free_level = cpu_to_be32(1);
 	}
@@ -364,14 +364,14 @@ xfs_ag_init_headers(
 		.ops = &xfs_inobt_buf_ops,
 		.work = &xfs_btroot_init,
 		.type = XFS_BTNUM_FINO,
-		.need_init =  xfs_sb_version_hasfinobt(&mp->m_sb)
+		.need_init =  xfs_has_finobt(mp)
 	},
 	{ /* RMAP root block */
 		.daddr = XFS_AGB_TO_DADDR(mp, id->agno, XFS_RMAP_BLOCK(mp)),
 		.numblks = BTOBB(mp->m_sb.sb_blocksize),
 		.ops = &xfs_rmapbt_buf_ops,
 		.work = &xfs_rmaproot_init,
-		.need_init = xfs_sb_version_hasrmapbt(&mp->m_sb)
+		.need_init = xfs_has_rmapbt(mp)
 	},
 	{ /* REFC root block */
 		.daddr = XFS_AGB_TO_DADDR(mp, id->agno, xfs_refc_block(mp)),
@@ -379,7 +379,7 @@ xfs_ag_init_headers(
 		.ops = &xfs_refcountbt_buf_ops,
 		.work = &xfs_btroot_init,
 		.type = XFS_BTNUM_REFC,
-		.need_init = xfs_sb_version_hasreflink(&mp->m_sb)
+		.need_init = xfs_has_reflink(mp)
 	},
 	{ /* NULL terminating block */
 		.daddr = XFS_BUF_DADDR_NULL,
diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
index e1c0c0d2f1b0..edf0fbd58ee5 100644
--- a/fs/xfs/libxfs/xfs_alloc.c
+++ b/fs/xfs/libxfs/xfs_alloc.c
@@ -55,7 +55,7 @@ xfs_agfl_size(
 {
 	unsigned int		size = mp->m_sb.sb_sectsize;
 
-	if (xfs_sb_version_hascrc(&mp->m_sb))
+	if (xfs_has_crc(mp))
 		size -= sizeof(struct xfs_agfl);
 
 	return size / sizeof(xfs_agblock_t);
@@ -65,9 +65,9 @@ unsigned int
 xfs_refc_block(
 	struct xfs_mount	*mp)
 {
-	if (xfs_sb_version_hasrmapbt(&mp->m_sb))
+	if (xfs_has_rmapbt(mp))
 		return XFS_RMAP_BLOCK(mp) + 1;
-	if (xfs_sb_version_hasfinobt(&mp->m_sb))
+	if (xfs_has_finobt(mp))
 		return XFS_FIBT_BLOCK(mp) + 1;
 	return XFS_IBT_BLOCK(mp) + 1;
 }
@@ -76,11 +76,11 @@ xfs_extlen_t
 xfs_prealloc_blocks(
 	struct xfs_mount	*mp)
 {
-	if (xfs_sb_version_hasreflink(&mp->m_sb))
+	if (xfs_has_reflink(mp))
 		return xfs_refc_block(mp) + 1;
-	if (xfs_sb_version_hasrmapbt(&mp->m_sb))
+	if (xfs_has_rmapbt(mp))
 		return XFS_RMAP_BLOCK(mp) + 1;
-	if (xfs_sb_version_hasfinobt(&mp->m_sb))
+	if (xfs_has_finobt(mp))
 		return XFS_FIBT_BLOCK(mp) + 1;
 	return XFS_IBT_BLOCK(mp) + 1;
 }
@@ -130,11 +130,11 @@ xfs_alloc_ag_max_usable(
 	blocks = XFS_BB_TO_FSB(mp, XFS_FSS_TO_BB(mp, 4)); /* ag headers */
 	blocks += XFS_ALLOC_AGFL_RESERVE;
 	blocks += 3;			/* AGF, AGI btree root blocks */
-	if (xfs_sb_version_hasfinobt(&mp->m_sb))
+	if (xfs_has_finobt(mp))
 		blocks++;		/* finobt root block */
-	if (xfs_sb_version_hasrmapbt(&mp->m_sb))
+	if (xfs_has_rmapbt(mp))
 		blocks++; 		/* rmap root block */
-	if (xfs_sb_version_hasreflink(&mp->m_sb))
+	if (xfs_has_reflink(mp))
 		blocks++;		/* refcount root block */
 
 	return mp->m_sb.sb_agblocks - blocks;
@@ -565,7 +565,7 @@ xfs_agfl_verify(
 	 * AGFL is what the AGF says is active. We can't get to the AGF, so we
 	 * can't verify just those entries are valid.
 	 */
-	if (!xfs_sb_version_hascrc(&mp->m_sb))
+	if (!xfs_has_crc(mp))
 		return NULL;
 
 	if (!uuid_equal(&agfl->agfl_uuid, &mp->m_sb.sb_meta_uuid))
@@ -605,7 +605,7 @@ xfs_agfl_read_verify(
 	 * AGFL is what the AGF says is active. We can't get to the AGF, so we
 	 * can't verify just those entries are valid.
 	 */
-	if (!xfs_sb_version_hascrc(&mp->m_sb))
+	if (!xfs_has_crc(mp))
 		return;
 
 	if (!xfs_buf_verify_cksum(bp, XFS_AGFL_CRC_OFF))
@@ -626,7 +626,7 @@ xfs_agfl_write_verify(
 	xfs_failaddr_t		fa;
 
 	/* no verification of non-crc AGFLs */
-	if (!xfs_sb_version_hascrc(&mp->m_sb))
+	if (!xfs_has_crc(mp))
 		return;
 
 	fa = xfs_agfl_verify(bp);
@@ -2019,7 +2019,7 @@ xfs_alloc_min_freelist(
 	min_free += min_t(unsigned int, pag->pagf_levels[XFS_BTNUM_CNTi] + 1,
 				       mp->m_ag_maxlevels);
 	/* space needed reverse mapping used space btree */
-	if (xfs_sb_version_hasrmapbt(&mp->m_sb))
+	if (xfs_has_rmapbt(mp))
 		min_free += min_t(unsigned int,
 				  pag->pagf_levels[XFS_BTNUM_RMAPi] + 1,
 				  mp->m_rmap_maxlevels);
@@ -2121,7 +2121,7 @@ xfs_agfl_needs_reset(
 	int			active;
 
 	/* no agfl header on v4 supers */
-	if (!xfs_sb_version_hascrc(&mp->m_sb))
+	if (!xfs_has_crc(mp))
 		return false;
 
 	/*
@@ -2580,7 +2580,7 @@ xfs_agf_verify(
 	struct xfs_mount	*mp = bp->b_target->bt_mount;
 	struct xfs_agf		*agf = XFS_BUF_TO_AGF(bp);
 
-	if (xfs_sb_version_hascrc(&mp->m_sb)) {
+	if (xfs_has_crc(mp)) {
 		if (!uuid_equal(&agf->agf_uuid, &mp->m_sb.sb_meta_uuid))
 			return __this_address;
 		if (!xfs_log_check_lsn(mp,
@@ -2602,7 +2602,7 @@ xfs_agf_verify(
 	    be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]) > XFS_BTREE_MAXLEVELS)
 		return __this_address;
 
-	if (xfs_sb_version_hasrmapbt(&mp->m_sb) &&
+	if (xfs_has_rmapbt(mp) &&
 	    (be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]) < 1 ||
 	     be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]) > XFS_BTREE_MAXLEVELS))
 		return __this_address;
@@ -2616,11 +2616,11 @@ xfs_agf_verify(
 	if (bp->b_pag && be32_to_cpu(agf->agf_seqno) != bp->b_pag->pag_agno)
 		return __this_address;
 
-	if (xfs_sb_version_haslazysbcount(&mp->m_sb) &&
+	if (xfs_has_lazysbcount(mp) &&
 	    be32_to_cpu(agf->agf_btreeblks) > be32_to_cpu(agf->agf_length))
 		return __this_address;
 
-	if (xfs_sb_version_hasreflink(&mp->m_sb) &&
+	if (xfs_has_reflink(mp) &&
 	    (be32_to_cpu(agf->agf_refcount_level) < 1 ||
 	     be32_to_cpu(agf->agf_refcount_level) > XFS_BTREE_MAXLEVELS))
 		return __this_address;
@@ -2636,7 +2636,7 @@ xfs_agf_read_verify(
 	struct xfs_mount *mp = bp->b_target->bt_mount;
 	xfs_failaddr_t	fa;
 
-	if (xfs_sb_version_hascrc(&mp->m_sb) &&
+	if (xfs_has_crc(mp) &&
 	    !xfs_buf_verify_cksum(bp, XFS_AGF_CRC_OFF))
 		xfs_verifier_error(bp, -EFSBADCRC, __this_address);
 	else {
@@ -2660,7 +2660,7 @@ xfs_agf_write_verify(
 		return;
 	}
 
-	if (!xfs_sb_version_hascrc(&mp->m_sb))
+	if (!xfs_has_crc(mp))
 		return;
 
 	if (bip)
diff --git a/fs/xfs/libxfs/xfs_alloc_btree.c b/fs/xfs/libxfs/xfs_alloc_btree.c
index 4e59cc8a2802..dd9c552d3eb0 100644
--- a/fs/xfs/libxfs/xfs_alloc_btree.c
+++ b/fs/xfs/libxfs/xfs_alloc_btree.c
@@ -513,7 +513,7 @@ xfs_allocbt_init_cursor(
 	cur->bc_private.a.agbp = agbp;
 	cur->bc_private.a.agno = agno;
 
-	if (xfs_sb_version_hascrc(&mp->m_sb))
+	if (xfs_has_crc(mp))
 		cur->bc_flags |= XFS_BTREE_CRC_BLOCKS;
 
 	return cur;
diff --git a/fs/xfs/libxfs/xfs_alloc_btree.h b/fs/xfs/libxfs/xfs_alloc_btree.h
index c9305ebb69f6..0f7afe756add 100644
--- a/fs/xfs/libxfs/xfs_alloc_btree.h
+++ b/fs/xfs/libxfs/xfs_alloc_btree.h
@@ -18,7 +18,7 @@ struct xfs_mount;
  * Btree block header size depends on a superblock flag.
  */
 #define XFS_ALLOC_BLOCK_LEN(mp) \
-	(xfs_sb_version_hascrc(&((mp)->m_sb)) ? \
+	(xfs_has_crc(((mp))) ? \
 		XFS_BTREE_SBLOCK_CRC_LEN : XFS_BTREE_SBLOCK_LEN)
 
 /*
diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c
index 6fc5425b1474..fbd53362b5bc 100644
--- a/fs/xfs/libxfs/xfs_attr_leaf.c
+++ b/fs/xfs/libxfs/xfs_attr_leaf.c
@@ -248,7 +248,7 @@ xfs_attr3_leaf_verify(
 
 	xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, leaf);
 
-	if (xfs_sb_version_hascrc(&mp->m_sb)) {
+	if (xfs_has_crc(mp)) {
 		struct xfs_da3_node_hdr *hdr3 = bp->b_addr;
 
 		if (ichdr.magic != XFS_ATTR3_LEAF_MAGIC)
@@ -328,7 +328,7 @@ xfs_attr3_leaf_write_verify(
 		return;
 	}
 
-	if (!xfs_sb_version_hascrc(&mp->m_sb))
+	if (!xfs_has_crc(mp))
 		return;
 
 	if (bip)
@@ -350,7 +350,7 @@ xfs_attr3_leaf_read_verify(
 	struct xfs_mount	*mp = bp->b_target->bt_mount;
 	xfs_failaddr_t		fa;
 
-	if (xfs_sb_version_hascrc(&mp->m_sb) &&
+	if (xfs_has_crc(mp) &&
 	     !xfs_buf_verify_cksum(bp, XFS_ATTR3_LEAF_CRC_OFF))
 		xfs_verifier_error(bp, -EFSBADCRC, __this_address);
 	else {
@@ -508,10 +508,10 @@ STATIC void
 xfs_sbversion_add_attr2(xfs_mount_t *mp, xfs_trans_t *tp)
 {
 	if ((mp->m_flags & XFS_MOUNT_ATTR2) &&
-	    !(xfs_sb_version_hasattr2(&mp->m_sb))) {
+	    !(xfs_has_attr2(mp))) {
 		spin_lock(&mp->m_sb_lock);
-		if (!xfs_sb_version_hasattr2(&mp->m_sb)) {
-			xfs_sb_version_addattr2(&mp->m_sb);
+		if (!xfs_has_attr2(mp)) {
+			xfs_feat_add_attr2(mp);
 			spin_unlock(&mp->m_sb_lock);
 			xfs_log_sb(tp);
 		} else
@@ -1089,7 +1089,7 @@ xfs_attr3_leaf_to_node(
 	xfs_trans_buf_set_type(args->trans, bp2, XFS_BLFT_ATTR_LEAF_BUF);
 	bp2->b_ops = bp1->b_ops;
 	memcpy(bp2->b_addr, bp1->b_addr, args->geo->blksize);
-	if (xfs_sb_version_hascrc(&mp->m_sb)) {
+	if (xfs_has_crc(mp)) {
 		struct xfs_da3_blkinfo *hdr3 = bp2->b_addr;
 		hdr3->blkno = cpu_to_be64(bp2->b_bn);
 	}
@@ -1155,7 +1155,7 @@ xfs_attr3_leaf_create(
 	memset(&ichdr, 0, sizeof(ichdr));
 	ichdr.firstused = args->geo->blksize;
 
-	if (xfs_sb_version_hascrc(&mp->m_sb)) {
+	if (xfs_has_crc(mp)) {
 		struct xfs_da3_blkinfo *hdr3 = bp->b_addr;
 
 		ichdr.magic = XFS_ATTR3_LEAF_MAGIC;
diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c
index af094063e402..a23946447037 100644
--- a/fs/xfs/libxfs/xfs_attr_remote.c
+++ b/fs/xfs/libxfs/xfs_attr_remote.c
@@ -41,7 +41,7 @@ xfs_attr3_rmt_blocks(
 	struct xfs_mount *mp,
 	int		attrlen)
 {
-	if (xfs_sb_version_hascrc(&mp->m_sb)) {
+	if (xfs_has_crc(mp)) {
 		int buflen = XFS_ATTR3_RMT_BUF_SPACE(mp, mp->m_sb.sb_blocksize);
 		return (attrlen + buflen - 1) / buflen;
 	}
@@ -85,7 +85,7 @@ xfs_attr3_rmt_verify(
 {
 	struct xfs_attr3_rmt_hdr *rmt = ptr;
 
-	if (!xfs_sb_version_hascrc(&mp->m_sb))
+	if (!xfs_has_crc(mp))
 		return __this_address;
 	if (rmt->rm_magic != cpu_to_be32(XFS_ATTR3_RMT_MAGIC))
 		return __this_address;
@@ -117,7 +117,7 @@ __xfs_attr3_rmt_read_verify(
 	int		blksize = mp->m_attr_geo->blksize;
 
 	/* no verification of non-crc buffers */
-	if (!xfs_sb_version_hascrc(&mp->m_sb))
+	if (!xfs_has_crc(mp))
 		return 0;
 
 	ptr = bp->b_addr;
@@ -182,7 +182,7 @@ xfs_attr3_rmt_write_verify(
 	xfs_daddr_t	bno;
 
 	/* no verification of non-crc buffers */
-	if (!xfs_sb_version_hascrc(&mp->m_sb))
+	if (!xfs_has_crc(mp))
 		return;
 
 	ptr = bp->b_addr;
@@ -236,7 +236,7 @@ xfs_attr3_rmt_hdr_set(
 {
 	struct xfs_attr3_rmt_hdr *rmt = ptr;
 
-	if (!xfs_sb_version_hascrc(&mp->m_sb))
+	if (!xfs_has_crc(mp))
 		return 0;
 
 	rmt->rm_magic = cpu_to_be32(XFS_ATTR3_RMT_MAGIC);
@@ -286,7 +286,7 @@ xfs_attr_rmtval_copyout(
 
 		byte_cnt = min(*valuelen, byte_cnt);
 
-		if (xfs_sb_version_hascrc(&mp->m_sb)) {
+		if (xfs_has_crc(mp)) {
 			if (xfs_attr3_rmt_hdr_ok(src, ino, *offset,
 						  byte_cnt, bno)) {
 				xfs_alert(mp,
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index 2760314fdf7f..777630f3066a 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -1110,17 +1110,17 @@ xfs_bmap_add_attrfork(
 		xfs_trans_log_inode(tp, ip, logflags);
 	if (error)
 		goto trans_cancel;
-	if (!xfs_sb_version_hasattr(&mp->m_sb) ||
-	   (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2)) {
+	if (!xfs_has_attr(mp) ||
+	   (!xfs_has_attr2(mp) && version == 2)) {
 		bool log_sb = false;
 
 		spin_lock(&mp->m_sb_lock);
-		if (!xfs_sb_version_hasattr(&mp->m_sb)) {
-			xfs_sb_version_addattr(&mp->m_sb);
+		if (!xfs_has_attr(mp)) {
+			xfs_feat_add_attr(mp);
 			log_sb = true;
 		}
-		if (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2) {
-			xfs_sb_version_addattr2(&mp->m_sb);
+		if (!xfs_has_attr2(mp) && version == 2) {
+			xfs_feat_add_attr2(mp);
 			log_sb = true;
 		}
 		spin_unlock(&mp->m_sb_lock);
@@ -4080,7 +4080,7 @@ xfs_bmapi_allocate(
 	 */
 	if ((!bma->wasdel || (bma->flags & XFS_BMAPI_COWFORK)) &&
 	    (bma->flags & XFS_BMAPI_PREALLOC) &&
-	    xfs_sb_version_hasextflgbit(&mp->m_sb))
+	    xfs_has_extflg(mp))
 		bma->got.br_state = XFS_EXT_UNWRITTEN;
 
 	if (bma->wasdel)
@@ -5244,7 +5244,7 @@ __xfs_bunmapi(
 			 * get rid of part of a realtime extent.
 			 */
 			if (del.br_state == XFS_EXT_UNWRITTEN ||
-			    !xfs_sb_version_hasextflgbit(&mp->m_sb)) {
+			    !xfs_has_extflg(mp)) {
 				/*
 				 * This piece is unwritten, or we're not
 				 * using unwritten extents.  Skip over it.
@@ -5297,7 +5297,7 @@ __xfs_bunmapi(
 			} else if ((del.br_startoff == start &&
 				    (del.br_state == XFS_EXT_UNWRITTEN ||
 				     tp->t_blk_res == 0)) ||
-				   !xfs_sb_version_hasextflgbit(&mp->m_sb)) {
+				   !xfs_has_extflg(mp)) {
 				/*
 				 * Can't make it unwritten.  There isn't
 				 * a full extent here so just skip it.
@@ -6115,7 +6115,7 @@ xfs_bmap_validate_extent(
 	if (irec->br_state != XFS_EXT_NORM) {
 		if (whichfork != XFS_DATA_FORK)
 			return __this_address;
-		if (!xfs_sb_version_hasextflgbit(&mp->m_sb))
+		if (!xfs_has_extflg(mp))
 			return __this_address;
 	}
 	return NULL;
diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c
index cdb74d2e2a43..91275ff86c8d 100644
--- a/fs/xfs/libxfs/xfs_bmap_btree.c
+++ b/fs/xfs/libxfs/xfs_bmap_btree.c
@@ -139,7 +139,7 @@ xfs_bmbt_to_bmdr(
 	xfs_bmbt_key_t		*tkp;
 	__be64			*tpp;
 
-	if (xfs_sb_version_hascrc(&mp->m_sb)) {
+	if (xfs_has_crc(mp)) {
 		ASSERT(rblock->bb_magic == cpu_to_be32(XFS_BMAP_CRC_MAGIC));
 		ASSERT(uuid_equal(&rblock->bb_u.l.bb_uuid,
 		       &mp->m_sb.sb_meta_uuid));
@@ -555,7 +555,7 @@ xfs_bmbt_init_cursor(
 
 	cur->bc_ops = &xfs_bmbt_ops;
 	cur->bc_flags = XFS_BTREE_LONG_PTRS | XFS_BTREE_ROOT_IN_INODE;
-	if (xfs_sb_version_hascrc(&mp->m_sb))
+	if (xfs_has_crc(mp))
 		cur->bc_flags |= XFS_BTREE_CRC_BLOCKS;
 
 	cur->bc_private.b.forksize = XFS_IFORK_SIZE(ip, whichfork);
diff --git a/fs/xfs/libxfs/xfs_bmap_btree.h b/fs/xfs/libxfs/xfs_bmap_btree.h
index 29b407d053b4..11a5586e752e 100644
--- a/fs/xfs/libxfs/xfs_bmap_btree.h
+++ b/fs/xfs/libxfs/xfs_bmap_btree.h
@@ -16,7 +16,7 @@ struct xfs_trans;
  * Btree block header size depends on a superblock flag.
  */
 #define XFS_BMBT_BLOCK_LEN(mp) \
-	(xfs_sb_version_hascrc(&((mp)->m_sb)) ? \
+	(xfs_has_crc(((mp))) ? \
 		XFS_BTREE_LBLOCK_CRC_LEN : XFS_BTREE_LBLOCK_LEN)
 
 #define XFS_BMBT_REC_ADDR(mp, block, index) \
diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c
index 34c6d7bd4d18..3319b9f8e2ba 100644
--- a/fs/xfs/libxfs/xfs_btree.c
+++ b/fs/xfs/libxfs/xfs_btree.c
@@ -65,7 +65,7 @@ __xfs_btree_check_lblock(
 {
 	struct xfs_mount	*mp = cur->bc_mp;
 	xfs_btnum_t		btnum = cur->bc_btnum;
-	int			crc = xfs_sb_version_hascrc(&mp->m_sb);
+	int			crc = xfs_has_crc(mp);
 
 	if (crc) {
 		if (!uuid_equal(&block->bb_u.l.bb_uuid, &mp->m_sb.sb_meta_uuid))
@@ -131,7 +131,7 @@ __xfs_btree_check_sblock(
 {
 	struct xfs_mount	*mp = cur->bc_mp;
 	xfs_btnum_t		btnum = cur->bc_btnum;
-	int			crc = xfs_sb_version_hascrc(&mp->m_sb);
+	int			crc = xfs_has_crc(mp);
 
 	if (crc) {
 		if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))
@@ -276,7 +276,7 @@ xfs_btree_lblock_calc_crc(
 	struct xfs_btree_block	*block = XFS_BUF_TO_BLOCK(bp);
 	struct xfs_buf_log_item	*bip = bp->b_log_item;
 
-	if (!xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb))
+	if (!xfs_has_crc(bp->b_target->bt_mount))
 		return;
 	if (bip)
 		block->bb_u.l.bb_lsn = cpu_to_be64(bip->bli_item.li_lsn);
@@ -290,7 +290,7 @@ xfs_btree_lblock_verify_crc(
 	struct xfs_btree_block	*block = XFS_BUF_TO_BLOCK(bp);
 	struct xfs_mount	*mp = bp->b_target->bt_mount;
 
-	if (xfs_sb_version_hascrc(&mp->m_sb)) {
+	if (xfs_has_crc(mp)) {
 		if (!xfs_log_check_lsn(mp, be64_to_cpu(block->bb_u.l.bb_lsn)))
 			return false;
 		return xfs_buf_verify_cksum(bp, XFS_BTREE_LBLOCK_CRC_OFF);
@@ -314,7 +314,7 @@ xfs_btree_sblock_calc_crc(
 	struct xfs_btree_block	*block = XFS_BUF_TO_BLOCK(bp);
 	struct xfs_buf_log_item	*bip = bp->b_log_item;
 
-	if (!xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb))
+	if (!xfs_has_crc(bp->b_target->bt_mount))
 		return;
 	if (bip)
 		block->bb_u.s.bb_lsn = cpu_to_be64(bip->bli_item.li_lsn);
@@ -328,7 +328,7 @@ xfs_btree_sblock_verify_crc(
 	struct xfs_btree_block  *block = XFS_BUF_TO_BLOCK(bp);
 	struct xfs_mount	*mp = bp->b_target->bt_mount;
 
-	if (xfs_sb_version_hascrc(&mp->m_sb)) {
+	if (xfs_has_crc(mp)) {
 		if (!xfs_log_check_lsn(mp, be64_to_cpu(block->bb_u.s.bb_lsn)))
 			return __this_address;
 		return xfs_buf_verify_cksum(bp, XFS_BTREE_SBLOCK_CRC_OFF);
@@ -1146,7 +1146,7 @@ xfs_btree_init_block_int(
 	__u64			owner,
 	unsigned int		flags)
 {
-	int			crc = xfs_sb_version_hascrc(&mp->m_sb);
+	int			crc = xfs_has_crc(mp);
 	__u32			magic = xfs_btree_magic(crc, btnum);
 
 	buf->bb_magic = cpu_to_be32(magic);
@@ -1811,7 +1811,7 @@ xfs_btree_lookup_get_block(
 		return error;
 
 	/* Check the inode owner since the verifiers don't. */
-	if (xfs_sb_version_hascrc(&cur->bc_mp->m_sb) &&
+	if (xfs_has_crc(cur->bc_mp) &&
 	    !(cur->bc_private.b.flags & XFS_BTCUR_BPRV_INVALID_OWNER) &&
 	    (cur->bc_flags & XFS_BTREE_LONG_PTRS) &&
 	    be64_to_cpu((*blkp)->bb_u.l.bb_owner) !=
@@ -4436,7 +4436,7 @@ xfs_btree_lblock_v5hdr_verify(
 	struct xfs_mount	*mp = bp->b_target->bt_mount;
 	struct xfs_btree_block	*block = XFS_BUF_TO_BLOCK(bp);
 
-	if (!xfs_sb_version_hascrc(&mp->m_sb))
+	if (!xfs_has_crc(mp))
 		return __this_address;
 	if (!uuid_equal(&block->bb_u.l.bb_uuid, &mp->m_sb.sb_meta_uuid))
 		return __this_address;
@@ -4488,7 +4488,7 @@ xfs_btree_sblock_v5hdr_verify(
 	struct xfs_btree_block	*block = XFS_BUF_TO_BLOCK(bp);
 	struct xfs_perag	*pag = bp->b_pag;
 
-	if (!xfs_sb_version_hascrc(&mp->m_sb))
+	if (!xfs_has_crc(mp))
 		return __this_address;
 	if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))
 		return __this_address;
diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c
index 376bee94b5dd..ed2132c0e3bc 100644
--- a/fs/xfs/libxfs/xfs_da_btree.c
+++ b/fs/xfs/libxfs/xfs_da_btree.c
@@ -129,7 +129,7 @@ xfs_da3_node_verify(
 
 	ops->node_hdr_from_disk(&ichdr, hdr);
 
-	if (xfs_sb_version_hascrc(&mp->m_sb)) {
+	if (xfs_has_crc(mp)) {
 		struct xfs_da3_node_hdr *hdr3 = bp->b_addr;
 
 		if (ichdr.magic != XFS_DA3_NODE_MAGIC)
@@ -180,7 +180,7 @@ xfs_da3_node_write_verify(
 		return;
 	}
 
-	if (!xfs_sb_version_hascrc(&mp->m_sb))
+	if (!xfs_has_crc(mp))
 		return;
 
 	if (bip)
@@ -337,7 +337,7 @@ xfs_da3_node_create(
 	xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DA_NODE_BUF);
 	node = bp->b_addr;
 
-	if (xfs_sb_version_hascrc(&mp->m_sb)) {
+	if (xfs_has_crc(mp)) {
 		struct xfs_da3_node_hdr *hdr3 = bp->b_addr;
 
 		memset(hdr3, 0, sizeof(struct xfs_da3_node_hdr));
diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
index b39053dcb643..04ca3b9044b0 100644
--- a/fs/xfs/libxfs/xfs_da_format.c
+++ b/fs/xfs/libxfs/xfs_da_format.c
@@ -869,9 +869,9 @@ xfs_dir_get_ops(
 		return dp->d_ops;
 	if (mp->m_dir_inode_ops)
 		return mp->m_dir_inode_ops;
-	if (xfs_sb_version_hascrc(&mp->m_sb))
+	if (xfs_has_crc(mp))
 		return &xfs_dir3_ops;
-	if (xfs_sb_version_hasftype(&mp->m_sb))
+	if (xfs_has_ftype(mp))
 		return &xfs_dir2_ftype_ops;
 	return &xfs_dir2_ops;
 }
@@ -885,7 +885,7 @@ xfs_nondir_get_ops(
 		return dp->d_ops;
 	if (mp->m_nondir_inode_ops)
 		return mp->m_nondir_inode_ops;
-	if (xfs_sb_version_hascrc(&mp->m_sb))
+	if (xfs_has_crc(mp))
 		return &xfs_dir3_nondir_ops;
 	return &xfs_dir2_nondir_ops;
 }
diff --git a/fs/xfs/libxfs/xfs_da_format.h b/fs/xfs/libxfs/xfs_da_format.h
index 5d5bf3bffc78..5df76821ffc8 100644
--- a/fs/xfs/libxfs/xfs_da_format.h
+++ b/fs/xfs/libxfs/xfs_da_format.h
@@ -860,7 +860,7 @@ struct xfs_attr3_rmt_hdr {
 #define XFS_ATTR3_RMT_CRC_OFF	offsetof(struct xfs_attr3_rmt_hdr, rm_crc)
 
 #define XFS_ATTR3_RMT_BUF_SPACE(mp, bufsize)	\
-	((bufsize) - (xfs_sb_version_hascrc(&(mp)->m_sb) ? \
+	((bufsize) - (xfs_has_crc((mp)) ? \
 			sizeof(struct xfs_attr3_rmt_hdr) : 0))
 
 /* Number of bytes in a directory block. */
diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c
index 229152cd1a24..f80fde72ad2d 100644
--- a/fs/xfs/libxfs/xfs_dir2.c
+++ b/fs/xfs/libxfs/xfs_dir2.c
@@ -151,7 +151,7 @@ xfs_da_mount(
 				(uint)sizeof(xfs_da_node_entry_t);
 	dageo->magicpct = (dageo->blksize * 37) / 100;
 
-	if (xfs_sb_version_hasasciici(&mp->m_sb))
+	if (xfs_has_asciici(mp))
 		mp->m_dirnameops = &xfs_ascii_ci_nameops;
 	else
 		mp->m_dirnameops = &xfs_default_nameops;
diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c
index 30ed5919da72..7ae94e0c111c 100644
--- a/fs/xfs/libxfs/xfs_dir2_block.c
+++ b/fs/xfs/libxfs/xfs_dir2_block.c
@@ -53,7 +53,7 @@ xfs_dir3_block_verify(
 	struct xfs_mount	*mp = bp->b_target->bt_mount;
 	struct xfs_dir3_blk_hdr	*hdr3 = bp->b_addr;
 
-	if (xfs_sb_version_hascrc(&mp->m_sb)) {
+	if (xfs_has_crc(mp)) {
 		if (hdr3->magic != cpu_to_be32(XFS_DIR3_BLOCK_MAGIC))
 			return __this_address;
 		if (!uuid_equal(&hdr3->uuid, &mp->m_sb.sb_meta_uuid))
@@ -76,7 +76,7 @@ xfs_dir3_block_read_verify(
 	struct xfs_mount	*mp = bp->b_target->bt_mount;
 	xfs_failaddr_t		fa;
 
-	if (xfs_sb_version_hascrc(&mp->m_sb) &&
+	if (xfs_has_crc(mp) &&
 	     !xfs_buf_verify_cksum(bp, XFS_DIR3_DATA_CRC_OFF))
 		xfs_verifier_error(bp, -EFSBADCRC, __this_address);
 	else {
@@ -101,7 +101,7 @@ xfs_dir3_block_write_verify(
 		return;
 	}
 
-	if (!xfs_sb_version_hascrc(&mp->m_sb))
+	if (!xfs_has_crc(mp))
 		return;
 
 	if (bip)
@@ -145,7 +145,7 @@ xfs_dir3_block_init(
 	bp->b_ops = &xfs_dir3_block_buf_ops;
 	xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DIR_BLOCK_BUF);
 
-	if (xfs_sb_version_hascrc(&mp->m_sb)) {
+	if (xfs_has_crc(mp)) {
 		memset(hdr3, 0, sizeof(*hdr3));
 		hdr3->magic = cpu_to_be32(XFS_DIR3_BLOCK_MAGIC);
 		hdr3->blkno = cpu_to_be64(bp->b_bn);
diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c
index 01162c62ec8f..cf0a3b40b3e5 100644
--- a/fs/xfs/libxfs/xfs_dir2_data.c
+++ b/fs/xfs/libxfs/xfs_dir2_data.c
@@ -252,7 +252,7 @@ xfs_dir3_data_verify(
 	struct xfs_mount	*mp = bp->b_target->bt_mount;
 	struct xfs_dir3_blk_hdr	*hdr3 = bp->b_addr;
 
-	if (xfs_sb_version_hascrc(&mp->m_sb)) {
+	if (xfs_has_crc(mp)) {
 		if (hdr3->magic != cpu_to_be32(XFS_DIR3_DATA_MAGIC))
 			return __this_address;
 		if (!uuid_equal(&hdr3->uuid, &mp->m_sb.sb_meta_uuid))
@@ -303,7 +303,7 @@ xfs_dir3_data_read_verify(
 	struct xfs_mount	*mp = bp->b_target->bt_mount;
 	xfs_failaddr_t		fa;
 
-	if (xfs_sb_version_hascrc(&mp->m_sb) &&
+	if (xfs_has_crc(mp) &&
 	    !xfs_buf_verify_cksum(bp, XFS_DIR3_DATA_CRC_OFF))
 		xfs_verifier_error(bp, -EFSBADCRC, __this_address);
 	else {
@@ -328,7 +328,7 @@ xfs_dir3_data_write_verify(
 		return;
 	}
 
-	if (!xfs_sb_version_hascrc(&mp->m_sb))
+	if (!xfs_has_crc(mp))
 		return;
 
 	if (bip)
@@ -665,7 +665,7 @@ xfs_dir3_data_init(
 	 * Initialize the header.
 	 */
 	hdr = bp->b_addr;
-	if (xfs_sb_version_hascrc(&mp->m_sb)) {
+	if (xfs_has_crc(mp)) {
 		struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
 
 		memset(hdr3, 0, sizeof(*hdr3));
diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
index 1728a3e6f5cf..7ed0e018555e 100644
--- a/fs/xfs/libxfs/xfs_dir2_leaf.c
+++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
@@ -150,7 +150,7 @@ xfs_dir3_leaf_verify(
 
 	ASSERT(magic == XFS_DIR2_LEAF1_MAGIC || magic == XFS_DIR2_LEAFN_MAGIC);
 
-	if (xfs_sb_version_hascrc(&mp->m_sb)) {
+	if (xfs_has_crc(mp)) {
 		struct xfs_dir3_leaf_hdr *leaf3 = bp->b_addr;
 		uint16_t		magic3;
 
@@ -181,7 +181,7 @@ __read_verify(
 	struct xfs_mount	*mp = bp->b_target->bt_mount;
 	xfs_failaddr_t		fa;
 
-	if (xfs_sb_version_hascrc(&mp->m_sb) &&
+	if (xfs_has_crc(mp) &&
 	     !xfs_buf_verify_cksum(bp, XFS_DIR3_LEAF_CRC_OFF))
 		xfs_verifier_error(bp, -EFSBADCRC, __this_address);
 	else {
@@ -207,7 +207,7 @@ __write_verify(
 		return;
 	}
 
-	if (!xfs_sb_version_hascrc(&mp->m_sb))
+	if (!xfs_has_crc(mp))
 		return;
 
 	if (bip)
@@ -321,7 +321,7 @@ xfs_dir3_leaf_init(
 
 	ASSERT(type == XFS_DIR2_LEAF1_MAGIC || type == XFS_DIR2_LEAFN_MAGIC);
 
-	if (xfs_sb_version_hascrc(&mp->m_sb)) {
+	if (xfs_has_crc(mp)) {
 		struct xfs_dir3_leaf_hdr *leaf3 = bp->b_addr;
 
 		memset(leaf3, 0, sizeof(*leaf3));
diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
index f1bb3434f51c..60e5b19a4516 100644
--- a/fs/xfs/libxfs/xfs_dir2_node.c
+++ b/fs/xfs/libxfs/xfs_dir2_node.c
@@ -87,7 +87,7 @@ xfs_dir3_free_verify(
 	struct xfs_mount	*mp = bp->b_target->bt_mount;
 	struct xfs_dir2_free_hdr *hdr = bp->b_addr;
 
-	if (xfs_sb_version_hascrc(&mp->m_sb)) {
+	if (xfs_has_crc(mp)) {
 		struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
 
 		if (hdr3->magic != cpu_to_be32(XFS_DIR3_FREE_MAGIC))
@@ -115,7 +115,7 @@ xfs_dir3_free_read_verify(
 	struct xfs_mount	*mp = bp->b_target->bt_mount;
 	xfs_failaddr_t		fa;
 
-	if (xfs_sb_version_hascrc(&mp->m_sb) &&
+	if (xfs_has_crc(mp) &&
 	    !xfs_buf_verify_cksum(bp, XFS_DIR3_FREE_CRC_OFF))
 		xfs_verifier_error(bp, -EFSBADCRC, __this_address);
 	else {
@@ -140,7 +140,7 @@ xfs_dir3_free_write_verify(
 		return;
 	}
 
-	if (!xfs_sb_version_hascrc(&mp->m_sb))
+	if (!xfs_has_crc(mp))
 		return;
 
 	if (bip)
@@ -171,7 +171,7 @@ xfs_dir3_free_header_check(
 	firstdb = (xfs_dir2_da_to_db(mp->m_dir_geo, fbno) -
 		   xfs_dir2_byte_to_db(mp->m_dir_geo, XFS_DIR2_FREE_OFFSET)) *
 			maxbests;
-	if (xfs_sb_version_hascrc(&mp->m_sb)) {
+	if (xfs_has_crc(mp)) {
 		struct xfs_dir3_free_hdr *hdr3 = bp->b_addr;
 
 		if (be32_to_cpu(hdr3->firstdb) != firstdb)
@@ -272,7 +272,7 @@ xfs_dir3_free_get_buf(
 	memset(bp->b_addr, 0, sizeof(struct xfs_dir3_free_hdr));
 	memset(&hdr, 0, sizeof(hdr));
 
-	if (xfs_sb_version_hascrc(&mp->m_sb)) {
+	if (xfs_has_crc(mp)) {
 		struct xfs_dir3_free_hdr *hdr3 = bp->b_addr;
 
 		hdr.magic = XFS_DIR3_FREE_MAGIC;
diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c
index 585dfdb7b6b6..8f5e17f79151 100644
--- a/fs/xfs/libxfs/xfs_dir2_sf.c
+++ b/fs/xfs/libxfs/xfs_dir2_sf.c
@@ -75,7 +75,7 @@ xfs_dir2_block_sfsize(
 	 * if there is a filetype field, add the extra byte to the namelen
 	 * for each entry that we see.
 	 */
-	has_ftype = xfs_sb_version_hasftype(&mp->m_sb) ? 1 : 0;
+	has_ftype = xfs_has_ftype(mp) ? 1 : 0;
 
 	count = i8count = namelen = 0;
 	btp = xfs_dir2_block_tail_p(geo, hdr);
diff --git a/fs/xfs/libxfs/xfs_dquot_buf.c b/fs/xfs/libxfs/xfs_dquot_buf.c
index d293f371dd54..b61029e2ca58 100644
--- a/fs/xfs/libxfs/xfs_dquot_buf.c
+++ b/fs/xfs/libxfs/xfs_dquot_buf.c
@@ -100,7 +100,7 @@ xfs_dqblk_verify(
 	xfs_dqid_t	 	id,
 	uint		 	type)	/* used only during quotacheck */
 {
-	if (xfs_sb_version_hascrc(&mp->m_sb) &&
+	if (xfs_has_crc(mp) &&
 	    !uuid_equal(&dqb->dd_uuid, &mp->m_sb.sb_meta_uuid))
 		return __this_address;
 
@@ -128,7 +128,7 @@ xfs_dqblk_repair(
 	dqb->dd_diskdq.d_flags = type;
 	dqb->dd_diskdq.d_id = cpu_to_be32(id);
 
-	if (xfs_sb_version_hascrc(&mp->m_sb)) {
+	if (xfs_has_crc(mp)) {
 		uuid_copy(&dqb->dd_uuid, &mp->m_sb.sb_meta_uuid);
 		xfs_update_cksum((char *)dqb, sizeof(struct xfs_dqblk),
 				 XFS_DQUOT_CRC_OFF);
@@ -147,7 +147,7 @@ xfs_dquot_buf_verify_crc(
 	int			ndquots;
 	int			i;
 
-	if (!xfs_sb_version_hascrc(&mp->m_sb))
+	if (!xfs_has_crc(mp))
 		return true;
 
 	/*
diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
index c7b5a43af910..e21c39b13890 100644
--- a/fs/xfs/libxfs/xfs_format.h
+++ b/fs/xfs/libxfs/xfs_format.h
@@ -357,7 +357,7 @@ static inline bool xfs_sb_version_haslogv2(struct xfs_sb *sbp)
 	       (sbp->sb_versionnum & XFS_SB_VERSION_LOGV2BIT);
 }
 
-static inline bool xfs_sb_version_hasextflgbit(struct xfs_sb *sbp)
+static inline bool xfs_sb_version_hasextflg(struct xfs_sb *sbp)
 {
 	return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 ||
 	       (sbp->sb_versionnum & XFS_SB_VERSION_EXTFLGBIT);
@@ -409,7 +409,7 @@ static inline void xfs_sb_version_removeattr2(struct xfs_sb *sbp)
 		sbp->sb_versionnum &= ~XFS_SB_VERSION_MOREBITSBIT;
 }
 
-static inline bool xfs_sb_version_hasprojid32bit(struct xfs_sb *sbp)
+static inline bool xfs_sb_version_hasprojid32(struct xfs_sb *sbp)
 {
 	return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) ||
 	       (xfs_sb_version_hasmorebits(sbp) &&
@@ -501,7 +501,7 @@ static inline bool xfs_sb_version_hascrc(struct xfs_sb *sbp)
 	return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5;
 }
 
-static inline bool xfs_sb_version_has_pquotino(struct xfs_sb *sbp)
+static inline bool xfs_sb_version_haspquotino(struct xfs_sb *sbp)
 {
 	return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5;
 }
@@ -790,7 +790,7 @@ typedef struct xfs_agi {
 #define	XFS_BUF_TO_AGFL(bp)	((xfs_agfl_t *)((bp)->b_addr))
 
 #define XFS_BUF_TO_AGFL_BNO(mp, bp) \
-	(xfs_sb_version_hascrc(&((mp)->m_sb)) ? \
+	(xfs_has_crc(((mp))) ? \
 		&(XFS_BUF_TO_AGFL(bp)->agfl_bno[0]) : \
 		(__be32 *)(bp)->b_addr)
 
@@ -1208,7 +1208,7 @@ struct xfs_dsymlink_hdr {
 #define XFS_SYMLINK_MAPS 3
 
 #define XFS_SYMLINK_BUF_SPACE(mp, bufsize)	\
-	((bufsize) - (xfs_sb_version_hascrc(&(mp)->m_sb) ? \
+	((bufsize) - (xfs_has_crc((mp)) ? \
 			sizeof(struct xfs_dsymlink_hdr) : 0))
 
 
@@ -1440,7 +1440,7 @@ struct xfs_rmap_key {
 typedef __be32 xfs_rmap_ptr_t;
 
 #define	XFS_RMAP_BLOCK(mp) \
-	(xfs_sb_version_hasfinobt(&((mp)->m_sb)) ? \
+	(xfs_has_finobt(((mp))) ? \
 	 XFS_FIBT_BLOCK(mp) + 1 : \
 	 XFS_IBT_BLOCK(mp) + 1)
 
@@ -1665,7 +1665,7 @@ struct xfs_acl {
  * limited only by the maximum size of the xattr that stores the information.
  */
 #define XFS_ACL_MAX_ENTRIES(mp)	\
-	(xfs_sb_version_hascrc(&mp->m_sb) \
+	(xfs_has_crc(mp) \
 		?  (XFS_XATTR_SIZE_MAX - sizeof(struct xfs_acl)) / \
 						sizeof(struct xfs_acl_entry) \
 		: 25)
diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c
index a8f6db735d5d..8d23491badb7 100644
--- a/fs/xfs/libxfs/xfs_ialloc.c
+++ b/fs/xfs/libxfs/xfs_ialloc.c
@@ -39,7 +39,7 @@ int
 xfs_ialloc_cluster_alignment(
 	struct xfs_mount	*mp)
 {
-	if (xfs_sb_version_hasalign(&mp->m_sb) &&
+	if (xfs_has_align(mp) &&
 	    mp->m_sb.sb_inoalignmt >= xfs_icluster_size_fsb(mp))
 		return mp->m_sb.sb_inoalignmt;
 	return 1;
@@ -75,7 +75,7 @@ xfs_inobt_update(
 	union xfs_btree_rec	rec;
 
 	rec.inobt.ir_startino = cpu_to_be32(irec->ir_startino);
-	if (xfs_sb_version_hassparseinodes(&cur->bc_mp->m_sb)) {
+	if (xfs_has_sparseinodes(cur->bc_mp)) {
 		rec.inobt.ir_u.sp.ir_holemask = cpu_to_be16(irec->ir_holemask);
 		rec.inobt.ir_u.sp.ir_count = irec->ir_count;
 		rec.inobt.ir_u.sp.ir_freecount = irec->ir_freecount;
@@ -95,7 +95,7 @@ xfs_inobt_btrec_to_irec(
 	struct xfs_inobt_rec_incore	*irec)
 {
 	irec->ir_startino = be32_to_cpu(rec->inobt.ir_startino);
-	if (xfs_sb_version_hassparseinodes(&mp->m_sb)) {
+	if (xfs_has_sparseinodes(mp)) {
 		irec->ir_holemask = be16_to_cpu(rec->inobt.ir_u.sp.ir_holemask);
 		irec->ir_count = rec->inobt.ir_u.sp.ir_count;
 		irec->ir_freecount = rec->inobt.ir_u.sp.ir_freecount;
@@ -322,7 +322,7 @@ xfs_ialloc_inode_init(
 	 * That means for v3 inode we log the entire buffer rather than just the
 	 * inode cores.
 	 */
-	if (xfs_sb_version_hascrc(&mp->m_sb)) {
+	if (xfs_has_crc(mp)) {
 		version = 3;
 		ino = XFS_AGINO_TO_INO(mp, agno,
 				       XFS_OFFBNO_TO_AGINO(mp, agbno, 0));
@@ -645,7 +645,7 @@ xfs_ialloc_ag_alloc(
 
 #ifdef DEBUG
 	/* randomly do sparse inode allocations */
-	if (xfs_sb_version_hassparseinodes(&tp->t_mountp->m_sb) &&
+	if (xfs_has_sparseinodes(tp->t_mountp) &&
 	    args.mp->m_ialloc_min_blks < args.mp->m_ialloc_blks)
 		do_sparse = prandom_u32() & 1;
 #endif
@@ -765,7 +765,7 @@ xfs_ialloc_ag_alloc(
 	 * Finally, try a sparse allocation if the filesystem supports it and
 	 * the sparse allocation length is smaller than a full chunk.
 	 */
-	if (xfs_sb_version_hassparseinodes(&args.mp->m_sb) &&
+	if (xfs_has_sparseinodes(args.mp) &&
 	    args.mp->m_ialloc_min_blks < args.mp->m_ialloc_blks &&
 	    args.fsbno == NULLFSBLOCK) {
 sparse_alloc:
@@ -868,7 +868,7 @@ xfs_ialloc_ag_alloc(
 		 * from the previous call. Set merge false to replace any
 		 * existing record with this one.
 		 */
-		if (xfs_sb_version_hasfinobt(&args.mp->m_sb)) {
+		if (xfs_has_finobt(args.mp)) {
 			error = xfs_inobt_insert_sprec(args.mp, tp, agbp,
 						       XFS_BTNUM_FINO, &rec,
 						       false);
@@ -882,7 +882,7 @@ xfs_ialloc_ag_alloc(
 		if (error)
 			return error;
 
-		if (xfs_sb_version_hasfinobt(&args.mp->m_sb)) {
+		if (xfs_has_finobt(args.mp)) {
 			error = xfs_inobt_insert(args.mp, tp, agbp, newino,
 						 newlen, XFS_BTNUM_FINO);
 			if (error)
@@ -1572,7 +1572,7 @@ xfs_dialloc_ag(
 	int				offset;
 	int				i;
 
-	if (!xfs_sb_version_hasfinobt(&mp->m_sb))
+	if (!xfs_has_finobt(mp))
 		return xfs_dialloc_ag_inobt(tp, agbp, parent, inop);
 
 	pag = xfs_perag_get(mp, agno);
@@ -2206,7 +2206,7 @@ xfs_difree(
 	/*
 	 * Fix up the free inode btree.
 	 */
-	if (xfs_sb_version_hasfinobt(&mp->m_sb)) {
+	if (xfs_has_finobt(mp)) {
 		error = xfs_difree_finobt(mp, tp, agbp, agino, &rec);
 		if (error)
 			goto error0;
@@ -2503,7 +2503,7 @@ xfs_agi_verify(
 	struct xfs_agi	*agi = XFS_BUF_TO_AGI(bp);
 	int		i;
 
-	if (xfs_sb_version_hascrc(&mp->m_sb)) {
+	if (xfs_has_crc(mp)) {
 		if (!uuid_equal(&agi->agi_uuid, &mp->m_sb.sb_meta_uuid))
 			return __this_address;
 		if (!xfs_log_check_lsn(mp,
@@ -2523,7 +2523,7 @@ xfs_agi_verify(
 	    be32_to_cpu(agi->agi_level) > XFS_BTREE_MAXLEVELS)
 		return __this_address;
 
-	if (xfs_sb_version_hasfinobt(&mp->m_sb) &&
+	if (xfs_has_finobt(mp) &&
 	    (be32_to_cpu(agi->agi_free_level) < 1 ||
 	     be32_to_cpu(agi->agi_free_level) > XFS_BTREE_MAXLEVELS))
 		return __this_address;
@@ -2554,7 +2554,7 @@ xfs_agi_read_verify(
 	struct xfs_mount *mp = bp->b_target->bt_mount;
 	xfs_failaddr_t	fa;
 
-	if (xfs_sb_version_hascrc(&mp->m_sb) &&
+	if (xfs_has_crc(mp) &&
 	    !xfs_buf_verify_cksum(bp, XFS_AGI_CRC_OFF))
 		xfs_verifier_error(bp, -EFSBADCRC, __this_address);
 	else {
@@ -2578,7 +2578,7 @@ xfs_agi_write_verify(
 		return;
 	}
 
-	if (!xfs_sb_version_hascrc(&mp->m_sb))
+	if (!xfs_has_crc(mp))
 		return;
 
 	if (bip)
diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c
index 86c50208a143..11af5a89c297 100644
--- a/fs/xfs/libxfs/xfs_ialloc_btree.c
+++ b/fs/xfs/libxfs/xfs_ialloc_btree.c
@@ -196,7 +196,7 @@ xfs_inobt_init_rec_from_cur(
 	union xfs_btree_rec	*rec)
 {
 	rec->inobt.ir_startino = cpu_to_be32(cur->bc_rec.i.ir_startino);
-	if (xfs_sb_version_hassparseinodes(&cur->bc_mp->m_sb)) {
+	if (xfs_has_sparseinodes(cur->bc_mp)) {
 		rec->inobt.ir_u.sp.ir_holemask =
 					cpu_to_be16(cur->bc_rec.i.ir_holemask);
 		rec->inobt.ir_u.sp.ir_count = cur->bc_rec.i.ir_count;
@@ -429,7 +429,7 @@ xfs_inobt_init_cursor(
 
 	cur->bc_blocklog = mp->m_sb.sb_blocklog;
 
-	if (xfs_sb_version_hascrc(&mp->m_sb))
+	if (xfs_has_crc(mp))
 		cur->bc_flags |= XFS_BTREE_CRC_BLOCKS;
 
 	cur->bc_private.a.agbp = agbp;
@@ -587,7 +587,7 @@ xfs_finobt_calc_reserves(
 	xfs_extlen_t		tree_len = 0;
 	int			error;
 
-	if (!xfs_sb_version_hasfinobt(&mp->m_sb))
+	if (!xfs_has_finobt(mp))
 		return 0;
 
 	error = xfs_inobt_count_blocks(mp, tp, agno, XFS_BTNUM_FINO, &tree_len);
diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.h b/fs/xfs/libxfs/xfs_ialloc_btree.h
index ebdd0c6b8766..f6f2123e7ca7 100644
--- a/fs/xfs/libxfs/xfs_ialloc_btree.h
+++ b/fs/xfs/libxfs/xfs_ialloc_btree.h
@@ -18,7 +18,7 @@ struct xfs_mount;
  * Btree block header size depends on a superblock flag.
  */
 #define XFS_INOBT_BLOCK_LEN(mp) \
-	(xfs_sb_version_hascrc(&((mp)->m_sb)) ? \
+	(xfs_has_crc(((mp))) ? \
 		XFS_BTREE_SBLOCK_CRC_LEN : XFS_BTREE_SBLOCK_LEN)
 
 /*
diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c
index 30d1d60f1d46..6eb9f967d087 100644
--- a/fs/xfs/libxfs/xfs_inode_buf.c
+++ b/fs/xfs/libxfs/xfs_inode_buf.c
@@ -54,7 +54,7 @@ xfs_dinode_good_version(
 	struct xfs_mount *mp,
 	__u8		version)
 {
-	if (xfs_sb_version_hascrc(&mp->m_sb))
+	if (xfs_has_crc(mp))
 		return version == 3;
 
 	return version == 1 || version == 2;
@@ -432,7 +432,7 @@ xfs_dinode_verify(
 
 	/* Verify v3 integrity information first */
 	if (dip->di_version >= 3) {
-		if (!xfs_sb_version_hascrc(&mp->m_sb))
+		if (!xfs_has_crc(mp))
 			return __this_address;
 		if (!xfs_verify_cksum((char *)dip, mp->m_sb.sb_inodesize,
 				      XFS_DINODE_CRC_OFF))
@@ -529,7 +529,7 @@ xfs_dinode_verify(
 
 	/* don't allow reflink/cowextsize if we don't have reflink */
 	if ((flags2 & (XFS_DIFLAG2_REFLINK | XFS_DIFLAG2_COWEXTSIZE)) &&
-	     !xfs_sb_version_hasreflink(&mp->m_sb))
+	     !xfs_has_reflink(mp))
 		return __this_address;
 
 	/* only regular files get reflink */
@@ -563,7 +563,7 @@ xfs_dinode_calc_crc(
 	if (dip->di_version < 3)
 		return;
 
-	ASSERT(xfs_sb_version_hascrc(&mp->m_sb));
+	ASSERT(xfs_has_crc(mp));
 	crc = xfs_start_cksum_update((char *)dip, mp->m_sb.sb_inodesize,
 			      XFS_DINODE_CRC_OFF);
 	dip->di_crc = xfs_end_cksum(crc);
@@ -602,7 +602,7 @@ xfs_iread(
 
 	/* shortcut IO on inode allocation if possible */
 	if ((iget_flags & XFS_IGET_CREATE) &&
-	    xfs_sb_version_hascrc(&mp->m_sb) &&
+	    xfs_has_crc(mp) &&
 	    !(mp->m_flags & XFS_MOUNT_IKEEP)) {
 		/* initialise the on-disk inode core */
 		memset(&ip->i_d, 0, sizeof(ip->i_d));
@@ -769,7 +769,7 @@ xfs_inode_validate_cowextsize(
 	hint_flag = (flags2 & XFS_DIFLAG2_COWEXTSIZE);
 	cowextsize_bytes = XFS_FSB_TO_B(mp, cowextsize);
 
-	if (hint_flag && !xfs_sb_version_hasreflink(&mp->m_sb))
+	if (hint_flag && !xfs_has_reflink(mp))
 		return __this_address;
 
 	if (hint_flag && !(S_ISDIR(mode) || S_ISREG(mode)))
diff --git a/fs/xfs/libxfs/xfs_log_format.h b/fs/xfs/libxfs/xfs_log_format.h
index e5f97c69b320..2654741bcff0 100644
--- a/fs/xfs/libxfs/xfs_log_format.h
+++ b/fs/xfs/libxfs/xfs_log_format.h
@@ -44,10 +44,10 @@ typedef uint32_t xlog_tid_t;
 #define XFS_MIN_LOG_FACTOR	3
 
 #define XLOG_REC_SHIFT(log) \
-	BTOBB(1 << (xfs_sb_version_haslogv2(&log->l_mp->m_sb) ? \
+	BTOBB(1 << (xfs_has_logv2(log->l_mp) ? \
 	 XLOG_MAX_RECORD_BSHIFT : XLOG_BIG_RECORD_BSHIFT))
 #define XLOG_TOTAL_REC_SHIFT(log) \
-	BTOBB(XLOG_MAX_ICLOGS << (xfs_sb_version_haslogv2(&log->l_mp->m_sb) ? \
+	BTOBB(XLOG_MAX_ICLOGS << (xfs_has_logv2(log->l_mp) ? \
 	 XLOG_MAX_RECORD_BSHIFT : XLOG_BIG_RECORD_BSHIFT))
 
 /* get lsn fields */
diff --git a/fs/xfs/libxfs/xfs_log_rlimit.c b/fs/xfs/libxfs/xfs_log_rlimit.c
index 1b542ec11d5d..5837ea72eaee 100644
--- a/fs/xfs/libxfs/xfs_log_rlimit.c
+++ b/fs/xfs/libxfs/xfs_log_rlimit.c
@@ -94,7 +94,7 @@ xfs_log_calc_minimum_size(
 	if (tres.tr_logcount > 1)
 		max_logres *= tres.tr_logcount;
 
-	if (xfs_sb_version_haslogv2(&mp->m_sb) && mp->m_sb.sb_logsunit > 1)
+	if (xfs_has_logv2(mp) && mp->m_sb.sb_logsunit > 1)
 		lsunit = BTOBB(mp->m_sb.sb_logsunit);
 
 	/*
diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c
index 542aa1475b5f..00e6d51f157a 100644
--- a/fs/xfs/libxfs/xfs_refcount.c
+++ b/fs/xfs/libxfs/xfs_refcount.c
@@ -1209,7 +1209,7 @@ xfs_refcount_increase_extent(
 	struct xfs_trans		*tp,
 	struct xfs_bmbt_irec		*PREV)
 {
-	if (!xfs_sb_version_hasreflink(&tp->t_mountp->m_sb))
+	if (!xfs_has_reflink(tp->t_mountp))
 		return 0;
 
 	return __xfs_refcount_add(tp, XFS_REFCOUNT_INCREASE,
@@ -1224,7 +1224,7 @@ xfs_refcount_decrease_extent(
 	struct xfs_trans		*tp,
 	struct xfs_bmbt_irec		*PREV)
 {
-	if (!xfs_sb_version_hasreflink(&tp->t_mountp->m_sb))
+	if (!xfs_has_reflink(tp->t_mountp))
 		return 0;
 
 	return __xfs_refcount_add(tp, XFS_REFCOUNT_DECREASE,
@@ -1552,7 +1552,7 @@ xfs_refcount_alloc_cow_extent(
 	struct xfs_mount		*mp = tp->t_mountp;
 	int				error;
 
-	if (!xfs_sb_version_hasreflink(&mp->m_sb))
+	if (!xfs_has_reflink(mp))
 		return 0;
 
 	error = __xfs_refcount_add(tp, XFS_REFCOUNT_ALLOC_COW, fsb, len);
@@ -1574,7 +1574,7 @@ xfs_refcount_free_cow_extent(
 	struct xfs_mount		*mp = tp->t_mountp;
 	int				error;
 
-	if (!xfs_sb_version_hasreflink(&mp->m_sb))
+	if (!xfs_has_reflink(mp))
 		return 0;
 
 	/* Remove rmap entry */
diff --git a/fs/xfs/libxfs/xfs_refcount_btree.c b/fs/xfs/libxfs/xfs_refcount_btree.c
index 1aaa01c97517..d409e7c91083 100644
--- a/fs/xfs/libxfs/xfs_refcount_btree.c
+++ b/fs/xfs/libxfs/xfs_refcount_btree.c
@@ -214,7 +214,7 @@ xfs_refcountbt_verify(
 	if (block->bb_magic != cpu_to_be32(XFS_REFC_CRC_MAGIC))
 		return __this_address;
 
-	if (!xfs_sb_version_hasreflink(&mp->m_sb))
+	if (!xfs_has_reflink(mp))
 		return __this_address;
 	fa = xfs_btree_sblock_v5hdr_verify(bp);
 	if (fa)
@@ -415,7 +415,7 @@ xfs_refcountbt_calc_reserves(
 	xfs_extlen_t		tree_len;
 	int			error;
 
-	if (!xfs_sb_version_hasreflink(&mp->m_sb))
+	if (!xfs_has_reflink(mp))
 		return 0;
 
 
diff --git a/fs/xfs/libxfs/xfs_rmap.c b/fs/xfs/libxfs/xfs_rmap.c
index 245af452840e..bba475aa3424 100644
--- a/fs/xfs/libxfs/xfs_rmap.c
+++ b/fs/xfs/libxfs/xfs_rmap.c
@@ -664,7 +664,7 @@ xfs_rmap_free(
 	struct xfs_btree_cur	*cur;
 	int			error;
 
-	if (!xfs_sb_version_hasrmapbt(&mp->m_sb))
+	if (!xfs_has_rmapbt(mp))
 		return 0;
 
 	cur = xfs_rmapbt_init_cursor(mp, tp, agbp, agno);
@@ -901,7 +901,7 @@ xfs_rmap_alloc(
 	struct xfs_btree_cur	*cur;
 	int			error;
 
-	if (!xfs_sb_version_hasrmapbt(&mp->m_sb))
+	if (!xfs_has_rmapbt(mp))
 		return 0;
 
 	cur = xfs_rmapbt_init_cursor(mp, tp, agbp, agno);
@@ -2268,7 +2268,7 @@ xfs_rmap_update_is_needed(
 	struct xfs_mount	*mp,
 	int			whichfork)
 {
-	return xfs_sb_version_hasrmapbt(&mp->m_sb) && whichfork != XFS_COW_FORK;
+	return xfs_has_rmapbt(mp) && whichfork != XFS_COW_FORK;
 }
 
 /*
diff --git a/fs/xfs/libxfs/xfs_rmap_btree.c b/fs/xfs/libxfs/xfs_rmap_btree.c
index f79cf040d745..f3c6bab96429 100644
--- a/fs/xfs/libxfs/xfs_rmap_btree.c
+++ b/fs/xfs/libxfs/xfs_rmap_btree.c
@@ -313,7 +313,7 @@ xfs_rmapbt_verify(
 	if (block->bb_magic != cpu_to_be32(XFS_RMAP_CRC_MAGIC))
 		return __this_address;
 
-	if (!xfs_sb_version_hasrmapbt(&mp->m_sb))
+	if (!xfs_has_rmapbt(mp))
 		return __this_address;
 	fa = xfs_btree_sblock_v5hdr_verify(bp);
 	if (fa)
@@ -517,7 +517,7 @@ xfs_rmapbt_compute_maxlevels(
 	 * disallow reflinking when less than 10% of the per-AG metadata
 	 * block reservation since the fallback is a regular file copy.
 	 */
-	if (xfs_sb_version_hasreflink(&mp->m_sb))
+	if (xfs_has_reflink(mp))
 		mp->m_rmap_maxlevels = XFS_BTREE_MAXLEVELS;
 	else
 		mp->m_rmap_maxlevels = xfs_btree_compute_maxlevels(
@@ -565,7 +565,7 @@ xfs_rmapbt_calc_reserves(
 	xfs_extlen_t		tree_len;
 	int			error;
 
-	if (!xfs_sb_version_hasrmapbt(&mp->m_sb))
+	if (!xfs_has_rmapbt(mp))
 		return 0;
 
 	error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp);
diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c
index f9c8e1e9d8e3..5dcb9005173c 100644
--- a/fs/xfs/libxfs/xfs_sb.c
+++ b/fs/xfs/libxfs/xfs_sb.c
@@ -299,7 +299,7 @@ xfs_validate_sb_common(
 		return -EWRONGFS;
 	}
 
-	if (xfs_sb_version_has_pquotino(sbp)) {
+	if (xfs_sb_version_haspquotino(sbp)) {
 		if (sbp->sb_qflags & (XFS_OQUOTA_ENFD | XFS_OQUOTA_CHKD)) {
 			xfs_notice(mp,
 			   "Version 5 of Super block has XFS_OQUOTA bits.");
@@ -409,7 +409,7 @@ xfs_validate_sb_common(
 	}
 
 
-	if (xfs_sb_version_hascrc(&mp->m_sb) &&
+	if (xfs_has_crc(mp) &&
 	    sbp->sb_blocksize < XFS_MIN_CRC_BLOCKSIZE) {
 		xfs_notice(mp, "v5 SB sanity check failed");
 		return -EFSCORRUPTED;
@@ -485,7 +485,7 @@ xfs_sb_quota_from_disk(struct xfs_sb *sbp)
 	 * We need to do these manipilations only if we are working
 	 * with an older version of on-disk superblock.
 	 */
-	if (xfs_sb_version_has_pquotino(sbp))
+	if (xfs_sb_version_haspquotino(sbp))
 		return;
 
 	if (sbp->sb_qflags & XFS_OQUOTA_ENFD)
@@ -603,7 +603,7 @@ xfs_sb_quota_to_disk(
 	uint16_t	qflags = from->sb_qflags;
 
 	to->sb_uquotino = cpu_to_be64(from->sb_uquotino);
-	if (xfs_sb_version_has_pquotino(from)) {
+	if (xfs_sb_version_haspquotino(from)) {
 		to->sb_qflags = cpu_to_be16(from->sb_qflags);
 		to->sb_gquotino = cpu_to_be64(from->sb_gquotino);
 		to->sb_pquotino = cpu_to_be64(from->sb_pquotino);
@@ -761,7 +761,7 @@ xfs_sb_read_verify(
 		if (!xfs_buf_verify_cksum(bp, XFS_SB_CRC_OFF)) {
 			/* Only fail bad secondaries on a known V5 filesystem */
 			if (bp->b_bn == XFS_SB_DADDR ||
-			    xfs_sb_version_hascrc(&mp->m_sb)) {
+			    xfs_has_crc(mp)) {
 				error = -EFSBADCRC;
 				goto out_error;
 			}
@@ -827,7 +827,7 @@ xfs_sb_write_verify(
 	if (error)
 		goto out_error;
 
-	if (!xfs_sb_version_hascrc(&mp->m_sb))
+	if (!xfs_has_crc(mp))
 		return;
 
 	if (bip)
@@ -1185,7 +1185,7 @@ xfs_fs_geometry(
 		geo->flags |= XFS_FSOP_GEOM_FLAGS_IALIGN;
 	if (xfs_sb_version_hasdalign(sbp))
 		geo->flags |= XFS_FSOP_GEOM_FLAGS_DALIGN;
-	if (xfs_sb_version_hasextflgbit(sbp))
+	if (xfs_sb_version_hasextflg(sbp))
 		geo->flags |= XFS_FSOP_GEOM_FLAGS_EXTFLG;
 	if (xfs_sb_version_hassector(sbp))
 		geo->flags |= XFS_FSOP_GEOM_FLAGS_SECTOR;
@@ -1195,7 +1195,7 @@ xfs_fs_geometry(
 		geo->flags |= XFS_FSOP_GEOM_FLAGS_LAZYSB;
 	if (xfs_sb_version_hasattr2(sbp))
 		geo->flags |= XFS_FSOP_GEOM_FLAGS_ATTR2;
-	if (xfs_sb_version_hasprojid32bit(sbp))
+	if (xfs_sb_version_hasprojid32(sbp))
 		geo->flags |= XFS_FSOP_GEOM_FLAGS_PROJID32;
 	if (xfs_sb_version_hascrc(sbp))
 		geo->flags |= XFS_FSOP_GEOM_FLAGS_V5SB;
diff --git a/fs/xfs/libxfs/xfs_symlink_remote.c b/fs/xfs/libxfs/xfs_symlink_remote.c
index 95374ab2dee7..a9377ceedaeb 100644
--- a/fs/xfs/libxfs/xfs_symlink_remote.c
+++ b/fs/xfs/libxfs/xfs_symlink_remote.c
@@ -46,7 +46,7 @@ xfs_symlink_hdr_set(
 {
 	struct xfs_dsymlink_hdr	*dsl = bp->b_addr;
 
-	if (!xfs_sb_version_hascrc(&mp->m_sb))
+	if (!xfs_has_crc(mp))
 		return 0;
 
 	memset(dsl, 0, sizeof(struct xfs_dsymlink_hdr));
@@ -93,7 +93,7 @@ xfs_symlink_verify(
 	struct xfs_mount	*mp = bp->b_target->bt_mount;
 	struct xfs_dsymlink_hdr	*dsl = bp->b_addr;
 
-	if (!xfs_sb_version_hascrc(&mp->m_sb))
+	if (!xfs_has_crc(mp))
 		return __this_address;
 	if (dsl->sl_magic != cpu_to_be32(XFS_SYMLINK_MAGIC))
 		return __this_address;
@@ -120,7 +120,7 @@ xfs_symlink_read_verify(
 	xfs_failaddr_t	fa;
 
 	/* no verification of non-crc buffers */
-	if (!xfs_sb_version_hascrc(&mp->m_sb))
+	if (!xfs_has_crc(mp))
 		return;
 
 	if (!xfs_buf_verify_cksum(bp, XFS_SYMLINK_CRC_OFF))
@@ -141,7 +141,7 @@ xfs_symlink_write_verify(
 	xfs_failaddr_t		fa;
 
 	/* no verification of non-crc buffers */
-	if (!xfs_sb_version_hascrc(&mp->m_sb))
+	if (!xfs_has_crc(mp))
 		return;
 
 	fa = xfs_symlink_verify(bp);
@@ -176,7 +176,7 @@ xfs_symlink_local_to_remote(
 
 	xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SYMLINK_BUF);
 
-	if (!xfs_sb_version_hascrc(&mp->m_sb)) {
+	if (!xfs_has_crc(mp)) {
 		bp->b_ops = NULL;
 		memcpy(bp->b_addr, ifp->if_u1.if_data, ifp->if_bytes);
 		xfs_trans_log_buf(tp, bp, 0, ifp->if_bytes - 1);
diff --git a/fs/xfs/libxfs/xfs_trans_resv.c b/fs/xfs/libxfs/xfs_trans_resv.c
index f99a7aefe418..a9af5d9962fe 100644
--- a/fs/xfs/libxfs/xfs_trans_resv.c
+++ b/fs/xfs/libxfs/xfs_trans_resv.c
@@ -73,9 +73,9 @@ xfs_allocfree_log_count(
 	uint		blocks;
 
 	blocks = num_ops * 2 * (2 * mp->m_ag_maxlevels - 1);
-	if (xfs_sb_version_hasrmapbt(&mp->m_sb))
+	if (xfs_has_rmapbt(mp))
 		blocks += num_ops * (2 * mp->m_rmap_maxlevels - 1);
-	if (xfs_sb_version_hasreflink(&mp->m_sb))
+	if (xfs_has_reflink(mp))
 		blocks += num_ops * (2 * mp->m_refc_maxlevels - 1);
 
 	return blocks;
@@ -156,7 +156,7 @@ STATIC uint
 xfs_calc_finobt_res(
 	struct xfs_mount	*mp)
 {
-	if (!xfs_sb_version_hasfinobt(&mp->m_sb))
+	if (!xfs_has_finobt(mp))
 		return 0;
 
 	return xfs_calc_inobt_res(mp);
@@ -188,7 +188,7 @@ xfs_calc_inode_chunk_res(
 			       XFS_FSB_TO_B(mp, 1));
 	if (alloc) {
 		/* icreate tx uses ordered buffers */
-		if (xfs_sb_version_hascrc(&mp->m_sb))
+		if (xfs_has_crc(mp))
 			return res;
 		size = XFS_FSB_TO_B(mp, 1);
 	}
@@ -785,14 +785,14 @@ xfs_trans_resv_calc(
 	 * require a permanent reservation on space.
 	 */
 	resp->tr_write.tr_logres = xfs_calc_write_reservation(mp);
-	if (xfs_sb_version_hasreflink(&mp->m_sb))
+	if (xfs_has_reflink(mp))
 		resp->tr_write.tr_logcount = XFS_WRITE_LOG_COUNT_REFLINK;
 	else
 		resp->tr_write.tr_logcount = XFS_WRITE_LOG_COUNT;
 	resp->tr_write.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
 
 	resp->tr_itruncate.tr_logres = xfs_calc_itruncate_reservation(mp);
-	if (xfs_sb_version_hasreflink(&mp->m_sb))
+	if (xfs_has_reflink(mp))
 		resp->tr_itruncate.tr_logcount =
 				XFS_ITRUNCATE_LOG_COUNT_REFLINK;
 	else
@@ -853,7 +853,7 @@ xfs_trans_resv_calc(
 	resp->tr_growrtalloc.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
 
 	resp->tr_qm_dqalloc.tr_logres = xfs_calc_qm_dqalloc_reservation(mp);
-	if (xfs_sb_version_hasreflink(&mp->m_sb))
+	if (xfs_has_reflink(mp))
 		resp->tr_qm_dqalloc.tr_logcount = XFS_WRITE_LOG_COUNT_REFLINK;
 	else
 		resp->tr_qm_dqalloc.tr_logcount = XFS_WRITE_LOG_COUNT;
diff --git a/fs/xfs/libxfs/xfs_trans_space.h b/fs/xfs/libxfs/xfs_trans_space.h
index a62fb950bef1..83d10dc5b1cc 100644
--- a/fs/xfs/libxfs/xfs_trans_space.h
+++ b/fs/xfs/libxfs/xfs_trans_space.h
@@ -57,7 +57,7 @@
 	XFS_DAREMOVE_SPACE_RES(mp, XFS_DATA_FORK)
 #define	XFS_IALLOC_SPACE_RES(mp)	\
 	((mp)->m_ialloc_blks + \
-	 (xfs_sb_version_hasfinobt(&mp->m_sb) ? 2 : 1 * \
+	 (xfs_has_finobt(mp) ? 2 : 1 * \
 	  ((mp)->m_in_maxlevels - 1)))
 
 /*
@@ -94,7 +94,7 @@
 #define	XFS_SYMLINK_SPACE_RES(mp,nl,b)	\
 	(XFS_IALLOC_SPACE_RES(mp) + XFS_DIRENTER_SPACE_RES(mp,nl) + (b))
 #define XFS_IFREE_SPACE_RES(mp)		\
-	(xfs_sb_version_hasfinobt(&mp->m_sb) ? (mp)->m_in_maxlevels : 0)
+	(xfs_has_finobt(mp) ? (mp)->m_in_maxlevels : 0)
 
 
 #endif	/* __XFS_TRANS_SPACE_H__ */
diff --git a/fs/xfs/libxfs/xfs_types.c b/fs/xfs/libxfs/xfs_types.c
index 33a5ca346baf..a5b87f20248f 100644
--- a/fs/xfs/libxfs/xfs_types.c
+++ b/fs/xfs/libxfs/xfs_types.c
@@ -142,7 +142,7 @@ xfs_internal_inum(
 	xfs_ino_t		ino)
 {
 	return ino == mp->m_sb.sb_rbmino || ino == mp->m_sb.sb_rsumino ||
-		(xfs_sb_version_hasquota(&mp->m_sb) &&
+		(xfs_has_quota(mp) &&
 		 xfs_is_quota_inode(&mp->m_sb, ino));
 }
 
diff --git a/fs/xfs/scrub/agheader.c b/fs/xfs/scrub/agheader.c
index 3068a9382feb..9135a0ffe751 100644
--- a/fs/xfs/scrub/agheader.c
+++ b/fs/xfs/scrub/agheader.c
@@ -280,7 +280,7 @@ xchk_superblock(
 	    (cpu_to_be32(mp->m_sb.sb_features2) & features_mask))
 		xchk_block_set_corrupt(sc, bp);
 
-	if (!xfs_sb_version_hascrc(&mp->m_sb)) {
+	if (!xfs_has_crc(mp)) {
 		/* all v5 fields must be zero */
 		if (memchr_inv(&sb->sb_features_compat, 0,
 				sizeof(struct xfs_dsb) -
@@ -331,7 +331,7 @@ xchk_superblock(
 		/* Don't care about sb_lsn */
 	}
 
-	if (xfs_sb_version_hasmetauuid(&mp->m_sb)) {
+	if (xfs_has_metauuid(mp)) {
 		/* The metadata UUID must be the same for all supers */
 		if (!uuid_equal(&sb->sb_meta_uuid, &mp->m_sb.sb_meta_uuid))
 			xchk_block_set_corrupt(sc, bp);
@@ -441,7 +441,7 @@ xchk_agf_xref_btreeblks(
 	 * No rmap cursor; we can't xref if we have the rmapbt feature.
 	 * We also can't do it if we're missing the free space btree cursors.
 	 */
-	if ((xfs_sb_version_hasrmapbt(&mp->m_sb) && !sc->sa.rmap_cur) ||
+	if ((xfs_has_rmapbt(mp) && !sc->sa.rmap_cur) ||
 	    !sc->sa.bno_cur || !sc->sa.cnt_cur)
 		return;
 
@@ -559,7 +559,7 @@ xchk_agf(
 	if (level <= 0 || level > XFS_BTREE_MAXLEVELS)
 		xchk_block_set_corrupt(sc, sc->sa.agf_bp);
 
-	if (xfs_sb_version_hasrmapbt(&mp->m_sb)) {
+	if (xfs_has_rmapbt(mp)) {
 		agbno = be32_to_cpu(agf->agf_roots[XFS_BTNUM_RMAP]);
 		if (!xfs_verify_agbno(mp, agno, agbno))
 			xchk_block_set_corrupt(sc, sc->sa.agf_bp);
@@ -569,7 +569,7 @@ xchk_agf(
 			xchk_block_set_corrupt(sc, sc->sa.agf_bp);
 	}
 
-	if (xfs_sb_version_hasreflink(&mp->m_sb)) {
+	if (xfs_has_reflink(mp)) {
 		agbno = be32_to_cpu(agf->agf_refcount_root);
 		if (!xfs_verify_agbno(mp, agno, agbno))
 			xchk_block_set_corrupt(sc, sc->sa.agf_bp);
@@ -856,7 +856,7 @@ xchk_agi(
 	if (level <= 0 || level > XFS_BTREE_MAXLEVELS)
 		xchk_block_set_corrupt(sc, sc->sa.agi_bp);
 
-	if (xfs_sb_version_hasfinobt(&mp->m_sb)) {
+	if (xfs_has_finobt(mp)) {
 		agbno = be32_to_cpu(agi->agi_free_root);
 		if (!xfs_verify_agbno(mp, agno, agbno))
 			xchk_block_set_corrupt(sc, sc->sa.agi_bp);
diff --git a/fs/xfs/scrub/agheader_repair.c b/fs/xfs/scrub/agheader_repair.c
index f7568a4b5fe5..5ba094312cb0 100644
--- a/fs/xfs/scrub/agheader_repair.c
+++ b/fs/xfs/scrub/agheader_repair.c
@@ -168,7 +168,7 @@ xrep_agf_find_btrees(
 		return -EFSCORRUPTED;
 
 	/* We must find the refcountbt root if that feature is enabled. */
-	if (xfs_sb_version_hasreflink(&sc->mp->m_sb) &&
+	if (xfs_has_reflink(sc->mp) &&
 	    !xrep_check_btree_root(sc, &fab[XREP_AGF_REFCOUNTBT]))
 		return -EFSCORRUPTED;
 
@@ -197,7 +197,7 @@ xrep_agf_init_header(
 	agf->agf_flfirst = old_agf->agf_flfirst;
 	agf->agf_fllast = old_agf->agf_fllast;
 	agf->agf_flcount = old_agf->agf_flcount;
-	if (xfs_sb_version_hascrc(&mp->m_sb))
+	if (xfs_has_crc(mp))
 		uuid_copy(&agf->agf_uuid, &mp->m_sb.sb_meta_uuid);
 
 	/* Mark the incore AGF data stale until we're done fixing things. */
@@ -227,7 +227,7 @@ xrep_agf_set_roots(
 	agf->agf_levels[XFS_BTNUM_RMAPi] =
 			cpu_to_be32(fab[XREP_AGF_RMAPBT].height);
 
-	if (xfs_sb_version_hasreflink(&sc->mp->m_sb)) {
+	if (xfs_has_reflink(sc->mp)) {
 		agf->agf_refcount_root =
 				cpu_to_be32(fab[XREP_AGF_REFCOUNTBT].root);
 		agf->agf_refcount_level =
@@ -284,7 +284,7 @@ xrep_agf_calc_from_btrees(
 	agf->agf_btreeblks = cpu_to_be32(btreeblks);
 
 	/* Update the AGF counters from the refcountbt. */
-	if (xfs_sb_version_hasreflink(&mp->m_sb)) {
+	if (xfs_has_reflink(mp)) {
 		cur = xfs_refcountbt_init_cursor(mp, sc->tp, agf_bp,
 				sc->sa.agno);
 		error = xfs_btree_count_blocks(cur, &blocks);
@@ -371,7 +371,7 @@ xrep_agf(
 	int				error;
 
 	/* We require the rmapbt to rebuild anything. */
-	if (!xfs_sb_version_hasrmapbt(&mp->m_sb))
+	if (!xfs_has_rmapbt(mp))
 		return -EOPNOTSUPP;
 
 	xchk_perag_get(sc->mp, &sc->sa);
@@ -655,7 +655,7 @@ xrep_agfl(
 	int			error;
 
 	/* We require the rmapbt to rebuild anything. */
-	if (!xfs_sb_version_hasrmapbt(&mp->m_sb))
+	if (!xfs_has_rmapbt(mp))
 		return -EOPNOTSUPP;
 
 	xchk_perag_get(sc->mp, &sc->sa);
@@ -758,7 +758,7 @@ xrep_agi_find_btrees(
 		return -EFSCORRUPTED;
 
 	/* We must find the finobt root if that feature is enabled. */
-	if (xfs_sb_version_hasfinobt(&mp->m_sb) &&
+	if (xfs_has_finobt(mp) &&
 	    !xrep_check_btree_root(sc, &fab[XREP_AGI_FINOBT]))
 		return -EFSCORRUPTED;
 
@@ -786,7 +786,7 @@ xrep_agi_init_header(
 	agi->agi_length = cpu_to_be32(xfs_ag_block_count(mp, sc->sa.agno));
 	agi->agi_newino = cpu_to_be32(NULLAGINO);
 	agi->agi_dirino = cpu_to_be32(NULLAGINO);
-	if (xfs_sb_version_hascrc(&mp->m_sb))
+	if (xfs_has_crc(mp))
 		uuid_copy(&agi->agi_uuid, &mp->m_sb.sb_meta_uuid);
 
 	/* We don't know how to fix the unlinked list yet. */
@@ -808,7 +808,7 @@ xrep_agi_set_roots(
 	agi->agi_root = cpu_to_be32(fab[XREP_AGI_INOBT].root);
 	agi->agi_level = cpu_to_be32(fab[XREP_AGI_INOBT].height);
 
-	if (xfs_sb_version_hasfinobt(&sc->mp->m_sb)) {
+	if (xfs_has_finobt(sc->mp)) {
 		agi->agi_free_root = cpu_to_be32(fab[XREP_AGI_FINOBT].root);
 		agi->agi_free_level = cpu_to_be32(fab[XREP_AGI_FINOBT].height);
 	}
@@ -894,7 +894,7 @@ xrep_agi(
 	int				error;
 
 	/* We require the rmapbt to rebuild anything. */
-	if (!xfs_sb_version_hasrmapbt(&mp->m_sb))
+	if (!xfs_has_rmapbt(mp))
 		return -EOPNOTSUPP;
 
 	xchk_perag_get(sc->mp, &sc->sa);
diff --git a/fs/xfs/scrub/attr.c b/fs/xfs/scrub/attr.c
index 81d5e90547a1..0ac1f766e1c0 100644
--- a/fs/xfs/scrub/attr.c
+++ b/fs/xfs/scrub/attr.c
@@ -270,7 +270,7 @@ xchk_xattr_block(
 	bitmap_zero(usedmap, mp->m_attr_geo->blksize);
 
 	/* Check all the padding. */
-	if (xfs_sb_version_hascrc(&ds->sc->mp->m_sb)) {
+	if (xfs_has_crc(ds->sc->mp)) {
 		struct xfs_attr3_leafblock	*leaf = bp->b_addr;
 
 		if (leaf->hdr.pad1 != 0 || leaf->hdr.pad2 != 0 ||
diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c
index e1d11f3223e3..db53b81cf667 100644
--- a/fs/xfs/scrub/bmap.c
+++ b/fs/xfs/scrub/bmap.c
@@ -372,7 +372,7 @@ xchk_bmapbt_rec(
 	 * Check the owners of the btree blocks up to the level below
 	 * the root since the verifiers don't do that.
 	 */
-	if (xfs_sb_version_hascrc(&bs->cur->bc_mp->m_sb) &&
+	if (xfs_has_crc(bs->cur->bc_mp) &&
 	    bs->cur->bc_ptrs[0] == 1) {
 		for (i = 0; i < bs->cur->bc_nlevels - 1; i++) {
 			block = xfs_btree_get_block(bs->cur, i, &bp);
@@ -529,7 +529,7 @@ xchk_bmap_check_rmaps(
 	xfs_agnumber_t		agno;
 	int			error;
 
-	if (!xfs_sb_version_hasrmapbt(&sc->mp->m_sb) ||
+	if (!xfs_has_rmapbt(sc->mp) ||
 	    whichfork == XFS_COW_FORK ||
 	    (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
 		return 0;
@@ -612,8 +612,8 @@ xchk_bmap(
 	case XFS_ATTR_FORK:
 		if (!ifp)
 			goto out_check_rmap;
-		if (!xfs_sb_version_hasattr(&mp->m_sb) &&
-		    !xfs_sb_version_hasattr2(&mp->m_sb))
+		if (!xfs_has_attr(mp) &&
+		    !xfs_has_attr2(mp))
 			xchk_ino_set_corrupt(sc, sc->ip->i_ino);
 		break;
 	default:
diff --git a/fs/xfs/scrub/common.c b/fs/xfs/scrub/common.c
index 346b02abccf7..26752fbee3fb 100644
--- a/fs/xfs/scrub/common.c
+++ b/fs/xfs/scrub/common.c
@@ -481,7 +481,7 @@ xchk_ag_btcur_init(
 	}
 
 	/* Set up a finobt cursor for cross-referencing. */
-	if (sa->agi_bp && xfs_sb_version_hasfinobt(&mp->m_sb)) {
+	if (sa->agi_bp && xfs_has_finobt(mp)) {
 		sa->fino_cur = xfs_inobt_init_cursor(mp, sc->tp, sa->agi_bp,
 				agno, XFS_BTNUM_FINO);
 		if (!sa->fino_cur)
@@ -489,7 +489,7 @@ xchk_ag_btcur_init(
 	}
 
 	/* Set up a rmapbt cursor for cross-referencing. */
-	if (sa->agf_bp && xfs_sb_version_hasrmapbt(&mp->m_sb)) {
+	if (sa->agf_bp && xfs_has_rmapbt(mp)) {
 		sa->rmap_cur = xfs_rmapbt_init_cursor(mp, sc->tp, sa->agf_bp,
 				agno);
 		if (!sa->rmap_cur)
@@ -497,7 +497,7 @@ xchk_ag_btcur_init(
 	}
 
 	/* Set up a refcountbt cursor for cross-referencing. */
-	if (sa->agf_bp && xfs_sb_version_hasreflink(&mp->m_sb)) {
+	if (sa->agf_bp && xfs_has_reflink(mp)) {
 		sa->refc_cur = xfs_refcountbt_init_cursor(mp, sc->tp,
 				sa->agf_bp, agno);
 		if (!sa->refc_cur)
@@ -850,7 +850,7 @@ xchk_metadata_inode_forks(
 		return error;
 
 	/* Look for incorrect shared blocks. */
-	if (xfs_sb_version_hasreflink(&sc->mp->m_sb)) {
+	if (xfs_has_reflink(sc->mp)) {
 		error = xfs_reflink_inode_has_shared_extents(sc->tp, sc->ip,
 				&shared);
 		if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, 0,
diff --git a/fs/xfs/scrub/dabtree.c b/fs/xfs/scrub/dabtree.c
index f1260b4bfdee..1497d6731bca 100644
--- a/fs/xfs/scrub/dabtree.c
+++ b/fs/xfs/scrub/dabtree.c
@@ -387,11 +387,11 @@ xchk_da_btree_block(
 	pmaxrecs = &ds->maxrecs[level];
 
 	/* We only started zeroing the header on v5 filesystems. */
-	if (xfs_sb_version_hascrc(&ds->sc->mp->m_sb) && hdr3->hdr.pad)
+	if (xfs_has_crc(ds->sc->mp) && hdr3->hdr.pad)
 		xchk_da_set_corrupt(ds, level);
 
 	/* Check the owner. */
-	if (xfs_sb_version_hascrc(&ip->i_mount->m_sb)) {
+	if (xfs_has_crc(ip->i_mount)) {
 		owner = be64_to_cpu(hdr3->owner);
 		if (owner != ip->i_ino)
 			xchk_da_set_corrupt(ds, level);
diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c
index cd3e4d768a18..68560a83871a 100644
--- a/fs/xfs/scrub/dir.c
+++ b/fs/xfs/scrub/dir.c
@@ -62,7 +62,7 @@ xchk_dir_check_ftype(
 	int			ino_dtype;
 	int			error = 0;
 
-	if (!xfs_sb_version_hasftype(&mp->m_sb)) {
+	if (!xfs_has_ftype(mp)) {
 		if (dtype != DT_UNKNOWN && dtype != DT_DIR)
 			xchk_fblock_set_corrupt(sdc->sc, XFS_DATA_FORK,
 					offset);
@@ -131,7 +131,7 @@ xchk_dir_actor(
 
 	if (!strncmp(".", name, namelen)) {
 		/* If this is "." then check that the inum matches the dir. */
-		if (xfs_sb_version_hasftype(&mp->m_sb) && type != DT_DIR)
+		if (xfs_has_ftype(mp) && type != DT_DIR)
 			xchk_fblock_set_corrupt(sdc->sc, XFS_DATA_FORK,
 					offset);
 		if (ino != ip->i_ino)
@@ -142,7 +142,7 @@ xchk_dir_actor(
 		 * If this is ".." in the root inode, check that the inum
 		 * matches this dir.
 		 */
-		if (xfs_sb_version_hasftype(&mp->m_sb) && type != DT_DIR)
+		if (xfs_has_ftype(mp) && type != DT_DIR)
 			xchk_fblock_set_corrupt(sdc->sc, XFS_DATA_FORK,
 					offset);
 		if (ip->i_ino == mp->m_sb.sb_rootino && ino != ip->i_ino)
@@ -508,7 +508,7 @@ xchk_directory_leaf1_bestfree(
 	bestcount = be32_to_cpu(ltp->bestcount);
 	bestp = xfs_dir2_leaf_bests_p(ltp);
 
-	if (xfs_sb_version_hascrc(&sc->mp->m_sb)) {
+	if (xfs_has_crc(sc->mp)) {
 		struct xfs_dir3_leaf_hdr	*hdr3 = bp->b_addr;
 
 		if (hdr3->pad != cpu_to_be32(0))
@@ -591,7 +591,7 @@ xchk_directory_free_bestfree(
 		goto out;
 	xchk_buffer_recheck(sc, bp);
 
-	if (xfs_sb_version_hascrc(&sc->mp->m_sb)) {
+	if (xfs_has_crc(sc->mp)) {
 		struct xfs_dir3_free_hdr	*hdr3 = bp->b_addr;
 
 		if (hdr3->pad != cpu_to_be32(0))
diff --git a/fs/xfs/scrub/ialloc.c b/fs/xfs/scrub/ialloc.c
index 224dba937492..7b046abf3c8c 100644
--- a/fs/xfs/scrub/ialloc.c
+++ b/fs/xfs/scrub/ialloc.c
@@ -373,7 +373,7 @@ xchk_iallocbt_xref_rmap_btreeblks(
 	int			error;
 
 	if (!sc->sa.ino_cur || !sc->sa.rmap_cur ||
-	    (xfs_sb_version_hasfinobt(&sc->mp->m_sb) && !sc->sa.fino_cur) ||
+	    (xfs_has_finobt(sc->mp) && !sc->sa.fino_cur) ||
 	    xchk_skip_xref(sc->sm))
 		return;
 
diff --git a/fs/xfs/scrub/inode.c b/fs/xfs/scrub/inode.c
index 5b3b177c0fc9..4fbddbbf84b4 100644
--- a/fs/xfs/scrub/inode.c
+++ b/fs/xfs/scrub/inode.c
@@ -177,7 +177,7 @@ xchk_inode_flags2(
 
 	/* reflink flag requires reflink feature */
 	if ((flags2 & XFS_DIFLAG2_REFLINK) &&
-	    !xfs_sb_version_hasreflink(&mp->m_sb))
+	    !xfs_has_reflink(mp))
 		goto bad;
 
 	/* cowextsize flag is checked w.r.t. mode separately */
@@ -259,7 +259,7 @@ xchk_dinode(
 			xchk_ino_set_corrupt(sc, ino);
 
 		if (dip->di_projid_hi != 0 &&
-		    !xfs_sb_version_hasprojid32bit(&mp->m_sb))
+		    !xfs_has_projid32(mp))
 			xchk_ino_set_corrupt(sc, ino);
 		break;
 	default:
@@ -547,7 +547,7 @@ xchk_inode_check_reflink_iflag(
 	bool			has_shared;
 	int			error;
 
-	if (!xfs_sb_version_hasreflink(&mp->m_sb))
+	if (!xfs_has_reflink(mp))
 		return;
 
 	error = xfs_reflink_inode_has_shared_extents(sc->tp, sc->ip,
diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c
index 782d582d3edd..c740b932a4b8 100644
--- a/fs/xfs/scrub/quota.c
+++ b/fs/xfs/scrub/quota.c
@@ -165,7 +165,7 @@ xchk_quota_item(
 	 * a reflink filesystem we're allowed to exceed physical space
 	 * if there are no quota limits.
 	 */
-	if (xfs_sb_version_hasreflink(&mp->m_sb)) {
+	if (xfs_has_reflink(mp)) {
 		if (mp->m_sb.sb_dblocks < bcount)
 			xchk_fblock_set_warning(sc, XFS_DATA_FORK,
 					offset);
diff --git a/fs/xfs/scrub/repair.c b/fs/xfs/scrub/repair.c
index 9f08dd9bf1d5..7c117582d6fd 100644
--- a/fs/xfs/scrub/repair.c
+++ b/fs/xfs/scrub/repair.c
@@ -258,19 +258,19 @@ xrep_calc_ag_resblks(
 	 * bnobt/cntbt or inobt/finobt as pairs.
 	 */
 	bnobt_sz = 2 * xfs_allocbt_calc_size(mp, freelen);
-	if (xfs_sb_version_hassparseinodes(&mp->m_sb))
+	if (xfs_has_sparseinodes(mp))
 		inobt_sz = xfs_iallocbt_calc_size(mp, icount /
 				XFS_INODES_PER_HOLEMASK_BIT);
 	else
 		inobt_sz = xfs_iallocbt_calc_size(mp, icount /
 				XFS_INODES_PER_CHUNK);
-	if (xfs_sb_version_hasfinobt(&mp->m_sb))
+	if (xfs_has_finobt(mp))
 		inobt_sz *= 2;
-	if (xfs_sb_version_hasreflink(&mp->m_sb))
+	if (xfs_has_reflink(mp))
 		refcbt_sz = xfs_refcountbt_calc_size(mp, usedlen);
 	else
 		refcbt_sz = 0;
-	if (xfs_sb_version_hasrmapbt(&mp->m_sb)) {
+	if (xfs_has_rmapbt(mp)) {
 		/*
 		 * Guess how many blocks we need to rebuild the rmapbt.
 		 * For non-reflink filesystems we can't have more records than
@@ -279,7 +279,7 @@ xrep_calc_ag_resblks(
 		 * many rmaps there could be in the AG, so we start off with
 		 * what we hope is an generous over-estimation.
 		 */
-		if (xfs_sb_version_hasreflink(&mp->m_sb))
+		if (xfs_has_reflink(mp))
 			rmapbt_sz = xfs_rmapbt_calc_size(mp,
 					(unsigned long long)aglen * 2);
 		else
@@ -620,7 +620,7 @@ xrep_reap_extents(
 	xfs_fsblock_t		fsbno;
 	int			error = 0;
 
-	ASSERT(xfs_sb_version_hasrmapbt(&sc->mp->m_sb));
+	ASSERT(xfs_has_rmapbt(sc->mp));
 
 	for_each_xfs_bitmap_block(fsbno, bmr, n, bitmap) {
 		ASSERT(sc->ip != NULL ||
@@ -730,7 +730,7 @@ xrep_findroot_block(
 	btblock = XFS_BUF_TO_BLOCK(bp);
 	if (be32_to_cpu(btblock->bb_magic) != fab->magic)
 		goto out;
-	if (xfs_sb_version_hascrc(&mp->m_sb) &&
+	if (xfs_has_crc(mp) &&
 	    !uuid_equal(&btblock->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))
 		goto out;
 	bp->b_ops = fab->buf_ops;
diff --git a/fs/xfs/scrub/scrub.c b/fs/xfs/scrub/scrub.c
index 4bfae1e61d30..4c486e89829d 100644
--- a/fs/xfs/scrub/scrub.c
+++ b/fs/xfs/scrub/scrub.c
@@ -422,7 +422,7 @@ xchk_validate_inputs(
 	 * We also don't support v1-v3 filesystems, which aren't
 	 * mountable.
 	 */
-	if (!xfs_sb_version_hasextflgbit(&mp->m_sb))
+	if (!xfs_has_extflg(mp))
 		goto out;
 
 	/*
@@ -433,7 +433,7 @@ xchk_validate_inputs(
 	 */
 	if (sm->sm_flags & XFS_SCRUB_IFLAG_REPAIR) {
 		error = -EOPNOTSUPP;
-		if (!xfs_sb_version_hascrc(&mp->m_sb))
+		if (!xfs_has_crc(mp))
 			goto out;
 
 		error = -EROFS;
diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c
index addbd74ecd8e..2647e4ef8dc5 100644
--- a/fs/xfs/xfs_bmap_util.c
+++ b/fs/xfs/xfs_bmap_util.c
@@ -1143,7 +1143,7 @@ xfs_free_file_space(
 	 * boundaries, and xfs_bunmapi will handle the rest.
 	 */
 	if (XFS_IS_REALTIME_INODE(ip) &&
-	    !xfs_sb_version_hasextflgbit(&mp->m_sb)) {
+	    !xfs_has_extflg(mp)) {
 		error = xfs_adjust_extent_unmap_boundaries(ip, &startoffset_fsb,
 				&endoffset_fsb);
 		if (error)
@@ -1452,7 +1452,7 @@ xfs_swap_extents_check_format(
 	 * If we have to use the (expensive) rmap swap method, we can
 	 * handle any number of extents and any format.
 	 */
-	if (xfs_sb_version_hasrmapbt(&ip->i_mount->m_sb))
+	if (xfs_has_rmapbt(ip->i_mount))
 		return 0;
 
 	/*
@@ -1835,7 +1835,7 @@ xfs_swap_extents(
 	 * a block reservation because it's really just a remap operation
 	 * performed with log redo items!
 	 */
-	if (xfs_sb_version_hasrmapbt(&mp->m_sb)) {
+	if (xfs_has_rmapbt(mp)) {
 		int		w	= XFS_DATA_FORK;
 		uint32_t	ipnext	= XFS_IFORK_NEXTENTS(ip, w);
 		uint32_t	tipnext	= XFS_IFORK_NEXTENTS(tip, w);
@@ -1918,7 +1918,7 @@ xfs_swap_extents(
 	src_log_flags = XFS_ILOG_CORE;
 	target_log_flags = XFS_ILOG_CORE;
 
-	if (xfs_sb_version_hasrmapbt(&mp->m_sb))
+	if (xfs_has_rmapbt(mp))
 		error = xfs_swap_extent_rmap(&tp, ip, tip);
 	else
 		error = xfs_swap_extent_forks(tp, ip, tip, &src_log_flags,
@@ -1937,7 +1937,7 @@ xfs_swap_extents(
 	}
 
 	/* Swap the cow forks. */
-	if (xfs_sb_version_hasreflink(&mp->m_sb)) {
+	if (xfs_has_reflink(mp)) {
 		ASSERT(ip->i_cformat == XFS_DINODE_FMT_EXTENTS);
 		ASSERT(tip->i_cformat == XFS_DINODE_FMT_EXTENTS);
 
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
index e839907e8492..8043c7a8c2e0 100644
--- a/fs/xfs/xfs_buf.c
+++ b/fs/xfs/xfs_buf.c
@@ -1394,7 +1394,7 @@ _xfs_buf_ioapply(
 			 * non-crc filesystems don't attach verifiers during
 			 * log recovery, so don't warn for such filesystems.
 			 */
-			if (xfs_sb_version_hascrc(&mp->m_sb)) {
+			if (xfs_has_crc(mp)) {
 				xfs_warn(mp,
 					"%s: no buf ops on daddr 0x%llx len %d",
 					__func__, bp->b_bn, bp->b_length);
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
index 1c9d1398980b..5d8495380d2b 100644
--- a/fs/xfs/xfs_buf_item.c
+++ b/fs/xfs/xfs_buf_item.c
@@ -330,7 +330,7 @@ xfs_buf_item_format(
 	 * occurs during recovery.
 	 */
 	if (bip->bli_flags & XFS_BLI_INODE_BUF) {
-		if (xfs_sb_version_hascrc(&lip->li_mountp->m_sb) ||
+		if (xfs_has_crc(lip->li_mountp) ||
 		    !((bip->bli_flags & XFS_BLI_INODE_ALLOC_BUF) &&
 		      xfs_log_item_in_current_chkpt(lip)))
 			bip->__bli_format.blf_flags |= XFS_BLF_INODE_BUF;
diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
index 5142e64e2345..5b1d16b2a823 100644
--- a/fs/xfs/xfs_dir2_readdir.c
+++ b/fs/xfs/xfs_dir2_readdir.c
@@ -34,7 +34,7 @@ xfs_dir3_get_dtype(
 	struct xfs_mount	*mp,
 	uint8_t			filetype)
 {
-	if (!xfs_sb_version_hasftype(&mp->m_sb))
+	if (!xfs_has_ftype(mp))
 		return DT_UNKNOWN;
 
 	if (filetype >= XFS_DIR3_FT_MAX)
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index 87e6dd5326d5..296d6cdfe7aa 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -235,7 +235,7 @@ xfs_qm_init_dquot_blk(
 		d->dd_diskdq.d_version = XFS_DQUOT_VERSION;
 		d->dd_diskdq.d_id = cpu_to_be32(curid);
 		d->dd_diskdq.d_flags = type;
-		if (xfs_sb_version_hascrc(&mp->m_sb)) {
+		if (xfs_has_crc(mp)) {
 			uuid_copy(&d->dd_uuid, &mp->m_sb.sb_meta_uuid);
 			xfs_update_cksum((char *)d, sizeof(struct xfs_dqblk),
 					 XFS_DQUOT_CRC_OFF);
@@ -1152,7 +1152,7 @@ xfs_qm_dqflush(
 	 * buffer always has a valid CRC. This ensures there is no possibility
 	 * of a dquot without an up-to-date CRC getting to disk.
 	 */
-	if (xfs_sb_version_hascrc(&mp->m_sb)) {
+	if (xfs_has_crc(mp)) {
 		dqb->dd_lsn = cpu_to_be64(dqp->q_logitem.qli_item.li_lsn);
 		xfs_update_cksum((char *)dqb, sizeof(struct xfs_dqblk),
 				 XFS_DQUOT_CRC_OFF);
diff --git a/fs/xfs/xfs_fsmap.c b/fs/xfs/xfs_fsmap.c
index 3d76a9e35870..a52cd4830553 100644
--- a/fs/xfs/xfs_fsmap.c
+++ b/fs/xfs/xfs_fsmap.c
@@ -205,7 +205,7 @@ xfs_getfsmap_is_shared(
 	int				error;
 
 	*stat = false;
-	if (!xfs_sb_version_hasreflink(&mp->m_sb))
+	if (!xfs_has_reflink(mp))
 		return 0;
 	/* rt files will have agno set to NULLAGNUMBER */
 	if (info->agno == NULLAGNUMBER)
@@ -837,7 +837,7 @@ xfs_getfsmap(
 		return -EINVAL;
 
 	use_rmap = capable(CAP_SYS_ADMIN) &&
-		   xfs_sb_version_hasrmapbt(&mp->m_sb);
+		   xfs_has_rmapbt(mp);
 	head->fmh_entries = 0;
 
 	/* Set up our device handlers. */
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index 0ef5ece5634c..4f4c6cd81b54 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -608,7 +608,7 @@ xfs_ioc_space(
 	 * Only allow the sys admin to reserve space unless
 	 * unwritten extents are enabled.
 	 */
-	if (!xfs_sb_version_hasextflgbit(&ip->i_mount->m_sb) &&
+	if (!xfs_has_extflg(ip->i_mount) &&
 	    !capable(CAP_SYS_ADMIN))
 		return -EPERM;
 
@@ -1264,7 +1264,7 @@ xfs_ioctl_setattr_check_cowextsize(
 	if (!(fa->fsx_xflags & FS_XFLAG_COWEXTSIZE))
 		return 0;
 
-	if (!xfs_sb_version_hasreflink(&ip->i_mount->m_sb) ||
+	if (!xfs_has_reflink(ip->i_mount) ||
 	    ip->i_d.di_version != 3)
 		return -EINVAL;
 
@@ -1296,9 +1296,9 @@ xfs_ioctl_setattr_check_projid(
 	struct xfs_inode	*ip,
 	struct fsxattr		*fa)
 {
-	/* Disallow 32bit project ids if projid32bit feature is not enabled. */
+	/* Disallow 32bit project ids if projid32 feature is not enabled. */
 	if (fa->fsx_projid > (uint16_t)-1 &&
-	    !xfs_sb_version_hasprojid32bit(&ip->i_mount->m_sb))
+	    !xfs_has_projid32(ip->i_mount))
 		return -EINVAL;
 
 	/*
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index c3e74f9128e8..066a97d108f5 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -349,7 +349,7 @@ xfs_vn_unlink(
 	 * but still hashed. This is incompatible with case-insensitive
 	 * mode, so invalidate (unhash) the dentry in CI-mode.
 	 */
-	if (xfs_sb_version_hasasciici(&XFS_M(dir->i_sb)->m_sb))
+	if (xfs_has_asciici(XFS_M(dir->i_sb)))
 		d_invalidate(dentry);
 	return 0;
 }
@@ -721,7 +721,7 @@ xfs_setattr_nonsize(
 		}
 		if (!gid_eq(igid, gid)) {
 			if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_GQUOTA_ON(mp)) {
-				ASSERT(xfs_sb_version_has_pquotino(&mp->m_sb) ||
+				ASSERT(xfs_has_pquotino(mp) ||
 				       !XFS_IS_PQUOTA_ON(mp));
 				ASSERT(mask & ATTR_GID);
 				ASSERT(gdqp);
@@ -1312,7 +1312,7 @@ xfs_setup_iops(
 			inode->i_mapping->a_ops = &xfs_address_space_operations;
 		break;
 	case S_IFDIR:
-		if (xfs_sb_version_hasasciici(&XFS_M(inode->i_sb)->m_sb))
+		if (xfs_has_asciici(XFS_M(inode->i_sb)))
 			inode->i_op = &xfs_dir_ci_inode_operations;
 		else
 			inode->i_op = &xfs_dir_inode_operations;
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index c3b610b687d1..7ad8c7bb1345 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -596,7 +596,7 @@ xfs_log_mount(
 	xfs_daddr_t	blk_offset,
 	int		num_bblks)
 {
-	bool		fatal = xfs_sb_version_hascrc(&mp->m_sb);
+	bool		fatal = xfs_has_crc(mp);
 	int		error = 0;
 	int		min_logfsbs;
 
@@ -1325,7 +1325,7 @@ xlog_get_iclog_buffer_size(
 			size >>= 1;
 		}
 
-		if (xfs_sb_version_haslogv2(&mp->m_sb)) {
+		if (xfs_has_logv2(mp)) {
 			/* # headers = size / 32k
 			 * one header holds cycles from 32k of data
 			 */
@@ -1451,7 +1451,7 @@ xlog_alloc_log(
 	xlog_grant_head_init(&log->l_write_head);
 
 	error = -EFSCORRUPTED;
-	if (xfs_sb_version_hassector(&mp->m_sb)) {
+	if (xfs_has_sector(mp)) {
 	        log2_size = mp->m_sb.sb_logsectlog;
 		if (log2_size < BBSHIFT) {
 			xfs_warn(mp, "Log sector size too small (0x%x < 0x%x)",
@@ -1468,7 +1468,7 @@ xlog_alloc_log(
 
 		/* for larger sector sizes, must have v2 or external log */
 		if (log2_size && log->l_logBBstart > 0 &&
-			    !xfs_sb_version_haslogv2(&mp->m_sb)) {
+			    !xfs_has_logv2(mp)) {
 			xfs_warn(mp,
 		"log sector size (0x%x) invalid for configuration.",
 				log2_size);
@@ -1545,7 +1545,7 @@ xlog_alloc_log(
 		memset(head, 0, sizeof(xlog_rec_header_t));
 		head->h_magicno = cpu_to_be32(XLOG_HEADER_MAGIC_NUM);
 		head->h_version = cpu_to_be32(
-			xfs_sb_version_haslogv2(&log->l_mp->m_sb) ? 2 : 1);
+			xfs_has_logv2(log->l_mp) ? 2 : 1);
 		head->h_size = cpu_to_be32(log->l_iclog_size);
 		/* new fields */
 		head->h_fmt = cpu_to_be32(XLOG_FMT);
@@ -1707,7 +1707,7 @@ xlog_pack_data(
 		dp += BBSIZE;
 	}
 
-	if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) {
+	if (xfs_has_logv2(log->l_mp)) {
 		xlog_in_core_2_t *xhdr = iclog->ic_data;
 
 		for ( ; i < BTOBB(size); i++) {
@@ -1744,7 +1744,7 @@ xlog_cksum(
 			      offsetof(struct xlog_rec_header, h_crc));
 
 	/* ... then for additional cycle data for v2 logs ... */
-	if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) {
+	if (xfs_has_logv2(log->l_mp)) {
 		union xlog_in_core2 *xhdr = (union xlog_in_core2 *)rhead;
 		int		i;
 		int		xheads;
@@ -1840,7 +1840,7 @@ xlog_sync(
 	int		roundoff;       /* roundoff to BB or stripe */
 	int		split = 0;	/* split write into two regions */
 	int		error;
-	int		v2 = xfs_sb_version_haslogv2(&log->l_mp->m_sb);
+	int		v2 = xfs_has_logv2(log->l_mp);
 	int		size;
 
 	XFS_STATS_INC(log->l_mp, xs_log_writes);
@@ -3259,7 +3259,7 @@ xlog_state_switch_iclogs(
 	log->l_curr_block += BTOBB(eventual_size)+BTOBB(log->l_iclog_hsize);
 
 	/* Round up to next log-sunit */
-	if (xfs_sb_version_haslogv2(&log->l_mp->m_sb) &&
+	if (xfs_has_logv2(log->l_mp) &&
 	    log->l_mp->m_sb.sb_logsunit > 1) {
 		uint32_t sunit_bb = BTOBB(log->l_mp->m_sb.sb_logsunit);
 		log->l_curr_block = roundup(log->l_curr_block, sunit_bb);
@@ -3657,7 +3657,7 @@ xfs_log_calc_unit_res(
 	unit_bytes += log->l_iclog_hsize;
 
 	/* for roundoff padding for transaction data and one for commit record */
-	if (xfs_sb_version_haslogv2(&mp->m_sb) && mp->m_sb.sb_logsunit > 1) {
+	if (xfs_has_logv2(mp) && mp->m_sb.sb_logsunit > 1) {
 		/* log su roundoff */
 		unit_bytes += 2 * mp->m_sb.sb_logsunit;
 	} else {
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 5d0438ec07dd..d57b992f6f6e 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -592,7 +592,7 @@ xlog_find_verify_log_record(
 	 * reset last_blk.  Only when last_blk points in the middle of a log
 	 * record do we update last_blk.
 	 */
-	if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) {
+	if (xfs_has_logv2(log->l_mp)) {
 		uint	h_size = be32_to_cpu(head->h_size);
 
 		xhdrs = h_size / XLOG_HEADER_CYCLE_SIZE;
@@ -1287,7 +1287,7 @@ xlog_check_unmount_rec(
 	 * below. We won't want to clear the unmount record if there is one, so
 	 * we pass the lsn of the unmount record rather than the block after it.
 	 */
-	if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) {
+	if (xfs_has_logv2(log->l_mp)) {
 		int	h_size = be32_to_cpu(rhead->h_size);
 		int	h_version = be32_to_cpu(rhead->h_version);
 
@@ -1650,7 +1650,7 @@ xlog_add_record(
 	recp->h_magicno = cpu_to_be32(XLOG_HEADER_MAGIC_NUM);
 	recp->h_cycle = cpu_to_be32(cycle);
 	recp->h_version = cpu_to_be32(
-			xfs_sb_version_haslogv2(&log->l_mp->m_sb) ? 2 : 1);
+			xfs_has_logv2(log->l_mp) ? 2 : 1);
 	recp->h_lsn = cpu_to_be64(xlog_assign_lsn(cycle, block));
 	recp->h_tail_lsn = cpu_to_be64(xlog_assign_lsn(tail_cycle, tail_block));
 	recp->h_fmt = cpu_to_be32(XLOG_FMT);
@@ -2169,7 +2169,7 @@ xlog_recover_do_inode_buffer(
 	 * Post recovery validation only works properly on CRC enabled
 	 * filesystems.
 	 */
-	if (xfs_sb_version_hascrc(&mp->m_sb))
+	if (xfs_has_crc(mp))
 		bp->b_ops = &xfs_inode_buf_ops;
 
 	inodes_per_buf = BBTOB(bp->b_io_length) >> mp->m_sb.sb_inodelog;
@@ -2283,7 +2283,7 @@ xlog_recover_get_buf_lsn(
 	xfs_lsn_t		lsn = -1;
 
 	/* v4 filesystems always recover immediately */
-	if (!xfs_sb_version_hascrc(&mp->m_sb))
+	if (!xfs_has_crc(mp))
 		goto recover_immediately;
 
 	magic32 = be32_to_cpu(*(__be32 *)blk);
@@ -2350,7 +2350,7 @@ xlog_recover_get_buf_lsn(
 		 * the relevant UUID in the superblock.
 		 */
 		lsn = be64_to_cpu(((struct xfs_dsb *)blk)->sb_lsn);
-		if (xfs_sb_version_hasmetauuid(&mp->m_sb))
+		if (xfs_has_metauuid(mp))
 			uuid = &((struct xfs_dsb *)blk)->sb_meta_uuid;
 		else
 			uuid = &((struct xfs_dsb *)blk)->sb_uuid;
@@ -2439,7 +2439,7 @@ xlog_recover_validate_buf_type(
 	 * inconsistent state resulting in verification failures. Hence for now
 	 * just avoid the verification stage for non-crc filesystems
 	 */
-	if (!xfs_sb_version_hascrc(&mp->m_sb))
+	if (!xfs_has_crc(mp))
 		return;
 
 	magic32 = be32_to_cpu(*(__be32 *)bp->b_addr);
@@ -3100,7 +3100,7 @@ xlog_recover_inode_pass2(
 	 * superblock flag to determine whether we need to look at di_flushiter
 	 * to skip replay when the on disk inode is newer than the log one
 	 */
-	if (!xfs_sb_version_hascrc(&mp->m_sb) &&
+	if (!xfs_has_crc(mp) &&
 	    ldip->di_flushiter < be16_to_cpu(dip->di_flushiter)) {
 		/*
 		 * Deal with the wrap case, DI_MAX_FLUSH is less
@@ -3389,7 +3389,7 @@ xlog_recover_dquot_pass2(
 	 * If the dquot has an LSN in it, recover the dquot only if it's less
 	 * than the lsn of the transaction we are replaying.
 	 */
-	if (xfs_sb_version_hascrc(&mp->m_sb)) {
+	if (xfs_has_crc(mp)) {
 		struct xfs_dqblk *dqb = (struct xfs_dqblk *)ddq;
 		xfs_lsn_t	lsn = be64_to_cpu(dqb->dd_lsn);
 
@@ -3399,7 +3399,7 @@ xlog_recover_dquot_pass2(
 	}
 
 	memcpy(ddq, recddq, item->ri_buf[1].i_len);
-	if (xfs_sb_version_hascrc(&mp->m_sb)) {
+	if (xfs_has_crc(mp)) {
 		xfs_update_cksum((char *)ddq, sizeof(struct xfs_dqblk),
 				 XFS_DQUOT_CRC_OFF);
 	}
@@ -5189,7 +5189,7 @@ xlog_unpack_data(
 		dp += BBSIZE;
 	}
 
-	if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) {
+	if (xfs_has_logv2(log->l_mp)) {
 		xlog_in_core_2_t *xhdr = (xlog_in_core_2_t *)rhead;
 		for ( ; i < BTOBB(be32_to_cpu(rhead->h_len)); i++) {
 			j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
@@ -5241,7 +5241,7 @@ xlog_recover_process(
 	 * the kernel from one that does not add CRCs by default.
 	 */
 	if (crc != old_crc) {
-		if (old_crc || xfs_sb_version_hascrc(&log->l_mp->m_sb)) {
+		if (old_crc || xfs_has_crc(log->l_mp)) {
 			xfs_alert(log->l_mp,
 		"log record CRC mismatch: found 0x%x, expected 0x%x.",
 					le32_to_cpu(old_crc),
@@ -5253,7 +5253,7 @@ xlog_recover_process(
 		 * If the filesystem is CRC enabled, this mismatch becomes a
 		 * fatal log corruption failure.
 		 */
-		if (xfs_sb_version_hascrc(&log->l_mp->m_sb))
+		if (xfs_has_crc(log->l_mp))
 			return -EFSCORRUPTED;
 	}
 
@@ -5340,7 +5340,7 @@ xlog_do_recovery_pass(
 	 * Read the header of the tail block and get the iclog buffer size from
 	 * h_size.  Use this to tell how many sectors make up the log header.
 	 */
-	if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) {
+	if (xfs_has_logv2(log->l_mp)) {
 		/*
 		 * When using variable length iclogs, read first sector of
 		 * iclog header and extract the header size from it.  Get a
@@ -5761,7 +5761,7 @@ xlog_recover(
 	 * could not be verified. Check the superblock LSN against the current
 	 * LSN now that it's known.
 	 */
-	if (xfs_sb_version_hascrc(&log->l_mp->m_sb) &&
+	if (xfs_has_crc(log->l_mp) &&
 	    !xfs_log_check_lsn(log->l_mp, log->l_mp->m_sb.sb_lsn))
 		return -EINVAL;
 
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index fc567ca8b9d3..212ae2695b88 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -400,7 +400,7 @@ xfs_update_alignment(xfs_mount_t *mp)
 		 * Update superblock with new values
 		 * and log changes
 		 */
-		if (xfs_sb_version_hasdalign(sbp)) {
+		if (xfs_has_dalign(mp)) {
 			if (sbp->sb_unit != mp->m_dalign) {
 				sbp->sb_unit = mp->m_dalign;
 				mp->m_update_sb = true;
@@ -415,7 +415,7 @@ xfs_update_alignment(xfs_mount_t *mp)
 			return -EINVAL;
 		}
 	} else if ((mp->m_flags & XFS_MOUNT_NOALIGN) != XFS_MOUNT_NOALIGN &&
-		    xfs_sb_version_hasdalign(&mp->m_sb)) {
+		    xfs_has_dalign(mp)) {
 			mp->m_dalign = sbp->sb_unit;
 			mp->m_swidth = sbp->sb_width;
 	}
@@ -510,7 +510,7 @@ xfs_set_low_space_thresholds(
 STATIC void
 xfs_set_inoalignment(xfs_mount_t *mp)
 {
-	if (xfs_sb_version_hasalign(&mp->m_sb) &&
+	if (xfs_has_align(mp) &&
 		mp->m_sb.sb_inoalignmt >= xfs_icluster_size_fsb(mp))
 		mp->m_inoalign_mask = mp->m_sb.sb_inoalignmt - 1;
 	else
@@ -653,7 +653,7 @@ xfs_check_summary_counts(
 	 * superblock to be correct and we don't need to do anything here.
 	 * Otherwise, recalculate the summary counters.
 	 */
-	if ((!xfs_sb_version_haslazysbcount(&mp->m_sb) ||
+	if ((!xfs_has_lazysbcount(mp) ||
 	     XFS_LAST_UNMOUNT_WAS_CLEAN(mp)) &&
 	    !(mp->m_flags & XFS_MOUNT_BAD_SUMMARY))
 		return 0;
@@ -709,14 +709,14 @@ xfs_mountfs(
 		 * Re-check for ATTR2 in case it was found in bad_features2
 		 * slot.
 		 */
-		if (xfs_sb_version_hasattr2(&mp->m_sb) &&
+		if (xfs_has_attr2(mp) &&
 		   !(mp->m_flags & XFS_MOUNT_NOATTR2))
 			mp->m_flags |= XFS_MOUNT_ATTR2;
 	}
 
-	if (xfs_sb_version_hasattr2(&mp->m_sb) &&
+	if (xfs_has_attr2(mp) &&
 	   (mp->m_flags & XFS_MOUNT_NOATTR2)) {
-		xfs_sb_version_removeattr2(&mp->m_sb);
+		xfs_feat_remove_attr2(mp);
 		mp->m_update_sb = true;
 
 		/* update sb_versionnum for the clearing of the morebits */
@@ -727,6 +727,7 @@ xfs_mountfs(
 	/* always use v2 inodes by default now */
 	if (!(mp->m_sb.sb_versionnum & XFS_SB_VERSION_NLINKBIT)) {
 		mp->m_sb.sb_versionnum |= XFS_SB_VERSION_NLINKBIT;
+		mp->m_features |= XFS_FEAT_NLINK;
 		mp->m_update_sb = true;
 	}
 
@@ -792,7 +793,7 @@ xfs_mountfs(
 	 * sizes.
 	 */
 	mp->m_inode_cluster_size = XFS_INODE_BIG_CLUSTER_SIZE;
-	if (xfs_sb_version_hascrc(&mp->m_sb)) {
+	if (xfs_has_crc(mp)) {
 		int	new_size = mp->m_inode_cluster_size;
 
 		new_size *= mp->m_sb.sb_inodesize / XFS_DINODE_MIN_SIZE;
@@ -805,7 +806,7 @@ xfs_mountfs(
 	 * cluster size. Full inode chunk alignment must match the chunk size,
 	 * but that is checked on sb read verification...
 	 */
-	if (xfs_sb_version_hassparseinodes(&mp->m_sb) &&
+	if (xfs_has_sparseinodes(mp) &&
 	    mp->m_sb.sb_spino_align !=
 			XFS_B_TO_FSBT(mp, mp->m_inode_cluster_size)) {
 		xfs_warn(mp,
@@ -1225,7 +1226,7 @@ xfs_log_sbcount(xfs_mount_t *mp)
 	 * we don't need to do this if we are updating the superblock
 	 * counters on every modification.
 	 */
-	if (!xfs_sb_version_haslazysbcount(&mp->m_sb))
+	if (!xfs_has_lazysbcount(mp))
 		return 0;
 
 	return xfs_sync_sb(mp, true);
@@ -1434,7 +1435,7 @@ void
 xfs_force_summary_recalc(
 	struct xfs_mount	*mp)
 {
-	if (!xfs_sb_version_haslazysbcount(&mp->m_sb))
+	if (!xfs_has_lazysbcount(mp))
 		return;
 
 	spin_lock(&mp->m_sb_lock);
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index 52ed7904df10..9ee840472138 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -751,7 +751,7 @@ xfs_qm_qino_alloc(
 	 * with PQUOTA, just use sb_gquotino for sb_pquotino and
 	 * vice-versa.
 	 */
-	if (!xfs_sb_version_has_pquotino(&mp->m_sb) &&
+	if (!xfs_has_pquotino(mp) &&
 			(flags & (XFS_QMOPT_PQUOTA|XFS_QMOPT_GQUOTA))) {
 		xfs_ino_t ino = NULLFSINO;
 
@@ -794,9 +794,9 @@ xfs_qm_qino_alloc(
 	 */
 	spin_lock(&mp->m_sb_lock);
 	if (flags & XFS_QMOPT_SBVERSION) {
-		ASSERT(!xfs_sb_version_hasquota(&mp->m_sb));
+		ASSERT(!xfs_has_quota(mp));
 
-		xfs_sb_version_addquota(&mp->m_sb);
+		xfs_feat_add_quota(mp);
 		mp->m_sb.sb_uquotino = NULLFSINO;
 		mp->m_sb.sb_gquotino = NULLFSINO;
 		mp->m_sb.sb_pquotino = NULLFSINO;
@@ -877,7 +877,7 @@ xfs_qm_reset_dqcounts(
 		ddq->d_iwarns = 0;
 		ddq->d_rtbwarns = 0;
 
-		if (xfs_sb_version_hascrc(&mp->m_sb)) {
+		if (xfs_has_crc(mp)) {
 			xfs_update_cksum((char *)&dqb[j],
 					 sizeof(struct xfs_dqblk),
 					 XFS_DQUOT_CRC_OFF);
@@ -1509,7 +1509,7 @@ xfs_qm_init_quotainos(
 	/*
 	 * Get the uquota and gquota inodes
 	 */
-	if (xfs_sb_version_hasquota(&mp->m_sb)) {
+	if (xfs_has_quota(mp)) {
 		if (XFS_IS_UQUOTA_ON(mp) &&
 		    mp->m_sb.sb_uquotino != NULLFSINO) {
 			ASSERT(mp->m_sb.sb_uquotino > 0);
diff --git a/fs/xfs/xfs_qm_bhv.c b/fs/xfs/xfs_qm_bhv.c
index 73a1d77ec187..97a46b176e14 100644
--- a/fs/xfs/xfs_qm_bhv.c
+++ b/fs/xfs/xfs_qm_bhv.c
@@ -75,7 +75,7 @@ xfs_qm_newmount(
 	uint		quotaondisk;
 	uint		uquotaondisk = 0, gquotaondisk = 0, pquotaondisk = 0;
 
-	quotaondisk = xfs_sb_version_hasquota(&mp->m_sb) &&
+	quotaondisk = xfs_has_quota(mp) &&
 				(mp->m_sb.sb_qflags & XFS_ALL_QUOTA_ACCT);
 
 	if (quotaondisk) {
diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
index b3190890f096..49860b1765f1 100644
--- a/fs/xfs/xfs_qm_syscalls.c
+++ b/fs/xfs/xfs_qm_syscalls.c
@@ -262,7 +262,7 @@ xfs_qm_scall_trunc_qfiles(
 {
 	int		error = -EINVAL;
 
-	if (!xfs_sb_version_hasquota(&mp->m_sb) || flags == 0 ||
+	if (!xfs_has_quota(mp) || flags == 0 ||
 	    (flags & ~XFS_DQ_ALLTYPES)) {
 		xfs_debug(mp, "%s: flags=%x m_qflags=%x",
 			__func__, flags, mp->m_qflags);
diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c
index 38f405415b88..66ba7c4446d5 100644
--- a/fs/xfs/xfs_reflink.c
+++ b/fs/xfs/xfs_reflink.c
@@ -743,7 +743,7 @@ xfs_reflink_recover_cow(
 	xfs_agnumber_t		agno;
 	int			error = 0;
 
-	if (!xfs_sb_version_hasreflink(&mp->m_sb))
+	if (!xfs_has_reflink(mp))
 		return 0;
 
 	for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
@@ -953,7 +953,7 @@ xfs_reflink_ag_has_free_space(
 	struct xfs_perag	*pag;
 	int			error = 0;
 
-	if (!xfs_sb_version_hasrmapbt(&mp->m_sb))
+	if (!xfs_has_rmapbt(mp))
 		return 0;
 
 	pag = xfs_perag_get(mp, agno);
@@ -1218,7 +1218,7 @@ xfs_reflink_remap_range(
 	xfs_extlen_t		cowextsize;
 	ssize_t			ret;
 
-	if (!xfs_sb_version_hasreflink(&mp->m_sb))
+	if (!xfs_has_reflink(mp))
 		return -EOPNOTSUPP;
 
 	if (XFS_FORCED_SHUTDOWN(mp))
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 207ee302b1bb..cf76884c2a95 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -810,7 +810,7 @@ xfs_setup_devices(
 	if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) {
 		unsigned int	log_sector_size = BBSIZE;
 
-		if (xfs_sb_version_hassector(&mp->m_sb))
+		if (xfs_has_sector(mp))
 			log_sector_size = mp->m_sb.sb_logsectsize;
 		error = xfs_setsize_buftarg(mp->m_logdev_targp,
 					    log_sector_size);
@@ -1438,7 +1438,7 @@ xfs_finish_flags(
 	int			ronly = (mp->m_flags & XFS_MOUNT_RDONLY);
 
 	/* Fail a mount where the logbuf is smaller than the log stripe */
-	if (xfs_sb_version_haslogv2(&mp->m_sb)) {
+	if (xfs_has_logv2(mp)) {
 		if (mp->m_logbsize <= 0 &&
 		    mp->m_sb.sb_logsunit > XLOG_BIG_RECORD_BSIZE) {
 			mp->m_logbsize = mp->m_sb.sb_logsunit;
@@ -1460,7 +1460,7 @@ xfs_finish_flags(
 	/*
 	 * V5 filesystems always use attr2 format for attributes.
 	 */
-	if (xfs_sb_version_hascrc(&mp->m_sb) &&
+	if (xfs_has_crc(mp) &&
 	    (mp->m_flags & XFS_MOUNT_NOATTR2)) {
 		xfs_warn(mp, "Cannot mount a V5 filesystem as noattr2. "
 			     "attr2 is always enabled for V5 filesystems.");
@@ -1471,7 +1471,7 @@ xfs_finish_flags(
 	 * mkfs'ed attr2 will turn on attr2 mount unless explicitly
 	 * told by noattr2 to turn it off
 	 */
-	if (xfs_sb_version_hasattr2(&mp->m_sb) &&
+	if (xfs_has_attr2(mp) &&
 	    !(mp->m_flags & XFS_MOUNT_NOATTR2))
 		mp->m_flags |= XFS_MOUNT_ATTR2;
 
@@ -1486,7 +1486,7 @@ xfs_finish_flags(
 
 	if ((mp->m_qflags & (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE)) &&
 	    (mp->m_qflags & (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE)) &&
-	    !xfs_sb_version_has_pquotino(&mp->m_sb)) {
+	    !xfs_has_pquotino(mp)) {
 		xfs_warn(mp,
 		  "Super block does not support project and group quota together");
 		return -EINVAL;
@@ -1678,7 +1678,7 @@ xfs_fs_fill_super(
 			"DAX unsupported by block device. Turning off DAX.");
 			mp->m_flags &= ~XFS_MOUNT_DAX;
 		}
-		if (xfs_sb_version_hasreflink(&mp->m_sb)) {
+		if (xfs_has_reflink(mp)) {
 			xfs_alert(mp,
 		"DAX and reflink cannot be used together!");
 			error = -EINVAL;
@@ -1696,14 +1696,14 @@ xfs_fs_fill_super(
 		}
 	}
 
-	if (xfs_sb_version_hasreflink(&mp->m_sb) && mp->m_sb.sb_rblocks) {
+	if (xfs_has_reflink(mp) && mp->m_sb.sb_rblocks) {
 		xfs_alert(mp,
 	"reflink not compatible with realtime device!");
 		error = -EINVAL;
 		goto out_filestream_unmount;
 	}
 
-	if (xfs_sb_version_hasrmapbt(&mp->m_sb) && mp->m_sb.sb_rblocks) {
+	if (xfs_has_rmapbt(mp) && mp->m_sb.sb_rblocks) {
 		xfs_alert(mp,
 	"reverse mapping btree not compatible with realtime device!");
 		error = -EINVAL;
diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c
index a3e98c64b6e3..647a9aa98646 100644
--- a/fs/xfs/xfs_symlink.c
+++ b/fs/xfs/xfs_symlink.c
@@ -80,7 +80,7 @@ xfs_readlink_bmap_ilocked(
 			byte_cnt = pathlen;
 
 		cur_chunk = bp->b_addr;
-		if (xfs_sb_version_hascrc(&mp->m_sb)) {
+		if (xfs_has_crc(mp)) {
 			if (!xfs_symlink_hdr_ok(ip->i_ino, offset,
 							byte_cnt, bp)) {
 				error = -EFSCORRUPTED;
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index bedc5a5133a5..db4367baab34 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -342,12 +342,12 @@ xfs_trans_mod_sb(
 	switch (field) {
 	case XFS_TRANS_SB_ICOUNT:
 		tp->t_icount_delta += delta;
-		if (xfs_sb_version_haslazysbcount(&mp->m_sb))
+		if (xfs_has_lazysbcount(mp))
 			flags &= ~XFS_TRANS_SB_DIRTY;
 		break;
 	case XFS_TRANS_SB_IFREE:
 		tp->t_ifree_delta += delta;
-		if (xfs_sb_version_haslazysbcount(&mp->m_sb))
+		if (xfs_has_lazysbcount(mp))
 			flags &= ~XFS_TRANS_SB_DIRTY;
 		break;
 	case XFS_TRANS_SB_FDBLOCKS:
@@ -362,7 +362,7 @@ xfs_trans_mod_sb(
 				xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
 		}
 		tp->t_fdblocks_delta += delta;
-		if (xfs_sb_version_haslazysbcount(&mp->m_sb))
+		if (xfs_has_lazysbcount(mp))
 			flags &= ~XFS_TRANS_SB_DIRTY;
 		break;
 	case XFS_TRANS_SB_RES_FDBLOCKS:
@@ -372,7 +372,7 @@ xfs_trans_mod_sb(
 		 * be applied to the on-disk superblock.
 		 */
 		tp->t_res_fdblocks_delta += delta;
-		if (xfs_sb_version_haslazysbcount(&mp->m_sb))
+		if (xfs_has_lazysbcount(mp))
 			flags &= ~XFS_TRANS_SB_DIRTY;
 		break;
 	case XFS_TRANS_SB_FREXTENTS:
@@ -459,7 +459,7 @@ xfs_trans_apply_sb_deltas(
 	/*
 	 * Only update the superblock counters if we are logging them
 	 */
-	if (!xfs_sb_version_haslazysbcount(&(tp->t_mountp->m_sb))) {
+	if (!xfs_has_lazysbcount((tp->t_mountp))) {
 		if (tp->t_icount_delta)
 			be64_add_cpu(&sbp->sb_icount, tp->t_icount_delta);
 		if (tp->t_ifree_delta)
@@ -600,7 +600,7 @@ xfs_trans_unreserve_and_mod_sb(
 	if (tp->t_blk_res > 0)
 		blkdelta = tp->t_blk_res;
 	if ((tp->t_fdblocks_delta != 0) &&
-	    (xfs_sb_version_haslazysbcount(&mp->m_sb) ||
+	    (xfs_has_lazysbcount(mp) ||
 	     (tp->t_flags & XFS_TRANS_SB_DIRTY)))
 	        blkdelta += tp->t_fdblocks_delta;
 
@@ -610,7 +610,7 @@ xfs_trans_unreserve_and_mod_sb(
 	    (tp->t_flags & XFS_TRANS_SB_DIRTY))
 		rtxdelta += tp->t_frextents_delta;
 
-	if (xfs_sb_version_haslazysbcount(&mp->m_sb) ||
+	if (xfs_has_lazysbcount(mp) ||
 	     (tp->t_flags & XFS_TRANS_SB_DIRTY)) {
 		idelta = tp->t_icount_delta;
 		ifreedelta = tp->t_ifree_delta;
-- 
2.17.0

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

* [PATCH 03/10] xfs: consolidate mount option features in m_features
  2018-08-20  4:48 [PATCH 0/10] xfs: feature flag rework Dave Chinner
  2018-08-20  4:48 ` [PATCH 01/10] xfs: reflect sb features in xfs_mount Dave Chinner
  2018-08-20  4:48 ` [PATCH 02/10] xfs: replace xfs_sb_version checks with feature flag checks Dave Chinner
@ 2018-08-20  4:48 ` Dave Chinner
  2018-08-21 13:21   ` Brian Foster
  2018-08-20  4:48 ` [PATCH 04/10] xfs: convert mount flags to features Dave Chinner
                   ` (7 subsequent siblings)
  10 siblings, 1 reply; 27+ messages in thread
From: Dave Chinner @ 2018-08-20  4:48 UTC (permalink / raw)
  To: linux-xfs

From: Dave Chinner <dchinner@redhat.com>

This provides separation of mount time feature flags from runtime
mount flagsi and mount option state. It also makes the feature
checks use the same interface as the superblock features. i.e. we
don't care if the feature is enabled by superblock flags or mount
options, we just care if it's enabled or not.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
 fs/xfs/xfs_mount.h | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 92d947f17c69..74a128fe316b 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -225,6 +225,21 @@ typedef struct xfs_mount {
 #define XFS_FEAT_META_UUID	(1ULL << 20)	/* metadata UUID */
 #define XFS_FEAT_REALTIME	(1ULL << 21)	/* realtime device present */
 
+#define XFS_FEAT_WSYNC		(1ULL << 22)	/* synchronous metadata ops */
+#define XFS_FEAT_DIRSYNC	(1ULL << 23)	/* synchronous directory ops */
+#define XFS_FEAT_DISCARD	(1ULL << 24)	/* discard unused blocks */
+#define XFS_FEAT_GRPID		(1ULL << 25)	/* group-ID assigned from directory */
+#define XFS_FEAT_SMALL_INUMS	(1ULL << 26)	/* user wants 32bit inodes */
+#define XFS_FEAT_IKEEP		(1ULL << 27)	/* keep empty inode clusters*/
+#define XFS_FEAT_SWALLOC	(1ULL << 28)	/* stripe width allocation */
+#define XFS_FEAT_FILESTREAMS	(1ULL << 29)	/* enable the filestreams
+						   allocator */
+#define XFS_FEAT_DAX		(1ULL << 30)	/* TEST ONLY! */
+#define XFS_FEAT_COMPAT_IOSIZE	(1ULL << 31)	/* don't report large preferred
+						 * I/O size in stat() */
+#define XFS_FEAT_NORECOVERY	(1ULL << 32)	/* no recovery - dirty fs */
+#define XFS_FEAT_NOUUID		(1ULL << 33)	/* ignore uuid during mount */
+
 #define __XFS_HAS_FEAT(name, NAME) \
 static inline bool xfs_has_ ## name (struct xfs_mount *mp) \
 { \
@@ -250,6 +265,7 @@ static inline void xfs_feat_remove_ ## name (struct xfs_mount *mp) \
 }
 
 
+/* superblock features */
 __XFS_HAS_ADDFEAT(attr, ATTR)
 __XFS_HAS_FEAT(nlink, NLINK)
 __XFS_HAS_ADDFEAT(quota, QUOTA)
@@ -274,6 +290,26 @@ __XFS_HAS_FEAT(metauuid, META_UUID)
 __XFS_HAS_FEAT(realtime, REALTIME)
 
 
+/*
+ * Mount features
+ *
+ * These do not change dynamically - features that can come and go,
+ * such as 32 bit inodes and read-only state, are kept as flags rather than
+ * features.
+ */
+__XFS_HAS_FEAT(wsync, WSYNC)
+__XFS_HAS_FEAT(dirsync, DIRSYNC)
+__XFS_HAS_FEAT(discard, DISCARD)
+__XFS_HAS_FEAT(grpid, GRPID)
+__XFS_HAS_FEAT(small_inums, SMALL_INUMS)
+__XFS_HAS_FEAT(ikeep, IKEEP)
+__XFS_HAS_FEAT(swalloc, SWALLOC)
+__XFS_HAS_FEAT(filestreams, FILESTREAMS)
+__XFS_HAS_FEAT(dax, DAX)
+__XFS_HAS_FEAT(compat_iosize, COMPAT_IOSIZE)
+__XFS_HAS_FEAT(norecovery, NORECOVERY)
+__XFS_HAS_FEAT(nouuid, NOUUID)
+
 /*
  * Flags for m_flags.
  */
-- 
2.17.0

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

* [PATCH 04/10] xfs: convert mount flags to features
  2018-08-20  4:48 [PATCH 0/10] xfs: feature flag rework Dave Chinner
                   ` (2 preceding siblings ...)
  2018-08-20  4:48 ` [PATCH 03/10] xfs: consolidate mount option features in m_features Dave Chinner
@ 2018-08-20  4:48 ` Dave Chinner
  2018-08-21 13:22   ` Brian Foster
  2018-08-20  4:48 ` [PATCH 05/10] xfs: convert remaining mount flags to state flags Dave Chinner
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 27+ messages in thread
From: Dave Chinner @ 2018-08-20  4:48 UTC (permalink / raw)
  To: linux-xfs

From: Dave Chinner <dchinner@redhat.com>

Replace m_flags feature checks with xfs_has_<feature>() calls and
rework the setup code to set flags in m_features.

Fallout is that there are some attr2/noattr2 changes - there's no
longer separate feature flags for the attr2 superblock and attr2
mount options - they both set the same flag. Hence we use the
noattr2 feature to trigger turning off attr2 at mount time - it
doesn't matter if it is the mount option or the sb feature that set
it, specifying noattr2 will turn off attr2 for the current mount and
clear it from the sb feature set.

[Discuss: Might be worth moving the attr2 changes into a separate
patch so it's clear what changes are being made.]

Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
 fs/xfs/libxfs/xfs_attr.c      |   6 +-
 fs/xfs/libxfs/xfs_attr_leaf.c |  36 +++++-----
 fs/xfs/libxfs/xfs_bmap.c      |   4 +-
 fs/xfs/libxfs/xfs_ialloc.c    |  10 ++-
 fs/xfs/libxfs/xfs_inode_buf.c |   5 +-
 fs/xfs/scrub/scrub.c          |   2 +-
 fs/xfs/xfs_bmap_util.c        |   2 +-
 fs/xfs/xfs_export.c           |   2 +-
 fs/xfs/xfs_filestream.h       |   2 +-
 fs/xfs/xfs_inode.c            |  10 +--
 fs/xfs/xfs_inode.h            |   3 +-
 fs/xfs/xfs_ioctl.c            |   2 +-
 fs/xfs/xfs_iomap.c            |   6 +-
 fs/xfs/xfs_iops.c             |   7 +-
 fs/xfs/xfs_log.c              |  14 ++--
 fs/xfs/xfs_log_cil.c          |   4 +-
 fs/xfs/xfs_mount.c            |  43 +++++-------
 fs/xfs/xfs_mount.h            |  52 +++++----------
 fs/xfs/xfs_super.c            | 119 +++++++++++++++-------------------
 fs/xfs/xfs_symlink.c          |   3 +-
 20 files changed, 144 insertions(+), 188 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index 1e671d4eb6fa..5ca0233fe135 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -294,7 +294,7 @@ xfs_attr_set(
 			 * the transaction goes to disk before returning
 			 * to the user.
 			 */
-			if (mp->m_flags & XFS_MOUNT_WSYNC)
+			if (xfs_has_wsync(mp))
 				xfs_trans_set_sync(args.trans);
 
 			if (!error && (flags & ATTR_KERNOTIME) == 0) {
@@ -347,7 +347,7 @@ xfs_attr_set(
 	 * If this is a synchronous mount, make sure that the
 	 * transaction goes to disk before returning to the user.
 	 */
-	if (mp->m_flags & XFS_MOUNT_WSYNC)
+	if (xfs_has_wsync(mp))
 		xfs_trans_set_sync(args.trans);
 
 	if ((flags & ATTR_KERNOTIME) == 0)
@@ -441,7 +441,7 @@ xfs_attr_remove(
 	 * If this is a synchronous mount, make sure that the
 	 * transaction goes to disk before returning to the user.
 	 */
-	if (mp->m_flags & XFS_MOUNT_WSYNC)
+	if (xfs_has_wsync(mp))
 		xfs_trans_set_sync(args.trans);
 
 	if ((flags & ATTR_KERNOTIME) == 0)
diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c
index fbd53362b5bc..f9e536d6dd72 100644
--- a/fs/xfs/libxfs/xfs_attr_leaf.c
+++ b/fs/xfs/libxfs/xfs_attr_leaf.c
@@ -448,7 +448,7 @@ xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes)
 	 * literal area, but for the old format we are done if there is no
 	 * space in the fixed attribute fork.
 	 */
-	if (!(mp->m_flags & XFS_MOUNT_ATTR2))
+	if (!xfs_has_attr2(mp))
 		return 0;
 
 	dsize = dp->i_df.if_bytes;
@@ -502,21 +502,26 @@ xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes)
 }
 
 /*
- * Switch on the ATTR2 superblock bit (implies also FEATURES2)
+ * Switch on the ATTR2 superblock bit (implies also FEATURES2) by default unless
+ * we've explicitly been told not to use attr2 (i.e. noattr2 mount option).
  */
 STATIC void
 xfs_sbversion_add_attr2(xfs_mount_t *mp, xfs_trans_t *tp)
 {
-	if ((mp->m_flags & XFS_MOUNT_ATTR2) &&
-	    !(xfs_has_attr2(mp))) {
-		spin_lock(&mp->m_sb_lock);
-		if (!xfs_has_attr2(mp)) {
-			xfs_feat_add_attr2(mp);
-			spin_unlock(&mp->m_sb_lock);
-			xfs_log_sb(tp);
-		} else
-			spin_unlock(&mp->m_sb_lock);
+	if (xfs_has_attr2(mp))
+		return;
+	if (xfs_has_noattr2(mp))
+		return;
+
+	spin_lock(&mp->m_sb_lock);
+	if (xfs_has_attr2(mp)) {
+		spin_unlock(&mp->m_sb_lock);
+		return;
 	}
+
+	xfs_feat_add_attr2(mp);
+	spin_unlock(&mp->m_sb_lock);
+	xfs_log_sb(tp);
 }
 
 /*
@@ -671,8 +676,7 @@ xfs_attr_shortform_remove(xfs_da_args_t *args)
 	 * Fix up the start offset of the attribute fork
 	 */
 	totsize -= size;
-	if (totsize == sizeof(xfs_attr_sf_hdr_t) &&
-	    (mp->m_flags & XFS_MOUNT_ATTR2) &&
+	if (totsize == sizeof(xfs_attr_sf_hdr_t) && xfs_has_attr2(mp) &&
 	    (dp->i_d.di_format != XFS_DINODE_FMT_BTREE) &&
 	    !(args->op_flags & XFS_DA_OP_ADDNAME)) {
 		xfs_attr_fork_remove(dp, args->trans);
@@ -682,7 +686,7 @@ xfs_attr_shortform_remove(xfs_da_args_t *args)
 		ASSERT(dp->i_d.di_forkoff);
 		ASSERT(totsize > sizeof(xfs_attr_sf_hdr_t) ||
 				(args->op_flags & XFS_DA_OP_ADDNAME) ||
-				!(mp->m_flags & XFS_MOUNT_ATTR2) ||
+				!xfs_has_attr2(mp) ||
 				dp->i_d.di_format == XFS_DINODE_FMT_BTREE);
 		xfs_trans_log_inode(args->trans, dp,
 					XFS_ILOG_CORE | XFS_ILOG_ADATA);
@@ -888,7 +892,7 @@ xfs_attr_shortform_allfit(
 				+ name_loc->namelen
 				+ be16_to_cpu(name_loc->valuelen);
 	}
-	if ((dp->i_mount->m_flags & XFS_MOUNT_ATTR2) &&
+	if (xfs_has_attr2(mp) &&
 	    (dp->i_d.di_format != XFS_DINODE_FMT_BTREE) &&
 	    (bytes == sizeof(struct xfs_attr_sf_hdr)))
 		return -1;
@@ -1011,7 +1015,7 @@ xfs_attr3_leaf_to_shortform(
 		goto out;
 
 	if (forkoff == -1) {
-		ASSERT(dp->i_mount->m_flags & XFS_MOUNT_ATTR2);
+		ASSERT(xfs_has_attr2(dp->i_mount));
 		ASSERT(dp->i_d.di_format != XFS_DINODE_FMT_BTREE);
 		xfs_attr_fork_remove(dp, args->trans);
 		goto out;
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index 777630f3066a..459b08856f3f 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -1079,7 +1079,7 @@ xfs_bmap_add_attrfork(
 		ip->i_d.di_forkoff = xfs_attr_shortform_bytesfit(ip, size);
 		if (!ip->i_d.di_forkoff)
 			ip->i_d.di_forkoff = xfs_default_attroffset(ip) >> 3;
-		else if (mp->m_flags & XFS_MOUNT_ATTR2)
+		else if (!xfs_has_noattr2(mp))
 			version = 2;
 		break;
 	default:
@@ -3386,7 +3386,7 @@ xfs_bmap_btalloc(
 
 	/* stripe alignment for allocation is determined by mount parameters */
 	stripe_align = 0;
-	if (mp->m_swidth && (mp->m_flags & XFS_MOUNT_SWALLOC))
+	if (mp->m_swidth && xfs_has_swalloc(mp))
 		stripe_align = mp->m_swidth;
 	else if (mp->m_dalign)
 		stripe_align = mp->m_dalign;
diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c
index 8d23491badb7..ffb1caf4c34a 100644
--- a/fs/xfs/libxfs/xfs_ialloc.c
+++ b/fs/xfs/libxfs/xfs_ialloc.c
@@ -723,7 +723,7 @@ xfs_ialloc_ag_alloc(
 		 */
 		isaligned = 0;
 		if (args.mp->m_sinoalign) {
-			ASSERT(!(args.mp->m_flags & XFS_MOUNT_NOALIGN));
+			ASSERT(!xfs_has_noalign(args.mp));
 			args.alignment = args.mp->m_dalign;
 			isaligned = 1;
 		} else
@@ -1974,8 +1974,7 @@ xfs_difree_inobt(
 	 * remove the chunk if the block size is large enough for multiple inode
 	 * chunks (that might not be free).
 	 */
-	if (!(mp->m_flags & XFS_MOUNT_IKEEP) &&
-	    rec.ir_free == XFS_INOBT_ALL_FREE &&
+	if (!xfs_has_ikeep(mp) && rec.ir_free == XFS_INOBT_ALL_FREE &&
 	    mp->m_sb.sb_inopblock <= XFS_INODES_PER_CHUNK) {
 		xic->deleted = true;
 		xic->first_ino = XFS_AGINO_TO_INO(mp, agno, rec.ir_startino);
@@ -2112,9 +2111,8 @@ xfs_difree_finobt(
 	 * enough for multiple chunks. Leave the finobt record to remain in sync
 	 * with the inobt.
 	 */
-	if (rec.ir_free == XFS_INOBT_ALL_FREE &&
-	    mp->m_sb.sb_inopblock <= XFS_INODES_PER_CHUNK &&
-	    !(mp->m_flags & XFS_MOUNT_IKEEP)) {
+	if (!xfs_has_ikeep(mp) && rec.ir_free == XFS_INOBT_ALL_FREE &&
+	    mp->m_sb.sb_inopblock <= XFS_INODES_PER_CHUNK) {
 		error = xfs_btree_delete(cur, &i);
 		if (error)
 			goto error;
diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c
index 6eb9f967d087..1d5389ad6502 100644
--- a/fs/xfs/libxfs/xfs_inode_buf.c
+++ b/fs/xfs/libxfs/xfs_inode_buf.c
@@ -573,7 +573,7 @@ xfs_dinode_calc_crc(
  * Read the disk inode attributes into the in-core inode structure.
  *
  * For version 5 superblocks, if we are initialising a new inode and we are not
- * utilising the XFS_MOUNT_IKEEP inode cluster mode, we can simple build the new
+ * utilising the XFS_FEAT_IKEEP inode cluster mode, we can simple build the new
  * inode core with a random generation number. If we are keeping inodes around,
  * we need to read the inode cluster to get the existing generation number off
  * disk. Further, if we are using version 4 superblocks (i.e. v1/v2 inode
@@ -602,8 +602,7 @@ xfs_iread(
 
 	/* shortcut IO on inode allocation if possible */
 	if ((iget_flags & XFS_IGET_CREATE) &&
-	    xfs_has_crc(mp) &&
-	    !(mp->m_flags & XFS_MOUNT_IKEEP)) {
+	    xfs_has_crc(mp) && !xfs_has_ikeep(mp)) {
 		/* initialise the on-disk inode core */
 		memset(&ip->i_d, 0, sizeof(ip->i_d));
 		VFS_I(ip)->i_generation = prandom_u32();
diff --git a/fs/xfs/scrub/scrub.c b/fs/xfs/scrub/scrub.c
index 4c486e89829d..a3698e9b084a 100644
--- a/fs/xfs/scrub/scrub.c
+++ b/fs/xfs/scrub/scrub.c
@@ -495,7 +495,7 @@ xfs_scrub_metadata(
 	if (XFS_FORCED_SHUTDOWN(mp))
 		goto out;
 	error = -ENOTRECOVERABLE;
-	if (mp->m_flags & XFS_MOUNT_NORECOVERY)
+	if (xfs_has_norecovery(mp))
 		goto out;
 
 	error = xchk_validate_inputs(mp, sm);
diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c
index 2647e4ef8dc5..bd733b256fee 100644
--- a/fs/xfs/xfs_bmap_util.c
+++ b/fs/xfs/xfs_bmap_util.c
@@ -1978,7 +1978,7 @@ xfs_swap_extents(
 	 * If this is a synchronous mount, make sure that the
 	 * transaction goes to disk before returning to the user.
 	 */
-	if (mp->m_flags & XFS_MOUNT_WSYNC)
+	if (xfs_has_wsync(mp))
 		xfs_trans_set_sync(tp);
 
 	error = xfs_trans_commit(tp);
diff --git a/fs/xfs/xfs_export.c b/fs/xfs/xfs_export.c
index f2284ceb129f..cc1f7d09102f 100644
--- a/fs/xfs/xfs_export.c
+++ b/fs/xfs/xfs_export.c
@@ -66,7 +66,7 @@ xfs_fs_encode_fh(
 	 * large enough filesystem may contain them, thus the slightly
 	 * confusing looking conditional below.
 	 */
-	if (!(XFS_M(inode->i_sb)->m_flags & XFS_MOUNT_SMALL_INUMS) ||
+	if (!xfs_has_small_inums(XFS_M(inode->i_sb)) ||
 	    (XFS_M(inode->i_sb)->m_flags & XFS_MOUNT_32BITINODES))
 		fileid_type |= XFS_FILEID_TYPE_64FLAG;
 
diff --git a/fs/xfs/xfs_filestream.h b/fs/xfs/xfs_filestream.h
index 5cc7665e93c9..c8760fffdda7 100644
--- a/fs/xfs/xfs_filestream.h
+++ b/fs/xfs/xfs_filestream.h
@@ -21,7 +21,7 @@ static inline int
 xfs_inode_is_filestream(
 	struct xfs_inode	*ip)
 {
-	return (ip->i_mount->m_flags & XFS_MOUNT_FILESTREAMS) ||
+	return xfs_has_filestreams(ip->i_mount) ||
 		(ip->i_d.di_flags & XFS_DIFLAG_FILESTREAM);
 }
 
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index d957a46dc1cb..0f67ca516c87 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -1245,7 +1245,7 @@ xfs_create(
 	 * create transaction goes to disk before returning to
 	 * the user.
 	 */
-	if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC))
+	if (xfs_has_wsync(mp) || xfs_has_dirsync(mp))
 		xfs_trans_set_sync(tp);
 
 	/*
@@ -1336,7 +1336,7 @@ xfs_create_tmpfile(
 	if (error)
 		goto out_trans_cancel;
 
-	if (mp->m_flags & XFS_MOUNT_WSYNC)
+	if (xfs_has_wsync(mp))
 		xfs_trans_set_sync(tp);
 
 	/*
@@ -1463,7 +1463,7 @@ xfs_link(
 	 * link transaction goes to disk before returning to
 	 * the user.
 	 */
-	if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC))
+	if (xfs_has_wsync(mp) || xfs_has_dirsync(mp))
 		xfs_trans_set_sync(tp);
 
 	return xfs_trans_commit(tp);
@@ -2627,7 +2627,7 @@ xfs_remove(
 	 * remove transaction goes to disk before returning to
 	 * the user.
 	 */
-	if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC))
+	if (xfs_has_wsync(mp) || xfs_has_dirsync(mp))
 		xfs_trans_set_sync(tp);
 
 	error = xfs_trans_commit(tp);
@@ -2704,7 +2704,7 @@ xfs_finish_rename(
 	 * If this is a synchronous mount, make sure that the rename transaction
 	 * goes to disk before returning to the user.
 	 */
-	if (tp->t_mountp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC))
+	if (xfs_has_wsync(tp->t_mountp) || xfs_has_dirsync(tp->t_mountp))
 		xfs_trans_set_sync(tp);
 
 	return xfs_trans_commit(tp);
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index be2014520155..40bc71d49220 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -394,8 +394,7 @@ enum layout_break_reason {
  * new subdirectory gets S_ISGID bit from parent.
  */
 #define XFS_INHERIT_GID(pip)	\
-	(((pip)->i_mount->m_flags & XFS_MOUNT_GRPID) || \
-	 (VFS_I(pip)->i_mode & S_ISGID))
+	(xfs_has_grpid((pip)->i_mount) || (VFS_I(pip)->i_mode & S_ISGID))
 
 int		xfs_release(struct xfs_inode *ip);
 void		xfs_inactive(struct xfs_inode *ip);
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index 4f4c6cd81b54..350b9276e6fe 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -1167,7 +1167,7 @@ xfs_ioctl_setattr_get_trans(
 		goto out_cancel;
 	}
 
-	if (mp->m_flags & XFS_MOUNT_WSYNC)
+	if (xfs_has_wsync(mp))
 		xfs_trans_set_sync(tp);
 
 	return tp;
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 6320aca39f39..3c999ea64021 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -79,7 +79,7 @@ xfs_eof_alignment(
 		 * If mounted with the "-o swalloc" option the alignment is
 		 * increased from the strip unit size to the stripe width.
 		 */
-		if (mp->m_swidth && (mp->m_flags & XFS_MOUNT_SWALLOC))
+		if (mp->m_swidth && xfs_has_swalloc(mp))
 			align = mp->m_swidth;
 		else if (mp->m_dalign)
 			align = mp->m_dalign;
@@ -385,7 +385,7 @@ xfs_iomap_prealloc_size(
 	if (offset + count <= XFS_ISIZE(ip))
 		return 0;
 
-	if (!(mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) &&
+	if (!xfs_has_iosize(mp) &&
 	    (XFS_ISIZE(ip) < XFS_FSB_TO_B(mp, mp->m_writeio_blocks)))
 		return 0;
 
@@ -393,7 +393,7 @@ xfs_iomap_prealloc_size(
 	 * If an explicit allocsize is set, the file is small, or we
 	 * are writing behind a hole, then use the minimum prealloc:
 	 */
-	if ((mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) ||
+	if (xfs_has_iosize(mp) ||
 	    XFS_ISIZE(ip) < XFS_FSB_TO_B(mp, mp->m_dalign) ||
 	    !xfs_iext_peek_prev_extent(ifp, icur, &prev) ||
 	    prev.br_startoff + prev.br_blockcount < offset_fsb)
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index 066a97d108f5..0241471916d9 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -742,7 +742,7 @@ xfs_setattr_nonsize(
 
 	XFS_STATS_INC(mp, xs_ig_attrchg);
 
-	if (mp->m_flags & XFS_MOUNT_WSYNC)
+	if (xfs_has_wsync(mp))
 		xfs_trans_set_sync(tp);
 	error = xfs_trans_commit(tp);
 
@@ -980,7 +980,7 @@ xfs_setattr_size(
 
 	XFS_STATS_INC(mp, xs_ig_attrchg);
 
-	if (mp->m_flags & XFS_MOUNT_WSYNC)
+	if (xfs_has_wsync(mp))
 		xfs_trans_set_sync(tp);
 
 	error = xfs_trans_commit(tp);
@@ -1200,8 +1200,7 @@ xfs_inode_supports_dax(
 		return false;
 
 	/* DAX mount option or DAX iflag must be set. */
-	if (!(mp->m_flags & XFS_MOUNT_DAX) &&
-	    !(ip->i_d.di_flags2 & XFS_DIFLAG2_DAX))
+	if (!xfs_has_dax(mp) && !(ip->i_d.di_flags2 & XFS_DIFLAG2_DAX))
 		return false;
 
 	/* Block size must match page size */
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index 7ad8c7bb1345..bcc068dee92a 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -600,7 +600,7 @@ xfs_log_mount(
 	int		error = 0;
 	int		min_logfsbs;
 
-	if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) {
+	if (!xfs_has_norecovery(mp)) {
 		xfs_notice(mp, "Mounting V%d Filesystem",
 			   XFS_SB_VERSION_NUM(&mp->m_sb));
 	} else {
@@ -685,8 +685,8 @@ xfs_log_mount(
 	 * skip log recovery on a norecovery mount.  pretend it all
 	 * just worked.
 	 */
-	if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) {
-		int	readonly = (mp->m_flags & XFS_MOUNT_RDONLY);
+	if (!xfs_has_norecovery(mp)) {
+		bool	readonly = (mp->m_flags & XFS_MOUNT_RDONLY);
 
 		if (readonly)
 			mp->m_flags &= ~XFS_MOUNT_RDONLY;
@@ -746,8 +746,8 @@ xfs_log_mount_finish(
 	bool	readonly = (mp->m_flags & XFS_MOUNT_RDONLY);
 	bool	recovered = mp->m_log->l_flags & XLOG_RECOVERY_NEEDED;
 
-	if (mp->m_flags & XFS_MOUNT_NORECOVERY) {
-		ASSERT(mp->m_flags & XFS_MOUNT_RDONLY);
+	if (xfs_has_norecovery(mp)) {
+		ASSERT(readonly);
 		return 0;
 	} else if (readonly) {
 		/* Allow unlinked processing to proceed */
@@ -930,7 +930,7 @@ xfs_log_unmount_write(xfs_mount_t *mp)
 	 * Don't write out unmount record on norecovery mounts or ro devices.
 	 * Or, if we are doing a forced umount (typically because of IO errors).
 	 */
-	if (mp->m_flags & XFS_MOUNT_NORECOVERY ||
+	if (xfs_has_norecovery(mp) ||
 	    xfs_readonly_buftarg(log->l_mp->m_logdev_targp)) {
 		ASSERT(mp->m_flags & XFS_MOUNT_RDONLY);
 		return 0;
@@ -4079,7 +4079,7 @@ xfs_log_check_lsn(
 	 * resets the in-core LSN. We can't validate in this mode, but
 	 * modifications are not allowed anyways so just return true.
 	 */
-	if (mp->m_flags & XFS_MOUNT_NORECOVERY)
+	if (xfs_has_norecovery(mp))
 		return true;
 
 	/*
diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c
index d3884e08b43c..c4f71e600f00 100644
--- a/fs/xfs/xfs_log_cil.c
+++ b/fs/xfs/xfs_log_cil.c
@@ -538,7 +538,7 @@ xlog_discard_busy_extents(
 	struct blk_plug		plug;
 	int			error = 0;
 
-	ASSERT(mp->m_flags & XFS_MOUNT_DISCARD);
+	ASSERT(xfs_has_discard(mp));
 
 	blk_start_plug(&plug);
 	list_for_each_entry(busyp, list, list) {
@@ -587,7 +587,7 @@ xlog_cil_committed(
 
 	xfs_extent_busy_sort(&ctx->busy_extents);
 	xfs_extent_busy_clear(mp, &ctx->busy_extents,
-			     (mp->m_flags & XFS_MOUNT_DISCARD) && !abort);
+			      xfs_has_discard(mp) && !abort);
 
 	/*
 	 * If we are aborting the commit, wake up anyone waiting on the
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 212ae2695b88..624387661cbc 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -64,7 +64,7 @@ xfs_uuid_mount(
 	/* Publish UUID in struct super_block */
 	uuid_copy(&mp->m_super->s_uuid, uuid);
 
-	if (mp->m_flags & XFS_MOUNT_NOUUID)
+	if (xfs_has_nouuid(mp))
 		return 0;
 
 	if (uuid_is_null(uuid)) {
@@ -106,7 +106,7 @@ xfs_uuid_unmount(
 	uuid_t			*uuid = &mp->m_sb.sb_uuid;
 	int			i;
 
-	if (mp->m_flags & XFS_MOUNT_NOUUID)
+	if (xfs_has_nouuid(mp))
 		return;
 
 	mutex_lock(&xfs_uuid_table_mutex);
@@ -414,8 +414,7 @@ xfs_update_alignment(xfs_mount_t *mp)
 	"cannot change alignment: superblock does not support data alignment");
 			return -EINVAL;
 		}
-	} else if ((mp->m_flags & XFS_MOUNT_NOALIGN) != XFS_MOUNT_NOALIGN &&
-		    xfs_has_dalign(mp)) {
+	} else if (xfs_has_dalign(mp) && !xfs_has_noalign(mp)) {
 			mp->m_dalign = sbp->sb_unit;
 			mp->m_swidth = sbp->sb_width;
 	}
@@ -454,22 +453,21 @@ xfs_set_maxicount(xfs_mount_t *mp)
  * is being used for NFS service (wsync mount option).
  */
 STATIC void
-xfs_set_rw_sizes(xfs_mount_t *mp)
+xfs_set_rw_sizes(
+	struct xfs_mount *mp)
 {
-	xfs_sb_t	*sbp = &(mp->m_sb);
+	struct xfs_sb	*sbp = &mp->m_sb;
 	int		readio_log, writeio_log;
 
-	if (!(mp->m_flags & XFS_MOUNT_DFLT_IOSIZE)) {
-		if (mp->m_flags & XFS_MOUNT_WSYNC) {
-			readio_log = XFS_WSYNC_READIO_LOG;
-			writeio_log = XFS_WSYNC_WRITEIO_LOG;
-		} else {
-			readio_log = XFS_READIO_LOG_LARGE;
-			writeio_log = XFS_WRITEIO_LOG_LARGE;
-		}
-	} else {
+	if (xfs_has_iosize(mp)) {
 		readio_log = mp->m_readio_log;
 		writeio_log = mp->m_writeio_log;
+	} else if (xfs_has_wsync(mp)) {
+		readio_log = XFS_WSYNC_READIO_LOG;
+		writeio_log = XFS_WSYNC_WRITEIO_LOG;
+	} else {
+		readio_log = XFS_READIO_LOG_LARGE;
+		writeio_log = XFS_WRITEIO_LOG_LARGE;
 	}
 
 	if (sbp->sb_blocklog > readio_log) {
@@ -704,18 +702,9 @@ xfs_mountfs(
 		xfs_warn(mp, "correcting sb_features alignment problem");
 		sbp->sb_features2 |= sbp->sb_bad_features2;
 		mp->m_update_sb = true;
-
-		/*
-		 * Re-check for ATTR2 in case it was found in bad_features2
-		 * slot.
-		 */
-		if (xfs_has_attr2(mp) &&
-		   !(mp->m_flags & XFS_MOUNT_NOATTR2))
-			mp->m_flags |= XFS_MOUNT_ATTR2;
 	}
 
-	if (xfs_has_attr2(mp) &&
-	   (mp->m_flags & XFS_MOUNT_NOATTR2)) {
+	if (xfs_has_attr2(mp) && xfs_has_noattr2(mp)) {
 		xfs_feat_remove_attr2(mp);
 		mp->m_update_sb = true;
 
@@ -988,10 +977,8 @@ xfs_mountfs(
 	 * We use the same quiesce mechanism as the rw->ro remount, as they are
 	 * semantically identical operations.
 	 */
-	if ((mp->m_flags & (XFS_MOUNT_RDONLY|XFS_MOUNT_NORECOVERY)) ==
-							XFS_MOUNT_RDONLY) {
+	if ((mp->m_flags & XFS_MOUNT_RDONLY) && !xfs_has_norecovery(mp))
 		xfs_quiesce_attr(mp);
-	}
 
 	/*
 	 * Complete the quota initialisation, post-log-replay component.
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 74a128fe316b..fee11d015b5a 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -228,17 +228,19 @@ typedef struct xfs_mount {
 #define XFS_FEAT_WSYNC		(1ULL << 22)	/* synchronous metadata ops */
 #define XFS_FEAT_DIRSYNC	(1ULL << 23)	/* synchronous directory ops */
 #define XFS_FEAT_DISCARD	(1ULL << 24)	/* discard unused blocks */
-#define XFS_FEAT_GRPID		(1ULL << 25)	/* group-ID assigned from directory */
+#define XFS_FEAT_GRPID		(1ULL << 25)	/* GID assigned from directory */
 #define XFS_FEAT_SMALL_INUMS	(1ULL << 26)	/* user wants 32bit inodes */
 #define XFS_FEAT_IKEEP		(1ULL << 27)	/* keep empty inode clusters*/
 #define XFS_FEAT_SWALLOC	(1ULL << 28)	/* stripe width allocation */
-#define XFS_FEAT_FILESTREAMS	(1ULL << 29)	/* enable the filestreams
-						   allocator */
+#define XFS_FEAT_FILESTREAMS	(1ULL << 29)	/* use filestreams allocator */
 #define XFS_FEAT_DAX		(1ULL << 30)	/* TEST ONLY! */
-#define XFS_FEAT_COMPAT_IOSIZE	(1ULL << 31)	/* don't report large preferred
+#define XFS_FEAT_IOSIZE		(1ULL << 31)	/* user specified iosize */
+#define XFS_FEAT_COMPAT_IOSIZE	(1ULL << 32)	/* don't report large preferred
 						 * I/O size in stat() */
-#define XFS_FEAT_NORECOVERY	(1ULL << 32)	/* no recovery - dirty fs */
-#define XFS_FEAT_NOUUID		(1ULL << 33)	/* ignore uuid during mount */
+#define XFS_FEAT_NORECOVERY	(1ULL << 33)	/* no recovery - dirty fs */
+#define XFS_FEAT_NOUUID		(1ULL << 34)	/* ignore uuid during mount */
+#define XFS_FEAT_NOATTR2	(1ULL << 35)	/* disable attr2 completely */
+#define XFS_FEAT_NOALIGN	(1ULL << 36)	/* ignore alignment */
 
 #define __XFS_HAS_FEAT(name, NAME) \
 static inline bool xfs_has_ ## name (struct xfs_mount *mp) \
@@ -306,44 +308,24 @@ __XFS_HAS_FEAT(ikeep, IKEEP)
 __XFS_HAS_FEAT(swalloc, SWALLOC)
 __XFS_HAS_FEAT(filestreams, FILESTREAMS)
 __XFS_HAS_FEAT(dax, DAX)
+__XFS_HAS_FEAT(iosize, IOSIZE)
 __XFS_HAS_FEAT(compat_iosize, COMPAT_IOSIZE)
 __XFS_HAS_FEAT(norecovery, NORECOVERY)
 __XFS_HAS_FEAT(nouuid, NOUUID)
+__XFS_HAS_FEAT(noattr2, NOATTR2)
+__XFS_HAS_FEAT(noalign, NOALIGN)
 
 /*
  * Flags for m_flags.
  */
-#define XFS_MOUNT_WSYNC		(1ULL << 0)	/* for nfs - all metadata ops
-						   must be synchronous except
-						   for space allocations */
 #define XFS_MOUNT_UNMOUNTING	(1ULL << 1)	/* filesystem is unmounting */
 #define XFS_MOUNT_BAD_SUMMARY	(1ULL << 2)	/* summary counters are bad */
 #define XFS_MOUNT_WAS_CLEAN	(1ULL << 3)
 #define XFS_MOUNT_FS_SHUTDOWN	(1ULL << 4)	/* atomic stop of all filesystem
 						   operations, typically for
 						   disk errors in metadata */
-#define XFS_MOUNT_DISCARD	(1ULL << 5)	/* discard unused blocks */
-#define XFS_MOUNT_NOALIGN	(1ULL << 7)	/* turn off stripe alignment
-						   allocations */
-#define XFS_MOUNT_ATTR2		(1ULL << 8)	/* allow use of attr2 format */
-#define XFS_MOUNT_GRPID		(1ULL << 9)	/* group-ID assigned from directory */
-#define XFS_MOUNT_NORECOVERY	(1ULL << 10)	/* no recovery - dirty fs */
-#define XFS_MOUNT_DFLT_IOSIZE	(1ULL << 12)	/* set default i/o size */
-#define XFS_MOUNT_SMALL_INUMS	(1ULL << 14)	/* user wants 32bit inodes */
 #define XFS_MOUNT_32BITINODES	(1ULL << 15)	/* inode32 allocator active */
-#define XFS_MOUNT_NOUUID	(1ULL << 16)	/* ignore uuid during mount */
-#define XFS_MOUNT_IKEEP		(1ULL << 18)	/* keep empty inode clusters*/
-#define XFS_MOUNT_SWALLOC	(1ULL << 19)	/* turn on stripe width
-						 * allocation */
 #define XFS_MOUNT_RDONLY	(1ULL << 20)	/* read-only fs */
-#define XFS_MOUNT_DIRSYNC	(1ULL << 21)	/* synchronous directory ops */
-#define XFS_MOUNT_COMPAT_IOSIZE	(1ULL << 22)	/* don't report large preferred
-						 * I/O size in stat() */
-#define XFS_MOUNT_FILESTREAMS	(1ULL << 24)	/* enable the filestreams
-						   allocator */
-#define XFS_MOUNT_NOATTR2	(1ULL << 25)	/* disable use of attr2 format */
-
-#define XFS_MOUNT_DAX		(1ULL << 62)	/* TEST ONLY! */
 
 
 /*
@@ -381,13 +363,13 @@ __XFS_HAS_FEAT(nouuid, NOUUID)
 static inline unsigned long
 xfs_preferred_iosize(xfs_mount_t *mp)
 {
-	if (mp->m_flags & XFS_MOUNT_COMPAT_IOSIZE)
+	if (xfs_has_compat_iosize(mp))
 		return PAGE_SIZE;
-	return (mp->m_swidth ?
-		(mp->m_swidth << mp->m_sb.sb_blocklog) :
-		((mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) ?
-			(1 << (int)max(mp->m_readio_log, mp->m_writeio_log)) :
-			PAGE_SIZE));
+	if (mp->m_swidth)
+		return mp->m_swidth << mp->m_sb.sb_blocklog;
+	if (xfs_has_iosize(mp))
+		return 1 << (int)max(mp->m_readio_log, mp->m_writeio_log);
+	return PAGE_SIZE;
 }
 
 #define XFS_LAST_UNMOUNT_WAS_CLEAN(mp)	\
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index cf76884c2a95..d3dff878be99 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -193,15 +193,15 @@ xfs_parseargs(
 	if (sb_rdonly(sb))
 		mp->m_flags |= XFS_MOUNT_RDONLY;
 	if (sb->s_flags & SB_DIRSYNC)
-		mp->m_flags |= XFS_MOUNT_DIRSYNC;
+		mp->m_features |= XFS_FEAT_DIRSYNC;
 	if (sb->s_flags & SB_SYNCHRONOUS)
-		mp->m_flags |= XFS_MOUNT_WSYNC;
+		mp->m_features |= XFS_FEAT_WSYNC;
 
 	/*
 	 * Set some default flags that could be cleared by the mount option
 	 * parsing.
 	 */
-	mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
+	mp->m_features |= XFS_FEAT_COMPAT_IOSIZE;
 
 	/*
 	 * These can be overridden by the mount option parsing.
@@ -251,23 +251,23 @@ xfs_parseargs(
 			break;
 		case Opt_grpid:
 		case Opt_bsdgroups:
-			mp->m_flags |= XFS_MOUNT_GRPID;
+			mp->m_features |= XFS_FEAT_GRPID;
 			break;
 		case Opt_nogrpid:
 		case Opt_sysvgroups:
-			mp->m_flags &= ~XFS_MOUNT_GRPID;
+			mp->m_features &= ~XFS_FEAT_GRPID;
 			break;
 		case Opt_wsync:
-			mp->m_flags |= XFS_MOUNT_WSYNC;
+			mp->m_features |= XFS_FEAT_WSYNC;
 			break;
 		case Opt_norecovery:
-			mp->m_flags |= XFS_MOUNT_NORECOVERY;
+			mp->m_features |= XFS_FEAT_NORECOVERY;
 			break;
 		case Opt_noalign:
-			mp->m_flags |= XFS_MOUNT_NOALIGN;
+			mp->m_features |= XFS_FEAT_NOALIGN;
 			break;
 		case Opt_swalloc:
-			mp->m_flags |= XFS_MOUNT_SWALLOC;
+			mp->m_features |= XFS_FEAT_SWALLOC;
 			break;
 		case Opt_sunit:
 			if (match_int(args, &dsunit))
@@ -278,35 +278,34 @@ xfs_parseargs(
 				return -EINVAL;
 			break;
 		case Opt_inode32:
-			mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
+			mp->m_features |= XFS_FEAT_SMALL_INUMS;
 			break;
 		case Opt_inode64:
-			mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS;
+			mp->m_features &= ~XFS_FEAT_SMALL_INUMS;
 			break;
 		case Opt_nouuid:
-			mp->m_flags |= XFS_MOUNT_NOUUID;
+			mp->m_features |= XFS_FEAT_NOUUID;
 			break;
 		case Opt_ikeep:
-			mp->m_flags |= XFS_MOUNT_IKEEP;
+			mp->m_features |= XFS_FEAT_IKEEP;
 			break;
 		case Opt_noikeep:
-			mp->m_flags &= ~XFS_MOUNT_IKEEP;
+			mp->m_features &= ~XFS_FEAT_IKEEP;
 			break;
 		case Opt_largeio:
-			mp->m_flags &= ~XFS_MOUNT_COMPAT_IOSIZE;
+			mp->m_features &= ~XFS_FEAT_COMPAT_IOSIZE;
 			break;
 		case Opt_nolargeio:
-			mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
+			mp->m_features |= XFS_FEAT_COMPAT_IOSIZE;
 			break;
 		case Opt_attr2:
-			mp->m_flags |= XFS_MOUNT_ATTR2;
+			mp->m_features |= XFS_FEAT_ATTR2;
 			break;
 		case Opt_noattr2:
-			mp->m_flags &= ~XFS_MOUNT_ATTR2;
-			mp->m_flags |= XFS_MOUNT_NOATTR2;
+			mp->m_features |= XFS_FEAT_NOATTR2;
 			break;
 		case Opt_filestreams:
-			mp->m_flags |= XFS_MOUNT_FILESTREAMS;
+			mp->m_features |= XFS_FEAT_FILESTREAMS;
 			break;
 		case Opt_noquota:
 			mp->m_qflags &= ~XFS_ALL_QUOTA_ACCT;
@@ -343,14 +342,14 @@ xfs_parseargs(
 			mp->m_qflags &= ~XFS_GQUOTA_ENFD;
 			break;
 		case Opt_discard:
-			mp->m_flags |= XFS_MOUNT_DISCARD;
+			mp->m_features |= XFS_FEAT_DISCARD;
 			break;
 		case Opt_nodiscard:
-			mp->m_flags &= ~XFS_MOUNT_DISCARD;
+			mp->m_features &= ~XFS_FEAT_DISCARD;
 			break;
 #ifdef CONFIG_FS_DAX
 		case Opt_dax:
-			mp->m_flags |= XFS_MOUNT_DAX;
+			mp->m_features |= XFS_FEAT_DAX;
 			break;
 #endif
 		default:
@@ -362,13 +361,12 @@ xfs_parseargs(
 	/*
 	 * no recovery flag requires a read-only mount
 	 */
-	if ((mp->m_flags & XFS_MOUNT_NORECOVERY) &&
-	    !(mp->m_flags & XFS_MOUNT_RDONLY)) {
+	if (xfs_has_norecovery(mp) && !(mp->m_flags & XFS_MOUNT_RDONLY)) {
 		xfs_warn(mp, "no-recovery mounts must be read-only.");
 		return -EINVAL;
 	}
 
-	if ((mp->m_flags & XFS_MOUNT_NOALIGN) && (dsunit || dswidth)) {
+	if (xfs_has_noalign(mp) && (dsunit || dswidth)) {
 		xfs_warn(mp,
 	"sunit and swidth options incompatible with the noalign option");
 		return -EINVAL;
@@ -394,7 +392,7 @@ xfs_parseargs(
 	}
 
 done:
-	if (dsunit && !(mp->m_flags & XFS_MOUNT_NOALIGN)) {
+	if (dsunit && !xfs_has_noalign(mp)) {
 		/*
 		 * At this point the superblock has not been read
 		 * in, therefore we do not know the block size.
@@ -433,7 +431,7 @@ xfs_parseargs(
 			return -EINVAL;
 		}
 
-		mp->m_flags |= XFS_MOUNT_DFLT_IOSIZE;
+		mp->m_features |= XFS_FEAT_IOSIZE;
 		mp->m_readio_log = iosizelog;
 		mp->m_writeio_log = iosizelog;
 	}
@@ -453,38 +451,38 @@ xfs_showargs(
 {
 	static struct proc_xfs_info xfs_info_set[] = {
 		/* the few simple ones we can get from the mount struct */
-		{ XFS_MOUNT_IKEEP,		",ikeep" },
-		{ XFS_MOUNT_WSYNC,		",wsync" },
-		{ XFS_MOUNT_NOALIGN,		",noalign" },
-		{ XFS_MOUNT_SWALLOC,		",swalloc" },
-		{ XFS_MOUNT_NOUUID,		",nouuid" },
-		{ XFS_MOUNT_NORECOVERY,		",norecovery" },
-		{ XFS_MOUNT_ATTR2,		",attr2" },
-		{ XFS_MOUNT_FILESTREAMS,	",filestreams" },
-		{ XFS_MOUNT_GRPID,		",grpid" },
-		{ XFS_MOUNT_DISCARD,		",discard" },
-		{ XFS_MOUNT_SMALL_INUMS,	",inode32" },
-		{ XFS_MOUNT_DAX,		",dax" },
+		{ XFS_FEAT_IKEEP,	",ikeep" },
+		{ XFS_FEAT_WSYNC,	",wsync" },
+		{ XFS_FEAT_NOALIGN,	",noalign" },
+		{ XFS_FEAT_SWALLOC,	",swalloc" },
+		{ XFS_FEAT_NOUUID,	",nouuid" },
+		{ XFS_FEAT_NORECOVERY,	",norecovery" },
+		{ XFS_FEAT_ATTR2,	",attr2" },
+		{ XFS_FEAT_FILESTREAMS,	",filestreams" },
+		{ XFS_FEAT_GRPID,	",grpid" },
+		{ XFS_FEAT_DISCARD,	",discard" },
+		{ XFS_FEAT_SMALL_INUMS,	",inode32" },
+		{ XFS_FEAT_DAX,		",dax" },
 		{ 0, NULL }
 	};
 	static struct proc_xfs_info xfs_info_unset[] = {
 		/* the few simple ones we can get from the mount struct */
-		{ XFS_MOUNT_COMPAT_IOSIZE,	",largeio" },
-		{ XFS_MOUNT_SMALL_INUMS,	",inode64" },
+		{ XFS_FEAT_COMPAT_IOSIZE, ",largeio" },
+		{ XFS_FEAT_SMALL_INUMS,	",inode64" },
 		{ 0, NULL }
 	};
 	struct proc_xfs_info	*xfs_infop;
 
 	for (xfs_infop = xfs_info_set; xfs_infop->flag; xfs_infop++) {
-		if (mp->m_flags & xfs_infop->flag)
+		if (mp->m_features & xfs_infop->flag)
 			seq_puts(m, xfs_infop->str);
 	}
 	for (xfs_infop = xfs_info_unset; xfs_infop->flag; xfs_infop++) {
-		if (!(mp->m_flags & xfs_infop->flag))
+		if (!(mp->m_features & xfs_infop->flag))
 			seq_puts(m, xfs_infop->str);
 	}
 
-	if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE)
+	if (xfs_has_iosize(mp))
 		seq_printf(m, ",allocsize=%dk",
 				(int)(1 << mp->m_writeio_log) >> 10);
 
@@ -565,10 +563,10 @@ xfs_max_file_offset(
 /*
  * Set parameters for inode allocation heuristics, taking into account
  * filesystem size and inode32/inode64 mount options; i.e. specifically
- * whether or not XFS_MOUNT_SMALL_INUMS is set.
+ * whether or not XFS_FEAT_SMALL_INUMS is set.
  *
  * Inode allocation patterns are altered only if inode32 is requested
- * (XFS_MOUNT_SMALL_INUMS), and the filesystem is sufficiently large.
+ * (XFS_FEAT_SMALL_INUMS), and the filesystem is sufficiently large.
  * If altered, XFS_MOUNT_32BITINODES is set as well.
  *
  * An agcount independent of that in the mount structure is provided
@@ -614,7 +612,7 @@ xfs_set_inode_alloc(
 	 * sufficiently large, set XFS_MOUNT_32BITINODES if we must alter
 	 * the allocator to accommodate the request.
 	 */
-	if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) && ino > XFS_MAXINUMBER_32)
+	if (xfs_has_small_inums(mp) && ino > XFS_MAXINUMBER_32)
 		mp->m_flags |= XFS_MOUNT_32BITINODES;
 	else
 		mp->m_flags &= ~XFS_MOUNT_32BITINODES;
@@ -1261,11 +1259,11 @@ xfs_fs_remount(
 		token = match_token(p, tokens, args);
 		switch (token) {
 		case Opt_inode64:
-			mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS;
+			mp->m_features &= ~XFS_FEAT_SMALL_INUMS;
 			mp->m_maxagi = xfs_set_inode_alloc(mp, sbp->sb_agcount);
 			break;
 		case Opt_inode32:
-			mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
+			mp->m_features |= XFS_FEAT_SMALL_INUMS;
 			mp->m_maxagi = xfs_set_inode_alloc(mp, sbp->sb_agcount);
 			break;
 		default:
@@ -1297,7 +1295,7 @@ xfs_fs_remount(
 
 	/* ro -> rw */
 	if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(*flags & SB_RDONLY)) {
-		if (mp->m_flags & XFS_MOUNT_NORECOVERY) {
+		if (xfs_has_norecovery(mp)) {
 			xfs_warn(mp,
 		"ro->rw transition prohibited on norecovery mount");
 			return -EINVAL;
@@ -1460,21 +1458,12 @@ xfs_finish_flags(
 	/*
 	 * V5 filesystems always use attr2 format for attributes.
 	 */
-	if (xfs_has_crc(mp) &&
-	    (mp->m_flags & XFS_MOUNT_NOATTR2)) {
+	if (xfs_has_crc(mp) && xfs_has_noattr2(mp)) {
 		xfs_warn(mp, "Cannot mount a V5 filesystem as noattr2. "
 			     "attr2 is always enabled for V5 filesystems.");
 		return -EINVAL;
 	}
 
-	/*
-	 * mkfs'ed attr2 will turn on attr2 mount unless explicitly
-	 * told by noattr2 to turn it off
-	 */
-	if (xfs_has_attr2(mp) &&
-	    !(mp->m_flags & XFS_MOUNT_NOATTR2))
-		mp->m_flags |= XFS_MOUNT_ATTR2;
-
 	/*
 	 * prohibit r/w mounts of read-only filesystems
 	 */
@@ -1662,7 +1651,7 @@ xfs_fs_fill_super(
 	if (XFS_SB_VERSION_NUM(&mp->m_sb) == XFS_SB_VERSION_5)
 		sb->s_flags |= SB_I_VERSION;
 
-	if (mp->m_flags & XFS_MOUNT_DAX) {
+	if (xfs_has_dax(mp)) {
 		bool rtdev_is_dax = false, datadev_is_dax;
 
 		xfs_warn(mp,
@@ -1676,7 +1665,7 @@ xfs_fs_fill_super(
 		if (!rtdev_is_dax && !datadev_is_dax) {
 			xfs_alert(mp,
 			"DAX unsupported by block device. Turning off DAX.");
-			mp->m_flags &= ~XFS_MOUNT_DAX;
+			mp->m_features &= ~XFS_FEAT_DAX;
 		}
 		if (xfs_has_reflink(mp)) {
 			xfs_alert(mp,
@@ -1686,13 +1675,13 @@ xfs_fs_fill_super(
 		}
 	}
 
-	if (mp->m_flags & XFS_MOUNT_DISCARD) {
+	if (xfs_has_discard(mp)) {
 		struct request_queue *q = bdev_get_queue(sb->s_bdev);
 
 		if (!blk_queue_discard(q)) {
 			xfs_warn(mp, "mounting with \"discard\" option, but "
 					"the device does not support discard");
-			mp->m_flags &= ~XFS_MOUNT_DISCARD;
+			mp->m_features &= ~XFS_FEAT_DISCARD;
 		}
 	}
 
diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c
index 647a9aa98646..675481028292 100644
--- a/fs/xfs/xfs_symlink.c
+++ b/fs/xfs/xfs_symlink.c
@@ -339,9 +339,8 @@ xfs_symlink(
 	 * symlink transaction goes to disk before returning to
 	 * the user.
 	 */
-	if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) {
+	if (xfs_has_wsync(mp) || xfs_has_dirsync(mp))
 		xfs_trans_set_sync(tp);
-	}
 
 	error = xfs_trans_commit(tp);
 	if (error)
-- 
2.17.0

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

* [PATCH 05/10] xfs: convert remaining mount flags to state flags
  2018-08-20  4:48 [PATCH 0/10] xfs: feature flag rework Dave Chinner
                   ` (3 preceding siblings ...)
  2018-08-20  4:48 ` [PATCH 04/10] xfs: convert mount flags to features Dave Chinner
@ 2018-08-20  4:48 ` Dave Chinner
  2018-08-21 13:23   ` Brian Foster
  2018-08-20  4:48 ` [PATCH 06/10] xfs: replace XFS_FORCED_SHUTDOWN with xfs_is_shut_down Dave Chinner
                   ` (5 subsequent siblings)
  10 siblings, 1 reply; 27+ messages in thread
From: Dave Chinner @ 2018-08-20  4:48 UTC (permalink / raw)
  To: linux-xfs

From: Dave Chinner <dchinner@redhat.com>

The remaining mount flags kept in m_flags are actually runtime state
flags. These change dynamically, so they really should be updated
atomically so we don't potentially lose an update dur to racing
modifications.

Rename m_flags to m_state, and convert it to use atomic bitops to
set and clear the flags. This also adds a couple of simple wrappers
for common state checks - read only and shutdown.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
 fs/xfs/libxfs/xfs_alloc.c |  2 +-
 fs/xfs/libxfs/xfs_sb.c    |  4 ++--
 fs/xfs/scrub/scrub.c      |  2 +-
 fs/xfs/xfs_buf_item.c     |  2 +-
 fs/xfs/xfs_export.c       |  5 +++--
 fs/xfs/xfs_filestream.c   |  2 +-
 fs/xfs/xfs_fsops.c        |  2 +-
 fs/xfs/xfs_inode.c        |  4 ++--
 fs/xfs/xfs_ioctl.c        |  6 +++---
 fs/xfs/xfs_iops.c         |  2 +-
 fs/xfs/xfs_log.c          | 39 ++++++++++++++++++++++-----------------
 fs/xfs/xfs_log_recover.c  |  2 +-
 fs/xfs/xfs_mount.c        | 25 +++++++++++--------------
 fs/xfs/xfs_mount.h        | 36 +++++++++++++++++++++++-------------
 fs/xfs/xfs_super.c        | 28 +++++++++++++---------------
 15 files changed, 86 insertions(+), 75 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
index edf0fbd58ee5..ad7e63d2cd67 100644
--- a/fs/xfs/libxfs/xfs_alloc.c
+++ b/fs/xfs/libxfs/xfs_alloc.c
@@ -2839,7 +2839,7 @@ xfs_alloc_vextent(
 		 * the first a.g. fails.
 		 */
 		if ((args->datatype & XFS_ALLOC_INITIAL_USER_DATA) &&
-		    (mp->m_flags & XFS_MOUNT_32BITINODES)) {
+		    test_bit(XFS_STATE_32BITINODES, &mp->m_state)) {
 			args->fsbno = XFS_AGB_TO_FSB(mp,
 					((mp->m_agfrotor / rotorstep) %
 					mp->m_sb.sb_agcount), 0);
diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c
index 5dcb9005173c..ee4d483e1209 100644
--- a/fs/xfs/libxfs/xfs_sb.c
+++ b/fs/xfs/libxfs/xfs_sb.c
@@ -183,7 +183,7 @@ xfs_validate_sb_read(
 "Superblock has unknown read-only compatible features (0x%x) enabled.",
 			(sbp->sb_features_ro_compat &
 					XFS_SB_FEAT_RO_COMPAT_UNKNOWN));
-		if (!(mp->m_flags & XFS_MOUNT_RDONLY)) {
+		if (!test_bit(XFS_STATE_RDONLY, &mp->m_state)) {
 			xfs_warn(mp,
 "Attempted to mount read-only compatible filesystem read-write.");
 			xfs_warn(mp,
@@ -981,7 +981,7 @@ xfs_initialize_perag_data(
 
 	xfs_reinit_percpu_counters(mp);
 out:
-	mp->m_flags &= ~XFS_MOUNT_BAD_SUMMARY;
+	clear_bit(XFS_STATE_BAD_SUMMARY, &mp->m_state);
 	return error;
 }
 
diff --git a/fs/xfs/scrub/scrub.c b/fs/xfs/scrub/scrub.c
index a3698e9b084a..f2cb022a23ab 100644
--- a/fs/xfs/scrub/scrub.c
+++ b/fs/xfs/scrub/scrub.c
@@ -437,7 +437,7 @@ xchk_validate_inputs(
 			goto out;
 
 		error = -EROFS;
-		if (mp->m_flags & XFS_MOUNT_RDONLY)
+		if (xfs_is_readonly(mp))
 			goto out;
 	}
 
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
index 5d8495380d2b..de99015fd715 100644
--- a/fs/xfs/xfs_buf_item.c
+++ b/fs/xfs/xfs_buf_item.c
@@ -1133,7 +1133,7 @@ xfs_buf_iodone_callback_error(
 			goto permanent_error;
 
 	/* At unmount we may treat errors differently */
-	if ((mp->m_flags & XFS_MOUNT_UNMOUNTING) && mp->m_fail_unmount)
+	if (test_bit(XFS_STATE_UNMOUNTING, &mp->m_state) && mp->m_fail_unmount)
 		goto permanent_error;
 
 	/*
diff --git a/fs/xfs/xfs_export.c b/fs/xfs/xfs_export.c
index cc1f7d09102f..9630e481f7f9 100644
--- a/fs/xfs/xfs_export.c
+++ b/fs/xfs/xfs_export.c
@@ -47,6 +47,7 @@ xfs_fs_encode_fh(
 	int		*max_len,
 	struct inode	*parent)
 {
+	struct xfs_mount	*mp = XFS_M(inode->i_sb);
 	struct fid		*fid = (struct fid *)fh;
 	struct xfs_fid64	*fid64 = (struct xfs_fid64 *)fh;
 	int			fileid_type;
@@ -66,8 +67,8 @@ xfs_fs_encode_fh(
 	 * large enough filesystem may contain them, thus the slightly
 	 * confusing looking conditional below.
 	 */
-	if (!xfs_has_small_inums(XFS_M(inode->i_sb)) ||
-	    (XFS_M(inode->i_sb)->m_flags & XFS_MOUNT_32BITINODES))
+	if (!xfs_has_small_inums(mp) ||
+	    test_bit(XFS_STATE_32BITINODES, &mp->m_state))
 		fileid_type |= XFS_FILEID_TYPE_64FLAG;
 
 	/*
diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c
index 182501373af2..b6b1690c4b42 100644
--- a/fs/xfs/xfs_filestream.c
+++ b/fs/xfs/xfs_filestream.c
@@ -330,7 +330,7 @@ xfs_filestream_lookup_ag(
 	 * Set the starting AG using the rotor for inode32, otherwise
 	 * use the directory inode's AG.
 	 */
-	if (mp->m_flags & XFS_MOUNT_32BITINODES) {
+	if (test_bit(XFS_STATE_32BITINODES, &mp->m_state)) {
 		xfs_agnumber_t	 rotorstep = xfs_rotorstep;
 		startag = (mp->m_agfrotor / rotorstep) % mp->m_sb.sb_agcount;
 		mp->m_agfrotor = (mp->m_agfrotor + 1) %
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index 7c00b8bedfe3..7c429c5b3a53 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -491,7 +491,7 @@ xfs_do_force_shutdown(
 		return;
 
 	/*
-	 * This flags XFS_MOUNT_FS_SHUTDOWN, makes sure that we don't
+	 * This flags XFS_STATE_SHUTDOWN, makes sure that we don't
 	 * queue up anybody new on the log reservations, and wakes up
 	 * everybody who's sleeping on log reservations to tell them
 	 * the bad news.
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 0f67ca516c87..5e396dca456e 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -1620,7 +1620,7 @@ xfs_release(
 		return 0;
 
 	/* If this is a read-only mount, don't do this (would generate I/O) */
-	if (mp->m_flags & XFS_MOUNT_RDONLY)
+	if (xfs_is_readonly(mp))
 		return 0;
 
 	if (!XFS_FORCED_SHUTDOWN(mp)) {
@@ -1847,7 +1847,7 @@ xfs_inactive(
 	ASSERT(!xfs_iflags_test(ip, XFS_IRECOVERY));
 
 	/* If this is a read-only mount, don't do this (would generate I/O) */
-	if (mp->m_flags & XFS_MOUNT_RDONLY)
+	if (xfs_is_readonly(mp))
 		return;
 
 	/* Try to clean out the cow blocks if there are any. */
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index 350b9276e6fe..d3bd93ba29a8 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -1142,7 +1142,7 @@ xfs_ioctl_setattr_get_trans(
 	struct xfs_trans	*tp;
 	int			error = -EROFS;
 
-	if (mp->m_flags & XFS_MOUNT_RDONLY)
+	if (xfs_is_readonly(mp))
 		goto out_unlock;
 	error = -EIO;
 	if (XFS_FORCED_SHUTDOWN(mp))
@@ -2055,7 +2055,7 @@ xfs_file_ioctl(
 		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
 
-		if (mp->m_flags & XFS_MOUNT_RDONLY)
+		if (xfs_is_readonly(mp))
 			return -EROFS;
 
 		if (copy_from_user(&inout, arg, sizeof(inout)))
@@ -2172,7 +2172,7 @@ xfs_file_ioctl(
 		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
 
-		if (mp->m_flags & XFS_MOUNT_RDONLY)
+		if (xfs_is_readonly(mp))
 			return -EROFS;
 
 		if (copy_from_user(&eofb, arg, sizeof(eofb)))
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index 0241471916d9..58ef007bccea 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -581,7 +581,7 @@ xfs_vn_change_ok(
 {
 	struct xfs_mount	*mp = XFS_I(d_inode(dentry))->i_mount;
 
-	if (mp->m_flags & XFS_MOUNT_RDONLY)
+	if (xfs_is_readonly(mp))
 		return -EROFS;
 
 	if (XFS_FORCED_SHUTDOWN(mp))
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index bcc068dee92a..47811fc143b5 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -607,7 +607,7 @@ xfs_log_mount(
 		xfs_notice(mp,
 "Mounting V%d filesystem in no-recovery mode. Filesystem will be inconsistent.",
 			   XFS_SB_VERSION_NUM(&mp->m_sb));
-		ASSERT(mp->m_flags & XFS_MOUNT_RDONLY);
+		ASSERT(xfs_is_readonly(mp));
 	}
 
 	mp->m_log = xlog_alloc_log(mp, log_target, blk_offset, num_bblks);
@@ -686,15 +686,17 @@ xfs_log_mount(
 	 * just worked.
 	 */
 	if (!xfs_has_norecovery(mp)) {
-		bool	readonly = (mp->m_flags & XFS_MOUNT_RDONLY);
-
-		if (readonly)
-			mp->m_flags &= ~XFS_MOUNT_RDONLY;
+		bool	readonly;
 
+		/*
+		 * log recovery ignores readonly state and so we need to clear
+		 * mount-based read only state so it can write to disk.
+		 */
+		readonly = test_and_clear_bit(XFS_STATE_RDONLY, &mp->m_state);
 		error = xlog_recover(mp->m_log);
-
 		if (readonly)
-			mp->m_flags |= XFS_MOUNT_RDONLY;
+			set_bit(XFS_STATE_RDONLY, &mp->m_state);
+
 		if (error) {
 			xfs_warn(mp, "log mount/recovery failed: error %d",
 				error);
@@ -743,17 +745,20 @@ xfs_log_mount_finish(
 	struct xfs_mount	*mp)
 {
 	int	error = 0;
-	bool	readonly = (mp->m_flags & XFS_MOUNT_RDONLY);
+	bool	readonly;
 	bool	recovered = mp->m_log->l_flags & XLOG_RECOVERY_NEEDED;
 
 	if (xfs_has_norecovery(mp)) {
-		ASSERT(readonly);
+		ASSERT(xfs_is_readonly(mp));
 		return 0;
-	} else if (readonly) {
-		/* Allow unlinked processing to proceed */
-		mp->m_flags &= ~XFS_MOUNT_RDONLY;
 	}
 
+	/*
+	 * log recovery ignores readonly state and so we need to clear
+	 * mount-based read only state so it can write to disk.
+	 */
+	readonly = test_and_clear_bit(XFS_STATE_RDONLY, &mp->m_state);
+
 	/*
 	 * During the second phase of log recovery, we need iget and
 	 * iput to behave like they do for an active filesystem.
@@ -797,7 +802,7 @@ xfs_log_mount_finish(
 	xfs_wait_buftarg(mp->m_ddev_targp);
 
 	if (readonly)
-		mp->m_flags |= XFS_MOUNT_RDONLY;
+		set_bit(XFS_STATE_RDONLY, &mp->m_state);
 
 	return error;
 }
@@ -861,7 +866,7 @@ xfs_log_write_unmount_record(
 	 * recalculated during log recovery at next mount.  Refer to
 	 * xlog_check_unmount_rec for more details.
 	 */
-	if (XFS_TEST_ERROR((mp->m_flags & XFS_MOUNT_BAD_SUMMARY), mp,
+	if (XFS_TEST_ERROR(test_bit(XFS_STATE_BAD_SUMMARY, &mp->m_state), mp,
 			XFS_ERRTAG_FORCE_SUMMARY_RECALC)) {
 		xfs_alert(mp, "%s: will fix summary counters at next mount",
 				__func__);
@@ -932,7 +937,7 @@ xfs_log_unmount_write(xfs_mount_t *mp)
 	 */
 	if (xfs_has_norecovery(mp) ||
 	    xfs_readonly_buftarg(log->l_mp->m_logdev_targp)) {
-		ASSERT(mp->m_flags & XFS_MOUNT_RDONLY);
+		ASSERT(xfs_is_readonly(mp));
 		return 0;
 	}
 
@@ -3966,7 +3971,7 @@ xfs_log_force_umount(
 	 */
 	if (!log ||
 	    log->l_flags & XLOG_ACTIVE_RECOVERY) {
-		mp->m_flags |= XFS_MOUNT_FS_SHUTDOWN;
+		set_bit(XFS_STATE_SHUTDOWN, &mp->m_state);
 		if (mp->m_sb_bp)
 			mp->m_sb_bp->b_flags |= XBF_DONE;
 		return 0;
@@ -3996,7 +4001,7 @@ xfs_log_force_umount(
 	 * everybody up to tell them the bad news.
 	 */
 	spin_lock(&log->l_icloglock);
-	mp->m_flags |= XFS_MOUNT_FS_SHUTDOWN;
+	set_bit(XFS_STATE_SHUTDOWN, &mp->m_state);
 	if (mp->m_sb_bp)
 		mp->m_sb_bp->b_flags |= XBF_DONE;
 
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index d57b992f6f6e..49579de464f6 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -1484,7 +1484,7 @@ xlog_find_tail(
 	 * headers if we have a filesystem using non-persistent counters.
 	 */
 	if (clean)
-		log->l_mp->m_flags |= XFS_MOUNT_WAS_CLEAN;
+		set_bit(XFS_STATE_WAS_CLEAN, &log->l_mp->m_state);
 
 	/*
 	 * Make sure that there are no blocks in front of the head
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 624387661cbc..7cb2577dbd73 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -634,11 +634,11 @@ xfs_check_summary_counts(
 	 * counters.  If any of them are obviously incorrect, we can recompute
 	 * them from the AGF headers in the next step.
 	 */
-	if (XFS_LAST_UNMOUNT_WAS_CLEAN(mp) &&
+	if (test_bit(XFS_STATE_WAS_CLEAN, &mp->m_state) &&
 	    (mp->m_sb.sb_fdblocks > mp->m_sb.sb_dblocks ||
 	     !xfs_verify_icount(mp, mp->m_sb.sb_icount) ||
 	     mp->m_sb.sb_ifree > mp->m_sb.sb_icount))
-		mp->m_flags |= XFS_MOUNT_BAD_SUMMARY;
+		set_bit(XFS_STATE_BAD_SUMMARY, &mp->m_state);
 
 	/*
 	 * We can safely re-initialise incore superblock counters from the
@@ -652,8 +652,8 @@ xfs_check_summary_counts(
 	 * Otherwise, recalculate the summary counters.
 	 */
 	if ((!xfs_has_lazysbcount(mp) ||
-	     XFS_LAST_UNMOUNT_WAS_CLEAN(mp)) &&
-	    !(mp->m_flags & XFS_MOUNT_BAD_SUMMARY))
+	     test_bit(XFS_STATE_WAS_CLEAN, &mp->m_state)) &&
+	     !test_bit(XFS_STATE_BAD_SUMMARY, &mp->m_state))
 		return 0;
 
 	return xfs_initialize_perag_data(mp, mp->m_sb.sb_agcount);
@@ -926,7 +926,7 @@ xfs_mountfs(
 	 * the next remount into writeable mode.  Otherwise we would never
 	 * perform the update e.g. for the root filesystem.
 	 */
-	if (mp->m_update_sb && !(mp->m_flags & XFS_MOUNT_RDONLY)) {
+	if (mp->m_update_sb && !xfs_is_readonly(mp)) {
 		error = xfs_sync_sb(mp, false);
 		if (error) {
 			xfs_warn(mp, "failed to write sb changes");
@@ -977,7 +977,7 @@ xfs_mountfs(
 	 * We use the same quiesce mechanism as the rw->ro remount, as they are
 	 * semantically identical operations.
 	 */
-	if ((mp->m_flags & XFS_MOUNT_RDONLY) && !xfs_has_norecovery(mp))
+	if (xfs_is_readonly(mp) && !xfs_has_norecovery(mp))
 		xfs_quiesce_attr(mp);
 
 	/*
@@ -1001,7 +1001,7 @@ xfs_mountfs(
 	 * This may drive us straight to ENOSPC on mount, but that implies
 	 * we were already there on the last unmount. Warn if this occurs.
 	 */
-	if (!(mp->m_flags & XFS_MOUNT_RDONLY)) {
+	if (!xfs_is_readonly(mp)) {
 		resblks = xfs_default_resblks(mp);
 		error = xfs_reserve_blocks(mp, &resblks, NULL);
 		if (error)
@@ -1049,7 +1049,7 @@ xfs_mountfs(
 	cancel_delayed_work_sync(&mp->m_reclaim_work);
 	xfs_reclaim_inodes(mp, SYNC_WAIT);
  out_log_dealloc:
-	mp->m_flags |= XFS_MOUNT_UNMOUNTING;
+	set_bit(XFS_STATE_UNMOUNTING, &mp->m_state);
 	xfs_log_mount_cancel(mp);
  out_fail_wait:
 	if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp)
@@ -1115,7 +1115,7 @@ xfs_unmountfs(
 	 * out anything that we have been retrying in the background. This will
 	 * prevent neverending retries in AIL pushing from hanging the unmount.
 	 */
-	mp->m_flags |= XFS_MOUNT_UNMOUNTING;
+	set_bit(XFS_STATE_UNMOUNTING, &mp->m_state);
 
 	/*
 	 * Flush all pending changes from the AIL.
@@ -1187,7 +1187,7 @@ xfs_fs_writable(
 {
 	ASSERT(level > SB_UNFROZEN);
 	if ((mp->m_super->s_writers.frozen >= level) ||
-	    XFS_FORCED_SHUTDOWN(mp) || (mp->m_flags & XFS_MOUNT_RDONLY))
+	    XFS_FORCED_SHUTDOWN(mp) || xfs_is_readonly(mp))
 		return false;
 
 	return true;
@@ -1424,8 +1424,5 @@ xfs_force_summary_recalc(
 {
 	if (!xfs_has_lazysbcount(mp))
 		return;
-
-	spin_lock(&mp->m_sb_lock);
-	mp->m_flags |= XFS_MOUNT_BAD_SUMMARY;
-	spin_unlock(&mp->m_sb_lock);
+	set_bit(XFS_STATE_BAD_SUMMARY, &mp->m_state);
 }
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index fee11d015b5a..03f4681c1ba6 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -126,7 +126,7 @@ typedef struct xfs_mount {
 	spinlock_t		m_perag_lock;	/* lock for m_perag_tree */
 	struct mutex		m_growlock;	/* growfs mutex */
 	int			m_fixedfsid[2];	/* unchanged for life of FS */
-	uint64_t		m_flags;	/* global mount flags */
+	unsigned long		m_state;	/* dynamic state flags */
 	uint64_t		m_features;	/* active filesystem features */
 	bool			m_inotbt_nores; /* no per-AG finobt resv. */
 	int			m_ialloc_inos;	/* inodes in inode allocation */
@@ -316,17 +316,28 @@ __XFS_HAS_FEAT(noattr2, NOATTR2)
 __XFS_HAS_FEAT(noalign, NOALIGN)
 
 /*
- * Flags for m_flags.
+ * Mount state flags
+ *
+ * Use these with atomic bit ops only!
  */
-#define XFS_MOUNT_UNMOUNTING	(1ULL << 1)	/* filesystem is unmounting */
-#define XFS_MOUNT_BAD_SUMMARY	(1ULL << 2)	/* summary counters are bad */
-#define XFS_MOUNT_WAS_CLEAN	(1ULL << 3)
-#define XFS_MOUNT_FS_SHUTDOWN	(1ULL << 4)	/* atomic stop of all filesystem
-						   operations, typically for
-						   disk errors in metadata */
-#define XFS_MOUNT_32BITINODES	(1ULL << 15)	/* inode32 allocator active */
-#define XFS_MOUNT_RDONLY	(1ULL << 20)	/* read-only fs */
+#define XFS_STATE_UNMOUNTING	0	/* filesystem is unmounting */
+#define XFS_STATE_BAD_SUMMARY	1	/* summary counters are bad */
+#define XFS_STATE_WAS_CLEAN	2	/* mount was clean */
+#define XFS_STATE_SHUTDOWN	3	/* atomic stop of all filesystem
+					   operations, typically for
+					   disk errors in metadata */
+#define XFS_STATE_32BITINODES	4	/* inode32 allocator active */
+#define XFS_STATE_RDONLY	5	/* read-only fs */
+
+static inline bool xfs_is_readonly(struct xfs_mount *mp)
+{
+	return test_bit(XFS_STATE_RDONLY, &mp->m_state);
+}
 
+static inline bool xfs_is_shut_down(struct xfs_mount *mp)
+{
+	return test_bit(XFS_STATE_SHUTDOWN, &mp->m_state);
+}
 
 /*
  * Default minimum read and write sizes.
@@ -372,9 +383,8 @@ xfs_preferred_iosize(xfs_mount_t *mp)
 	return PAGE_SIZE;
 }
 
-#define XFS_LAST_UNMOUNT_WAS_CLEAN(mp)	\
-				((mp)->m_flags & XFS_MOUNT_WAS_CLEAN)
-#define XFS_FORCED_SHUTDOWN(mp)	((mp)->m_flags & XFS_MOUNT_FS_SHUTDOWN)
+#define XFS_FORCED_SHUTDOWN(mp) \
+		test_bit(XFS_STATE_SHUTDOWN, &(mp)->m_state)
 void xfs_do_force_shutdown(struct xfs_mount *mp, int flags, char *fname,
 		int lnnum);
 #define xfs_force_shutdown(m,f)	\
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index d3dff878be99..9938d9fb420b 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -191,7 +191,7 @@ xfs_parseargs(
 	 * Copy binary VFS mount flags we are interested in.
 	 */
 	if (sb_rdonly(sb))
-		mp->m_flags |= XFS_MOUNT_RDONLY;
+		set_bit(XFS_STATE_RDONLY, &mp->m_state);
 	if (sb->s_flags & SB_DIRSYNC)
 		mp->m_features |= XFS_FEAT_DIRSYNC;
 	if (sb->s_flags & SB_SYNCHRONOUS)
@@ -361,7 +361,7 @@ xfs_parseargs(
 	/*
 	 * no recovery flag requires a read-only mount
 	 */
-	if (xfs_has_norecovery(mp) && !(mp->m_flags & XFS_MOUNT_RDONLY)) {
+	if (xfs_has_norecovery(mp) && !xfs_is_readonly(mp)) {
 		xfs_warn(mp, "no-recovery mounts must be read-only.");
 		return -EINVAL;
 	}
@@ -567,7 +567,7 @@ xfs_max_file_offset(
  *
  * Inode allocation patterns are altered only if inode32 is requested
  * (XFS_FEAT_SMALL_INUMS), and the filesystem is sufficiently large.
- * If altered, XFS_MOUNT_32BITINODES is set as well.
+ * If altered, XFS_STATE_32BITINODES is set as well.
  *
  * An agcount independent of that in the mount structure is provided
  * because in the growfs case, mp->m_sb.sb_agcount is not yet updated
@@ -609,13 +609,13 @@ xfs_set_inode_alloc(
 
 	/*
 	 * If user asked for no more than 32-bit inodes, and the fs is
-	 * sufficiently large, set XFS_MOUNT_32BITINODES if we must alter
+	 * sufficiently large, set XFS_STATE_32BITINODES if we must alter
 	 * the allocator to accommodate the request.
 	 */
 	if (xfs_has_small_inums(mp) && ino > XFS_MAXINUMBER_32)
-		mp->m_flags |= XFS_MOUNT_32BITINODES;
+		set_bit(XFS_STATE_32BITINODES, &mp->m_state);
 	else
-		mp->m_flags &= ~XFS_MOUNT_32BITINODES;
+		clear_bit(XFS_STATE_32BITINODES, &mp->m_state);
 
 	for (index = 0; index < agcount; index++) {
 		struct xfs_perag	*pag;
@@ -624,7 +624,7 @@ xfs_set_inode_alloc(
 
 		pag = xfs_perag_get(mp, index);
 
-		if (mp->m_flags & XFS_MOUNT_32BITINODES) {
+		if (test_bit(XFS_STATE_32BITINODES, &mp->m_state)) {
 			if (ino > XFS_MAXINUMBER_32) {
 				pag->pagi_inodeok = 0;
 				pag->pagf_metadata = 0;
@@ -644,7 +644,7 @@ xfs_set_inode_alloc(
 		xfs_perag_put(pag);
 	}
 
-	return (mp->m_flags & XFS_MOUNT_32BITINODES) ? maxagi : agcount;
+	return test_bit(XFS_STATE_32BITINODES, &mp->m_state) ? maxagi : agcount;
 }
 
 STATIC int
@@ -1294,7 +1294,7 @@ xfs_fs_remount(
 	}
 
 	/* ro -> rw */
-	if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(*flags & SB_RDONLY)) {
+	if (xfs_is_readonly(mp) && !(*flags & SB_RDONLY)) {
 		if (xfs_has_norecovery(mp)) {
 			xfs_warn(mp,
 		"ro->rw transition prohibited on norecovery mount");
@@ -1311,7 +1311,7 @@ xfs_fs_remount(
 			return -EINVAL;
 		}
 
-		mp->m_flags &= ~XFS_MOUNT_RDONLY;
+		clear_bit(XFS_STATE_RDONLY, &mp->m_state);
 
 		/*
 		 * If this is the first remount to writeable state we
@@ -1350,7 +1350,7 @@ xfs_fs_remount(
 	}
 
 	/* rw -> ro */
-	if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (*flags & SB_RDONLY)) {
+	if (!xfs_is_readonly(mp) && (*flags & SB_RDONLY)) {
 		/*
 		 * Cancel background eofb scanning so it cannot race with the
 		 * final log force+buftarg wait and deadlock the remount.
@@ -1381,7 +1381,7 @@ xfs_fs_remount(
 		xfs_save_resvblks(mp);
 
 		xfs_quiesce_attr(mp);
-		mp->m_flags |= XFS_MOUNT_RDONLY;
+		set_bit(XFS_STATE_RDONLY, &mp->m_state);
 	}
 
 	return 0;
@@ -1433,8 +1433,6 @@ STATIC int
 xfs_finish_flags(
 	struct xfs_mount	*mp)
 {
-	int			ronly = (mp->m_flags & XFS_MOUNT_RDONLY);
-
 	/* Fail a mount where the logbuf is smaller than the log stripe */
 	if (xfs_has_logv2(mp)) {
 		if (mp->m_logbsize <= 0 &&
@@ -1467,7 +1465,7 @@ xfs_finish_flags(
 	/*
 	 * prohibit r/w mounts of read-only filesystems
 	 */
-	if ((mp->m_sb.sb_flags & XFS_SBF_READONLY) && !ronly) {
+	if ((mp->m_sb.sb_flags & XFS_SBF_READONLY) && !xfs_is_readonly(mp)) {
 		xfs_warn(mp,
 			"cannot mount a read-only filesystem as read-write");
 		return -EROFS;
-- 
2.17.0

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

* [PATCH 06/10] xfs: replace XFS_FORCED_SHUTDOWN with xfs_is_shut_down
  2018-08-20  4:48 [PATCH 0/10] xfs: feature flag rework Dave Chinner
                   ` (4 preceding siblings ...)
  2018-08-20  4:48 ` [PATCH 05/10] xfs: convert remaining mount flags to state flags Dave Chinner
@ 2018-08-20  4:48 ` Dave Chinner
  2018-08-21 13:23   ` Brian Foster
  2018-08-20  4:48 ` [PATCH 07/10] xfs: convert xfs_fs_geometry to use mount feature checks Dave Chinner
                   ` (4 subsequent siblings)
  10 siblings, 1 reply; 27+ messages in thread
From: Dave Chinner @ 2018-08-20  4:48 UTC (permalink / raw)
  To: linux-xfs

From: Dave Chinner <dchinner@redhat.com>

Remove the shouty macro and instead use the inline function that
matches other state/feature check wrapper naming. This conversion
was done with sed.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
 fs/xfs/libxfs/xfs_alloc.c      |  2 +-
 fs/xfs/libxfs/xfs_attr.c       |  6 +++---
 fs/xfs/libxfs/xfs_bmap.c       | 16 ++++++++--------
 fs/xfs/libxfs/xfs_dir2_block.c |  2 +-
 fs/xfs/libxfs/xfs_dir2_sf.c    |  8 ++++----
 fs/xfs/libxfs/xfs_ialloc.c     |  6 +++---
 fs/xfs/scrub/scrub.c           |  2 +-
 fs/xfs/xfs_aops.c              |  8 ++++----
 fs/xfs/xfs_attr_list.c         |  2 +-
 fs/xfs/xfs_bmap_util.c         |  8 ++++----
 fs/xfs/xfs_buf.c               |  2 +-
 fs/xfs/xfs_buf_item.c          |  4 ++--
 fs/xfs/xfs_dir2_readdir.c      |  2 +-
 fs/xfs/xfs_dquot.c             |  2 +-
 fs/xfs/xfs_file.c              | 12 ++++++------
 fs/xfs/xfs_fsops.c             |  2 +-
 fs/xfs/xfs_icache.c            |  4 ++--
 fs/xfs/xfs_inode.c             | 20 ++++++++++----------
 fs/xfs/xfs_inode_item.c        |  6 +++---
 fs/xfs/xfs_ioctl.c             |  8 ++++----
 fs/xfs/xfs_ioctl32.c           |  2 +-
 fs/xfs/xfs_iomap.c             |  6 +++---
 fs/xfs/xfs_iops.c              |  4 ++--
 fs/xfs/xfs_log_recover.c       |  8 ++++----
 fs/xfs/xfs_mount.c             |  2 +-
 fs/xfs/xfs_mount.h             |  4 +---
 fs/xfs/xfs_pnfs.c              |  2 +-
 fs/xfs/xfs_qm.c                |  4 ++--
 fs/xfs/xfs_reflink.c           |  2 +-
 fs/xfs/xfs_super.c             |  2 +-
 fs/xfs/xfs_symlink.c           |  8 ++++----
 fs/xfs/xfs_trans.c             |  8 ++++----
 fs/xfs/xfs_trans_ail.c         |  8 ++++----
 fs/xfs/xfs_trans_buf.c         | 10 +++++-----
 34 files changed, 95 insertions(+), 97 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
index ad7e63d2cd67..f23d3c7ea537 100644
--- a/fs/xfs/libxfs/xfs_alloc.c
+++ b/fs/xfs/libxfs/xfs_alloc.c
@@ -2751,7 +2751,7 @@ xfs_alloc_read_agf(
 		pag->pagf_agflreset = xfs_agfl_needs_reset(mp, agf);
 	}
 #ifdef DEBUG
-	else if (!XFS_FORCED_SHUTDOWN(mp)) {
+	else if (!xfs_is_shut_down(mp)) {
 		ASSERT(pag->pagf_freeblks == be32_to_cpu(agf->agf_freeblks));
 		ASSERT(pag->pagf_btreeblks == be32_to_cpu(agf->agf_btreeblks));
 		ASSERT(pag->pagf_flcount == be32_to_cpu(agf->agf_flcount));
diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index 5ca0233fe135..1932758b8faf 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -135,7 +135,7 @@ xfs_attr_get(
 
 	XFS_STATS_INC(ip->i_mount, xs_attr_get);
 
-	if (XFS_FORCED_SHUTDOWN(ip->i_mount))
+	if (xfs_is_shut_down(ip->i_mount))
 		return -EIO;
 
 	error = xfs_attr_args_init(&args, ip, name, flags);
@@ -208,7 +208,7 @@ xfs_attr_set(
 
 	XFS_STATS_INC(mp, xs_attr_set);
 
-	if (XFS_FORCED_SHUTDOWN(dp->i_mount))
+	if (xfs_is_shut_down(dp->i_mount))
 		return -EIO;
 
 	error = xfs_attr_args_init(&args, dp, name, flags);
@@ -387,7 +387,7 @@ xfs_attr_remove(
 
 	XFS_STATS_INC(mp, xs_attr_remove);
 
-	if (XFS_FORCED_SHUTDOWN(dp->i_mount))
+	if (xfs_is_shut_down(dp->i_mount))
 		return -EIO;
 
 	error = xfs_attr_args_init(&args, dp, name, flags);
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index 459b08856f3f..5e12f6b3be7f 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -3816,7 +3816,7 @@ xfs_bmapi_read(
 		return -EFSCORRUPTED;
 	}
 
-	if (XFS_FORCED_SHUTDOWN(mp))
+	if (xfs_is_shut_down(mp))
 		return -EIO;
 
 	XFS_STATS_INC(mp, xs_blk_mapr);
@@ -4260,7 +4260,7 @@ xfs_bmapi_write(
 		return -EFSCORRUPTED;
 	}
 
-	if (XFS_FORCED_SHUTDOWN(mp))
+	if (xfs_is_shut_down(mp))
 		return -EIO;
 
 	ifp = XFS_IFORK_PTR(ip, whichfork);
@@ -4485,7 +4485,7 @@ xfs_bmapi_remap(
 		return -EFSCORRUPTED;
 	}
 
-	if (XFS_FORCED_SHUTDOWN(mp))
+	if (xfs_is_shut_down(mp))
 		return -EIO;
 
 	if (!(ifp->if_flags & XFS_IFEXTENTS)) {
@@ -5124,7 +5124,7 @@ __xfs_bunmapi(
 		return -EFSCORRUPTED;
 	}
 	mp = ip->i_mount;
-	if (XFS_FORCED_SHUTDOWN(mp))
+	if (xfs_is_shut_down(mp))
 		return -EIO;
 
 	ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
@@ -5632,7 +5632,7 @@ xfs_bmap_collapse_extents(
 		return -EFSCORRUPTED;
 	}
 
-	if (XFS_FORCED_SHUTDOWN(mp))
+	if (xfs_is_shut_down(mp))
 		return -EIO;
 
 	ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL));
@@ -5710,7 +5710,7 @@ xfs_bmap_can_insert_extents(
 
 	ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL));
 
-	if (XFS_FORCED_SHUTDOWN(ip->i_mount))
+	if (xfs_is_shut_down(ip->i_mount))
 		return -EIO;
 
 	xfs_ilock(ip, XFS_ILOCK_EXCL);
@@ -5750,7 +5750,7 @@ xfs_bmap_insert_extents(
 		return -EFSCORRUPTED;
 	}
 
-	if (XFS_FORCED_SHUTDOWN(mp))
+	if (xfs_is_shut_down(mp))
 		return -EIO;
 
 	ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL));
@@ -5857,7 +5857,7 @@ xfs_bmap_split_extent_at(
 		return -EFSCORRUPTED;
 	}
 
-	if (XFS_FORCED_SHUTDOWN(mp))
+	if (xfs_is_shut_down(mp))
 		return -EIO;
 
 	ifp = XFS_IFORK_PTR(ip, whichfork);
diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c
index 7ae94e0c111c..79052c19881b 100644
--- a/fs/xfs/libxfs/xfs_dir2_block.c
+++ b/fs/xfs/libxfs/xfs_dir2_block.c
@@ -1080,7 +1080,7 @@ xfs_dir2_sf_to_block(
 	 * Bomb out if the shortform directory is way too short.
 	 */
 	if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) {
-		ASSERT(XFS_FORCED_SHUTDOWN(mp));
+		ASSERT(xfs_is_shut_down(mp));
 		return -EIO;
 	}
 
diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c
index 8f5e17f79151..223eb7ccb927 100644
--- a/fs/xfs/libxfs/xfs_dir2_sf.c
+++ b/fs/xfs/libxfs/xfs_dir2_sf.c
@@ -284,7 +284,7 @@ xfs_dir2_sf_addname(
 	 * Make sure the shortform value has some of its header.
 	 */
 	if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) {
-		ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount));
+		ASSERT(xfs_is_shut_down(dp->i_mount));
 		return -EIO;
 	}
 	ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
@@ -800,7 +800,7 @@ xfs_dir2_sf_lookup(
 	 * Bail out if the directory is way too short.
 	 */
 	if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) {
-		ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount));
+		ASSERT(xfs_is_shut_down(dp->i_mount));
 		return -EIO;
 	}
 	ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
@@ -886,7 +886,7 @@ xfs_dir2_sf_removename(
 	 * Bail out if the directory is way too short.
 	 */
 	if (oldsize < offsetof(xfs_dir2_sf_hdr_t, parent)) {
-		ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount));
+		ASSERT(xfs_is_shut_down(dp->i_mount));
 		return -EIO;
 	}
 	ASSERT(dp->i_df.if_bytes == oldsize);
@@ -970,7 +970,7 @@ xfs_dir2_sf_replace(
 	 * Bail out if the shortform directory is way too small.
 	 */
 	if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) {
-		ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount));
+		ASSERT(xfs_is_shut_down(dp->i_mount));
 		return -EIO;
 	}
 	ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c
index ffb1caf4c34a..bbf9efcd6aea 100644
--- a/fs/xfs/libxfs/xfs_ialloc.c
+++ b/fs/xfs/libxfs/xfs_ialloc.c
@@ -260,7 +260,7 @@ xfs_check_agi_freecount(
 			}
 		} while (i == 1);
 
-		if (!XFS_FORCED_SHUTDOWN(cur->bc_mp))
+		if (!xfs_is_shut_down(cur->bc_mp))
 			ASSERT(freecount == be32_to_cpu(agi->agi_freecount));
 	}
 	return 0;
@@ -1035,7 +1035,7 @@ xfs_ialloc_ag_select(
 		 * No point in iterating over the rest, if we're shutting
 		 * down.
 		 */
-		if (XFS_FORCED_SHUTDOWN(mp))
+		if (xfs_is_shut_down(mp))
 			return NULLAGNUMBER;
 		agno++;
 		if (agno >= agcount)
@@ -2648,7 +2648,7 @@ xfs_ialloc_read_agi(
 	 * we are in the middle of a forced shutdown.
 	 */
 	ASSERT(pag->pagi_freecount == be32_to_cpu(agi->agi_freecount) ||
-		XFS_FORCED_SHUTDOWN(mp));
+		xfs_is_shut_down(mp));
 	xfs_perag_put(pag);
 	return 0;
 }
diff --git a/fs/xfs/scrub/scrub.c b/fs/xfs/scrub/scrub.c
index f2cb022a23ab..8c1edb39fb8c 100644
--- a/fs/xfs/scrub/scrub.c
+++ b/fs/xfs/scrub/scrub.c
@@ -492,7 +492,7 @@ xfs_scrub_metadata(
 
 	/* Forbidden if we are shut down or mounted norecovery. */
 	error = -ESHUTDOWN;
-	if (XFS_FORCED_SHUTDOWN(mp))
+	if (xfs_is_shut_down(mp))
 		goto out;
 	error = -ENOTRECOVERABLE;
 	if (xfs_has_norecovery(mp))
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
index 49f5f5896a43..83fa2c85239c 100644
--- a/fs/xfs/xfs_aops.c
+++ b/fs/xfs/xfs_aops.c
@@ -245,7 +245,7 @@ xfs_end_io(
 	/*
 	 * Just clean up the in-memory strutures if the fs has been shut down.
 	 */
-	if (XFS_FORCED_SHUTDOWN(ip->i_mount)) {
+	if (xfs_is_shut_down(ip->i_mount)) {
 		error = -EIO;
 		goto done;
 	}
@@ -354,7 +354,7 @@ xfs_map_blocks(
 	     wpc->cow_seq == READ_ONCE(ip->i_cowfp->if_seq)))
 		return 0;
 
-	if (XFS_FORCED_SHUTDOWN(mp))
+	if (xfs_is_shut_down(mp))
 		return -EIO;
 
 	/*
@@ -658,7 +658,7 @@ xfs_aops_discard_page(
 	xfs_fileoff_t		start_fsb = XFS_B_TO_FSBT(mp, offset);
 	int			error;
 
-	if (XFS_FORCED_SHUTDOWN(mp))
+	if (xfs_is_shut_down(mp))
 		goto out_invalidate;
 
 	xfs_alert(mp,
@@ -667,7 +667,7 @@ xfs_aops_discard_page(
 
 	error = xfs_bmap_punch_delalloc_range(ip, start_fsb,
 			PAGE_SIZE / i_blocksize(inode));
-	if (error && !XFS_FORCED_SHUTDOWN(mp))
+	if (error && !xfs_is_shut_down(mp))
 		xfs_alert(mp, "page discard unable to remove delalloc mapping.");
 out_invalidate:
 	xfs_vm_invalidatepage(page, 0, PAGE_SIZE);
diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c
index a58034049995..ef6465e3275a 100644
--- a/fs/xfs/xfs_attr_list.c
+++ b/fs/xfs/xfs_attr_list.c
@@ -523,7 +523,7 @@ xfs_attr_list_int(
 
 	XFS_STATS_INC(dp->i_mount, xs_attr_list);
 
-	if (XFS_FORCED_SHUTDOWN(dp->i_mount))
+	if (xfs_is_shut_down(dp->i_mount))
 		return -EIO;
 
 	lock_mode = xfs_ilock_attr_map_shared(dp);
diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c
index bd733b256fee..8bdaa39f3812 100644
--- a/fs/xfs/xfs_bmap_util.c
+++ b/fs/xfs/xfs_bmap_util.c
@@ -828,7 +828,7 @@ xfs_free_eofblocks(
 		error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0,
 				&tp);
 		if (error) {
-			ASSERT(XFS_FORCED_SHUTDOWN(mp));
+			ASSERT(xfs_is_shut_down(mp));
 			return error;
 		}
 
@@ -883,7 +883,7 @@ xfs_alloc_file_space(
 
 	trace_xfs_alloc_file_space(ip);
 
-	if (XFS_FORCED_SHUTDOWN(mp))
+	if (xfs_is_shut_down(mp))
 		return -EIO;
 
 	error = xfs_qm_dqattach(ip);
@@ -959,7 +959,7 @@ xfs_alloc_file_space(
 			/*
 			 * Free the transaction structure.
 			 */
-			ASSERT(error == -ENOSPC || XFS_FORCED_SHUTDOWN(mp));
+			ASSERT(error == -ENOSPC || xfs_is_shut_down(mp));
 			break;
 		}
 		xfs_ilock(ip, XFS_ILOCK_EXCL);
@@ -1020,7 +1020,7 @@ xfs_unmap_extent(
 
 	error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks, 0, 0, &tp);
 	if (error) {
-		ASSERT(error == -ENOSPC || XFS_FORCED_SHUTDOWN(mp));
+		ASSERT(error == -ENOSPC || xfs_is_shut_down(mp));
 		return error;
 	}
 
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
index 8043c7a8c2e0..3290a7d10824 100644
--- a/fs/xfs/xfs_buf.c
+++ b/fs/xfs/xfs_buf.c
@@ -1466,7 +1466,7 @@ __xfs_buf_submit(
 	ASSERT(!(bp->b_flags & _XBF_DELWRI_Q));
 
 	/* on shutdown we stale and complete the buffer immediately */
-	if (XFS_FORCED_SHUTDOWN(bp->b_target->bt_mount)) {
+	if (xfs_is_shut_down(bp->b_target->bt_mount)) {
 		xfs_buf_ioerror(bp, -EIO);
 		bp->b_flags &= ~XBF_DONE;
 		xfs_buf_stale(bp);
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
index de99015fd715..1b2b05ed2a99 100644
--- a/fs/xfs/xfs_buf_item.c
+++ b/fs/xfs/xfs_buf_item.c
@@ -617,7 +617,7 @@ xfs_buf_item_unlock(
 	 */
 	if (atomic_dec_and_test(&bip->bli_refcount)) {
 		if (aborted) {
-			ASSERT(XFS_FORCED_SHUTDOWN(lip->li_mountp));
+			ASSERT(xfs_is_shut_down(lip->li_mountp));
 			xfs_trans_ail_remove(lip, SHUTDOWN_LOG_IO_ERROR);
 			xfs_buf_item_relse(bp);
 		} else if (!dirty)
@@ -1081,7 +1081,7 @@ xfs_buf_iodone_callback_error(
 	 * If we've already decided to shutdown the filesystem because of
 	 * I/O errors, there's no point in giving this a retry.
 	 */
-	if (XFS_FORCED_SHUTDOWN(mp))
+	if (xfs_is_shut_down(mp))
 		goto out_stale;
 
 	if (bp->b_target != lasttarg ||
diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
index 5b1d16b2a823..acbe265a0031 100644
--- a/fs/xfs/xfs_dir2_readdir.c
+++ b/fs/xfs/xfs_dir2_readdir.c
@@ -506,7 +506,7 @@ xfs_readdir(
 
 	trace_xfs_readdir(dp);
 
-	if (XFS_FORCED_SHUTDOWN(dp->i_mount))
+	if (xfs_is_shut_down(dp->i_mount))
 		return -EIO;
 
 	ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index 296d6cdfe7aa..5e55d369a56e 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -1094,7 +1094,7 @@ xfs_qm_dqflush(
 	 * We also have to remove the log item from the AIL in this case,
 	 * as we wait for an emptry AIL as part of the unmount process.
 	 */
-	if (XFS_FORCED_SHUTDOWN(mp)) {
+	if (xfs_is_shut_down(mp)) {
 		struct xfs_log_item	*lip = &dqp->q_logitem.qli_item;
 		dqp->dq_flags &= ~XFS_DQ_DIRTY;
 
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 5eaef2c17293..2111b1883394 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -119,7 +119,7 @@ xfs_file_fsync(
 	if (error)
 		return error;
 
-	if (XFS_FORCED_SHUTDOWN(mp))
+	if (xfs_is_shut_down(mp))
 		return -EIO;
 
 	xfs_iflags_clear(ip, XFS_ITRUNCATED);
@@ -259,7 +259,7 @@ xfs_file_read_iter(
 
 	XFS_STATS_INC(mp, xs_read_calls);
 
-	if (XFS_FORCED_SHUTDOWN(mp))
+	if (xfs_is_shut_down(mp))
 		return -EIO;
 
 	if (IS_DAX(inode))
@@ -396,7 +396,7 @@ xfs_dio_write_end_io(
 
 	trace_xfs_end_io_direct_write(ip, offset, size);
 
-	if (XFS_FORCED_SHUTDOWN(ip->i_mount))
+	if (xfs_is_shut_down(ip->i_mount))
 		return -EIO;
 
 	if (size <= 0)
@@ -698,7 +698,7 @@ xfs_file_write_iter(
 	if (ocount == 0)
 		return 0;
 
-	if (XFS_FORCED_SHUTDOWN(ip->i_mount))
+	if (xfs_is_shut_down(ip->i_mount))
 		return -EIO;
 
 	if (IS_DAX(inode))
@@ -965,7 +965,7 @@ xfs_file_open(
 {
 	if (!(file->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS)
 		return -EFBIG;
-	if (XFS_FORCED_SHUTDOWN(XFS_M(inode->i_sb)))
+	if (xfs_is_shut_down(XFS_M(inode->i_sb)))
 		return -EIO;
 	file->f_mode |= FMODE_NOWAIT;
 	return 0;
@@ -1037,7 +1037,7 @@ xfs_file_llseek(
 {
 	struct inode		*inode = file->f_mapping->host;
 
-	if (XFS_FORCED_SHUTDOWN(XFS_I(inode)->i_mount))
+	if (xfs_is_shut_down(XFS_I(inode)->i_mount))
 		return -EIO;
 
 	switch (whence) {
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index 7c429c5b3a53..ed29294e1b4f 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -487,7 +487,7 @@ xfs_do_force_shutdown(
 	/*
 	 * No need to duplicate efforts.
 	 */
-	if (XFS_FORCED_SHUTDOWN(mp) && !logerror)
+	if (xfs_is_shut_down(mp) && !logerror)
 		return;
 
 	/*
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index 245483cc282b..4878f958a0c3 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -758,7 +758,7 @@ xfs_inode_ag_walk_grab(
 	spin_unlock(&ip->i_flags_lock);
 
 	/* nothing to sync during shutdown */
-	if (XFS_FORCED_SHUTDOWN(ip->i_mount))
+	if (xfs_is_shut_down(ip->i_mount))
 		return -EFSCORRUPTED;
 
 	/* If we can't grab the inode, it must on it's way to reclaim. */
@@ -1106,7 +1106,7 @@ xfs_reclaim_inode(
 		xfs_iflock(ip);
 	}
 
-	if (XFS_FORCED_SHUTDOWN(ip->i_mount)) {
+	if (xfs_is_shut_down(ip->i_mount)) {
 		xfs_iunpin_wait(ip);
 		/* xfs_iflush_abort() drops the flush lock */
 		xfs_iflush_abort(ip, false);
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 5e396dca456e..c1e6d94efd6c 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -693,7 +693,7 @@ xfs_lookup(
 
 	trace_xfs_lookup(dp, name);
 
-	if (XFS_FORCED_SHUTDOWN(dp->i_mount))
+	if (xfs_is_shut_down(dp->i_mount))
 		return -EIO;
 
 	error = xfs_dir_lookup(NULL, dp, name, &inum, ci_name);
@@ -1152,7 +1152,7 @@ xfs_create(
 
 	trace_xfs_create(dp, name);
 
-	if (XFS_FORCED_SHUTDOWN(mp))
+	if (xfs_is_shut_down(mp))
 		return -EIO;
 
 	prid = xfs_get_initial_prid(dp);
@@ -1305,7 +1305,7 @@ xfs_create_tmpfile(
 	struct xfs_trans_res	*tres;
 	uint			resblks;
 
-	if (XFS_FORCED_SHUTDOWN(mp))
+	if (xfs_is_shut_down(mp))
 		return -EIO;
 
 	prid = xfs_get_initial_prid(dp);
@@ -1396,7 +1396,7 @@ xfs_link(
 
 	ASSERT(!S_ISDIR(VFS_I(sip)->i_mode));
 
-	if (XFS_FORCED_SHUTDOWN(mp))
+	if (xfs_is_shut_down(mp))
 		return -EIO;
 
 	error = xfs_qm_dqattach(sip);
@@ -1623,7 +1623,7 @@ xfs_release(
 	if (xfs_is_readonly(mp))
 		return 0;
 
-	if (!XFS_FORCED_SHUTDOWN(mp)) {
+	if (!xfs_is_shut_down(mp)) {
 		int truncated;
 
 		/*
@@ -1704,7 +1704,7 @@ xfs_inactive_truncate(
 
 	error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp);
 	if (error) {
-		ASSERT(XFS_FORCED_SHUTDOWN(mp));
+		ASSERT(xfs_is_shut_down(mp));
 		return error;
 	}
 	xfs_ilock(ip, XFS_ILOCK_EXCL);
@@ -1775,7 +1775,7 @@ xfs_inactive_ifree(
 			"Failed to remove inode(s) from unlinked list. "
 			"Please free space, unmount and run xfs_repair.");
 		} else {
-			ASSERT(XFS_FORCED_SHUTDOWN(mp));
+			ASSERT(xfs_is_shut_down(mp));
 		}
 		return error;
 	}
@@ -1790,7 +1790,7 @@ xfs_inactive_ifree(
 		 * might do that, we need to make sure.  Otherwise the
 		 * inode might be lost for a long time or forever.
 		 */
-		if (!XFS_FORCED_SHUTDOWN(mp)) {
+		if (!xfs_is_shut_down(mp)) {
 			xfs_notice(mp, "%s: xfs_ifree returned error %d",
 				__func__, error);
 			xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR);
@@ -2541,7 +2541,7 @@ xfs_remove(
 
 	trace_xfs_remove(dp, name);
 
-	if (XFS_FORCED_SHUTDOWN(mp))
+	if (xfs_is_shut_down(mp))
 		return -EIO;
 
 	error = xfs_qm_dqattach(dp);
@@ -3352,7 +3352,7 @@ xfs_iflush(
 	 * We also have to remove the log item from the AIL in this case,
 	 * as we wait for an empty AIL as part of the unmount process.
 	 */
-	if (XFS_FORCED_SHUTDOWN(mp)) {
+	if (xfs_is_shut_down(mp)) {
 		error = -EIO;
 		goto abort_out;
 	}
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
index fa1c4fe2ffbf..f97430a237d4 100644
--- a/fs/xfs/xfs_inode_item.c
+++ b/fs/xfs/xfs_inode_item.c
@@ -543,8 +543,8 @@ xfs_inode_item_push(
 		goto out_unlock;
 	}
 
-	ASSERT(iip->ili_fields != 0 || XFS_FORCED_SHUTDOWN(ip->i_mount));
-	ASSERT(iip->ili_logged == 0 || XFS_FORCED_SHUTDOWN(ip->i_mount));
+	ASSERT(iip->ili_fields != 0 || xfs_is_shut_down(ip->i_mount));
+	ASSERT(iip->ili_logged == 0 || xfs_is_shut_down(ip->i_mount));
 
 	spin_unlock(&lip->li_ailp->ail_lock);
 
@@ -747,7 +747,7 @@ xfs_iflush_done(
 		}
 
 		if (mlip_changed) {
-			if (!XFS_FORCED_SHUTDOWN(ailp->ail_mount))
+			if (!xfs_is_shut_down(ailp->ail_mount))
 				xlog_assign_tail_lsn_locked(ailp->ail_mount);
 			if (list_empty(&ailp->ail_head))
 				wake_up_all(&ailp->ail_empty);
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index d3bd93ba29a8..6238b6bb7653 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -309,7 +309,7 @@ xfs_set_dmattrs(
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 
-	if (XFS_FORCED_SHUTDOWN(mp))
+	if (xfs_is_shut_down(mp))
 		return -EIO;
 
 	error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, 0, 0, &tp);
@@ -745,7 +745,7 @@ xfs_ioc_bulkstat(
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 
-	if (XFS_FORCED_SHUTDOWN(mp))
+	if (xfs_is_shut_down(mp))
 		return -EIO;
 
 	if (copy_from_user(&bulkreq, arg, sizeof(xfs_fsop_bulkreq_t)))
@@ -1145,7 +1145,7 @@ xfs_ioctl_setattr_get_trans(
 	if (xfs_is_readonly(mp))
 		goto out_unlock;
 	error = -EIO;
-	if (XFS_FORCED_SHUTDOWN(mp))
+	if (xfs_is_shut_down(mp))
 		goto out_unlock;
 
 	error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, 0, 0, &tp);
@@ -1786,7 +1786,7 @@ xfs_ioc_swapext(
 		goto out_put_tmp_file;
 	}
 
-	if (XFS_FORCED_SHUTDOWN(ip->i_mount)) {
+	if (xfs_is_shut_down(ip->i_mount)) {
 		error = -EIO;
 		goto out_put_tmp_file;
 	}
diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c
index fba115f4103a..375d5baead9e 100644
--- a/fs/xfs/xfs_ioctl32.c
+++ b/fs/xfs/xfs_ioctl32.c
@@ -247,7 +247,7 @@ xfs_compat_ioc_bulkstat(
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 
-	if (XFS_FORCED_SHUTDOWN(mp))
+	if (xfs_is_shut_down(mp))
 		return -EIO;
 
 	if (get_user(addr, &p32->lastip))
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 3c999ea64021..d975f35594e7 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -1006,7 +1006,7 @@ xfs_file_iomap_begin(
 	bool			shared = false, trimmed = false;
 	unsigned		lockmode;
 
-	if (XFS_FORCED_SHUTDOWN(mp))
+	if (xfs_is_shut_down(mp))
 		return -EIO;
 
 	if (((flags & (IOMAP_WRITE | IOMAP_DIRECT)) == IOMAP_WRITE) &&
@@ -1181,7 +1181,7 @@ xfs_file_iomap_end_delalloc(
 
 		error = xfs_bmap_punch_delalloc_range(ip, start_fsb,
 					       end_fsb - start_fsb);
-		if (error && !XFS_FORCED_SHUTDOWN(mp)) {
+		if (error && !xfs_is_shut_down(mp)) {
 			xfs_alert(mp, "%s: unable to clean up ino %lld",
 				__func__, ip->i_ino);
 			return error;
@@ -1227,7 +1227,7 @@ xfs_xattr_iomap_begin(
 	int			nimaps = 1, error = 0;
 	unsigned		lockmode;
 
-	if (XFS_FORCED_SHUTDOWN(mp))
+	if (xfs_is_shut_down(mp))
 		return -EIO;
 
 	lockmode = xfs_ilock_attr_map_shared(ip);
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index 58ef007bccea..c2f028c3f8f5 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -488,7 +488,7 @@ xfs_vn_getattr(
 
 	trace_xfs_getattr(ip);
 
-	if (XFS_FORCED_SHUTDOWN(mp))
+	if (xfs_is_shut_down(mp))
 		return -EIO;
 
 	stat->size = XFS_ISIZE(ip);
@@ -584,7 +584,7 @@ xfs_vn_change_ok(
 	if (xfs_is_readonly(mp))
 		return -EROFS;
 
-	if (XFS_FORCED_SHUTDOWN(mp))
+	if (xfs_is_shut_down(mp))
 		return -EIO;
 
 	return setattr_prepare(dentry, iattr);
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 49579de464f6..043b1a6c5ebd 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -197,7 +197,7 @@ xlog_bread_noalign(
 	bp->b_error = 0;
 
 	error = xfs_buf_submit(bp);
-	if (error && !XFS_FORCED_SHUTDOWN(log->l_mp))
+	if (error && !xfs_is_shut_down(log->l_mp))
 		xfs_buf_ioerror_alert(bp, __func__);
 	return error;
 }
@@ -377,7 +377,7 @@ xlog_recover_iodone(
 		 * We're not going to bother about retrying
 		 * this during recovery. One strike!
 		 */
-		if (!XFS_FORCED_SHUTDOWN(bp->b_target->bt_mount)) {
+		if (!xfs_is_shut_down(bp->b_target->bt_mount)) {
 			xfs_buf_ioerror_alert(bp, __func__);
 			xfs_force_shutdown(bp->b_target->bt_mount,
 						SHUTDOWN_META_IO_ERROR);
@@ -5682,7 +5682,7 @@ xlog_do_recover(
 	/*
 	 * If IO errors happened during recovery, bail out.
 	 */
-	if (XFS_FORCED_SHUTDOWN(mp)) {
+	if (xfs_is_shut_down(mp)) {
 		return -EIO;
 	}
 
@@ -5709,7 +5709,7 @@ xlog_do_recover(
 
 	error = xfs_buf_submit(bp);
 	if (error) {
-		if (!XFS_FORCED_SHUTDOWN(mp)) {
+		if (!xfs_is_shut_down(mp)) {
 			xfs_buf_ioerror_alert(bp, __func__);
 			ASSERT(0);
 		}
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 7cb2577dbd73..d7b5ed30d4c9 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -1187,7 +1187,7 @@ xfs_fs_writable(
 {
 	ASSERT(level > SB_UNFROZEN);
 	if ((mp->m_super->s_writers.frozen >= level) ||
-	    XFS_FORCED_SHUTDOWN(mp) || xfs_is_readonly(mp))
+	    xfs_is_shut_down(mp) || xfs_is_readonly(mp))
 		return false;
 
 	return true;
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 03f4681c1ba6..2a7e7ef7c338 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -296,7 +296,7 @@ __XFS_HAS_FEAT(realtime, REALTIME)
  * Mount features
  *
  * These do not change dynamically - features that can come and go,
- * such as 32 bit inodes and read-only state, are kept as flags rather than
+ * such as 32 bit inodes and read-only state, are kept as state rather than
  * features.
  */
 __XFS_HAS_FEAT(wsync, WSYNC)
@@ -383,8 +383,6 @@ xfs_preferred_iosize(xfs_mount_t *mp)
 	return PAGE_SIZE;
 }
 
-#define XFS_FORCED_SHUTDOWN(mp) \
-		test_bit(XFS_STATE_SHUTDOWN, &(mp)->m_state)
 void xfs_do_force_shutdown(struct xfs_mount *mp, int flags, char *fname,
 		int lnnum);
 #define xfs_force_shutdown(m,f)	\
diff --git a/fs/xfs/xfs_pnfs.c b/fs/xfs/xfs_pnfs.c
index f44c3599527d..2908dcfa9ecf 100644
--- a/fs/xfs/xfs_pnfs.c
+++ b/fs/xfs/xfs_pnfs.c
@@ -99,7 +99,7 @@ xfs_fs_map_blocks(
 	uint			lock_flags;
 	int			error = 0;
 
-	if (XFS_FORCED_SHUTDOWN(mp))
+	if (xfs_is_shut_down(mp))
 		return -EIO;
 
 	/*
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index 9ee840472138..1957042882d5 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -157,7 +157,7 @@ xfs_qm_dqpurge(
 	}
 
 	ASSERT(atomic_read(&dqp->q_pincount) == 0);
-	ASSERT(XFS_FORCED_SHUTDOWN(mp) ||
+	ASSERT(xfs_is_shut_down(mp) ||
 		!test_bit(XFS_LI_IN_AIL, &dqp->q_logitem.qli_item.li_flags));
 
 	xfs_dqfunlock(dqp);
@@ -815,7 +815,7 @@ xfs_qm_qino_alloc(
 
 	error = xfs_trans_commit(tp);
 	if (error) {
-		ASSERT(XFS_FORCED_SHUTDOWN(mp));
+		ASSERT(xfs_is_shut_down(mp));
 		xfs_alert(mp, "%s failed (error %d)!", __func__, error);
 	}
 	if (need_alloc)
diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c
index 66ba7c4446d5..b1196911a8b2 100644
--- a/fs/xfs/xfs_reflink.c
+++ b/fs/xfs/xfs_reflink.c
@@ -1221,7 +1221,7 @@ xfs_reflink_remap_range(
 	if (!xfs_has_reflink(mp))
 		return -EOPNOTSUPP;
 
-	if (XFS_FORCED_SHUTDOWN(mp))
+	if (xfs_is_shut_down(mp))
 		return -EIO;
 
 	/* Lock both files against IO */
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 9938d9fb420b..7c1e03539b5e 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -949,7 +949,7 @@ xfs_fs_destroy_inode(
 
 	xfs_inactive(ip);
 
-	ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0);
+	ASSERT(xfs_is_shut_down(ip->i_mount) || ip->i_delayed_blks == 0);
 	XFS_STATS_INC(ip->i_mount, vn_reclaim);
 
 	/*
diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c
index 675481028292..41e1054748e5 100644
--- a/fs/xfs/xfs_symlink.c
+++ b/fs/xfs/xfs_symlink.c
@@ -124,7 +124,7 @@ xfs_readlink(
 
 	ASSERT(!(ip->i_df.if_flags & XFS_IFINLINE));
 
-	if (XFS_FORCED_SHUTDOWN(mp))
+	if (xfs_is_shut_down(mp))
 		return -EIO;
 
 	xfs_ilock(ip, XFS_ILOCK_SHARED);
@@ -183,7 +183,7 @@ xfs_symlink(
 
 	trace_xfs_symlink(dp, link_name);
 
-	if (XFS_FORCED_SHUTDOWN(mp))
+	if (xfs_is_shut_down(mp))
 		return -EIO;
 
 	/*
@@ -456,7 +456,7 @@ xfs_inactive_symlink_rmt(
 	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
 	error = xfs_trans_commit(tp);
 	if (error) {
-		ASSERT(XFS_FORCED_SHUTDOWN(mp));
+		ASSERT(xfs_is_shut_down(mp));
 		goto error_unlock;
 	}
 
@@ -489,7 +489,7 @@ xfs_inactive_symlink(
 
 	trace_xfs_inactive_symlink(ip);
 
-	if (XFS_FORCED_SHUTDOWN(mp))
+	if (xfs_is_shut_down(mp))
 		return -EIO;
 
 	xfs_ilock(ip, XFS_ILOCK_EXCL);
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index db4367baab34..5c064bc8d49a 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -857,7 +857,7 @@ xfs_trans_committed_bulk(
 		 * object into the AIL as we are in a shutdown situation.
 		 */
 		if (aborted) {
-			ASSERT(XFS_FORCED_SHUTDOWN(ailp->ail_mount));
+			ASSERT(xfs_is_shut_down(ailp->ail_mount));
 			lip->li_ops->iop_unpin(lip, 1);
 			continue;
 		}
@@ -944,7 +944,7 @@ __xfs_trans_commit(
 	if (!(tp->t_flags & XFS_TRANS_DIRTY))
 		goto out_unreserve;
 
-	if (XFS_FORCED_SHUTDOWN(mp)) {
+	if (xfs_is_shut_down(mp)) {
 		error = -EIO;
 		goto out_unreserve;
 	}
@@ -1031,12 +1031,12 @@ xfs_trans_cancel(
 	 * filesystem.  This happens in paths where we detect
 	 * corruption and decide to give up.
 	 */
-	if (dirty && !XFS_FORCED_SHUTDOWN(mp)) {
+	if (dirty && !xfs_is_shut_down(mp)) {
 		XFS_ERROR_REPORT("xfs_trans_cancel", XFS_ERRLEVEL_LOW, mp);
 		xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
 	}
 #ifdef DEBUG
-	if (!dirty && !XFS_FORCED_SHUTDOWN(mp)) {
+	if (!dirty && !xfs_is_shut_down(mp)) {
 		struct xfs_log_item *lip;
 
 		list_for_each_entry(lip, &tp->t_items, li_trans)
diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c
index 55326f971cb3..19e79d8279fc 100644
--- a/fs/xfs/xfs_trans_ail.c
+++ b/fs/xfs/xfs_trans_ail.c
@@ -601,7 +601,7 @@ xfs_ail_push(
 	xfs_log_item_t	*lip;
 
 	lip = xfs_ail_min(ailp);
-	if (!lip || XFS_FORCED_SHUTDOWN(ailp->ail_mount) ||
+	if (!lip || xfs_is_shut_down(ailp->ail_mount) ||
 	    XFS_LSN_CMP(threshold_lsn, ailp->ail_target) <= 0)
 		return;
 
@@ -713,7 +713,7 @@ xfs_trans_ail_update_bulk(
 		xfs_ail_splice(ailp, cur, &tmp, lsn);
 
 	if (mlip_changed) {
-		if (!XFS_FORCED_SHUTDOWN(ailp->ail_mount))
+		if (!xfs_is_shut_down(ailp->ail_mount))
 			xlog_assign_tail_lsn_locked(ailp->ail_mount);
 		spin_unlock(&ailp->ail_lock);
 
@@ -771,7 +771,7 @@ xfs_trans_ail_delete(
 
 	if (!test_bit(XFS_LI_IN_AIL, &lip->li_flags)) {
 		spin_unlock(&ailp->ail_lock);
-		if (!XFS_FORCED_SHUTDOWN(mp)) {
+		if (!xfs_is_shut_down(mp)) {
 			xfs_alert_tag(mp, XFS_PTAG_AILDELETE,
 	"%s: attempting to delete a log item that is not in the AIL",
 					__func__);
@@ -782,7 +782,7 @@ xfs_trans_ail_delete(
 
 	mlip_changed = xfs_ail_delete_one(ailp, lip);
 	if (mlip_changed) {
-		if (!XFS_FORCED_SHUTDOWN(mp))
+		if (!xfs_is_shut_down(mp))
 			xlog_assign_tail_lsn_locked(mp);
 		if (list_empty(&ailp->ail_head))
 			wake_up_all(&ailp->ail_empty);
diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c
index 15919f67a88f..f18d5cd0f606 100644
--- a/fs/xfs/xfs_trans_buf.c
+++ b/fs/xfs/xfs_trans_buf.c
@@ -137,7 +137,7 @@ xfs_trans_get_buf_map(
 	bp = xfs_trans_buf_item_match(tp, target, map, nmaps);
 	if (bp != NULL) {
 		ASSERT(xfs_buf_islocked(bp));
-		if (XFS_FORCED_SHUTDOWN(tp->t_mountp)) {
+		if (xfs_is_shut_down(tp->t_mountp)) {
 			xfs_buf_stale(bp);
 			bp->b_flags |= XBF_DONE;
 		}
@@ -259,7 +259,7 @@ xfs_trans_read_buf_map(
 		 * We never locked this buf ourselves, so we shouldn't
 		 * brelse it either. Just get out.
 		 */
-		if (XFS_FORCED_SHUTDOWN(mp)) {
+		if (xfs_is_shut_down(mp)) {
 			trace_xfs_trans_read_buf_shut(bp, _RET_IP_);
 			return -EIO;
 		}
@@ -291,7 +291,7 @@ xfs_trans_read_buf_map(
 	 */
 	if (bp->b_error) {
 		error = bp->b_error;
-		if (!XFS_FORCED_SHUTDOWN(mp))
+		if (!xfs_is_shut_down(mp))
 			xfs_buf_ioerror_alert(bp, __func__);
 		bp->b_flags &= ~XBF_DONE;
 		xfs_buf_stale(bp);
@@ -306,7 +306,7 @@ xfs_trans_read_buf_map(
 		return error;
 	}
 
-	if (XFS_FORCED_SHUTDOWN(mp)) {
+	if (xfs_is_shut_down(mp)) {
 		xfs_buf_relse(bp);
 		trace_xfs_trans_read_buf_shut(bp, _RET_IP_);
 		return -EIO;
@@ -418,7 +418,7 @@ xfs_trans_brelse(
 	 * due to our reference). Since we're already shutdown and need
 	 * ail_lock, just force remove from the AIL and release the bli here.
 	 */
-	if (XFS_FORCED_SHUTDOWN(tp->t_mountp) && freed) {
+	if (xfs_is_shut_down(tp->t_mountp) && freed) {
 		xfs_trans_ail_remove(&bip->bli_item, SHUTDOWN_LOG_IO_ERROR);
 		xfs_buf_item_relse(bp);
 	} else if (!(bip->bli_flags & XFS_BLI_DIRTY)) {
-- 
2.17.0

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

* [PATCH 07/10] xfs: convert xfs_fs_geometry to use mount feature checks
  2018-08-20  4:48 [PATCH 0/10] xfs: feature flag rework Dave Chinner
                   ` (5 preceding siblings ...)
  2018-08-20  4:48 ` [PATCH 06/10] xfs: replace XFS_FORCED_SHUTDOWN with xfs_is_shut_down Dave Chinner
@ 2018-08-20  4:48 ` Dave Chinner
  2018-08-20  4:48 ` [PATCH 08/10] xfs: open code sb verifier " Dave Chinner
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 27+ messages in thread
From: Dave Chinner @ 2018-08-20  4:48 UTC (permalink / raw)
  To: linux-xfs

From: Dave Chinner <dchinner@redhat.com>

Reporting filesystem features to userspace is currently superblock
based. Now we have a general mount-based feature infrastructure,
switch to using the xfs_mount rather than the superblock directly.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
 fs/xfs/libxfs/xfs_sb.c | 44 ++++++++++++++++++++++--------------------
 fs/xfs/libxfs/xfs_sb.h |  2 +-
 fs/xfs/xfs_ioctl.c     |  4 ++--
 fs/xfs/xfs_ioctl32.c   |  2 +-
 4 files changed, 27 insertions(+), 25 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c
index ee4d483e1209..bedf6c6bf990 100644
--- a/fs/xfs/libxfs/xfs_sb.c
+++ b/fs/xfs/libxfs/xfs_sb.c
@@ -1144,10 +1144,12 @@ xfs_sync_sb_buf(
 
 int
 xfs_fs_geometry(
-	struct xfs_sb		*sbp,
+	struct xfs_mount	*mp,
 	struct xfs_fsop_geom	*geo,
 	int			struct_version)
 {
+	struct xfs_sb		*sbp = &mp->m_sb;
+
 	memset(geo, 0, sizeof(struct xfs_fsop_geom));
 
 	geo->blocksize = sbp->sb_blocksize;
@@ -1177,49 +1179,49 @@ xfs_fs_geometry(
 	geo->version = XFS_FSOP_GEOM_VERSION;
 	geo->flags = XFS_FSOP_GEOM_FLAGS_NLINK |
 		     XFS_FSOP_GEOM_FLAGS_DIRV2;
-	if (xfs_sb_version_hasattr(sbp))
+	if (xfs_has_attr(mp))
 		geo->flags |= XFS_FSOP_GEOM_FLAGS_ATTR;
-	if (xfs_sb_version_hasquota(sbp))
+	if (xfs_has_quota(mp))
 		geo->flags |= XFS_FSOP_GEOM_FLAGS_QUOTA;
-	if (xfs_sb_version_hasalign(sbp))
+	if (xfs_has_align(mp))
 		geo->flags |= XFS_FSOP_GEOM_FLAGS_IALIGN;
-	if (xfs_sb_version_hasdalign(sbp))
+	if (xfs_has_dalign(mp))
 		geo->flags |= XFS_FSOP_GEOM_FLAGS_DALIGN;
-	if (xfs_sb_version_hasextflg(sbp))
+	if (xfs_has_extflg(mp))
 		geo->flags |= XFS_FSOP_GEOM_FLAGS_EXTFLG;
-	if (xfs_sb_version_hassector(sbp))
-		geo->flags |= XFS_FSOP_GEOM_FLAGS_SECTOR;
-	if (xfs_sb_version_hasasciici(sbp))
+	if (xfs_has_asciici(mp))
 		geo->flags |= XFS_FSOP_GEOM_FLAGS_DIRV2CI;
-	if (xfs_sb_version_haslazysbcount(sbp))
+	if (xfs_has_lazysbcount(mp))
 		geo->flags |= XFS_FSOP_GEOM_FLAGS_LAZYSB;
-	if (xfs_sb_version_hasattr2(sbp))
+	if (xfs_has_attr2(mp))
 		geo->flags |= XFS_FSOP_GEOM_FLAGS_ATTR2;
-	if (xfs_sb_version_hasprojid32(sbp))
+	if (xfs_has_projid32(mp))
 		geo->flags |= XFS_FSOP_GEOM_FLAGS_PROJID32;
-	if (xfs_sb_version_hascrc(sbp))
+	if (xfs_has_crc(mp))
 		geo->flags |= XFS_FSOP_GEOM_FLAGS_V5SB;
-	if (xfs_sb_version_hasftype(sbp))
+	if (xfs_has_ftype(mp))
 		geo->flags |= XFS_FSOP_GEOM_FLAGS_FTYPE;
-	if (xfs_sb_version_hasfinobt(sbp))
+	if (xfs_has_finobt(mp))
 		geo->flags |= XFS_FSOP_GEOM_FLAGS_FINOBT;
-	if (xfs_sb_version_hassparseinodes(sbp))
+	if (xfs_has_sparseinodes(mp))
 		geo->flags |= XFS_FSOP_GEOM_FLAGS_SPINODES;
-	if (xfs_sb_version_hasrmapbt(sbp))
+	if (xfs_has_rmapbt(mp))
 		geo->flags |= XFS_FSOP_GEOM_FLAGS_RMAPBT;
-	if (xfs_sb_version_hasreflink(sbp))
+	if (xfs_has_reflink(mp))
 		geo->flags |= XFS_FSOP_GEOM_FLAGS_REFLINK;
-	if (xfs_sb_version_hassector(sbp))
+	if (xfs_has_sector(mp)) {
+		geo->flags |= XFS_FSOP_GEOM_FLAGS_SECTOR;
 		geo->logsectsize = sbp->sb_logsectsize;
-	else
+	} else {
 		geo->logsectsize = BBSIZE;
+	}
 	geo->rtsectsize = sbp->sb_blocksize;
 	geo->dirblocksize = xfs_dir2_dirblock_bytes(sbp);
 
 	if (struct_version < 4)
 		return 0;
 
-	if (xfs_sb_version_haslogv2(sbp))
+	if (xfs_has_logv2(mp))
 		geo->flags |= XFS_FSOP_GEOM_FLAGS_LOGV2;
 
 	geo->logsunit = sbp->sb_logsunit;
diff --git a/fs/xfs/libxfs/xfs_sb.h b/fs/xfs/libxfs/xfs_sb.h
index 640a438402aa..8f4cbe2b639c 100644
--- a/fs/xfs/libxfs/xfs_sb.h
+++ b/fs/xfs/libxfs/xfs_sb.h
@@ -34,7 +34,7 @@ extern uint64_t	xfs_sb_version_to_features(struct xfs_sb *sbp);
 extern int	xfs_update_secondary_sbs(struct xfs_mount *mp);
 
 #define XFS_FS_GEOM_MAX_STRUCT_VER	(4)
-extern int	xfs_fs_geometry(struct xfs_sb *sbp, struct xfs_fsop_geom *geo,
+extern int	xfs_fs_geometry(struct xfs_mount *mp, struct xfs_fsop_geom *geo,
 				int struct_version);
 extern int	xfs_sb_read_secondary(struct xfs_mount *mp,
 				struct xfs_trans *tp, xfs_agnumber_t agno,
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index 6238b6bb7653..8071a297bb44 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -794,7 +794,7 @@ xfs_ioc_fsgeometry_v1(
 	xfs_fsop_geom_t         fsgeo;
 	int			error;
 
-	error = xfs_fs_geometry(&mp->m_sb, &fsgeo, 3);
+	error = xfs_fs_geometry(mp, &fsgeo, 3);
 	if (error)
 		return error;
 
@@ -816,7 +816,7 @@ xfs_ioc_fsgeometry(
 	xfs_fsop_geom_t		fsgeo;
 	int			error;
 
-	error = xfs_fs_geometry(&mp->m_sb, &fsgeo, 4);
+	error = xfs_fs_geometry(mp, &fsgeo, 4);
 	if (error)
 		return error;
 
diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c
index 375d5baead9e..6b395dd63ea1 100644
--- a/fs/xfs/xfs_ioctl32.c
+++ b/fs/xfs/xfs_ioctl32.c
@@ -55,7 +55,7 @@ xfs_compat_ioc_fsgeometry_v1(
 	xfs_fsop_geom_t		  fsgeo;
 	int			  error;
 
-	error = xfs_fs_geometry(&mp->m_sb, &fsgeo, 3);
+	error = xfs_fs_geometry(mp, &fsgeo, 3);
 	if (error)
 		return error;
 	/* The 32-bit variant simply has some padding at the end */
-- 
2.17.0

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

* [PATCH 08/10] xfs: open code sb verifier feature checks
  2018-08-20  4:48 [PATCH 0/10] xfs: feature flag rework Dave Chinner
                   ` (6 preceding siblings ...)
  2018-08-20  4:48 ` [PATCH 07/10] xfs: convert xfs_fs_geometry to use mount feature checks Dave Chinner
@ 2018-08-20  4:48 ` Dave Chinner
  2018-08-21 13:01   ` Jan Tulak
  2018-08-21 13:25   ` Brian Foster
  2018-08-20  4:48 ` [PATCH 09/10] xfs: convert scrub to use mount-based " Dave Chinner
                   ` (2 subsequent siblings)
  10 siblings, 2 replies; 27+ messages in thread
From: Dave Chinner @ 2018-08-20  4:48 UTC (permalink / raw)
  To: linux-xfs

From: Dave Chinner <dchinner@redhat.com>

The superblock verifiers are one of the last places that use the sb
version functions to do feature checks. This are all quite simple
uses, and there aren't many of them so open code them all.

Also, move the good version number check into xfs_sb.c instead of it
being an inline function in xfs_format.h

Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
 fs/xfs/libxfs/xfs_format.h |  26 ---------
 fs/xfs/libxfs/xfs_sb.c     | 116 +++++++++++++++++++++++++------------
 fs/xfs/libxfs/xfs_sb.h     |   1 +
 3 files changed, 81 insertions(+), 62 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
index e21c39b13890..1f1107892dcd 100644
--- a/fs/xfs/libxfs/xfs_format.h
+++ b/fs/xfs/libxfs/xfs_format.h
@@ -280,32 +280,6 @@ typedef struct xfs_dsb {
 
 #define	XFS_SB_VERSION_NUM(sbp)	((sbp)->sb_versionnum & XFS_SB_VERSION_NUMBITS)
 
-/*
- * The first XFS version we support is a v4 superblock with V2 directories.
- */
-static inline bool xfs_sb_good_v4_features(struct xfs_sb *sbp)
-{
-	if (!(sbp->sb_versionnum & XFS_SB_VERSION_DIRV2BIT))
-		return false;
-
-	/* check for unknown features in the fs */
-	if ((sbp->sb_versionnum & ~XFS_SB_VERSION_OKBITS) ||
-	    ((sbp->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT) &&
-	     (sbp->sb_features2 & ~XFS_SB_VERSION2_OKBITS)))
-		return false;
-
-	return true;
-}
-
-static inline bool xfs_sb_good_version(struct xfs_sb *sbp)
-{
-	if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5)
-		return true;
-	if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4)
-		return xfs_sb_good_v4_features(sbp);
-	return false;
-}
-
 static inline bool xfs_sb_version_hasrealtime(struct xfs_sb *sbp)
 {
 	return sbp->sb_rblocks > 0;
diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c
index bedf6c6bf990..b83cf8adca1a 100644
--- a/fs/xfs/libxfs/xfs_sb.c
+++ b/fs/xfs/libxfs/xfs_sb.c
@@ -96,6 +96,35 @@ xfs_perag_put(
 	trace_xfs_perag_put(pag->pag_mount, pag->pag_agno, ref, _RET_IP_);
 }
 
+/*
+ * We support all XFS versions newer than a v4 superblock with V2 directories.
+ */
+bool
+xfs_sb_good_version(
+	struct xfs_sb	*sbp)
+{
+	/* all v5 filesystems are supported */
+	if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5)
+		return true;
+
+	/* versions prior to v4 are not supported */
+	if (XFS_SB_VERSION_NUM(sbp) < XFS_SB_VERSION_4)
+		return false;
+
+	/* V4 filesystems need v2 directories */
+	if (!(sbp->sb_versionnum & XFS_SB_VERSION_DIRV2BIT))
+		return false;
+
+	/* And must not have any unknown v4 feature bits set */
+	if ((sbp->sb_versionnum & ~XFS_SB_VERSION_OKBITS) ||
+	    ((sbp->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT) &&
+	     (sbp->sb_features2 & ~XFS_SB_VERSION2_OKBITS)))
+		return false;
+
+	/* It's a supported v4 filesystem */
+	return true;
+}
+
 uint64_t
 xfs_sb_version_to_features(
 	struct xfs_sb	*sbp)
@@ -288,6 +317,7 @@ xfs_validate_sb_common(
 {
 	uint32_t		agcount = 0;
 	uint32_t		rem;
+	bool			has_dalign;
 
 	if (sbp->sb_magicnum != XFS_SB_MAGIC) {
 		xfs_warn(mp, "bad magic number");
@@ -299,12 +329,43 @@ xfs_validate_sb_common(
 		return -EWRONGFS;
 	}
 
-	if (xfs_sb_version_haspquotino(sbp)) {
+	/*
+	 * Validate feature flags and state
+	 */
+	if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) {
+
+		if (sbp->sb_blocksize < XFS_MIN_CRC_BLOCKSIZE) {
+			xfs_notice(mp,
+"Block size (%u bytes) too small for Version 5 superblock (minimum %d bytes)",
+				sbp->sb_blocksize, XFS_MIN_CRC_BLOCKSIZE);
+			return -EFSCORRUPTED;
+		}
+
+		/* V5 has a separate project quota inode */
 		if (sbp->sb_qflags & (XFS_OQUOTA_ENFD | XFS_OQUOTA_CHKD)) {
 			xfs_notice(mp,
 			   "Version 5 of Super block has XFS_OQUOTA bits.");
 			return -EFSCORRUPTED;
 		}
+
+		/*
+		 * Full inode chunks must be aligned to inode chunk size when
+		 * sparse inodes are enabled to support the sparse chunk
+		 * allocation algorithm and prevent overlapping inode records.
+		 */
+		if (xfs_sb_has_incompat_feature(sbp,
+				XFS_SB_FEAT_INCOMPAT_SPINODES)) {
+			uint32_t	align;
+
+			align = XFS_INODES_PER_CHUNK * sbp->sb_inodesize
+					>> sbp->sb_blocklog;
+			if (sbp->sb_inoalignmt != align) {
+				xfs_warn(mp,
+"Inode block alignment (%u) must match chunk size (%u) for sparse inodes.",
+					 sbp->sb_inoalignmt, align);
+				return -EINVAL;
+			}
+		}
 	} else if (sbp->sb_qflags & (XFS_PQUOTA_ENFD | XFS_GQUOTA_ENFD |
 				XFS_PQUOTA_CHKD | XFS_GQUOTA_CHKD)) {
 			xfs_notice(mp,
@@ -312,24 +373,6 @@ xfs_validate_sb_common(
 			return -EFSCORRUPTED;
 	}
 
-	/*
-	 * Full inode chunks must be aligned to inode chunk size when
-	 * sparse inodes are enabled to support the sparse chunk
-	 * allocation algorithm and prevent overlapping inode records.
-	 */
-	if (xfs_sb_version_hassparseinodes(sbp)) {
-		uint32_t	align;
-
-		align = XFS_INODES_PER_CHUNK * sbp->sb_inodesize
-				>> sbp->sb_blocklog;
-		if (sbp->sb_inoalignmt != align) {
-			xfs_warn(mp,
-"Inode block alignment (%u) must match chunk size (%u) for sparse inodes.",
-				 sbp->sb_inoalignmt, align);
-			return -EINVAL;
-		}
-	}
-
 	if (unlikely(
 	    sbp->sb_logstart == 0 && mp->m_logdev_targp == mp->m_ddev_targp)) {
 		xfs_warn(mp,
@@ -393,14 +436,15 @@ xfs_validate_sb_common(
 		return -EFSCORRUPTED;
 	}
 
+
+	has_dalign = sbp->sb_versionnum & XFS_SB_VERSION_DALIGNBIT;
 	if (sbp->sb_unit) {
-		if (!xfs_sb_version_hasdalign(sbp) ||
-		    sbp->sb_unit > sbp->sb_width ||
+		if (!has_dalign || sbp->sb_unit > sbp->sb_width ||
 		    (sbp->sb_width % sbp->sb_unit) != 0) {
 			xfs_notice(mp, "SB stripe unit sanity check failed");
 			return -EFSCORRUPTED;
 		}
-	} else if (xfs_sb_version_hasdalign(sbp)) {
+	} else if (has_dalign) {
 		xfs_notice(mp, "SB stripe alignment sanity check failed");
 		return -EFSCORRUPTED;
 	} else if (sbp->sb_width) {
@@ -409,12 +453,6 @@ xfs_validate_sb_common(
 	}
 
 
-	if (xfs_has_crc(mp) &&
-	    sbp->sb_blocksize < XFS_MIN_CRC_BLOCKSIZE) {
-		xfs_notice(mp, "v5 SB sanity check failed");
-		return -EFSCORRUPTED;
-	}
-
 	/*
 	 * Until this is fixed only page-sized or smaller data blocks work.
 	 */
@@ -485,7 +523,7 @@ xfs_sb_quota_from_disk(struct xfs_sb *sbp)
 	 * We need to do these manipilations only if we are working
 	 * with an older version of on-disk superblock.
 	 */
-	if (xfs_sb_version_haspquotino(sbp))
+	if (XFS_SB_VERSION_NUM(sbp) < XFS_SB_VERSION_5)
 		return;
 
 	if (sbp->sb_qflags & XFS_OQUOTA_ENFD)
@@ -578,7 +616,8 @@ __xfs_sb_from_disk(
 	 * sb_meta_uuid is only on disk if it differs from sb_uuid and the
 	 * feature flag is set; if not set we keep it only in memory.
 	 */
-	if (xfs_sb_version_hasmetauuid(to))
+	if (XFS_SB_VERSION_NUM(to) == XFS_SB_VERSION_5 &&
+	    (to->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_META_UUID))
 		uuid_copy(&to->sb_meta_uuid, &from->sb_meta_uuid);
 	else
 		uuid_copy(&to->sb_meta_uuid, &from->sb_uuid);
@@ -603,7 +642,12 @@ xfs_sb_quota_to_disk(
 	uint16_t	qflags = from->sb_qflags;
 
 	to->sb_uquotino = cpu_to_be64(from->sb_uquotino);
-	if (xfs_sb_version_haspquotino(from)) {
+
+	/*
+	 * The in-memory superblock quota state matches the v5 on-disk format so
+	 * just write them out and return
+	 */
+	if (XFS_SB_VERSION_NUM(from) == XFS_SB_VERSION_5) {
 		to->sb_qflags = cpu_to_be16(from->sb_qflags);
 		to->sb_gquotino = cpu_to_be64(from->sb_gquotino);
 		to->sb_pquotino = cpu_to_be64(from->sb_pquotino);
@@ -611,9 +655,9 @@ xfs_sb_quota_to_disk(
 	}
 
 	/*
-	 * The in-core version of sb_qflags do not have XFS_OQUOTA_*
-	 * flags, whereas the on-disk version does.  So, convert incore
-	 * XFS_{PG}QUOTA_* flags to on-disk XFS_OQUOTA_* flags.
+	 * For older superblocks (v4), the in-core version of sb_qflags do not
+	 * have XFS_OQUOTA_* flags, whereas the on-disk version does.  So,
+	 * convert incore XFS_{PG}QUOTA_* flags to on-disk XFS_OQUOTA_* flags.
 	 */
 	qflags &= ~(XFS_PQUOTA_ENFD | XFS_PQUOTA_CHKD |
 			XFS_GQUOTA_ENFD | XFS_GQUOTA_CHKD);
@@ -713,7 +757,7 @@ xfs_sb_to_disk(
 	to->sb_features2 = cpu_to_be32(from->sb_features2);
 	to->sb_bad_features2 = cpu_to_be32(from->sb_bad_features2);
 
-	if (xfs_sb_version_hascrc(from)) {
+	if (XFS_SB_VERSION_NUM(from) == XFS_SB_VERSION_5) {
 		to->sb_features_compat = cpu_to_be32(from->sb_features_compat);
 		to->sb_features_ro_compat =
 				cpu_to_be32(from->sb_features_ro_compat);
@@ -723,7 +767,7 @@ xfs_sb_to_disk(
 				cpu_to_be32(from->sb_features_log_incompat);
 		to->sb_spino_align = cpu_to_be32(from->sb_spino_align);
 		to->sb_lsn = cpu_to_be64(from->sb_lsn);
-		if (xfs_sb_version_hasmetauuid(from))
+		if (from->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_META_UUID)
 			uuid_copy(&to->sb_meta_uuid, &from->sb_meta_uuid);
 	}
 }
diff --git a/fs/xfs/libxfs/xfs_sb.h b/fs/xfs/libxfs/xfs_sb.h
index 8f4cbe2b639c..e136c2517647 100644
--- a/fs/xfs/libxfs/xfs_sb.h
+++ b/fs/xfs/libxfs/xfs_sb.h
@@ -29,6 +29,7 @@ extern void	xfs_sb_mount_common(struct xfs_mount *mp, struct xfs_sb *sbp);
 extern void	xfs_sb_from_disk(struct xfs_sb *to, struct xfs_dsb *from);
 extern void	xfs_sb_to_disk(struct xfs_dsb *to, struct xfs_sb *from);
 extern void	xfs_sb_quota_from_disk(struct xfs_sb *sbp);
+extern bool	xfs_sb_good_version(struct xfs_sb *sbp);
 extern uint64_t	xfs_sb_version_to_features(struct xfs_sb *sbp);
 
 extern int	xfs_update_secondary_sbs(struct xfs_mount *mp);
-- 
2.17.0

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

* [PATCH 09/10] xfs: convert scrub to use mount-based feature checks
  2018-08-20  4:48 [PATCH 0/10] xfs: feature flag rework Dave Chinner
                   ` (7 preceding siblings ...)
  2018-08-20  4:48 ` [PATCH 08/10] xfs: open code sb verifier " Dave Chinner
@ 2018-08-20  4:48 ` Dave Chinner
  2018-08-20  4:48 ` [PATCH 10/10] xfs: remove unused xfs_sb_version_has... wrappers Dave Chinner
  2018-08-21 13:54 ` [PATCH 0/10] xfs: feature flag rework Jan Tulak
  10 siblings, 0 replies; 27+ messages in thread
From: Dave Chinner @ 2018-08-20  4:48 UTC (permalink / raw)
  To: linux-xfs

From: Dave Chinner <dchinner@redhat.com>

THe scrub feature checks are the last place that the superblock
feature checks are used. Convert them to mount based feature checks.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
 fs/xfs/scrub/scrub.c | 12 ++++++------
 fs/xfs/scrub/scrub.h |  2 +-
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/fs/xfs/scrub/scrub.c b/fs/xfs/scrub/scrub.c
index 8c1edb39fb8c..4e3323777a2f 100644
--- a/fs/xfs/scrub/scrub.c
+++ b/fs/xfs/scrub/scrub.c
@@ -250,21 +250,21 @@ static const struct xchk_meta_ops meta_scrub_ops[] = {
 		.type	= ST_PERAG,
 		.setup	= xchk_setup_ag_iallocbt,
 		.scrub	= xchk_finobt,
-		.has	= xfs_sb_version_hasfinobt,
+		.has	= xfs_has_finobt,
 		.repair	= xrep_notsupported,
 	},
 	[XFS_SCRUB_TYPE_RMAPBT] = {	/* rmapbt */
 		.type	= ST_PERAG,
 		.setup	= xchk_setup_ag_rmapbt,
 		.scrub	= xchk_rmapbt,
-		.has	= xfs_sb_version_hasrmapbt,
+		.has	= xfs_has_rmapbt,
 		.repair	= xrep_notsupported,
 	},
 	[XFS_SCRUB_TYPE_REFCNTBT] = {	/* refcountbt */
 		.type	= ST_PERAG,
 		.setup	= xchk_setup_ag_refcountbt,
 		.scrub	= xchk_refcountbt,
-		.has	= xfs_sb_version_hasreflink,
+		.has	= xfs_has_reflink,
 		.repair	= xrep_notsupported,
 	},
 	[XFS_SCRUB_TYPE_INODE] = {	/* inode record */
@@ -319,14 +319,14 @@ static const struct xchk_meta_ops meta_scrub_ops[] = {
 		.type	= ST_FS,
 		.setup	= xchk_setup_rt,
 		.scrub	= xchk_rtbitmap,
-		.has	= xfs_sb_version_hasrealtime,
+		.has	= xfs_has_realtime,
 		.repair	= xrep_notsupported,
 	},
 	[XFS_SCRUB_TYPE_RTSUM] = {	/* realtime summary */
 		.type	= ST_FS,
 		.setup	= xchk_setup_rt,
 		.scrub	= xchk_rtsummary,
-		.has	= xfs_sb_version_hasrealtime,
+		.has	= xfs_has_realtime,
 		.repair	= xrep_notsupported,
 	},
 	[XFS_SCRUB_TYPE_UQUOTA] = {	/* user quota */
@@ -388,7 +388,7 @@ xchk_validate_inputs(
 	if (ops->setup == NULL || ops->scrub == NULL)
 		goto out;
 	/* Does this fs even support this type of metadata? */
-	if (ops->has && !ops->has(&mp->m_sb))
+	if (ops->has && !ops->has(mp))
 		goto out;
 
 	error = -EINVAL;
diff --git a/fs/xfs/scrub/scrub.h b/fs/xfs/scrub/scrub.h
index af323b229c4b..1453766a6920 100644
--- a/fs/xfs/scrub/scrub.h
+++ b/fs/xfs/scrub/scrub.h
@@ -28,7 +28,7 @@ struct xchk_meta_ops {
 	int		(*repair)(struct xfs_scrub *);
 
 	/* Decide if we even have this piece of metadata. */
-	bool		(*has)(struct xfs_sb *);
+	bool		(*has)(struct xfs_mount *);
 
 	/* type describing required/allowed inputs */
 	enum xchk_type	type;
-- 
2.17.0

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

* [PATCH 10/10] xfs: remove unused xfs_sb_version_has... wrappers
  2018-08-20  4:48 [PATCH 0/10] xfs: feature flag rework Dave Chinner
                   ` (8 preceding siblings ...)
  2018-08-20  4:48 ` [PATCH 09/10] xfs: convert scrub to use mount-based " Dave Chinner
@ 2018-08-20  4:48 ` Dave Chinner
  2018-08-21 13:54 ` [PATCH 0/10] xfs: feature flag rework Jan Tulak
  10 siblings, 0 replies; 27+ messages in thread
From: Dave Chinner @ 2018-08-20  4:48 UTC (permalink / raw)
  To: linux-xfs

From: Dave Chinner <dchinner@redhat.com>

These wrappers are now almost entirely unused. Remove them.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
 fs/xfs/libxfs/xfs_format.h | 135 +------------------------------------
 1 file changed, 3 insertions(+), 132 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
index 1f1107892dcd..c21fd566bf13 100644
--- a/fs/xfs/libxfs/xfs_format.h
+++ b/fs/xfs/libxfs/xfs_format.h
@@ -280,11 +280,6 @@ typedef struct xfs_dsb {
 
 #define	XFS_SB_VERSION_NUM(sbp)	((sbp)->sb_versionnum & XFS_SB_VERSION_NUMBITS)
 
-static inline bool xfs_sb_version_hasrealtime(struct xfs_sb *sbp)
-{
-	return sbp->sb_rblocks > 0;
-}
-
 /*
  * Detect a mismatched features2 field.  Older kernels read/wrote
  * this into the wrong slot, so to be safe we keep them in sync.
@@ -294,9 +289,10 @@ static inline bool xfs_sb_has_mismatched_features2(struct xfs_sb *sbp)
 	return sbp->sb_bad_features2 != sbp->sb_features2;
 }
 
-static inline bool xfs_sb_version_hasattr(struct xfs_sb *sbp)
+static inline bool xfs_sb_version_hasmorebits(struct xfs_sb *sbp)
 {
-	return (sbp->sb_versionnum & XFS_SB_VERSION_ATTRBIT);
+	return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 ||
+	       (sbp->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT);
 }
 
 static inline void xfs_sb_version_addattr(struct xfs_sb *sbp)
@@ -304,72 +300,11 @@ static inline void xfs_sb_version_addattr(struct xfs_sb *sbp)
 	sbp->sb_versionnum |= XFS_SB_VERSION_ATTRBIT;
 }
 
-static inline bool xfs_sb_version_hasquota(struct xfs_sb *sbp)
-{
-	return (sbp->sb_versionnum & XFS_SB_VERSION_QUOTABIT);
-}
-
 static inline void xfs_sb_version_addquota(struct xfs_sb *sbp)
 {
 	sbp->sb_versionnum |= XFS_SB_VERSION_QUOTABIT;
 }
 
-static inline bool xfs_sb_version_hasalign(struct xfs_sb *sbp)
-{
-	return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 ||
-		(sbp->sb_versionnum & XFS_SB_VERSION_ALIGNBIT));
-}
-
-static inline bool xfs_sb_version_hasdalign(struct xfs_sb *sbp)
-{
-	return (sbp->sb_versionnum & XFS_SB_VERSION_DALIGNBIT);
-}
-
-static inline bool xfs_sb_version_haslogv2(struct xfs_sb *sbp)
-{
-	return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 ||
-	       (sbp->sb_versionnum & XFS_SB_VERSION_LOGV2BIT);
-}
-
-static inline bool xfs_sb_version_hasextflg(struct xfs_sb *sbp)
-{
-	return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 ||
-	       (sbp->sb_versionnum & XFS_SB_VERSION_EXTFLGBIT);
-}
-
-static inline bool xfs_sb_version_hassector(struct xfs_sb *sbp)
-{
-	return (sbp->sb_versionnum & XFS_SB_VERSION_SECTORBIT);
-}
-
-static inline bool xfs_sb_version_hasasciici(struct xfs_sb *sbp)
-{
-	return (sbp->sb_versionnum & XFS_SB_VERSION_BORGBIT);
-}
-
-static inline bool xfs_sb_version_hasmorebits(struct xfs_sb *sbp)
-{
-	return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 ||
-	       (sbp->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT);
-}
-
-/*
- * sb_features2 bit version macros.
- */
-static inline bool xfs_sb_version_haslazysbcount(struct xfs_sb *sbp)
-{
-	return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) ||
-	       (xfs_sb_version_hasmorebits(sbp) &&
-		(sbp->sb_features2 & XFS_SB_VERSION2_LAZYSBCOUNTBIT));
-}
-
-static inline bool xfs_sb_version_hasattr2(struct xfs_sb *sbp)
-{
-	return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) ||
-	       (xfs_sb_version_hasmorebits(sbp) &&
-		(sbp->sb_features2 & XFS_SB_VERSION2_ATTR2BIT));
-}
-
 static inline void xfs_sb_version_addattr2(struct xfs_sb *sbp)
 {
 	sbp->sb_versionnum |= XFS_SB_VERSION_MOREBITSBIT;
@@ -383,13 +318,6 @@ static inline void xfs_sb_version_removeattr2(struct xfs_sb *sbp)
 		sbp->sb_versionnum &= ~XFS_SB_VERSION_MOREBITSBIT;
 }
 
-static inline bool xfs_sb_version_hasprojid32(struct xfs_sb *sbp)
-{
-	return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) ||
-	       (xfs_sb_version_hasmorebits(sbp) &&
-		(sbp->sb_features2 & XFS_SB_VERSION2_PROJID32BIT));
-}
-
 static inline void xfs_sb_version_addprojid32(struct xfs_sb *sbp)
 {
 	sbp->sb_versionnum |= XFS_SB_VERSION_MOREBITSBIT;
@@ -467,63 +395,6 @@ xfs_sb_has_incompat_log_feature(
 	return (sbp->sb_features_log_incompat & feature) != 0;
 }
 
-/*
- * V5 superblock specific feature checks
- */
-static inline bool xfs_sb_version_hascrc(struct xfs_sb *sbp)
-{
-	return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5;
-}
-
-static inline bool xfs_sb_version_haspquotino(struct xfs_sb *sbp)
-{
-	return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5;
-}
-
-static inline int xfs_sb_version_hasftype(struct xfs_sb *sbp)
-{
-	return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 &&
-		xfs_sb_has_incompat_feature(sbp, XFS_SB_FEAT_INCOMPAT_FTYPE)) ||
-	       (xfs_sb_version_hasmorebits(sbp) &&
-		 (sbp->sb_features2 & XFS_SB_VERSION2_FTYPE));
-}
-
-static inline bool xfs_sb_version_hasfinobt(xfs_sb_t *sbp)
-{
-	return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) &&
-		(sbp->sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_FINOBT);
-}
-
-static inline bool xfs_sb_version_hassparseinodes(struct xfs_sb *sbp)
-{
-	return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 &&
-		xfs_sb_has_incompat_feature(sbp, XFS_SB_FEAT_INCOMPAT_SPINODES);
-}
-
-/*
- * XFS_SB_FEAT_INCOMPAT_META_UUID indicates that the metadata UUID
- * is stored separately from the user-visible UUID; this allows the
- * user-visible UUID to be changed on V5 filesystems which have a
- * filesystem UUID stamped into every piece of metadata.
- */
-static inline bool xfs_sb_version_hasmetauuid(struct xfs_sb *sbp)
-{
-	return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) &&
-		(sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_META_UUID);
-}
-
-static inline bool xfs_sb_version_hasrmapbt(struct xfs_sb *sbp)
-{
-	return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) &&
-		(sbp->sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_RMAPBT);
-}
-
-static inline bool xfs_sb_version_hasreflink(struct xfs_sb *sbp)
-{
-	return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 &&
-		(sbp->sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_REFLINK);
-}
-
 /*
  * end of superblock version macros
  */
-- 
2.17.0

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

* Re: [PATCH 08/10] xfs: open code sb verifier feature checks
  2018-08-20  4:48 ` [PATCH 08/10] xfs: open code sb verifier " Dave Chinner
@ 2018-08-21 13:01   ` Jan Tulak
  2018-08-21 23:43     ` Dave Chinner
  2018-08-21 13:25   ` Brian Foster
  1 sibling, 1 reply; 27+ messages in thread
From: Jan Tulak @ 2018-08-21 13:01 UTC (permalink / raw)
  To: Chinner, Dave; +Cc: linux-xfs

On Mon, Aug 20, 2018 at 6:49 AM Dave Chinner <david@fromorbit.com> wrote:
>
> From: Dave Chinner <dchinner@redhat.com>
>
> The superblock verifiers are one of the last places that use the sb
> version functions to do feature checks. This are all quite simple
> uses, and there aren't many of them so open code them all.
>
> Also, move the good version number check into xfs_sb.c instead of it
> being an inline function in xfs_format.h
>
> Signed-off-by: Dave Chinner <dchinner@redhat.com>
> ---
>  fs/xfs/libxfs/xfs_format.h |  26 ---------
>  fs/xfs/libxfs/xfs_sb.c     | 116 +++++++++++++++++++++++++------------
>  fs/xfs/libxfs/xfs_sb.h     |   1 +
>  3 files changed, 81 insertions(+), 62 deletions(-)
>
> diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
> index e21c39b13890..1f1107892dcd 100644
> --- a/fs/xfs/libxfs/xfs_format.h
> +++ b/fs/xfs/libxfs/xfs_format.h
> @@ -280,32 +280,6 @@ typedef struct xfs_dsb {
>
>  #define        XFS_SB_VERSION_NUM(sbp) ((sbp)->sb_versionnum & XFS_SB_VERSION_NUMBITS)
>
> -/*
> - * The first XFS version we support is a v4 superblock with V2 directories.
> - */
> -static inline bool xfs_sb_good_v4_features(struct xfs_sb *sbp)
> -{
> -       if (!(sbp->sb_versionnum & XFS_SB_VERSION_DIRV2BIT))
> -               return false;
> -
> -       /* check for unknown features in the fs */
> -       if ((sbp->sb_versionnum & ~XFS_SB_VERSION_OKBITS) ||
> -           ((sbp->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT) &&
> -            (sbp->sb_features2 & ~XFS_SB_VERSION2_OKBITS)))
> -               return false;
> -
> -       return true;
> -}
> -
> -static inline bool xfs_sb_good_version(struct xfs_sb *sbp)
> -{
> -       if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5)
> -               return true;
> -       if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4)
> -               return xfs_sb_good_v4_features(sbp);
> -       return false;
> -}
> -

As I understand this removed code, if, in the future, we would have
e.g. superblock v6, then xfs_sb_good_version would return false,
right? Which I think is not correctly replicated in the new function
below.

>  static inline bool xfs_sb_version_hasrealtime(struct xfs_sb *sbp)
>  {
>         return sbp->sb_rblocks > 0;
> diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c
> index bedf6c6bf990..b83cf8adca1a 100644
> --- a/fs/xfs/libxfs/xfs_sb.c
> +++ b/fs/xfs/libxfs/xfs_sb.c
> @@ -96,6 +96,35 @@ xfs_perag_put(
>         trace_xfs_perag_put(pag->pag_mount, pag->pag_agno, ref, _RET_IP_);
>  }
>
> +/*
> + * We support all XFS versions newer than a v4 superblock with V2 directories.
> + */
> +bool
> +xfs_sb_good_version(
> +       struct xfs_sb   *sbp)
> +{
> +       /* all v5 filesystems are supported */
> +       if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5)
> +               return true;
> +
> +       /* versions prior to v4 are not supported */
> +       if (XFS_SB_VERSION_NUM(sbp) < XFS_SB_VERSION_4)
> +               return false;
> +
> +       /* V4 filesystems need v2 directories */
> +       if (!(sbp->sb_versionnum & XFS_SB_VERSION_DIRV2BIT))
> +               return false;
> +
> +       /* And must not have any unknown v4 feature bits set */
> +       if ((sbp->sb_versionnum & ~XFS_SB_VERSION_OKBITS) ||
> +           ((sbp->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT) &&
> +            (sbp->sb_features2 & ~XFS_SB_VERSION2_OKBITS)))
> +               return false;
> +
> +       /* It's a supported v4 filesystem */
> +       return true;
> +}
> +

If we call this xfs_sb_good_version() with superblock v6 or higher, it
returns true too, not only for a supported v4. Unless the V4 specific
checks (v2 directories and feature bits) somehow implicitly prevents
that from happening, which is something I can't tell. :-)

Cheers,
Jan

-- 
Jan Tulak
jtulak@redhat.com / jan@tulak.me

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

* Re: [PATCH 01/10] xfs: reflect sb features in xfs_mount
  2018-08-20  4:48 ` [PATCH 01/10] xfs: reflect sb features in xfs_mount Dave Chinner
@ 2018-08-21 13:21   ` Brian Foster
  2018-08-21 23:31     ` Dave Chinner
  0 siblings, 1 reply; 27+ messages in thread
From: Brian Foster @ 2018-08-21 13:21 UTC (permalink / raw)
  To: Dave Chinner; +Cc: linux-xfs

On Mon, Aug 20, 2018 at 02:48:42PM +1000, Dave Chinner wrote:
> From: Dave Chinner <dchinner@redhat.com>
> 
> Currently on-disk feature checks require decoding the superblock
> fileds and so can be non-trivial. We have almost 400 hundred
> individual feature checks in the XFS code, so this is a significant
> amount of code. To reduce runtime check overhead, pre-process all
> the version flags into a features field in the xfs_mount at mount
> time so we can convert all the feature checks to a simple flag
> check.
> 
> There is also a need to convert the dynamic feature flags to update
> the m_features field. This is required for attr, attr2 and quota
> features. New xfs_mount based wrappers are added for this.
> 
> Before:
> 
> $ size -t fs/xfs/built-in.a
>    text	   data	    bss	    dec	    hex	filename
> ....
> 1294873	 182766	   1036	1478675	 169013	(TOTALS
> 

Was some text truncated from the commit log description here? Did you
mean to include the after size as well?

> Signed-off-by: Dave Chinner <dchinner@redhat.com>
> ---
>  fs/xfs/libxfs/xfs_format.h |  2 +-
>  fs/xfs/libxfs/xfs_sb.c     | 61 +++++++++++++++++++++++++++++
>  fs/xfs/libxfs/xfs_sb.h     |  1 +
>  fs/xfs/xfs_log_recover.c   |  1 +
>  fs/xfs/xfs_mount.c         |  1 +
>  fs/xfs/xfs_mount.h         | 79 ++++++++++++++++++++++++++++++++++++++
>  6 files changed, 144 insertions(+), 1 deletion(-)
> 
...
> diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
> index a21dc61ec09e..5d0438ec07dd 100644
> --- a/fs/xfs/xfs_log_recover.c
> +++ b/fs/xfs/xfs_log_recover.c
> @@ -5723,6 +5723,7 @@ xlog_do_recover(
>  	xfs_buf_relse(bp);
>  
>  	/* re-initialise in-core superblock and geometry structures */
> +	mp->m_features |= xfs_sb_version_to_features(sbp);

How is this a reinit if it ORs in fields? I guess I'm curious why we OR
in fields in either case as opposed to using an assignment.

>  	xfs_reinit_percpu_counters(mp);
>  	error = xfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi);
>  	if (error) {
...
> diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
> index 7964513c3128..92d947f17c69 100644
> --- a/fs/xfs/xfs_mount.h
> +++ b/fs/xfs/xfs_mount.h
> @@ -127,6 +127,7 @@ typedef struct xfs_mount {
>  	struct mutex		m_growlock;	/* growfs mutex */
>  	int			m_fixedfsid[2];	/* unchanged for life of FS */
>  	uint64_t		m_flags;	/* global mount flags */
> +	uint64_t		m_features;	/* active filesystem features */
>  	bool			m_inotbt_nores; /* no per-AG finobt resv. */
>  	int			m_ialloc_inos;	/* inodes in inode allocation */
>  	int			m_ialloc_blks;	/* blocks in inode allocation */
> @@ -195,6 +196,84 @@ typedef struct xfs_mount {
>  #endif
>  } xfs_mount_t;
>  
> +/*
> + * Flags for m_features.
> + *
> + * These are all the active features in the filesystem, regardless of how
> + * they are configured.
> + */
> +#define	XFS_FEAT_ATTR		(1ULL << 0)	/* xattrs present in fs */
> +#define	XFS_FEAT_NLINK		(1ULL << 1)	/* 32 bit link counts */
> +#define	XFS_FEAT_QUOTA		(1ULL << 2)	/* quota active */
> +#define	XFS_FEAT_ALIGN		(1ULL << 3)	/* inode alignment */
> +#define	XFS_FEAT_DALIGN		(1ULL << 4)	/* data alignment */
> +#define XFS_FEAT_LOGV2		(1ULL << 5)	/* version 2 logs */
> +#define XFS_FEAT_SECTOR		(1ULL << 6)	/* sector size > 512 bytes */
> +#define	XFS_FEAT_EXTFLG		(1ULL << 7)	/* unwritten extents */
> +#define	XFS_FEAT_ASCIICI	(1ULL << 8)	/* ASCII only case-insens. */
> +#define XFS_FEAT_LAZYSBCOUNT	(1ULL << 9)	/* Superblk counters */
> +#define XFS_FEAT_ATTR2		(1ULL << 10)	/* dynamic attr fork */
> +#define XFS_FEAT_PARENT		(1ULL << 11)	/* parent pointers */

Hmm, none of the parent pointer stuff has been merged yet, has it? If
not, I'm sure it will be at some point, but I'd prefer not to include
code for features that technically don't exist.

Otherwise it looks like we have some inconsistent spacing/indentation.

> +#define XFS_FEAT_PROJID32	(1ULL << 12)	/* 32 bit project id */
> +#define XFS_FEAT_CRC		(1ULL << 13)	/* metadata CRCs */
> +#define XFS_FEAT_PQUOTINO	(1ULL << 14)	/* non-shared proj/grp quotas */
> +#define XFS_FEAT_FTYPE		(1ULL << 15)	/* inode type in dir */
> +#define XFS_FEAT_FINOBT		(1ULL << 16)	/* free inode btree */
> +#define XFS_FEAT_RMAPBT		(1ULL << 17)	/* reverse map btree */
> +#define XFS_FEAT_REFLINK	(1ULL << 18)	/* reflinked files */
> +#define XFS_FEAT_SPINODES	(1ULL << 19)	/* sparse inode chunks */
> +#define XFS_FEAT_META_UUID	(1ULL << 20)	/* metadata UUID */
> +#define XFS_FEAT_REALTIME	(1ULL << 21)	/* realtime device present */
> +
> +#define __XFS_HAS_FEAT(name, NAME) \
> +static inline bool xfs_has_ ## name (struct xfs_mount *mp) \
> +{ \

I'm assuming these xfs_has_*() calls will end up replacing the current
xfs_sb_version_has*() calls throughout the code. Could we start using a
consistent function name prefix across the helpers? E.g., I think using
'xfs_feat_ ## name' here (instead of xfs_has_) would be fine, and
consistent with the other helpers.

I don't want to get into bikeshedding too much but tbh I've always found
the xfs_sb_has_* thing kind of weird where the "has" text seems
superfluous. It's just not been worth changing. It would be nice if we
could stop propagating it here and define a consistently used prefix.

> +	return mp->m_features & XFS_FEAT_ ## NAME; \
> +}
> +
> +/* Some features can be added dynamically so they need a set wrapper, too. */
> +#define __XFS_HAS_ADDFEAT(name, NAME) \
> +	__XFS_HAS_FEAT(name, NAME); \
> +static inline void xfs_feat_add_ ## name (struct xfs_mount *mp) \
> +{ \
> +	mp->m_features |= XFS_FEAT_ ## NAME; \
> +	xfs_sb_version_add ## name(&mp->m_sb); \
> +}
> +
> +/* Some features can be cleared dynamically so they need a clear wrapper */
> +#define __XFS_HAS_REMOVEFEAT(name, NAME) \
> +	__XFS_HAS_ADDFEAT(name, NAME); \
> +static inline void xfs_feat_remove_ ## name (struct xfs_mount *mp) \
> +{ \
> +	mp->m_features &= ~XFS_FEAT_ ## NAME; \
> +	xfs_sb_version_remove ## name(&mp->m_sb); \
> +}
> +

In addition to the above, we use HAS_FEAT for an underlying xfs_has_
(i.e., no "feat") helper above, yet for some reason also use the HAS for
the underlying xfs_feat_add/remove() helpers that don't use the "has"
wording. On top of that, HAS_ADD implies HAS and HAS_REMOVE implies
HAS_ADD, which isn't really clear from the naming.

I think this would all be much clearer if we defined something like the
following:

	__XFS_FEAT -> xfs_feat_*
	__XFS_FEAT_ADD -> xfs_feat_add_*
	__XFS_FEAT_REMOVE -> xfs_feat_remove_*

... for the individual helpers (i.e., no implicit dependencies) and then
just open-coded the appropriate calls in the list below. Alternatively,
we could create another set of macros like
XFS_FEAT_[FIXED|ADDONLY|ADDRM]() for the particular combinations that we
happen to use today. Either way would make it self-evident from the list
itself what helpers are defined without having to dig into all of the
macros.

Brian

> +
> +__XFS_HAS_ADDFEAT(attr, ATTR)
> +__XFS_HAS_FEAT(nlink, NLINK)
> +__XFS_HAS_ADDFEAT(quota, QUOTA)
> +__XFS_HAS_FEAT(align, ALIGN)
> +__XFS_HAS_FEAT(dalign, DALIGN)
> +__XFS_HAS_FEAT(logv2, LOGV2)
> +__XFS_HAS_FEAT(sector, SECTOR)
> +__XFS_HAS_FEAT(extflg, EXTFLG)
> +__XFS_HAS_FEAT(asciici, ASCIICI)
> +__XFS_HAS_FEAT(lazysbcount, LAZYSBCOUNT)
> +__XFS_HAS_REMOVEFEAT(attr2, ATTR2)
> +__XFS_HAS_FEAT(parent, PARENT)
> +__XFS_HAS_ADDFEAT(projid32, PROJID32)
> +__XFS_HAS_FEAT(crc, CRC)
> +__XFS_HAS_FEAT(pquotino, PQUOTINO)
> +__XFS_HAS_FEAT(ftype, FTYPE)
> +__XFS_HAS_FEAT(finobt, FINOBT)
> +__XFS_HAS_FEAT(rmapbt, RMAPBT)
> +__XFS_HAS_FEAT(reflink, REFLINK)
> +__XFS_HAS_FEAT(sparseinodes, SPINODES)
> +__XFS_HAS_FEAT(metauuid, META_UUID)
> +__XFS_HAS_FEAT(realtime, REALTIME)
> +
> +
>  /*
>   * Flags for m_flags.
>   */
> -- 
> 2.17.0
> 

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

* Re: [PATCH 03/10] xfs: consolidate mount option features in m_features
  2018-08-20  4:48 ` [PATCH 03/10] xfs: consolidate mount option features in m_features Dave Chinner
@ 2018-08-21 13:21   ` Brian Foster
  2018-08-21 23:32     ` Dave Chinner
  0 siblings, 1 reply; 27+ messages in thread
From: Brian Foster @ 2018-08-21 13:21 UTC (permalink / raw)
  To: Dave Chinner; +Cc: linux-xfs

On Mon, Aug 20, 2018 at 02:48:44PM +1000, Dave Chinner wrote:
> From: Dave Chinner <dchinner@redhat.com>
> 
> This provides separation of mount time feature flags from runtime
> mount flagsi and mount option state. It also makes the feature

s/flagsi/flags/

> checks use the same interface as the superblock features. i.e. we
> don't care if the feature is enabled by superblock flags or mount
> options, we just care if it's enabled or not.
> 
> Signed-off-by: Dave Chinner <dchinner@redhat.com>
> ---
>  fs/xfs/xfs_mount.h | 36 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 36 insertions(+)
> 
> diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
> index 92d947f17c69..74a128fe316b 100644
> --- a/fs/xfs/xfs_mount.h
> +++ b/fs/xfs/xfs_mount.h
> @@ -225,6 +225,21 @@ typedef struct xfs_mount {
>  #define XFS_FEAT_META_UUID	(1ULL << 20)	/* metadata UUID */
>  #define XFS_FEAT_REALTIME	(1ULL << 21)	/* realtime device present */
>  
> +#define XFS_FEAT_WSYNC		(1ULL << 22)	/* synchronous metadata ops */
> +#define XFS_FEAT_DIRSYNC	(1ULL << 23)	/* synchronous directory ops */
> +#define XFS_FEAT_DISCARD	(1ULL << 24)	/* discard unused blocks */
> +#define XFS_FEAT_GRPID		(1ULL << 25)	/* group-ID assigned from directory */
> +#define XFS_FEAT_SMALL_INUMS	(1ULL << 26)	/* user wants 32bit inodes */
> +#define XFS_FEAT_IKEEP		(1ULL << 27)	/* keep empty inode clusters*/
> +#define XFS_FEAT_SWALLOC	(1ULL << 28)	/* stripe width allocation */
> +#define XFS_FEAT_FILESTREAMS	(1ULL << 29)	/* enable the filestreams
> +						   allocator */
> +#define XFS_FEAT_DAX		(1ULL << 30)	/* TEST ONLY! */
> +#define XFS_FEAT_COMPAT_IOSIZE	(1ULL << 31)	/* don't report large preferred
> +						 * I/O size in stat() */
> +#define XFS_FEAT_NORECOVERY	(1ULL << 32)	/* no recovery - dirty fs */
> +#define XFS_FEAT_NOUUID		(1ULL << 33)	/* ignore uuid during mount */

Similar indentation issue here..? Otherwise looks fine modulo the
previous comments on the broader API.

Brian

> +
>  #define __XFS_HAS_FEAT(name, NAME) \
>  static inline bool xfs_has_ ## name (struct xfs_mount *mp) \
>  { \
> @@ -250,6 +265,7 @@ static inline void xfs_feat_remove_ ## name (struct xfs_mount *mp) \
>  }
>  
>  
> +/* superblock features */
>  __XFS_HAS_ADDFEAT(attr, ATTR)
>  __XFS_HAS_FEAT(nlink, NLINK)
>  __XFS_HAS_ADDFEAT(quota, QUOTA)
> @@ -274,6 +290,26 @@ __XFS_HAS_FEAT(metauuid, META_UUID)
>  __XFS_HAS_FEAT(realtime, REALTIME)
>  
>  
> +/*
> + * Mount features
> + *
> + * These do not change dynamically - features that can come and go,
> + * such as 32 bit inodes and read-only state, are kept as flags rather than
> + * features.
> + */
> +__XFS_HAS_FEAT(wsync, WSYNC)
> +__XFS_HAS_FEAT(dirsync, DIRSYNC)
> +__XFS_HAS_FEAT(discard, DISCARD)
> +__XFS_HAS_FEAT(grpid, GRPID)
> +__XFS_HAS_FEAT(small_inums, SMALL_INUMS)
> +__XFS_HAS_FEAT(ikeep, IKEEP)
> +__XFS_HAS_FEAT(swalloc, SWALLOC)
> +__XFS_HAS_FEAT(filestreams, FILESTREAMS)
> +__XFS_HAS_FEAT(dax, DAX)
> +__XFS_HAS_FEAT(compat_iosize, COMPAT_IOSIZE)
> +__XFS_HAS_FEAT(norecovery, NORECOVERY)
> +__XFS_HAS_FEAT(nouuid, NOUUID)
> +
>  /*
>   * Flags for m_flags.
>   */
> -- 
> 2.17.0
> 

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

* Re: [PATCH 04/10] xfs: convert mount flags to features
  2018-08-20  4:48 ` [PATCH 04/10] xfs: convert mount flags to features Dave Chinner
@ 2018-08-21 13:22   ` Brian Foster
  2018-08-21 23:36     ` Dave Chinner
  0 siblings, 1 reply; 27+ messages in thread
From: Brian Foster @ 2018-08-21 13:22 UTC (permalink / raw)
  To: Dave Chinner; +Cc: linux-xfs

On Mon, Aug 20, 2018 at 02:48:45PM +1000, Dave Chinner wrote:
> From: Dave Chinner <dchinner@redhat.com>
> 
> Replace m_flags feature checks with xfs_has_<feature>() calls and
> rework the setup code to set flags in m_features.
> 
> Fallout is that there are some attr2/noattr2 changes - there's no
> longer separate feature flags for the attr2 superblock and attr2
> mount options - they both set the same flag. Hence we use the
> noattr2 feature to trigger turning off attr2 at mount time - it
> doesn't matter if it is the mount option or the sb feature that set
> it, specifying noattr2 will turn off attr2 for the current mount and
> clear it from the sb feature set.
> 
> [Discuss: Might be worth moving the attr2 changes into a separate
> patch so it's clear what changes are being made.]
> 

Yeah, a separate patch to condense the attr bits might be a good idea.
It also looks like some iosize feature changes crept in here that should
have been in a previous patch..?

Otherwise looks reasonable.

Brian

> Signed-off-by: Dave Chinner <dchinner@redhat.com>
> ---
>  fs/xfs/libxfs/xfs_attr.c      |   6 +-
>  fs/xfs/libxfs/xfs_attr_leaf.c |  36 +++++-----
>  fs/xfs/libxfs/xfs_bmap.c      |   4 +-
>  fs/xfs/libxfs/xfs_ialloc.c    |  10 ++-
>  fs/xfs/libxfs/xfs_inode_buf.c |   5 +-
>  fs/xfs/scrub/scrub.c          |   2 +-
>  fs/xfs/xfs_bmap_util.c        |   2 +-
>  fs/xfs/xfs_export.c           |   2 +-
>  fs/xfs/xfs_filestream.h       |   2 +-
>  fs/xfs/xfs_inode.c            |  10 +--
>  fs/xfs/xfs_inode.h            |   3 +-
>  fs/xfs/xfs_ioctl.c            |   2 +-
>  fs/xfs/xfs_iomap.c            |   6 +-
>  fs/xfs/xfs_iops.c             |   7 +-
>  fs/xfs/xfs_log.c              |  14 ++--
>  fs/xfs/xfs_log_cil.c          |   4 +-
>  fs/xfs/xfs_mount.c            |  43 +++++-------
>  fs/xfs/xfs_mount.h            |  52 +++++----------
>  fs/xfs/xfs_super.c            | 119 +++++++++++++++-------------------
>  fs/xfs/xfs_symlink.c          |   3 +-
>  20 files changed, 144 insertions(+), 188 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
> index 1e671d4eb6fa..5ca0233fe135 100644
> --- a/fs/xfs/libxfs/xfs_attr.c
> +++ b/fs/xfs/libxfs/xfs_attr.c
> @@ -294,7 +294,7 @@ xfs_attr_set(
>  			 * the transaction goes to disk before returning
>  			 * to the user.
>  			 */
> -			if (mp->m_flags & XFS_MOUNT_WSYNC)
> +			if (xfs_has_wsync(mp))
>  				xfs_trans_set_sync(args.trans);
>  
>  			if (!error && (flags & ATTR_KERNOTIME) == 0) {
> @@ -347,7 +347,7 @@ xfs_attr_set(
>  	 * If this is a synchronous mount, make sure that the
>  	 * transaction goes to disk before returning to the user.
>  	 */
> -	if (mp->m_flags & XFS_MOUNT_WSYNC)
> +	if (xfs_has_wsync(mp))
>  		xfs_trans_set_sync(args.trans);
>  
>  	if ((flags & ATTR_KERNOTIME) == 0)
> @@ -441,7 +441,7 @@ xfs_attr_remove(
>  	 * If this is a synchronous mount, make sure that the
>  	 * transaction goes to disk before returning to the user.
>  	 */
> -	if (mp->m_flags & XFS_MOUNT_WSYNC)
> +	if (xfs_has_wsync(mp))
>  		xfs_trans_set_sync(args.trans);
>  
>  	if ((flags & ATTR_KERNOTIME) == 0)
> diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c
> index fbd53362b5bc..f9e536d6dd72 100644
> --- a/fs/xfs/libxfs/xfs_attr_leaf.c
> +++ b/fs/xfs/libxfs/xfs_attr_leaf.c
> @@ -448,7 +448,7 @@ xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes)
>  	 * literal area, but for the old format we are done if there is no
>  	 * space in the fixed attribute fork.
>  	 */
> -	if (!(mp->m_flags & XFS_MOUNT_ATTR2))
> +	if (!xfs_has_attr2(mp))
>  		return 0;
>  
>  	dsize = dp->i_df.if_bytes;
> @@ -502,21 +502,26 @@ xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes)
>  }
>  
>  /*
> - * Switch on the ATTR2 superblock bit (implies also FEATURES2)
> + * Switch on the ATTR2 superblock bit (implies also FEATURES2) by default unless
> + * we've explicitly been told not to use attr2 (i.e. noattr2 mount option).
>   */
>  STATIC void
>  xfs_sbversion_add_attr2(xfs_mount_t *mp, xfs_trans_t *tp)
>  {
> -	if ((mp->m_flags & XFS_MOUNT_ATTR2) &&
> -	    !(xfs_has_attr2(mp))) {
> -		spin_lock(&mp->m_sb_lock);
> -		if (!xfs_has_attr2(mp)) {
> -			xfs_feat_add_attr2(mp);
> -			spin_unlock(&mp->m_sb_lock);
> -			xfs_log_sb(tp);
> -		} else
> -			spin_unlock(&mp->m_sb_lock);
> +	if (xfs_has_attr2(mp))
> +		return;
> +	if (xfs_has_noattr2(mp))
> +		return;
> +
> +	spin_lock(&mp->m_sb_lock);
> +	if (xfs_has_attr2(mp)) {
> +		spin_unlock(&mp->m_sb_lock);
> +		return;
>  	}
> +
> +	xfs_feat_add_attr2(mp);
> +	spin_unlock(&mp->m_sb_lock);
> +	xfs_log_sb(tp);
>  }
>  
>  /*
> @@ -671,8 +676,7 @@ xfs_attr_shortform_remove(xfs_da_args_t *args)
>  	 * Fix up the start offset of the attribute fork
>  	 */
>  	totsize -= size;
> -	if (totsize == sizeof(xfs_attr_sf_hdr_t) &&
> -	    (mp->m_flags & XFS_MOUNT_ATTR2) &&
> +	if (totsize == sizeof(xfs_attr_sf_hdr_t) && xfs_has_attr2(mp) &&
>  	    (dp->i_d.di_format != XFS_DINODE_FMT_BTREE) &&
>  	    !(args->op_flags & XFS_DA_OP_ADDNAME)) {
>  		xfs_attr_fork_remove(dp, args->trans);
> @@ -682,7 +686,7 @@ xfs_attr_shortform_remove(xfs_da_args_t *args)
>  		ASSERT(dp->i_d.di_forkoff);
>  		ASSERT(totsize > sizeof(xfs_attr_sf_hdr_t) ||
>  				(args->op_flags & XFS_DA_OP_ADDNAME) ||
> -				!(mp->m_flags & XFS_MOUNT_ATTR2) ||
> +				!xfs_has_attr2(mp) ||
>  				dp->i_d.di_format == XFS_DINODE_FMT_BTREE);
>  		xfs_trans_log_inode(args->trans, dp,
>  					XFS_ILOG_CORE | XFS_ILOG_ADATA);
> @@ -888,7 +892,7 @@ xfs_attr_shortform_allfit(
>  				+ name_loc->namelen
>  				+ be16_to_cpu(name_loc->valuelen);
>  	}
> -	if ((dp->i_mount->m_flags & XFS_MOUNT_ATTR2) &&
> +	if (xfs_has_attr2(mp) &&
>  	    (dp->i_d.di_format != XFS_DINODE_FMT_BTREE) &&
>  	    (bytes == sizeof(struct xfs_attr_sf_hdr)))
>  		return -1;
> @@ -1011,7 +1015,7 @@ xfs_attr3_leaf_to_shortform(
>  		goto out;
>  
>  	if (forkoff == -1) {
> -		ASSERT(dp->i_mount->m_flags & XFS_MOUNT_ATTR2);
> +		ASSERT(xfs_has_attr2(dp->i_mount));
>  		ASSERT(dp->i_d.di_format != XFS_DINODE_FMT_BTREE);
>  		xfs_attr_fork_remove(dp, args->trans);
>  		goto out;
> diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
> index 777630f3066a..459b08856f3f 100644
> --- a/fs/xfs/libxfs/xfs_bmap.c
> +++ b/fs/xfs/libxfs/xfs_bmap.c
> @@ -1079,7 +1079,7 @@ xfs_bmap_add_attrfork(
>  		ip->i_d.di_forkoff = xfs_attr_shortform_bytesfit(ip, size);
>  		if (!ip->i_d.di_forkoff)
>  			ip->i_d.di_forkoff = xfs_default_attroffset(ip) >> 3;
> -		else if (mp->m_flags & XFS_MOUNT_ATTR2)
> +		else if (!xfs_has_noattr2(mp))
>  			version = 2;
>  		break;
>  	default:
> @@ -3386,7 +3386,7 @@ xfs_bmap_btalloc(
>  
>  	/* stripe alignment for allocation is determined by mount parameters */
>  	stripe_align = 0;
> -	if (mp->m_swidth && (mp->m_flags & XFS_MOUNT_SWALLOC))
> +	if (mp->m_swidth && xfs_has_swalloc(mp))
>  		stripe_align = mp->m_swidth;
>  	else if (mp->m_dalign)
>  		stripe_align = mp->m_dalign;
> diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c
> index 8d23491badb7..ffb1caf4c34a 100644
> --- a/fs/xfs/libxfs/xfs_ialloc.c
> +++ b/fs/xfs/libxfs/xfs_ialloc.c
> @@ -723,7 +723,7 @@ xfs_ialloc_ag_alloc(
>  		 */
>  		isaligned = 0;
>  		if (args.mp->m_sinoalign) {
> -			ASSERT(!(args.mp->m_flags & XFS_MOUNT_NOALIGN));
> +			ASSERT(!xfs_has_noalign(args.mp));
>  			args.alignment = args.mp->m_dalign;
>  			isaligned = 1;
>  		} else
> @@ -1974,8 +1974,7 @@ xfs_difree_inobt(
>  	 * remove the chunk if the block size is large enough for multiple inode
>  	 * chunks (that might not be free).
>  	 */
> -	if (!(mp->m_flags & XFS_MOUNT_IKEEP) &&
> -	    rec.ir_free == XFS_INOBT_ALL_FREE &&
> +	if (!xfs_has_ikeep(mp) && rec.ir_free == XFS_INOBT_ALL_FREE &&
>  	    mp->m_sb.sb_inopblock <= XFS_INODES_PER_CHUNK) {
>  		xic->deleted = true;
>  		xic->first_ino = XFS_AGINO_TO_INO(mp, agno, rec.ir_startino);
> @@ -2112,9 +2111,8 @@ xfs_difree_finobt(
>  	 * enough for multiple chunks. Leave the finobt record to remain in sync
>  	 * with the inobt.
>  	 */
> -	if (rec.ir_free == XFS_INOBT_ALL_FREE &&
> -	    mp->m_sb.sb_inopblock <= XFS_INODES_PER_CHUNK &&
> -	    !(mp->m_flags & XFS_MOUNT_IKEEP)) {
> +	if (!xfs_has_ikeep(mp) && rec.ir_free == XFS_INOBT_ALL_FREE &&
> +	    mp->m_sb.sb_inopblock <= XFS_INODES_PER_CHUNK) {
>  		error = xfs_btree_delete(cur, &i);
>  		if (error)
>  			goto error;
> diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c
> index 6eb9f967d087..1d5389ad6502 100644
> --- a/fs/xfs/libxfs/xfs_inode_buf.c
> +++ b/fs/xfs/libxfs/xfs_inode_buf.c
> @@ -573,7 +573,7 @@ xfs_dinode_calc_crc(
>   * Read the disk inode attributes into the in-core inode structure.
>   *
>   * For version 5 superblocks, if we are initialising a new inode and we are not
> - * utilising the XFS_MOUNT_IKEEP inode cluster mode, we can simple build the new
> + * utilising the XFS_FEAT_IKEEP inode cluster mode, we can simple build the new
>   * inode core with a random generation number. If we are keeping inodes around,
>   * we need to read the inode cluster to get the existing generation number off
>   * disk. Further, if we are using version 4 superblocks (i.e. v1/v2 inode
> @@ -602,8 +602,7 @@ xfs_iread(
>  
>  	/* shortcut IO on inode allocation if possible */
>  	if ((iget_flags & XFS_IGET_CREATE) &&
> -	    xfs_has_crc(mp) &&
> -	    !(mp->m_flags & XFS_MOUNT_IKEEP)) {
> +	    xfs_has_crc(mp) && !xfs_has_ikeep(mp)) {
>  		/* initialise the on-disk inode core */
>  		memset(&ip->i_d, 0, sizeof(ip->i_d));
>  		VFS_I(ip)->i_generation = prandom_u32();
> diff --git a/fs/xfs/scrub/scrub.c b/fs/xfs/scrub/scrub.c
> index 4c486e89829d..a3698e9b084a 100644
> --- a/fs/xfs/scrub/scrub.c
> +++ b/fs/xfs/scrub/scrub.c
> @@ -495,7 +495,7 @@ xfs_scrub_metadata(
>  	if (XFS_FORCED_SHUTDOWN(mp))
>  		goto out;
>  	error = -ENOTRECOVERABLE;
> -	if (mp->m_flags & XFS_MOUNT_NORECOVERY)
> +	if (xfs_has_norecovery(mp))
>  		goto out;
>  
>  	error = xchk_validate_inputs(mp, sm);
> diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c
> index 2647e4ef8dc5..bd733b256fee 100644
> --- a/fs/xfs/xfs_bmap_util.c
> +++ b/fs/xfs/xfs_bmap_util.c
> @@ -1978,7 +1978,7 @@ xfs_swap_extents(
>  	 * If this is a synchronous mount, make sure that the
>  	 * transaction goes to disk before returning to the user.
>  	 */
> -	if (mp->m_flags & XFS_MOUNT_WSYNC)
> +	if (xfs_has_wsync(mp))
>  		xfs_trans_set_sync(tp);
>  
>  	error = xfs_trans_commit(tp);
> diff --git a/fs/xfs/xfs_export.c b/fs/xfs/xfs_export.c
> index f2284ceb129f..cc1f7d09102f 100644
> --- a/fs/xfs/xfs_export.c
> +++ b/fs/xfs/xfs_export.c
> @@ -66,7 +66,7 @@ xfs_fs_encode_fh(
>  	 * large enough filesystem may contain them, thus the slightly
>  	 * confusing looking conditional below.
>  	 */
> -	if (!(XFS_M(inode->i_sb)->m_flags & XFS_MOUNT_SMALL_INUMS) ||
> +	if (!xfs_has_small_inums(XFS_M(inode->i_sb)) ||
>  	    (XFS_M(inode->i_sb)->m_flags & XFS_MOUNT_32BITINODES))
>  		fileid_type |= XFS_FILEID_TYPE_64FLAG;
>  
> diff --git a/fs/xfs/xfs_filestream.h b/fs/xfs/xfs_filestream.h
> index 5cc7665e93c9..c8760fffdda7 100644
> --- a/fs/xfs/xfs_filestream.h
> +++ b/fs/xfs/xfs_filestream.h
> @@ -21,7 +21,7 @@ static inline int
>  xfs_inode_is_filestream(
>  	struct xfs_inode	*ip)
>  {
> -	return (ip->i_mount->m_flags & XFS_MOUNT_FILESTREAMS) ||
> +	return xfs_has_filestreams(ip->i_mount) ||
>  		(ip->i_d.di_flags & XFS_DIFLAG_FILESTREAM);
>  }
>  
> diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
> index d957a46dc1cb..0f67ca516c87 100644
> --- a/fs/xfs/xfs_inode.c
> +++ b/fs/xfs/xfs_inode.c
> @@ -1245,7 +1245,7 @@ xfs_create(
>  	 * create transaction goes to disk before returning to
>  	 * the user.
>  	 */
> -	if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC))
> +	if (xfs_has_wsync(mp) || xfs_has_dirsync(mp))
>  		xfs_trans_set_sync(tp);
>  
>  	/*
> @@ -1336,7 +1336,7 @@ xfs_create_tmpfile(
>  	if (error)
>  		goto out_trans_cancel;
>  
> -	if (mp->m_flags & XFS_MOUNT_WSYNC)
> +	if (xfs_has_wsync(mp))
>  		xfs_trans_set_sync(tp);
>  
>  	/*
> @@ -1463,7 +1463,7 @@ xfs_link(
>  	 * link transaction goes to disk before returning to
>  	 * the user.
>  	 */
> -	if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC))
> +	if (xfs_has_wsync(mp) || xfs_has_dirsync(mp))
>  		xfs_trans_set_sync(tp);
>  
>  	return xfs_trans_commit(tp);
> @@ -2627,7 +2627,7 @@ xfs_remove(
>  	 * remove transaction goes to disk before returning to
>  	 * the user.
>  	 */
> -	if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC))
> +	if (xfs_has_wsync(mp) || xfs_has_dirsync(mp))
>  		xfs_trans_set_sync(tp);
>  
>  	error = xfs_trans_commit(tp);
> @@ -2704,7 +2704,7 @@ xfs_finish_rename(
>  	 * If this is a synchronous mount, make sure that the rename transaction
>  	 * goes to disk before returning to the user.
>  	 */
> -	if (tp->t_mountp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC))
> +	if (xfs_has_wsync(tp->t_mountp) || xfs_has_dirsync(tp->t_mountp))
>  		xfs_trans_set_sync(tp);
>  
>  	return xfs_trans_commit(tp);
> diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
> index be2014520155..40bc71d49220 100644
> --- a/fs/xfs/xfs_inode.h
> +++ b/fs/xfs/xfs_inode.h
> @@ -394,8 +394,7 @@ enum layout_break_reason {
>   * new subdirectory gets S_ISGID bit from parent.
>   */
>  #define XFS_INHERIT_GID(pip)	\
> -	(((pip)->i_mount->m_flags & XFS_MOUNT_GRPID) || \
> -	 (VFS_I(pip)->i_mode & S_ISGID))
> +	(xfs_has_grpid((pip)->i_mount) || (VFS_I(pip)->i_mode & S_ISGID))
>  
>  int		xfs_release(struct xfs_inode *ip);
>  void		xfs_inactive(struct xfs_inode *ip);
> diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
> index 4f4c6cd81b54..350b9276e6fe 100644
> --- a/fs/xfs/xfs_ioctl.c
> +++ b/fs/xfs/xfs_ioctl.c
> @@ -1167,7 +1167,7 @@ xfs_ioctl_setattr_get_trans(
>  		goto out_cancel;
>  	}
>  
> -	if (mp->m_flags & XFS_MOUNT_WSYNC)
> +	if (xfs_has_wsync(mp))
>  		xfs_trans_set_sync(tp);
>  
>  	return tp;
> diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
> index 6320aca39f39..3c999ea64021 100644
> --- a/fs/xfs/xfs_iomap.c
> +++ b/fs/xfs/xfs_iomap.c
> @@ -79,7 +79,7 @@ xfs_eof_alignment(
>  		 * If mounted with the "-o swalloc" option the alignment is
>  		 * increased from the strip unit size to the stripe width.
>  		 */
> -		if (mp->m_swidth && (mp->m_flags & XFS_MOUNT_SWALLOC))
> +		if (mp->m_swidth && xfs_has_swalloc(mp))
>  			align = mp->m_swidth;
>  		else if (mp->m_dalign)
>  			align = mp->m_dalign;
> @@ -385,7 +385,7 @@ xfs_iomap_prealloc_size(
>  	if (offset + count <= XFS_ISIZE(ip))
>  		return 0;
>  
> -	if (!(mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) &&
> +	if (!xfs_has_iosize(mp) &&
>  	    (XFS_ISIZE(ip) < XFS_FSB_TO_B(mp, mp->m_writeio_blocks)))
>  		return 0;
>  
> @@ -393,7 +393,7 @@ xfs_iomap_prealloc_size(
>  	 * If an explicit allocsize is set, the file is small, or we
>  	 * are writing behind a hole, then use the minimum prealloc:
>  	 */
> -	if ((mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) ||
> +	if (xfs_has_iosize(mp) ||
>  	    XFS_ISIZE(ip) < XFS_FSB_TO_B(mp, mp->m_dalign) ||
>  	    !xfs_iext_peek_prev_extent(ifp, icur, &prev) ||
>  	    prev.br_startoff + prev.br_blockcount < offset_fsb)
> diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
> index 066a97d108f5..0241471916d9 100644
> --- a/fs/xfs/xfs_iops.c
> +++ b/fs/xfs/xfs_iops.c
> @@ -742,7 +742,7 @@ xfs_setattr_nonsize(
>  
>  	XFS_STATS_INC(mp, xs_ig_attrchg);
>  
> -	if (mp->m_flags & XFS_MOUNT_WSYNC)
> +	if (xfs_has_wsync(mp))
>  		xfs_trans_set_sync(tp);
>  	error = xfs_trans_commit(tp);
>  
> @@ -980,7 +980,7 @@ xfs_setattr_size(
>  
>  	XFS_STATS_INC(mp, xs_ig_attrchg);
>  
> -	if (mp->m_flags & XFS_MOUNT_WSYNC)
> +	if (xfs_has_wsync(mp))
>  		xfs_trans_set_sync(tp);
>  
>  	error = xfs_trans_commit(tp);
> @@ -1200,8 +1200,7 @@ xfs_inode_supports_dax(
>  		return false;
>  
>  	/* DAX mount option or DAX iflag must be set. */
> -	if (!(mp->m_flags & XFS_MOUNT_DAX) &&
> -	    !(ip->i_d.di_flags2 & XFS_DIFLAG2_DAX))
> +	if (!xfs_has_dax(mp) && !(ip->i_d.di_flags2 & XFS_DIFLAG2_DAX))
>  		return false;
>  
>  	/* Block size must match page size */
> diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
> index 7ad8c7bb1345..bcc068dee92a 100644
> --- a/fs/xfs/xfs_log.c
> +++ b/fs/xfs/xfs_log.c
> @@ -600,7 +600,7 @@ xfs_log_mount(
>  	int		error = 0;
>  	int		min_logfsbs;
>  
> -	if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) {
> +	if (!xfs_has_norecovery(mp)) {
>  		xfs_notice(mp, "Mounting V%d Filesystem",
>  			   XFS_SB_VERSION_NUM(&mp->m_sb));
>  	} else {
> @@ -685,8 +685,8 @@ xfs_log_mount(
>  	 * skip log recovery on a norecovery mount.  pretend it all
>  	 * just worked.
>  	 */
> -	if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) {
> -		int	readonly = (mp->m_flags & XFS_MOUNT_RDONLY);
> +	if (!xfs_has_norecovery(mp)) {
> +		bool	readonly = (mp->m_flags & XFS_MOUNT_RDONLY);
>  
>  		if (readonly)
>  			mp->m_flags &= ~XFS_MOUNT_RDONLY;
> @@ -746,8 +746,8 @@ xfs_log_mount_finish(
>  	bool	readonly = (mp->m_flags & XFS_MOUNT_RDONLY);
>  	bool	recovered = mp->m_log->l_flags & XLOG_RECOVERY_NEEDED;
>  
> -	if (mp->m_flags & XFS_MOUNT_NORECOVERY) {
> -		ASSERT(mp->m_flags & XFS_MOUNT_RDONLY);
> +	if (xfs_has_norecovery(mp)) {
> +		ASSERT(readonly);
>  		return 0;
>  	} else if (readonly) {
>  		/* Allow unlinked processing to proceed */
> @@ -930,7 +930,7 @@ xfs_log_unmount_write(xfs_mount_t *mp)
>  	 * Don't write out unmount record on norecovery mounts or ro devices.
>  	 * Or, if we are doing a forced umount (typically because of IO errors).
>  	 */
> -	if (mp->m_flags & XFS_MOUNT_NORECOVERY ||
> +	if (xfs_has_norecovery(mp) ||
>  	    xfs_readonly_buftarg(log->l_mp->m_logdev_targp)) {
>  		ASSERT(mp->m_flags & XFS_MOUNT_RDONLY);
>  		return 0;
> @@ -4079,7 +4079,7 @@ xfs_log_check_lsn(
>  	 * resets the in-core LSN. We can't validate in this mode, but
>  	 * modifications are not allowed anyways so just return true.
>  	 */
> -	if (mp->m_flags & XFS_MOUNT_NORECOVERY)
> +	if (xfs_has_norecovery(mp))
>  		return true;
>  
>  	/*
> diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c
> index d3884e08b43c..c4f71e600f00 100644
> --- a/fs/xfs/xfs_log_cil.c
> +++ b/fs/xfs/xfs_log_cil.c
> @@ -538,7 +538,7 @@ xlog_discard_busy_extents(
>  	struct blk_plug		plug;
>  	int			error = 0;
>  
> -	ASSERT(mp->m_flags & XFS_MOUNT_DISCARD);
> +	ASSERT(xfs_has_discard(mp));
>  
>  	blk_start_plug(&plug);
>  	list_for_each_entry(busyp, list, list) {
> @@ -587,7 +587,7 @@ xlog_cil_committed(
>  
>  	xfs_extent_busy_sort(&ctx->busy_extents);
>  	xfs_extent_busy_clear(mp, &ctx->busy_extents,
> -			     (mp->m_flags & XFS_MOUNT_DISCARD) && !abort);
> +			      xfs_has_discard(mp) && !abort);
>  
>  	/*
>  	 * If we are aborting the commit, wake up anyone waiting on the
> diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
> index 212ae2695b88..624387661cbc 100644
> --- a/fs/xfs/xfs_mount.c
> +++ b/fs/xfs/xfs_mount.c
> @@ -64,7 +64,7 @@ xfs_uuid_mount(
>  	/* Publish UUID in struct super_block */
>  	uuid_copy(&mp->m_super->s_uuid, uuid);
>  
> -	if (mp->m_flags & XFS_MOUNT_NOUUID)
> +	if (xfs_has_nouuid(mp))
>  		return 0;
>  
>  	if (uuid_is_null(uuid)) {
> @@ -106,7 +106,7 @@ xfs_uuid_unmount(
>  	uuid_t			*uuid = &mp->m_sb.sb_uuid;
>  	int			i;
>  
> -	if (mp->m_flags & XFS_MOUNT_NOUUID)
> +	if (xfs_has_nouuid(mp))
>  		return;
>  
>  	mutex_lock(&xfs_uuid_table_mutex);
> @@ -414,8 +414,7 @@ xfs_update_alignment(xfs_mount_t *mp)
>  	"cannot change alignment: superblock does not support data alignment");
>  			return -EINVAL;
>  		}
> -	} else if ((mp->m_flags & XFS_MOUNT_NOALIGN) != XFS_MOUNT_NOALIGN &&
> -		    xfs_has_dalign(mp)) {
> +	} else if (xfs_has_dalign(mp) && !xfs_has_noalign(mp)) {
>  			mp->m_dalign = sbp->sb_unit;
>  			mp->m_swidth = sbp->sb_width;
>  	}
> @@ -454,22 +453,21 @@ xfs_set_maxicount(xfs_mount_t *mp)
>   * is being used for NFS service (wsync mount option).
>   */
>  STATIC void
> -xfs_set_rw_sizes(xfs_mount_t *mp)
> +xfs_set_rw_sizes(
> +	struct xfs_mount *mp)
>  {
> -	xfs_sb_t	*sbp = &(mp->m_sb);
> +	struct xfs_sb	*sbp = &mp->m_sb;
>  	int		readio_log, writeio_log;
>  
> -	if (!(mp->m_flags & XFS_MOUNT_DFLT_IOSIZE)) {
> -		if (mp->m_flags & XFS_MOUNT_WSYNC) {
> -			readio_log = XFS_WSYNC_READIO_LOG;
> -			writeio_log = XFS_WSYNC_WRITEIO_LOG;
> -		} else {
> -			readio_log = XFS_READIO_LOG_LARGE;
> -			writeio_log = XFS_WRITEIO_LOG_LARGE;
> -		}
> -	} else {
> +	if (xfs_has_iosize(mp)) {
>  		readio_log = mp->m_readio_log;
>  		writeio_log = mp->m_writeio_log;
> +	} else if (xfs_has_wsync(mp)) {
> +		readio_log = XFS_WSYNC_READIO_LOG;
> +		writeio_log = XFS_WSYNC_WRITEIO_LOG;
> +	} else {
> +		readio_log = XFS_READIO_LOG_LARGE;
> +		writeio_log = XFS_WRITEIO_LOG_LARGE;
>  	}
>  
>  	if (sbp->sb_blocklog > readio_log) {
> @@ -704,18 +702,9 @@ xfs_mountfs(
>  		xfs_warn(mp, "correcting sb_features alignment problem");
>  		sbp->sb_features2 |= sbp->sb_bad_features2;
>  		mp->m_update_sb = true;
> -
> -		/*
> -		 * Re-check for ATTR2 in case it was found in bad_features2
> -		 * slot.
> -		 */
> -		if (xfs_has_attr2(mp) &&
> -		   !(mp->m_flags & XFS_MOUNT_NOATTR2))
> -			mp->m_flags |= XFS_MOUNT_ATTR2;
>  	}
>  
> -	if (xfs_has_attr2(mp) &&
> -	   (mp->m_flags & XFS_MOUNT_NOATTR2)) {
> +	if (xfs_has_attr2(mp) && xfs_has_noattr2(mp)) {
>  		xfs_feat_remove_attr2(mp);
>  		mp->m_update_sb = true;
>  
> @@ -988,10 +977,8 @@ xfs_mountfs(
>  	 * We use the same quiesce mechanism as the rw->ro remount, as they are
>  	 * semantically identical operations.
>  	 */
> -	if ((mp->m_flags & (XFS_MOUNT_RDONLY|XFS_MOUNT_NORECOVERY)) ==
> -							XFS_MOUNT_RDONLY) {
> +	if ((mp->m_flags & XFS_MOUNT_RDONLY) && !xfs_has_norecovery(mp))
>  		xfs_quiesce_attr(mp);
> -	}
>  
>  	/*
>  	 * Complete the quota initialisation, post-log-replay component.
> diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
> index 74a128fe316b..fee11d015b5a 100644
> --- a/fs/xfs/xfs_mount.h
> +++ b/fs/xfs/xfs_mount.h
> @@ -228,17 +228,19 @@ typedef struct xfs_mount {
>  #define XFS_FEAT_WSYNC		(1ULL << 22)	/* synchronous metadata ops */
>  #define XFS_FEAT_DIRSYNC	(1ULL << 23)	/* synchronous directory ops */
>  #define XFS_FEAT_DISCARD	(1ULL << 24)	/* discard unused blocks */
> -#define XFS_FEAT_GRPID		(1ULL << 25)	/* group-ID assigned from directory */
> +#define XFS_FEAT_GRPID		(1ULL << 25)	/* GID assigned from directory */
>  #define XFS_FEAT_SMALL_INUMS	(1ULL << 26)	/* user wants 32bit inodes */
>  #define XFS_FEAT_IKEEP		(1ULL << 27)	/* keep empty inode clusters*/
>  #define XFS_FEAT_SWALLOC	(1ULL << 28)	/* stripe width allocation */
> -#define XFS_FEAT_FILESTREAMS	(1ULL << 29)	/* enable the filestreams
> -						   allocator */
> +#define XFS_FEAT_FILESTREAMS	(1ULL << 29)	/* use filestreams allocator */
>  #define XFS_FEAT_DAX		(1ULL << 30)	/* TEST ONLY! */
> -#define XFS_FEAT_COMPAT_IOSIZE	(1ULL << 31)	/* don't report large preferred
> +#define XFS_FEAT_IOSIZE		(1ULL << 31)	/* user specified iosize */
> +#define XFS_FEAT_COMPAT_IOSIZE	(1ULL << 32)	/* don't report large preferred
>  						 * I/O size in stat() */
> -#define XFS_FEAT_NORECOVERY	(1ULL << 32)	/* no recovery - dirty fs */
> -#define XFS_FEAT_NOUUID		(1ULL << 33)	/* ignore uuid during mount */
> +#define XFS_FEAT_NORECOVERY	(1ULL << 33)	/* no recovery - dirty fs */
> +#define XFS_FEAT_NOUUID		(1ULL << 34)	/* ignore uuid during mount */
> +#define XFS_FEAT_NOATTR2	(1ULL << 35)	/* disable attr2 completely */
> +#define XFS_FEAT_NOALIGN	(1ULL << 36)	/* ignore alignment */
>  
>  #define __XFS_HAS_FEAT(name, NAME) \
>  static inline bool xfs_has_ ## name (struct xfs_mount *mp) \
> @@ -306,44 +308,24 @@ __XFS_HAS_FEAT(ikeep, IKEEP)
>  __XFS_HAS_FEAT(swalloc, SWALLOC)
>  __XFS_HAS_FEAT(filestreams, FILESTREAMS)
>  __XFS_HAS_FEAT(dax, DAX)
> +__XFS_HAS_FEAT(iosize, IOSIZE)
>  __XFS_HAS_FEAT(compat_iosize, COMPAT_IOSIZE)
>  __XFS_HAS_FEAT(norecovery, NORECOVERY)
>  __XFS_HAS_FEAT(nouuid, NOUUID)
> +__XFS_HAS_FEAT(noattr2, NOATTR2)
> +__XFS_HAS_FEAT(noalign, NOALIGN)
>  
>  /*
>   * Flags for m_flags.
>   */
> -#define XFS_MOUNT_WSYNC		(1ULL << 0)	/* for nfs - all metadata ops
> -						   must be synchronous except
> -						   for space allocations */
>  #define XFS_MOUNT_UNMOUNTING	(1ULL << 1)	/* filesystem is unmounting */
>  #define XFS_MOUNT_BAD_SUMMARY	(1ULL << 2)	/* summary counters are bad */
>  #define XFS_MOUNT_WAS_CLEAN	(1ULL << 3)
>  #define XFS_MOUNT_FS_SHUTDOWN	(1ULL << 4)	/* atomic stop of all filesystem
>  						   operations, typically for
>  						   disk errors in metadata */
> -#define XFS_MOUNT_DISCARD	(1ULL << 5)	/* discard unused blocks */
> -#define XFS_MOUNT_NOALIGN	(1ULL << 7)	/* turn off stripe alignment
> -						   allocations */
> -#define XFS_MOUNT_ATTR2		(1ULL << 8)	/* allow use of attr2 format */
> -#define XFS_MOUNT_GRPID		(1ULL << 9)	/* group-ID assigned from directory */
> -#define XFS_MOUNT_NORECOVERY	(1ULL << 10)	/* no recovery - dirty fs */
> -#define XFS_MOUNT_DFLT_IOSIZE	(1ULL << 12)	/* set default i/o size */
> -#define XFS_MOUNT_SMALL_INUMS	(1ULL << 14)	/* user wants 32bit inodes */
>  #define XFS_MOUNT_32BITINODES	(1ULL << 15)	/* inode32 allocator active */
> -#define XFS_MOUNT_NOUUID	(1ULL << 16)	/* ignore uuid during mount */
> -#define XFS_MOUNT_IKEEP		(1ULL << 18)	/* keep empty inode clusters*/
> -#define XFS_MOUNT_SWALLOC	(1ULL << 19)	/* turn on stripe width
> -						 * allocation */
>  #define XFS_MOUNT_RDONLY	(1ULL << 20)	/* read-only fs */
> -#define XFS_MOUNT_DIRSYNC	(1ULL << 21)	/* synchronous directory ops */
> -#define XFS_MOUNT_COMPAT_IOSIZE	(1ULL << 22)	/* don't report large preferred
> -						 * I/O size in stat() */
> -#define XFS_MOUNT_FILESTREAMS	(1ULL << 24)	/* enable the filestreams
> -						   allocator */
> -#define XFS_MOUNT_NOATTR2	(1ULL << 25)	/* disable use of attr2 format */
> -
> -#define XFS_MOUNT_DAX		(1ULL << 62)	/* TEST ONLY! */
>  
>  
>  /*
> @@ -381,13 +363,13 @@ __XFS_HAS_FEAT(nouuid, NOUUID)
>  static inline unsigned long
>  xfs_preferred_iosize(xfs_mount_t *mp)
>  {
> -	if (mp->m_flags & XFS_MOUNT_COMPAT_IOSIZE)
> +	if (xfs_has_compat_iosize(mp))
>  		return PAGE_SIZE;
> -	return (mp->m_swidth ?
> -		(mp->m_swidth << mp->m_sb.sb_blocklog) :
> -		((mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) ?
> -			(1 << (int)max(mp->m_readio_log, mp->m_writeio_log)) :
> -			PAGE_SIZE));
> +	if (mp->m_swidth)
> +		return mp->m_swidth << mp->m_sb.sb_blocklog;
> +	if (xfs_has_iosize(mp))
> +		return 1 << (int)max(mp->m_readio_log, mp->m_writeio_log);
> +	return PAGE_SIZE;
>  }
>  
>  #define XFS_LAST_UNMOUNT_WAS_CLEAN(mp)	\
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index cf76884c2a95..d3dff878be99 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
> @@ -193,15 +193,15 @@ xfs_parseargs(
>  	if (sb_rdonly(sb))
>  		mp->m_flags |= XFS_MOUNT_RDONLY;
>  	if (sb->s_flags & SB_DIRSYNC)
> -		mp->m_flags |= XFS_MOUNT_DIRSYNC;
> +		mp->m_features |= XFS_FEAT_DIRSYNC;
>  	if (sb->s_flags & SB_SYNCHRONOUS)
> -		mp->m_flags |= XFS_MOUNT_WSYNC;
> +		mp->m_features |= XFS_FEAT_WSYNC;
>  
>  	/*
>  	 * Set some default flags that could be cleared by the mount option
>  	 * parsing.
>  	 */
> -	mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
> +	mp->m_features |= XFS_FEAT_COMPAT_IOSIZE;
>  
>  	/*
>  	 * These can be overridden by the mount option parsing.
> @@ -251,23 +251,23 @@ xfs_parseargs(
>  			break;
>  		case Opt_grpid:
>  		case Opt_bsdgroups:
> -			mp->m_flags |= XFS_MOUNT_GRPID;
> +			mp->m_features |= XFS_FEAT_GRPID;
>  			break;
>  		case Opt_nogrpid:
>  		case Opt_sysvgroups:
> -			mp->m_flags &= ~XFS_MOUNT_GRPID;
> +			mp->m_features &= ~XFS_FEAT_GRPID;
>  			break;
>  		case Opt_wsync:
> -			mp->m_flags |= XFS_MOUNT_WSYNC;
> +			mp->m_features |= XFS_FEAT_WSYNC;
>  			break;
>  		case Opt_norecovery:
> -			mp->m_flags |= XFS_MOUNT_NORECOVERY;
> +			mp->m_features |= XFS_FEAT_NORECOVERY;
>  			break;
>  		case Opt_noalign:
> -			mp->m_flags |= XFS_MOUNT_NOALIGN;
> +			mp->m_features |= XFS_FEAT_NOALIGN;
>  			break;
>  		case Opt_swalloc:
> -			mp->m_flags |= XFS_MOUNT_SWALLOC;
> +			mp->m_features |= XFS_FEAT_SWALLOC;
>  			break;
>  		case Opt_sunit:
>  			if (match_int(args, &dsunit))
> @@ -278,35 +278,34 @@ xfs_parseargs(
>  				return -EINVAL;
>  			break;
>  		case Opt_inode32:
> -			mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
> +			mp->m_features |= XFS_FEAT_SMALL_INUMS;
>  			break;
>  		case Opt_inode64:
> -			mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS;
> +			mp->m_features &= ~XFS_FEAT_SMALL_INUMS;
>  			break;
>  		case Opt_nouuid:
> -			mp->m_flags |= XFS_MOUNT_NOUUID;
> +			mp->m_features |= XFS_FEAT_NOUUID;
>  			break;
>  		case Opt_ikeep:
> -			mp->m_flags |= XFS_MOUNT_IKEEP;
> +			mp->m_features |= XFS_FEAT_IKEEP;
>  			break;
>  		case Opt_noikeep:
> -			mp->m_flags &= ~XFS_MOUNT_IKEEP;
> +			mp->m_features &= ~XFS_FEAT_IKEEP;
>  			break;
>  		case Opt_largeio:
> -			mp->m_flags &= ~XFS_MOUNT_COMPAT_IOSIZE;
> +			mp->m_features &= ~XFS_FEAT_COMPAT_IOSIZE;
>  			break;
>  		case Opt_nolargeio:
> -			mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
> +			mp->m_features |= XFS_FEAT_COMPAT_IOSIZE;
>  			break;
>  		case Opt_attr2:
> -			mp->m_flags |= XFS_MOUNT_ATTR2;
> +			mp->m_features |= XFS_FEAT_ATTR2;
>  			break;
>  		case Opt_noattr2:
> -			mp->m_flags &= ~XFS_MOUNT_ATTR2;
> -			mp->m_flags |= XFS_MOUNT_NOATTR2;
> +			mp->m_features |= XFS_FEAT_NOATTR2;
>  			break;
>  		case Opt_filestreams:
> -			mp->m_flags |= XFS_MOUNT_FILESTREAMS;
> +			mp->m_features |= XFS_FEAT_FILESTREAMS;
>  			break;
>  		case Opt_noquota:
>  			mp->m_qflags &= ~XFS_ALL_QUOTA_ACCT;
> @@ -343,14 +342,14 @@ xfs_parseargs(
>  			mp->m_qflags &= ~XFS_GQUOTA_ENFD;
>  			break;
>  		case Opt_discard:
> -			mp->m_flags |= XFS_MOUNT_DISCARD;
> +			mp->m_features |= XFS_FEAT_DISCARD;
>  			break;
>  		case Opt_nodiscard:
> -			mp->m_flags &= ~XFS_MOUNT_DISCARD;
> +			mp->m_features &= ~XFS_FEAT_DISCARD;
>  			break;
>  #ifdef CONFIG_FS_DAX
>  		case Opt_dax:
> -			mp->m_flags |= XFS_MOUNT_DAX;
> +			mp->m_features |= XFS_FEAT_DAX;
>  			break;
>  #endif
>  		default:
> @@ -362,13 +361,12 @@ xfs_parseargs(
>  	/*
>  	 * no recovery flag requires a read-only mount
>  	 */
> -	if ((mp->m_flags & XFS_MOUNT_NORECOVERY) &&
> -	    !(mp->m_flags & XFS_MOUNT_RDONLY)) {
> +	if (xfs_has_norecovery(mp) && !(mp->m_flags & XFS_MOUNT_RDONLY)) {
>  		xfs_warn(mp, "no-recovery mounts must be read-only.");
>  		return -EINVAL;
>  	}
>  
> -	if ((mp->m_flags & XFS_MOUNT_NOALIGN) && (dsunit || dswidth)) {
> +	if (xfs_has_noalign(mp) && (dsunit || dswidth)) {
>  		xfs_warn(mp,
>  	"sunit and swidth options incompatible with the noalign option");
>  		return -EINVAL;
> @@ -394,7 +392,7 @@ xfs_parseargs(
>  	}
>  
>  done:
> -	if (dsunit && !(mp->m_flags & XFS_MOUNT_NOALIGN)) {
> +	if (dsunit && !xfs_has_noalign(mp)) {
>  		/*
>  		 * At this point the superblock has not been read
>  		 * in, therefore we do not know the block size.
> @@ -433,7 +431,7 @@ xfs_parseargs(
>  			return -EINVAL;
>  		}
>  
> -		mp->m_flags |= XFS_MOUNT_DFLT_IOSIZE;
> +		mp->m_features |= XFS_FEAT_IOSIZE;
>  		mp->m_readio_log = iosizelog;
>  		mp->m_writeio_log = iosizelog;
>  	}
> @@ -453,38 +451,38 @@ xfs_showargs(
>  {
>  	static struct proc_xfs_info xfs_info_set[] = {
>  		/* the few simple ones we can get from the mount struct */
> -		{ XFS_MOUNT_IKEEP,		",ikeep" },
> -		{ XFS_MOUNT_WSYNC,		",wsync" },
> -		{ XFS_MOUNT_NOALIGN,		",noalign" },
> -		{ XFS_MOUNT_SWALLOC,		",swalloc" },
> -		{ XFS_MOUNT_NOUUID,		",nouuid" },
> -		{ XFS_MOUNT_NORECOVERY,		",norecovery" },
> -		{ XFS_MOUNT_ATTR2,		",attr2" },
> -		{ XFS_MOUNT_FILESTREAMS,	",filestreams" },
> -		{ XFS_MOUNT_GRPID,		",grpid" },
> -		{ XFS_MOUNT_DISCARD,		",discard" },
> -		{ XFS_MOUNT_SMALL_INUMS,	",inode32" },
> -		{ XFS_MOUNT_DAX,		",dax" },
> +		{ XFS_FEAT_IKEEP,	",ikeep" },
> +		{ XFS_FEAT_WSYNC,	",wsync" },
> +		{ XFS_FEAT_NOALIGN,	",noalign" },
> +		{ XFS_FEAT_SWALLOC,	",swalloc" },
> +		{ XFS_FEAT_NOUUID,	",nouuid" },
> +		{ XFS_FEAT_NORECOVERY,	",norecovery" },
> +		{ XFS_FEAT_ATTR2,	",attr2" },
> +		{ XFS_FEAT_FILESTREAMS,	",filestreams" },
> +		{ XFS_FEAT_GRPID,	",grpid" },
> +		{ XFS_FEAT_DISCARD,	",discard" },
> +		{ XFS_FEAT_SMALL_INUMS,	",inode32" },
> +		{ XFS_FEAT_DAX,		",dax" },
>  		{ 0, NULL }
>  	};
>  	static struct proc_xfs_info xfs_info_unset[] = {
>  		/* the few simple ones we can get from the mount struct */
> -		{ XFS_MOUNT_COMPAT_IOSIZE,	",largeio" },
> -		{ XFS_MOUNT_SMALL_INUMS,	",inode64" },
> +		{ XFS_FEAT_COMPAT_IOSIZE, ",largeio" },
> +		{ XFS_FEAT_SMALL_INUMS,	",inode64" },
>  		{ 0, NULL }
>  	};
>  	struct proc_xfs_info	*xfs_infop;
>  
>  	for (xfs_infop = xfs_info_set; xfs_infop->flag; xfs_infop++) {
> -		if (mp->m_flags & xfs_infop->flag)
> +		if (mp->m_features & xfs_infop->flag)
>  			seq_puts(m, xfs_infop->str);
>  	}
>  	for (xfs_infop = xfs_info_unset; xfs_infop->flag; xfs_infop++) {
> -		if (!(mp->m_flags & xfs_infop->flag))
> +		if (!(mp->m_features & xfs_infop->flag))
>  			seq_puts(m, xfs_infop->str);
>  	}
>  
> -	if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE)
> +	if (xfs_has_iosize(mp))
>  		seq_printf(m, ",allocsize=%dk",
>  				(int)(1 << mp->m_writeio_log) >> 10);
>  
> @@ -565,10 +563,10 @@ xfs_max_file_offset(
>  /*
>   * Set parameters for inode allocation heuristics, taking into account
>   * filesystem size and inode32/inode64 mount options; i.e. specifically
> - * whether or not XFS_MOUNT_SMALL_INUMS is set.
> + * whether or not XFS_FEAT_SMALL_INUMS is set.
>   *
>   * Inode allocation patterns are altered only if inode32 is requested
> - * (XFS_MOUNT_SMALL_INUMS), and the filesystem is sufficiently large.
> + * (XFS_FEAT_SMALL_INUMS), and the filesystem is sufficiently large.
>   * If altered, XFS_MOUNT_32BITINODES is set as well.
>   *
>   * An agcount independent of that in the mount structure is provided
> @@ -614,7 +612,7 @@ xfs_set_inode_alloc(
>  	 * sufficiently large, set XFS_MOUNT_32BITINODES if we must alter
>  	 * the allocator to accommodate the request.
>  	 */
> -	if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) && ino > XFS_MAXINUMBER_32)
> +	if (xfs_has_small_inums(mp) && ino > XFS_MAXINUMBER_32)
>  		mp->m_flags |= XFS_MOUNT_32BITINODES;
>  	else
>  		mp->m_flags &= ~XFS_MOUNT_32BITINODES;
> @@ -1261,11 +1259,11 @@ xfs_fs_remount(
>  		token = match_token(p, tokens, args);
>  		switch (token) {
>  		case Opt_inode64:
> -			mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS;
> +			mp->m_features &= ~XFS_FEAT_SMALL_INUMS;
>  			mp->m_maxagi = xfs_set_inode_alloc(mp, sbp->sb_agcount);
>  			break;
>  		case Opt_inode32:
> -			mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
> +			mp->m_features |= XFS_FEAT_SMALL_INUMS;
>  			mp->m_maxagi = xfs_set_inode_alloc(mp, sbp->sb_agcount);
>  			break;
>  		default:
> @@ -1297,7 +1295,7 @@ xfs_fs_remount(
>  
>  	/* ro -> rw */
>  	if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(*flags & SB_RDONLY)) {
> -		if (mp->m_flags & XFS_MOUNT_NORECOVERY) {
> +		if (xfs_has_norecovery(mp)) {
>  			xfs_warn(mp,
>  		"ro->rw transition prohibited on norecovery mount");
>  			return -EINVAL;
> @@ -1460,21 +1458,12 @@ xfs_finish_flags(
>  	/*
>  	 * V5 filesystems always use attr2 format for attributes.
>  	 */
> -	if (xfs_has_crc(mp) &&
> -	    (mp->m_flags & XFS_MOUNT_NOATTR2)) {
> +	if (xfs_has_crc(mp) && xfs_has_noattr2(mp)) {
>  		xfs_warn(mp, "Cannot mount a V5 filesystem as noattr2. "
>  			     "attr2 is always enabled for V5 filesystems.");
>  		return -EINVAL;
>  	}
>  
> -	/*
> -	 * mkfs'ed attr2 will turn on attr2 mount unless explicitly
> -	 * told by noattr2 to turn it off
> -	 */
> -	if (xfs_has_attr2(mp) &&
> -	    !(mp->m_flags & XFS_MOUNT_NOATTR2))
> -		mp->m_flags |= XFS_MOUNT_ATTR2;
> -
>  	/*
>  	 * prohibit r/w mounts of read-only filesystems
>  	 */
> @@ -1662,7 +1651,7 @@ xfs_fs_fill_super(
>  	if (XFS_SB_VERSION_NUM(&mp->m_sb) == XFS_SB_VERSION_5)
>  		sb->s_flags |= SB_I_VERSION;
>  
> -	if (mp->m_flags & XFS_MOUNT_DAX) {
> +	if (xfs_has_dax(mp)) {
>  		bool rtdev_is_dax = false, datadev_is_dax;
>  
>  		xfs_warn(mp,
> @@ -1676,7 +1665,7 @@ xfs_fs_fill_super(
>  		if (!rtdev_is_dax && !datadev_is_dax) {
>  			xfs_alert(mp,
>  			"DAX unsupported by block device. Turning off DAX.");
> -			mp->m_flags &= ~XFS_MOUNT_DAX;
> +			mp->m_features &= ~XFS_FEAT_DAX;
>  		}
>  		if (xfs_has_reflink(mp)) {
>  			xfs_alert(mp,
> @@ -1686,13 +1675,13 @@ xfs_fs_fill_super(
>  		}
>  	}
>  
> -	if (mp->m_flags & XFS_MOUNT_DISCARD) {
> +	if (xfs_has_discard(mp)) {
>  		struct request_queue *q = bdev_get_queue(sb->s_bdev);
>  
>  		if (!blk_queue_discard(q)) {
>  			xfs_warn(mp, "mounting with \"discard\" option, but "
>  					"the device does not support discard");
> -			mp->m_flags &= ~XFS_MOUNT_DISCARD;
> +			mp->m_features &= ~XFS_FEAT_DISCARD;
>  		}
>  	}
>  
> diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c
> index 647a9aa98646..675481028292 100644
> --- a/fs/xfs/xfs_symlink.c
> +++ b/fs/xfs/xfs_symlink.c
> @@ -339,9 +339,8 @@ xfs_symlink(
>  	 * symlink transaction goes to disk before returning to
>  	 * the user.
>  	 */
> -	if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) {
> +	if (xfs_has_wsync(mp) || xfs_has_dirsync(mp))
>  		xfs_trans_set_sync(tp);
> -	}
>  
>  	error = xfs_trans_commit(tp);
>  	if (error)
> -- 
> 2.17.0
> 

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

* Re: [PATCH 05/10] xfs: convert remaining mount flags to state flags
  2018-08-20  4:48 ` [PATCH 05/10] xfs: convert remaining mount flags to state flags Dave Chinner
@ 2018-08-21 13:23   ` Brian Foster
  0 siblings, 0 replies; 27+ messages in thread
From: Brian Foster @ 2018-08-21 13:23 UTC (permalink / raw)
  To: Dave Chinner; +Cc: linux-xfs

On Mon, Aug 20, 2018 at 02:48:46PM +1000, Dave Chinner wrote:
> From: Dave Chinner <dchinner@redhat.com>
> 
> The remaining mount flags kept in m_flags are actually runtime state
> flags. These change dynamically, so they really should be updated
> atomically so we don't potentially lose an update dur to racing

s/dur/due/

> modifications.
> 
> Rename m_flags to m_state, and convert it to use atomic bitops to
> set and clear the flags. This also adds a couple of simple wrappers
> for common state checks - read only and shutdown.
> 
> Signed-off-by: Dave Chinner <dchinner@redhat.com>
> ---
>  fs/xfs/libxfs/xfs_alloc.c |  2 +-
>  fs/xfs/libxfs/xfs_sb.c    |  4 ++--
>  fs/xfs/scrub/scrub.c      |  2 +-
>  fs/xfs/xfs_buf_item.c     |  2 +-
>  fs/xfs/xfs_export.c       |  5 +++--
>  fs/xfs/xfs_filestream.c   |  2 +-
>  fs/xfs/xfs_fsops.c        |  2 +-
>  fs/xfs/xfs_inode.c        |  4 ++--
>  fs/xfs/xfs_ioctl.c        |  6 +++---
>  fs/xfs/xfs_iops.c         |  2 +-
>  fs/xfs/xfs_log.c          | 39 ++++++++++++++++++++++-----------------
>  fs/xfs/xfs_log_recover.c  |  2 +-
>  fs/xfs/xfs_mount.c        | 25 +++++++++++--------------
>  fs/xfs/xfs_mount.h        | 36 +++++++++++++++++++++++-------------
>  fs/xfs/xfs_super.c        | 28 +++++++++++++---------------
>  15 files changed, 86 insertions(+), 75 deletions(-)
> 
...
> diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c
> index 5dcb9005173c..ee4d483e1209 100644
> --- a/fs/xfs/libxfs/xfs_sb.c
> +++ b/fs/xfs/libxfs/xfs_sb.c
> @@ -183,7 +183,7 @@ xfs_validate_sb_read(
>  "Superblock has unknown read-only compatible features (0x%x) enabled.",
>  			(sbp->sb_features_ro_compat &
>  					XFS_SB_FEAT_RO_COMPAT_UNKNOWN));
> -		if (!(mp->m_flags & XFS_MOUNT_RDONLY)) {
> +		if (!test_bit(XFS_STATE_RDONLY, &mp->m_state)) {

!xfs_is_readonly() ?

>  			xfs_warn(mp,
>  "Attempted to mount read-only compatible filesystem read-write.");
>  			xfs_warn(mp,
> @@ -981,7 +981,7 @@ xfs_initialize_perag_data(
>  
>  	xfs_reinit_percpu_counters(mp);
>  out:
> -	mp->m_flags &= ~XFS_MOUNT_BAD_SUMMARY;
> +	clear_bit(XFS_STATE_BAD_SUMMARY, &mp->m_state);
>  	return error;
>  }
>  
...
> diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
> index fee11d015b5a..03f4681c1ba6 100644
> --- a/fs/xfs/xfs_mount.h
> +++ b/fs/xfs/xfs_mount.h
...
> @@ -316,17 +316,28 @@ __XFS_HAS_FEAT(noattr2, NOATTR2)
>  __XFS_HAS_FEAT(noalign, NOALIGN)
>  
>  /*
> - * Flags for m_flags.
> + * Mount state flags
> + *
> + * Use these with atomic bit ops only!
>   */
> -#define XFS_MOUNT_UNMOUNTING	(1ULL << 1)	/* filesystem is unmounting */
> -#define XFS_MOUNT_BAD_SUMMARY	(1ULL << 2)	/* summary counters are bad */
> -#define XFS_MOUNT_WAS_CLEAN	(1ULL << 3)
> -#define XFS_MOUNT_FS_SHUTDOWN	(1ULL << 4)	/* atomic stop of all filesystem
> -						   operations, typically for
> -						   disk errors in metadata */
> -#define XFS_MOUNT_32BITINODES	(1ULL << 15)	/* inode32 allocator active */
> -#define XFS_MOUNT_RDONLY	(1ULL << 20)	/* read-only fs */
> +#define XFS_STATE_UNMOUNTING	0	/* filesystem is unmounting */
> +#define XFS_STATE_BAD_SUMMARY	1	/* summary counters are bad */
> +#define XFS_STATE_WAS_CLEAN	2	/* mount was clean */
> +#define XFS_STATE_SHUTDOWN	3	/* atomic stop of all filesystem
> +					   operations, typically for
> +					   disk errors in metadata */
> +#define XFS_STATE_32BITINODES	4	/* inode32 allocator active */
> +#define XFS_STATE_RDONLY	5	/* read-only fs */
> +
> +static inline bool xfs_is_readonly(struct xfs_mount *mp)
> +{
> +	return test_bit(XFS_STATE_RDONLY, &mp->m_state);
> +}
>  
> +static inline bool xfs_is_shut_down(struct xfs_mount *mp)
> +{
> +	return test_bit(XFS_STATE_SHUTDOWN, &mp->m_state);
> +}

This is unused, so what is the purpose of this in relation to
XFS_FORCED_SHUTDOWN(), which this duplicates?

Brian

>  
>  /*
>   * Default minimum read and write sizes.
> @@ -372,9 +383,8 @@ xfs_preferred_iosize(xfs_mount_t *mp)
>  	return PAGE_SIZE;
>  }
>  
> -#define XFS_LAST_UNMOUNT_WAS_CLEAN(mp)	\
> -				((mp)->m_flags & XFS_MOUNT_WAS_CLEAN)
> -#define XFS_FORCED_SHUTDOWN(mp)	((mp)->m_flags & XFS_MOUNT_FS_SHUTDOWN)
> +#define XFS_FORCED_SHUTDOWN(mp) \
> +		test_bit(XFS_STATE_SHUTDOWN, &(mp)->m_state)
>  void xfs_do_force_shutdown(struct xfs_mount *mp, int flags, char *fname,
>  		int lnnum);
>  #define xfs_force_shutdown(m,f)	\
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index d3dff878be99..9938d9fb420b 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
> @@ -191,7 +191,7 @@ xfs_parseargs(
>  	 * Copy binary VFS mount flags we are interested in.
>  	 */
>  	if (sb_rdonly(sb))
> -		mp->m_flags |= XFS_MOUNT_RDONLY;
> +		set_bit(XFS_STATE_RDONLY, &mp->m_state);
>  	if (sb->s_flags & SB_DIRSYNC)
>  		mp->m_features |= XFS_FEAT_DIRSYNC;
>  	if (sb->s_flags & SB_SYNCHRONOUS)
> @@ -361,7 +361,7 @@ xfs_parseargs(
>  	/*
>  	 * no recovery flag requires a read-only mount
>  	 */
> -	if (xfs_has_norecovery(mp) && !(mp->m_flags & XFS_MOUNT_RDONLY)) {
> +	if (xfs_has_norecovery(mp) && !xfs_is_readonly(mp)) {
>  		xfs_warn(mp, "no-recovery mounts must be read-only.");
>  		return -EINVAL;
>  	}
> @@ -567,7 +567,7 @@ xfs_max_file_offset(
>   *
>   * Inode allocation patterns are altered only if inode32 is requested
>   * (XFS_FEAT_SMALL_INUMS), and the filesystem is sufficiently large.
> - * If altered, XFS_MOUNT_32BITINODES is set as well.
> + * If altered, XFS_STATE_32BITINODES is set as well.
>   *
>   * An agcount independent of that in the mount structure is provided
>   * because in the growfs case, mp->m_sb.sb_agcount is not yet updated
> @@ -609,13 +609,13 @@ xfs_set_inode_alloc(
>  
>  	/*
>  	 * If user asked for no more than 32-bit inodes, and the fs is
> -	 * sufficiently large, set XFS_MOUNT_32BITINODES if we must alter
> +	 * sufficiently large, set XFS_STATE_32BITINODES if we must alter
>  	 * the allocator to accommodate the request.
>  	 */
>  	if (xfs_has_small_inums(mp) && ino > XFS_MAXINUMBER_32)
> -		mp->m_flags |= XFS_MOUNT_32BITINODES;
> +		set_bit(XFS_STATE_32BITINODES, &mp->m_state);
>  	else
> -		mp->m_flags &= ~XFS_MOUNT_32BITINODES;
> +		clear_bit(XFS_STATE_32BITINODES, &mp->m_state);
>  
>  	for (index = 0; index < agcount; index++) {
>  		struct xfs_perag	*pag;
> @@ -624,7 +624,7 @@ xfs_set_inode_alloc(
>  
>  		pag = xfs_perag_get(mp, index);
>  
> -		if (mp->m_flags & XFS_MOUNT_32BITINODES) {
> +		if (test_bit(XFS_STATE_32BITINODES, &mp->m_state)) {
>  			if (ino > XFS_MAXINUMBER_32) {
>  				pag->pagi_inodeok = 0;
>  				pag->pagf_metadata = 0;
> @@ -644,7 +644,7 @@ xfs_set_inode_alloc(
>  		xfs_perag_put(pag);
>  	}
>  
> -	return (mp->m_flags & XFS_MOUNT_32BITINODES) ? maxagi : agcount;
> +	return test_bit(XFS_STATE_32BITINODES, &mp->m_state) ? maxagi : agcount;
>  }
>  
>  STATIC int
> @@ -1294,7 +1294,7 @@ xfs_fs_remount(
>  	}
>  
>  	/* ro -> rw */
> -	if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(*flags & SB_RDONLY)) {
> +	if (xfs_is_readonly(mp) && !(*flags & SB_RDONLY)) {
>  		if (xfs_has_norecovery(mp)) {
>  			xfs_warn(mp,
>  		"ro->rw transition prohibited on norecovery mount");
> @@ -1311,7 +1311,7 @@ xfs_fs_remount(
>  			return -EINVAL;
>  		}
>  
> -		mp->m_flags &= ~XFS_MOUNT_RDONLY;
> +		clear_bit(XFS_STATE_RDONLY, &mp->m_state);
>  
>  		/*
>  		 * If this is the first remount to writeable state we
> @@ -1350,7 +1350,7 @@ xfs_fs_remount(
>  	}
>  
>  	/* rw -> ro */
> -	if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (*flags & SB_RDONLY)) {
> +	if (!xfs_is_readonly(mp) && (*flags & SB_RDONLY)) {
>  		/*
>  		 * Cancel background eofb scanning so it cannot race with the
>  		 * final log force+buftarg wait and deadlock the remount.
> @@ -1381,7 +1381,7 @@ xfs_fs_remount(
>  		xfs_save_resvblks(mp);
>  
>  		xfs_quiesce_attr(mp);
> -		mp->m_flags |= XFS_MOUNT_RDONLY;
> +		set_bit(XFS_STATE_RDONLY, &mp->m_state);
>  	}
>  
>  	return 0;
> @@ -1433,8 +1433,6 @@ STATIC int
>  xfs_finish_flags(
>  	struct xfs_mount	*mp)
>  {
> -	int			ronly = (mp->m_flags & XFS_MOUNT_RDONLY);
> -
>  	/* Fail a mount where the logbuf is smaller than the log stripe */
>  	if (xfs_has_logv2(mp)) {
>  		if (mp->m_logbsize <= 0 &&
> @@ -1467,7 +1465,7 @@ xfs_finish_flags(
>  	/*
>  	 * prohibit r/w mounts of read-only filesystems
>  	 */
> -	if ((mp->m_sb.sb_flags & XFS_SBF_READONLY) && !ronly) {
> +	if ((mp->m_sb.sb_flags & XFS_SBF_READONLY) && !xfs_is_readonly(mp)) {
>  		xfs_warn(mp,
>  			"cannot mount a read-only filesystem as read-write");
>  		return -EROFS;
> -- 
> 2.17.0
> 

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

* Re: [PATCH 06/10] xfs: replace XFS_FORCED_SHUTDOWN with xfs_is_shut_down
  2018-08-20  4:48 ` [PATCH 06/10] xfs: replace XFS_FORCED_SHUTDOWN with xfs_is_shut_down Dave Chinner
@ 2018-08-21 13:23   ` Brian Foster
  0 siblings, 0 replies; 27+ messages in thread
From: Brian Foster @ 2018-08-21 13:23 UTC (permalink / raw)
  To: Dave Chinner; +Cc: linux-xfs

On Mon, Aug 20, 2018 at 02:48:47PM +1000, Dave Chinner wrote:
> From: Dave Chinner <dchinner@redhat.com>
> 
> Remove the shouty macro and instead use the inline function that
> matches other state/feature check wrapper naming. This conversion
> was done with sed.
> 
> Signed-off-by: Dave Chinner <dchinner@redhat.com>
> ---

Ok, that answers my previous question.. though the new helper should be
in this patch instead of the previous..

>  fs/xfs/libxfs/xfs_alloc.c      |  2 +-
>  fs/xfs/libxfs/xfs_attr.c       |  6 +++---
>  fs/xfs/libxfs/xfs_bmap.c       | 16 ++++++++--------
>  fs/xfs/libxfs/xfs_dir2_block.c |  2 +-
>  fs/xfs/libxfs/xfs_dir2_sf.c    |  8 ++++----
>  fs/xfs/libxfs/xfs_ialloc.c     |  6 +++---
>  fs/xfs/scrub/scrub.c           |  2 +-
>  fs/xfs/xfs_aops.c              |  8 ++++----
>  fs/xfs/xfs_attr_list.c         |  2 +-
>  fs/xfs/xfs_bmap_util.c         |  8 ++++----
>  fs/xfs/xfs_buf.c               |  2 +-
>  fs/xfs/xfs_buf_item.c          |  4 ++--
>  fs/xfs/xfs_dir2_readdir.c      |  2 +-
>  fs/xfs/xfs_dquot.c             |  2 +-
>  fs/xfs/xfs_file.c              | 12 ++++++------
>  fs/xfs/xfs_fsops.c             |  2 +-
>  fs/xfs/xfs_icache.c            |  4 ++--
>  fs/xfs/xfs_inode.c             | 20 ++++++++++----------
>  fs/xfs/xfs_inode_item.c        |  6 +++---
>  fs/xfs/xfs_ioctl.c             |  8 ++++----
>  fs/xfs/xfs_ioctl32.c           |  2 +-
>  fs/xfs/xfs_iomap.c             |  6 +++---
>  fs/xfs/xfs_iops.c              |  4 ++--
>  fs/xfs/xfs_log_recover.c       |  8 ++++----
>  fs/xfs/xfs_mount.c             |  2 +-
>  fs/xfs/xfs_mount.h             |  4 +---
>  fs/xfs/xfs_pnfs.c              |  2 +-
>  fs/xfs/xfs_qm.c                |  4 ++--
>  fs/xfs/xfs_reflink.c           |  2 +-
>  fs/xfs/xfs_super.c             |  2 +-
>  fs/xfs/xfs_symlink.c           |  8 ++++----
>  fs/xfs/xfs_trans.c             |  8 ++++----
>  fs/xfs/xfs_trans_ail.c         |  8 ++++----
>  fs/xfs/xfs_trans_buf.c         | 10 +++++-----
>  34 files changed, 95 insertions(+), 97 deletions(-)
> 
...
> diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
> index 03f4681c1ba6..2a7e7ef7c338 100644
> --- a/fs/xfs/xfs_mount.h
> +++ b/fs/xfs/xfs_mount.h
> @@ -296,7 +296,7 @@ __XFS_HAS_FEAT(realtime, REALTIME)
>   * Mount features
>   *
>   * These do not change dynamically - features that can come and go,
> - * such as 32 bit inodes and read-only state, are kept as flags rather than
> + * such as 32 bit inodes and read-only state, are kept as state rather than

... and this change looks like it should probably be in the previous
patch.

Brian

>   * features.
>   */
>  __XFS_HAS_FEAT(wsync, WSYNC)
> @@ -383,8 +383,6 @@ xfs_preferred_iosize(xfs_mount_t *mp)
>  	return PAGE_SIZE;
>  }
>  
> -#define XFS_FORCED_SHUTDOWN(mp) \
> -		test_bit(XFS_STATE_SHUTDOWN, &(mp)->m_state)
>  void xfs_do_force_shutdown(struct xfs_mount *mp, int flags, char *fname,
>  		int lnnum);
>  #define xfs_force_shutdown(m,f)	\
> diff --git a/fs/xfs/xfs_pnfs.c b/fs/xfs/xfs_pnfs.c
> index f44c3599527d..2908dcfa9ecf 100644
> --- a/fs/xfs/xfs_pnfs.c
> +++ b/fs/xfs/xfs_pnfs.c
> @@ -99,7 +99,7 @@ xfs_fs_map_blocks(
>  	uint			lock_flags;
>  	int			error = 0;
>  
> -	if (XFS_FORCED_SHUTDOWN(mp))
> +	if (xfs_is_shut_down(mp))
>  		return -EIO;
>  
>  	/*
> diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
> index 9ee840472138..1957042882d5 100644
> --- a/fs/xfs/xfs_qm.c
> +++ b/fs/xfs/xfs_qm.c
> @@ -157,7 +157,7 @@ xfs_qm_dqpurge(
>  	}
>  
>  	ASSERT(atomic_read(&dqp->q_pincount) == 0);
> -	ASSERT(XFS_FORCED_SHUTDOWN(mp) ||
> +	ASSERT(xfs_is_shut_down(mp) ||
>  		!test_bit(XFS_LI_IN_AIL, &dqp->q_logitem.qli_item.li_flags));
>  
>  	xfs_dqfunlock(dqp);
> @@ -815,7 +815,7 @@ xfs_qm_qino_alloc(
>  
>  	error = xfs_trans_commit(tp);
>  	if (error) {
> -		ASSERT(XFS_FORCED_SHUTDOWN(mp));
> +		ASSERT(xfs_is_shut_down(mp));
>  		xfs_alert(mp, "%s failed (error %d)!", __func__, error);
>  	}
>  	if (need_alloc)
> diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c
> index 66ba7c4446d5..b1196911a8b2 100644
> --- a/fs/xfs/xfs_reflink.c
> +++ b/fs/xfs/xfs_reflink.c
> @@ -1221,7 +1221,7 @@ xfs_reflink_remap_range(
>  	if (!xfs_has_reflink(mp))
>  		return -EOPNOTSUPP;
>  
> -	if (XFS_FORCED_SHUTDOWN(mp))
> +	if (xfs_is_shut_down(mp))
>  		return -EIO;
>  
>  	/* Lock both files against IO */
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index 9938d9fb420b..7c1e03539b5e 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
> @@ -949,7 +949,7 @@ xfs_fs_destroy_inode(
>  
>  	xfs_inactive(ip);
>  
> -	ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0);
> +	ASSERT(xfs_is_shut_down(ip->i_mount) || ip->i_delayed_blks == 0);
>  	XFS_STATS_INC(ip->i_mount, vn_reclaim);
>  
>  	/*
> diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c
> index 675481028292..41e1054748e5 100644
> --- a/fs/xfs/xfs_symlink.c
> +++ b/fs/xfs/xfs_symlink.c
> @@ -124,7 +124,7 @@ xfs_readlink(
>  
>  	ASSERT(!(ip->i_df.if_flags & XFS_IFINLINE));
>  
> -	if (XFS_FORCED_SHUTDOWN(mp))
> +	if (xfs_is_shut_down(mp))
>  		return -EIO;
>  
>  	xfs_ilock(ip, XFS_ILOCK_SHARED);
> @@ -183,7 +183,7 @@ xfs_symlink(
>  
>  	trace_xfs_symlink(dp, link_name);
>  
> -	if (XFS_FORCED_SHUTDOWN(mp))
> +	if (xfs_is_shut_down(mp))
>  		return -EIO;
>  
>  	/*
> @@ -456,7 +456,7 @@ xfs_inactive_symlink_rmt(
>  	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
>  	error = xfs_trans_commit(tp);
>  	if (error) {
> -		ASSERT(XFS_FORCED_SHUTDOWN(mp));
> +		ASSERT(xfs_is_shut_down(mp));
>  		goto error_unlock;
>  	}
>  
> @@ -489,7 +489,7 @@ xfs_inactive_symlink(
>  
>  	trace_xfs_inactive_symlink(ip);
>  
> -	if (XFS_FORCED_SHUTDOWN(mp))
> +	if (xfs_is_shut_down(mp))
>  		return -EIO;
>  
>  	xfs_ilock(ip, XFS_ILOCK_EXCL);
> diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
> index db4367baab34..5c064bc8d49a 100644
> --- a/fs/xfs/xfs_trans.c
> +++ b/fs/xfs/xfs_trans.c
> @@ -857,7 +857,7 @@ xfs_trans_committed_bulk(
>  		 * object into the AIL as we are in a shutdown situation.
>  		 */
>  		if (aborted) {
> -			ASSERT(XFS_FORCED_SHUTDOWN(ailp->ail_mount));
> +			ASSERT(xfs_is_shut_down(ailp->ail_mount));
>  			lip->li_ops->iop_unpin(lip, 1);
>  			continue;
>  		}
> @@ -944,7 +944,7 @@ __xfs_trans_commit(
>  	if (!(tp->t_flags & XFS_TRANS_DIRTY))
>  		goto out_unreserve;
>  
> -	if (XFS_FORCED_SHUTDOWN(mp)) {
> +	if (xfs_is_shut_down(mp)) {
>  		error = -EIO;
>  		goto out_unreserve;
>  	}
> @@ -1031,12 +1031,12 @@ xfs_trans_cancel(
>  	 * filesystem.  This happens in paths where we detect
>  	 * corruption and decide to give up.
>  	 */
> -	if (dirty && !XFS_FORCED_SHUTDOWN(mp)) {
> +	if (dirty && !xfs_is_shut_down(mp)) {
>  		XFS_ERROR_REPORT("xfs_trans_cancel", XFS_ERRLEVEL_LOW, mp);
>  		xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
>  	}
>  #ifdef DEBUG
> -	if (!dirty && !XFS_FORCED_SHUTDOWN(mp)) {
> +	if (!dirty && !xfs_is_shut_down(mp)) {
>  		struct xfs_log_item *lip;
>  
>  		list_for_each_entry(lip, &tp->t_items, li_trans)
> diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c
> index 55326f971cb3..19e79d8279fc 100644
> --- a/fs/xfs/xfs_trans_ail.c
> +++ b/fs/xfs/xfs_trans_ail.c
> @@ -601,7 +601,7 @@ xfs_ail_push(
>  	xfs_log_item_t	*lip;
>  
>  	lip = xfs_ail_min(ailp);
> -	if (!lip || XFS_FORCED_SHUTDOWN(ailp->ail_mount) ||
> +	if (!lip || xfs_is_shut_down(ailp->ail_mount) ||
>  	    XFS_LSN_CMP(threshold_lsn, ailp->ail_target) <= 0)
>  		return;
>  
> @@ -713,7 +713,7 @@ xfs_trans_ail_update_bulk(
>  		xfs_ail_splice(ailp, cur, &tmp, lsn);
>  
>  	if (mlip_changed) {
> -		if (!XFS_FORCED_SHUTDOWN(ailp->ail_mount))
> +		if (!xfs_is_shut_down(ailp->ail_mount))
>  			xlog_assign_tail_lsn_locked(ailp->ail_mount);
>  		spin_unlock(&ailp->ail_lock);
>  
> @@ -771,7 +771,7 @@ xfs_trans_ail_delete(
>  
>  	if (!test_bit(XFS_LI_IN_AIL, &lip->li_flags)) {
>  		spin_unlock(&ailp->ail_lock);
> -		if (!XFS_FORCED_SHUTDOWN(mp)) {
> +		if (!xfs_is_shut_down(mp)) {
>  			xfs_alert_tag(mp, XFS_PTAG_AILDELETE,
>  	"%s: attempting to delete a log item that is not in the AIL",
>  					__func__);
> @@ -782,7 +782,7 @@ xfs_trans_ail_delete(
>  
>  	mlip_changed = xfs_ail_delete_one(ailp, lip);
>  	if (mlip_changed) {
> -		if (!XFS_FORCED_SHUTDOWN(mp))
> +		if (!xfs_is_shut_down(mp))
>  			xlog_assign_tail_lsn_locked(mp);
>  		if (list_empty(&ailp->ail_head))
>  			wake_up_all(&ailp->ail_empty);
> diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c
> index 15919f67a88f..f18d5cd0f606 100644
> --- a/fs/xfs/xfs_trans_buf.c
> +++ b/fs/xfs/xfs_trans_buf.c
> @@ -137,7 +137,7 @@ xfs_trans_get_buf_map(
>  	bp = xfs_trans_buf_item_match(tp, target, map, nmaps);
>  	if (bp != NULL) {
>  		ASSERT(xfs_buf_islocked(bp));
> -		if (XFS_FORCED_SHUTDOWN(tp->t_mountp)) {
> +		if (xfs_is_shut_down(tp->t_mountp)) {
>  			xfs_buf_stale(bp);
>  			bp->b_flags |= XBF_DONE;
>  		}
> @@ -259,7 +259,7 @@ xfs_trans_read_buf_map(
>  		 * We never locked this buf ourselves, so we shouldn't
>  		 * brelse it either. Just get out.
>  		 */
> -		if (XFS_FORCED_SHUTDOWN(mp)) {
> +		if (xfs_is_shut_down(mp)) {
>  			trace_xfs_trans_read_buf_shut(bp, _RET_IP_);
>  			return -EIO;
>  		}
> @@ -291,7 +291,7 @@ xfs_trans_read_buf_map(
>  	 */
>  	if (bp->b_error) {
>  		error = bp->b_error;
> -		if (!XFS_FORCED_SHUTDOWN(mp))
> +		if (!xfs_is_shut_down(mp))
>  			xfs_buf_ioerror_alert(bp, __func__);
>  		bp->b_flags &= ~XBF_DONE;
>  		xfs_buf_stale(bp);
> @@ -306,7 +306,7 @@ xfs_trans_read_buf_map(
>  		return error;
>  	}
>  
> -	if (XFS_FORCED_SHUTDOWN(mp)) {
> +	if (xfs_is_shut_down(mp)) {
>  		xfs_buf_relse(bp);
>  		trace_xfs_trans_read_buf_shut(bp, _RET_IP_);
>  		return -EIO;
> @@ -418,7 +418,7 @@ xfs_trans_brelse(
>  	 * due to our reference). Since we're already shutdown and need
>  	 * ail_lock, just force remove from the AIL and release the bli here.
>  	 */
> -	if (XFS_FORCED_SHUTDOWN(tp->t_mountp) && freed) {
> +	if (xfs_is_shut_down(tp->t_mountp) && freed) {
>  		xfs_trans_ail_remove(&bip->bli_item, SHUTDOWN_LOG_IO_ERROR);
>  		xfs_buf_item_relse(bp);
>  	} else if (!(bip->bli_flags & XFS_BLI_DIRTY)) {
> -- 
> 2.17.0
> 

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

* Re: [PATCH 08/10] xfs: open code sb verifier feature checks
  2018-08-20  4:48 ` [PATCH 08/10] xfs: open code sb verifier " Dave Chinner
  2018-08-21 13:01   ` Jan Tulak
@ 2018-08-21 13:25   ` Brian Foster
  2018-08-21 23:43     ` Dave Chinner
  1 sibling, 1 reply; 27+ messages in thread
From: Brian Foster @ 2018-08-21 13:25 UTC (permalink / raw)
  To: Dave Chinner; +Cc: linux-xfs

On Mon, Aug 20, 2018 at 02:48:49PM +1000, Dave Chinner wrote:
> From: Dave Chinner <dchinner@redhat.com>
> 
> The superblock verifiers are one of the last places that use the sb
> version functions to do feature checks. This are all quite simple
> uses, and there aren't many of them so open code them all.
> 
> Also, move the good version number check into xfs_sb.c instead of it
> being an inline function in xfs_format.h
> 
> Signed-off-by: Dave Chinner <dchinner@redhat.com>
> ---
>  fs/xfs/libxfs/xfs_format.h |  26 ---------
>  fs/xfs/libxfs/xfs_sb.c     | 116 +++++++++++++++++++++++++------------
>  fs/xfs/libxfs/xfs_sb.h     |   1 +
>  3 files changed, 81 insertions(+), 62 deletions(-)
> 
...
> diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c
> index bedf6c6bf990..b83cf8adca1a 100644
> --- a/fs/xfs/libxfs/xfs_sb.c
> +++ b/fs/xfs/libxfs/xfs_sb.c
...
> @@ -485,7 +523,7 @@ xfs_sb_quota_from_disk(struct xfs_sb *sbp)
>  	 * We need to do these manipilations only if we are working
>  	 * with an older version of on-disk superblock.
>  	 */
> -	if (xfs_sb_version_haspquotino(sbp))
> +	if (XFS_SB_VERSION_NUM(sbp) < XFS_SB_VERSION_5)
>  		return;

Isn't this backwards (we want to exit if == XFS_SB_VERSION_5)?

Brian

>  
>  	if (sbp->sb_qflags & XFS_OQUOTA_ENFD)
> @@ -578,7 +616,8 @@ __xfs_sb_from_disk(
>  	 * sb_meta_uuid is only on disk if it differs from sb_uuid and the
>  	 * feature flag is set; if not set we keep it only in memory.
>  	 */
> -	if (xfs_sb_version_hasmetauuid(to))
> +	if (XFS_SB_VERSION_NUM(to) == XFS_SB_VERSION_5 &&
> +	    (to->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_META_UUID))
>  		uuid_copy(&to->sb_meta_uuid, &from->sb_meta_uuid);
>  	else
>  		uuid_copy(&to->sb_meta_uuid, &from->sb_uuid);
> @@ -603,7 +642,12 @@ xfs_sb_quota_to_disk(
>  	uint16_t	qflags = from->sb_qflags;
>  
>  	to->sb_uquotino = cpu_to_be64(from->sb_uquotino);
> -	if (xfs_sb_version_haspquotino(from)) {
> +
> +	/*
> +	 * The in-memory superblock quota state matches the v5 on-disk format so
> +	 * just write them out and return
> +	 */
> +	if (XFS_SB_VERSION_NUM(from) == XFS_SB_VERSION_5) {
>  		to->sb_qflags = cpu_to_be16(from->sb_qflags);
>  		to->sb_gquotino = cpu_to_be64(from->sb_gquotino);
>  		to->sb_pquotino = cpu_to_be64(from->sb_pquotino);
> @@ -611,9 +655,9 @@ xfs_sb_quota_to_disk(
>  	}
>  
>  	/*
> -	 * The in-core version of sb_qflags do not have XFS_OQUOTA_*
> -	 * flags, whereas the on-disk version does.  So, convert incore
> -	 * XFS_{PG}QUOTA_* flags to on-disk XFS_OQUOTA_* flags.
> +	 * For older superblocks (v4), the in-core version of sb_qflags do not
> +	 * have XFS_OQUOTA_* flags, whereas the on-disk version does.  So,
> +	 * convert incore XFS_{PG}QUOTA_* flags to on-disk XFS_OQUOTA_* flags.
>  	 */
>  	qflags &= ~(XFS_PQUOTA_ENFD | XFS_PQUOTA_CHKD |
>  			XFS_GQUOTA_ENFD | XFS_GQUOTA_CHKD);
> @@ -713,7 +757,7 @@ xfs_sb_to_disk(
>  	to->sb_features2 = cpu_to_be32(from->sb_features2);
>  	to->sb_bad_features2 = cpu_to_be32(from->sb_bad_features2);
>  
> -	if (xfs_sb_version_hascrc(from)) {
> +	if (XFS_SB_VERSION_NUM(from) == XFS_SB_VERSION_5) {
>  		to->sb_features_compat = cpu_to_be32(from->sb_features_compat);
>  		to->sb_features_ro_compat =
>  				cpu_to_be32(from->sb_features_ro_compat);
> @@ -723,7 +767,7 @@ xfs_sb_to_disk(
>  				cpu_to_be32(from->sb_features_log_incompat);
>  		to->sb_spino_align = cpu_to_be32(from->sb_spino_align);
>  		to->sb_lsn = cpu_to_be64(from->sb_lsn);
> -		if (xfs_sb_version_hasmetauuid(from))
> +		if (from->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_META_UUID)
>  			uuid_copy(&to->sb_meta_uuid, &from->sb_meta_uuid);
>  	}
>  }
> diff --git a/fs/xfs/libxfs/xfs_sb.h b/fs/xfs/libxfs/xfs_sb.h
> index 8f4cbe2b639c..e136c2517647 100644
> --- a/fs/xfs/libxfs/xfs_sb.h
> +++ b/fs/xfs/libxfs/xfs_sb.h
> @@ -29,6 +29,7 @@ extern void	xfs_sb_mount_common(struct xfs_mount *mp, struct xfs_sb *sbp);
>  extern void	xfs_sb_from_disk(struct xfs_sb *to, struct xfs_dsb *from);
>  extern void	xfs_sb_to_disk(struct xfs_dsb *to, struct xfs_sb *from);
>  extern void	xfs_sb_quota_from_disk(struct xfs_sb *sbp);
> +extern bool	xfs_sb_good_version(struct xfs_sb *sbp);
>  extern uint64_t	xfs_sb_version_to_features(struct xfs_sb *sbp);
>  
>  extern int	xfs_update_secondary_sbs(struct xfs_mount *mp);
> -- 
> 2.17.0
> 

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

* Re: [PATCH 0/10] xfs: feature flag rework
  2018-08-20  4:48 [PATCH 0/10] xfs: feature flag rework Dave Chinner
                   ` (9 preceding siblings ...)
  2018-08-20  4:48 ` [PATCH 10/10] xfs: remove unused xfs_sb_version_has... wrappers Dave Chinner
@ 2018-08-21 13:54 ` Jan Tulak
  10 siblings, 0 replies; 27+ messages in thread
From: Jan Tulak @ 2018-08-21 13:54 UTC (permalink / raw)
  To: Chinner, Dave; +Cc: linux-xfs

On Mon, Aug 20, 2018 at 6:49 AM Dave Chinner <david@fromorbit.com> wrote:
>
> Hi folks,
>
> This series reworks how the kernel code handles feature bits. It
> seemed to me to be a bit crazy to repeatedly have to check multiple
> values in the superblock to check whether a feature is supported.
> e.g. to check if reflink is available, we first mask the version
> number to extract it from the superblock field, then we check it
> against the v5 value, then we load and check the feature bit from
> the superblock.
>
> This could all just be a single flag check - a flag that is set at
> mount time after doing all of the above, and so it's just a single
> operation to check.
>
> I'm also tired of typing "xfs_sb_version_hasfoo" everytime a check
> needs to be done. Not to mention having a different mechanism to
> check mount option based features.
>
> And then there's the conflation of mount option feature flags and
> runtime state in the one set of flags. The flags field is not
> updated atomically, so there no guarantee that a change of a state
> flag does race with anything else and we lose it.
>
> So this patch set moves all the feature flags into a new m_features
> field in the struct xfs_mount. It doesn't matter if they are mount
> options or superblock feature bits - they all end up in the one
> place whether they are [almost entirely] read only. These are now
> checked by "xfs_has_foo(mp)" functions (following the ext4 feature
> check syntax), and for the very few features that can be dynamically
> added or removed there are also xfs_feat_add/remove_foo(mp) helpers.
> IOWs, both superblock and mount option features are checked the same
> way.
>
> The state flags (clean mount, unmounting, shutdown, etc) are all
> moved to a new m_state field, which is manipulated entirely by
> atomic bitops to avoid update races. THere are a couple of wrappers
> for the common checks - xfs_is_read_only(mp) and
> xfs_is_shut_down(mp). The latter replaces the XFS_FORCED_SHUTDOWN()
> macro.
>
> There's a bit of extra work around the attr2 feature bit - we've got
> the superblock bit, and then "attr2" and "noattr2" mount options and
> somewhat convoluted interactions. This patchset changes the
> behaviour of all these now - the attr2 bit on disk and mount option
> now mean the same thing, and noattr2 will turn off the superblock
> bit if it is set and prevent attr2 inodes from being created. This
> simplifies the mount time checking and clearing of these features.
>
> Also, it gives us a clean separation of "inode32 mount option" and
> "inode32 allocation is active". The former is a feature bit (i.e.
> SMALL_INUMS), and the latter is a state bit (32BITINODES) that is
> set if the filesystem size requires the allocator to limit
> allocation to 32 bit inode space.
>
> This also allows us to get rid of all the xfs_sb_version_hasfoo()
> inline functions. THere is a single function to populate m_features
> from the superblock bits, and the low level checks that are purely
> superblock based (i.e. on disk conversion and verifiers) directly
> check the superblock fields rather than use wrappers.
>
> Overall, this doesn't change the amount of code. If does reduce the
> built binary size by about 3.2kB, mainly through replacing the
> xfs_sb_version...() checks with a single m_features flag check. It
> makes the code a bit simpler, easier to read, and less shouty and
> separates runtime state from filesystem features.
>
> -Dave.
>
>

I have tried to give this patchset some review. Generally, it looks
ok, but I didn't run any tests and could only look for inconsistencies
between added and removed code and similar low-level stuff. I'm not
sure if it is enough to add my Reviewed-by. :)

Cheers,
Jan

-- 
Jan Tulak
jtulak@redhat.com / jan@tulak.me

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

* Re: [PATCH 01/10] xfs: reflect sb features in xfs_mount
  2018-08-21 13:21   ` Brian Foster
@ 2018-08-21 23:31     ` Dave Chinner
  2018-08-22 12:17       ` Brian Foster
  0 siblings, 1 reply; 27+ messages in thread
From: Dave Chinner @ 2018-08-21 23:31 UTC (permalink / raw)
  To: Brian Foster; +Cc: linux-xfs

On Tue, Aug 21, 2018 at 09:21:40AM -0400, Brian Foster wrote:
> On Mon, Aug 20, 2018 at 02:48:42PM +1000, Dave Chinner wrote:
> > From: Dave Chinner <dchinner@redhat.com>
> > 
> > Currently on-disk feature checks require decoding the superblock
> > fileds and so can be non-trivial. We have almost 400 hundred
> > individual feature checks in the XFS code, so this is a significant
> > amount of code. To reduce runtime check overhead, pre-process all
> > the version flags into a features field in the xfs_mount at mount
> > time so we can convert all the feature checks to a simple flag
> > check.
> > 
> > There is also a need to convert the dynamic feature flags to update
> > the m_features field. This is required for attr, attr2 and quota
> > features. New xfs_mount based wrappers are added for this.
> > 
> > Before:
> > 
> > $ size -t fs/xfs/built-in.a
> >    text	   data	    bss	    dec	    hex	filename
> > ....
> > 1294873	 182766	   1036	1478675	 169013	(TOTALS
> > 
> 
> Was some text truncated from the commit log description here? Did you
> mean to include the after size as well?

Yeah, I thought I did update that. Maybe forgot to refresh the
header once I did. The before and after are:

	text	   data	    bss	    dec	    hex	filename
before	1326155	 189006	   1036	1516197	 1722a5	(TOTALS)
after	1322929	 189006	   1036	1512971	 17160b	(TOTALS)

> > Signed-off-by: Dave Chinner <dchinner@redhat.com>
> > ---
> >  fs/xfs/libxfs/xfs_format.h |  2 +-
> >  fs/xfs/libxfs/xfs_sb.c     | 61 +++++++++++++++++++++++++++++
> >  fs/xfs/libxfs/xfs_sb.h     |  1 +
> >  fs/xfs/xfs_log_recover.c   |  1 +
> >  fs/xfs/xfs_mount.c         |  1 +
> >  fs/xfs/xfs_mount.h         | 79 ++++++++++++++++++++++++++++++++++++++
> >  6 files changed, 144 insertions(+), 1 deletion(-)
> > 
> ...
> > diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
> > index a21dc61ec09e..5d0438ec07dd 100644
> > --- a/fs/xfs/xfs_log_recover.c
> > +++ b/fs/xfs/xfs_log_recover.c
> > @@ -5723,6 +5723,7 @@ xlog_do_recover(
> >  	xfs_buf_relse(bp);
> >  
> >  	/* re-initialise in-core superblock and geometry structures */
> > +	mp->m_features |= xfs_sb_version_to_features(sbp);
> 
> How is this a reinit if it ORs in fields?

The only feature bit that can be removed by log recovery is the
attr2 feature bit which means the last mount was mounted with
"noattr2". So apart from that feature bit, ORing in the new
superblock feature mask works just fine.

As it is, for v5 attr2 can't be turned off, so it's just fine for
v5 filesystems. For v4 the old code would set XFS_MOUNT_ATTR2 if the
sb feature bit was set /prior/ to log recovery being run. Hence if
log recovery removed the feature bit, the very next attr creation
will turn it straight back on.

The only way to not have attr2 enabled in this case is to use the
noattr2 mount option, and the new code has exactly the same
behaviour - the attr2 superblock bit and the feature flag will get
cleared after log recovery if the noattr2 mount option is set.

Also worth noting is that if there's a sb_bad_features2
interatction, it will re-add the feature bit because it just ORs the
two fields together.

IOWs, the behaviour of this patch is roughly the same as the
existing code when it comes to the attr2 flag being removed when the
superblock is recovered as well as when there is a features2
mismatch.

I think there's more work needed on the attr2 feature side of
things, as noted in the cover description. In addition to the
unpredictable behaviour via log recovery, I don't see a reason for
noattr2 existing these days. It doesn't get rid of existing attr2
format inodes on disk - it just stops new ones from being created.
We've used attr2 for more than 10 years now without it being an
issue, so there's no reason for needing to turn it off anymore. I
think we should deprecate the option and remove it.

> I guess I'm curious why we OR
> in fields in either case as opposed to using an assignment.

Because mount option features are already set in m_features, so we
can't just overwrite it with just the superblock features.

> 
> >  	xfs_reinit_percpu_counters(mp);
> >  	error = xfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi);
> >  	if (error) {
> ...
> > diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
> > index 7964513c3128..92d947f17c69 100644
> > --- a/fs/xfs/xfs_mount.h
> > +++ b/fs/xfs/xfs_mount.h
> > @@ -127,6 +127,7 @@ typedef struct xfs_mount {
> >  	struct mutex		m_growlock;	/* growfs mutex */
> >  	int			m_fixedfsid[2];	/* unchanged for life of FS */
> >  	uint64_t		m_flags;	/* global mount flags */
> > +	uint64_t		m_features;	/* active filesystem features */
> >  	bool			m_inotbt_nores; /* no per-AG finobt resv. */
> >  	int			m_ialloc_inos;	/* inodes in inode allocation */
> >  	int			m_ialloc_blks;	/* blocks in inode allocation */
> > @@ -195,6 +196,84 @@ typedef struct xfs_mount {
> >  #endif
> >  } xfs_mount_t;
> >  
> > +/*
> > + * Flags for m_features.
> > + *
> > + * These are all the active features in the filesystem, regardless of how
> > + * they are configured.
> > + */
> > +#define	XFS_FEAT_ATTR		(1ULL << 0)	/* xattrs present in fs */
> > +#define	XFS_FEAT_NLINK		(1ULL << 1)	/* 32 bit link counts */
> > +#define	XFS_FEAT_QUOTA		(1ULL << 2)	/* quota active */
> > +#define	XFS_FEAT_ALIGN		(1ULL << 3)	/* inode alignment */
> > +#define	XFS_FEAT_DALIGN		(1ULL << 4)	/* data alignment */
> > +#define XFS_FEAT_LOGV2		(1ULL << 5)	/* version 2 logs */
> > +#define XFS_FEAT_SECTOR		(1ULL << 6)	/* sector size > 512 bytes */
> > +#define	XFS_FEAT_EXTFLG		(1ULL << 7)	/* unwritten extents */
> > +#define	XFS_FEAT_ASCIICI	(1ULL << 8)	/* ASCII only case-insens. */
> > +#define XFS_FEAT_LAZYSBCOUNT	(1ULL << 9)	/* Superblk counters */
> > +#define XFS_FEAT_ATTR2		(1ULL << 10)	/* dynamic attr fork */
> > +#define XFS_FEAT_PARENT		(1ULL << 11)	/* parent pointers */
> 
> Hmm, none of the parent pointer stuff has been merged yet, has it? If
> not, I'm sure it will be at some point, but I'd prefer not to include
> code for features that technically don't exist.

We already have the parent point feature bit declared and this is a
direct translation of the superblock feature bits. If it's unused,
then the compiler elides the xfs_has_parent() check function,
otherwise it's just a flag...

> Otherwise it looks like we have some inconsistent spacing/indentation.

Inherited from the superblock feature bit definitions. I'll clean it
up.

> 
> > +#define XFS_FEAT_PROJID32	(1ULL << 12)	/* 32 bit project id */
> > +#define XFS_FEAT_CRC		(1ULL << 13)	/* metadata CRCs */
> > +#define XFS_FEAT_PQUOTINO	(1ULL << 14)	/* non-shared proj/grp quotas */
> > +#define XFS_FEAT_FTYPE		(1ULL << 15)	/* inode type in dir */
> > +#define XFS_FEAT_FINOBT		(1ULL << 16)	/* free inode btree */
> > +#define XFS_FEAT_RMAPBT		(1ULL << 17)	/* reverse map btree */
> > +#define XFS_FEAT_REFLINK	(1ULL << 18)	/* reflinked files */
> > +#define XFS_FEAT_SPINODES	(1ULL << 19)	/* sparse inode chunks */
> > +#define XFS_FEAT_META_UUID	(1ULL << 20)	/* metadata UUID */
> > +#define XFS_FEAT_REALTIME	(1ULL << 21)	/* realtime device present */
> > +
> > +#define __XFS_HAS_FEAT(name, NAME) \
> > +static inline bool xfs_has_ ## name (struct xfs_mount *mp) \
> > +{ \
> 
> I'm assuming these xfs_has_*() calls will end up replacing the current
> xfs_sb_version_has*() calls throughout the code. Could we start using a

Yes.

> consistent function name prefix across the helpers? E.g., I think using
> 'xfs_feat_ ## name' here (instead of xfs_has_) would be fine, and
> consistent with the other helpers.

I'd prefer to drop the _feat_ prefix for the couple of add/remove
wrappers that exist, not add it to every feature check.

> I don't want to get into bikeshedding too much but tbh I've always found
> the xfs_sb_has_* thing kind of weird where the "has" text seems
> superfluous. It's just not been worth changing. It would be nice if we
> could stop propagating it here and define a consistently used prefix.

Yet we use "is" all over the place when checking if an object is
<something> (e.g. xfs_btree_ptr_is_null(), xfs_iext_rec_is_empty(),
xfs_rmap_is_mergeable(), etc) because it makes the code more
readable. The old sbversion namespace format is the problem, not the
use of "has" to indicate we are checking if the filesystem has a
feature...

I omitted the "_feat_" part of the name because it's effectively
redundant when you read it. i.e. if (xfs_has_pquotaino(mp)) reads as
a well composed sentence: "if XFS has project quotas inodes on this
mount". Doing s/has/feature/ does not improve the readbility of the
code, just makes it unnecessarily verbose.




> > +	return mp->m_features & XFS_FEAT_ ## NAME; \
> > +}
> > +
> > +/* Some features can be added dynamically so they need a set wrapper, too. */
> > +#define __XFS_HAS_ADDFEAT(name, NAME) \
> > +	__XFS_HAS_FEAT(name, NAME); \
> > +static inline void xfs_feat_add_ ## name (struct xfs_mount *mp) \
> > +{ \
> > +	mp->m_features |= XFS_FEAT_ ## NAME; \
> > +	xfs_sb_version_add ## name(&mp->m_sb); \
> > +}
> > +
> > +/* Some features can be cleared dynamically so they need a clear wrapper */
> > +#define __XFS_HAS_REMOVEFEAT(name, NAME) \
> > +	__XFS_HAS_ADDFEAT(name, NAME); \
> > +static inline void xfs_feat_remove_ ## name (struct xfs_mount *mp) \
> > +{ \
> > +	mp->m_features &= ~XFS_FEAT_ ## NAME; \
> > +	xfs_sb_version_remove ## name(&mp->m_sb); \
> > +}
> > +
> 
> In addition to the above, we use HAS_FEAT for an underlying xfs_has_
> (i.e., no "feat") helper above, yet for some reason also use the HAS for
> the underlying xfs_feat_add/remove() helpers that don't use the "has"
> wording. On top of that, HAS_ADD implies HAS and HAS_REMOVE implies
> HAS_ADD, which isn't really clear from the naming.

I'll remove the HAS from them - that was just a side effect of a
quick copy-n-paste.

> I think this would all be much clearer if we defined something like the
> following:
> 
> 	__XFS_FEAT -> xfs_feat_*
> 	__XFS_FEAT_ADD -> xfs_feat_add_*
> 	__XFS_FEAT_REMOVE -> xfs_feat_remove_*

Adding and removing features dynamically is the exception rather
than the common case. I want the common case to be simple and easy,
and I'd much prefer we special case the implementation of the rare,
unusual corner cases rather than make the common case more complex.

> ... for the individual helpers (i.e., no implicit dependencies) and then
> just open-coded the appropriate calls in the list below. Alternatively,
> we could create another set of macros like
> XFS_FEAT_[FIXED|ADDONLY|ADDRM]() for the particular combinations that we
> happen to use today. Either way would make it self-evident from the list
> itself what helpers are defined without having to dig into all of the
> macros.

I'll rename the constructor macros so it's clearer.

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

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

* Re: [PATCH 03/10] xfs: consolidate mount option features in m_features
  2018-08-21 13:21   ` Brian Foster
@ 2018-08-21 23:32     ` Dave Chinner
  0 siblings, 0 replies; 27+ messages in thread
From: Dave Chinner @ 2018-08-21 23:32 UTC (permalink / raw)
  To: Brian Foster; +Cc: linux-xfs

On Tue, Aug 21, 2018 at 09:21:53AM -0400, Brian Foster wrote:
> On Mon, Aug 20, 2018 at 02:48:44PM +1000, Dave Chinner wrote:
> > From: Dave Chinner <dchinner@redhat.com>
> > 
> > This provides separation of mount time feature flags from runtime
> > mount flagsi and mount option state. It also makes the feature
> 
> s/flagsi/flags/
> 
> > checks use the same interface as the superblock features. i.e. we
> > don't care if the feature is enabled by superblock flags or mount
> > options, we just care if it's enabled or not.
> > 
> > Signed-off-by: Dave Chinner <dchinner@redhat.com>
> > ---
> >  fs/xfs/xfs_mount.h | 36 ++++++++++++++++++++++++++++++++++++
> >  1 file changed, 36 insertions(+)
> > 
> > diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
> > index 92d947f17c69..74a128fe316b 100644
> > --- a/fs/xfs/xfs_mount.h
> > +++ b/fs/xfs/xfs_mount.h
> > @@ -225,6 +225,21 @@ typedef struct xfs_mount {
> >  #define XFS_FEAT_META_UUID	(1ULL << 20)	/* metadata UUID */
> >  #define XFS_FEAT_REALTIME	(1ULL << 21)	/* realtime device present */
> >  
> > +#define XFS_FEAT_WSYNC		(1ULL << 22)	/* synchronous metadata ops */
> > +#define XFS_FEAT_DIRSYNC	(1ULL << 23)	/* synchronous directory ops */
> > +#define XFS_FEAT_DISCARD	(1ULL << 24)	/* discard unused blocks */
> > +#define XFS_FEAT_GRPID		(1ULL << 25)	/* group-ID assigned from directory */
> > +#define XFS_FEAT_SMALL_INUMS	(1ULL << 26)	/* user wants 32bit inodes */
> > +#define XFS_FEAT_IKEEP		(1ULL << 27)	/* keep empty inode clusters*/
> > +#define XFS_FEAT_SWALLOC	(1ULL << 28)	/* stripe width allocation */
> > +#define XFS_FEAT_FILESTREAMS	(1ULL << 29)	/* enable the filestreams
> > +						   allocator */
> > +#define XFS_FEAT_DAX		(1ULL << 30)	/* TEST ONLY! */
> > +#define XFS_FEAT_COMPAT_IOSIZE	(1ULL << 31)	/* don't report large preferred
> > +						 * I/O size in stat() */
> > +#define XFS_FEAT_NORECOVERY	(1ULL << 32)	/* no recovery - dirty fs */
> > +#define XFS_FEAT_NOUUID		(1ULL << 33)	/* ignore uuid during mount */
> 
> Similar indentation issue here..? Otherwise looks fine modulo the
> previous comments on the broader API.

That's just the diff changing layout of tabs because everything is
indented one space.

Cheers,

Dave.

-- 
Dave Chinner
david@fromorbit.com

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

* Re: [PATCH 04/10] xfs: convert mount flags to features
  2018-08-21 13:22   ` Brian Foster
@ 2018-08-21 23:36     ` Dave Chinner
  0 siblings, 0 replies; 27+ messages in thread
From: Dave Chinner @ 2018-08-21 23:36 UTC (permalink / raw)
  To: Brian Foster; +Cc: linux-xfs

On Tue, Aug 21, 2018 at 09:22:04AM -0400, Brian Foster wrote:
> On Mon, Aug 20, 2018 at 02:48:45PM +1000, Dave Chinner wrote:
> > From: Dave Chinner <dchinner@redhat.com>
> > 
> > Replace m_flags feature checks with xfs_has_<feature>() calls and
> > rework the setup code to set flags in m_features.
> > 
> > Fallout is that there are some attr2/noattr2 changes - there's no
> > longer separate feature flags for the attr2 superblock and attr2
> > mount options - they both set the same flag. Hence we use the
> > noattr2 feature to trigger turning off attr2 at mount time - it
> > doesn't matter if it is the mount option or the sb feature that set
> > it, specifying noattr2 will turn off attr2 for the current mount and
> > clear it from the sb feature set.
> > 
> > [Discuss: Might be worth moving the attr2 changes into a separate
> > patch so it's clear what changes are being made.]
> > 
> 
> Yeah, a separate patch to condense the attr bits might be a good idea.

ok.

> It also looks like some iosize feature changes crept in here that should
> have been in a previous patch..?

No change, just a small reformats of the logic to use
common stacked if/else if/else rather than nested if/ternary
constructs. I can split it into another patch if you really want.

-Dave.
-- 
Dave Chinner
david@fromorbit.com

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

* Re: [PATCH 08/10] xfs: open code sb verifier feature checks
  2018-08-21 13:01   ` Jan Tulak
@ 2018-08-21 23:43     ` Dave Chinner
  0 siblings, 0 replies; 27+ messages in thread
From: Dave Chinner @ 2018-08-21 23:43 UTC (permalink / raw)
  To: Jan Tulak; +Cc: linux-xfs

On Tue, Aug 21, 2018 at 03:01:21PM +0200, Jan Tulak wrote:
> On Mon, Aug 20, 2018 at 6:49 AM Dave Chinner <david@fromorbit.com> wrote:
> >
> > From: Dave Chinner <dchinner@redhat.com>
> >
> > The superblock verifiers are one of the last places that use the sb
> > version functions to do feature checks. This are all quite simple
> > uses, and there aren't many of them so open code them all.
> >
> > Also, move the good version number check into xfs_sb.c instead of it
> > being an inline function in xfs_format.h
> >
> > Signed-off-by: Dave Chinner <dchinner@redhat.com>
> > ---
> >  fs/xfs/libxfs/xfs_format.h |  26 ---------
> >  fs/xfs/libxfs/xfs_sb.c     | 116 +++++++++++++++++++++++++------------
> >  fs/xfs/libxfs/xfs_sb.h     |   1 +
> >  3 files changed, 81 insertions(+), 62 deletions(-)
> >
> > diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
> > index e21c39b13890..1f1107892dcd 100644
> > --- a/fs/xfs/libxfs/xfs_format.h
> > +++ b/fs/xfs/libxfs/xfs_format.h
> > @@ -280,32 +280,6 @@ typedef struct xfs_dsb {
> >
> >  #define        XFS_SB_VERSION_NUM(sbp) ((sbp)->sb_versionnum & XFS_SB_VERSION_NUMBITS)
> >
> > -/*
> > - * The first XFS version we support is a v4 superblock with V2 directories.
> > - */
> > -static inline bool xfs_sb_good_v4_features(struct xfs_sb *sbp)
> > -{
> > -       if (!(sbp->sb_versionnum & XFS_SB_VERSION_DIRV2BIT))
> > -               return false;
> > -
> > -       /* check for unknown features in the fs */
> > -       if ((sbp->sb_versionnum & ~XFS_SB_VERSION_OKBITS) ||
> > -           ((sbp->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT) &&
> > -            (sbp->sb_features2 & ~XFS_SB_VERSION2_OKBITS)))
> > -               return false;
> > -
> > -       return true;
> > -}
> > -
> > -static inline bool xfs_sb_good_version(struct xfs_sb *sbp)
> > -{
> > -       if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5)
> > -               return true;
> > -       if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4)
> > -               return xfs_sb_good_v4_features(sbp);
> > -       return false;
> > -}
> > -
> 
> As I understand this removed code, if, in the future, we would have
> e.g. superblock v6, then xfs_sb_good_version would return false,
> right?

Yes, which is correct because this kernel does not support v6
superblock filesystems.

> Which I think is not correctly replicated in the new function
> below.
> 
> >  static inline bool xfs_sb_version_hasrealtime(struct xfs_sb *sbp)
> >  {
> >         return sbp->sb_rblocks > 0;
> > diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c
> > index bedf6c6bf990..b83cf8adca1a 100644
> > --- a/fs/xfs/libxfs/xfs_sb.c
> > +++ b/fs/xfs/libxfs/xfs_sb.c
> > @@ -96,6 +96,35 @@ xfs_perag_put(
> >         trace_xfs_perag_put(pag->pag_mount, pag->pag_agno, ref, _RET_IP_);
> >  }
> >
> > +/*
> > + * We support all XFS versions newer than a v4 superblock with V2 directories.
> > + */
> > +bool
> > +xfs_sb_good_version(
> > +       struct xfs_sb   *sbp)
> > +{
> > +       /* all v5 filesystems are supported */
> > +       if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5)
> > +               return true;
> > +
> > +       /* versions prior to v4 are not supported */
> > +       if (XFS_SB_VERSION_NUM(sbp) < XFS_SB_VERSION_4)
> > +               return false;
> > +
> > +       /* V4 filesystems need v2 directories */
> > +       if (!(sbp->sb_versionnum & XFS_SB_VERSION_DIRV2BIT))
> > +               return false;
> > +
> > +       /* And must not have any unknown v4 feature bits set */
> > +       if ((sbp->sb_versionnum & ~XFS_SB_VERSION_OKBITS) ||
> > +           ((sbp->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT) &&
> > +            (sbp->sb_features2 & ~XFS_SB_VERSION2_OKBITS)))
> > +               return false;
> > +
> > +       /* It's a supported v4 filesystem */
> > +       return true;
> > +}
> > +
> 
> If we call this xfs_sb_good_version() with superblock v6 or higher, it
> returns true too, not only for a supported v4. Unless the V4 specific
> checks (v2 directories and feature bits) somehow implicitly prevents
> that from happening, which is something I can't tell. :-)

Well, the unsupported v4 feature bits would catch it (like the
unsupported CRC V4 feature bit we set on v5 filesystems to ensure
pre-v5 sb kernels will reject it based on unsupported v4
functionality).

Regardless, I'll change it to explicitly check for supported
versions so (i.e. the num < v4 check becomes != v4).

Cheers,

Dave.

> 
> Cheers,
> Jan
> 
> -- 
> Jan Tulak
> jtulak@redhat.com / jan@tulak.me
> 

-- 
Dave Chinner
david@fromorbit.com

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

* Re: [PATCH 08/10] xfs: open code sb verifier feature checks
  2018-08-21 13:25   ` Brian Foster
@ 2018-08-21 23:43     ` Dave Chinner
  0 siblings, 0 replies; 27+ messages in thread
From: Dave Chinner @ 2018-08-21 23:43 UTC (permalink / raw)
  To: Brian Foster; +Cc: linux-xfs

On Tue, Aug 21, 2018 at 09:25:35AM -0400, Brian Foster wrote:
> On Mon, Aug 20, 2018 at 02:48:49PM +1000, Dave Chinner wrote:
> > From: Dave Chinner <dchinner@redhat.com>
> > 
> > The superblock verifiers are one of the last places that use the sb
> > version functions to do feature checks. This are all quite simple
> > uses, and there aren't many of them so open code them all.
> > 
> > Also, move the good version number check into xfs_sb.c instead of it
> > being an inline function in xfs_format.h
> > 
> > Signed-off-by: Dave Chinner <dchinner@redhat.com>
> > ---
> >  fs/xfs/libxfs/xfs_format.h |  26 ---------
> >  fs/xfs/libxfs/xfs_sb.c     | 116 +++++++++++++++++++++++++------------
> >  fs/xfs/libxfs/xfs_sb.h     |   1 +
> >  3 files changed, 81 insertions(+), 62 deletions(-)
> > 
> ...
> > diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c
> > index bedf6c6bf990..b83cf8adca1a 100644
> > --- a/fs/xfs/libxfs/xfs_sb.c
> > +++ b/fs/xfs/libxfs/xfs_sb.c
> ...
> > @@ -485,7 +523,7 @@ xfs_sb_quota_from_disk(struct xfs_sb *sbp)
> >  	 * We need to do these manipilations only if we are working
> >  	 * with an older version of on-disk superblock.
> >  	 */
> > -	if (xfs_sb_version_haspquotino(sbp))
> > +	if (XFS_SB_VERSION_NUM(sbp) < XFS_SB_VERSION_5)
> >  		return;
> 
> Isn't this backwards (we want to exit if == XFS_SB_VERSION_5)?

Good catch, will fix.

-Dave.
-- 
Dave Chinner
david@fromorbit.com

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

* Re: [PATCH 01/10] xfs: reflect sb features in xfs_mount
  2018-08-21 23:31     ` Dave Chinner
@ 2018-08-22 12:17       ` Brian Foster
  2018-08-22 23:59         ` Dave Chinner
  0 siblings, 1 reply; 27+ messages in thread
From: Brian Foster @ 2018-08-22 12:17 UTC (permalink / raw)
  To: Dave Chinner; +Cc: linux-xfs

On Wed, Aug 22, 2018 at 09:31:33AM +1000, Dave Chinner wrote:
> On Tue, Aug 21, 2018 at 09:21:40AM -0400, Brian Foster wrote:
> > On Mon, Aug 20, 2018 at 02:48:42PM +1000, Dave Chinner wrote:
> > > From: Dave Chinner <dchinner@redhat.com>
> > > 
> > > Currently on-disk feature checks require decoding the superblock
> > > fileds and so can be non-trivial. We have almost 400 hundred
> > > individual feature checks in the XFS code, so this is a significant
> > > amount of code. To reduce runtime check overhead, pre-process all
> > > the version flags into a features field in the xfs_mount at mount
> > > time so we can convert all the feature checks to a simple flag
> > > check.
> > > 
> > > There is also a need to convert the dynamic feature flags to update
> > > the m_features field. This is required for attr, attr2 and quota
> > > features. New xfs_mount based wrappers are added for this.
> > > 
> > > Before:
> > > 
> > > $ size -t fs/xfs/built-in.a
> > >    text	   data	    bss	    dec	    hex	filename
> > > ....
> > > 1294873	 182766	   1036	1478675	 169013	(TOTALS
> > > 
> > 
> > Was some text truncated from the commit log description here? Did you
> > mean to include the after size as well?
> 
> Yeah, I thought I did update that. Maybe forgot to refresh the
> header once I did. The before and after are:
> 
> 	text	   data	    bss	    dec	    hex	filename
> before	1326155	 189006	   1036	1516197	 1722a5	(TOTALS)
> after	1322929	 189006	   1036	1512971	 17160b	(TOTALS)
> 

That's a much larger delta than what I saw when I checked out of
curiousity, but I just ran against this first patch. It looks like this
delta is before/after the whole series. It might be good to qualify that
in the commit log (i.e., "after the old xfs_sb_version_* wrappers are
removed") just because the series context isn't always clear in the
broader git log history.

> > > Signed-off-by: Dave Chinner <dchinner@redhat.com>
> > > ---
> > >  fs/xfs/libxfs/xfs_format.h |  2 +-
> > >  fs/xfs/libxfs/xfs_sb.c     | 61 +++++++++++++++++++++++++++++
> > >  fs/xfs/libxfs/xfs_sb.h     |  1 +
> > >  fs/xfs/xfs_log_recover.c   |  1 +
> > >  fs/xfs/xfs_mount.c         |  1 +
> > >  fs/xfs/xfs_mount.h         | 79 ++++++++++++++++++++++++++++++++++++++
> > >  6 files changed, 144 insertions(+), 1 deletion(-)
> > > 
> > ...
> > > diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
> > > index a21dc61ec09e..5d0438ec07dd 100644
> > > --- a/fs/xfs/xfs_log_recover.c
> > > +++ b/fs/xfs/xfs_log_recover.c
> > > @@ -5723,6 +5723,7 @@ xlog_do_recover(
> > >  	xfs_buf_relse(bp);
> > >  
> > >  	/* re-initialise in-core superblock and geometry structures */
> > > +	mp->m_features |= xfs_sb_version_to_features(sbp);
> > 
> > How is this a reinit if it ORs in fields?
> 
> The only feature bit that can be removed by log recovery is the
> attr2 feature bit which means the last mount was mounted with
> "noattr2". So apart from that feature bit, ORing in the new
> superblock feature mask works just fine.
> 

To be clear.. that's because attr2 is the only feature that can be
currently unset at runtime, right?

> As it is, for v5 attr2 can't be turned off, so it's just fine for
> v5 filesystems. For v4 the old code would set XFS_MOUNT_ATTR2 if the
> sb feature bit was set /prior/ to log recovery being run. Hence if
> log recovery removed the feature bit, the very next attr creation
> will turn it straight back on.
> 
> The only way to not have attr2 enabled in this case is to use the
> noattr2 mount option, and the new code has exactly the same
> behaviour - the attr2 superblock bit and the feature flag will get
> cleared after log recovery if the noattr2 mount option is set.
> 
> Also worth noting is that if there's a sb_bad_features2
> interatction, it will re-add the feature bit because it just ORs the
> two fields together.
> 
> IOWs, the behaviour of this patch is roughly the same as the
> existing code when it comes to the attr2 flag being removed when the
> superblock is recovered as well as when there is a features2
> mismatch.
> 

Ok, but this all sounds like a happy coincidence that depends on the
semantics of attr2. IOW, the behavior of attr2 may ultimately be the
same (which I haven't fully grokked), but unless I'm missing something
more fundamental the logic in this patch still seems slightly dynamic
feature challenged in this regard.

Mount a filesystem with some feature enabled, disable it and crash with
the superblock change in the dirty log. Mount again, enable said feature
based on sb, log recovery updates sb, feature remains inconsistently
enabled due to not being cleared by the post-recovery feature init.
Unless I'm missing something, this is handled correctly by the existing
mechanism simply because each feature check refers to the superblock.

> I think there's more work needed on the attr2 feature side of
> things, as noted in the cover description. In addition to the
> unpredictable behaviour via log recovery, I don't see a reason for
> noattr2 existing these days. It doesn't get rid of existing attr2
> format inodes on disk - it just stops new ones from being created.
> We've used attr2 for more than 10 years now without it being an
> issue, so there's no reason for needing to turn it off anymore. I
> think we should deprecate the option and remove it.
> 
> > I guess I'm curious why we OR
> > in fields in either case as opposed to using an assignment.
> 
> Because mount option features are already set in m_features, so we
> can't just overwrite it with just the superblock features.
> 

That doesn't appear to be the case as of this patch. If it's a factor
later in the series, we should tweak it then where the intent is clear.

This also doesn't strike me as a technically difficult problem to
address. We just need to filter out the set of superblock based features
one way or another. If you wanted to simplify it further, we could just
have the sb -> features function update ->m_features itself in a safe
manner (i.e., the subset of features it is responsible for) and then the
caller context doesn't really have to be concerned with such details.

> > 
> > >  	xfs_reinit_percpu_counters(mp);
> > >  	error = xfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi);
> > >  	if (error) {
> > ...
> > > diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
> > > index 7964513c3128..92d947f17c69 100644
> > > --- a/fs/xfs/xfs_mount.h
> > > +++ b/fs/xfs/xfs_mount.h
> > > @@ -127,6 +127,7 @@ typedef struct xfs_mount {
> > >  	struct mutex		m_growlock;	/* growfs mutex */
> > >  	int			m_fixedfsid[2];	/* unchanged for life of FS */
> > >  	uint64_t		m_flags;	/* global mount flags */
> > > +	uint64_t		m_features;	/* active filesystem features */
> > >  	bool			m_inotbt_nores; /* no per-AG finobt resv. */
> > >  	int			m_ialloc_inos;	/* inodes in inode allocation */
> > >  	int			m_ialloc_blks;	/* blocks in inode allocation */
> > > @@ -195,6 +196,84 @@ typedef struct xfs_mount {
> > >  #endif
> > >  } xfs_mount_t;
> > >  
> > > +/*
> > > + * Flags for m_features.
> > > + *
> > > + * These are all the active features in the filesystem, regardless of how
> > > + * they are configured.

Given the point above around mount options, I think the comment above
would be more helpful if it said something like:

"These are all the active features in the filesystem. Some are
configured based on superblock version, others are based on mount
options."

> > > + */
> > > +#define	XFS_FEAT_ATTR		(1ULL << 0)	/* xattrs present in fs */
> > > +#define	XFS_FEAT_NLINK		(1ULL << 1)	/* 32 bit link counts */
> > > +#define	XFS_FEAT_QUOTA		(1ULL << 2)	/* quota active */
> > > +#define	XFS_FEAT_ALIGN		(1ULL << 3)	/* inode alignment */
> > > +#define	XFS_FEAT_DALIGN		(1ULL << 4)	/* data alignment */
> > > +#define XFS_FEAT_LOGV2		(1ULL << 5)	/* version 2 logs */
> > > +#define XFS_FEAT_SECTOR		(1ULL << 6)	/* sector size > 512 bytes */
> > > +#define	XFS_FEAT_EXTFLG		(1ULL << 7)	/* unwritten extents */
> > > +#define	XFS_FEAT_ASCIICI	(1ULL << 8)	/* ASCII only case-insens. */
> > > +#define XFS_FEAT_LAZYSBCOUNT	(1ULL << 9)	/* Superblk counters */
> > > +#define XFS_FEAT_ATTR2		(1ULL << 10)	/* dynamic attr fork */
> > > +#define XFS_FEAT_PARENT		(1ULL << 11)	/* parent pointers */
> > 
> > Hmm, none of the parent pointer stuff has been merged yet, has it? If
> > not, I'm sure it will be at some point, but I'd prefer not to include
> > code for features that technically don't exist.
> 
> We already have the parent point feature bit declared and this is a
> direct translation of the superblock feature bits. If it's unused,
> then the compiler elides the xfs_has_parent() check function,
> otherwise it's just a flag...
> 

Ok, I just wasn't aware it was already defined.

> > Otherwise it looks like we have some inconsistent spacing/indentation.
> 
> Inherited from the superblock feature bit definitions. I'll clean it
> up.
> 
> > 
> > > +#define XFS_FEAT_PROJID32	(1ULL << 12)	/* 32 bit project id */
> > > +#define XFS_FEAT_CRC		(1ULL << 13)	/* metadata CRCs */
> > > +#define XFS_FEAT_PQUOTINO	(1ULL << 14)	/* non-shared proj/grp quotas */
> > > +#define XFS_FEAT_FTYPE		(1ULL << 15)	/* inode type in dir */
> > > +#define XFS_FEAT_FINOBT		(1ULL << 16)	/* free inode btree */
> > > +#define XFS_FEAT_RMAPBT		(1ULL << 17)	/* reverse map btree */
> > > +#define XFS_FEAT_REFLINK	(1ULL << 18)	/* reflinked files */
> > > +#define XFS_FEAT_SPINODES	(1ULL << 19)	/* sparse inode chunks */
> > > +#define XFS_FEAT_META_UUID	(1ULL << 20)	/* metadata UUID */
> > > +#define XFS_FEAT_REALTIME	(1ULL << 21)	/* realtime device present */
> > > +
> > > +#define __XFS_HAS_FEAT(name, NAME) \
> > > +static inline bool xfs_has_ ## name (struct xfs_mount *mp) \
> > > +{ \
> > 
> > I'm assuming these xfs_has_*() calls will end up replacing the current
> > xfs_sb_version_has*() calls throughout the code. Could we start using a
> 
> Yes.
> 
> > consistent function name prefix across the helpers? E.g., I think using
> > 'xfs_feat_ ## name' here (instead of xfs_has_) would be fine, and
> > consistent with the other helpers.
> 
> I'd prefer to drop the _feat_ prefix for the couple of add/remove
> wrappers that exist, not add it to every feature check.
> 
> > I don't want to get into bikeshedding too much but tbh I've always found
> > the xfs_sb_has_* thing kind of weird where the "has" text seems
> > superfluous. It's just not been worth changing. It would be nice if we
> > could stop propagating it here and define a consistently used prefix.
> 
> Yet we use "is" all over the place when checking if an object is
> <something> (e.g. xfs_btree_ptr_is_null(), xfs_iext_rec_is_empty(),
> xfs_rmap_is_mergeable(), etc) because it makes the code more
> readable. The old sbversion namespace format is the problem, not the
> use of "has" to indicate we are checking if the filesystem has a
> feature...
> 

Each of the examples you cited above have widely used function name
prefixes. There's a reason they are named as they are and not as
xfs_is_empty_iext_rec(), for example. That's what I'm asking for here.
I don't fundamentally object to the fact that we use "has" or "is." I'm
merely pointing out that I think "has" is superfluous with respect to a
properly used function prefix and therefore we could replace it with the
prefix used by the other related helpers, restoring consistency without
sacrificing readability.

IOW, if you wanted to rename these to something like
xfs_feat_crc_enablement_it_has(mp), that wouldn't exactly be my
preference...  but I won't object if we can address the function prefix
thing. ;P

> I omitted the "_feat_" part of the name because it's effectively
> redundant when you read it. i.e. if (xfs_has_pquotaino(mp)) reads as
> a well composed sentence: "if XFS has project quotas inodes on this
> mount". Doing s/has/feature/ does not improve the readbility of the
> code, just makes it unnecessarily verbose.
> 

Eh, I don't think anybody is going to be confused by
xfs_has_pquotaino(mp) vs. xfs_feat_pquotaino(mp). Either way is
self-descriptive and obvious IMO. As noted, I'm not really looking to
bikeshed over the most clear way to say "if this feature is enabled" in
a function name. I'd just prefer to use the associated function prefix
as we do most everywhere else.

> 
> 
> 
> > > +	return mp->m_features & XFS_FEAT_ ## NAME; \
> > > +}
> > > +
> > > +/* Some features can be added dynamically so they need a set wrapper, too. */
> > > +#define __XFS_HAS_ADDFEAT(name, NAME) \
> > > +	__XFS_HAS_FEAT(name, NAME); \
> > > +static inline void xfs_feat_add_ ## name (struct xfs_mount *mp) \
> > > +{ \
> > > +	mp->m_features |= XFS_FEAT_ ## NAME; \
> > > +	xfs_sb_version_add ## name(&mp->m_sb); \
> > > +}
> > > +
> > > +/* Some features can be cleared dynamically so they need a clear wrapper */
> > > +#define __XFS_HAS_REMOVEFEAT(name, NAME) \
> > > +	__XFS_HAS_ADDFEAT(name, NAME); \
> > > +static inline void xfs_feat_remove_ ## name (struct xfs_mount *mp) \
> > > +{ \
> > > +	mp->m_features &= ~XFS_FEAT_ ## NAME; \
> > > +	xfs_sb_version_remove ## name(&mp->m_sb); \
> > > +}
> > > +
> > 
> > In addition to the above, we use HAS_FEAT for an underlying xfs_has_
> > (i.e., no "feat") helper above, yet for some reason also use the HAS for
> > the underlying xfs_feat_add/remove() helpers that don't use the "has"
> > wording. On top of that, HAS_ADD implies HAS and HAS_REMOVE implies
> > HAS_ADD, which isn't really clear from the naming.
> 
> I'll remove the HAS from them - that was just a side effect of a
> quick copy-n-paste.
> 
> > I think this would all be much clearer if we defined something like the
> > following:
> > 
> > 	__XFS_FEAT -> xfs_feat_*
> > 	__XFS_FEAT_ADD -> xfs_feat_add_*
> > 	__XFS_FEAT_REMOVE -> xfs_feat_remove_*
> 
> Adding and removing features dynamically is the exception rather
> than the common case. I want the common case to be simple and easy,
> and I'd much prefer we special case the implementation of the rare,
> unusual corner cases rather than make the common case more complex.
> 
> > ... for the individual helpers (i.e., no implicit dependencies) and then
> > just open-coded the appropriate calls in the list below. Alternatively,
> > we could create another set of macros like
> > XFS_FEAT_[FIXED|ADDONLY|ADDRM]() for the particular combinations that we
> > happen to use today. Either way would make it self-evident from the list
> > itself what helpers are defined without having to dig into all of the
> > macros.
> 
> I'll rename the constructor macros so it's clearer.
> 

Ok. All I'm really asking for is the ability to look at the list of
macros and know what's going on without having to dig into the
underlying implementation every time. If that can be accomplished with
more clear names, then that works too.

Brian

> Cheers,
> 
> Dave.
> -- 
> Dave Chinner
> david@fromorbit.com

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

* Re: [PATCH 01/10] xfs: reflect sb features in xfs_mount
  2018-08-22 12:17       ` Brian Foster
@ 2018-08-22 23:59         ` Dave Chinner
  2018-08-23 13:39           ` Brian Foster
  0 siblings, 1 reply; 27+ messages in thread
From: Dave Chinner @ 2018-08-22 23:59 UTC (permalink / raw)
  To: Brian Foster; +Cc: linux-xfs

On Wed, Aug 22, 2018 at 08:17:55AM -0400, Brian Foster wrote:
> On Wed, Aug 22, 2018 at 09:31:33AM +1000, Dave Chinner wrote:
> > On Tue, Aug 21, 2018 at 09:21:40AM -0400, Brian Foster wrote:
> > > On Mon, Aug 20, 2018 at 02:48:42PM +1000, Dave Chinner wrote:
> > > > From: Dave Chinner <dchinner@redhat.com>
> > > > 
> > > > Currently on-disk feature checks require decoding the superblock
> > > > fileds and so can be non-trivial. We have almost 400 hundred
> > > > individual feature checks in the XFS code, so this is a significant
> > > > amount of code. To reduce runtime check overhead, pre-process all
> > > > the version flags into a features field in the xfs_mount at mount
> > > > time so we can convert all the feature checks to a simple flag
> > > > check.
> > > > 
> > > > There is also a need to convert the dynamic feature flags to update
> > > > the m_features field. This is required for attr, attr2 and quota
> > > > features. New xfs_mount based wrappers are added for this.
> > > > 
> > > > Before:
> > > > 
> > > > $ size -t fs/xfs/built-in.a
> > > >    text	   data	    bss	    dec	    hex	filename
> > > > ....
> > > > 1294873	 182766	   1036	1478675	 169013	(TOTALS
> > > > 
> > > 
> > > Was some text truncated from the commit log description here? Did you
> > > mean to include the after size as well?
> > 
> > Yeah, I thought I did update that. Maybe forgot to refresh the
> > header once I did. The before and after are:
> > 
> > 	text	   data	    bss	    dec	    hex	filename
> > before	1326155	 189006	   1036	1516197	 1722a5	(TOTALS)
> > after	1322929	 189006	   1036	1512971	 17160b	(TOTALS)
> > 
> 
> That's a much larger delta than what I saw when I checked out of
> curiousity, but I just ran against this first patch. It looks like this
> delta is before/after the whole series.

Yeah, it is - I couldn't find the original numbers in the scrollback
history of the build machine terminal. However, ~90% of the reduction
it comes from the first patch (3kB vs 3.2kB for the entire series)

> It might be good to qualify that
> in the commit log (i.e., "after the old xfs_sb_version_* wrappers are
> removed") just because the series context isn't always clear in the
> broader git log history.

Yeah, I'll fix it up, put the right number in it.

> > > > Signed-off-by: Dave Chinner <dchinner@redhat.com>
> > > > ---
> > > >  fs/xfs/libxfs/xfs_format.h |  2 +-
> > > >  fs/xfs/libxfs/xfs_sb.c     | 61 +++++++++++++++++++++++++++++
> > > >  fs/xfs/libxfs/xfs_sb.h     |  1 +
> > > >  fs/xfs/xfs_log_recover.c   |  1 +
> > > >  fs/xfs/xfs_mount.c         |  1 +
> > > >  fs/xfs/xfs_mount.h         | 79 ++++++++++++++++++++++++++++++++++++++
> > > >  6 files changed, 144 insertions(+), 1 deletion(-)
> > > > 
> > > ...
> > > > diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
> > > > index a21dc61ec09e..5d0438ec07dd 100644
> > > > --- a/fs/xfs/xfs_log_recover.c
> > > > +++ b/fs/xfs/xfs_log_recover.c
> > > > @@ -5723,6 +5723,7 @@ xlog_do_recover(
> > > >  	xfs_buf_relse(bp);
> > > >  
> > > >  	/* re-initialise in-core superblock and geometry structures */
> > > > +	mp->m_features |= xfs_sb_version_to_features(sbp);
> > > 
> > > How is this a reinit if it ORs in fields?
> > 
> > The only feature bit that can be removed by log recovery is the
> > attr2 feature bit which means the last mount was mounted with
> > "noattr2". So apart from that feature bit, ORing in the new
> > superblock feature mask works just fine.
> > 
> 
> To be clear.. that's because attr2 is the only feature that can be
> currently unset at runtime, right?

Well, it's not really at runtime - it can only be cleared at mount
time before log recovery is run.  IMO, the attr2/noattr2 mount
option stuff really just needs to go away.

> > As it is, for v5 attr2 can't be turned off, so it's just fine for
> > v5 filesystems. For v4 the old code would set XFS_MOUNT_ATTR2 if the
> > sb feature bit was set /prior/ to log recovery being run. Hence if
> > log recovery removed the feature bit, the very next attr creation
> > will turn it straight back on.
> > 
> > The only way to not have attr2 enabled in this case is to use the
> > noattr2 mount option, and the new code has exactly the same
> > behaviour - the attr2 superblock bit and the feature flag will get
> > cleared after log recovery if the noattr2 mount option is set.
> > 
> > Also worth noting is that if there's a sb_bad_features2
> > interatction, it will re-add the feature bit because it just ORs the
> > two fields together.
> > 
> > IOWs, the behaviour of this patch is roughly the same as the
> > existing code when it comes to the attr2 flag being removed when the
> > superblock is recovered as well as when there is a features2
> > mismatch.
> > 
> 
> Ok, but this all sounds like a happy coincidence that depends on the
> semantics of attr2. IOW, the behavior of attr2 may ultimately be the
> same (which I haven't fully grokked), but unless I'm missing something
> more fundamental the logic in this patch still seems slightly dynamic
> feature challenged in this regard.
> 
> Mount a filesystem with some feature enabled, disable it and crash with
> the superblock change in the dirty log. Mount again, enable said feature
> based on sb, log recovery updates sb, feature remains inconsistently
> enabled due to not being cleared by the post-recovery feature init.
> Unless I'm missing something, this is handled correctly by the existing
> mechanism simply because each feature check refers to the superblock.

The only way to disable it is via the noattr2 mount option. So to
have the above occur, you've have to first mount with noattr2, crash
after mount has logged the superblock (which happens after
recovery), then mount again *without* the noattr2 mount option set.

IOWs, the XFS_MOUNT_ATTR2 flag in this case is set during
xfs_finish_flags() (i.e. mount option parsing) because the
unrecovered superblock has the feature flag set and
XFS_MOUNT_NOATTR2 is not set. All future decisions about whether to
create attr2 format forks are based on XFS_MOUNT_ATTR2, not the
superblock feature bit. If log recovery clears the sb feature bit,
then the next attribute fork creation will see XFS_MOUNT_ATTR2 set
and re-add the superblock bit.

IOWs, in the crash+recover case of attr2 sb feature bit removal, the
code I wrote does the same thing as the existing code - you need to
use the noattr2 mount option to guarantee that attr2 is not used.

IMO, this is legacy code (attr2 is permanently enabled for v5) that
has nasty warts. While the noattr2 mount option was introduced right
at the start in 2005, it didn't remove the superblock feature bit
until more than 3 years later because the sb feature bit processing
got moved by the sb_bad_features2 debacle and that broke noattr2. SO
instead of just looking at the noattr2 mount option again, it was
decided to clear the feature bit from the superblock. This is
despite the fact there are still attr2 format inode forks on disk.

i.e. the removal of the attr2 sb feature bit breaks all the
conventions we have for "sb feature bit indicates a specific on disk
format feature is present in the fs". The original noattr2 code did
not have this problem, and as such I think we should be reverting to
the original behaviour of the noattr2 mount option and stop trying
to screw with the on-disk sb flag once it is set because of the
above can of worms it opened.

I think I'll rework the attr2 code as the initial patch in this
series now, and get rid of the sb feature bit removal code
altogether so this whole problem goes away.

> > I think there's more work needed on the attr2 feature side of
> > things, as noted in the cover description. In addition to the
> > unpredictable behaviour via log recovery, I don't see a reason for
> > noattr2 existing these days. It doesn't get rid of existing attr2
> > format inodes on disk - it just stops new ones from being created.
> > We've used attr2 for more than 10 years now without it being an
> > issue, so there's no reason for needing to turn it off anymore. I
> > think we should deprecate the option and remove it.
> > 
> > > I guess I'm curious why we OR
> > > in fields in either case as opposed to using an assignment.
> > 
> > Because mount option features are already set in m_features, so we
> > can't just overwrite it with just the superblock features.
> 
> That doesn't appear to be the case as of this patch. If it's a factor
> later in the series, we should tweak it then where the intent is clear.

Patches don't exist in isolation. Please look at the work as a
whole, not just patches in isolation.

> This also doesn't strike me as a technically difficult problem to
> address. We just need to filter out the set of superblock based features
> one way or another. If you wanted to simplify it further, we could just
> have the sb -> features function update ->m_features itself in a safe
> manner (i.e., the subset of features it is responsible for) and then the
> caller context doesn't really have to be concerned with such details.

We shouldn't be clearing superblock feature bits while there are
still those features on disk. Only attr2 does this, and as per
above, it's broken. I'm going to remove the code that removes the
attr2 feature bit in the next round of the patch, and then this
whole problem goes away.

> 
> > > 
> > > >  	xfs_reinit_percpu_counters(mp);
> > > >  	error = xfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi);
> > > >  	if (error) {
> > > ...
> > > > diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
> > > > index 7964513c3128..92d947f17c69 100644
> > > > --- a/fs/xfs/xfs_mount.h
> > > > +++ b/fs/xfs/xfs_mount.h
> > > > @@ -127,6 +127,7 @@ typedef struct xfs_mount {
> > > >  	struct mutex		m_growlock;	/* growfs mutex */
> > > >  	int			m_fixedfsid[2];	/* unchanged for life of FS */
> > > >  	uint64_t		m_flags;	/* global mount flags */
> > > > +	uint64_t		m_features;	/* active filesystem features */
> > > >  	bool			m_inotbt_nores; /* no per-AG finobt resv. */
> > > >  	int			m_ialloc_inos;	/* inodes in inode allocation */
> > > >  	int			m_ialloc_blks;	/* blocks in inode allocation */
> > > > @@ -195,6 +196,84 @@ typedef struct xfs_mount {
> > > >  #endif
> > > >  } xfs_mount_t;
> > > >  
> > > > +/*
> > > > + * Flags for m_features.
> > > > + *
> > > > + * These are all the active features in the filesystem, regardless of how
> > > > + * they are configured.
> 
> Given the point above around mount options, I think the comment above
> would be more helpful if it said something like:
> 
> "These are all the active features in the filesystem. Some are
> configured based on superblock version, others are based on mount
> options."

Bigger picture: what about options we may set through, say, /proc,
/sys, ioctls, online repair, etc? I think that the the places and
ways we can set feature flags is only going to grow in future, and
hence I'd prefer to leave this as a generic comment that encompasses
everything rather than have it grow stale over time.

> > > I don't want to get into bikeshedding too much but tbh I've always found
> > > the xfs_sb_has_* thing kind of weird where the "has" text seems
> > > superfluous. It's just not been worth changing. It would be nice if we
> > > could stop propagating it here and define a consistently used prefix.
> > 
> > Yet we use "is" all over the place when checking if an object is
> > <something> (e.g. xfs_btree_ptr_is_null(), xfs_iext_rec_is_empty(),
> > xfs_rmap_is_mergeable(), etc) because it makes the code more
> > readable. The old sbversion namespace format is the problem, not the
> > use of "has" to indicate we are checking if the filesystem has a
> > feature...
> > 
> 
> Each of the examples you cited above have widely used function name
> prefixes.

The prefix indicates the subsystem the operation belongs to.

However, filesystem features are, well, belong in the global
context.  They span all subsystems, and are a property of the global
mount structure. IOWs, They don't have a single widely used
subsystem that can be used as a namespace prefix, and using
"feature" because "we must have a namespace prefix" turns all the
function names into tautologies.

Consider this: why is xfs_is_read_only(mp) an acceptible function
name for checking global filesystem state, but xfs_has_attr2(mp) is
not acceptible for checking global filesystem state?

> There's a reason they are named as they are and not as
> xfs_is_empty_iext_rec(), for example. That's what I'm asking for here.
> I don't fundamentally object to the fact that we use "has" or "is." I'm
> merely pointing out that I think "has" is superfluous with respect to a
> properly used function prefix and therefore we could replace it with the
> prefix used by the other related helpers, restoring consistency without
> sacrificing readability.
> 
> IOW, if you wanted to rename these to something like
> xfs_feat_crc_enablement_it_has(mp), that wouldn't exactly be my
> preference...  but I won't object if we can address the function prefix
> thing. ;P
> 
> > I omitted the "_feat_" part of the name because it's effectively
> > redundant when you read it. i.e. if (xfs_has_pquotaino(mp)) reads as
> > a well composed sentence: "if XFS has project quotas inodes on this
> > mount". Doing s/has/feature/ does not improve the readbility of the
> > code, just makes it unnecessarily verbose.
> > 
> 
> Eh, I don't think anybody is going to be confused by
> xfs_has_pquotaino(mp) vs. xfs_feat_pquotaino(mp). Either way is

I find it confusing. Is it checking if the feature is enabled? Is it
manipulating the feature in some way? Is it checking if we actually
have a project quota inode present on the xfs_mount? Or maybe
something else?

i.e. There's no action defined or implied by the function name and so
I can't tell what that function is doing without looking at it.
That's what "has" or "is" adds to the function name: a definitive
action. i.e.  it's not the namespace prefix that is meaningful here
- it's the action in the name ("has") that makes it obvious what the
function does.

> self-descriptive and obvious IMO. As noted, I'm not really looking to
> bikeshed over the most clear way to say "if this feature is enabled" in
> a function name. I'd just prefer to use the associated function prefix
> as we do most everywhere else.

And that's the issue I have here - we must do exactly what we've
done in the past, even though those rules are falling down around
us. Look at the mess this blind obedience to namespace rules got the
scrub code into; it was ending up an unreadable jumble of noise
because every structure and function had 25+ character namespace
prefixes you had to read on every line of code before you get to the
meaningful information.

Namespacing structures and functions have their place, but there is
such a thing as taking it too far. Stuff that is easily
understandable without verbose namespace prefixes should not have
verbose/redundant namespace prefixes. 

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

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

* Re: [PATCH 01/10] xfs: reflect sb features in xfs_mount
  2018-08-22 23:59         ` Dave Chinner
@ 2018-08-23 13:39           ` Brian Foster
  0 siblings, 0 replies; 27+ messages in thread
From: Brian Foster @ 2018-08-23 13:39 UTC (permalink / raw)
  To: Dave Chinner; +Cc: linux-xfs

On Thu, Aug 23, 2018 at 09:59:13AM +1000, Dave Chinner wrote:
> On Wed, Aug 22, 2018 at 08:17:55AM -0400, Brian Foster wrote:
> > On Wed, Aug 22, 2018 at 09:31:33AM +1000, Dave Chinner wrote:
> > > On Tue, Aug 21, 2018 at 09:21:40AM -0400, Brian Foster wrote:
> > > > On Mon, Aug 20, 2018 at 02:48:42PM +1000, Dave Chinner wrote:
> > > > > From: Dave Chinner <dchinner@redhat.com>
> > > > > 
> > > > > Currently on-disk feature checks require decoding the superblock
> > > > > fileds and so can be non-trivial. We have almost 400 hundred
> > > > > individual feature checks in the XFS code, so this is a significant
> > > > > amount of code. To reduce runtime check overhead, pre-process all
> > > > > the version flags into a features field in the xfs_mount at mount
> > > > > time so we can convert all the feature checks to a simple flag
> > > > > check.
> > > > > 
> > > > > There is also a need to convert the dynamic feature flags to update
> > > > > the m_features field. This is required for attr, attr2 and quota
> > > > > features. New xfs_mount based wrappers are added for this.
> > > > > 
> > > > > Before:
> > > > > 
> > > > > $ size -t fs/xfs/built-in.a
> > > > >    text	   data	    bss	    dec	    hex	filename
> > > > > ....
> > > > > 1294873	 182766	   1036	1478675	 169013	(TOTALS
> > > > > 
> > > > 
> > > > Was some text truncated from the commit log description here? Did you
> > > > mean to include the after size as well?
> > > 
> > > Yeah, I thought I did update that. Maybe forgot to refresh the
> > > header once I did. The before and after are:
> > > 
> > > 	text	   data	    bss	    dec	    hex	filename
> > > before	1326155	 189006	   1036	1516197	 1722a5	(TOTALS)
> > > after	1322929	 189006	   1036	1512971	 17160b	(TOTALS)
> > > 
> > 
> > That's a much larger delta than what I saw when I checked out of
> > curiousity, but I just ran against this first patch. It looks like this
> > delta is before/after the whole series.
> 
> Yeah, it is - I couldn't find the original numbers in the scrollback
> history of the build machine terminal. However, ~90% of the reduction
> it comes from the first patch (3kB vs 3.2kB for the entire series)
> 
> > It might be good to qualify that
> > in the commit log (i.e., "after the old xfs_sb_version_* wrappers are
> > removed") just because the series context isn't always clear in the
> > broader git log history.
> 
> Yeah, I'll fix it up, put the right number in it.
> 
> > > > > Signed-off-by: Dave Chinner <dchinner@redhat.com>
> > > > > ---
> > > > >  fs/xfs/libxfs/xfs_format.h |  2 +-
> > > > >  fs/xfs/libxfs/xfs_sb.c     | 61 +++++++++++++++++++++++++++++
> > > > >  fs/xfs/libxfs/xfs_sb.h     |  1 +
> > > > >  fs/xfs/xfs_log_recover.c   |  1 +
> > > > >  fs/xfs/xfs_mount.c         |  1 +
> > > > >  fs/xfs/xfs_mount.h         | 79 ++++++++++++++++++++++++++++++++++++++
> > > > >  6 files changed, 144 insertions(+), 1 deletion(-)
> > > > > 
> > > > ...
> > > > > diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
> > > > > index a21dc61ec09e..5d0438ec07dd 100644
> > > > > --- a/fs/xfs/xfs_log_recover.c
> > > > > +++ b/fs/xfs/xfs_log_recover.c
> > > > > @@ -5723,6 +5723,7 @@ xlog_do_recover(
> > > > >  	xfs_buf_relse(bp);
> > > > >  
> > > > >  	/* re-initialise in-core superblock and geometry structures */
> > > > > +	mp->m_features |= xfs_sb_version_to_features(sbp);
> > > > 
> > > > How is this a reinit if it ORs in fields?
> > > 
> > > The only feature bit that can be removed by log recovery is the
> > > attr2 feature bit which means the last mount was mounted with
> > > "noattr2". So apart from that feature bit, ORing in the new
> > > superblock feature mask works just fine.
> > > 
> > 
> > To be clear.. that's because attr2 is the only feature that can be
> > currently unset at runtime, right?
> 
> Well, it's not really at runtime - it can only be cleared at mount
> time before log recovery is run.  IMO, the attr2/noattr2 mount
> option stuff really just needs to go away.
> 
> > > As it is, for v5 attr2 can't be turned off, so it's just fine for
> > > v5 filesystems. For v4 the old code would set XFS_MOUNT_ATTR2 if the
> > > sb feature bit was set /prior/ to log recovery being run. Hence if
> > > log recovery removed the feature bit, the very next attr creation
> > > will turn it straight back on.
> > > 
> > > The only way to not have attr2 enabled in this case is to use the
> > > noattr2 mount option, and the new code has exactly the same
> > > behaviour - the attr2 superblock bit and the feature flag will get
> > > cleared after log recovery if the noattr2 mount option is set.
> > > 
> > > Also worth noting is that if there's a sb_bad_features2
> > > interatction, it will re-add the feature bit because it just ORs the
> > > two fields together.
> > > 
> > > IOWs, the behaviour of this patch is roughly the same as the
> > > existing code when it comes to the attr2 flag being removed when the
> > > superblock is recovered as well as when there is a features2
> > > mismatch.
> > > 
> > 
> > Ok, but this all sounds like a happy coincidence that depends on the
> > semantics of attr2. IOW, the behavior of attr2 may ultimately be the
> > same (which I haven't fully grokked), but unless I'm missing something
> > more fundamental the logic in this patch still seems slightly dynamic
> > feature challenged in this regard.
> > 
> > Mount a filesystem with some feature enabled, disable it and crash with
> > the superblock change in the dirty log. Mount again, enable said feature
> > based on sb, log recovery updates sb, feature remains inconsistently
> > enabled due to not being cleared by the post-recovery feature init.
> > Unless I'm missing something, this is handled correctly by the existing
> > mechanism simply because each feature check refers to the superblock.
> 
> The only way to disable it is via the noattr2 mount option. So to
> have the above occur, you've have to first mount with noattr2, crash
> after mount has logged the superblock (which happens after
> recovery), then mount again *without* the noattr2 mount option set.
> 
> IOWs, the XFS_MOUNT_ATTR2 flag in this case is set during
> xfs_finish_flags() (i.e. mount option parsing) because the
> unrecovered superblock has the feature flag set and
> XFS_MOUNT_NOATTR2 is not set. All future decisions about whether to
> create attr2 format forks are based on XFS_MOUNT_ATTR2, not the
> superblock feature bit. If log recovery clears the sb feature bit,
> then the next attribute fork creation will see XFS_MOUNT_ATTR2 set
> and re-add the superblock bit.
> 

Ok, I think I was confused as to how the existing feature bit worked. It
sounds like the bit is more driven by the mount option.

I still don't think that the mechanism should be susceptible to
inconsistency in general, even if it's not a real problem based on the
current usage (i.e., still a landmine). If the solution to that is to
drop the ability to dynamically remove a superblock feature, then it
sounds like that addresses the problem just as well. I'll wait and see
what the code looks like...

> IOWs, in the crash+recover case of attr2 sb feature bit removal, the
> code I wrote does the same thing as the existing code - you need to
> use the noattr2 mount option to guarantee that attr2 is not used.
> 
> IMO, this is legacy code (attr2 is permanently enabled for v5) that
> has nasty warts. While the noattr2 mount option was introduced right
> at the start in 2005, it didn't remove the superblock feature bit
> until more than 3 years later because the sb feature bit processing
> got moved by the sb_bad_features2 debacle and that broke noattr2. SO
> instead of just looking at the noattr2 mount option again, it was
> decided to clear the feature bit from the superblock. This is
> despite the fact there are still attr2 format inode forks on disk.
> 
> i.e. the removal of the attr2 sb feature bit breaks all the
> conventions we have for "sb feature bit indicates a specific on disk
> format feature is present in the fs". The original noattr2 code did
> not have this problem, and as such I think we should be reverting to
> the original behaviour of the noattr2 mount option and stop trying
> to screw with the on-disk sb flag once it is set because of the
> above can of worms it opened.
> 
> I think I'll rework the attr2 code as the initial patch in this
> series now, and get rid of the sb feature bit removal code
> altogether so this whole problem goes away.
> 

Ok.

> > > I think there's more work needed on the attr2 feature side of
> > > things, as noted in the cover description. In addition to the
> > > unpredictable behaviour via log recovery, I don't see a reason for
> > > noattr2 existing these days. It doesn't get rid of existing attr2
> > > format inodes on disk - it just stops new ones from being created.
> > > We've used attr2 for more than 10 years now without it being an
> > > issue, so there's no reason for needing to turn it off anymore. I
> > > think we should deprecate the option and remove it.
> > > 
> > > > I guess I'm curious why we OR
> > > > in fields in either case as opposed to using an assignment.
> > > 
> > > Because mount option features are already set in m_features, so we
> > > can't just overwrite it with just the superblock features.
> > 
> > That doesn't appear to be the case as of this patch. If it's a factor
> > later in the series, we should tweak it then where the intent is clear.
> 
> Patches don't exist in isolation. Please look at the work as a
> whole, not just patches in isolation.
> 

This is a simple matter of ordering changes in a series to facilitate
review.

> > This also doesn't strike me as a technically difficult problem to
> > address. We just need to filter out the set of superblock based features
> > one way or another. If you wanted to simplify it further, we could just
> > have the sb -> features function update ->m_features itself in a safe
> > manner (i.e., the subset of features it is responsible for) and then the
> > caller context doesn't really have to be concerned with such details.
> 
> We shouldn't be clearing superblock feature bits while there are
> still those features on disk. Only attr2 does this, and as per
> above, it's broken. I'm going to remove the code that removes the
> attr2 feature bit in the next round of the patch, and then this
> whole problem goes away.
> 
> > 
> > > > 
> > > > >  	xfs_reinit_percpu_counters(mp);
> > > > >  	error = xfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi);
> > > > >  	if (error) {
> > > > ...
> > > > > diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
> > > > > index 7964513c3128..92d947f17c69 100644
> > > > > --- a/fs/xfs/xfs_mount.h
> > > > > +++ b/fs/xfs/xfs_mount.h
> > > > > @@ -127,6 +127,7 @@ typedef struct xfs_mount {
> > > > >  	struct mutex		m_growlock;	/* growfs mutex */
> > > > >  	int			m_fixedfsid[2];	/* unchanged for life of FS */
> > > > >  	uint64_t		m_flags;	/* global mount flags */
> > > > > +	uint64_t		m_features;	/* active filesystem features */
> > > > >  	bool			m_inotbt_nores; /* no per-AG finobt resv. */
> > > > >  	int			m_ialloc_inos;	/* inodes in inode allocation */
> > > > >  	int			m_ialloc_blks;	/* blocks in inode allocation */
> > > > > @@ -195,6 +196,84 @@ typedef struct xfs_mount {
> > > > >  #endif
> > > > >  } xfs_mount_t;
> > > > >  
> > > > > +/*
> > > > > + * Flags for m_features.
> > > > > + *
> > > > > + * These are all the active features in the filesystem, regardless of how
> > > > > + * they are configured.
> > 
> > Given the point above around mount options, I think the comment above
> > would be more helpful if it said something like:
> > 
> > "These are all the active features in the filesystem. Some are
> > configured based on superblock version, others are based on mount
> > options."
> 
> Bigger picture: what about options we may set through, say, /proc,
> /sys, ioctls, online repair, etc? I think that the the places and
> ways we can set feature flags is only going to grow in future, and
> hence I'd prefer to leave this as a generic comment that encompasses
> everything rather than have it grow stale over time.
> 
> > > > I don't want to get into bikeshedding too much but tbh I've always found
> > > > the xfs_sb_has_* thing kind of weird where the "has" text seems
> > > > superfluous. It's just not been worth changing. It would be nice if we
> > > > could stop propagating it here and define a consistently used prefix.
> > > 
> > > Yet we use "is" all over the place when checking if an object is
> > > <something> (e.g. xfs_btree_ptr_is_null(), xfs_iext_rec_is_empty(),
> > > xfs_rmap_is_mergeable(), etc) because it makes the code more
> > > readable. The old sbversion namespace format is the problem, not the
> > > use of "has" to indicate we are checking if the filesystem has a
> > > feature...
> > > 
> > 
> > Each of the examples you cited above have widely used function name
> > prefixes.
> 
> The prefix indicates the subsystem the operation belongs to.
> 
> However, filesystem features are, well, belong in the global
> context.  They span all subsystems, and are a property of the global
> mount structure. IOWs, They don't have a single widely used
> subsystem that can be used as a namespace prefix, and using
> "feature" because "we must have a namespace prefix" turns all the
> function names into tautologies.
> 

Hmm, I've not introduced the requirement for a prefix here. One was
already used and it is renamed to "xfs_feat_" by your patches. I'm just
asking that you use it consistently. ;)

FWIW, I do think it's reasonable to retain the prefix because this set
of functions is clearly related as they're now generated by the same
macro infrastructure. This may not be a subsystem or whatever, but the
functional relation is obvious.

> Consider this: why is xfs_is_read_only(mp) an acceptible function
> name for checking global filesystem state, but xfs_has_attr2(mp) is
> not acceptible for checking global filesystem state?
> 

Because it's a standalone helper and read_only is an obvious state to an
fs developer. Would xfs_is_awesome() be just as clear? Would
xfs_read_only() really be more confusing?

If you defined xfs_is_readonly(), xfs_set_readonly() and
xfs_clear_readonly(), I might have a slightly different opinion. I say
slightly because that's still a fairly narrow usage for the set of
functions (read-only) as opposed to a more broad/generic mechanism for
the set of all features. It's easier to track the former without a
prefix IMO.

Some additional questions might be.. why did we have a common prefix in
the first place (and drop it in one case here)? Or why do the other two
related functions still share a prefix? I almost find the inconsistent
use of the renamed prefix more strange than not having one at all.

> > There's a reason they are named as they are and not as
> > xfs_is_empty_iext_rec(), for example. That's what I'm asking for here.
> > I don't fundamentally object to the fact that we use "has" or "is." I'm
> > merely pointing out that I think "has" is superfluous with respect to a
> > properly used function prefix and therefore we could replace it with the
> > prefix used by the other related helpers, restoring consistency without
> > sacrificing readability.
> > 
> > IOW, if you wanted to rename these to something like
> > xfs_feat_crc_enablement_it_has(mp), that wouldn't exactly be my
> > preference...  but I won't object if we can address the function prefix
> > thing. ;P
> > 
> > > I omitted the "_feat_" part of the name because it's effectively
> > > redundant when you read it. i.e. if (xfs_has_pquotaino(mp)) reads as
> > > a well composed sentence: "if XFS has project quotas inodes on this
> > > mount". Doing s/has/feature/ does not improve the readbility of the
> > > code, just makes it unnecessarily verbose.
> > > 
> > 
> > Eh, I don't think anybody is going to be confused by
> > xfs_has_pquotaino(mp) vs. xfs_feat_pquotaino(mp). Either way is
> 
> I find it confusing. Is it checking if the feature is enabled? Is it
> manipulating the feature in some way? Is it checking if we actually
> have a project quota inode present on the xfs_mount? Or maybe
> something else?
> 

"Is it checking if we actually _have_ a project quota inode present
...?" (emphasis mine)
				
Hmm, really? So the argument is that xfs_has_pquotino() somehow
clarifies that? :P

I think that's just preferential analysis. I really don't see how you
could confuse something like 'if (xfs_feat_pquotaino(mp))' with checking
for a quota inode or whatever but not acknowledge that 'if
(xfs_has_pquotaino(mp))' might be just as confusing to somebody else.
They really are equally terse (which I think is fine, btw) and just as
vague for somebody who might be looking at XFS for the first time (who
then takes the 5 seconds to check the function and it's moot).

> i.e. There's no action defined or implied by the function name and so
> I can't tell what that function is doing without looking at it.
> That's what "has" or "is" adds to the function name: a definitive
> action. i.e.  it's not the namespace prefix that is meaningful here
> - it's the action in the name ("has") that makes it obvious what the
> function does.
> 

I don't think either name makes it truly obvious what the function does.
It's the context and trivial implementation that makes it obvious what
the function does, to the point where (IMO) any argument around the
clarity of one of xfs_feat_crc() or xfs_has_crc() or XFS_CRC() or
whatever other (shortened and reasonably related) pattern you can think
of over the others is mostly spurious.

Basically, I think this whole line of argument is moot. If we want to
prioritize the self-descriptiveness of the name, then don't shorten it
to the point where we're trying to rely on whether "has" has some
special clarifying value. The current functions are
xfs_sb_version_[has|add|remove]<feature>(). It's clear what they do and
how they're related. If "has" is that important, then
xfs_feat_[has|add|remove]*() should work just as well.

> > self-descriptive and obvious IMO. As noted, I'm not really looking to
> > bikeshed over the most clear way to say "if this feature is enabled" in
> > a function name. I'd just prefer to use the associated function prefix
> > as we do most everywhere else.
> 
> And that's the issue I have here - we must do exactly what we've
> done in the past, even though those rules are falling down around
> us. Look at the mess this blind obedience to namespace rules got the
> scrub code into; it was ending up an unreadable jumble of noise
> because every structure and function had 25+ character namespace
> prefixes you had to read on every line of code before you get to the
> meaningful information.
> 
> Namespacing structures and functions have their place, but there is
> such a thing as taking it too far. Stuff that is easily
> understandable without verbose namespace prefixes should not have
> verbose/redundant namespace prefixes. 
> 

I think you're amplifying my fairly minor request into something more
involved than it really is. For one, the fact that some other subsystem
had too large a namespace or too descriptive a prefix doesn't make it a
problem here. Further and as noted above, a prefix for these functions
existed before these patches and one still exists after.

Brian

> Cheers,
> 
> Dave.
> -- 
> Dave Chinner
> david@fromorbit.com

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

end of thread, other threads:[~2018-08-23 17:08 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-08-20  4:48 [PATCH 0/10] xfs: feature flag rework Dave Chinner
2018-08-20  4:48 ` [PATCH 01/10] xfs: reflect sb features in xfs_mount Dave Chinner
2018-08-21 13:21   ` Brian Foster
2018-08-21 23:31     ` Dave Chinner
2018-08-22 12:17       ` Brian Foster
2018-08-22 23:59         ` Dave Chinner
2018-08-23 13:39           ` Brian Foster
2018-08-20  4:48 ` [PATCH 02/10] xfs: replace xfs_sb_version checks with feature flag checks Dave Chinner
2018-08-20  4:48 ` [PATCH 03/10] xfs: consolidate mount option features in m_features Dave Chinner
2018-08-21 13:21   ` Brian Foster
2018-08-21 23:32     ` Dave Chinner
2018-08-20  4:48 ` [PATCH 04/10] xfs: convert mount flags to features Dave Chinner
2018-08-21 13:22   ` Brian Foster
2018-08-21 23:36     ` Dave Chinner
2018-08-20  4:48 ` [PATCH 05/10] xfs: convert remaining mount flags to state flags Dave Chinner
2018-08-21 13:23   ` Brian Foster
2018-08-20  4:48 ` [PATCH 06/10] xfs: replace XFS_FORCED_SHUTDOWN with xfs_is_shut_down Dave Chinner
2018-08-21 13:23   ` Brian Foster
2018-08-20  4:48 ` [PATCH 07/10] xfs: convert xfs_fs_geometry to use mount feature checks Dave Chinner
2018-08-20  4:48 ` [PATCH 08/10] xfs: open code sb verifier " Dave Chinner
2018-08-21 13:01   ` Jan Tulak
2018-08-21 23:43     ` Dave Chinner
2018-08-21 13:25   ` Brian Foster
2018-08-21 23:43     ` Dave Chinner
2018-08-20  4:48 ` [PATCH 09/10] xfs: convert scrub to use mount-based " Dave Chinner
2018-08-20  4:48 ` [PATCH 10/10] xfs: remove unused xfs_sb_version_has... wrappers Dave Chinner
2018-08-21 13:54 ` [PATCH 0/10] xfs: feature flag rework Jan Tulak

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.