diff options
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r-- | fs/xfs/xfs_inode.c | 79 |
1 files changed, 32 insertions, 47 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index ae667ba74a1c..8a39d80f4863 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -1918,26 +1918,24 @@ xfs_inactive( | |||
1918 | */ | 1918 | */ |
1919 | STATIC int | 1919 | STATIC int |
1920 | xfs_iunlink( | 1920 | xfs_iunlink( |
1921 | struct xfs_trans *tp, | 1921 | struct xfs_trans *tp, |
1922 | struct xfs_inode *ip) | 1922 | struct xfs_inode *ip) |
1923 | { | 1923 | { |
1924 | xfs_mount_t *mp = tp->t_mountp; | 1924 | struct xfs_mount *mp = tp->t_mountp; |
1925 | xfs_agi_t *agi; | 1925 | struct xfs_agi *agi; |
1926 | xfs_dinode_t *dip; | 1926 | struct xfs_dinode *dip; |
1927 | xfs_buf_t *agibp; | 1927 | struct xfs_buf *agibp; |
1928 | xfs_buf_t *ibp; | 1928 | struct xfs_buf *ibp; |
1929 | xfs_agino_t agino; | 1929 | xfs_agnumber_t agno = XFS_INO_TO_AGNO(mp, ip->i_ino); |
1930 | short bucket_index; | 1930 | xfs_agino_t agino = XFS_INO_TO_AGINO(mp, ip->i_ino); |
1931 | int offset; | 1931 | short bucket_index = agino % XFS_AGI_UNLINKED_BUCKETS; |
1932 | int error; | 1932 | int offset; |
1933 | int error; | ||
1933 | 1934 | ||
1934 | ASSERT(VFS_I(ip)->i_mode != 0); | 1935 | ASSERT(VFS_I(ip)->i_mode != 0); |
1935 | 1936 | ||
1936 | /* | 1937 | /* Get the agi buffer first. It ensures lock ordering on the list. */ |
1937 | * Get the agi buffer first. It ensures lock ordering | 1938 | error = xfs_read_agi(mp, tp, agno, &agibp); |
1938 | * on the list. | ||
1939 | */ | ||
1940 | error = xfs_read_agi(mp, tp, XFS_INO_TO_AGNO(mp, ip->i_ino), &agibp); | ||
1941 | if (error) | 1939 | if (error) |
1942 | return error; | 1940 | return error; |
1943 | agi = XFS_BUF_TO_AGI(agibp); | 1941 | agi = XFS_BUF_TO_AGI(agibp); |
@@ -1946,9 +1944,6 @@ xfs_iunlink( | |||
1946 | * Get the index into the agi hash table for the | 1944 | * Get the index into the agi hash table for the |
1947 | * list this inode will go on. | 1945 | * list this inode will go on. |
1948 | */ | 1946 | */ |
1949 | agino = XFS_INO_TO_AGINO(mp, ip->i_ino); | ||
1950 | ASSERT(agino != 0); | ||
1951 | bucket_index = agino % XFS_AGI_UNLINKED_BUCKETS; | ||
1952 | ASSERT(agi->agi_unlinked[bucket_index]); | 1947 | ASSERT(agi->agi_unlinked[bucket_index]); |
1953 | ASSERT(be32_to_cpu(agi->agi_unlinked[bucket_index]) != agino); | 1948 | ASSERT(be32_to_cpu(agi->agi_unlinked[bucket_index]) != agino); |
1954 | 1949 | ||
@@ -1995,45 +1990,35 @@ xfs_iunlink( | |||
1995 | */ | 1990 | */ |
1996 | STATIC int | 1991 | STATIC int |
1997 | xfs_iunlink_remove( | 1992 | xfs_iunlink_remove( |
1998 | xfs_trans_t *tp, | 1993 | struct xfs_trans *tp, |
1999 | xfs_inode_t *ip) | 1994 | struct xfs_inode *ip) |
2000 | { | 1995 | { |
2001 | xfs_ino_t next_ino; | 1996 | struct xfs_mount *mp = tp->t_mountp; |
2002 | xfs_mount_t *mp; | 1997 | struct xfs_agi *agi; |
2003 | xfs_agi_t *agi; | 1998 | struct xfs_dinode *dip; |
2004 | xfs_dinode_t *dip; | 1999 | struct xfs_buf *agibp; |
2005 | xfs_buf_t *agibp; | 2000 | struct xfs_buf *ibp; |
2006 | xfs_buf_t *ibp; | 2001 | struct xfs_buf *last_ibp; |
2007 | xfs_agnumber_t agno; | 2002 | struct xfs_dinode *last_dip = NULL; |
2008 | xfs_agino_t agino; | 2003 | xfs_ino_t next_ino; |
2009 | xfs_agino_t next_agino; | 2004 | xfs_agnumber_t agno = XFS_INO_TO_AGNO(mp, ip->i_ino); |
2010 | xfs_buf_t *last_ibp; | 2005 | xfs_agino_t agino = XFS_INO_TO_AGINO(mp, ip->i_ino); |
2011 | xfs_dinode_t *last_dip = NULL; | 2006 | xfs_agino_t next_agino; |
2012 | short bucket_index; | 2007 | short bucket_index = agino % XFS_AGI_UNLINKED_BUCKETS; |
2013 | int offset, last_offset = 0; | 2008 | int offset; |
2014 | int error; | 2009 | int last_offset = 0; |
2015 | 2010 | int error; | |
2016 | mp = tp->t_mountp; | ||
2017 | agno = XFS_INO_TO_AGNO(mp, ip->i_ino); | ||
2018 | 2011 | ||
2019 | /* | 2012 | /* Get the agi buffer first. It ensures lock ordering on the list. */ |
2020 | * Get the agi buffer first. It ensures lock ordering | ||
2021 | * on the list. | ||
2022 | */ | ||
2023 | error = xfs_read_agi(mp, tp, agno, &agibp); | 2013 | error = xfs_read_agi(mp, tp, agno, &agibp); |
2024 | if (error) | 2014 | if (error) |
2025 | return error; | 2015 | return error; |
2026 | |||
2027 | agi = XFS_BUF_TO_AGI(agibp); | 2016 | agi = XFS_BUF_TO_AGI(agibp); |
2028 | 2017 | ||
2029 | /* | 2018 | /* |
2030 | * Get the index into the agi hash table for the | 2019 | * Get the index into the agi hash table for the |
2031 | * list this inode will go on. | 2020 | * list this inode will go on. |
2032 | */ | 2021 | */ |
2033 | agino = XFS_INO_TO_AGINO(mp, ip->i_ino); | ||
2034 | if (!xfs_verify_agino(mp, agno, agino)) | ||
2035 | return -EFSCORRUPTED; | ||
2036 | bucket_index = agino % XFS_AGI_UNLINKED_BUCKETS; | ||
2037 | if (!xfs_verify_agino(mp, agno, | 2022 | if (!xfs_verify_agino(mp, agno, |
2038 | be32_to_cpu(agi->agi_unlinked[bucket_index]))) { | 2023 | be32_to_cpu(agi->agi_unlinked[bucket_index]))) { |
2039 | XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, | 2024 | XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, |