[XFS] split up xlog_recover_process_iunlinks

Split out the body of the main loop into a separate helper to make the
code readable.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Niv Sardi <xaiki@sgi.com>
This commit is contained in:
Christoph Hellwig 2008-11-28 14:23:40 +11:00 committed by Niv Sardi
parent 51ce16d519
commit 23fac50f95

View File

@ -3147,6 +3147,70 @@ out_error:
return;
}
STATIC xfs_agino_t
xlog_recover_process_one_iunlink(
struct xfs_mount *mp,
xfs_agnumber_t agno,
xfs_agino_t agino,
int bucket)
{
struct xfs_buf *ibp;
struct xfs_dinode *dip;
struct xfs_inode *ip;
xfs_ino_t ino;
int error;
ino = XFS_AGINO_TO_INO(mp, agno, agino);
error = xfs_iget(mp, NULL, ino, 0, 0, &ip, 0);
if (error)
goto fail;
/*
* Get the on disk inode to find the next inode in the bucket.
*/
ASSERT(ip != NULL);
error = xfs_itobp(mp, NULL, ip, &dip, &ibp, 0, 0, XFS_BUF_LOCK);
if (error)
goto fail;
ASSERT(dip != NULL);
ASSERT(ip->i_d.di_nlink == 0);
/* setup for the next pass */
agino = be32_to_cpu(dip->di_next_unlinked);
xfs_buf_relse(ibp);
/*
* Prevent any DMAPI event from being sent when the reference on
* the inode is dropped.
*/
ip->i_d.di_dmevmask = 0;
/*
* If this is a new inode, handle it specially. Otherwise, just
* drop our reference to the inode. If there are no other
* references, this will send the inode to xfs_inactive() which
* will truncate the file and free the inode.
*/
if (ip->i_d.di_mode == 0)
xfs_iput_new(ip, 0);
else
IRELE(ip);
return agino;
fail:
/*
* We can't read in the inode this bucket points to, or this inode
* is messed up. Just ditch this bucket of inodes. We will lose
* some inodes and space, but at least we won't hang.
*
* Call xlog_recover_clear_agi_bucket() to perform a transaction to
* clear the inode pointer in the bucket.
*/
xlog_recover_clear_agi_bucket(mp, agno, bucket);
return NULLAGINO;
}
/*
* xlog_iunlink_recover
*
@ -3167,11 +3231,7 @@ xlog_recover_process_iunlinks(
xfs_agnumber_t agno;
xfs_agi_t *agi;
xfs_buf_t *agibp;
xfs_buf_t *ibp;
xfs_dinode_t *dip;
xfs_inode_t *ip;
xfs_agino_t agino;
xfs_ino_t ino;
int bucket;
int error;
uint mp_dmevmask;
@ -3201,10 +3261,8 @@ xlog_recover_process_iunlinks(
agi = XFS_BUF_TO_AGI(agibp);
for (bucket = 0; bucket < XFS_AGI_UNLINKED_BUCKETS; bucket++) {
agino = be32_to_cpu(agi->agi_unlinked[bucket]);
while (agino != NULLAGINO) {
/*
* Release the agi buffer so that it can
* be acquired in the normal course of the
@ -3212,68 +3270,8 @@ xlog_recover_process_iunlinks(
*/
xfs_buf_relse(agibp);
ino = XFS_AGINO_TO_INO(mp, agno, agino);
error = xfs_iget(mp, NULL, ino, 0, 0, &ip, 0);
ASSERT(error || (ip != NULL));
if (!error) {
/*
* Get the on disk inode to find the
* next inode in the bucket.
*/
error = xfs_itobp(mp, NULL, ip, &dip,
&ibp, 0, 0,
XFS_BUF_LOCK);
ASSERT(error || (dip != NULL));
}
if (!error) {
ASSERT(ip->i_d.di_nlink == 0);
/* setup for the next pass */
agino = be32_to_cpu(
dip->di_next_unlinked);
xfs_buf_relse(ibp);
/*
* Prevent any DMAPI event from
* being sent when the
* reference on the inode is
* dropped.
*/
ip->i_d.di_dmevmask = 0;
/*
* If this is a new inode, handle
* it specially. Otherwise,
* just drop our reference to the
* inode. If there are no
* other references, this will
* send the inode to
* xfs_inactive() which will
* truncate the file and free
* the inode.
*/
if (ip->i_d.di_mode == 0)
xfs_iput_new(ip, 0);
else
IRELE(ip);
} else {
/*
* We can't read in the inode
* this bucket points to, or
* this inode is messed up. Just
* ditch this bucket of inodes. We
* will lose some inodes and space,
* but at least we won't hang. Call
* xlog_recover_clear_agi_bucket()
* to perform a transaction to clear
* the inode pointer in the bucket.
*/
xlog_recover_clear_agi_bucket(mp, agno,
bucket);
agino = NULLAGINO;
}
agino = xlog_recover_process_one_iunlink(mp,
agno, agino, bucket);
/*
* Reacquire the agibuffer and continue around