xfs_log_force related cleanups
A couple cleanups and refactorig around xfs_log_force and friends.
PATCH 1/8 xfs: remove misleading comment text on xfs_inode_item_unlock
--- fs/xfs/xfs_inode_item.c | 3 --- 1 file changed, 3 deletions(-)
fs/xfs/xfs_inode_item.c +0 -3
@@ -579,9 +579,6 @@ xfs_inode_item_push(/* * Unlock the inode associated with the inode log item. -* Clear the fields of the inode and inode log item that -* are specific to the current transaction. If the -* hold flags is set, do not unlock the inode. */ STATIC void xfs_inode_item_unlock(
Signature · 1 line
2.14.2
Re: [PATCH 1/8] xfs: remove misleading comment text on xfs_inode_item_unlock
Quoted 1 line · Christoph Hellwig
Signed-off-by Christoph Hellwig <[email protected]>
Looks ok,
--D
Quoted 25 lines
--- fs/xfs/xfs_inode_item.c | 3 --- 1 file changed, 3 deletions(-)fs/xfs/xfs_inode_item.c +0
-3@@ -579,9 +579,6 @@ xfs_inode_item_push(/* * Unlock the inode associated with the inode log item. -* Clear the fields of the inode and inode log item that -* are specific to the current transaction. If the -* hold flags is set, do not unlock the inode. */ STATIC void xfs_inode_item_unlock(Signature · 6 lines
2.14.2 -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 2/8 xfs: remove an outdated comment for xfs_inode_item_committing
In reply to Christoph HellwigThe function now does something, and that something is central to our inode logging scheme.
--- fs/xfs/xfs_inode_item.c | 4 ---- 1 file changed, 4 deletions(-)
fs/xfs/xfs_inode_item.c +0 -4
@@ -634,10 +634,6 @@ xfs_inode_item_committed(return lsn; } -/* -* XXX rcc - this one really has to do something. Probably needs -* to stamp in a new field in the incore inode. -*/ STATIC void xfs_inode_item_committing( struct xfs_log_item *lip,
Signature · 1 line
2.14.2
Re: [PATCH 2/8] xfs: remove an outdated comment for xfs_inode_item_committing
Quoted 4 lines · Christoph Hellwig
The function now does something, and that something is central to our inode logging scheme.
Signed-off-by Christoph Hellwig <[email protected]>
Looks ok,
--D
Quoted 26 lines
--- fs/xfs/xfs_inode_item.c | 4 ---- 1 file changed, 4 deletions(-)fs/xfs/xfs_inode_item.c +0
-4@@ -634,10 +634,6 @@ xfs_inode_item_committed(return lsn; } -/* -* XXX rcc - this one really has to do something. Probably needs -* to stamp in a new field in the incore inode. -*/ STATIC void xfs_inode_item_committing( struct xfs_log_item *lip,Signature · 6 lines
2.14.2 -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 3/8 xfs: remove the unused log_flushed variable in xfs_extent_busy_flush
In reply to Christoph Hellwig--- fs/xfs/xfs_extent_busy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/xfs/xfs_extent_busy.c +2 -2
@@ -611,10 +611,10 @@ xfs_extent_busy_flush( unsigned busy_gen) {DEFINE_WAIT (wait); -int log_flushed =0 , error; +int error;trace_xfs_log_force (mp,0 , _THIS_IP_); - error =_xfs_log_force (mp,XFS_LOG_SYNC , &log_flushed); + error =_xfs_log_force (mp,XFS_LOG_SYNC ,NULL );if (error)return ;
Signature · 1 line
2.14.2
Re: [PATCH 3/8] xfs: remove the unused log_flushed variable in xfs_extent_busy_flush
Quoted 1 line · Christoph Hellwig
Signed-off-by Christoph Hellwig <[email protected]>
Looks ok,
--D
Quoted 28 lines
--- fs/xfs/xfs_extent_busy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)fs/xfs/xfs_extent_busy.c +2
-2@@ -611,10 +611,10 @@ xfs_extent_busy_flush( unsigned busy_gen) {DEFINE_WAIT (wait); -int log_flushed =0 , error; +int error;trace_xfs_log_force (mp,0 , _THIS_IP_); - error =_xfs_log_force (mp,XFS_LOG_SYNC , &log_flushed); + error =_xfs_log_force (mp,XFS_LOG_SYNC ,NULL );if (error)return ;Signature · 6 lines
2.14.2 -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 4/8 xfs: merge _xfs_log_force and xfs_log_force
In reply to Christoph HellwigSwitch to a single interface for flushing the whole log, which gives consistent trace point coverage, and removes the unused log_flushed argument for the previous _xfs_log_force callers.
--- fs/xfs/scrub/common.c | 2 +- fs/xfs/xfs_extent_busy.c | 3 +-- fs/xfs/xfs_log.c | 26 +++++--------------------- fs/xfs/xfs_log.h | 6 +----- 4 files changed, 8 insertions(+), 29 deletions(-)
fs/xfs/scrub/common.c +1 -1
@@ -619,7 +619,7 @@ xfs_scrub_checkpoint_log( {int error; - error =_xfs_log_force (mp,XFS_LOG_SYNC ,NULL ); + error =xfs_log_force (mp,XFS_LOG_SYNC );if (error)return error;xfs_ail_push_all_sync (mp->m_ail);
fs/xfs/xfs_extent_busy.c +1 -2
@@ -613,8 +613,7 @@ xfs_extent_busy_flush(DEFINE_WAIT (wait);int error; -trace_xfs_log_force (mp,0 , _THIS_IP_); - error =_xfs_log_force (mp,XFS_LOG_SYNC ,NULL ); + error =xfs_log_force (mp,XFS_LOG_SYNC );if (error)return ;
fs/xfs/xfs_log.c +5 -21
@@ -869,7 +869,7 @@ xfs_log_unmount_write(xfs_mount_t *mp)return 0 ; } - error =_xfs_log_force (mp,XFS_LOG_SYNC ,NULL ); + error =xfs_log_force (mp,XFS_LOG_SYNC );ASSERT (error || !(XLOG_FORCED_SHUTDOWN (log)));#ifdef DEBUG
@@ -3304,16 +3304,16 @@ xlog_state_switch_iclogs(* not in the active nor dirty state. */ int -_xfs_log_force ( +xfs_log_force (struct xfs_mount *mp, -uint flags, -int *log_flushed) +uint flags) {struct xlog *log = mp->m_log;struct xlog_in_core *iclog;xfs_lsn_t lsn;XFS_STATS_INC (mp, xs_log_force); +trace_xfs_log_force (mp,0 , _RET_IP_);xlog_cil_force (log);
@@ -3362,8 +3362,6 @@ _xfs_log_force(if (xlog_state_release_iclog (log, iclog))return -EIO ; -if (log_flushed) - *log_flushed =1 ;spin_lock (&log->l_icloglock);if (be64_to_cpu (iclog->ic_header.h_lsn) == lsn && iclog->ic_state !=XLOG_STATE_DIRTY )
@@ -3415,20 +3413,6 @@ _xfs_log_force(return 0 ; } -/* -* Wrapper for _xfs_log_force(), to be used when caller doesn't care -* about errors or whether the log was flushed or not. This is the normal -* interface to use when trying to unpin items or move the log forward. -*/ -void -xfs_log_force ( -xfs_mount_t *mp, -uint flags) -{ -trace_xfs_log_force (mp,0 , _RET_IP_); -_xfs_log_force (mp, flags,NULL ); -} -/* * Force the in-core log to disk for a specific LSN. *
@@ -4035,7 +4019,7 @@ xfs_log_force_umount(* to guarantee this. */ if (!logerror) -_xfs_log_force (mp,XFS_LOG_SYNC ,NULL ); +xfs_log_force (mp,XFS_LOG_SYNC );/* * mark the filesystem and the as in a shutdown state and wake
fs/xfs/xfs_log.h +1 -5
@@ -129,11 +129,7 @@ xfs_lsn_t xfs_log_done(struct xfs_mount *mp,struct xlog_ticket *ticket, struct xlog_in_core **iclog, bool regrant); -int _xfs_log_force (struct xfs_mount *mp, -uint flags, -int *log_forced); -void xfs_log_force (struct xfs_mount *mp, -uint flags); +int xfs_log_force (struct xfs_mount *mp,uint flags); int _xfs_log_force_lsn(struct xfs_mount *mp, xfs_lsn_t lsn, uint flags,
Signature · 1 line
2.14.2
Re: [PATCH 4/8] xfs: merge _xfs_log_force and xfs_log_force
Quoted 5 lines · Christoph Hellwig
Switch to a single interface for flushing the whole log, which gives consistent trace point coverage, and removes the unused
log_flushedargument for the previous_xfs_log_forcecallers.Signed-off-by Christoph Hellwig <[email protected]>
Looks ok,
--D
Quoted 130 lines
--- fs/xfs/scrub/common.c | 2 +- fs/xfs/xfs_extent_busy.c | 3 +-- fs/xfs/xfs_log.c | 26 +++++--------------------- fs/xfs/xfs_log.h | 6 +----- 4 files changed, 8 insertions(+), 29 deletions(-)fs/xfs/scrub/common.c +1
-1@@ -619,7 +619,7 @@ xfs_scrub_checkpoint_log( {int error; - error =_xfs_log_force (mp,XFS_LOG_SYNC ,NULL ); + error =xfs_log_force (mp,XFS_LOG_SYNC );if (error)return error;xfs_ail_push_all_sync (mp->m_ail);fs/xfs/xfs_extent_busy.c +1
-2@@ -613,8 +613,7 @@ xfs_extent_busy_flush(DEFINE_WAIT (wait);int error; -trace_xfs_log_force (mp,0 , _THIS_IP_); - error =_xfs_log_force (mp,XFS_LOG_SYNC ,NULL ); + error =xfs_log_force (mp,XFS_LOG_SYNC );if (error)return ;fs/xfs/xfs_log.c +5
-21@@ -869,7 +869,7 @@ xfs_log_unmount_write(xfs_mount_t *mp)return 0 ; } - error =_xfs_log_force (mp,XFS_LOG_SYNC ,NULL ); + error =xfs_log_force (mp,XFS_LOG_SYNC );ASSERT (error || !(XLOG_FORCED_SHUTDOWN (log)));#ifdef DEBUG @@ -3304,16 +3304,16 @@ xlog_state_switch_iclogs(* not in the active nor dirty state. */ int -_xfs_log_force ( +xfs_log_force (struct xfs_mount *mp, -uint flags, -int *log_flushed) +uint flags) {struct xlog *log = mp->m_log;struct xlog_in_core *iclog;xfs_lsn_t lsn;XFS_STATS_INC (mp, xs_log_force); +trace_xfs_log_force (mp,0 , _RET_IP_);xlog_cil_force (log);@@ -3362,8 +3362,6 @@ _xfs_log_force(if (xlog_state_release_iclog (log, iclog))return -EIO ; -if (log_flushed) - *log_flushed =1 ;spin_lock (&log->l_icloglock);if (be64_to_cpu (iclog->ic_header.h_lsn) == lsn && iclog->ic_state !=XLOG_STATE_DIRTY )@@ -3415,20 +3413,6 @@ _xfs_log_force(return 0 ; } -/* -* Wrapper for _xfs_log_force(), to be used when caller doesn't care -* about errors or whether the log was flushed or not. This is the normal -* interface to use when trying to unpin items or move the log forward. -*/ -void -xfs_log_force ( -xfs_mount_t *mp, -uint flags) -{ -trace_xfs_log_force (mp,0 , _RET_IP_); -_xfs_log_force (mp, flags,NULL ); -} -/* * Force the in-core log to disk for a specific LSN. * @@ -4035,7 +4019,7 @@ xfs_log_force_umount(* to guarantee this. */ if (!logerror) -_xfs_log_force (mp,XFS_LOG_SYNC ,NULL ); +xfs_log_force (mp,XFS_LOG_SYNC );/* * mark the filesystem and the as in a shutdown state and wake fs/xfs/xfs_log.h +1
-5@@ -129,11 +129,7 @@ xfs_lsn_t xfs_log_done(struct xfs_mount *mp,struct xlog_ticket *ticket, struct xlog_in_core **iclog, bool regrant); -int _xfs_log_force (struct xfs_mount *mp, -uint flags, -int *log_forced); -void xfs_log_force (struct xfs_mount *mp, -uint flags); +int xfs_log_force (struct xfs_mount *mp,uint flags); int _xfs_log_force_lsn(struct xfs_mount *mp, xfs_lsn_t lsn, uint flags,Signature · 6 lines
2.14.2 -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 5/8 xfs: merge _xfs_log_force_lsn and xfs_log_force_lsn
In reply to Christoph HellwigSwitch to a single interface for flushing the log to a specific LSN, which gives consistent trace point coverage and a less confusing interface.
The was only a single user of the previous xfs_log_force_lsn function, which now also passes a NULL log_flushed argument.
--- fs/xfs/xfs_export.c | 2 +- fs/xfs/xfs_file.c | 4 ++-- fs/xfs/xfs_inode.c | 2 +- fs/xfs/xfs_log.c | 18 ++---------------- fs/xfs/xfs_log.h | 9 ++------- fs/xfs/xfs_trans.c | 2 +- 6 files changed, 9 insertions(+), 28 deletions(-)
fs/xfs/xfs_export.c +1 -1
@@ -237,7 +237,7 @@ xfs_fs_nfs_commit_metadata(if (!lsn)return 0 ; -return _xfs_log_force_lsn (mp, lsn,XFS_LOG_SYNC ,NULL ); +return xfs_log_force_lsn (mp, lsn,XFS_LOG_SYNC ,NULL ); }const struct export_operations xfs_export_operations = {
fs/xfs/xfs_file.c +2 -2
@@ -122,7 +122,7 @@ xfs_dir_fsync(if (!lsn)return 0 ; -return _xfs_log_force_lsn (mp, lsn,XFS_LOG_SYNC ,NULL ); +return xfs_log_force_lsn (mp, lsn,XFS_LOG_SYNC ,NULL ); }STATIC int
@@ -182,7 +182,7 @@ xfs_file_fsync( }if (lsn) { - error =_xfs_log_force_lsn (mp, lsn,XFS_LOG_SYNC , &log_flushed); + error =xfs_log_force_lsn (mp, lsn,XFS_LOG_SYNC , &log_flushed); ip->i_itemp->ili_fsync_fields =0 ; }xfs_iunlock (ip,XFS_ILOCK_SHARED );
fs/xfs/xfs_inode.c +1 -1
@@ -2497,7 +2497,7 @@ xfs_iunpin(trace_xfs_inode_unpin_nowait (ip, _RET_IP_);/* Give the log a push to start the unpinning I/O */ -xfs_log_force_lsn (ip->i_mount, ip->i_itemp->ili_last_lsn,0 ); +xfs_log_force_lsn (ip->i_mount, ip->i_itemp->ili_last_lsn,0 ,NULL ); }
fs/xfs/xfs_log.c +2 -16
@@ -3429,7 +3429,7 @@ xfs_log_force(* sv. */ int -_xfs_log_force_lsn( +xfs_log_force_lsn( struct xfs_mount *mp, xfs_lsn_t lsn, uint flags,
@@ -3442,6 +3442,7 @@ _xfs_log_force_lsn(ASSERT (lsn !=0 );XFS_STATS_INC (mp, xs_log_force); +trace_xfs_log_force (mp, lsn, _RET_IP_); lsn =xlog_cil_force_lsn (log, lsn);if (lsn ==NULLCOMMITLSN )
@@ -3538,21 +3539,6 @@ _xfs_log_force_lsn(return 0 ; } -/* -* Wrapper for _xfs_log_force_lsn(), to be used when caller doesn't care -* about errors or whether the log was flushed or not. This is the normal -* interface to use when trying to unpin items or move the log forward. -*/ -void -xfs_log_force_lsn ( -xfs_mount_t *mp, -xfs_lsn_t lsn, -uint flags) -{ -trace_xfs_log_force (mp, lsn, _RET_IP_); -_xfs_log_force_lsn (mp, lsn, flags,NULL ); -} -/* * Called when we want to mark the current iclog as being ready to sync to * disk.
fs/xfs/xfs_log.h +2 -7
@@ -130,13 +130,8 @@ xfs_lsn_t xfs_log_done(struct xfs_mount *mp,struct xlog_in_core **iclog, bool regrant);int xfs_log_force (struct xfs_mount *mp,uint flags); -int _xfs_log_force_lsn (struct xfs_mount *mp, -xfs_lsn_t lsn, -uint flags, -int *log_forced); -void xfs_log_force_lsn (struct xfs_mount *mp, -xfs_lsn_t lsn, -uint flags); +int xfs_log_force_lsn (struct xfs_mount *mp,xfs_lsn_t lsn,uint flags, +int *log_forced); int xfs_log_mount(struct xfs_mount *mp, struct xfs_buftarg *log_target, xfs_daddr_t start_block,
fs/xfs/xfs_trans.c +1 -1
@@ -966,7 +966,7 @@ __xfs_trans_commit(* log out now and wait for it. */ if (sync) { - error =_xfs_log_force_lsn (mp, commit_lsn,XFS_LOG_SYNC ,NULL ); + error =xfs_log_force_lsn (mp, commit_lsn,XFS_LOG_SYNC ,NULL );XFS_STATS_INC (mp, xs_trans_sync); }else {XFS_STATS_INC (mp, xs_trans_async);
Signature · 1 line
2.14.2
Re: [PATCH 5/8] xfs: merge _xfs_log_force_lsn and xfs_log_force_lsn
Quoted 7 lines · Christoph Hellwig
Switch to a single interface for flushing the log to a specific LSN, which gives consistent trace point coverage and a less confusing interface.
The was only a single user of the previous
xfs_log_force_lsnfunction, which now also passes a NULLlog_flushedargument.Signed-off-by Christoph Hellwig <[email protected]>
Looks ok,
--D
Quoted 140 lines
--- fs/xfs/xfs_export.c | 2 +- fs/xfs/xfs_file.c | 4 ++-- fs/xfs/xfs_inode.c | 2 +- fs/xfs/xfs_log.c | 18 ++---------------- fs/xfs/xfs_log.h | 9 ++------- fs/xfs/xfs_trans.c | 2 +- 6 files changed, 9 insertions(+), 28 deletions(-)fs/xfs/xfs_export.c +1
-1@@ -237,7 +237,7 @@ xfs_fs_nfs_commit_metadata(if (!lsn)return 0 ; -return _xfs_log_force_lsn (mp, lsn,XFS_LOG_SYNC ,NULL ); +return xfs_log_force_lsn (mp, lsn,XFS_LOG_SYNC ,NULL ); }const struct export_operations xfs_export_operations = {fs/xfs/xfs_file.c +2
-2@@ -122,7 +122,7 @@ xfs_dir_fsync(if (!lsn)return 0 ; -return _xfs_log_force_lsn (mp, lsn,XFS_LOG_SYNC ,NULL ); +return xfs_log_force_lsn (mp, lsn,XFS_LOG_SYNC ,NULL ); }STATIC int@@ -182,7 +182,7 @@ xfs_file_fsync( }if (lsn) { - error =_xfs_log_force_lsn (mp, lsn,XFS_LOG_SYNC , &log_flushed); + error =xfs_log_force_lsn (mp, lsn,XFS_LOG_SYNC , &log_flushed); ip->i_itemp->ili_fsync_fields =0 ; }xfs_iunlock (ip,XFS_ILOCK_SHARED );fs/xfs/xfs_inode.c +1
-1@@ -2497,7 +2497,7 @@ xfs_iunpin(trace_xfs_inode_unpin_nowait (ip, _RET_IP_);/* Give the log a push to start the unpinning I/O */ -xfs_log_force_lsn (ip->i_mount, ip->i_itemp->ili_last_lsn,0 ); +xfs_log_force_lsn (ip->i_mount, ip->i_itemp->ili_last_lsn,0 ,NULL ); }fs/xfs/xfs_log.c +2
-16@@ -3429,7 +3429,7 @@ xfs_log_force(* sv. */ int -_xfs_log_force_lsn( +xfs_log_force_lsn( struct xfs_mount *mp, xfs_lsn_t lsn, uint flags,@@ -3442,6 +3442,7 @@ _xfs_log_force_lsn(ASSERT (lsn !=0 );XFS_STATS_INC (mp, xs_log_force); +trace_xfs_log_force (mp, lsn, _RET_IP_); lsn =xlog_cil_force_lsn (log, lsn);if (lsn ==NULLCOMMITLSN )@@ -3538,21 +3539,6 @@ _xfs_log_force_lsn(return 0 ; } -/* -* Wrapper for _xfs_log_force_lsn(), to be used when caller doesn't care -* about errors or whether the log was flushed or not. This is the normal -* interface to use when trying to unpin items or move the log forward. -*/ -void -xfs_log_force_lsn ( -xfs_mount_t *mp, -xfs_lsn_t lsn, -uint flags) -{ -trace_xfs_log_force (mp, lsn, _RET_IP_); -_xfs_log_force_lsn (mp, lsn, flags,NULL ); -} -/* * Called when we want to mark the current iclog as being ready to sync to * disk. fs/xfs/xfs_log.h +2
-7@@ -130,13 +130,8 @@ xfs_lsn_t xfs_log_done(struct xfs_mount *mp,struct xlog_in_core **iclog, bool regrant);int xfs_log_force (struct xfs_mount *mp,uint flags); -int _xfs_log_force_lsn (struct xfs_mount *mp, -xfs_lsn_t lsn, -uint flags, -int *log_forced); -void xfs_log_force_lsn (struct xfs_mount *mp, -xfs_lsn_t lsn, -uint flags); +int xfs_log_force_lsn (struct xfs_mount *mp,xfs_lsn_t lsn,uint flags, +int *log_forced); int xfs_log_mount(struct xfs_mount *mp, struct xfs_buftarg *log_target, xfs_daddr_t start_block,fs/xfs/xfs_trans.c +1
-1@@ -966,7 +966,7 @@ __xfs_trans_commit(* log out now and wait for it. */ if (sync) { - error =_xfs_log_force_lsn (mp, commit_lsn,XFS_LOG_SYNC ,NULL ); + error =xfs_log_force_lsn (mp, commit_lsn,XFS_LOG_SYNC ,NULL );XFS_STATS_INC (mp, xs_trans_sync); }else {XFS_STATS_INC (mp, xs_trans_async);Signature · 6 lines
2.14.2 -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 6/8 xfs: refactor xfs_log_force
In reply to Christoph HellwigStreamline the conditionals so that it is more obvious which specific case form the top of the function comments is being handled. Use gotos only for early returns.
--- fs/xfs/xfs_log.c | 144 ++++++++++++++++++++++++------------------------------- 1 file changed, 63 insertions(+), 81 deletions(-)
fs/xfs/xfs_log.c +63 -81
@@ -3318,99 +3318,81 @@ xfs_log_force(xlog_cil_force (log);spin_lock (&log->l_icloglock); - iclog = log->l_iclog; -if (iclog->ic_state &XLOG_STATE_IOERROR ) { -spin_unlock (&log->l_icloglock); -return -EIO ; - } +if (iclog->ic_state &XLOG_STATE_IOERROR ) + goto out_error; -/* If the head iclog is not active nor dirty, we just attach -* ourselves to the head and go to sleep. -*/ -if (iclog->ic_state ==XLOG_STATE_ACTIVE || - iclog->ic_state ==XLOG_STATE_DIRTY ) { +if (iclog->ic_state ==XLOG_STATE_DIRTY || + (iclog->ic_state ==XLOG_STATE_ACTIVE && +atomic_read (&iclog->ic_refcnt) ==0 && iclog->ic_offset ==0 )) {/* -* If the head is dirty or (active and empty), then -* we need to look at the previous iclog. If the previous -* iclog is active or dirty we are done. There is nothing -* to sync out. Otherwise, we attach ourselves to the +* If the head is dirty or (active and empty), then we need to +* look at the previous iclog. +* +* If the previous iclog is active or dirty we are done. There +* is nothing to sync out. Otherwise, we attach ourselves to the * previous iclog and go to sleep. */ -if (iclog->ic_state ==XLOG_STATE_DIRTY || - (atomic_read (&iclog->ic_refcnt) ==0 - && iclog->ic_offset ==0 )) { - iclog = iclog->ic_prev; -if (iclog->ic_state ==XLOG_STATE_ACTIVE || - iclog->ic_state ==XLOG_STATE_DIRTY ) - goto no_sleep; -else - goto maybe_sleep; - }else { -if (atomic_read (&iclog->ic_refcnt) ==0 ) { -/* We are the only one with access to this -* iclog. Flush it out now. There should -* be a roundoff of zero to show that someone -* has already taken care of the roundoff from -* the previous sync. -*/ -atomic_inc (&iclog->ic_refcnt); - lsn =be64_to_cpu (iclog->ic_header.h_lsn); -xlog_state_switch_iclogs (log, iclog,0 ); -spin_unlock (&log->l_icloglock); - -if (xlog_state_release_iclog (log, iclog)) -return -EIO ; + iclog = iclog->ic_prev; +if (iclog->ic_state ==XLOG_STATE_ACTIVE || + iclog->ic_state ==XLOG_STATE_DIRTY ) + goto out_unlock; + }else if (iclog->ic_state ==XLOG_STATE_ACTIVE ) { +if (atomic_read (&iclog->ic_refcnt) ==0 ) { +/* +* We are the only one with access to this iclog. +* +* Flush it out now. There should be a roundoff of zero +* to show that someone has already taken care of the +* roundoff from the previous sync. +*/ +atomic_inc (&iclog->ic_refcnt); + lsn =be64_to_cpu (iclog->ic_header.h_lsn); +xlog_state_switch_iclogs (log, iclog,0 ); +spin_unlock (&log->l_icloglock); -spin_lock (&log->l_icloglock); -if (be64_to_cpu (iclog->ic_header.h_lsn) == lsn && - iclog->ic_state !=XLOG_STATE_DIRTY ) - goto maybe_sleep; -else - goto no_sleep; - }else { -/* Someone else is writing to this iclog. -* Use its call to flush out the data. However, -* the other thread may not force out this LR, -* so we mark it WANT_SYNC. -*/ -xlog_state_switch_iclogs (log, iclog,0 ); - goto maybe_sleep; - } - } - } +if (xlog_state_release_iclog (log, iclog)) +return -EIO ; -/* By the time we come around again, the iclog could've been filled -* which would give it another lsn. If we have a new lsn, just -* return because the relevant data has been flushed. -*/ -maybe_sleep: -if (flags &XFS_LOG_SYNC ) { -/* -* We must check if we're shutting down here, before -* we wait, while we're holding the l_icloglock. -* Then we check again after waking up, in case our -* sleep was disturbed by a bad news. -*/ -if (iclog->ic_state &XLOG_STATE_IOERROR ) { -spin_unlock (&log->l_icloglock); -return -EIO ; +spin_lock (&log->l_icloglock); +if (be64_to_cpu (iclog->ic_header.h_lsn) != lsn || + iclog->ic_state ==XLOG_STATE_DIRTY ) + goto out_unlock; + }else { +/* +* Someone else is writing to this iclog. +* +* Use its call to flush out the data. However, the +* other thread may not force out this LR, so we mark +* it WANT_SYNC. +*/ +xlog_state_switch_iclogs (log, iclog,0 ); } -XFS_STATS_INC (mp, xs_log_force_sleep); -xlog_wait (&iclog->ic_force_wait, &log->l_icloglock); + }else {/* -* No need to grab the log lock here since we're -* only deciding whether or not to return EIO -* and the memory read should be atomic. +* If the head iclog is not active nor dirty, we just attach +* ourselves to the head and go to sleep if necessary. */ -if (iclog->ic_state &XLOG_STATE_IOERROR ) -return -EIO ; - }else { - -no_sleep: -spin_unlock (&log->l_icloglock); + ; } + +if (!(flags &XFS_LOG_SYNC )) + goto out_unlock; + +if (iclog->ic_state &XLOG_STATE_IOERROR ) + goto out_error; +XFS_STATS_INC (mp, xs_log_force_sleep); +xlog_wait (&iclog->ic_force_wait, &log->l_icloglock); +if (iclog->ic_state &XLOG_STATE_IOERROR ) +return -EIO ;return 0 ; + +out_unlock: +spin_unlock (&log->l_icloglock); +return 0 ; +out_error: +spin_unlock (&log->l_icloglock); +return -EIO ; }/*
Signature · 1 line
2.14.2
Re: [PATCH 6/8] xfs: refactor xfs_log_force
Quoted 5 lines · Christoph Hellwig
Streamline the conditionals so that it is more obvious which specific case form the top of the function comments is being handled. Use gotos only for early returns.
Signed-off-by Christoph Hellwig <[email protected]>
Well, that made my brain hurt... :)
--D
Quoted 178 lines
--- fs/xfs/xfs_log.c | 144 ++++++++++++++++++++++++------------------------------- 1 file changed, 63 insertions(+), 81 deletions(-)fs/xfs/xfs_log.c +63
-81@@ -3318,99 +3318,81 @@ xfs_log_force(xlog_cil_force (log);spin_lock (&log->l_icloglock); - iclog = log->l_iclog; -if (iclog->ic_state &XLOG_STATE_IOERROR ) { -spin_unlock (&log->l_icloglock); -return -EIO ; - } +if (iclog->ic_state &XLOG_STATE_IOERROR ) + goto out_error; -/* If the head iclog is not active nor dirty, we just attach -* ourselves to the head and go to sleep. -*/ -if (iclog->ic_state ==XLOG_STATE_ACTIVE || - iclog->ic_state ==XLOG_STATE_DIRTY ) { +if (iclog->ic_state ==XLOG_STATE_DIRTY || + (iclog->ic_state ==XLOG_STATE_ACTIVE && +atomic_read (&iclog->ic_refcnt) ==0 && iclog->ic_offset ==0 )) {/* -* If the head is dirty or (active and empty), then -* we need to look at the previous iclog. If the previous -* iclog is active or dirty we are done. There is nothing -* to sync out. Otherwise, we attach ourselves to the +* If the head is dirty or (active and empty), then we need to +* look at the previous iclog. +* +* If the previous iclog is active or dirty we are done. There +* is nothing to sync out. Otherwise, we attach ourselves to the * previous iclog and go to sleep. */ -if (iclog->ic_state ==XLOG_STATE_DIRTY || - (atomic_read (&iclog->ic_refcnt) ==0 - && iclog->ic_offset ==0 )) { - iclog = iclog->ic_prev; -if (iclog->ic_state ==XLOG_STATE_ACTIVE || - iclog->ic_state ==XLOG_STATE_DIRTY ) - goto no_sleep; -else - goto maybe_sleep; - }else { -if (atomic_read (&iclog->ic_refcnt) ==0 ) { -/* We are the only one with access to this -* iclog. Flush it out now. There should -* be a roundoff of zero to show that someone -* has already taken care of the roundoff from -* the previous sync. -*/ -atomic_inc (&iclog->ic_refcnt); - lsn =be64_to_cpu (iclog->ic_header.h_lsn); -xlog_state_switch_iclogs (log, iclog,0 ); -spin_unlock (&log->l_icloglock); - -if (xlog_state_release_iclog (log, iclog)) -return -EIO ; + iclog = iclog->ic_prev; +if (iclog->ic_state ==XLOG_STATE_ACTIVE || + iclog->ic_state ==XLOG_STATE_DIRTY ) + goto out_unlock; + }else if (iclog->ic_state ==XLOG_STATE_ACTIVE ) { +if (atomic_read (&iclog->ic_refcnt) ==0 ) { +/* +* We are the only one with access to this iclog. +* +* Flush it out now. There should be a roundoff of zero +* to show that someone has already taken care of the +* roundoff from the previous sync. +*/ +atomic_inc (&iclog->ic_refcnt); + lsn =be64_to_cpu (iclog->ic_header.h_lsn); +xlog_state_switch_iclogs (log, iclog,0 ); +spin_unlock (&log->l_icloglock); -spin_lock (&log->l_icloglock); -if (be64_to_cpu (iclog->ic_header.h_lsn) == lsn && - iclog->ic_state !=XLOG_STATE_DIRTY ) - goto maybe_sleep; -else - goto no_sleep; - }else { -/* Someone else is writing to this iclog. -* Use its call to flush out the data. However, -* the other thread may not force out this LR, -* so we mark it WANT_SYNC. -*/ -xlog_state_switch_iclogs (log, iclog,0 ); - goto maybe_sleep; - } - } - } +if (xlog_state_release_iclog (log, iclog)) +return -EIO ; -/* By the time we come around again, the iclog could've been filled -* which would give it another lsn. If we have a new lsn, just -* return because the relevant data has been flushed. -*/ -maybe_sleep: -if (flags &XFS_LOG_SYNC ) { -/* -* We must check if we're shutting down here, before -* we wait, while we're holding the l_icloglock. -* Then we check again after waking up, in case our -* sleep was disturbed by a bad news. -*/ -if (iclog->ic_state &XLOG_STATE_IOERROR ) { -spin_unlock (&log->l_icloglock); -return -EIO ; +spin_lock (&log->l_icloglock); +if (be64_to_cpu (iclog->ic_header.h_lsn) != lsn || + iclog->ic_state ==XLOG_STATE_DIRTY ) + goto out_unlock; + }else { +/* +* Someone else is writing to this iclog. +* +* Use its call to flush out the data. However, the +* other thread may not force out this LR, so we mark +* it WANT_SYNC. +*/ +xlog_state_switch_iclogs (log, iclog,0 ); } -XFS_STATS_INC (mp, xs_log_force_sleep); -xlog_wait (&iclog->ic_force_wait, &log->l_icloglock); + }else {/* -* No need to grab the log lock here since we're -* only deciding whether or not to return EIO -* and the memory read should be atomic. +* If the head iclog is not active nor dirty, we just attach +* ourselves to the head and go to sleep if necessary. */ -if (iclog->ic_state &XLOG_STATE_IOERROR ) -return -EIO ; - }else { - -no_sleep: -spin_unlock (&log->l_icloglock); + ; } + +if (!(flags &XFS_LOG_SYNC )) + goto out_unlock; + +if (iclog->ic_state &XLOG_STATE_IOERROR ) + goto out_error; +XFS_STATS_INC (mp, xs_log_force_sleep); +xlog_wait (&iclog->ic_force_wait, &log->l_icloglock); +if (iclog->ic_state &XLOG_STATE_IOERROR ) +return -EIO ;return 0 ; + +out_unlock: +spin_unlock (&log->l_icloglock); +return 0 ; +out_error: +spin_unlock (&log->l_icloglock); +return -EIO ; }/* Signature · 6 lines
2.14.2 -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 7/8 xfs: refactor xfs_log_force_lsn
In reply to Christoph HellwigUse the the smallest possible loop as preable to find the correct iclog buffer, and then use gotos for unwinding to straighten the code.
Also fix the top of function comment while we're at it.
--- fs/xfs/xfs_log.c | 142 ++++++++++++++++++++++++------------------------------- 1 file changed, 62 insertions(+), 80 deletions(-)
fs/xfs/xfs_log.c +62 -80
@@ -3404,11 +3404,10 @@ xfs_log_force(* state and go to sleep or return. * If it is in any other state, go to sleep or return. * -* Synchronous forces are implemented with a signal variable. All callers -* to force a given lsn to disk will wait on a the sv attached to the -* specific in-core log. When given in-core log finally completes its -* write to disk, that thread will wake up all threads waiting on the -* sv. +* Synchronous forces are implemented with a wait queue. All callers to force a +* given lsn to disk will wait on a the queue attached to the specific in-core +* log. When given in-core log finally completes its write to disk, that thread +* will wake up all threads waiting on the queue. */ int xfs_log_force_lsn(
@@ -3433,92 +3432,75 @@ xfs_log_force_lsn( try_again:spin_lock (&log->l_icloglock); iclog = log->l_iclog; -if (iclog->ic_state &XLOG_STATE_IOERROR ) { -spin_unlock (&log->l_icloglock); -return -EIO ; - } +if (iclog->ic_state &XLOG_STATE_IOERROR ) + goto out_error; -do { -if (be64_to_cpu (iclog->ic_header.h_lsn) != lsn) { - iclog = iclog->ic_next; -continue ; - } +while (be64_to_cpu (iclog->ic_header.h_lsn) != lsn) { + iclog = iclog->ic_next; +if (iclog == log->l_iclog) + goto out_unlock; + } -if (iclog->ic_state ==XLOG_STATE_DIRTY ) { -spin_unlock (&log->l_icloglock); -return 0 ; - } +if (iclog->ic_state ==XLOG_STATE_DIRTY ) + goto out_unlock; -if (iclog->ic_state ==XLOG_STATE_ACTIVE ) { -/* -* We sleep here if we haven't already slept (e.g. -* this is the first time we've looked at the correct -* iclog buf) and the buffer before us is going to -* be sync'ed. The reason for this is that if we -* are doing sync transactions here, by waiting for -* the previous I/O to complete, we can allow a few -* more transactions into this iclog before we close -* it down. -* -* Otherwise, we mark the buffer WANT_SYNC, and bump -* up the refcnt so we can release the log (which -* drops the ref count). The state switch keeps new -* transaction commits from using this buffer. When -* the current commits finish writing into the buffer, -* the refcount will drop to zero and the buffer will -* go out then. -*/ -if (!already_slept && - (iclog->ic_prev->ic_state & - (XLOG_STATE_WANT_SYNC |XLOG_STATE_SYNCING ))) { -ASSERT (!(iclog->ic_state &XLOG_STATE_IOERROR )); +if (iclog->ic_state ==XLOG_STATE_ACTIVE ) { +/* +* We sleep here if we haven't already slept (e.g. this is the +* first time we've looked at the correct iclog buf) and the +* buffer before us is going to be sync'ed. The reason for this +* is that if we are doing sync transactions here, by waiting +* for the previous I/O to complete, we can allow a few more +* transactions into this iclog before we close it down. +* +* Otherwise, we mark the buffer WANT_SYNC, and bump up the +* refcnt so we can release the log (which drops the ref count). +* The state switch keeps new transaction commits from using +* this buffer. When the current commits finish writing into +* the buffer, the refcount will drop to zero and the buffer +* will go out then. +*/ +if (!already_slept && + (iclog->ic_prev->ic_state & + (XLOG_STATE_WANT_SYNC |XLOG_STATE_SYNCING ))) { +ASSERT (!(iclog->ic_state &XLOG_STATE_IOERROR )); -XFS_STATS_INC (mp, xs_log_force_sleep); +XFS_STATS_INC (mp, xs_log_force_sleep); -xlog_wait (&iclog->ic_prev->ic_write_wait, - &log->l_icloglock); - already_slept =1 ; - goto try_again; - } -atomic_inc (&iclog->ic_refcnt); -xlog_state_switch_iclogs (log, iclog,0 ); -spin_unlock (&log->l_icloglock); -if (xlog_state_release_iclog (log, iclog)) -return -EIO ; -if (log_flushed) - *log_flushed =1 ; -spin_lock (&log->l_icloglock); +xlog_wait (&iclog->ic_prev->ic_write_wait, + &log->l_icloglock); + already_slept =1 ; + goto try_again; } +atomic_inc (&iclog->ic_refcnt); +xlog_state_switch_iclogs (log, iclog,0 ); +spin_unlock (&log->l_icloglock); +if (xlog_state_release_iclog (log, iclog)) +return -EIO ; +if (log_flushed) + *log_flushed =1 ; +spin_lock (&log->l_icloglock); + } -if ((flags &XFS_LOG_SYNC ) &&/* sleep */ - !(iclog->ic_state & - (XLOG_STATE_ACTIVE |XLOG_STATE_DIRTY ))) { -/* -* Don't wait on completion if we know that we've -* gotten a log write error. -*/ -if (iclog->ic_state &XLOG_STATE_IOERROR ) { -spin_unlock (&log->l_icloglock); -return -EIO ; - } -XFS_STATS_INC (mp, xs_log_force_sleep); -xlog_wait (&iclog->ic_force_wait, &log->l_icloglock); -/* -* No need to grab the log lock here since we're -* only deciding whether or not to return EIO -* and the memory read should be atomic. -*/ -if (iclog->ic_state &XLOG_STATE_IOERROR ) -return -EIO ; - }else {/* just return */ -spin_unlock (&log->l_icloglock); - } +if (!(flags &XFS_LOG_SYNC ) || + (iclog->ic_state & (XLOG_STATE_ACTIVE |XLOG_STATE_DIRTY ))) + goto out_unlock; -return 0 ; - }while (iclog != log->l_iclog); +if (iclog->ic_state &XLOG_STATE_IOERROR ) + goto out_error; + +XFS_STATS_INC (mp, xs_log_force_sleep); +xlog_wait (&iclog->ic_force_wait, &log->l_icloglock); +if (iclog->ic_state &XLOG_STATE_IOERROR ) +return -EIO ; +return 0 ; +out_unlock:spin_unlock (&log->l_icloglock);return 0 ; +out_error: +spin_unlock (&log->l_icloglock); +return -EIO ; }/*
Signature · 1 line
2.14.2
Re: [PATCH 7/8] xfs: refactor xfs_log_force_lsn
Quoted 2 lines · Christoph Hellwig
Use the the smallest possible loop as preable to find the correct iclog buffer, and then use gotos for unwinding to straighten the code.
"Use the smallest possible loop to find the correct iclog..." ?
Quoted 13 lines
Also fix the top of function comment while we're at it.
Signed-off-by Christoph Hellwig <[email protected]>--- fs/xfs/xfs_log.c | 142 ++++++++++++++++++++++++------------------------------- 1 file changed, 62 insertions(+), 80 deletions(-)fs/xfs/xfs_log.c +0
-0
fs/xfs/xfs_log.c xfs_log_force( · line 3408
Quoted 10 lines
fs/xfs/xfs_log.c +2
-5@@ -3404,11 +3404,10 @@ xfs_log_force(* state and go to sleep or return. * If it is in any other state, go to sleep or return. * -* Synchronous forces are implemented with a signal variable. All callers -* to force a given lsn to disk will wait on a the sv attached to the -* specific in-core log. When given in-core log finally completes its -* write to disk, that thread will wake up all threads waiting on the -* sv. +* Synchronous forces are implemented with a wait queue. All callers to force a +* given lsn to disk will wait on a the queue attached to the specific in-core
"All callers trying to force a given lsn to disk must wait on the queue attached to the specific in-core log."... I think?
--D
Quoted 163 lines
fs/xfs/xfs_log.c +60
-75+* log. When given in-core log finally completes its write to disk, that thread +* will wake up all threads waiting on the queue. */ int xfs_log_force_lsn(@@ -3433,92 +3432,75 @@ xfs_log_force_lsn( try_again:spin_lock (&log->l_icloglock); iclog = log->l_iclog; -if (iclog->ic_state &XLOG_STATE_IOERROR ) { -spin_unlock (&log->l_icloglock); -return -EIO ; - } +if (iclog->ic_state &XLOG_STATE_IOERROR ) + goto out_error; -do { -if (be64_to_cpu (iclog->ic_header.h_lsn) != lsn) { - iclog = iclog->ic_next; -continue ; - } +while (be64_to_cpu (iclog->ic_header.h_lsn) != lsn) { + iclog = iclog->ic_next; +if (iclog == log->l_iclog) + goto out_unlock; + } -if (iclog->ic_state ==XLOG_STATE_DIRTY ) { -spin_unlock (&log->l_icloglock); -return 0 ; - } +if (iclog->ic_state ==XLOG_STATE_DIRTY ) + goto out_unlock; -if (iclog->ic_state ==XLOG_STATE_ACTIVE ) { -/* -* We sleep here if we haven't already slept (e.g. -* this is the first time we've looked at the correct -* iclog buf) and the buffer before us is going to -* be sync'ed. The reason for this is that if we -* are doing sync transactions here, by waiting for -* the previous I/O to complete, we can allow a few -* more transactions into this iclog before we close -* it down. -* -* Otherwise, we mark the buffer WANT_SYNC, and bump -* up the refcnt so we can release the log (which -* drops the ref count). The state switch keeps new -* transaction commits from using this buffer. When -* the current commits finish writing into the buffer, -* the refcount will drop to zero and the buffer will -* go out then. -*/ -if (!already_slept && - (iclog->ic_prev->ic_state & - (XLOG_STATE_WANT_SYNC |XLOG_STATE_SYNCING ))) { -ASSERT (!(iclog->ic_state &XLOG_STATE_IOERROR )); +if (iclog->ic_state ==XLOG_STATE_ACTIVE ) { +/* +* We sleep here if we haven't already slept (e.g. this is the +* first time we've looked at the correct iclog buf) and the +* buffer before us is going to be sync'ed. The reason for this +* is that if we are doing sync transactions here, by waiting +* for the previous I/O to complete, we can allow a few more +* transactions into this iclog before we close it down. +* +* Otherwise, we mark the buffer WANT_SYNC, and bump up the +* refcnt so we can release the log (which drops the ref count). +* The state switch keeps new transaction commits from using +* this buffer. When the current commits finish writing into +* the buffer, the refcount will drop to zero and the buffer +* will go out then. +*/ +if (!already_slept && + (iclog->ic_prev->ic_state & + (XLOG_STATE_WANT_SYNC |XLOG_STATE_SYNCING ))) { +ASSERT (!(iclog->ic_state &XLOG_STATE_IOERROR )); -XFS_STATS_INC (mp, xs_log_force_sleep); +XFS_STATS_INC (mp, xs_log_force_sleep); -xlog_wait (&iclog->ic_prev->ic_write_wait, - &log->l_icloglock); - already_slept =1 ; - goto try_again; - } -atomic_inc (&iclog->ic_refcnt); -xlog_state_switch_iclogs (log, iclog,0 ); -spin_unlock (&log->l_icloglock); -if (xlog_state_release_iclog (log, iclog)) -return -EIO ; -if (log_flushed) - *log_flushed =1 ; -spin_lock (&log->l_icloglock); +xlog_wait (&iclog->ic_prev->ic_write_wait, + &log->l_icloglock); + already_slept =1 ; + goto try_again; } +atomic_inc (&iclog->ic_refcnt); +xlog_state_switch_iclogs (log, iclog,0 ); +spin_unlock (&log->l_icloglock); +if (xlog_state_release_iclog (log, iclog)) +return -EIO ; +if (log_flushed) + *log_flushed =1 ; +spin_lock (&log->l_icloglock); + } -if ((flags &XFS_LOG_SYNC ) &&/* sleep */ - !(iclog->ic_state & - (XLOG_STATE_ACTIVE |XLOG_STATE_DIRTY ))) { -/* -* Don't wait on completion if we know that we've -* gotten a log write error. -*/ -if (iclog->ic_state &XLOG_STATE_IOERROR ) { -spin_unlock (&log->l_icloglock); -return -EIO ; - } -XFS_STATS_INC (mp, xs_log_force_sleep); -xlog_wait (&iclog->ic_force_wait, &log->l_icloglock); -/* -* No need to grab the log lock here since we're -* only deciding whether or not to return EIO -* and the memory read should be atomic. -*/ -if (iclog->ic_state &XLOG_STATE_IOERROR ) -return -EIO ; - }else {/* just return */ -spin_unlock (&log->l_icloglock); - } +if (!(flags &XFS_LOG_SYNC ) || + (iclog->ic_state & (XLOG_STATE_ACTIVE |XLOG_STATE_DIRTY ))) + goto out_unlock; -return 0 ; - }while (iclog != log->l_iclog); +if (iclog->ic_state &XLOG_STATE_IOERROR ) + goto out_error; + +XFS_STATS_INC (mp, xs_log_force_sleep); +xlog_wait (&iclog->ic_force_wait, &log->l_icloglock); +if (iclog->ic_state &XLOG_STATE_IOERROR ) +return -EIO ; +return 0 ; +out_unlock:spin_unlock (&log->l_icloglock);return 0 ; +out_error: +spin_unlock (&log->l_icloglock); +return -EIO ; }/* Signature · 6 lines
2.14.2 -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 8/8 xfs: unwind the try_again loop in xfs_log_force
In reply to Christoph HellwigInstead split out a __xfs_log_fore_lsn helper that gets called again with the already_slept flag set to true in case we had to sleep.
This prepares for aio_fsync support.
--- fs/xfs/xfs_log.c | 72 +++++++++++++++++++++++++++++++++----------------------- 1 file changed, 42 insertions(+), 30 deletions(-)
fs/xfs/xfs_log.c +42 -30
@@ -3395,41 +3395,17 @@ xfs_log_force(return -EIO ; } -/* -* Force the in-core log to disk for a specific LSN. -* -* Find in-core log with lsn. -* If it is in the DIRTY state, just return. -* If it is in the ACTIVE state, move the in-core log into the WANT_SYNC -* state and go to sleep or return. -* If it is in any other state, go to sleep or return. -* -* Synchronous forces are implemented with a wait queue. All callers to force a -* given lsn to disk will wait on a the queue attached to the specific in-core -* log. When given in-core log finally completes its write to disk, that thread -* will wake up all threads waiting on the queue. -*/ -int -xfs_log_force_lsn ( +static int +__xfs_log_force_lsn (struct xfs_mount *mp,xfs_lsn_t lsn,uint flags, -int *log_flushed) +int *log_flushed, +bool already_slept) {struct xlog *log = mp->m_log;struct xlog_in_core *iclog; -int already_slept =0 ; - -ASSERT (lsn !=0 ); - -XFS_STATS_INC (mp, xs_log_force); -trace_xfs_log_force (mp, lsn, _RET_IP_); - - lsn =xlog_cil_force_lsn (log, lsn); -if (lsn ==NULLCOMMITLSN ) -return 0 ; -try_again:spin_lock (&log->l_icloglock); iclog = log->l_iclog;if (iclog->ic_state &XLOG_STATE_IOERROR )
@@ -3469,8 +3445,7 @@ xfs_log_force_lsn(xlog_wait (&iclog->ic_prev->ic_write_wait, &log->l_icloglock); - already_slept =1 ; - goto try_again; +return -EAGAIN ; }atomic_inc (&iclog->ic_refcnt);xlog_state_switch_iclogs (log, iclog,0 );
@@ -3503,6 +3478,43 @@ xfs_log_force_lsn(return -EIO ; } +/* +* Force the in-core log to disk for a specific LSN. +* +* Find in-core log with lsn. +* If it is in the DIRTY state, just return. +* If it is in the ACTIVE state, move the in-core log into the WANT_SYNC +* state and go to sleep or return. +* If it is in any other state, go to sleep or return. +* +* Synchronous forces are implemented with a wait queue. All callers to force a +* given lsn to disk will wait on a the queue attached to the specific in-core +* log. When given in-core log finally completes its write to disk, that thread +* will wake up all threads waiting on the queue. +*/ +int +xfs_log_force_lsn ( +struct xfs_mount *mp, +xfs_lsn_t lsn, +uint flags, +int *log_flushed) +{ +int ret; +ASSERT (lsn !=0 ); + +XFS_STATS_INC (mp, xs_log_force); +trace_xfs_log_force (mp, lsn, _RET_IP_); + + lsn =xlog_cil_force_lsn (mp->m_log, lsn); +if (lsn ==NULLCOMMITLSN ) +return 0 ; + + ret =__xfs_log_force_lsn (mp, lsn, flags, log_flushed, false); +if (ret == -EAGAIN ) + ret =__xfs_log_force_lsn (mp, lsn, flags, log_flushed, true); +return ret; +} +/* * Called when we want to mark the current iclog as being ready to sync to * disk.
Signature · 1 line
2.14.2
Re: [PATCH 8/8] xfs: unwind the try_again loop in xfs_log_force
Quoted 1 line · Christoph Hellwig
Instead split out a
__xfs_log_fore_lsnhelper that gets called again
I assume you meant __xfs_log_force_lsn?
Looks ok modulo fixing the tortured sentence in the comment in the previous patch that gets moved around in this one,
--D
Quoted 120 lines
with the
already_sleptflag set to true in case we had to sleep.This prepares for
aio_fsyncsupport.Signed-off-by Christoph Hellwig <[email protected]>--- fs/xfs/xfs_log.c | 72 +++++++++++++++++++++++++++++++++----------------------- 1 file changed, 42 insertions(+), 30 deletions(-)fs/xfs/xfs_log.c +42
-30@@ -3395,41 +3395,17 @@ xfs_log_force(return -EIO ; } -/* -* Force the in-core log to disk for a specific LSN. -* -* Find in-core log with lsn. -* If it is in the DIRTY state, just return. -* If it is in the ACTIVE state, move the in-core log into the WANT_SYNC -* state and go to sleep or return. -* If it is in any other state, go to sleep or return. -* -* Synchronous forces are implemented with a wait queue. All callers to force a -* given lsn to disk will wait on a the queue attached to the specific in-core -* log. When given in-core log finally completes its write to disk, that thread -* will wake up all threads waiting on the queue. -*/ -int -xfs_log_force_lsn ( +static int +__xfs_log_force_lsn (struct xfs_mount *mp,xfs_lsn_t lsn,uint flags, -int *log_flushed) +int *log_flushed, +bool already_slept) {struct xlog *log = mp->m_log;struct xlog_in_core *iclog; -int already_slept =0 ; - -ASSERT (lsn !=0 ); - -XFS_STATS_INC (mp, xs_log_force); -trace_xfs_log_force (mp, lsn, _RET_IP_); - - lsn =xlog_cil_force_lsn (log, lsn); -if (lsn ==NULLCOMMITLSN ) -return 0 ; -try_again:spin_lock (&log->l_icloglock); iclog = log->l_iclog;if (iclog->ic_state &XLOG_STATE_IOERROR )@@ -3469,8 +3445,7 @@ xfs_log_force_lsn(xlog_wait (&iclog->ic_prev->ic_write_wait, &log->l_icloglock); - already_slept =1 ; - goto try_again; +return -EAGAIN ; }atomic_inc (&iclog->ic_refcnt);xlog_state_switch_iclogs (log, iclog,0 );@@ -3503,6 +3478,43 @@ xfs_log_force_lsn(return -EIO ; } +/* +* Force the in-core log to disk for a specific LSN. +* +* Find in-core log with lsn. +* If it is in the DIRTY state, just return. +* If it is in the ACTIVE state, move the in-core log into the WANT_SYNC +* state and go to sleep or return. +* If it is in any other state, go to sleep or return. +* +* Synchronous forces are implemented with a wait queue. All callers to force a +* given lsn to disk will wait on a the queue attached to the specific in-core +* log. When given in-core log finally completes its write to disk, that thread +* will wake up all threads waiting on the queue. +*/ +int +xfs_log_force_lsn ( +struct xfs_mount *mp, +xfs_lsn_t lsn, +uint flags, +int *log_flushed) +{ +int ret; +ASSERT (lsn !=0 ); + +XFS_STATS_INC (mp, xs_log_force); +trace_xfs_log_force (mp, lsn, _RET_IP_); + + lsn =xlog_cil_force_lsn (mp->m_log, lsn); +if (lsn ==NULLCOMMITLSN ) +return 0 ; + + ret =__xfs_log_force_lsn (mp, lsn, flags, log_flushed, false); +if (ret == -EAGAIN ) + ret =__xfs_log_force_lsn (mp, lsn, flags, log_flushed, true); +return ret; +} +/* * Called when we want to mark the current iclog as being ready to sync to * disk. Signature · 6 lines
2.14.2 -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html