There is no need to keep old multiple short unlink inode buckets since we have an in-memory double linked list for all unlinked inodes. Apart from the perspective of the necessity, the main advantage is the log and AGI update can be reduced since each AG has the only one head now, which is implemented in the following patches. Therefore, this patch applies the new way in xfs_iunlink() and keep the old approach in xfs_iunlink_remove_inode() path as well so inode eviction can still work properly in recovery. Signed-off-by: Gao Xiang <hsiangkao@xxxxxxxxxx> --- fs/xfs/xfs_inode.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index ab288424764c..4994398373df 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -33,6 +33,7 @@ #include "xfs_symlink.h" #include "xfs_trans_priv.h" #include "xfs_log.h" +#include "xfs_log_priv.h" #include "xfs_bmap_btree.h" #include "xfs_reflink.h" #include "xfs_iunlink_item.h" @@ -2001,14 +2002,13 @@ xfs_iunlink_insert_inode( xfs_agino_t agno = XFS_INO_TO_AGNO(mp, ip->i_ino); xfs_agino_t agino = XFS_INO_TO_AGINO(mp, ip->i_ino); xfs_agino_t next_agino; - short bucket_index = agino % XFS_AGI_UNLINKED_BUCKETS; /* * Get the index into the agi hash table for the list this inode will * go on. Make sure the pointer isn't garbage and that this inode * isn't already on the list. */ - next_agino = be32_to_cpu(agi->agi_unlinked[bucket_index]); + next_agino = be32_to_cpu(agi->agi_unlinked[0]); if (next_agino == agino || !xfs_verify_agino_or_null(mp, agno, next_agino)) { xfs_buf_mark_corrupt(agibp); @@ -2036,7 +2036,7 @@ xfs_iunlink_insert_inode( } /* Point the head of the list to point to this inode. */ - return xfs_iunlink_update_bucket(tp, agno, agibp, bucket_index, agino); + return xfs_iunlink_update_bucket(tp, agno, agibp, 0, agino); } /* @@ -2055,10 +2055,17 @@ xfs_iunlink_remove_inode( xfs_agino_t agno = XFS_INO_TO_AGNO(mp, ip->i_ino); xfs_agino_t agino = XFS_INO_TO_AGINO(mp, ip->i_ino); xfs_agino_t next_agino = ip->i_next_unlinked; - short bucket_index = agino % XFS_AGI_UNLINKED_BUCKETS; int error; if (ip->i_prev_unlinked == NULLAGINO) { + struct xlog *log = mp->m_log; + short bucket_index = 0; + + /* During recovery, the old multiple bucket can be applied */ + if ((!log || log->l_flags & XLOG_RECOVERY_NEEDED) && + be32_to_cpu(agi->agi_unlinked[0]) != agino) + bucket_index = agino % XFS_AGI_UNLINKED_BUCKETS; + /* remove from head of list */ if (be32_to_cpu(agi->agi_unlinked[bucket_index]) != agino) { xfs_buf_mark_corrupt(agibp); -- 2.18.1