summaryrefslogtreecommitdiff
path: root/fs/xfs/xfs_mount.c
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2015-01-22 01:10:26 +0300
committerDave Chinner <david@fromorbit.com>2015-01-22 01:10:26 +0300
commit4d11a40239405e531fc0e9dcd07921f00b965931 (patch)
treef8a6b43d76e4d698f7cb1a5daf9027d2a2f22ca7 /fs/xfs/xfs_mount.c
parent97bf6af1f928216fd6c5a66e8a57bfa95a659672 (diff)
downloadlinux-4d11a40239405e531fc0e9dcd07921f00b965931.tar.xz
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/xfs_mount.c')
-rw-r--r--fs/xfs/xfs_mount.c22
1 files changed, 8 insertions, 14 deletions
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(
return error;
}
- xfs_mod_sb(tp, XFS_SB_QFLAGS);
+ xfs_mod_sb(tp);
return xfs_trans_commit(tp, 0);
}
@@ -896,7 +896,7 @@ xfs_mountfs(
* perform the update e.g. for the root filesystem.
*/
if (mp->m_update_flags && !(mp->m_flags & XFS_MOUNT_RDONLY)) {
- error = xfs_mount_log_sb(mp, mp->m_update_flags);
+ error = xfs_mount_log_sb(mp);
if (error) {
xfs_warn(mp, "failed to write sb changes");
goto out_rtunmount;
@@ -1126,7 +1126,7 @@ xfs_log_sbcount(xfs_mount_t *mp)
return error;
}
- xfs_mod_sb(tp, XFS_SB_IFREE | XFS_SB_ICOUNT | XFS_SB_FDBLOCKS);
+ xfs_mod_sb(tp);
xfs_trans_set_sync(tp);
error = xfs_trans_commit(tp, 0);
return error;
@@ -1429,15 +1429,10 @@ xfs_freesb(
*/
int
xfs_mount_log_sb(
- xfs_mount_t *mp,
- __int64_t fields)
+ struct xfs_mount *mp)
{
- xfs_trans_t *tp;
- int error;
-
- ASSERT(fields & (XFS_SB_UNIT | XFS_SB_WIDTH | XFS_SB_UUID |
- XFS_SB_FEATURES2 | XFS_SB_BAD_FEATURES2 |
- XFS_SB_VERSIONNUM));
+ struct xfs_trans *tp;
+ int error;
tp = xfs_trans_alloc(mp, XFS_TRANS_SB_UNIT);
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_sb, 0, 0);
@@ -1445,9 +1440,8 @@ xfs_mount_log_sb(
xfs_trans_cancel(tp, 0);
return error;
}
- xfs_mod_sb(tp, fields);
- error = xfs_trans_commit(tp, 0);
- return error;
+ xfs_mod_sb(tp);
+ return xfs_trans_commit(tp, 0);
}
/*