Loading fs/xfs/xfs_log_recover.c +66 −68 Original line number Diff line number Diff line Loading @@ -3147,6 +3147,70 @@ xlog_recover_clear_agi_bucket( 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 * Loading @@ -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; Loading Loading @@ -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 Loading @@ -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 Loading Loading
fs/xfs/xfs_log_recover.c +66 −68 Original line number Diff line number Diff line Loading @@ -3147,6 +3147,70 @@ xlog_recover_clear_agi_bucket( 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 * Loading @@ -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; Loading Loading @@ -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 Loading @@ -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 Loading