* 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);
 
 "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,
 
         * Readonly filesystems do not perform inactivation or speculative
         * preallocation, so there's no need to restart the workers.
         */
-       if (!(sc->mp->m_flags & XFS_MOUNT_RDONLY)) {
+       if (!xfs_is_readonly(sc->mp)) {
                xfs_inodegc_start(sc->mp);
                xfs_blockgc_start(sc->mp);
        }
 
                        goto out;
 
                error = -EROFS;
-               if (mp->m_flags & XFS_MOUNT_RDONLY)
+               if (xfs_is_readonly(mp))
                        goto out;
        }
 
 
                return true;
 
        /* At unmount we may treat errors differently */
-       if ((mp->m_flags & XFS_MOUNT_UNMOUNTING) && mp->m_fail_unmount)
+       if (xfs_is_unmounting(mp) && mp->m_fail_unmount)
                return true;
 
        return false;
 
        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;
         * 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) || xfs_is_inode32(mp))
                fileid_type |= XFS_FILEID_TYPE_64FLAG;
 
        /*
 
         * Set the starting AG using the rotor for inode32, otherwise
         * use the directory inode's AG.
         */
-       if (mp->m_flags & XFS_MOUNT_32BITINODES) {
+       if (xfs_is_inode32(mp)) {
                xfs_agnumber_t   rotorstep = xfs_rotorstep;
                startag = (mp->m_agfrotor / rotorstep) % mp->m_sb.sb_agcount;
                mp->m_agfrotor = (mp->m_agfrotor + 1) %
 
        int             tag;
        const char      *why;
 
-       spin_lock(&mp->m_sb_lock);
-       if (XFS_FORCED_SHUTDOWN(mp)) {
-               spin_unlock(&mp->m_sb_lock);
+       if (test_and_set_bit(XFS_OPSTATE_SHUTDOWN, &mp->m_opstate))
                return;
-       }
-       mp->m_flags |= XFS_MOUNT_FS_SHUTDOWN;
        if (mp->m_sb_bp)
                mp->m_sb_bp->b_flags |= XBF_DONE;
-       spin_unlock(&mp->m_sb_lock);
 
        if (flags & SHUTDOWN_FORCE_UMOUNT)
                xfs_alert(mp, "User initiated shutdown received.");
 
 xfs_want_reclaim_sick(
        struct xfs_mount        *mp)
 {
-       return (mp->m_flags & XFS_MOUNT_UNMOUNTING) || xfs_has_norecovery(mp) ||
+       return xfs_is_unmounting(mp) || xfs_has_norecovery(mp) ||
               XFS_FORCED_SHUTDOWN(mp);
 }
 
 
                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)) {
                return false;
 
        /* 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 false;
 
        /* If the log isn't running, push inodes straight to reclaim. */
        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))
                goto out;
 
        /* Metadata inodes require explicit resource cleanup. */
 
        struct xfs_trans        *tp;
        int                     error = -EROFS;
 
-       if (mp->m_flags & XFS_MOUNT_RDONLY)
+       if (xfs_is_readonly(mp))
                goto out_error;
        error = -EIO;
        if (XFS_FORCED_SHUTDOWN(mp))
                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)))
                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)))
 
 {
        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))
 
                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));
        }
 
        log = xlog_alloc_log(mp, log_target, blk_offset, num_bblks);
         * just worked.
         */
        if (!xfs_has_norecovery(mp)) {
-               bool    readonly = (mp->m_flags & XFS_MOUNT_RDONLY);
-
-               if (readonly)
-                       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.
+                */
+               bool    readonly = test_and_clear_bit(XFS_OPSTATE_READONLY,
+                                               &mp->m_opstate);
                error = xlog_recover(log);
-
                if (readonly)
-                       mp->m_flags |= XFS_MOUNT_RDONLY;
+                       set_bit(XFS_OPSTATE_READONLY, &mp->m_opstate);
                if (error) {
                        xfs_warn(mp, "log mount/recovery failed: error %d",
                                error);
        struct xfs_mount        *mp)
 {
        struct xlog             *log = mp->m_log;
-       bool                    readonly = (mp->m_flags & XFS_MOUNT_RDONLY);
+       bool                    readonly;
        int                     error = 0;
 
        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_OPSTATE_READONLY, &mp->m_opstate);
+
        /*
         * During the second phase of log recovery, we need iget and
         * iput to behave like they do for an active filesystem.
 
        clear_bit(XLOG_RECOVERY_NEEDED, &log->l_opstate);
        if (readonly)
-               mp->m_flags |= XFS_MOUNT_RDONLY;
+               set_bit(XFS_OPSTATE_READONLY, &mp->m_opstate);
 
        /* Make sure the log is dead if we're returning failure. */
        ASSERT(!error || xlog_is_shutdown(log));
 
         * headers if we have a filesystem using non-persistent counters.
         */
        if (clean)
-               log->l_mp->m_flags |= XFS_MOUNT_WAS_CLEAN;
+               set_bit(XFS_OPSTATE_CLEAN, &log->l_mp->m_opstate);
 
        /*
         * Make sure that there are no blocks in front of the head
 
         * 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 (xfs_is_clean(mp) &&
            (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))
         * superblock to be correct and we don't need to do anything here.
         * Otherwise, recalculate the summary counters.
         */
-       if ((!xfs_has_lazysbcount(mp) ||
-            XFS_LAST_UNMOUNT_WAS_CLEAN(mp)) &&
+       if ((!xfs_has_lazysbcount(mp) || xfs_is_clean(mp)) &&
            !xfs_fs_has_sickness(mp, XFS_SICK_FS_COUNTERS))
                return 0;
 
        xfs_extent_busy_wait_all(mp);
        flush_workqueue(xfs_discard_wq);
 
-       mp->m_flags |= XFS_MOUNT_UNMOUNTING;
+       set_bit(XFS_OPSTATE_UNMOUNTING, &mp->m_opstate);
 
        xfs_ail_push_all_sync(mp->m_ail);
        xfs_inodegc_stop(mp);
         * 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");
         * 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_log_clean(mp);
 
        /*
         * 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)
 {
        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;
 
        uint                    m_rsumsize;     /* size of rt summary, bytes */
        int                     m_fixedfsid[2]; /* unchanged for life of FS */
        uint                    m_qflags;       /* quota status flags */
-       uint64_t                m_flags;        /* global mount flags */
        uint64_t                m_features;     /* active filesystem features */
        uint64_t                m_low_space[XFS_LOWSP_MAX];
        uint64_t                m_low_rtexts[XFS_LOWSP_MAX];
 /*
  * 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
+ * These do not change dynamically - features that can come and go, such as 32
+ * bit inodes and read-only state, are kept as operational state rather than
  * features.
  */
 __XFS_HAS_FEAT(noattr2, NOATTR2)
 __XFS_HAS_FEAT(nouuid, NOUUID)
 
 /*
- * Flags for m_flags.
+ * Operational mount state flags
+ *
+ * Use these with atomic bit ops only!
  */
-#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_WAS_CLEAN    (1ULL << 2)
-#define XFS_MOUNT_FS_SHUTDOWN  (1ULL << 3)     /* 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 << 4)     /* read-only fs */
+#define XFS_OPSTATE_UNMOUNTING         0       /* filesystem is unmounting */
+#define XFS_OPSTATE_CLEAN              1       /* mount was clean */
+#define XFS_OPSTATE_SHUTDOWN           2       /* stop all fs operations */
+#define XFS_OPSTATE_INODE32            3       /* inode32 allocator active */
+#define XFS_OPSTATE_READONLY           4       /* read-only fs */
 
 /*
  * If set, inactivation worker threads will be scheduled to process queued
  * inodegc work.  If not, queued inodes remain in memory waiting to be
  * processed.
  */
-#define XFS_OPSTATE_INODEGC_ENABLED    0
+#define XFS_OPSTATE_INODEGC_ENABLED    5
 /*
  * If set, background speculative prealloc gc worker threads will be scheduled
  * to process queued blockgc work.  If not, inodes retain their preallocations
  * until explicitly deleted.
  */
-#define XFS_OPSTATE_BLOCKGC_ENABLED    1
+#define XFS_OPSTATE_BLOCKGC_ENABLED    6
 
 #define __XFS_IS_OPSTATE(name, NAME) \
 static inline bool xfs_is_ ## name (struct xfs_mount *mp) \
        return test_and_set_bit(XFS_OPSTATE_ ## NAME, &mp->m_opstate); \
 }
 
+__XFS_IS_OPSTATE(unmounting, UNMOUNTING)
+__XFS_IS_OPSTATE(clean, CLEAN)
+__XFS_IS_OPSTATE(shutdown, SHUTDOWN)
+__XFS_IS_OPSTATE(inode32, INODE32)
+__XFS_IS_OPSTATE(readonly, READONLY)
 __XFS_IS_OPSTATE(inodegc_enabled, INODEGC_ENABLED)
 __XFS_IS_OPSTATE(blockgc_enabled, BLOCKGC_ENABLED)
 
 #define XFS_OPSTATE_STRINGS \
+       { (1UL << XFS_OPSTATE_UNMOUNTING),              "unmounting" }, \
+       { (1UL << XFS_OPSTATE_CLEAN),                   "clean" }, \
+       { (1UL << XFS_OPSTATE_SHUTDOWN),                "shutdown" }, \
+       { (1UL << XFS_OPSTATE_INODE32),                 "inode32" }, \
+       { (1UL << XFS_OPSTATE_READONLY),                "read_only" }, \
        { (1UL << XFS_OPSTATE_INODEGC_ENABLED),         "inodegc" }, \
        { (1UL << XFS_OPSTATE_BLOCKGC_ENABLED),         "blockgc" }
 
 #define XFS_MAX_IO_LOG         30      /* 1G */
 #define XFS_MIN_IO_LOG         PAGE_SHIFT
 
-#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)                xfs_is_shutdown(mp)
 void xfs_do_force_shutdown(struct xfs_mount *mp, int flags, char *fname,
                int lnnum);
 #define xfs_force_shutdown(m,f)        \
 
  *
  * 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_OPSTATE_INODE32 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
 
        /*
         * 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_OPSTATE_INODE32 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_OPSTATE_INODE32, &mp->m_opstate);
        else
-               mp->m_flags &= ~XFS_MOUNT_32BITINODES;
+               clear_bit(XFS_OPSTATE_INODE32, &mp->m_opstate);
 
        for (index = 0; index < agcount; index++) {
                struct xfs_perag        *pag;
 
                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;
                xfs_perag_put(pag);
        }
 
-       return (mp->m_flags & XFS_MOUNT_32BITINODES) ? maxagi : agcount;
+       return xfs_is_inode32(mp) ? maxagi : agcount;
 }
 
 STATIC int
         * here, so we can restart safely without racing with a stop in
         * xfs_fs_sync_fs().
         */
-       if (ret && !(mp->m_flags & XFS_MOUNT_RDONLY)) {
+       if (ret && !xfs_is_readonly(mp)) {
                xfs_blockgc_start(mp);
                xfs_inodegc_start(mp);
        }
         * worker because there are no speculative preallocations on a readonly
         * filesystem.
         */
-       if (!(mp->m_flags & XFS_MOUNT_RDONLY)) {
+       if (!xfs_is_readonly(mp)) {
                xfs_blockgc_start(mp);
                xfs_inodegc_start(mp);
        }
 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 &&
        /*
         * 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;
        struct xfs_mount        *mp)
 {
        /* 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;
        }
                return -EINVAL;
        }
 
-       mp->m_flags &= ~XFS_MOUNT_RDONLY;
+       clear_bit(XFS_OPSTATE_READONLY, &mp->m_opstate);
 
        /*
         * If this is the first remount to writeable state we might have some
        xfs_save_resvblks(mp);
 
        xfs_log_clean(mp);
-       mp->m_flags |= XFS_MOUNT_RDONLY;
+       set_bit(XFS_OPSTATE_READONLY, &mp->m_opstate);
 
        return 0;
 }
        }
 
        /* ro -> rw */
-       if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(flags & SB_RDONLY)) {
+       if (xfs_is_readonly(mp) && !(flags & SB_RDONLY)) {
                error = xfs_remount_rw(mp);
                if (error)
                        return error;
        }
 
        /* rw -> ro */
-       if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (flags & SB_RDONLY)) {
+       if (!xfs_is_readonly(mp) && (flags & SB_RDONLY)) {
                error = xfs_remount_ro(mp);
                if (error)
                        return error;
         * Copy binary VFS mount flags we are interested in.
         */
        if (fc->sb_flags & SB_RDONLY)
-               mp->m_flags |= XFS_MOUNT_RDONLY;
+               set_bit(XFS_OPSTATE_READONLY, &mp->m_opstate);
        if (fc->sb_flags & SB_DIRSYNC)
                mp->m_features |= XFS_FEAT_DIRSYNC;
        if (fc->sb_flags & SB_SYNCHRONOUS)
 
        TP_fast_assign(
                if (mp) {
                        __entry->dev = mp->m_super->s_dev;
-                       __entry->mflags = mp->m_flags;
+                       __entry->mflags = mp->m_features;
                        __entry->opstate = mp->m_opstate;
                        __entry->sbflags = mp->m_super->s_flags;
                }
                __entry->caller_ip = caller_ip;
        ),
-       TP_printk("dev %d:%d m_flags 0x%llx opstate (%s) s_flags 0x%lx caller %pS",
+       TP_printk("dev %d:%d m_features 0x%llx opstate (%s) s_flags 0x%lx caller %pS",
                  MAJOR(__entry->dev), MINOR(__entry->dev),
                  __entry->mflags,
                  __print_flags(__entry->opstate, "|", XFS_OPSTATE_STRINGS),