aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/libxfs/xfs_attr_leaf.c2
-rw-r--r--fs/xfs/libxfs/xfs_bmap.c10
-rw-r--r--fs/xfs/libxfs/xfs_sb.c43
-rw-r--r--fs/xfs/libxfs/xfs_sb.h3
-rw-r--r--fs/xfs/libxfs/xfs_shared.h33
-rw-r--r--fs/xfs/libxfs/xfs_trans_resv.c14
-rw-r--r--fs/xfs/libxfs/xfs_trans_resv.h1
-rw-r--r--fs/xfs/xfs_fsops.c29
-rw-r--r--fs/xfs/xfs_log.c18
-rw-r--r--fs/xfs/xfs_mount.c78
-rw-r--r--fs/xfs/xfs_mount.h3
-rw-r--r--fs/xfs/xfs_qm.c27
-rw-r--r--fs/xfs/xfs_qm.h1
-rw-r--r--fs/xfs/xfs_qm_syscalls.c7
-rw-r--r--fs/xfs/xfs_super.c13
15 files changed, 101 insertions, 181 deletions
diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c
index c9144221798f..15105dbc9e28 100644
--- a/fs/xfs/libxfs/xfs_attr_leaf.c
+++ b/fs/xfs/libxfs/xfs_attr_leaf.c
@@ -403,7 +403,7 @@ xfs_sbversion_add_attr2(xfs_mount_t *mp, xfs_trans_t *tp)
403 if (!xfs_sb_version_hasattr2(&mp->m_sb)) { 403 if (!xfs_sb_version_hasattr2(&mp->m_sb)) {
404 xfs_sb_version_addattr2(&mp->m_sb); 404 xfs_sb_version_addattr2(&mp->m_sb);
405 spin_unlock(&mp->m_sb_lock); 405 spin_unlock(&mp->m_sb_lock);
406 xfs_mod_sb(tp); 406 xfs_log_sb(tp);
407 } else 407 } else
408 spin_unlock(&mp->m_sb_lock); 408 spin_unlock(&mp->m_sb_lock);
409 } 409 }
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index 8c39cc852e4b..63a5bb9113ee 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -1221,20 +1221,20 @@ xfs_bmap_add_attrfork(
1221 goto bmap_cancel; 1221 goto bmap_cancel;
1222 if (!xfs_sb_version_hasattr(&mp->m_sb) || 1222 if (!xfs_sb_version_hasattr(&mp->m_sb) ||
1223 (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2)) { 1223 (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2)) {
1224 bool mod_sb = false; 1224 bool log_sb = false;
1225 1225
1226 spin_lock(&mp->m_sb_lock); 1226 spin_lock(&mp->m_sb_lock);
1227 if (!xfs_sb_version_hasattr(&mp->m_sb)) { 1227 if (!xfs_sb_version_hasattr(&mp->m_sb)) {
1228 xfs_sb_version_addattr(&mp->m_sb); 1228 xfs_sb_version_addattr(&mp->m_sb);
1229 mod_sb = true; 1229 log_sb = true;
1230 } 1230 }
1231 if (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2) { 1231 if (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2) {
1232 xfs_sb_version_addattr2(&mp->m_sb); 1232 xfs_sb_version_addattr2(&mp->m_sb);
1233 mod_sb = true; 1233 log_sb = true;
1234 } 1234 }
1235 spin_unlock(&mp->m_sb_lock); 1235 spin_unlock(&mp->m_sb_lock);
1236 if (mod_sb) 1236 if (log_sb)
1237 xfs_mod_sb(tp); 1237 xfs_log_sb(tp);
1238 } 1238 }
1239 1239
1240 error = xfs_bmap_finish(&tp, &flist, &committed); 1240 error = xfs_bmap_finish(&tp, &flist, &committed);
diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c
index 115a7cd3a6fb..63f814872dfb 100644
--- a/fs/xfs/libxfs/xfs_sb.c
+++ b/fs/xfs/libxfs/xfs_sb.c
@@ -753,14 +753,13 @@ xfs_initialize_perag_data(
753} 753}
754 754
755/* 755/*
756 * xfs_mod_sb() can be used to copy arbitrary changes to the 756 * xfs_log_sb() can be used to copy arbitrary changes to the in-core superblock
757 * in-core superblock into the superblock buffer to be logged. 757 * into the superblock buffer to be logged. It does not provide the higher
758 * It does not provide the higher level of locking that is 758 * level of locking that is needed to protect the in-core superblock from
759 * needed to protect the in-core superblock from concurrent 759 * concurrent access.
760 * access.
761 */ 760 */
762void 761void
763xfs_mod_sb( 762xfs_log_sb(
764 struct xfs_trans *tp) 763 struct xfs_trans *tp)
765{ 764{
766 struct xfs_mount *mp = tp->t_mountp; 765 struct xfs_mount *mp = tp->t_mountp;
@@ -770,3 +769,35 @@ xfs_mod_sb(
770 xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SB_BUF); 769 xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SB_BUF);
771 xfs_trans_log_buf(tp, bp, 0, sizeof(struct xfs_dsb)); 770 xfs_trans_log_buf(tp, bp, 0, sizeof(struct xfs_dsb));
772} 771}
772
773/*
774 * xfs_sync_sb
775 *
776 * Sync the superblock to disk.
777 *
778 * Note that the caller is responsible for checking the frozen state of the
779 * filesystem. This procedure uses the non-blocking transaction allocator and
780 * thus will allow modifications to a frozen fs. This is required because this
781 * code can be called during the process of freezing where use of the high-level
782 * allocator would deadlock.
783 */
784int
785xfs_sync_sb(
786 struct xfs_mount *mp,
787 bool wait)
788{
789 struct xfs_trans *tp;
790 int error;
791
792 tp = _xfs_trans_alloc(mp, XFS_TRANS_SB_CHANGE, KM_SLEEP);
793 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_sb, 0, 0);
794 if (error) {
795 xfs_trans_cancel(tp, 0);
796 return error;
797 }
798
799 xfs_log_sb(tp);
800 if (wait)
801 xfs_trans_set_sync(tp);
802 return xfs_trans_commit(tp, 0);
803}
diff --git a/fs/xfs/libxfs/xfs_sb.h b/fs/xfs/libxfs/xfs_sb.h
index e193caa42988..b25bb9a343f3 100644
--- a/fs/xfs/libxfs/xfs_sb.h
+++ b/fs/xfs/libxfs/xfs_sb.h
@@ -28,7 +28,8 @@ extern void xfs_perag_put(struct xfs_perag *pag);
28extern int xfs_initialize_perag_data(struct xfs_mount *, xfs_agnumber_t); 28extern int xfs_initialize_perag_data(struct xfs_mount *, xfs_agnumber_t);
29 29
30extern void xfs_sb_calc_crc(struct xfs_buf *bp); 30extern void xfs_sb_calc_crc(struct xfs_buf *bp);
31extern void xfs_mod_sb(struct xfs_trans *tp); 31extern void xfs_log_sb(struct xfs_trans *tp);
32extern int xfs_sync_sb(struct xfs_mount *mp, bool wait);
32extern void xfs_sb_mount_common(struct xfs_mount *mp, struct xfs_sb *sbp); 33extern void xfs_sb_mount_common(struct xfs_mount *mp, struct xfs_sb *sbp);
33extern void xfs_sb_from_disk(struct xfs_sb *to, struct xfs_dsb *from); 34extern void xfs_sb_from_disk(struct xfs_sb *to, struct xfs_dsb *from);
34extern void xfs_sb_to_disk(struct xfs_dsb *to, struct xfs_sb *from); 35extern void xfs_sb_to_disk(struct xfs_dsb *to, struct xfs_sb *from);
diff --git a/fs/xfs/libxfs/xfs_shared.h b/fs/xfs/libxfs/xfs_shared.h
index 82404da2ca67..8dda4b321343 100644
--- a/fs/xfs/libxfs/xfs_shared.h
+++ b/fs/xfs/libxfs/xfs_shared.h
@@ -82,7 +82,7 @@ extern const struct xfs_buf_ops xfs_symlink_buf_ops;
82#define XFS_TRANS_ATTR_RM 23 82#define XFS_TRANS_ATTR_RM 23
83#define XFS_TRANS_ATTR_FLAG 24 83#define XFS_TRANS_ATTR_FLAG 24
84#define XFS_TRANS_CLEAR_AGI_BUCKET 25 84#define XFS_TRANS_CLEAR_AGI_BUCKET 25
85#define XFS_TRANS_QM_SBCHANGE 26 85#define XFS_TRANS_SB_CHANGE 26
86/* 86/*
87 * Dummy entries since we use the transaction type to index into the 87 * Dummy entries since we use the transaction type to index into the
88 * trans_type[] in xlog_recover_print_trans_head() 88 * trans_type[] in xlog_recover_print_trans_head()
@@ -95,17 +95,15 @@ extern const struct xfs_buf_ops xfs_symlink_buf_ops;
95#define XFS_TRANS_QM_DQCLUSTER 32 95#define XFS_TRANS_QM_DQCLUSTER 32
96#define XFS_TRANS_QM_QINOCREATE 33 96#define XFS_TRANS_QM_QINOCREATE 33
97#define XFS_TRANS_QM_QUOTAOFF_END 34 97#define XFS_TRANS_QM_QUOTAOFF_END 34
98#define XFS_TRANS_SB_UNIT 35 98#define XFS_TRANS_FSYNC_TS 35
99#define XFS_TRANS_FSYNC_TS 36 99#define XFS_TRANS_GROWFSRT_ALLOC 36
100#define XFS_TRANS_GROWFSRT_ALLOC 37 100#define XFS_TRANS_GROWFSRT_ZERO 37
101#define XFS_TRANS_GROWFSRT_ZERO 38 101#define XFS_TRANS_GROWFSRT_FREE 38
102#define XFS_TRANS_GROWFSRT_FREE 39 102#define XFS_TRANS_SWAPEXT 39
103#define XFS_TRANS_SWAPEXT 40 103#define XFS_TRANS_CHECKPOINT 40
104#define XFS_TRANS_SB_COUNT 41 104#define XFS_TRANS_ICREATE 41
105#define XFS_TRANS_CHECKPOINT 42 105#define XFS_TRANS_CREATE_TMPFILE 42
106#define XFS_TRANS_ICREATE 43 106#define XFS_TRANS_TYPE_MAX 43
107#define XFS_TRANS_CREATE_TMPFILE 44
108#define XFS_TRANS_TYPE_MAX 44
109/* new transaction types need to be reflected in xfs_logprint(8) */ 107/* new transaction types need to be reflected in xfs_logprint(8) */
110 108
111#define XFS_TRANS_TYPES \ 109#define XFS_TRANS_TYPES \
@@ -113,7 +111,6 @@ extern const struct xfs_buf_ops xfs_symlink_buf_ops;
113 { XFS_TRANS_SETATTR_SIZE, "SETATTR_SIZE" }, \ 111 { XFS_TRANS_SETATTR_SIZE, "SETATTR_SIZE" }, \
114 { XFS_TRANS_INACTIVE, "INACTIVE" }, \ 112 { XFS_TRANS_INACTIVE, "INACTIVE" }, \
115 { XFS_TRANS_CREATE, "CREATE" }, \ 113 { XFS_TRANS_CREATE, "CREATE" }, \
116 { XFS_TRANS_CREATE_TMPFILE, "CREATE_TMPFILE" }, \
117 { XFS_TRANS_CREATE_TRUNC, "CREATE_TRUNC" }, \ 114 { XFS_TRANS_CREATE_TRUNC, "CREATE_TRUNC" }, \
118 { XFS_TRANS_TRUNCATE_FILE, "TRUNCATE_FILE" }, \ 115 { XFS_TRANS_TRUNCATE_FILE, "TRUNCATE_FILE" }, \
119 { XFS_TRANS_REMOVE, "REMOVE" }, \ 116 { XFS_TRANS_REMOVE, "REMOVE" }, \
@@ -134,23 +131,23 @@ extern const struct xfs_buf_ops xfs_symlink_buf_ops;
134 { XFS_TRANS_ATTR_RM, "ATTR_RM" }, \ 131 { XFS_TRANS_ATTR_RM, "ATTR_RM" }, \
135 { XFS_TRANS_ATTR_FLAG, "ATTR_FLAG" }, \ 132 { XFS_TRANS_ATTR_FLAG, "ATTR_FLAG" }, \
136 { XFS_TRANS_CLEAR_AGI_BUCKET, "CLEAR_AGI_BUCKET" }, \ 133 { XFS_TRANS_CLEAR_AGI_BUCKET, "CLEAR_AGI_BUCKET" }, \
137 { XFS_TRANS_QM_SBCHANGE, "QM_SBCHANGE" }, \ 134 { XFS_TRANS_SB_CHANGE, "SBCHANGE" }, \
135 { XFS_TRANS_DUMMY1, "DUMMY1" }, \
136 { XFS_TRANS_DUMMY2, "DUMMY2" }, \
138 { XFS_TRANS_QM_QUOTAOFF, "QM_QUOTAOFF" }, \ 137 { XFS_TRANS_QM_QUOTAOFF, "QM_QUOTAOFF" }, \
139 { XFS_TRANS_QM_DQALLOC, "QM_DQALLOC" }, \ 138 { XFS_TRANS_QM_DQALLOC, "QM_DQALLOC" }, \
140 { XFS_TRANS_QM_SETQLIM, "QM_SETQLIM" }, \ 139 { XFS_TRANS_QM_SETQLIM, "QM_SETQLIM" }, \
141 { XFS_TRANS_QM_DQCLUSTER, "QM_DQCLUSTER" }, \ 140 { XFS_TRANS_QM_DQCLUSTER, "QM_DQCLUSTER" }, \
142 { XFS_TRANS_QM_QINOCREATE, "QM_QINOCREATE" }, \ 141 { XFS_TRANS_QM_QINOCREATE, "QM_QINOCREATE" }, \
143 { XFS_TRANS_QM_QUOTAOFF_END, "QM_QOFF_END" }, \ 142 { XFS_TRANS_QM_QUOTAOFF_END, "QM_QOFF_END" }, \
144 { XFS_TRANS_SB_UNIT, "SB_UNIT" }, \
145 { XFS_TRANS_FSYNC_TS, "FSYNC_TS" }, \ 143 { XFS_TRANS_FSYNC_TS, "FSYNC_TS" }, \
146 { XFS_TRANS_GROWFSRT_ALLOC, "GROWFSRT_ALLOC" }, \ 144 { XFS_TRANS_GROWFSRT_ALLOC, "GROWFSRT_ALLOC" }, \
147 { XFS_TRANS_GROWFSRT_ZERO, "GROWFSRT_ZERO" }, \ 145 { XFS_TRANS_GROWFSRT_ZERO, "GROWFSRT_ZERO" }, \
148 { XFS_TRANS_GROWFSRT_FREE, "GROWFSRT_FREE" }, \ 146 { XFS_TRANS_GROWFSRT_FREE, "GROWFSRT_FREE" }, \
149 { XFS_TRANS_SWAPEXT, "SWAPEXT" }, \ 147 { XFS_TRANS_SWAPEXT, "SWAPEXT" }, \
150 { XFS_TRANS_SB_COUNT, "SB_COUNT" }, \
151 { XFS_TRANS_CHECKPOINT, "CHECKPOINT" }, \ 148 { XFS_TRANS_CHECKPOINT, "CHECKPOINT" }, \
152 { XFS_TRANS_DUMMY1, "DUMMY1" }, \ 149 { XFS_TRANS_ICREATE, "ICREATE" }, \
153 { XFS_TRANS_DUMMY2, "DUMMY2" }, \ 150 { XFS_TRANS_CREATE_TMPFILE, "CREATE_TMPFILE" }, \
154 { XLOG_UNMOUNT_REC_TYPE, "UNMOUNT" } 151 { XLOG_UNMOUNT_REC_TYPE, "UNMOUNT" }
155 152
156/* 153/*
diff --git a/fs/xfs/libxfs/xfs_trans_resv.c b/fs/xfs/libxfs/xfs_trans_resv.c
index 6c1330f29050..68cb1e7bf2bb 100644
--- a/fs/xfs/libxfs/xfs_trans_resv.c
+++ b/fs/xfs/libxfs/xfs_trans_resv.c
@@ -716,17 +716,6 @@ xfs_calc_clear_agi_bucket_reservation(
716} 716}
717 717
718/* 718/*
719 * Clearing the quotaflags in the superblock.
720 * the super block for changing quota flags: sector size
721 */
722STATIC uint
723xfs_calc_qm_sbchange_reservation(
724 struct xfs_mount *mp)
725{
726 return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize);
727}
728
729/*
730 * Adjusting quota limits. 719 * Adjusting quota limits.
731 * the xfs_disk_dquot_t: sizeof(struct xfs_disk_dquot) 720 * the xfs_disk_dquot_t: sizeof(struct xfs_disk_dquot)
732 */ 721 */
@@ -864,9 +853,6 @@ xfs_trans_resv_calc(
864 * The following transactions are logged in logical format with 853 * The following transactions are logged in logical format with
865 * a default log count. 854 * a default log count.
866 */ 855 */
867 resp->tr_qm_sbchange.tr_logres = xfs_calc_qm_sbchange_reservation(mp);
868 resp->tr_qm_sbchange.tr_logcount = XFS_DEFAULT_LOG_COUNT;
869
870 resp->tr_qm_setqlim.tr_logres = xfs_calc_qm_setqlim_reservation(mp); 856 resp->tr_qm_setqlim.tr_logres = xfs_calc_qm_setqlim_reservation(mp);
871 resp->tr_qm_setqlim.tr_logcount = XFS_DEFAULT_LOG_COUNT; 857 resp->tr_qm_setqlim.tr_logcount = XFS_DEFAULT_LOG_COUNT;
872 858
diff --git a/fs/xfs/libxfs/xfs_trans_resv.h b/fs/xfs/libxfs/xfs_trans_resv.h
index 1097d14cd583..2d5bdfce6d8f 100644
--- a/fs/xfs/libxfs/xfs_trans_resv.h
+++ b/fs/xfs/libxfs/xfs_trans_resv.h
@@ -56,7 +56,6 @@ struct xfs_trans_resv {
56 struct xfs_trans_res tr_growrtalloc; /* grow realtime allocations */ 56 struct xfs_trans_res tr_growrtalloc; /* grow realtime allocations */
57 struct xfs_trans_res tr_growrtzero; /* grow realtime zeroing */ 57 struct xfs_trans_res tr_growrtzero; /* grow realtime zeroing */
58 struct xfs_trans_res tr_growrtfree; /* grow realtime freeing */ 58 struct xfs_trans_res tr_growrtfree; /* grow realtime freeing */
59 struct xfs_trans_res tr_qm_sbchange; /* change quota flags */
60 struct xfs_trans_res tr_qm_setqlim; /* adjust quota limits */ 59 struct xfs_trans_res tr_qm_setqlim; /* adjust quota limits */
61 struct xfs_trans_res tr_qm_dqalloc; /* allocate quota on disk */ 60 struct xfs_trans_res tr_qm_dqalloc; /* allocate quota on disk */
62 struct xfs_trans_res tr_qm_quotaoff; /* turn quota off */ 61 struct xfs_trans_res tr_qm_quotaoff; /* turn quota off */
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index 82af857405af..f7114527cd2f 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -756,35 +756,6 @@ out:
756 return 0; 756 return 0;
757} 757}
758 758
759/*
760 * Dump a transaction into the log that contains no real change. This is needed
761 * to be able to make the log dirty or stamp the current tail LSN into the log
762 * during the covering operation.
763 *
764 * We cannot use an inode here for this - that will push dirty state back up
765 * into the VFS and then periodic inode flushing will prevent log covering from
766 * making progress. Hence we log a field in the superblock instead and use a
767 * synchronous transaction to ensure the superblock is immediately unpinned
768 * and can be written back.
769 */
770int
771xfs_fs_log_dummy(
772 xfs_mount_t *mp)
773{
774 xfs_trans_t *tp;
775 int error;
776
777 tp = _xfs_trans_alloc(mp, XFS_TRANS_DUMMY1, KM_SLEEP);
778 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_sb, 0, 0);
779 if (error) {
780 xfs_trans_cancel(tp, 0);
781 return error;
782 }
783 xfs_mod_sb(tp);
784 xfs_trans_set_sync(tp);
785 return xfs_trans_commit(tp, 0);
786}
787
788int 759int
789xfs_fs_goingdown( 760xfs_fs_goingdown(
790 xfs_mount_t *mp, 761 xfs_mount_t *mp,
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index e408bf5a3ff7..2b8dcf2b3dd1 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -33,6 +33,7 @@
33#include "xfs_fsops.h" 33#include "xfs_fsops.h"
34#include "xfs_cksum.h" 34#include "xfs_cksum.h"
35#include "xfs_sysfs.h" 35#include "xfs_sysfs.h"
36#include "xfs_sb.h"
36 37
37kmem_zone_t *xfs_log_ticket_zone; 38kmem_zone_t *xfs_log_ticket_zone;
38 39
@@ -1290,9 +1291,20 @@ xfs_log_worker(
1290 struct xfs_mount *mp = log->l_mp; 1291 struct xfs_mount *mp = log->l_mp;
1291 1292
1292 /* dgc: errors ignored - not fatal and nowhere to report them */ 1293 /* dgc: errors ignored - not fatal and nowhere to report them */
1293 if (xfs_log_need_covered(mp)) 1294 if (xfs_log_need_covered(mp)) {
1294 xfs_fs_log_dummy(mp); 1295 /*
1295 else 1296 * Dump a transaction into the log that contains no real change.
1297 * This is needed to stamp the current tail LSN into the log
1298 * during the covering operation.
1299 *
1300 * We cannot use an inode here for this - that will push dirty
1301 * state back up into the VFS and then periodic inode flushing
1302 * will prevent log covering from making progress. Hence we
1303 * synchronously log the superblock instead to ensure the
1304 * superblock is immediately unpinned and can be written back.
1305 */
1306 xfs_sync_sb(mp, true);
1307 } else
1296 xfs_log_force(mp, 0); 1308 xfs_log_force(mp, 0);
1297 1309
1298 /* start pushing all the metadata that is currently dirty */ 1310 /* start pushing all the metadata that is currently dirty */
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 2953d46be249..5ef9aa2bfa19 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -408,11 +408,11 @@ xfs_update_alignment(xfs_mount_t *mp)
408 if (xfs_sb_version_hasdalign(sbp)) { 408 if (xfs_sb_version_hasdalign(sbp)) {
409 if (sbp->sb_unit != mp->m_dalign) { 409 if (sbp->sb_unit != mp->m_dalign) {
410 sbp->sb_unit = mp->m_dalign; 410 sbp->sb_unit = mp->m_dalign;
411 mp->m_update_flags |= XFS_SB_UNIT; 411 mp->m_update_sb = true;
412 } 412 }
413 if (sbp->sb_width != mp->m_swidth) { 413 if (sbp->sb_width != mp->m_swidth) {
414 sbp->sb_width = mp->m_swidth; 414 sbp->sb_width = mp->m_swidth;
415 mp->m_update_flags |= XFS_SB_WIDTH; 415 mp->m_update_sb = true;
416 } 416 }
417 } else { 417 } else {
418 xfs_warn(mp, 418 xfs_warn(mp,
@@ -583,38 +583,19 @@ int
583xfs_mount_reset_sbqflags( 583xfs_mount_reset_sbqflags(
584 struct xfs_mount *mp) 584 struct xfs_mount *mp)
585{ 585{
586 int error;
587 struct xfs_trans *tp;
588
589 mp->m_qflags = 0; 586 mp->m_qflags = 0;
590 587
591 /* 588 /* It is OK to look at sb_qflags in the mount path without m_sb_lock. */
592 * It is OK to look at sb_qflags here in mount path,
593 * without m_sb_lock.
594 */
595 if (mp->m_sb.sb_qflags == 0) 589 if (mp->m_sb.sb_qflags == 0)
596 return 0; 590 return 0;
597 spin_lock(&mp->m_sb_lock); 591 spin_lock(&mp->m_sb_lock);
598 mp->m_sb.sb_qflags = 0; 592 mp->m_sb.sb_qflags = 0;
599 spin_unlock(&mp->m_sb_lock); 593 spin_unlock(&mp->m_sb_lock);
600 594
601 /* 595 if (!xfs_fs_writable(mp, SB_FREEZE_WRITE))
602 * If the fs is readonly, let the incore superblock run
603 * with quotas off but don't flush the update out to disk
604 */
605 if (mp->m_flags & XFS_MOUNT_RDONLY)
606 return 0; 596 return 0;
607 597
608 tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SBCHANGE); 598 return xfs_sync_sb(mp, false);
609 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_qm_sbchange, 0, 0);
610 if (error) {
611 xfs_trans_cancel(tp, 0);
612 xfs_alert(mp, "%s: Superblock update failed!", __func__);
613 return error;
614 }
615
616 xfs_mod_sb(tp);
617 return xfs_trans_commit(tp, 0);
618} 599}
619 600
620__uint64_t 601__uint64_t
@@ -678,7 +659,7 @@ xfs_mountfs(
678 xfs_warn(mp, "correcting sb_features alignment problem"); 659 xfs_warn(mp, "correcting sb_features alignment problem");
679 sbp->sb_features2 |= sbp->sb_bad_features2; 660 sbp->sb_features2 |= sbp->sb_bad_features2;
680 sbp->sb_bad_features2 = sbp->sb_features2; 661 sbp->sb_bad_features2 = sbp->sb_features2;
681 mp->m_update_flags |= XFS_SB_FEATURES2 | XFS_SB_BAD_FEATURES2; 662 mp->m_update_sb = true;
682 663
683 /* 664 /*
684 * Re-check for ATTR2 in case it was found in bad_features2 665 * Re-check for ATTR2 in case it was found in bad_features2
@@ -692,17 +673,17 @@ xfs_mountfs(
692 if (xfs_sb_version_hasattr2(&mp->m_sb) && 673 if (xfs_sb_version_hasattr2(&mp->m_sb) &&
693 (mp->m_flags & XFS_MOUNT_NOATTR2)) { 674 (mp->m_flags & XFS_MOUNT_NOATTR2)) {
694 xfs_sb_version_removeattr2(&mp->m_sb); 675 xfs_sb_version_removeattr2(&mp->m_sb);
695 mp->m_update_flags |= XFS_SB_FEATURES2; 676 mp->m_update_sb = true;
696 677
697 /* update sb_versionnum for the clearing of the morebits */ 678 /* update sb_versionnum for the clearing of the morebits */
698 if (!sbp->sb_features2) 679 if (!sbp->sb_features2)
699 mp->m_update_flags |= XFS_SB_VERSIONNUM; 680 mp->m_update_sb = true;
700 } 681 }
701 682
702 /* always use v2 inodes by default now */ 683 /* always use v2 inodes by default now */
703 if (!(mp->m_sb.sb_versionnum & XFS_SB_VERSION_NLINKBIT)) { 684 if (!(mp->m_sb.sb_versionnum & XFS_SB_VERSION_NLINKBIT)) {
704 mp->m_sb.sb_versionnum |= XFS_SB_VERSION_NLINKBIT; 685 mp->m_sb.sb_versionnum |= XFS_SB_VERSION_NLINKBIT;
705 mp->m_update_flags |= XFS_SB_VERSIONNUM; 686 mp->m_update_sb = true;
706 } 687 }
707 688
708 /* 689 /*
@@ -895,8 +876,8 @@ xfs_mountfs(
895 * the next remount into writeable mode. Otherwise we would never 876 * the next remount into writeable mode. Otherwise we would never
896 * perform the update e.g. for the root filesystem. 877 * perform the update e.g. for the root filesystem.
897 */ 878 */
898 if (mp->m_update_flags && !(mp->m_flags & XFS_MOUNT_RDONLY)) { 879 if (mp->m_update_sb && !(mp->m_flags & XFS_MOUNT_RDONLY)) {
899 error = xfs_mount_log_sb(mp); 880 error = xfs_sync_sb(mp, false);
900 if (error) { 881 if (error) {
901 xfs_warn(mp, "failed to write sb changes"); 882 xfs_warn(mp, "failed to write sb changes");
902 goto out_rtunmount; 883 goto out_rtunmount;
@@ -1103,9 +1084,6 @@ xfs_fs_writable(
1103int 1084int
1104xfs_log_sbcount(xfs_mount_t *mp) 1085xfs_log_sbcount(xfs_mount_t *mp)
1105{ 1086{
1106 xfs_trans_t *tp;
1107 int error;
1108
1109 /* allow this to proceed during the freeze sequence... */ 1087 /* allow this to proceed during the freeze sequence... */
1110 if (!xfs_fs_writable(mp, SB_FREEZE_COMPLETE)) 1088 if (!xfs_fs_writable(mp, SB_FREEZE_COMPLETE))
1111 return 0; 1089 return 0;
@@ -1119,17 +1097,7 @@ xfs_log_sbcount(xfs_mount_t *mp)
1119 if (!xfs_sb_version_haslazysbcount(&mp->m_sb)) 1097 if (!xfs_sb_version_haslazysbcount(&mp->m_sb))
1120 return 0; 1098 return 0;
1121 1099
1122 tp = _xfs_trans_alloc(mp, XFS_TRANS_SB_COUNT, KM_SLEEP); 1100 return xfs_sync_sb(mp, true);
1123 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_sb, 0, 0);
1124 if (error) {
1125 xfs_trans_cancel(tp, 0);
1126 return error;
1127 }
1128
1129 xfs_mod_sb(tp);
1130 xfs_trans_set_sync(tp);
1131 error = xfs_trans_commit(tp, 0);
1132 return error;
1133} 1101}
1134 1102
1135/* 1103/*
@@ -1423,28 +1391,6 @@ xfs_freesb(
1423} 1391}
1424 1392
1425/* 1393/*
1426 * Used to log changes to the superblock unit and width fields which could
1427 * be altered by the mount options, as well as any potential sb_features2
1428 * fixup. Only the first superblock is updated.
1429 */
1430int
1431xfs_mount_log_sb(
1432 struct xfs_mount *mp)
1433{
1434 struct xfs_trans *tp;
1435 int error;
1436
1437 tp = xfs_trans_alloc(mp, XFS_TRANS_SB_UNIT);
1438 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_sb, 0, 0);
1439 if (error) {
1440 xfs_trans_cancel(tp, 0);
1441 return error;
1442 }
1443 xfs_mod_sb(tp);
1444 return xfs_trans_commit(tp, 0);
1445}
1446
1447/*
1448 * If the underlying (data/log/rt) device is readonly, there are some 1394 * If the underlying (data/log/rt) device is readonly, there are some
1449 * operations that cannot proceed. 1395 * operations that cannot proceed.
1450 */ 1396 */
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 28b341bf1555..a5b2ff822653 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -162,8 +162,7 @@ typedef struct xfs_mount {
162 struct delayed_work m_reclaim_work; /* background inode reclaim */ 162 struct delayed_work m_reclaim_work; /* background inode reclaim */
163 struct delayed_work m_eofblocks_work; /* background eof blocks 163 struct delayed_work m_eofblocks_work; /* background eof blocks
164 trimming */ 164 trimming */
165 __int64_t m_update_flags; /* sb flags we need to update 165 bool m_update_sb; /* sb needs update in mount */
166 on the next remount,rw */
167 int64_t m_low_space[XFS_LOWSP_MAX]; 166 int64_t m_low_space[XFS_LOWSP_MAX];
168 /* low free space thresholds */ 167 /* low free space thresholds */
169 struct xfs_kobj m_kobj; 168 struct xfs_kobj m_kobj;
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index c815a8060b59..3e8186279541 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -792,7 +792,7 @@ xfs_qm_qino_alloc(
792 else 792 else
793 mp->m_sb.sb_pquotino = (*ip)->i_ino; 793 mp->m_sb.sb_pquotino = (*ip)->i_ino;
794 spin_unlock(&mp->m_sb_lock); 794 spin_unlock(&mp->m_sb_lock);
795 xfs_mod_sb(tp); 795 xfs_log_sb(tp);
796 796
797 if ((error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES))) { 797 if ((error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES))) {
798 xfs_alert(mp, "%s failed (error %d)!", __func__, error); 798 xfs_alert(mp, "%s failed (error %d)!", __func__, error);
@@ -1445,7 +1445,7 @@ xfs_qm_mount_quotas(
1445 spin_unlock(&mp->m_sb_lock); 1445 spin_unlock(&mp->m_sb_lock);
1446 1446
1447 if (sbf != (mp->m_qflags & XFS_MOUNT_QUOTA_ALL)) { 1447 if (sbf != (mp->m_qflags & XFS_MOUNT_QUOTA_ALL)) {
1448 if (xfs_qm_write_sb_changes(mp)) { 1448 if (xfs_sync_sb(mp, false)) {
1449 /* 1449 /*
1450 * We could only have been turning quotas off. 1450 * We could only have been turning quotas off.
1451 * We aren't in very good shape actually because 1451 * We aren't in very good shape actually because
@@ -1574,29 +1574,6 @@ xfs_qm_dqfree_one(
1574 xfs_qm_dqdestroy(dqp); 1574 xfs_qm_dqdestroy(dqp);
1575} 1575}
1576 1576
1577/*
1578 * Start a transaction and write the incore superblock changes to
1579 * disk. flags parameter indicates which fields have changed.
1580 */
1581int
1582xfs_qm_write_sb_changes(
1583 struct xfs_mount *mp)
1584{
1585 xfs_trans_t *tp;
1586 int error;
1587
1588 tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SBCHANGE);
1589 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_qm_sbchange, 0, 0);
1590 if (error) {
1591 xfs_trans_cancel(tp, 0);
1592 return error;
1593 }
1594
1595 xfs_mod_sb(tp);
1596 return xfs_trans_commit(tp, 0);
1597}
1598
1599
1600/* --------------- utility functions for vnodeops ---------------- */ 1577/* --------------- utility functions for vnodeops ---------------- */
1601 1578
1602 1579
diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h
index bddd23fda9ce..d6e4d88094ab 100644
--- a/fs/xfs/xfs_qm.h
+++ b/fs/xfs/xfs_qm.h
@@ -157,7 +157,6 @@ struct xfs_dquot_acct {
157#define XFS_QM_RTBWARNLIMIT 5 157#define XFS_QM_RTBWARNLIMIT 5
158 158
159extern void xfs_qm_destroy_quotainfo(struct xfs_mount *); 159extern void xfs_qm_destroy_quotainfo(struct xfs_mount *);
160extern int xfs_qm_write_sb_changes(struct xfs_mount *);
161 160
162/* dquot stuff */ 161/* dquot stuff */
163extern void xfs_qm_dqpurge_all(struct xfs_mount *, uint); 162extern void xfs_qm_dqpurge_all(struct xfs_mount *, uint);
diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
index 8d7e5f068803..b8a565edb4ae 100644
--- a/fs/xfs/xfs_qm_syscalls.c
+++ b/fs/xfs/xfs_qm_syscalls.c
@@ -92,7 +92,7 @@ xfs_qm_scall_quotaoff(
92 mutex_unlock(&q->qi_quotaofflock); 92 mutex_unlock(&q->qi_quotaofflock);
93 93
94 /* XXX what to do if error ? Revert back to old vals incore ? */ 94 /* XXX what to do if error ? Revert back to old vals incore ? */
95 return xfs_qm_write_sb_changes(mp); 95 return xfs_sync_sb(mp, false);
96 } 96 }
97 97
98 dqtype = 0; 98 dqtype = 0;
@@ -369,7 +369,8 @@ xfs_qm_scall_quotaon(
369 if ((qf & flags) == flags) 369 if ((qf & flags) == flags)
370 return -EEXIST; 370 return -EEXIST;
371 371
372 if ((error = xfs_qm_write_sb_changes(mp))) 372 error = xfs_sync_sb(mp, false);
373 if (error)
373 return error; 374 return error;
374 /* 375 /*
375 * If we aren't trying to switch on quota enforcement, we are done. 376 * If we aren't trying to switch on quota enforcement, we are done.
@@ -796,7 +797,7 @@ xfs_qm_log_quotaoff(
796 mp->m_sb.sb_qflags = (mp->m_qflags & ~(flags)) & XFS_MOUNT_QUOTA_ALL; 797 mp->m_sb.sb_qflags = (mp->m_qflags & ~(flags)) & XFS_MOUNT_QUOTA_ALL;
797 spin_unlock(&mp->m_sb_lock); 798 spin_unlock(&mp->m_sb_lock);
798 799
799 xfs_mod_sb(tp); 800 xfs_log_sb(tp);
800 801
801 /* 802 /*
802 * We have to make sure that the transaction is secure on disk before we 803 * We have to make sure that the transaction is secure on disk before we
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 6fb298963d1b..a3b791b85336 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -1257,13 +1257,13 @@ xfs_fs_remount(
1257 * If this is the first remount to writeable state we 1257 * If this is the first remount to writeable state we
1258 * might have some superblock changes to update. 1258 * might have some superblock changes to update.
1259 */ 1259 */
1260 if (mp->m_update_flags) { 1260 if (mp->m_update_sb) {
1261 error = xfs_mount_log_sb(mp); 1261 error = xfs_sync_sb(mp, false);
1262 if (error) { 1262 if (error) {
1263 xfs_warn(mp, "failed to write sb changes"); 1263 xfs_warn(mp, "failed to write sb changes");
1264 return error; 1264 return error;
1265 } 1265 }
1266 mp->m_update_flags = 0; 1266 mp->m_update_sb = false;
1267 } 1267 }
1268 1268
1269 /* 1269 /*
@@ -1293,8 +1293,9 @@ xfs_fs_remount(
1293 1293
1294/* 1294/*
1295 * Second stage of a freeze. The data is already frozen so we only 1295 * Second stage of a freeze. The data is already frozen so we only
1296 * need to take care of the metadata. Once that's done write a dummy 1296 * need to take care of the metadata. Once that's done sync the superblock
1297 * record to dirty the log in case of a crash while frozen. 1297 * to the log to dirty it in case of a crash while frozen. This ensures that we
1298 * will recover the unlinked inode lists on the next mount.
1298 */ 1299 */
1299STATIC int 1300STATIC int
1300xfs_fs_freeze( 1301xfs_fs_freeze(
@@ -1304,7 +1305,7 @@ xfs_fs_freeze(
1304 1305
1305 xfs_save_resvblks(mp); 1306 xfs_save_resvblks(mp);
1306 xfs_quiesce_attr(mp); 1307 xfs_quiesce_attr(mp);
1307 return xfs_fs_log_dummy(mp); 1308 return xfs_sync_sb(mp, true);
1308} 1309}
1309 1310
1310STATIC int 1311STATIC int