Skip to content

Commit

Permalink
xfs: split out inode walk inode grabbing
Browse files Browse the repository at this point in the history
When doing read side inode cache walks, the code to validate and
grab an inode is common to all callers. Split it out of the execute
callbacks in preparation for batching lookups. Similarly, split out
the inode reference dropping from the execute callbacks into the
main lookup look to be symmetric with the grab.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Alex Elder <aelder@sgi.com>
  • Loading branch information
Dave Chinner authored and Alex Elder committed Oct 18, 2010
1 parent 65d0f20 commit e13de95
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 54 deletions.
79 changes: 34 additions & 45 deletions fs/xfs/linux-2.6/xfs_sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,33 @@
#include <linux/kthread.h>
#include <linux/freezer.h>

STATIC int
xfs_inode_ag_walk_grab(
struct xfs_inode *ip)
{
struct inode *inode = VFS_I(ip);

/* nothing to sync during shutdown */
if (XFS_FORCED_SHUTDOWN(ip->i_mount))
return EFSCORRUPTED;

/* avoid new or reclaimable inodes. Leave for reclaim code to flush */
if (xfs_iflags_test(ip, XFS_INEW | XFS_IRECLAIMABLE | XFS_IRECLAIM))
return ENOENT;

/* If we can't grab the inode, it must on it's way to reclaim. */
if (!igrab(inode))
return ENOENT;

if (is_bad_inode(inode)) {
IRELE(ip);
return ENOENT;
}

/* inode is valid */
return 0;
}


STATIC int
xfs_inode_ag_walk(
Expand Down Expand Up @@ -80,8 +107,14 @@ xfs_inode_ag_walk(
if (first_index < XFS_INO_TO_AGINO(mp, ip->i_ino))
done = 1;

/* execute releases pag->pag_ici_lock */
if (xfs_inode_ag_walk_grab(ip)) {
read_unlock(&pag->pag_ici_lock);
continue;
}
read_unlock(&pag->pag_ici_lock);

error = execute(ip, pag, flags);
IRELE(ip);
if (error == EAGAIN) {
skipped++;
continue;
Expand Down Expand Up @@ -128,40 +161,6 @@ xfs_inode_ag_iterator(
return XFS_ERROR(last_error);
}

/* must be called with pag_ici_lock held and releases it */
int
xfs_sync_inode_valid(
struct xfs_inode *ip,
struct xfs_perag *pag)
{
struct inode *inode = VFS_I(ip);
int error = EFSCORRUPTED;

/* nothing to sync during shutdown */
if (XFS_FORCED_SHUTDOWN(ip->i_mount))
goto out_unlock;

/* avoid new or reclaimable inodes. Leave for reclaim code to flush */
error = ENOENT;
if (xfs_iflags_test(ip, XFS_INEW | XFS_IRECLAIMABLE | XFS_IRECLAIM))
goto out_unlock;

/* If we can't grab the inode, it must on it's way to reclaim. */
if (!igrab(inode))
goto out_unlock;

if (is_bad_inode(inode)) {
IRELE(ip);
goto out_unlock;
}

/* inode is valid */
error = 0;
out_unlock:
read_unlock(&pag->pag_ici_lock);
return error;
}

STATIC int
xfs_sync_inode_data(
struct xfs_inode *ip,
Expand All @@ -172,10 +171,6 @@ xfs_sync_inode_data(
struct address_space *mapping = inode->i_mapping;
int error = 0;

error = xfs_sync_inode_valid(ip, pag);
if (error)
return error;

if (!mapping_tagged(mapping, PAGECACHE_TAG_DIRTY))
goto out_wait;

Expand All @@ -192,7 +187,6 @@ xfs_sync_inode_data(
out_wait:
if (flags & SYNC_WAIT)
xfs_ioend_wait(ip);
IRELE(ip);
return error;
}

Expand All @@ -204,10 +198,6 @@ xfs_sync_inode_attr(
{
int error = 0;

error = xfs_sync_inode_valid(ip, pag);
if (error)
return error;

xfs_ilock(ip, XFS_ILOCK_SHARED);
if (xfs_inode_clean(ip))
goto out_unlock;
Expand All @@ -226,7 +216,6 @@ xfs_sync_inode_attr(

out_unlock:
xfs_iunlock(ip, XFS_ILOCK_SHARED);
IRELE(ip);
return error;
}

Expand Down
9 changes: 0 additions & 9 deletions fs/xfs/quota/xfs_qm_syscalls.c
Original file line number Diff line number Diff line change
Expand Up @@ -875,21 +875,14 @@ xfs_dqrele_inode(
struct xfs_perag *pag,
int flags)
{
int error;

/* skip quota inodes */
if (ip == ip->i_mount->m_quotainfo->qi_uquotaip ||
ip == ip->i_mount->m_quotainfo->qi_gquotaip) {
ASSERT(ip->i_udquot == NULL);
ASSERT(ip->i_gdquot == NULL);
read_unlock(&pag->pag_ici_lock);
return 0;
}

error = xfs_sync_inode_valid(ip, pag);
if (error)
return error;

xfs_ilock(ip, XFS_ILOCK_EXCL);
if ((flags & XFS_UQUOTA_ACCT) && ip->i_udquot) {
xfs_qm_dqrele(ip->i_udquot);
Expand All @@ -900,8 +893,6 @@ xfs_dqrele_inode(
ip->i_gdquot = NULL;
}
xfs_iunlock(ip, XFS_ILOCK_EXCL);

IRELE(ip);
return 0;
}

Expand Down

0 comments on commit e13de95

Please sign in to comment.