@ -648,10 +648,6 @@ xfs_reclaim_inode_grab(
* ( * ) dgc : I don ' t think the clean , pinned state is possible but it gets
* handled anyway given the order of checks implemented .
*
* As can be seen from the table , the return value of xfs_iflush ( ) is not
* sufficient to correctly decide the reclaim action here . The checks in
* xfs_iflush ( ) might look like duplicates , but they are not .
*
* Also , because we get the flush lock first , we know that any inode that has
* been flushed delwri has had the flush completed by the time we check that
* the inode is clean .
@ -679,7 +675,8 @@ xfs_reclaim_inode(
struct xfs_perag * pag ,
int sync_mode )
{
int error ;
struct xfs_buf * bp = NULL ;
int error ;
restart :
error = 0 ;
@ -728,29 +725,33 @@ restart:
/*
* Now we have an inode that needs flushing .
*
* We do a nonblocking flush here even if we are doing a SYNC_WAIT
* reclaim as we can deadlock with inode cluster removal .
* Note that xfs_iflush will never block on the inode buffer lock , as
* xfs_ifree_cluster ( ) can lock the inode buffer before it locks the
* ip - > i_lock , and we are doing the exact opposite here . As a result ,
* doing a blocking xfs_itobp ( ) to get the cluster buffer will result
* ip - > i_lock , and we are doing the exact opposite here . As a result ,
* doing a blocking xfs_itobp ( ) to get the cluster buffer would result
* in an ABBA deadlock with xfs_ifree_cluster ( ) .
*
* As xfs_ifree_cluser ( ) must gather all inodes that are active in the
* cache to mark them stale , if we hit this case we don ' t actually want
* to do IO here - we want the inode marked stale so we can simply
* reclaim it . Hence if we get an EAGAIN error on a SYNC_WAIT flush ,
* just unlock the inode , back off and try again . Hopefully the next
* pass through will see the stale flag set on the inode .
* reclaim it . Hence if we get an EAGAIN error here , just unlock the
* inode , back off and try again . Hopefully the next pass through will
* see the stale flag set on the inode .
*/
error = xfs_iflush ( ip , SYNC_TRYLOCK | sync_mode ) ;
error = xfs_iflush ( ip , & bp ) ;
if ( error = = EAGAIN ) {
xfs_iunlock ( ip , XFS_ILOCK_EXCL ) ;
/* backoff longer than in xfs_ifree_cluster */
delay ( 2 ) ;
goto restart ;
}
xfs_iflock ( ip ) ;
if ( ! error ) {
error = xfs_bwrite ( bp ) ;
xfs_buf_relse ( bp ) ;
}
xfs_iflock ( ip ) ;
reclaim :
xfs_ifunlock ( ip ) ;
xfs_iunlock ( ip , XFS_ILOCK_EXCL ) ;