]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: convert remaining mount flags to state flags
authorDave Chinner <dchinner@redhat.com>
Mon, 31 Jan 2022 22:26:19 +0000 (17:26 -0500)
committerEric Sandeen <sandeen@redhat.com>
Mon, 31 Jan 2022 22:26:19 +0000 (17:26 -0500)
Source kernel commit: 2e973b2cd4cdb993be94cca4c33f532f1ed05316

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 due to racing
modifications.

Convert these remaining flags to be stored in m_opstate and 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>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
include/xfs_mount.h
libxfs/init.c
libxfs/xfs_alloc.c
libxfs/xfs_sb.c

index 7805394637d250d0a15607ab60a6fab6b7019a7b..67d03e77750ed55ff32ed1db74edfa6bd3e10318 100644 (file)
@@ -81,6 +81,7 @@ typedef struct xfs_mount {
        struct radix_tree_root  m_perag_tree;
        uint                    m_flags;        /* global mount flags */
        uint64_t                m_features;     /* active filesystem features */
+       unsigned long           m_opstate;      /* dynamic state flags */
        bool                    m_finobt_nores; /* no per-AG finobt resv. */
        uint                    m_qflags;       /* quota status flags */
        uint                    m_attroffset;   /* inode attribute offset */
@@ -208,6 +209,39 @@ __XFS_UNSUPP_FEAT(noattr2)
 __XFS_UNSUPP_FEAT(ikeep)
 __XFS_UNSUPP_FEAT(swalloc)
 __XFS_UNSUPP_FEAT(small_inums)
+__XFS_UNSUPP_FEAT(readonly)
+
+/* Operational mount state flags */
+#define XFS_OPSTATE_INODE32            0       /* inode32 allocator active */
+
+#define __XFS_IS_OPSTATE(name, NAME) \
+static inline bool xfs_is_ ## name (struct xfs_mount *mp) \
+{ \
+       return (mp)->m_opstate & (1UL << XFS_OPSTATE_ ## NAME); \
+} \
+static inline bool xfs_clear_ ## name (struct xfs_mount *mp) \
+{ \
+       bool    ret = xfs_is_ ## name(mp); \
+\
+       (mp)->m_opstate &= ~(1UL << XFS_OPSTATE_ ## NAME); \
+       return ret; \
+} \
+static inline bool xfs_set_ ## name (struct xfs_mount *mp) \
+{ \
+       bool    ret = xfs_is_ ## name(mp); \
+\
+       (mp)->m_opstate |= (1UL << XFS_OPSTATE_ ## NAME); \
+       return ret; \
+}
+
+__XFS_IS_OPSTATE(inode32, INODE32)
+
+#define __XFS_UNSUPP_OPSTATE(name) \
+static inline bool xfs_is_ ## name (struct xfs_mount *mp) \
+{ \
+       return false; \
+}
+__XFS_UNSUPP_OPSTATE(readonly)
 
 #define LIBXFS_MOUNT_DEBUGGER          0x0001
 #define LIBXFS_MOUNT_32BITINODES       0x0002
index 364c357848f00ac9c8d9b9216e0db92d805fde32..875c847edf48a5ba9c44486683303e0ce9d27f32 100644 (file)
@@ -540,10 +540,13 @@ xfs_set_inode_alloc(
         * sufficiently large, set XFS_MOUNT_32BITINODES if we must alter
         * the allocator to accommodate the request.
         */
-       if (xfs_has_small_inums(mp) && ino > XFS_MAXINUMBER_32)
+       if (xfs_has_small_inums(mp) && ino > XFS_MAXINUMBER_32) {
+               xfs_set_inode32(mp);
                mp->m_flags |= XFS_MOUNT_32BITINODES;
-       else
+       } else {
+               xfs_clear_inode32(mp);
                mp->m_flags &= ~XFS_MOUNT_32BITINODES;
+       }
 
        for (index = 0; index < agcount; index++) {
                struct xfs_perag        *pag;
@@ -552,7 +555,7 @@ xfs_set_inode_alloc(
 
                pag = xfs_perag_get(mp, index);
 
-               if (mp->m_flags & XFS_MOUNT_32BITINODES) {
+               if (xfs_is_inode32(mp)) {
                        if (ino > XFS_MAXINUMBER_32) {
                                pag->pagi_inodeok = 0;
                                pag->pagf_metadata = 0;
@@ -572,7 +575,7 @@ xfs_set_inode_alloc(
                xfs_perag_put(pag);
        }
 
-       return (mp->m_flags & XFS_MOUNT_32BITINODES) ? maxagi : agcount;
+       return xfs_is_inode32(mp) ? maxagi : agcount;
 }
 
 static struct xfs_buftarg *
@@ -728,6 +731,7 @@ libxfs_mount(
 
        mp->m_finobt_nores = true;
        mp->m_flags = (LIBXFS_MOUNT_32BITINODES|LIBXFS_MOUNT_32BITINOOPT);
+       xfs_set_inode32(mp);
        mp->m_sb = *sb;
        INIT_RADIX_TREE(&mp->m_perag_tree, GFP_KERNEL);
        sbp = &mp->m_sb;
index b87253392bf40fb007f494477ac090c53c192187..163c726f2d93fac59e54e99951ab72ab95b404b5 100644 (file)
@@ -3162,7 +3162,7 @@ xfs_alloc_vextent(
                 * the first a.g. fails.
                 */
                if ((args->datatype & XFS_ALLOC_INITIAL_USER_DATA) &&
-                   (mp->m_flags & XFS_MOUNT_32BITINODES)) {
+                   xfs_is_inode32(mp)) {
                        args->fsbno = XFS_AGB_TO_FSB(mp,
                                        ((mp->m_agfrotor / rotorstep) %
                                        mp->m_sb.sb_agcount), 0);
index 25a4ffdb543d81ff267986c38b1547e140a8aab1..d2de96d149ca50b7e7942a870643134db56572b3 100644 (file)
@@ -120,7 +120,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 (!xfs_is_readonly(mp)) {
                        xfs_warn(mp,
 "Attempted to mount read-only compatible filesystem read-write.");
                        xfs_warn(mp,