aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_sync.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2012-04-23 01:58:36 -0400
committerBen Myers <bpm@sgi.com>2012-05-14 17:20:28 -0400
commit4c46819a8097a75d3b378c5e56d2bcf47bb7408d (patch)
tree031f84bd94f044218d43ef3d11f90df0480513c6 /fs/xfs/xfs_sync.c
parent8a48088f6439249019b5e17f6391e710656879d9 (diff)
xfs: do not write the buffer from xfs_iflush
Instead of writing the buffer directly from inside xfs_iflush return it to the caller and let the caller decide what to do with the buffer. Also remove the pincount check in xfs_iflush that all non-blocking callers already implement and the now unused flags parameter. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Mark Tinguely <tinguely@sgi.com> Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_sync.c')
-rw-r--r--fs/xfs/xfs_sync.c29
1 files changed, 15 insertions, 14 deletions
diff --git a/fs/xfs/xfs_sync.c b/fs/xfs/xfs_sync.c
index 7b2bccc4d67b..468c3c0a4f9f 100644
--- a/fs/xfs/xfs_sync.c
+++ b/fs/xfs/xfs_sync.c
@@ -648,10 +648,6 @@ xfs_reclaim_inode_grab(
648 * (*) dgc: I don't think the clean, pinned state is possible but it gets 648 * (*) dgc: I don't think the clean, pinned state is possible but it gets
649 * handled anyway given the order of checks implemented. 649 * handled anyway given the order of checks implemented.
650 * 650 *
651 * As can be seen from the table, the return value of xfs_iflush() is not
652 * sufficient to correctly decide the reclaim action here. The checks in
653 * xfs_iflush() might look like duplicates, but they are not.
654 *
655 * Also, because we get the flush lock first, we know that any inode that has 651 * Also, because we get the flush lock first, we know that any inode that has
656 * been flushed delwri has had the flush completed by the time we check that 652 * been flushed delwri has had the flush completed by the time we check that
657 * the inode is clean. 653 * the inode is clean.
@@ -679,7 +675,8 @@ xfs_reclaim_inode(
679 struct xfs_perag *pag, 675 struct xfs_perag *pag,
680 int sync_mode) 676 int sync_mode)
681{ 677{
682 int error; 678 struct xfs_buf *bp = NULL;
679 int error;
683 680
684restart: 681restart:
685 error = 0; 682 error = 0;
@@ -728,29 +725,33 @@ restart:
728 /* 725 /*
729 * Now we have an inode that needs flushing. 726 * Now we have an inode that needs flushing.
730 * 727 *
731 * We do a nonblocking flush here even if we are doing a SYNC_WAIT 728 * Note that xfs_iflush will never block on the inode buffer lock, as
732 * reclaim as we can deadlock with inode cluster removal.
733 * xfs_ifree_cluster() can lock the inode buffer before it locks the 729 * xfs_ifree_cluster() can lock the inode buffer before it locks the
734 * ip->i_lock, and we are doing the exact opposite here. As a result, 730 * ip->i_lock, and we are doing the exact opposite here. As a result,
735 * doing a blocking xfs_itobp() to get the cluster buffer will result 731 * doing a blocking xfs_itobp() to get the cluster buffer would result
736 * in an ABBA deadlock with xfs_ifree_cluster(). 732 * in an ABBA deadlock with xfs_ifree_cluster().
737 * 733 *
738 * As xfs_ifree_cluser() must gather all inodes that are active in the 734 * As xfs_ifree_cluser() must gather all inodes that are active in the
739 * cache to mark them stale, if we hit this case we don't actually want 735 * cache to mark them stale, if we hit this case we don't actually want
740 * to do IO here - we want the inode marked stale so we can simply 736 * to do IO here - we want the inode marked stale so we can simply
741 * reclaim it. Hence if we get an EAGAIN error on a SYNC_WAIT flush, 737 * reclaim it. Hence if we get an EAGAIN error here, just unlock the
742 * just unlock the inode, back off and try again. Hopefully the next 738 * inode, back off and try again. Hopefully the next pass through will
743 * pass through will see the stale flag set on the inode. 739 * see the stale flag set on the inode.
744 */ 740 */
745 error = xfs_iflush(ip, SYNC_TRYLOCK | sync_mode); 741 error = xfs_iflush(ip, &bp);
746 if (error == EAGAIN) { 742 if (error == EAGAIN) {
747 xfs_iunlock(ip, XFS_ILOCK_EXCL); 743 xfs_iunlock(ip, XFS_ILOCK_EXCL);
748 /* backoff longer than in xfs_ifree_cluster */ 744 /* backoff longer than in xfs_ifree_cluster */
749 delay(2); 745 delay(2);
750 goto restart; 746 goto restart;
751 } 747 }
752 xfs_iflock(ip);
753 748
749 if (!error) {
750 error = xfs_bwrite(bp);
751 xfs_buf_relse(bp);
752 }
753
754 xfs_iflock(ip);
754reclaim: 755reclaim:
755 xfs_ifunlock(ip); 756 xfs_ifunlock(ip);
756 xfs_iunlock(ip, XFS_ILOCK_EXCL); 757 xfs_iunlock(ip, XFS_ILOCK_EXCL);