@@ -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);
@@ -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;
}
@@ -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;
}
@@ -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;
/*
@@ -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;
/*
@@ -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) %
@@ -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.
@@ -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. */
@@ -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)))
@@ -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))
@@ -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;
@@ -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
@@ -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);
}
@@ -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) \
@@ -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;