···10741074 xfs_sysfs_del(&mp->m_kobj);10751075}1076107610771077-int10781078-xfs_fs_writable(xfs_mount_t *mp)10771077+/*10781078+ * Determine whether modifications can proceed. The caller specifies the minimum10791079+ * freeze level for which modifications should not be allowed. This allows10801080+ * certain operations to proceed while the freeze sequence is in progress, if10811081+ * necessary.10821082+ */10831083+bool10841084+xfs_fs_writable(10851085+ struct xfs_mount *mp,10861086+ int level)10791087{10801080- return !(mp->m_super->s_writers.frozen || XFS_FORCED_SHUTDOWN(mp) ||10811081- (mp->m_flags & XFS_MOUNT_RDONLY));10881088+ ASSERT(level > SB_UNFROZEN);10891089+ if ((mp->m_super->s_writers.frozen >= level) ||10901090+ XFS_FORCED_SHUTDOWN(mp) || (mp->m_flags & XFS_MOUNT_RDONLY))10911091+ return false;10921092+10931093+ return true;10821094}1083109510841096/*···10981086 *10991087 * Sync the superblock counters to disk.11001088 *11011101- * Note this code can be called during the process of freezing, so11021102- * we may need to use the transaction allocator which does not11031103- * block when the transaction subsystem is in its frozen state.10891089+ * Note this code can be called during the process of freezing, so we use the10901090+ * transaction allocator that does not block when the transaction subsystem is10911091+ * in its frozen state.11041092 */11051093int11061094xfs_log_sbcount(xfs_mount_t *mp)···11081096 xfs_trans_t *tp;11091097 int error;1110109811111111- if (!xfs_fs_writable(mp))10991099+ /* allow this to proceed during the freeze sequence... */11001100+ if (!xfs_fs_writable(mp, SB_FREEZE_COMPLETE))11121101 return 0;1113110211141103 xfs_icsb_sync_counters(mp, 0);
+2-1
fs/xfs/xfs_mount.h
···168168 /* low free space thresholds */169169 struct xfs_kobj m_kobj;170170171171+ struct workqueue_struct *m_buf_workqueue;171172 struct workqueue_struct *m_data_workqueue;172173 struct workqueue_struct *m_unwritten_workqueue;173174 struct workqueue_struct *m_cil_workqueue;···385384extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int);386385extern int xfs_readsb(xfs_mount_t *, int);387386extern void xfs_freesb(xfs_mount_t *);388388-extern int xfs_fs_writable(xfs_mount_t *);387387+extern bool xfs_fs_writable(struct xfs_mount *mp, int level);389388extern int xfs_sb_validate_fsb_count(struct xfs_sb *, __uint64_t);390389391390extern int xfs_dev_is_read_only(struct xfs_mount *, char *);
+10-16
fs/xfs/xfs_qm_syscalls.c
···784784{785785 xfs_trans_t *tp;786786 int error;787787- xfs_qoff_logitem_t *qoffi=NULL;788788- uint oldsbqflag=0;787787+ xfs_qoff_logitem_t *qoffi;788788+789789+ *qoffstartp = NULL;789790790791 tp = xfs_trans_alloc(mp, XFS_TRANS_QM_QUOTAOFF);791792 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_qm_quotaoff, 0, 0);792792- if (error)793793- goto error0;793793+ if (error) {794794+ xfs_trans_cancel(tp, 0);795795+ goto out;796796+ }794797795798 qoffi = xfs_trans_get_qoff_item(tp, NULL, flags & XFS_ALL_QUOTA_ACCT);796799 xfs_trans_log_quotaoff_item(tp, qoffi);797800798801 spin_lock(&mp->m_sb_lock);799799- oldsbqflag = mp->m_sb.sb_qflags;800802 mp->m_sb.sb_qflags = (mp->m_qflags & ~(flags)) & XFS_MOUNT_QUOTA_ALL;801803 spin_unlock(&mp->m_sb_lock);802804···811809 */812810 xfs_trans_set_sync(tp);813811 error = xfs_trans_commit(tp, 0);812812+ if (error)813813+ goto out;814814815815-error0:816816- if (error) {817817- xfs_trans_cancel(tp, 0);818818- /*819819- * No one else is modifying sb_qflags, so this is OK.820820- * We still hold the quotaofflock.821821- */822822- spin_lock(&mp->m_sb_lock);823823- mp->m_sb.sb_qflags = oldsbqflag;824824- spin_unlock(&mp->m_sb_lock);825825- }826815 *qoffstartp = qoffi;816816+out:827817 return error;828818}829819