xfs: superblock logging rework
v2 cover xfs: superblock logging rework
Hi folks,
This is an updated version of the superblock logging simplification patch series I first sent here:
http://oss.sgi.com/archives/xfs/2014-07/msg00465.html
Version 2:
- added initial patch to sanitse xfs_fs_writeable
- updated comments to describe caller requirements for xfs_sync_sb()
-Dave.
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH v2 1/3 xfs: consider freeze levels in xfs_fs_writable()
From: Dave Chinner <[email protected]>
The filesystem is still writable in certain circumstances while a freeze is in progress but xfs_fs_writable() does not reflect that. In some code we want to check whether the fs is writable, and the context we can be called under varies because the code call be called from under both unmount and freeze contexts. Hence allow the caller to pass in the freeze level it is allowed to write at, thereby ensuring that we can use the general writable function in more places.
Note: Brian Foster also wrote an almost identical patch at the same time, so some credit is due to him for the existence of this commit.
--- fs/xfs/xfs_log.c | 2 +- fs/xfs/xfs_mount.c | 21 +++++++++++++++------ fs/xfs/xfs_mount.h | 2 +- 3 files changed, 17 insertions(+), 8 deletions(-)
fs/xfs/xfs_log.c +1 -1
@@ -1031,7 +1031,7 @@ xfs_log_need_covered(xfs_mount_t *mp)struct xlog *log = mp->m_log;int needed =0 ; -if (!xfs_fs_writable (mp)) +if (!xfs_fs_writable (mp,SB_UNFROZEN ))return 0 ;if (!xlog_cil_empty (log))
fs/xfs/xfs_mount.c +15 -6
@@ -607,7 +607,7 @@ xfs_mount_reset_sbqflags(* If the fs is readonly, let the incore superblock run * with quotas off but don't flush the update out to disk */ -if (mp->m_flags &XFS_MOUNT_RDONLY ) +if (!xfs_fs_writable (mp,SB_UNFROZEN ))return 0 ; tp =xfs_trans_alloc (mp,XFS_TRANS_QM_SBCHANGE );
@@ -1077,11 +1077,16 @@ xfs_unmountfs(xfs_sysfs_del (&mp->m_kobj); } -int -xfs_fs_writable (xfs_mount_t *mp) +bool +xfs_fs_writable (xfs_mount_t *mp,int frozen_state) { -return !(mp->m_super->s_writers.frozen ||XFS_FORCED_SHUTDOWN (mp) || - (mp->m_flags &XFS_MOUNT_RDONLY )); +if (mp->m_super->s_writers.frozen > frozen_state) +return false; +if (XFS_FORCED_SHUTDOWN (mp)) +return false; +if (mp->m_flags &XFS_MOUNT_RDONLY ) +return false; +return true; }/*
@@ -1099,7 +1104,11 @@ xfs_log_sbcount(xfs_mount_t *mp)xfs_trans_t *tp;int error; -if (!xfs_fs_writable (mp)) +/* +* We can be called during the fs freeze process, and we need to be +* able to write the superblock in that case. +*/ +if (!xfs_fs_writable (mp,SB_FREEZE_FS ))return 0 ;xfs_icsb_sync_counters (mp,0 );
fs/xfs/xfs_mount.h +1 -1
@@ -384,7 +384,7 @@ extern int xfs_mount_log_sb(xfs_mount_t *, __int64_t);extern struct xfs_buf *xfs_getsb (xfs_mount_t *,int );extern int xfs_readsb (xfs_mount_t *,int );extern void xfs_freesb (xfs_mount_t *); -extern int xfs_fs_writable (xfs_mount_t *); +extern bool xfs_fs_writable (struct xfs_mount *,int );extern int xfs_sb_validate_fsb_count (struct xfs_sb *,__uint64_t );extern int xfs_dev_is_read_only (struct xfs_mount *,char *);
Signature · 6 lines
2.0.0 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 1/3] xfs: consider freeze levels in xfs_fs_writable()
fs/xfs/xfs_mount.c xfs_mount_reset_sbqflags( · line 610
Quoted 9 lines
index d36bdbc..9073895 100644
fs/xfs/xfs_mount.c +1
-1@@ -607,7 +607,7 @@ xfs_mount_reset_sbqflags(* If the fs is readonly, let the incore superblock run * with quotas off but don't flush the update out to disk */ -if (mp->m_flags &XFS_MOUNT_RDONLY ) +if (!xfs_fs_writable (mp,SB_UNFROZEN ))
This adds a new caller of xfs_fs_writable, which isn't mentioned in the changelog.
fs/xfs/xfs_mount.c xfs_log_sbcount(xfs_mount_t *mp) · line 1112
Quoted 6 lines
fs/xfs/xfs_mount.c +5
-0+/* +* We can be called during the fs freeze process, and we need to be +* able to write the superblock in that case. +*/ +if (!xfs_fs_writable (mp,SB_FREEZE_FS ))return 0 ;
And this already changes the checked freeze level, also not mentioned.
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 1/3] xfs: consider freeze levels in xfs_fs_writable()
Quoted 4 lines · Christoph Hellwig
Quoted 4 lines
index d36bdbc..9073895 100644
fs/xfs/xfs_mount.c +0
-0@@ -607,7 +607,7 @@ xfs_mount_reset_sbqflags(
Quoted 8 lines
fs/xfs/xfs_mount.c xfs_mount_reset_sbqflags( · line 610
Quoted 5 lines
fs/xfs/xfs_mount.c +1
-1* If the fs is readonly, let the incore superblock run * with quotas off but don't flush the update out to disk */ -if (mp->m_flags &XFS_MOUNT_RDONLY ) +if (!xfs_fs_writable (mp,SB_UNFROZEN ))This adds a new caller of
xfs_fs_writable, which isn't mentioned in the changelog.
I can mention it, but it's so trivial I didn't think it was worth it.
Quoted 8 lines
fs/xfs/xfs_mount.c xfs_log_sbcount(xfs_mount_t *mp) · line 1112
Quoted 6 lines
fs/xfs/xfs_mount.c +5
-0+/* +* We can be called during the fs freeze process, and we need to be +* able to write the superblock in that case. +*/ +if (!xfs_fs_writable (mp,SB_FREEZE_FS ))return 0 ;And this already changes the checked freeze level, also not mentioned.
The changelog says "Hence allow the caller to pass in the freeze level it is allowed to write" which is exactly what this code is doing.
Cheers,
Dave.
Signature · 7 lines
Dave Chinner [email protected] _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 1/3] xfs: consider freeze levels in xfs_fs_writable()
Quoted 2 lines · Dave Chinner
I can mention it, but it's so trivial I didn't think it was worth it.
It does change behavior, so it should document why that was changed.
Quoted 3 lines
The changelog says "Hence allow the caller to pass in the freeze level it is allowed to write" which is exactly what this code is doing.
The changelog says the you can pass the argument now. It doesn't say that it did change a caller to pass a different argument, and more importanly why.
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 1/3] xfs: consider freeze levels in xfs_fs_writable()
Quoted 6 lines · Christoph Hellwig
Quoted 2 lines · Dave Chinner
I can mention it, but it's so trivial I didn't think it was worth it.
It does change behavior, so it should document why that was changed.
Quoted 8 lines
Quoted 3 lines
The changelog says "Hence allow the caller to pass in the freeze level it is allowed to write" which is exactly what this code is doing.
The changelog says the you can pass the argument now. It doesn't say that it did change a caller to pass a different argument, and more importanly why.
Note that iirc the patch I posted had a bug so this one is preferred, but feel free to steal the commit log/problem description from the old one:
http://oss.sgi.com/archives/xfs/2014-08/msg00073.html
Brian
Quoted 4 lines
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH v2 2/3 xfs: remove bitfield based superblock updates
In reply to Dave ChinnerFrom: Dave Chinner <[email protected]>
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.
--- fs/xfs/libxfs/xfs_attr_leaf.c | 2 +- fs/xfs/libxfs/xfs_bmap.c | 14 +-- fs/xfs/libxfs/xfs_sb.c | 287 +++++++++++++++--------------------------- fs/xfs/libxfs/xfs_sb.h | 10 +- fs/xfs/xfs_fsops.c | 6 +- fs/xfs/xfs_mount.c | 18 +-- fs/xfs/xfs_mount.h | 2 +- fs/xfs/xfs_qm.c | 26 +--- fs/xfs/xfs_qm.h | 2 +- fs/xfs/xfs_qm_syscalls.c | 13 +- fs/xfs/xfs_super.c | 2 +- 11 files changed, 130 insertions(+), 252 deletions(-)
fs/xfs/libxfs/xfs_attr_leaf.c +1 -1
@@ -405,7 +405,7 @@ xfs_sbversion_add_attr2(xfs_mount_t *mp, xfs_trans_t *tp)if (!xfs_sb_version_hasattr2 (&mp->m_sb)) {xfs_sb_version_addattr2 (&mp->m_sb);spin_unlock (&mp->m_sb_lock); -xfs_mod_sb (tp,XFS_SB_VERSIONNUM |XFS_SB_FEATURES2 ); +xfs_mod_sb (tp); }else spin_unlock (&mp->m_sb_lock); }
fs/xfs/libxfs/xfs_bmap.c +6 -8
@@ -1224,22 +1224,20 @@ xfs_bmap_add_attrfork( goto bmap_cancel;if (!xfs_sb_version_hasattr (&mp->m_sb) || (!xfs_sb_version_hasattr2 (&mp->m_sb) && version ==2 )) { -__int64_t sbfields =0 ; +bool mod_sb = false;spin_lock (&mp->m_sb_lock);if (!xfs_sb_version_hasattr (&mp->m_sb)) {xfs_sb_version_addattr (&mp->m_sb); - sbfields |=XFS_SB_VERSIONNUM ; + mod_sb = true; }if (!xfs_sb_version_hasattr2 (&mp->m_sb) && version ==2 ) {xfs_sb_version_addattr2 (&mp->m_sb); - sbfields |= (XFS_SB_VERSIONNUM |XFS_SB_FEATURES2 ); + mod_sb = true; } -if (sbfields) { -spin_unlock (&mp->m_sb_lock); -xfs_mod_sb (tp, sbfields); - }else -spin_unlock (&mp->m_sb_lock); +spin_unlock (&mp->m_sb_lock); +if (mod_sb) +xfs_mod_sb (tp); } error =xfs_bmap_finish (&tp, &flist, &committed);
fs/xfs/libxfs/xfs_sb.c +98 -189
327 lines not on this page · raw message
fs/xfs/libxfs/xfs_sb.h +5 -5
@@ -611,11 +611,11 @@ extern struct xfs_perag *xfs_perag_get_tag(struct xfs_mount *, xfs_agnumber_t,extern void xfs_perag_put (struct xfs_perag *pag);extern int xfs_initialize_perag_data (struct xfs_mount *,xfs_agnumber_t ); -extern void xfs_sb_calc_crc (struct xfs_buf *); -extern void xfs_mod_sb (struct xfs_trans *,__int64_t ); -extern void xfs_sb_mount_common (struct xfs_mount *,struct xfs_sb *); -extern void xfs_sb_from_disk (struct xfs_sb *,struct xfs_dsb *); -extern void xfs_sb_to_disk (struct xfs_dsb *,struct xfs_sb *,__int64_t ); +extern void xfs_sb_calc_crc (struct xfs_buf *bp); +extern void xfs_mod_sb (struct xfs_trans *tp); +extern void xfs_sb_mount_common (struct xfs_mount *mp,struct xfs_sb *sbp); +extern void xfs_sb_from_disk (struct xfs_sb *to,struct xfs_dsb *from); +extern void xfs_sb_to_disk (struct xfs_dsb *to,struct xfs_sb *from);extern void xfs_sb_quota_from_disk (struct xfs_sb *sbp);#endif /* __XFS_SB_H__ */
fs/xfs/xfs_fsops.c +2 -4
@@ -548,7 +548,7 @@ xfs_growfs_data_private( saved_error = error;continue ; } -xfs_sb_to_disk (XFS_BUF_TO_SBP (bp), &mp->m_sb,XFS_SB_ALL_BITS ); +xfs_sb_to_disk (XFS_BUF_TO_SBP (bp), &mp->m_sb); error =xfs_bwrite (bp);xfs_buf_relse (bp);
@@ -787,9 +787,7 @@ xfs_fs_log_dummy(xfs_trans_cancel (tp,0 );return error; } - -/* log the UUID because it is an unchanging field */ -xfs_mod_sb (tp,XFS_SB_UUID ); +xfs_mod_sb (tp);xfs_trans_set_sync (tp);return xfs_trans_commit (tp,0 ); }
fs/xfs/xfs_mount.c +6 -12
@@ -618,7 +618,7 @@ xfs_mount_reset_sbqflags(return error; } -xfs_mod_sb (tp,XFS_SB_QFLAGS ); +xfs_mod_sb (tp);return xfs_trans_commit (tp,0 ); }
@@ -901,7 +901,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;
@@ -1127,7 +1127,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;
@@ -1430,25 +1430,19 @@ xfs_freesb(*/ int xfs_mount_log_sb ( -xfs_mount_t *mp, -__int64_t fields) +xfs_mount_t *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 )); - tp =xfs_trans_alloc (mp,XFS_TRANS_SB_UNIT ); error =xfs_trans_reserve (tp, &M_RES (mp)->tr_sb,0 ,0 );if (error) {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 ); }/*
fs/xfs/xfs_mount.h +1 -1
@@ -380,7 +380,7 @@ extern void xfs_unmountfs(xfs_mount_t *);extern int xfs_mod_incore_sb (xfs_mount_t *,xfs_sb_field_t ,int64_t ,int );extern int xfs_mod_incore_sb_batch (xfs_mount_t *,xfs_mod_sb_t *,uint ,int ); -extern int xfs_mount_log_sb (xfs_mount_t *,__int64_t ); +extern int xfs_mount_log_sb (xfs_mount_t *);extern struct xfs_buf *xfs_getsb (xfs_mount_t *,int );extern int xfs_readsb (xfs_mount_t *,int );extern void xfs_freesb (xfs_mount_t *);
fs/xfs/xfs_qm.c +5 -21
@@ -716,7 +716,6 @@ STATIC intxfs_qm_qino_alloc ( xfs_mount_t *mp, xfs_inode_t **ip, - __int64_t sbfields, uint flags) {xfs_trans_t *tp;
@@ -779,11 +778,6 @@ xfs_qm_qino_alloc(spin_lock (&mp->m_sb_lock);if (flags &XFS_QMOPT_SBVERSION ) {ASSERT (!xfs_sb_version_hasquota (&mp->m_sb)); -ASSERT ((sbfields & (XFS_SB_VERSIONNUM |XFS_SB_UQUOTINO | -XFS_SB_GQUOTINO |XFS_SB_PQUOTINO |XFS_SB_QFLAGS )) == - (XFS_SB_VERSIONNUM |XFS_SB_UQUOTINO | -XFS_SB_GQUOTINO |XFS_SB_PQUOTINO | -XFS_SB_QFLAGS ));xfs_sb_version_addquota (&mp->m_sb); mp->m_sb.sb_uquotino =NULLFSINO ;
@@ -800,7 +794,7 @@ xfs_qm_qino_alloc(else mp->m_sb.sb_pquotino = (*ip)->i_ino;spin_unlock (&mp->m_sb_lock); -xfs_mod_sb (tp, sbfields); +xfs_mod_sb (tp);if ((error =xfs_trans_commit (tp,XFS_TRANS_RELEASE_LOG_RES ))) {xfs_alert (mp,"%s failed (error %d)!" , __func__, error);
@@ -1453,7 +1447,7 @@ xfs_qm_mount_quotas(spin_unlock (&mp->m_sb_lock);if (sbf != (mp->m_qflags &XFS_MOUNT_QUOTA_ALL )) { -if (xfs_qm_write_sb_changes (mp,XFS_SB_QFLAGS )) { +if (xfs_qm_write_sb_changes (mp)) {/* * We could only have been turning quotas off. * We aren't in very good shape actually because
@@ -1484,7 +1478,6 @@ xfs_qm_init_quotainos(struct xfs_inode *gip =NULL ;struct xfs_inode *pip =NULL ;int error; -__int64_t sbflags =0 ;uint flags =0 ;ASSERT (mp->m_quotainfo);
@@ -1519,9 +1512,6 @@ xfs_qm_init_quotainos( } }else { flags |=XFS_QMOPT_SBVERSION ; - sbflags |= (XFS_SB_VERSIONNUM |XFS_SB_UQUOTINO | -XFS_SB_GQUOTINO |XFS_SB_PQUOTINO | -XFS_SB_QFLAGS ); }/*
@@ -1532,7 +1522,6 @@ xfs_qm_init_quotainos(*/ if (XFS_IS_UQUOTA_ON (mp) && uip ==NULL ) { error =xfs_qm_qino_alloc (mp, &uip, - sbflags |XFS_SB_UQUOTINO , flags |XFS_QMOPT_UQUOTA );if (error) goto error_rele;
@@ -1541,7 +1530,6 @@ xfs_qm_init_quotainos( }if (XFS_IS_GQUOTA_ON (mp) && gip ==NULL ) { error =xfs_qm_qino_alloc (mp, &gip, - sbflags |XFS_SB_GQUOTINO , flags |XFS_QMOPT_GQUOTA );if (error) goto error_rele;
@@ -1550,7 +1538,6 @@ xfs_qm_init_quotainos( }if (XFS_IS_PQUOTA_ON (mp) && pip ==NULL ) { error =xfs_qm_qino_alloc (mp, &pip, - sbflags |XFS_SB_PQUOTINO , flags |XFS_QMOPT_PQUOTA );if (error) goto error_rele;
@@ -1595,8 +1582,7 @@ xfs_qm_dqfree_one(*/ int xfs_qm_write_sb_changes ( -xfs_mount_t *mp, -__int64_t flags) +struct xfs_mount *mp) {xfs_trans_t *tp;int error;
@@ -1608,10 +1594,8 @@ xfs_qm_write_sb_changes(return error; } -xfs_mod_sb (tp, flags); - error =xfs_trans_commit (tp,0 ); - -return error; +xfs_mod_sb (tp); +return xfs_trans_commit (tp,0 ); }
fs/xfs/xfs_qm.h +1 -1
@@ -157,7 +157,7 @@ struct xfs_dquot_acct {#define XFS_QM_RTBWARNLIMIT 5extern void xfs_qm_destroy_quotainfo (struct xfs_mount *); -extern int xfs_qm_write_sb_changes (struct xfs_mount *,__int64_t ); +extern int xfs_qm_write_sb_changes (struct xfs_mount *);/* dquot stuff */ extern void xfs_qm_dqpurge_all (struct xfs_mount *,uint );
fs/xfs/xfs_qm_syscalls.c +4 -9
@@ -93,8 +93,7 @@ xfs_qm_scall_quotaoff(mutex_unlock (&q->qi_quotaofflock);/* XXX what to do if error ? Revert back to old vals incore ? */ - error =xfs_qm_write_sb_changes (mp,XFS_SB_QFLAGS ); -return error; +return xfs_qm_write_sb_changes (mp); } dqtype =0 ;
@@ -315,7 +314,6 @@ xfs_qm_scall_quotaon( {int error;uint qf; -__int64_t sbflags; flags &= (XFS_ALL_QUOTA_ACCT |XFS_ALL_QUOTA_ENFD );/*
@@ -323,8 +321,6 @@ xfs_qm_scall_quotaon(*/ flags &= ~(XFS_ALL_QUOTA_ACCT ); - sbflags =0 ; -if (flags ==0 ) {xfs_debug (mp,"%s: zero flags, m_qflags=%x" , __func__, mp->m_qflags);
@@ -371,11 +367,10 @@ xfs_qm_scall_quotaon(/* * There's nothing to change if it's the same. */ -if ((qf & flags) == flags && sbflags ==0 ) +if ((qf & flags) == flags)return -EEXIST ; - sbflags |=XFS_SB_QFLAGS ; -if ((error =xfs_qm_write_sb_changes (mp, sbflags))) +if ((error =xfs_qm_write_sb_changes (mp)))return error;/* * If we aren't trying to switch on quota enforcement, we are done.
@@ -800,7 +795,7 @@ xfs_qm_log_quotaoff( mp->m_sb.sb_qflags = (mp->m_qflags & ~(flags)) &XFS_MOUNT_QUOTA_ALL ;spin_unlock (&mp->m_sb_lock); -xfs_mod_sb (tp,XFS_SB_QFLAGS ); +xfs_mod_sb (tp);/* * We have to make sure that the transaction is secure on disk before we
fs/xfs/xfs_super.c +1 -1
@@ -1255,7 +1255,7 @@ xfs_fs_remount(* might have some superblock changes to update. */ if (mp->m_update_flags) { - 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" );return error;
Signature · 6 lines
2.0.0 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 2/3] xfs: remove bitfield based superblock updates
This breaks generic/230 for me on an x86-64 VM:
root/xfstests/results//generic/230.out.bad renamed from generic/230.out +0 -3
@@ -23,11 +23,8 @@ Write 900k... Rewrite 1001k... Write 1000k... -pwrite64: Disk quota exceeded Write 4096... -pwrite64: Disk quota exceeded Touch 3+4 Touch 5+6 touch: cannot touch 'SCRATCH_MNT/file6': Disk quota exceeded Touch 5 -touch: cannot touch 'SCRATCH_MNT/file5': Disk quota exceeded
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 2/3] xfs: remove bitfield based superblock updates
Quoted 6 lines · Christoph Hellwig
This breaks generic/230 for me on an x86-64 VM:
root/xfstests/results//generic/230.out.bad renamed from generic/230.out +0
-0@@ -23,11 +23,8 @@ Write 900k...
root/xfstests/results//generic/230.out.bad line 33
Quoted 10 lines
root/xfstests/results//generic/230.out.bad renamed from generic/230.out +0
-3Rewrite 1001k... Write 1000k... -pwrite64: Disk quota exceeded Write 4096... -pwrite64: Disk quota exceeded Touch 3+4 Touch 5+6 touch: cannot touch 'SCRATCH_MNT/file6': Disk quota exceeded Touch 5 -touch: cannot touch 'SCRATCH_MNT/file5': Disk quota exceeded
Curious, I haven't seen any change in quota behaviour on any test as a result of these changes. What's the config of your VM and xfstests run?
Cheers,
Dave.
Signature · 7 lines
Dave Chinner [email protected] _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 2/3] xfs: remove bitfield based superblock updates
In reply to Dave Chinnerfs/xfs/libxfs/xfs_sb.c xfs_sb_from_disk( · line 414
Quoted 7 lines
fs/xfs/libxfs/xfs_sb.c +7
-0+ to->sb_uquotino =cpu_to_be64 (from->sb_uquotino); +if (xfs_sb_version_has_pquotino (from)) { + to->sb_qflags =be16_to_cpu (from->sb_qflags); + to->sb_gquotino =cpu_to_be64 (from->sb_gquotino); + to->sb_pquotino =cpu_to_be64 (from->sb_pquotino); +return ; + }
sparse complains that the be16_to_cpu should be a cpu_to_be16 for sb_qflags..
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 2/3] xfs: remove bitfield based superblock updates
Quoted 10 lines · Christoph Hellwig
fs/xfs/libxfs/xfs_sb.c xfs_sb_from_disk( · line 414
Quoted 7 lines
fs/xfs/libxfs/xfs_sb.c +7
-0+ to->sb_uquotino =cpu_to_be64 (from->sb_uquotino); +if (xfs_sb_version_has_pquotino (from)) { + to->sb_qflags =be16_to_cpu (from->sb_qflags); + to->sb_gquotino =cpu_to_be64 (from->sb_gquotino); + to->sb_pquotino =cpu_to_be64 (from->sb_pquotino); +return ; + }sparse complains that the
be16_to_cpushould be acpu_to_be16forsb_qflags..
Good catch. Fixed.
Signature · 7 lines
Dave Chinner [email protected] _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
PATCH v2 3/3 xfs: consolidate superblock logging functions
In reply to Dave ChinnerFrom: Dave Chinner <[email protected]>
We now have several superblock loggin functions that are identical except for the transaction reservation and whether it shoul dbe a synchronous transaction or not. Consolidate these all into a single function, a single reserveration and a sync flag and call it xfs_sync_sb().
Also, xfs_mod_sb() is not really a modification function - it's the operation of logging the superblock buffer. hence change the name of it to reflect this.
Note that we have to change the mp->m_update_flags that are passed around at mount time to a boolean simply to indicate a superblock update is needed.
--- fs/xfs/libxfs/xfs_attr_leaf.c | 2 +- fs/xfs/libxfs/xfs_bmap.c | 10 +++--- fs/xfs/libxfs/xfs_sb.c | 43 +++++++++++++++++++---- fs/xfs/libxfs/xfs_sb.h | 42 ++--------------------- fs/xfs/libxfs/xfs_shared.h | 26 ++++++-------- fs/xfs/libxfs/xfs_trans_resv.c | 14 -------- fs/xfs/libxfs/xfs_trans_resv.h | 1 - fs/xfs/xfs_fsops.c | 29 ---------------- fs/xfs/xfs_log.c | 17 ++++++++-- fs/xfs/xfs_mount.c | 77 ++++++------------------------------------ fs/xfs/xfs_mount.h | 3 +- fs/xfs/xfs_qm.c | 27 ++------------- fs/xfs/xfs_qm_syscalls.c | 7 ++-- fs/xfs/xfs_super.c | 13 +++---- 14 files changed, 95 insertions(+), 216 deletions(-)
fs/xfs/libxfs/xfs_attr_leaf.c +1 -1
@@ -405,7 +405,7 @@ xfs_sbversion_add_attr2(xfs_mount_t *mp, xfs_trans_t *tp)if (!xfs_sb_version_hasattr2 (&mp->m_sb)) {xfs_sb_version_addattr2 (&mp->m_sb);spin_unlock (&mp->m_sb_lock); -xfs_mod_sb (tp); +xfs_log_sb (tp); }else spin_unlock (&mp->m_sb_lock); }
fs/xfs/libxfs/xfs_bmap.c +5 -5
@@ -1224,20 +1224,20 @@ xfs_bmap_add_attrfork( goto bmap_cancel;if (!xfs_sb_version_hasattr (&mp->m_sb) || (!xfs_sb_version_hasattr2 (&mp->m_sb) && version ==2 )) { -bool mod_sb = false; +bool log_sb = false;spin_lock (&mp->m_sb_lock);if (!xfs_sb_version_hasattr (&mp->m_sb)) {xfs_sb_version_addattr (&mp->m_sb); - mod_sb = true; + log_sb = true; }if (!xfs_sb_version_hasattr2 (&mp->m_sb) && version ==2 ) {xfs_sb_version_addattr2 (&mp->m_sb); - mod_sb = true; + log_sb = true; }spin_unlock (&mp->m_sb_lock); -if (mod_sb) -xfs_mod_sb (tp); +if (log_sb) +xfs_log_sb (tp); } error =xfs_bmap_finish (&tp, &flist, &committed);
fs/xfs/libxfs/xfs_sb.c +37 -6
54 lines not on this page · raw message
fs/xfs/libxfs/xfs_sb.h +2 -40
54 lines not on this page · raw message
fs/xfs/libxfs/xfs_shared.h +11 -15
@@ -82,7 +82,7 @@ extern const struct xfs_buf_ops xfs_symlink_buf_ops;#define XFS_TRANS_ATTR_RM 23#define XFS_TRANS_ATTR_FLAG 24#define XFS_TRANS_CLEAR_AGI_BUCKET 25 -#define XFS_TRANS_QM_SBCHANGE 26 +#define XFS_TRANS_SB_CHANGE 26/* * Dummy entries since we use the transaction type to index into the * trans_type[] in xlog_recover_print_trans_head()
@@ -95,17 +95,15 @@ extern const struct xfs_buf_ops xfs_symlink_buf_ops;#define XFS_TRANS_QM_DQCLUSTER 32#define XFS_TRANS_QM_QINOCREATE 33#define XFS_TRANS_QM_QUOTAOFF_END 34 -#define XFS_TRANS_SB_UNIT 35 -#define XFS_TRANS_FSYNC_TS 36 -#define XFS_TRANS_GROWFSRT_ALLOC 37 -#define XFS_TRANS_GROWFSRT_ZERO 38 -#define XFS_TRANS_GROWFSRT_FREE 39 -#define XFS_TRANS_SWAPEXT 40 -#define XFS_TRANS_SB_COUNT 41 -#define XFS_TRANS_CHECKPOINT 42 -#define XFS_TRANS_ICREATE 43 -#define XFS_TRANS_CREATE_TMPFILE 44 -#define XFS_TRANS_TYPE_MAX 44 +#define XFS_TRANS_FSYNC_TS 35 +#define XFS_TRANS_GROWFSRT_ALLOC 36 +#define XFS_TRANS_GROWFSRT_ZERO 37 +#define XFS_TRANS_GROWFSRT_FREE 37 +#define XFS_TRANS_SWAPEXT 39 +#define XFS_TRANS_CHECKPOINT 40 +#define XFS_TRANS_ICREATE 41 +#define XFS_TRANS_CREATE_TMPFILE 42 +#define XFS_TRANS_TYPE_MAX 43/* new transaction types need to be reflected in xfs_logprint(8) */ #define XFS_TRANS_TYPES \
@@ -134,20 +132,18 @@ extern const struct xfs_buf_ops xfs_symlink_buf_ops; { XFS_TRANS_ATTR_RM, "ATTR_RM" }, \ { XFS_TRANS_ATTR_FLAG, "ATTR_FLAG" }, \ { XFS_TRANS_CLEAR_AGI_BUCKET, "CLEAR_AGI_BUCKET" }, \ - { XFS_TRANS_QM_SBCHANGE, "QM_SBCHANGE" }, \ + { XFS_TRANS_SB_CHANGE, "SBCHANGE" }, \ { XFS_TRANS_QM_QUOTAOFF, "QM_QUOTAOFF" }, \ { XFS_TRANS_QM_DQALLOC, "QM_DQALLOC" }, \ { XFS_TRANS_QM_SETQLIM, "QM_SETQLIM" }, \ { XFS_TRANS_QM_DQCLUSTER, "QM_DQCLUSTER" }, \ { XFS_TRANS_QM_QINOCREATE, "QM_QINOCREATE" }, \ { XFS_TRANS_QM_QUOTAOFF_END, "QM_QOFF_END" }, \ - { XFS_TRANS_SB_UNIT, "SB_UNIT" }, \ { XFS_TRANS_FSYNC_TS, "FSYNC_TS" }, \ { XFS_TRANS_GROWFSRT_ALLOC, "GROWFSRT_ALLOC" }, \ { XFS_TRANS_GROWFSRT_ZERO, "GROWFSRT_ZERO" }, \ { XFS_TRANS_GROWFSRT_FREE, "GROWFSRT_FREE" }, \ { XFS_TRANS_SWAPEXT, "SWAPEXT" }, \ - { XFS_TRANS_SB_COUNT, "SB_COUNT" }, \ { XFS_TRANS_CHECKPOINT, "CHECKPOINT" }, \ { XFS_TRANS_DUMMY1, "DUMMY1" }, \ { XFS_TRANS_DUMMY2, "DUMMY2" }, \
fs/xfs/libxfs/xfs_trans_resv.c +0 -14
@@ -718,17 +718,6 @@ xfs_calc_clear_agi_bucket_reservation( }/* -* Clearing the quotaflags in the superblock. -* the super block for changing quota flags: sector size -*/ -STATIC uint -xfs_calc_qm_sbchange_reservation ( -struct xfs_mount *mp) -{ -return xfs_calc_buf_res (1 , mp->m_sb.sb_sectsize); -} - -/* * Adjusting quota limits. * the xfs_disk_dquot_t: sizeof(struct xfs_disk_dquot) */
@@ -866,9 +855,6 @@ xfs_trans_resv_calc(* The following transactions are logged in logical format with * a default log count. */ - resp->tr_qm_sbchange.tr_logres =xfs_calc_qm_sbchange_reservation (mp); - resp->tr_qm_sbchange.tr_logcount =XFS_DEFAULT_LOG_COUNT ; - resp->tr_qm_setqlim.tr_logres =xfs_calc_qm_setqlim_reservation (mp); resp->tr_qm_setqlim.tr_logcount =XFS_DEFAULT_LOG_COUNT ;
fs/xfs/libxfs/xfs_trans_resv.h +0 -1
@@ -56,7 +56,6 @@ struct xfs_trans_resv {struct xfs_trans_res tr_growrtalloc;/* grow realtime allocations */ struct xfs_trans_res tr_growrtzero;/* grow realtime zeroing */ struct xfs_trans_res tr_growrtfree;/* grow realtime freeing */ -struct xfs_trans_res tr_qm_sbchange;/* change quota flags */ struct xfs_trans_res tr_qm_setqlim;/* adjust quota limits */ struct xfs_trans_res tr_qm_dqalloc;/* allocate quota on disk */ struct xfs_trans_res tr_qm_quotaoff;/* turn quota off */
fs/xfs/xfs_fsops.c +0 -29
@@ -763,35 +763,6 @@ out:return 0 ; } -/* -* Dump a transaction into the log that contains no real change. This is needed -* to be able to make the log dirty or stamp the current tail LSN into the log -* during the covering operation. -* -* We cannot use an inode here for this - that will push dirty state back up -* into the VFS and then periodic inode flushing will prevent log covering from -* making progress. Hence we log a field in the superblock instead and use a -* synchronous transaction to ensure the superblock is immediately unpinned -* and can be written back. -*/ -int -xfs_fs_log_dummy ( -xfs_mount_t *mp) -{ -xfs_trans_t *tp; -int error; - - tp =_xfs_trans_alloc (mp,XFS_TRANS_DUMMY1 ,KM_SLEEP ); - error =xfs_trans_reserve (tp, &M_RES (mp)->tr_sb,0 ,0 ); -if (error) { -xfs_trans_cancel (tp,0 ); -return error; - } -xfs_mod_sb (tp); -xfs_trans_set_sync (tp); -return xfs_trans_commit (tp,0 ); -} - int xfs_fs_goingdown( xfs_mount_t *mp,
fs/xfs/xfs_log.c +14 -3
@@ -1292,9 +1292,20 @@ xfs_log_worker(struct xfs_mount *mp = log->l_mp;/* dgc: errors ignored - not fatal and nowhere to report them */ -if (xfs_log_need_covered (mp)) -xfs_fs_log_dummy (mp); -else +if (xfs_log_need_covered (mp)) { +/* +* Dump a transaction into the log that contains no real change. +* This is needed stamp the current tail LSN into the log during +* the covering operation. +* +* We cannot use an inode here for this - that will push dirty +* state back up into the VFS and then periodic inode flushing +* will prevent log covering from making progress. Hence we +* synchronously log the superblock instead to ensure the +* superblock is immediately unpinned and can be written back. +*/ +xfs_sync_sb (mp, true); + }else xfs_log_force (mp,0 );/* start pushing all the metadata that is currently dirty */
fs/xfs/xfs_mount.c +11 -66
146 lines not on this page · raw message
fs/xfs/xfs_mount.h +1 -2
@@ -162,8 +162,7 @@ typedef struct xfs_mount {struct delayed_work m_reclaim_work;/* background inode reclaim */ struct delayed_work m_eofblocks_work;/* background eof blocks trimming */ -__int64_t m_update_flags;/* sb flags we need to update -on the next remount,rw */ +bool m_update_sb;/* sb needs update in mount */ int64_t m_low_space[XFS_LOWSP_MAX ];/* low free space thresholds */ struct xfs_kobj m_kobj;
fs/xfs/xfs_qm.c +2 -25
@@ -794,7 +794,7 @@ xfs_qm_qino_alloc(else mp->m_sb.sb_pquotino = (*ip)->i_ino;spin_unlock (&mp->m_sb_lock); -xfs_mod_sb (tp); +xfs_log_sb (tp);if ((error =xfs_trans_commit (tp,XFS_TRANS_RELEASE_LOG_RES ))) {xfs_alert (mp,"%s failed (error %d)!" , __func__, error);
@@ -1447,7 +1447,7 @@ xfs_qm_mount_quotas(spin_unlock (&mp->m_sb_lock);if (sbf != (mp->m_qflags &XFS_MOUNT_QUOTA_ALL )) { -if (xfs_qm_write_sb_changes (mp)) { +if (xfs_sync_sb (mp, false)) {/* * We could only have been turning quotas off. * We aren't in very good shape actually because
@@ -1576,29 +1576,6 @@ xfs_qm_dqfree_one(xfs_qm_dqdestroy (dqp); } -/* -* Start a transaction and write the incore superblock changes to -* disk. flags parameter indicates which fields have changed. -*/ -int -xfs_qm_write_sb_changes ( -struct xfs_mount *mp) -{ -xfs_trans_t *tp; -int error; - - tp =xfs_trans_alloc (mp,XFS_TRANS_QM_SBCHANGE ); - error =xfs_trans_reserve (tp, &M_RES (mp)->tr_qm_sbchange,0 ,0 ); -if (error) { -xfs_trans_cancel (tp,0 ); -return error; - } - -xfs_mod_sb (tp); -return xfs_trans_commit (tp,0 ); -} - -/* --------------- utility functions for vnodeops ---------------- */
fs/xfs/xfs_qm_syscalls.c +4 -3
@@ -93,7 +93,7 @@ xfs_qm_scall_quotaoff(mutex_unlock (&q->qi_quotaofflock);/* XXX what to do if error ? Revert back to old vals incore ? */ -return xfs_qm_write_sb_changes (mp); +return xfs_sync_sb (mp, false); } dqtype =0 ;
@@ -370,7 +370,8 @@ xfs_qm_scall_quotaon(if ((qf & flags) == flags)return -EEXIST ; -if ((error =xfs_qm_write_sb_changes (mp))) + error =xfs_sync_sb (mp, false); +if (error)return error;/* * If we aren't trying to switch on quota enforcement, we are done.
@@ -795,7 +796,7 @@ xfs_qm_log_quotaoff( mp->m_sb.sb_qflags = (mp->m_qflags & ~(flags)) &XFS_MOUNT_QUOTA_ALL ;spin_unlock (&mp->m_sb_lock); -xfs_mod_sb (tp); +xfs_log_sb (tp);/* * We have to make sure that the transaction is secure on disk before we
fs/xfs/xfs_super.c +7 -6
@@ -1254,13 +1254,13 @@ xfs_fs_remount(* If this is the first remount to writeable state we * might have some superblock changes to update. */ -if (mp->m_update_flags) { - error =xfs_mount_log_sb (mp); +if (mp->m_update_sb) { + error =xfs_sync_sb (mp, false);if (error) {xfs_warn (mp,"failed to write sb changes" );return error; } - mp->m_update_flags =0 ; + mp->m_update_sb = false; }/*
@@ -1290,8 +1290,9 @@ xfs_fs_remount(/* * Second stage of a freeze. The data is already frozen so we only -* need to take care of the metadata. Once that's done write a dummy -* record to dirty the log in case of a crash while frozen. +* need to take care of the metadata. Once that's done sync the superblock +* to the log to dirty it in case of a crash while frozen. This ensures that we +* will recover the unlinked inode lists on the next mount. */ STATIC int xfs_fs_freeze(
@@ -1301,7 +1302,7 @@ xfs_fs_freeze(xfs_save_resvblks (mp);xfs_quiesce_attr (mp); -return xfs_fs_log_dummy (mp); +return xfs_sync_sb (mp, true); }STATIC int
Signature · 6 lines
2.0.0 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 3/3] xfs: consolidate superblock logging functions
Quoted 219 lines · Dave Chinner
From: Dave Chinner <[email protected]>
We now have several superblock loggin functions that are identical except for the transaction reservation and whether it shoul dbe a synchronous transaction or not. Consolidate these all into a single function, a single reserveration and a sync flag and call it
xfs_sync_sb().Also,
xfs_mod_sb()is not really a modification function - it's the operation of logging the superblock buffer. hence change the name of it to reflect this.Note that we have to change the
mp->m_update_flagsthat are passed around at mount time to a boolean simply to indicate a superblock update is needed.Signed-off-by Dave Chinner <[email protected]>--- fs/xfs/libxfs/xfs_attr_leaf.c | 2 +- fs/xfs/libxfs/xfs_bmap.c | 10 +++--- fs/xfs/libxfs/xfs_sb.c | 43 +++++++++++++++++++---- fs/xfs/libxfs/xfs_sb.h | 42 ++--------------------- fs/xfs/libxfs/xfs_shared.h | 26 ++++++-------- fs/xfs/libxfs/xfs_trans_resv.c | 14 -------- fs/xfs/libxfs/xfs_trans_resv.h | 1 - fs/xfs/xfs_fsops.c | 29 ---------------- fs/xfs/xfs_log.c | 17 ++++++++-- fs/xfs/xfs_mount.c | 77 ++++++------------------------------------ fs/xfs/xfs_mount.h | 3 +- fs/xfs/xfs_qm.c | 27 ++------------- fs/xfs/xfs_qm_syscalls.c | 7 ++-- fs/xfs/xfs_super.c | 13 +++---- 14 files changed, 95 insertions(+), 216 deletions(-)fs/xfs/libxfs/xfs_attr_leaf.c +1
-1@@ -405,7 +405,7 @@ xfs_sbversion_add_attr2(xfs_mount_t *mp, xfs_trans_t *tp)if (!xfs_sb_version_hasattr2 (&mp->m_sb)) {xfs_sb_version_addattr2 (&mp->m_sb);spin_unlock (&mp->m_sb_lock); -xfs_mod_sb (tp); +xfs_log_sb (tp); }else spin_unlock (&mp->m_sb_lock); }fs/xfs/libxfs/xfs_bmap.c +5
-5@@ -1224,20 +1224,20 @@ xfs_bmap_add_attrfork( goto bmap_cancel;if (!xfs_sb_version_hasattr (&mp->m_sb) || (!xfs_sb_version_hasattr2 (&mp->m_sb) && version ==2 )) { -bool mod_sb = false; +bool log_sb = false;spin_lock (&mp->m_sb_lock);if (!xfs_sb_version_hasattr (&mp->m_sb)) {xfs_sb_version_addattr (&mp->m_sb); - mod_sb = true; + log_sb = true; }if (!xfs_sb_version_hasattr2 (&mp->m_sb) && version ==2 ) {xfs_sb_version_addattr2 (&mp->m_sb); - mod_sb = true; + log_sb = true; }spin_unlock (&mp->m_sb_lock); -if (mod_sb) -xfs_mod_sb (tp); +if (log_sb) +xfs_log_sb (tp); } error =xfs_bmap_finish (&tp, &flist, &committed);fs/xfs/libxfs/xfs_sb.c +37
-6@@ -744,14 +744,13 @@ xfs_initialize_perag_data( }/* -* xfs_mod_sb() can be used to copy arbitrary changes to the -* in-core superblock into the superblock buffer to be logged. -* It does not provide the higher level of locking that is -* needed to protect the in-core superblock from concurrent -* access. +* xfs_log_sb() can be used to copy arbitrary changes to the in-core superblock +* into the superblock buffer to be logged. It does not provide the higher +* level of locking that is needed to protect the in-core superblock from +* concurrent access. */ void -xfs_mod_sb ( +xfs_log_sb (struct xfs_trans *tp) {struct xfs_mount *mp = tp->t_mountp;@@ -761,3 +760,35 @@ xfs_mod_sb(xfs_trans_buf_set_type (tp, bp,XFS_BLFT_SB_BUF );xfs_trans_log_buf (tp, bp,0 ,sizeof (struct xfs_dsb )); } + +/* +* xfs_sync_sb +* +* Sync the superblock to disk. +* +* Note that the caller is responsible for checking the frozen state of the +* filesystem. This procedure uses the non-blocking transaction allocator and +* thus will allow modifications to a frozen fs. This is required because this +* code can be called during the process of freezing where use of the high-level +* allocator would deadlock. +*/ +int +xfs_sync_sb ( +struct xfs_mount *mp, +bool wait) +{ +struct xfs_trans *tp; +int error; + + tp =_xfs_trans_alloc (mp,XFS_TRANS_SB_CHANGE ,KM_SLEEP ); + error =xfs_trans_reserve (tp, &M_RES (mp)->tr_sb,0 ,0 ); +if (error) { +xfs_trans_cancel (tp,0 ); +return error; + } + +xfs_log_sb (tp); +if (wait) +xfs_trans_set_sync (tp); +return xfs_trans_commit (tp,0 ); +}fs/xfs/libxfs/xfs_sb.h +2
-40@@ -274,45 +274,6 @@ typedef enum { XFS_SBS_FIELDCOUNT } xfs_sb_field_t; -/* -* Mask values, defined based on the xfs_sb_field_t values. -* Only define the ones we're using. -*/ -#define XFS_SB_MVAL (x) (1LL << XFS_SBS_ ## x) -#define XFS_SB_UUID XFS_SB_MVAL(UUID) -#define XFS_SB_FNAME XFS_SB_MVAL(FNAME) -#define XFS_SB_ROOTINO XFS_SB_MVAL(ROOTINO) -#define XFS_SB_RBMINO XFS_SB_MVAL(RBMINO) -#define XFS_SB_RSUMINO XFS_SB_MVAL(RSUMINO) -#define XFS_SB_VERSIONNUM XFS_SB_MVAL(VERSIONNUM) -#define XFS_SB_UQUOTINO XFS_SB_MVAL(UQUOTINO) -#define XFS_SB_GQUOTINO XFS_SB_MVAL(GQUOTINO) -#define XFS_SB_QFLAGS XFS_SB_MVAL(QFLAGS) -#define XFS_SB_SHARED_VN XFS_SB_MVAL(SHARED_VN) -#define XFS_SB_UNIT XFS_SB_MVAL(UNIT) -#define XFS_SB_WIDTH XFS_SB_MVAL(WIDTH) -#define XFS_SB_ICOUNT XFS_SB_MVAL(ICOUNT) -#define XFS_SB_IFREE XFS_SB_MVAL(IFREE) -#define XFS_SB_FDBLOCKS XFS_SB_MVAL(FDBLOCKS) -#define XFS_SB_FEATURES2 XFS_SB_MVAL(FEATURES2) -#define XFS_SB_BAD_FEATURES2 XFS_SB_MVAL(BAD_FEATURES2) -#define XFS_SB_FEATURES_COMPAT XFS_SB_MVAL(FEATURES_COMPAT) -#define XFS_SB_FEATURES_RO_COMPAT XFS_SB_MVAL(FEATURES_RO_COMPAT) -#define XFS_SB_FEATURES_INCOMPAT XFS_SB_MVAL(FEATURES_INCOMPAT) -#define XFS_SB_FEATURES_LOG_INCOMPAT XFS_SB_MVAL(FEATURES_LOG_INCOMPAT) -#define XFS_SB_CRC XFS_SB_MVAL(CRC) -#define XFS_SB_PQUOTINO XFS_SB_MVAL(PQUOTINO) -#define XFS_SB_NUM_BITS ((int)XFS_SBS_FIELDCOUNT) -#define XFS_SB_ALL_BITS ((1LL << XFS_SB_NUM_BITS) - 1) -#define XFS_SB_MOD_BITS \ - (XFS_SB_UUID | XFS_SB_ROOTINO | XFS_SB_RBMINO | XFS_SB_RSUMINO | \ - XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | XFS_SB_GQUOTINO | \ - XFS_SB_QFLAGS | XFS_SB_SHARED_VN | XFS_SB_UNIT | XFS_SB_WIDTH | \ - XFS_SB_ICOUNT | XFS_SB_IFREE | XFS_SB_FDBLOCKS | XFS_SB_FEATURES2 | \ - XFS_SB_BAD_FEATURES2 | XFS_SB_FEATURES_COMPAT | \ - XFS_SB_FEATURES_RO_COMPAT | XFS_SB_FEATURES_INCOMPAT | \ - XFS_SB_FEATURES_LOG_INCOMPAT | XFS_SB_PQUOTINO) -/* * Misc. Flags - warning - these will be cleared by xfs_repair unless @@ -612,7 +573,8 @@ extern void xfs_perag_put(struct xfs_perag *pag);extern int xfs_initialize_perag_data (struct xfs_mount *,xfs_agnumber_t );extern void xfs_sb_calc_crc (struct xfs_buf *bp); -extern void xfs_mod_sb (struct xfs_trans *tp); +extern void xfs_log_sb (struct xfs_trans *tp); +extern int xfs_sync_sb (struct xfs_mount *mp,bool wait);extern void xfs_sb_mount_common (struct xfs_mount *mp,struct xfs_sb *sbp);extern void xfs_sb_from_disk (struct xfs_sb *to,struct xfs_dsb *from);extern void xfs_sb_to_disk (struct xfs_dsb *to,struct xfs_sb *from);fs/xfs/libxfs/xfs_shared.h +1
-6@@ -82,7 +82,7 @@ extern const struct xfs_buf_ops xfs_symlink_buf_ops;#define XFS_TRANS_ATTR_RM 23#define XFS_TRANS_ATTR_FLAG 24#define XFS_TRANS_CLEAR_AGI_BUCKET 25 -#define XFS_TRANS_QM_SBCHANGE 26 +#define XFS_TRANS_SB_CHANGE 26/* * Dummy entries since we use the transaction type to index into the * trans_type[] in xlog_recover_print_trans_head() @@ -95,17 +95,15 @@ extern const struct xfs_buf_ops xfs_symlink_buf_ops;#define XFS_TRANS_QM_DQCLUSTER 32#define XFS_TRANS_QM_QINOCREATE 33#define XFS_TRANS_QM_QUOTAOFF_END 34 -#define XFS_TRANS_SB_UNIT 35 -#define XFS_TRANS_FSYNC_TS 36 -#define XFS_TRANS_GROWFSRT_ALLOC 37 -#define XFS_TRANS_GROWFSRT_ZERO 38 -#define XFS_TRANS_GROWFSRT_FREE 39
fs/xfs/libxfs/xfs_shared.h extern const struct xfs_buf_ops xfs_symlink_buf_ops; · line 101
Quoted 10 lines
fs/xfs/libxfs/xfs_shared.h +4
-6-#define XFS_TRANS_SWAPEXT 40 -#define XFS_TRANS_SB_COUNT 41 -#define XFS_TRANS_CHECKPOINT 42 -#define XFS_TRANS_ICREATE 43 -#define XFS_TRANS_CREATE_TMPFILE 44 -#define XFS_TRANS_TYPE_MAX 44 +#define XFS_TRANS_FSYNC_TS 35 +#define XFS_TRANS_GROWFSRT_ALLOC 36 +#define XFS_TRANS_GROWFSRT_ZERO 37 +#define XFS_TRANS_GROWFSRT_FREE 37
38?
FWIW, it also looks like the dummy entries are out of order between these definitions and the XFS_TRANS_TYPES definition below (aesthetic) and a couple of the create entries are missing.
Quoted 119 lines
fs/xfs/libxfs/xfs_shared.h +6
-3+#define XFS_TRANS_SWAPEXT 39 +#define XFS_TRANS_CHECKPOINT 40 +#define XFS_TRANS_ICREATE 41 +#define XFS_TRANS_CREATE_TMPFILE 42 +#define XFS_TRANS_TYPE_MAX 43/* new transaction types need to be reflected in xfs_logprint(8) */ #define XFS_TRANS_TYPES \@@ -134,20 +132,18 @@ extern const struct xfs_buf_ops xfs_symlink_buf_ops; { XFS_TRANS_ATTR_RM, "ATTR_RM" }, \ { XFS_TRANS_ATTR_FLAG, "ATTR_FLAG" }, \ { XFS_TRANS_CLEAR_AGI_BUCKET, "CLEAR_AGI_BUCKET" }, \ - { XFS_TRANS_QM_SBCHANGE, "QM_SBCHANGE" }, \ + { XFS_TRANS_SB_CHANGE, "SBCHANGE" }, \ { XFS_TRANS_QM_QUOTAOFF, "QM_QUOTAOFF" }, \ { XFS_TRANS_QM_DQALLOC, "QM_DQALLOC" }, \ { XFS_TRANS_QM_SETQLIM, "QM_SETQLIM" }, \ { XFS_TRANS_QM_DQCLUSTER, "QM_DQCLUSTER" }, \ { XFS_TRANS_QM_QINOCREATE, "QM_QINOCREATE" }, \ { XFS_TRANS_QM_QUOTAOFF_END, "QM_QOFF_END" }, \ - { XFS_TRANS_SB_UNIT, "SB_UNIT" }, \ { XFS_TRANS_FSYNC_TS, "FSYNC_TS" }, \ { XFS_TRANS_GROWFSRT_ALLOC, "GROWFSRT_ALLOC" }, \ { XFS_TRANS_GROWFSRT_ZERO, "GROWFSRT_ZERO" }, \ { XFS_TRANS_GROWFSRT_FREE, "GROWFSRT_FREE" }, \ { XFS_TRANS_SWAPEXT, "SWAPEXT" }, \ - { XFS_TRANS_SB_COUNT, "SB_COUNT" }, \ { XFS_TRANS_CHECKPOINT, "CHECKPOINT" }, \ { XFS_TRANS_DUMMY1, "DUMMY1" }, \ { XFS_TRANS_DUMMY2, "DUMMY2" }, \fs/xfs/libxfs/xfs_trans_resv.c +0
-14@@ -718,17 +718,6 @@ xfs_calc_clear_agi_bucket_reservation( }/* -* Clearing the quotaflags in the superblock. -* the super block for changing quota flags: sector size -*/ -STATIC uint -xfs_calc_qm_sbchange_reservation ( -struct xfs_mount *mp) -{ -return xfs_calc_buf_res (1 , mp->m_sb.sb_sectsize); -} - -/* * Adjusting quota limits. * the xfs_disk_dquot_t: sizeof(struct xfs_disk_dquot) */ @@ -866,9 +855,6 @@ xfs_trans_resv_calc(* The following transactions are logged in logical format with * a default log count. */ - resp->tr_qm_sbchange.tr_logres =xfs_calc_qm_sbchange_reservation (mp); - resp->tr_qm_sbchange.tr_logcount =XFS_DEFAULT_LOG_COUNT ; - resp->tr_qm_setqlim.tr_logres =xfs_calc_qm_setqlim_reservation (mp); resp->tr_qm_setqlim.tr_logcount =XFS_DEFAULT_LOG_COUNT ;fs/xfs/libxfs/xfs_trans_resv.h +0
-1@@ -56,7 +56,6 @@ struct xfs_trans_resv {struct xfs_trans_res tr_growrtalloc;/* grow realtime allocations */ struct xfs_trans_res tr_growrtzero;/* grow realtime zeroing */ struct xfs_trans_res tr_growrtfree;/* grow realtime freeing */ -struct xfs_trans_res tr_qm_sbchange;/* change quota flags */ struct xfs_trans_res tr_qm_setqlim;/* adjust quota limits */ struct xfs_trans_res tr_qm_dqalloc;/* allocate quota on disk */ struct xfs_trans_res tr_qm_quotaoff;/* turn quota off */ fs/xfs/xfs_fsops.c +0
-29@@ -763,35 +763,6 @@ out:return 0 ; } -/* -* Dump a transaction into the log that contains no real change. This is needed -* to be able to make the log dirty or stamp the current tail LSN into the log -* during the covering operation. -* -* We cannot use an inode here for this - that will push dirty state back up -* into the VFS and then periodic inode flushing will prevent log covering from -* making progress. Hence we log a field in the superblock instead and use a -* synchronous transaction to ensure the superblock is immediately unpinned -* and can be written back. -*/ -int -xfs_fs_log_dummy ( -xfs_mount_t *mp) -{ -xfs_trans_t *tp; -int error; - - tp =_xfs_trans_alloc (mp,XFS_TRANS_DUMMY1 ,KM_SLEEP ); - error =xfs_trans_reserve (tp, &M_RES (mp)->tr_sb,0 ,0 ); -if (error) { -xfs_trans_cancel (tp,0 ); -return error; - } -xfs_mod_sb (tp); -xfs_trans_set_sync (tp); -return xfs_trans_commit (tp,0 ); -} - int xfs_fs_goingdown( xfs_mount_t *mp,fs/xfs/xfs_log.c +0
-0
fs/xfs/xfs_log.c xfs_log_worker( · line 1298
Quoted 10 lines
fs/xfs/xfs_log.c +4
-3@@ -1292,9 +1292,20 @@ xfs_log_worker(struct xfs_mount *mp = log->l_mp;/* dgc: errors ignored - not fatal and nowhere to report them */ -if (xfs_log_need_covered (mp)) -xfs_fs_log_dummy (mp); -else +if (xfs_log_need_covered (mp)) { +/* +* Dump a transaction into the log that contains no real change. +* This is needed stamp the current tail LSN into the log during
"... to stamp"
Brian
Quoted 318 lines
fs/xfs/xfs_log.c +10
-0+* the covering operation. +* +* We cannot use an inode here for this - that will push dirty +* state back up into the VFS and then periodic inode flushing +* will prevent log covering from making progress. Hence we +* synchronously log the superblock instead to ensure the +* superblock is immediately unpinned and can be written back. +*/ +xfs_sync_sb (mp, true); + }else xfs_log_force (mp,0 );/* start pushing all the metadata that is currently dirty */ fs/xfs/xfs_mount.c +11
-66@@ -416,11 +416,11 @@ xfs_update_alignment(xfs_mount_t *mp)if (xfs_sb_version_hasdalign (sbp)) {if (sbp->sb_unit != mp->m_dalign) { sbp->sb_unit = mp->m_dalign; - mp->m_update_flags |=XFS_SB_UNIT ; + mp->m_update_sb = true; }if (sbp->sb_width != mp->m_swidth) { sbp->sb_width = mp->m_swidth; - mp->m_update_flags |=XFS_SB_WIDTH ; + mp->m_update_sb = true; } }else { xfs_warn(mp,@@ -588,38 +588,18 @@ intxfs_mount_reset_sbqflags ( struct xfs_mount *mp) { -int error; -struct xfs_trans *tp; - mp->m_qflags =0 ; -/* -* It is OK to look at sb_qflags here in mount path, -* without m_sb_lock. -*/ +/* It is OK to look at sb_qflags in the mount path without m_sb_lock. */ if (mp->m_sb.sb_qflags ==0 )return 0 ;spin_lock (&mp->m_sb_lock); mp->m_sb.sb_qflags =0 ;spin_unlock (&mp->m_sb_lock); -/* -* If the fs is readonly, let the incore superblock run -* with quotas off but don't flush the update out to disk -*/ if (!xfs_fs_writable (mp,SB_UNFROZEN ))return 0 ; - - tp =xfs_trans_alloc (mp,XFS_TRANS_QM_SBCHANGE ); - error =xfs_trans_reserve (tp, &M_RES (mp)->tr_qm_sbchange,0 ,0 ); -if (error) { -xfs_trans_cancel (tp,0 ); -xfs_alert (mp,"%s: Superblock update failed!" , __func__); -return error; - } - -xfs_mod_sb (tp); -return xfs_trans_commit (tp,0 ); +return xfs_sync_sb (mp, false); } __uint64_t@@ -683,7 +663,7 @@ xfs_mountfs(xfs_warn (mp,"correcting sb_features alignment problem" ); sbp->sb_features2 |= sbp->sb_bad_features2; sbp->sb_bad_features2 = sbp->sb_features2; - mp->m_update_flags |=XFS_SB_FEATURES2 |XFS_SB_BAD_FEATURES2 ; + mp->m_update_sb = true;/* * Re-check for ATTR2 in case it was found in bad_features2 @@ -697,17 +677,17 @@ xfs_mountfs(if (xfs_sb_version_hasattr2 (&mp->m_sb) && (mp->m_flags &XFS_MOUNT_NOATTR2 )) {xfs_sb_version_removeattr2 (&mp->m_sb); - mp->m_update_flags |=XFS_SB_FEATURES2 ; + mp->m_update_sb = true;/* update sb_versionnum for the clearing of the morebits */ if (!sbp->sb_features2) - mp->m_update_flags |=XFS_SB_VERSIONNUM ; + mp->m_update_sb = true; }/* always use v2 inodes by default now */ if (!(mp->m_sb.sb_versionnum &XFS_SB_VERSION_NLINKBIT )) { mp->m_sb.sb_versionnum |=XFS_SB_VERSION_NLINKBIT ; - mp->m_update_flags |=XFS_SB_VERSIONNUM ; + mp->m_update_sb = true; }/* @@ -900,8 +880,8 @@ 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_flags && !(mp->m_flags &XFS_MOUNT_RDONLY )) { - error =xfs_mount_log_sb (mp); +if (mp->m_update_sb && !(mp->m_flags &XFS_MOUNT_RDONLY )) { + error =xfs_sync_sb (mp, false);if (error) {xfs_warn (mp,"failed to write sb changes" ); goto out_rtunmount;@@ -1101,9 +1081,6 @@ xfs_fs_writable(xfs_mount_t *mp, int frozen_state)int xfs_log_sbcount (xfs_mount_t *mp) { -xfs_trans_t *tp; -int error; -/* * We can be called during the fs freeze process, and we need to be * able to write the superblock in that case. @@ -1120,17 +1097,7 @@ xfs_log_sbcount(xfs_mount_t *mp)if (!xfs_sb_version_haslazysbcount (&mp->m_sb))return 0 ; - tp =_xfs_trans_alloc (mp,XFS_TRANS_SB_COUNT ,KM_SLEEP ); - error =xfs_trans_reserve (tp, &M_RES (mp)->tr_sb,0 ,0 ); -if (error) { -xfs_trans_cancel (tp,0 ); -return error; - } - -xfs_mod_sb (tp); -xfs_trans_set_sync (tp); - error =xfs_trans_commit (tp,0 ); -return error; +return xfs_sync_sb (mp, true); }/* @@ -1424,28 +1391,6 @@ xfs_freesb( }/* -* Used to log changes to the superblock unit and width fields which could -* be altered by the mount options, as well as any potential sb_features2 -* fixup. Only the first superblock is updated. -*/ -int -xfs_mount_log_sb ( -xfs_mount_t *mp) -{ -xfs_trans_t *tp; -int error; - - tp =xfs_trans_alloc (mp,XFS_TRANS_SB_UNIT ); - error =xfs_trans_reserve (tp, &M_RES (mp)->tr_sb,0 ,0 ); -if (error) { -xfs_trans_cancel (tp,0 ); -return error; - } -xfs_mod_sb (tp); -return xfs_trans_commit (tp,0 ); -} - -/* * If the underlying (data/log/rt) device is readonly, there are some * operations that cannot proceed. */ fs/xfs/xfs_mount.h +1
-2@@ -162,8 +162,7 @@ typedef struct xfs_mount {struct delayed_work m_reclaim_work;/* background inode reclaim */ struct delayed_work m_eofblocks_work;/* background eof blocks trimming */ -__int64_t m_update_flags;/* sb flags we need to update -on the next remount,rw */ +bool m_update_sb;/* sb needs update in mount */ int64_t m_low_space[XFS_LOWSP_MAX ];/* low free space thresholds */ struct xfs_kobj m_kobj;fs/xfs/xfs_qm.c +2
-25@@ -794,7 +794,7 @@ xfs_qm_qino_alloc(else mp->m_sb.sb_pquotino = (*ip)->i_ino;spin_unlock (&mp->m_sb_lock); -xfs_mod_sb (tp); +xfs_log_sb (tp);if ((error =xfs_trans_commit (tp,XFS_TRANS_RELEASE_LOG_RES ))) {xfs_alert (mp,"%s failed (error %d)!" , __func__, error);@@ -1447,7 +1447,7 @@ xfs_qm_mount_quotas(spin_unlock (&mp->m_sb_lock);if (sbf != (mp->m_qflags &XFS_MOUNT_QUOTA_ALL )) { -if (xfs_qm_write_sb_changes (mp)) { +if (xfs_sync_sb (mp, false)) {/* * We could only have been turning quotas off. * We aren't in very good shape actually because @@ -1576,29 +1576,6 @@ xfs_qm_dqfree_one(xfs_qm_dqdestroy (dqp); } -/* -* Start a transaction and write the incore superblock changes to -* disk. flags parameter indicates which fields have changed. -*/ -int -xfs_qm_write_sb_changes ( -struct xfs_mount *mp) -{ -xfs_trans_t *tp; -int error; - - tp =xfs_trans_alloc (mp,XFS_TRANS_QM_SBCHANGE ); - error =xfs_trans_reserve (tp, &M_RES (mp)->tr_qm_sbchange,0 ,0 ); -if (error) { -xfs_trans_cancel (tp,0 ); -return error; - } - -xfs_mod_sb (tp); -return xfs_trans_commit (tp,0 ); -} - -/* --------------- utility functions for vnodeops ---------------- */ fs/xfs/xfs_qm_syscalls.c +4
-3@@ -93,7 +93,7 @@ xfs_qm_scall_quotaoff(mutex_unlock (&q->qi_quotaofflock);/* XXX what to do if error ? Revert back to old vals incore ? */ -return xfs_qm_write_sb_changes (mp); +return xfs_sync_sb (mp, false); } dqtype =0 ;@@ -370,7 +370,8 @@ xfs_qm_scall_quotaon(if ((qf & flags) == flags)return -EEXIST ; -if ((error =xfs_qm_write_sb_changes (mp))) + error =xfs_sync_sb (mp, false); +if (error)return error;/* * If we aren't trying to switch on quota enforcement, we are done. @@ -795,7 +796,7 @@ xfs_qm_log_quotaoff( mp->m_sb.sb_qflags = (mp->m_qflags & ~(flags)) &XFS_MOUNT_QUOTA_ALL ;spin_unlock (&mp->m_sb_lock); -xfs_mod_sb (tp); +xfs_log_sb (tp);/* * We have to make sure that the transaction is secure on disk before we fs/xfs/xfs_super.c +7
-6@@ -1254,13 +1254,13 @@ xfs_fs_remount(* If this is the first remount to writeable state we * might have some superblock changes to update. */ -if (mp->m_update_flags) { - error =xfs_mount_log_sb (mp); +if (mp->m_update_sb) { + error =xfs_sync_sb (mp, false);if (error) {xfs_warn (mp,"failed to write sb changes" );return error; } - mp->m_update_flags =0 ; + mp->m_update_sb = false; }/* @@ -1290,8 +1290,9 @@ xfs_fs_remount(/* * Second stage of a freeze. The data is already frozen so we only -* need to take care of the metadata. Once that's done write a dummy -* record to dirty the log in case of a crash while frozen. +* need to take care of the metadata. Once that's done sync the superblock +* to the log to dirty it in case of a crash while frozen. This ensures that we +* will recover the unlinked inode lists on the next mount. */ STATIC int xfs_fs_freeze(@@ -1301,7 +1302,7 @@ xfs_fs_freeze(xfs_save_resvblks (mp);xfs_quiesce_attr (mp); -return xfs_fs_log_dummy (mp); +return xfs_sync_sb (mp, true); }STATIC intSignature · 6 lines
2.0.0 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs