aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2015-01-21 17:10:26 -0500
committerDave Chinner <david@fromorbit.com>2015-01-21 17:10:26 -0500
commit4d11a40239405e531fc0e9dcd07921f00b965931 (patch)
treef8a6b43d76e4d698f7cb1a5daf9027d2a2f22ca7 /fs/xfs
parent97bf6af1f928216fd6c5a66e8a57bfa95a659672 (diff)
xfs: remove bitfield based superblock updates
When we log changes to the superblock, we first have to write them to the on-disk buffer, and then log that. Right now we have a complex bitfield based arrangement to only write the modified field to the buffer before we log it. This used to be necessary as a performance optimisation because we logged the superblock buffer in every extent or inode allocation or freeing, and so performance was extremely important. We haven't done this for years, however, ever since the lazy superblock counters pulled the superblock logging out of the transaction commit fast path. Hence we have a bunch of complexity that is not necessary that makes writing the in-core superblock to disk much more complex than it needs to be. We only need to log the superblock now during management operations (e.g. during mount, unmount or quota control operations) so it is not a performance critical path anymore. As such, remove the complex field based logging mechanism and replace it with a simple conversion function similar to what we use for all other on-disk structures. This means we always log the entirity of the superblock, but again because we rarely modify the superblock this is not an issue for log bandwidth or CPU time. Indeed, if we do log the superblock frequently, delayed logging will minimise the impact of this overhead. [Fixed gquota/pquota inode sharing regression noticed by bfoster.] Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Brian Foster <bfoster@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/libxfs/xfs_attr_leaf.c2
-rw-r--r--fs/xfs/libxfs/xfs_bmap.c14
-rw-r--r--fs/xfs/libxfs/xfs_sb.c277
-rw-r--r--fs/xfs/libxfs/xfs_sb.h10
-rw-r--r--fs/xfs/xfs_fsops.c6
-rw-r--r--fs/xfs/xfs_mount.c22
-rw-r--r--fs/xfs/xfs_mount.h2
-rw-r--r--fs/xfs/xfs_qm.c26
-rw-r--r--fs/xfs/xfs_qm.h2
-rw-r--r--fs/xfs/xfs_qm_syscalls.c13
-rw-r--r--fs/xfs/xfs_super.c2
11 files changed, 130 insertions, 246 deletions
diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c
index 5d38e8b8a913..c9144221798f 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, XFS_SB_VERSIONNUM | XFS_SB_FEATURES2); 406 xfs_mod_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 b5eb4743f75a..8c39cc852e4b 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -1221,22 +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 __int64_t sbfields = 0; 1224 bool mod_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 sbfields |= XFS_SB_VERSIONNUM; 1229 mod_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 sbfields |= (XFS_SB_VERSIONNUM | XFS_SB_FEATURES2); 1233 mod_sb = true;
1234 } 1234 }
1235 if (sbfields) { 1235 spin_unlock(&mp->m_sb_lock);
1236 spin_unlock(&mp->m_sb_lock); 1236 if (mod_sb)
1237 xfs_mod_sb(tp, sbfields); 1237 xfs_mod_sb(tp);
1238 } else
1239 spin_unlock(&mp->m_sb_lock);
1240 } 1238 }
1241 1239
1242 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 752915fa775a..115a7cd3a6fb 100644
--- a/fs/xfs/libxfs/xfs_sb.c
+++ b/fs/xfs/libxfs/xfs_sb.c
@@ -40,69 +40,6 @@
40 * Physical superblock buffer manipulations. Shared with libxfs in userspace. 40 * Physical superblock buffer manipulations. Shared with libxfs in userspace.
41 */ 41 */
42 42
43static const struct {
44 short offset;
45 short type; /* 0 = integer
46 * 1 = binary / string (no translation)
47 */
48} xfs_sb_info[] = {
49 { offsetof(xfs_sb_t, sb_magicnum), 0 },
50 { offsetof(xfs_sb_t, sb_blocksize), 0 },
51 { offsetof(xfs_sb_t, sb_dblocks), 0 },
52 { offsetof(xfs_sb_t, sb_rblocks), 0 },
53 { offsetof(xfs_sb_t, sb_rextents), 0 },
54 { offsetof(xfs_sb_t, sb_uuid), 1 },
55 { offsetof(xfs_sb_t, sb_logstart), 0 },
56 { offsetof(xfs_sb_t, sb_rootino), 0 },
57 { offsetof(xfs_sb_t, sb_rbmino), 0 },
58 { offsetof(xfs_sb_t, sb_rsumino), 0 },
59 { offsetof(xfs_sb_t, sb_rextsize), 0 },
60 { offsetof(xfs_sb_t, sb_agblocks), 0 },
61 { offsetof(xfs_sb_t, sb_agcount), 0 },
62 { offsetof(xfs_sb_t, sb_rbmblocks), 0 },
63 { offsetof(xfs_sb_t, sb_logblocks), 0 },
64 { offsetof(xfs_sb_t, sb_versionnum), 0 },
65 { offsetof(xfs_sb_t, sb_sectsize), 0 },
66 { offsetof(xfs_sb_t, sb_inodesize), 0 },
67 { offsetof(xfs_sb_t, sb_inopblock), 0 },
68 { offsetof(xfs_sb_t, sb_fname[0]), 1 },
69 { offsetof(xfs_sb_t, sb_blocklog), 0 },
70 { offsetof(xfs_sb_t, sb_sectlog), 0 },
71 { offsetof(xfs_sb_t, sb_inodelog), 0 },
72 { offsetof(xfs_sb_t, sb_inopblog), 0 },
73 { offsetof(xfs_sb_t, sb_agblklog), 0 },
74 { offsetof(xfs_sb_t, sb_rextslog), 0 },
75 { offsetof(xfs_sb_t, sb_inprogress), 0 },
76 { offsetof(xfs_sb_t, sb_imax_pct), 0 },
77 { offsetof(xfs_sb_t, sb_icount), 0 },
78 { offsetof(xfs_sb_t, sb_ifree), 0 },
79 { offsetof(xfs_sb_t, sb_fdblocks), 0 },
80 { offsetof(xfs_sb_t, sb_frextents), 0 },
81 { offsetof(xfs_sb_t, sb_uquotino), 0 },
82 { offsetof(xfs_sb_t, sb_gquotino), 0 },
83 { offsetof(xfs_sb_t, sb_qflags), 0 },
84 { offsetof(xfs_sb_t, sb_flags), 0 },
85 { offsetof(xfs_sb_t, sb_shared_vn), 0 },
86 { offsetof(xfs_sb_t, sb_inoalignmt), 0 },
87 { offsetof(xfs_sb_t, sb_unit), 0 },
88 { offsetof(xfs_sb_t, sb_width), 0 },
89 { offsetof(xfs_sb_t, sb_dirblklog), 0 },
90 { offsetof(xfs_sb_t, sb_logsectlog), 0 },
91 { offsetof(xfs_sb_t, sb_logsectsize), 0 },
92 { offsetof(xfs_sb_t, sb_logsunit), 0 },
93 { offsetof(xfs_sb_t, sb_features2), 0 },
94 { offsetof(xfs_sb_t, sb_bad_features2), 0 },
95 { offsetof(xfs_sb_t, sb_features_compat), 0 },
96 { offsetof(xfs_sb_t, sb_features_ro_compat), 0 },
97 { offsetof(xfs_sb_t, sb_features_incompat), 0 },
98 { offsetof(xfs_sb_t, sb_features_log_incompat), 0 },
99 { offsetof(xfs_sb_t, sb_crc), 0 },
100 { offsetof(xfs_sb_t, sb_pad), 0 },
101 { offsetof(xfs_sb_t, sb_pquotino), 0 },
102 { offsetof(xfs_sb_t, sb_lsn), 0 },
103 { sizeof(xfs_sb_t), 0 }
104};
105
106/* 43/*
107 * Reference counting access wrappers to the perag structures. 44 * Reference counting access wrappers to the perag structures.
108 * Because we never free per-ag structures, the only thing we 45 * Because we never free per-ag structures, the only thing we
@@ -461,58 +398,49 @@ xfs_sb_from_disk(
461 __xfs_sb_from_disk(to, from, true); 398 __xfs_sb_from_disk(to, from, true);
462} 399}
463 400
464static inline void 401static void
465xfs_sb_quota_to_disk( 402xfs_sb_quota_to_disk(
466 xfs_dsb_t *to, 403 struct xfs_dsb *to,
467 xfs_sb_t *from, 404 struct xfs_sb *from)
468 __int64_t *fields)
469{ 405{
470 __uint16_t qflags = from->sb_qflags; 406 __uint16_t qflags = from->sb_qflags;
471 407
408 to->sb_uquotino = cpu_to_be64(from->sb_uquotino);
409 if (xfs_sb_version_has_pquotino(from)) {
410 to->sb_qflags = cpu_to_be16(from->sb_qflags);
411 to->sb_gquotino = cpu_to_be64(from->sb_gquotino);
412 to->sb_pquotino = cpu_to_be64(from->sb_pquotino);
413 return;
414 }
415
472 /* 416 /*
473 * We need to do these manipilations only if we are working 417 * The in-core version of sb_qflags do not have XFS_OQUOTA_*
474 * with an older version of on-disk superblock. 418 * flags, whereas the on-disk version does. So, convert incore
419 * XFS_{PG}QUOTA_* flags to on-disk XFS_OQUOTA_* flags.
475 */ 420 */
476 if (xfs_sb_version_has_pquotino(from)) 421 qflags &= ~(XFS_PQUOTA_ENFD | XFS_PQUOTA_CHKD |
477 return; 422 XFS_GQUOTA_ENFD | XFS_GQUOTA_CHKD);
478 423
479 if (*fields & XFS_SB_QFLAGS) { 424 if (from->sb_qflags &
480 /* 425 (XFS_PQUOTA_ENFD | XFS_GQUOTA_ENFD))
481 * The in-core version of sb_qflags do not have 426 qflags |= XFS_OQUOTA_ENFD;
482 * XFS_OQUOTA_* flags, whereas the on-disk version 427 if (from->sb_qflags &
483 * does. So, convert incore XFS_{PG}QUOTA_* flags 428 (XFS_PQUOTA_CHKD | XFS_GQUOTA_CHKD))
484 * to on-disk XFS_OQUOTA_* flags. 429 qflags |= XFS_OQUOTA_CHKD;
485 */ 430 to->sb_qflags = cpu_to_be16(qflags);
486 qflags &= ~(XFS_PQUOTA_ENFD | XFS_PQUOTA_CHKD |
487 XFS_GQUOTA_ENFD | XFS_GQUOTA_CHKD);
488
489 if (from->sb_qflags &
490 (XFS_PQUOTA_ENFD | XFS_GQUOTA_ENFD))
491 qflags |= XFS_OQUOTA_ENFD;
492 if (from->sb_qflags &
493 (XFS_PQUOTA_CHKD | XFS_GQUOTA_CHKD))
494 qflags |= XFS_OQUOTA_CHKD;
495 to->sb_qflags = cpu_to_be16(qflags);
496 *fields &= ~XFS_SB_QFLAGS;
497 }
498 431
499 /* 432 /*
500 * GQUOTINO and PQUOTINO cannot be used together in versions of 433 * GQUOTINO and PQUOTINO cannot be used together in versions
501 * superblock that do not have pquotino. from->sb_flags tells us which 434 * of superblock that do not have pquotino. from->sb_flags
502 * quota is active and should be copied to disk. If neither are active, 435 * tells us which quota is active and should be copied to
503 * make sure we write NULLFSINO to the sb_gquotino field as a quota 436 * disk. If neither are active, we should NULL the inode.
504 * inode value of "0" is invalid when the XFS_SB_VERSION_QUOTA feature
505 * bit is set.
506 * 437 *
507 * Note that we don't need to handle the sb_uquotino or sb_pquotino here 438 * In all cases, the separate pquotino must remain 0 because it
508 * as they do not require any translation. Hence the main sb field loop 439 * it beyond the "end" of the valid non-pquotino superblock.
509 * will write them appropriately from the in-core superblock.
510 */ 440 */
511 if ((*fields & XFS_SB_GQUOTINO) && 441 if (from->sb_qflags & XFS_GQUOTA_ACCT)
512 (from->sb_qflags & XFS_GQUOTA_ACCT))
513 to->sb_gquotino = cpu_to_be64(from->sb_gquotino); 442 to->sb_gquotino = cpu_to_be64(from->sb_gquotino);
514 else if ((*fields & XFS_SB_PQUOTINO) && 443 else if (from->sb_qflags & XFS_PQUOTA_ACCT)
515 (from->sb_qflags & XFS_PQUOTA_ACCT))
516 to->sb_gquotino = cpu_to_be64(from->sb_pquotino); 444 to->sb_gquotino = cpu_to_be64(from->sb_pquotino);
517 else { 445 else {
518 /* 446 /*
@@ -526,63 +454,72 @@ xfs_sb_quota_to_disk(
526 to->sb_gquotino = cpu_to_be64(NULLFSINO); 454 to->sb_gquotino = cpu_to_be64(NULLFSINO);
527 } 455 }
528 456
529 *fields &= ~(XFS_SB_PQUOTINO | XFS_SB_GQUOTINO); 457 to->sb_pquotino = 0;
530} 458}
531 459
532/*
533 * Copy in core superblock to ondisk one.
534 *
535 * The fields argument is mask of superblock fields to copy.
536 */
537void 460void
538xfs_sb_to_disk( 461xfs_sb_to_disk(
539 xfs_dsb_t *to, 462 struct xfs_dsb *to,
540 xfs_sb_t *from, 463 struct xfs_sb *from)
541 __int64_t fields)
542{ 464{
543 xfs_caddr_t to_ptr = (xfs_caddr_t)to; 465 xfs_sb_quota_to_disk(to, from);
544 xfs_caddr_t from_ptr = (xfs_caddr_t)from; 466
545 xfs_sb_field_t f; 467 to->sb_magicnum = cpu_to_be32(from->sb_magicnum);
546 int first; 468 to->sb_blocksize = cpu_to_be32(from->sb_blocksize);
547 int size; 469 to->sb_dblocks = cpu_to_be64(from->sb_dblocks);
548 470 to->sb_rblocks = cpu_to_be64(from->sb_rblocks);
549 ASSERT(fields); 471 to->sb_rextents = cpu_to_be64(from->sb_rextents);
550 if (!fields) 472 memcpy(&to->sb_uuid, &from->sb_uuid, sizeof(to->sb_uuid));
551 return; 473 to->sb_logstart = cpu_to_be64(from->sb_logstart);
474 to->sb_rootino = cpu_to_be64(from->sb_rootino);
475 to->sb_rbmino = cpu_to_be64(from->sb_rbmino);
476 to->sb_rsumino = cpu_to_be64(from->sb_rsumino);
477 to->sb_rextsize = cpu_to_be32(from->sb_rextsize);
478 to->sb_agblocks = cpu_to_be32(from->sb_agblocks);
479 to->sb_agcount = cpu_to_be32(from->sb_agcount);
480 to->sb_rbmblocks = cpu_to_be32(from->sb_rbmblocks);
481 to->sb_logblocks = cpu_to_be32(from->sb_logblocks);
482 to->sb_versionnum = cpu_to_be16(from->sb_versionnum);
483 to->sb_sectsize = cpu_to_be16(from->sb_sectsize);
484 to->sb_inodesize = cpu_to_be16(from->sb_inodesize);
485 to->sb_inopblock = cpu_to_be16(from->sb_inopblock);
486 memcpy(&to->sb_fname, &from->sb_fname, sizeof(to->sb_fname));
487 to->sb_blocklog = from->sb_blocklog;
488 to->sb_sectlog = from->sb_sectlog;
489 to->sb_inodelog = from->sb_inodelog;
490 to->sb_inopblog = from->sb_inopblog;
491 to->sb_agblklog = from->sb_agblklog;
492 to->sb_rextslog = from->sb_rextslog;
493 to->sb_inprogress = from->sb_inprogress;
494 to->sb_imax_pct = from->sb_imax_pct;
495 to->sb_icount = cpu_to_be64(from->sb_icount);
496 to->sb_ifree = cpu_to_be64(from->sb_ifree);
497 to->sb_fdblocks = cpu_to_be64(from->sb_fdblocks);
498 to->sb_frextents = cpu_to_be64(from->sb_frextents);
552 499
553 /* We should never write the crc here, it's updated in the IO path */
554 fields &= ~XFS_SB_CRC;
555
556 xfs_sb_quota_to_disk(to, from, &fields);
557 while (fields) {
558 f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields);
559 first = xfs_sb_info[f].offset;
560 size = xfs_sb_info[f + 1].offset - first;
561
562 ASSERT(xfs_sb_info[f].type == 0 || xfs_sb_info[f].type == 1);
563
564 if (size == 1 || xfs_sb_info[f].type == 1) {
565 memcpy(to_ptr + first, from_ptr + first, size);
566 } else {
567 switch (size) {
568 case 2:
569 *(__be16 *)(to_ptr + first) =
570 cpu_to_be16(*(__u16 *)(from_ptr + first));
571 break;
572 case 4:
573 *(__be32 *)(to_ptr + first) =
574 cpu_to_be32(*(__u32 *)(from_ptr + first));
575 break;
576 case 8:
577 *(__be64 *)(to_ptr + first) =
578 cpu_to_be64(*(__u64 *)(from_ptr + first));
579 break;
580 default:
581 ASSERT(0);
582 }
583 }
584 500
585 fields &= ~(1LL << f); 501 to->sb_flags = from->sb_flags;
502 to->sb_shared_vn = from->sb_shared_vn;
503 to->sb_inoalignmt = cpu_to_be32(from->sb_inoalignmt);
504 to->sb_unit = cpu_to_be32(from->sb_unit);
505 to->sb_width = cpu_to_be32(from->sb_width);
506 to->sb_dirblklog = from->sb_dirblklog;
507 to->sb_logsectlog = from->sb_logsectlog;
508 to->sb_logsectsize = cpu_to_be16(from->sb_logsectsize);
509 to->sb_logsunit = cpu_to_be32(from->sb_logsunit);
510 to->sb_features2 = cpu_to_be32(from->sb_features2);
511 to->sb_bad_features2 = cpu_to_be32(from->sb_bad_features2);
512
513 if (xfs_sb_version_hascrc(from)) {
514 to->sb_features_compat = cpu_to_be32(from->sb_features_compat);
515 to->sb_features_ro_compat =
516 cpu_to_be32(from->sb_features_ro_compat);
517 to->sb_features_incompat =
518 cpu_to_be32(from->sb_features_incompat);
519 to->sb_features_log_incompat =
520 cpu_to_be32(from->sb_features_log_incompat);
521 to->sb_pad = 0;
522 to->sb_lsn = cpu_to_be64(from->sb_lsn);
586 } 523 }
587} 524}
588 525
@@ -823,35 +760,13 @@ xfs_initialize_perag_data(
823 * access. 760 * access.
824 */ 761 */
825void 762void
826xfs_mod_sb(xfs_trans_t *tp, __int64_t fields) 763xfs_mod_sb(
764 struct xfs_trans *tp)
827{ 765{
828 xfs_buf_t *bp; 766 struct xfs_mount *mp = tp->t_mountp;
829 int first; 767 struct xfs_buf *bp = xfs_trans_getsb(tp, mp, 0);
830 int last;
831 xfs_mount_t *mp;
832 xfs_sb_field_t f;
833
834 ASSERT(fields);
835 if (!fields)
836 return;
837 mp = tp->t_mountp;
838 bp = xfs_trans_getsb(tp, mp, 0);
839 first = sizeof(xfs_sb_t);
840 last = 0;
841
842 /* translate/copy */
843
844 xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb, fields);
845
846 /* find modified range */
847 f = (xfs_sb_field_t)xfs_highbit64((__uint64_t)fields);
848 ASSERT((1LL << f) & XFS_SB_MOD_BITS);
849 last = xfs_sb_info[f + 1].offset - 1;
850
851 f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields);
852 ASSERT((1LL << f) & XFS_SB_MOD_BITS);
853 first = xfs_sb_info[f].offset;
854 768
769 xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb);
855 xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SB_BUF); 770 xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SB_BUF);
856 xfs_trans_log_buf(tp, bp, first, last); 771 xfs_trans_log_buf(tp, bp, 0, sizeof(struct xfs_dsb));
857} 772}
diff --git a/fs/xfs/libxfs/xfs_sb.h b/fs/xfs/libxfs/xfs_sb.h
index 8eb1c54bafbf..e193caa42988 100644
--- a/fs/xfs/libxfs/xfs_sb.h
+++ b/fs/xfs/libxfs/xfs_sb.h
@@ -27,11 +27,11 @@ extern struct xfs_perag *xfs_perag_get_tag(struct xfs_mount *, xfs_agnumber_t,
27extern void xfs_perag_put(struct xfs_perag *pag); 27extern 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 *); 30extern void xfs_sb_calc_crc(struct xfs_buf *bp);
31extern void xfs_mod_sb(struct xfs_trans *, __int64_t); 31extern void xfs_mod_sb(struct xfs_trans *tp);
32extern void xfs_sb_mount_common(struct xfs_mount *, struct xfs_sb *); 32extern void xfs_sb_mount_common(struct xfs_mount *mp, struct xfs_sb *sbp);
33extern void xfs_sb_from_disk(struct xfs_sb *, struct xfs_dsb *); 33extern void xfs_sb_from_disk(struct xfs_sb *to, struct xfs_dsb *from);
34extern void xfs_sb_to_disk(struct xfs_dsb *, struct xfs_sb *, __int64_t); 34extern void xfs_sb_to_disk(struct xfs_dsb *to, struct xfs_sb *from);
35extern void xfs_sb_quota_from_disk(struct xfs_sb *sbp); 35extern void xfs_sb_quota_from_disk(struct xfs_sb *sbp);
36 36
37#endif /* __XFS_SB_H__ */ 37#endif /* __XFS_SB_H__ */
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index fdc64220fcb0..82af857405af 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -541,7 +541,7 @@ xfs_growfs_data_private(
541 saved_error = error; 541 saved_error = error;
542 continue; 542 continue;
543 } 543 }
544 xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb, XFS_SB_ALL_BITS); 544 xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb);
545 545
546 error = xfs_bwrite(bp); 546 error = xfs_bwrite(bp);
547 xfs_buf_relse(bp); 547 xfs_buf_relse(bp);
@@ -780,9 +780,7 @@ xfs_fs_log_dummy(
780 xfs_trans_cancel(tp, 0); 780 xfs_trans_cancel(tp, 0);
781 return error; 781 return error;
782 } 782 }
783 783 xfs_mod_sb(tp);
784 /* log the UUID because it is an unchanging field */
785 xfs_mod_sb(tp, XFS_SB_UUID);
786 xfs_trans_set_sync(tp); 784 xfs_trans_set_sync(tp);
787 return xfs_trans_commit(tp, 0); 785 return xfs_trans_commit(tp, 0);
788} 786}
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index d3d38836f87f..2953d46be249 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -613,7 +613,7 @@ xfs_mount_reset_sbqflags(
613 return error; 613 return error;
614 } 614 }
615 615
616 xfs_mod_sb(tp, XFS_SB_QFLAGS); 616 xfs_mod_sb(tp);
617 return xfs_trans_commit(tp, 0); 617 return xfs_trans_commit(tp, 0);
618} 618}
619 619
@@ -896,7 +896,7 @@ xfs_mountfs(
896 * perform the update e.g. for the root filesystem. 896 * perform the update e.g. for the root filesystem.
897 */ 897 */
898 if (mp->m_update_flags && !(mp->m_flags & XFS_MOUNT_RDONLY)) { 898 if (mp->m_update_flags && !(mp->m_flags & XFS_MOUNT_RDONLY)) {
899 error = xfs_mount_log_sb(mp, mp->m_update_flags); 899 error = xfs_mount_log_sb(mp);
900 if (error) { 900 if (error) {
901 xfs_warn(mp, "failed to write sb changes"); 901 xfs_warn(mp, "failed to write sb changes");
902 goto out_rtunmount; 902 goto out_rtunmount;
@@ -1126,7 +1126,7 @@ xfs_log_sbcount(xfs_mount_t *mp)
1126 return error; 1126 return error;
1127 } 1127 }
1128 1128
1129 xfs_mod_sb(tp, XFS_SB_IFREE | XFS_SB_ICOUNT | XFS_SB_FDBLOCKS); 1129 xfs_mod_sb(tp);
1130 xfs_trans_set_sync(tp); 1130 xfs_trans_set_sync(tp);
1131 error = xfs_trans_commit(tp, 0); 1131 error = xfs_trans_commit(tp, 0);
1132 return error; 1132 return error;
@@ -1429,15 +1429,10 @@ xfs_freesb(
1429 */ 1429 */
1430int 1430int
1431xfs_mount_log_sb( 1431xfs_mount_log_sb(
1432 xfs_mount_t *mp, 1432 struct xfs_mount *mp)
1433 __int64_t fields)
1434{ 1433{
1435 xfs_trans_t *tp; 1434 struct xfs_trans *tp;
1436 int error; 1435 int error;
1437
1438 ASSERT(fields & (XFS_SB_UNIT | XFS_SB_WIDTH | XFS_SB_UUID |
1439 XFS_SB_FEATURES2 | XFS_SB_BAD_FEATURES2 |
1440 XFS_SB_VERSIONNUM));
1441 1436
1442 tp = xfs_trans_alloc(mp, XFS_TRANS_SB_UNIT); 1437 tp = xfs_trans_alloc(mp, XFS_TRANS_SB_UNIT);
1443 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_sb, 0, 0); 1438 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_sb, 0, 0);
@@ -1445,9 +1440,8 @@ xfs_mount_log_sb(
1445 xfs_trans_cancel(tp, 0); 1440 xfs_trans_cancel(tp, 0);
1446 return error; 1441 return error;
1447 } 1442 }
1448 xfs_mod_sb(tp, fields); 1443 xfs_mod_sb(tp);
1449 error = xfs_trans_commit(tp, 0); 1444 return xfs_trans_commit(tp, 0);
1450 return error;
1451} 1445}
1452 1446
1453/* 1447/*
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 22ccf69d4d3c..28b341bf1555 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -378,7 +378,7 @@ extern void xfs_unmountfs(xfs_mount_t *);
378extern int xfs_mod_incore_sb(xfs_mount_t *, xfs_sb_field_t, int64_t, int); 378extern int xfs_mod_incore_sb(xfs_mount_t *, xfs_sb_field_t, int64_t, int);
379extern int xfs_mod_incore_sb_batch(xfs_mount_t *, xfs_mod_sb_t *, 379extern int xfs_mod_incore_sb_batch(xfs_mount_t *, xfs_mod_sb_t *,
380 uint, int); 380 uint, int);
381extern int xfs_mount_log_sb(xfs_mount_t *, __int64_t); 381extern int xfs_mount_log_sb(xfs_mount_t *);
382extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int); 382extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int);
383extern int xfs_readsb(xfs_mount_t *, int); 383extern int xfs_readsb(xfs_mount_t *, int);
384extern void xfs_freesb(xfs_mount_t *); 384extern void xfs_freesb(xfs_mount_t *);
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index 79fb19dd9c83..c815a8060b59 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -714,7 +714,6 @@ STATIC int
714xfs_qm_qino_alloc( 714xfs_qm_qino_alloc(
715 xfs_mount_t *mp, 715 xfs_mount_t *mp,
716 xfs_inode_t **ip, 716 xfs_inode_t **ip,
717 __int64_t sbfields,
718 uint flags) 717 uint flags)
719{ 718{
720 xfs_trans_t *tp; 719 xfs_trans_t *tp;
@@ -777,11 +776,6 @@ xfs_qm_qino_alloc(
777 spin_lock(&mp->m_sb_lock); 776 spin_lock(&mp->m_sb_lock);
778 if (flags & XFS_QMOPT_SBVERSION) { 777 if (flags & XFS_QMOPT_SBVERSION) {
779 ASSERT(!xfs_sb_version_hasquota(&mp->m_sb)); 778 ASSERT(!xfs_sb_version_hasquota(&mp->m_sb));
780 ASSERT((sbfields & (XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO |
781 XFS_SB_GQUOTINO | XFS_SB_PQUOTINO | XFS_SB_QFLAGS)) ==
782 (XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO |
783 XFS_SB_GQUOTINO | XFS_SB_PQUOTINO |
784 XFS_SB_QFLAGS));
785 779
786 xfs_sb_version_addquota(&mp->m_sb); 780 xfs_sb_version_addquota(&mp->m_sb);
787 mp->m_sb.sb_uquotino = NULLFSINO; 781 mp->m_sb.sb_uquotino = NULLFSINO;
@@ -798,7 +792,7 @@ xfs_qm_qino_alloc(
798 else 792 else
799 mp->m_sb.sb_pquotino = (*ip)->i_ino; 793 mp->m_sb.sb_pquotino = (*ip)->i_ino;
800 spin_unlock(&mp->m_sb_lock); 794 spin_unlock(&mp->m_sb_lock);
801 xfs_mod_sb(tp, sbfields); 795 xfs_mod_sb(tp);
802 796
803 if ((error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES))) { 797 if ((error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES))) {
804 xfs_alert(mp, "%s failed (error %d)!", __func__, error); 798 xfs_alert(mp, "%s failed (error %d)!", __func__, error);
@@ -1451,7 +1445,7 @@ xfs_qm_mount_quotas(
1451 spin_unlock(&mp->m_sb_lock); 1445 spin_unlock(&mp->m_sb_lock);
1452 1446
1453 if (sbf != (mp->m_qflags & XFS_MOUNT_QUOTA_ALL)) { 1447 if (sbf != (mp->m_qflags & XFS_MOUNT_QUOTA_ALL)) {
1454 if (xfs_qm_write_sb_changes(mp, XFS_SB_QFLAGS)) { 1448 if (xfs_qm_write_sb_changes(mp)) {
1455 /* 1449 /*
1456 * We could only have been turning quotas off. 1450 * We could only have been turning quotas off.
1457 * We aren't in very good shape actually because 1451 * We aren't in very good shape actually because
@@ -1482,7 +1476,6 @@ xfs_qm_init_quotainos(
1482 struct xfs_inode *gip = NULL; 1476 struct xfs_inode *gip = NULL;
1483 struct xfs_inode *pip = NULL; 1477 struct xfs_inode *pip = NULL;
1484 int error; 1478 int error;
1485 __int64_t sbflags = 0;
1486 uint flags = 0; 1479 uint flags = 0;
1487 1480
1488 ASSERT(mp->m_quotainfo); 1481 ASSERT(mp->m_quotainfo);
@@ -1517,9 +1510,6 @@ xfs_qm_init_quotainos(
1517 } 1510 }
1518 } else { 1511 } else {
1519 flags |= XFS_QMOPT_SBVERSION; 1512 flags |= XFS_QMOPT_SBVERSION;
1520 sbflags |= (XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO |
1521 XFS_SB_GQUOTINO | XFS_SB_PQUOTINO |
1522 XFS_SB_QFLAGS);
1523 } 1513 }
1524 1514
1525 /* 1515 /*
@@ -1530,7 +1520,6 @@ xfs_qm_init_quotainos(
1530 */ 1520 */
1531 if (XFS_IS_UQUOTA_ON(mp) && uip == NULL) { 1521 if (XFS_IS_UQUOTA_ON(mp) && uip == NULL) {
1532 error = xfs_qm_qino_alloc(mp, &uip, 1522 error = xfs_qm_qino_alloc(mp, &uip,
1533 sbflags | XFS_SB_UQUOTINO,
1534 flags | XFS_QMOPT_UQUOTA); 1523 flags | XFS_QMOPT_UQUOTA);
1535 if (error) 1524 if (error)
1536 goto error_rele; 1525 goto error_rele;
@@ -1539,7 +1528,6 @@ xfs_qm_init_quotainos(
1539 } 1528 }
1540 if (XFS_IS_GQUOTA_ON(mp) && gip == NULL) { 1529 if (XFS_IS_GQUOTA_ON(mp) && gip == NULL) {
1541 error = xfs_qm_qino_alloc(mp, &gip, 1530 error = xfs_qm_qino_alloc(mp, &gip,
1542 sbflags | XFS_SB_GQUOTINO,
1543 flags | XFS_QMOPT_GQUOTA); 1531 flags | XFS_QMOPT_GQUOTA);
1544 if (error) 1532 if (error)
1545 goto error_rele; 1533 goto error_rele;
@@ -1548,7 +1536,6 @@ xfs_qm_init_quotainos(
1548 } 1536 }
1549 if (XFS_IS_PQUOTA_ON(mp) && pip == NULL) { 1537 if (XFS_IS_PQUOTA_ON(mp) && pip == NULL) {
1550 error = xfs_qm_qino_alloc(mp, &pip, 1538 error = xfs_qm_qino_alloc(mp, &pip,
1551 sbflags | XFS_SB_PQUOTINO,
1552 flags | XFS_QMOPT_PQUOTA); 1539 flags | XFS_QMOPT_PQUOTA);
1553 if (error) 1540 if (error)
1554 goto error_rele; 1541 goto error_rele;
@@ -1593,8 +1580,7 @@ xfs_qm_dqfree_one(
1593 */ 1580 */
1594int 1581int
1595xfs_qm_write_sb_changes( 1582xfs_qm_write_sb_changes(
1596 xfs_mount_t *mp, 1583 struct xfs_mount *mp)
1597 __int64_t flags)
1598{ 1584{
1599 xfs_trans_t *tp; 1585 xfs_trans_t *tp;
1600 int error; 1586 int error;
@@ -1606,10 +1592,8 @@ xfs_qm_write_sb_changes(
1606 return error; 1592 return error;
1607 } 1593 }
1608 1594
1609 xfs_mod_sb(tp, flags); 1595 xfs_mod_sb(tp);
1610 error = xfs_trans_commit(tp, 0); 1596 return xfs_trans_commit(tp, 0);
1611
1612 return error;
1613} 1597}
1614 1598
1615 1599
diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h
index 3a07a937e232..bddd23fda9ce 100644
--- a/fs/xfs/xfs_qm.h
+++ b/fs/xfs/xfs_qm.h
@@ -157,7 +157,7 @@ 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 *, __int64_t); 160extern int xfs_qm_write_sb_changes(struct xfs_mount *);
161 161
162/* dquot stuff */ 162/* dquot stuff */
163extern void xfs_qm_dqpurge_all(struct xfs_mount *, uint); 163extern 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 74fca68e43b6..8d7e5f068803 100644
--- a/fs/xfs/xfs_qm_syscalls.c
+++ b/fs/xfs/xfs_qm_syscalls.c
@@ -92,8 +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 error = xfs_qm_write_sb_changes(mp, XFS_SB_QFLAGS); 95 return xfs_qm_write_sb_changes(mp);
96 return error;
97 } 96 }
98 97
99 dqtype = 0; 98 dqtype = 0;
@@ -314,7 +313,6 @@ xfs_qm_scall_quotaon(
314{ 313{
315 int error; 314 int error;
316 uint qf; 315 uint qf;
317 __int64_t sbflags;
318 316
319 flags &= (XFS_ALL_QUOTA_ACCT | XFS_ALL_QUOTA_ENFD); 317 flags &= (XFS_ALL_QUOTA_ACCT | XFS_ALL_QUOTA_ENFD);
320 /* 318 /*
@@ -322,8 +320,6 @@ xfs_qm_scall_quotaon(
322 */ 320 */
323 flags &= ~(XFS_ALL_QUOTA_ACCT); 321 flags &= ~(XFS_ALL_QUOTA_ACCT);
324 322
325 sbflags = 0;
326
327 if (flags == 0) { 323 if (flags == 0) {
328 xfs_debug(mp, "%s: zero flags, m_qflags=%x", 324 xfs_debug(mp, "%s: zero flags, m_qflags=%x",
329 __func__, mp->m_qflags); 325 __func__, mp->m_qflags);
@@ -370,11 +366,10 @@ xfs_qm_scall_quotaon(
370 /* 366 /*
371 * There's nothing to change if it's the same. 367 * There's nothing to change if it's the same.
372 */ 368 */
373 if ((qf & flags) == flags && sbflags == 0) 369 if ((qf & flags) == flags)
374 return -EEXIST; 370 return -EEXIST;
375 sbflags |= XFS_SB_QFLAGS;
376 371
377 if ((error = xfs_qm_write_sb_changes(mp, sbflags))) 372 if ((error = xfs_qm_write_sb_changes(mp)))
378 return error; 373 return error;
379 /* 374 /*
380 * If we aren't trying to switch on quota enforcement, we are done. 375 * If we aren't trying to switch on quota enforcement, we are done.
@@ -801,7 +796,7 @@ xfs_qm_log_quotaoff(
801 mp->m_sb.sb_qflags = (mp->m_qflags & ~(flags)) & XFS_MOUNT_QUOTA_ALL; 796 mp->m_sb.sb_qflags = (mp->m_qflags & ~(flags)) & XFS_MOUNT_QUOTA_ALL;
802 spin_unlock(&mp->m_sb_lock); 797 spin_unlock(&mp->m_sb_lock);
803 798
804 xfs_mod_sb(tp, XFS_SB_QFLAGS); 799 xfs_mod_sb(tp);
805 800
806 /* 801 /*
807 * We have to make sure that the transaction is secure on disk before we 802 * 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 19cbda196369..6fb298963d1b 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -1258,7 +1258,7 @@ xfs_fs_remount(
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_flags) {
1261 error = xfs_mount_log_sb(mp, mp->m_update_flags); 1261 error = xfs_mount_log_sb(mp);
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;