diff options
author | Christoph Hellwig <hch@lst.de> | 2008-11-27 22:23:37 -0500 |
---|---|---|
committer | Niv Sardi <xaiki@sgi.com> | 2008-11-30 19:37:15 -0500 |
commit | 5e1be0fb1a3950597aeda448698e85b0595a2e92 (patch) | |
tree | e9cb423d6f253b689a9e0cfb4a1d429de37959cd /fs/xfs/xfs_inode.c | |
parent | 26c5295135d10fc90cbf160adfda392d91f58279 (diff) |
[XFS] factor out xfs_read_agi helper
Add a helper to read the AGI header and perform basic verification.
Based on hunks from a larger patch from Dave Chinner.
(First sent on Juli 23rd)
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Niv Sardi <xaiki@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r-- | fs/xfs/xfs_inode.c | 57 |
1 files changed, 6 insertions, 51 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index b97710047062..46b0526acd4e 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -1843,13 +1843,10 @@ xfs_iunlink( | |||
1843 | xfs_dinode_t *dip; | 1843 | xfs_dinode_t *dip; |
1844 | xfs_buf_t *agibp; | 1844 | xfs_buf_t *agibp; |
1845 | xfs_buf_t *ibp; | 1845 | xfs_buf_t *ibp; |
1846 | xfs_agnumber_t agno; | ||
1847 | xfs_daddr_t agdaddr; | ||
1848 | xfs_agino_t agino; | 1846 | xfs_agino_t agino; |
1849 | short bucket_index; | 1847 | short bucket_index; |
1850 | int offset; | 1848 | int offset; |
1851 | int error; | 1849 | int error; |
1852 | int agi_ok; | ||
1853 | 1850 | ||
1854 | ASSERT(ip->i_d.di_nlink == 0); | 1851 | ASSERT(ip->i_d.di_nlink == 0); |
1855 | ASSERT(ip->i_d.di_mode != 0); | 1852 | ASSERT(ip->i_d.di_mode != 0); |
@@ -1857,31 +1854,15 @@ xfs_iunlink( | |||
1857 | 1854 | ||
1858 | mp = tp->t_mountp; | 1855 | mp = tp->t_mountp; |
1859 | 1856 | ||
1860 | agno = XFS_INO_TO_AGNO(mp, ip->i_ino); | ||
1861 | agdaddr = XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)); | ||
1862 | |||
1863 | /* | 1857 | /* |
1864 | * Get the agi buffer first. It ensures lock ordering | 1858 | * Get the agi buffer first. It ensures lock ordering |
1865 | * on the list. | 1859 | * on the list. |
1866 | */ | 1860 | */ |
1867 | error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, agdaddr, | 1861 | error = xfs_read_agi(mp, tp, XFS_INO_TO_AGNO(mp, ip->i_ino), &agibp); |
1868 | XFS_FSS_TO_BB(mp, 1), 0, &agibp); | ||
1869 | if (error) | 1862 | if (error) |
1870 | return error; | 1863 | return error; |
1871 | |||
1872 | /* | ||
1873 | * Validate the magic number of the agi block. | ||
1874 | */ | ||
1875 | agi = XFS_BUF_TO_AGI(agibp); | 1864 | agi = XFS_BUF_TO_AGI(agibp); |
1876 | agi_ok = | 1865 | |
1877 | be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC && | ||
1878 | XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum)); | ||
1879 | if (unlikely(XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IUNLINK, | ||
1880 | XFS_RANDOM_IUNLINK))) { | ||
1881 | XFS_CORRUPTION_ERROR("xfs_iunlink", XFS_ERRLEVEL_LOW, mp, agi); | ||
1882 | xfs_trans_brelse(tp, agibp); | ||
1883 | return XFS_ERROR(EFSCORRUPTED); | ||
1884 | } | ||
1885 | /* | 1866 | /* |
1886 | * Get the index into the agi hash table for the | 1867 | * Get the index into the agi hash table for the |
1887 | * list this inode will go on. | 1868 | * list this inode will go on. |
@@ -1941,7 +1922,6 @@ xfs_iunlink_remove( | |||
1941 | xfs_buf_t *agibp; | 1922 | xfs_buf_t *agibp; |
1942 | xfs_buf_t *ibp; | 1923 | xfs_buf_t *ibp; |
1943 | xfs_agnumber_t agno; | 1924 | xfs_agnumber_t agno; |
1944 | xfs_daddr_t agdaddr; | ||
1945 | xfs_agino_t agino; | 1925 | xfs_agino_t agino; |
1946 | xfs_agino_t next_agino; | 1926 | xfs_agino_t next_agino; |
1947 | xfs_buf_t *last_ibp; | 1927 | xfs_buf_t *last_ibp; |
@@ -1949,45 +1929,20 @@ xfs_iunlink_remove( | |||
1949 | short bucket_index; | 1929 | short bucket_index; |
1950 | int offset, last_offset = 0; | 1930 | int offset, last_offset = 0; |
1951 | int error; | 1931 | int error; |
1952 | int agi_ok; | ||
1953 | 1932 | ||
1954 | /* | ||
1955 | * First pull the on-disk inode from the AGI unlinked list. | ||
1956 | */ | ||
1957 | mp = tp->t_mountp; | 1933 | mp = tp->t_mountp; |
1958 | |||
1959 | agno = XFS_INO_TO_AGNO(mp, ip->i_ino); | 1934 | agno = XFS_INO_TO_AGNO(mp, ip->i_ino); |
1960 | agdaddr = XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)); | ||
1961 | 1935 | ||
1962 | /* | 1936 | /* |
1963 | * Get the agi buffer first. It ensures lock ordering | 1937 | * Get the agi buffer first. It ensures lock ordering |
1964 | * on the list. | 1938 | * on the list. |
1965 | */ | 1939 | */ |
1966 | error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, agdaddr, | 1940 | error = xfs_read_agi(mp, tp, agno, &agibp); |
1967 | XFS_FSS_TO_BB(mp, 1), 0, &agibp); | 1941 | if (error) |
1968 | if (error) { | ||
1969 | cmn_err(CE_WARN, | ||
1970 | "xfs_iunlink_remove: xfs_trans_read_buf() returned an error %d on %s. Returning error.", | ||
1971 | error, mp->m_fsname); | ||
1972 | return error; | 1942 | return error; |
1973 | } | 1943 | |
1974 | /* | ||
1975 | * Validate the magic number of the agi block. | ||
1976 | */ | ||
1977 | agi = XFS_BUF_TO_AGI(agibp); | 1944 | agi = XFS_BUF_TO_AGI(agibp); |
1978 | agi_ok = | 1945 | |
1979 | be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC && | ||
1980 | XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum)); | ||
1981 | if (unlikely(XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IUNLINK_REMOVE, | ||
1982 | XFS_RANDOM_IUNLINK_REMOVE))) { | ||
1983 | XFS_CORRUPTION_ERROR("xfs_iunlink_remove", XFS_ERRLEVEL_LOW, | ||
1984 | mp, agi); | ||
1985 | xfs_trans_brelse(tp, agibp); | ||
1986 | cmn_err(CE_WARN, | ||
1987 | "xfs_iunlink_remove: XFS_TEST_ERROR() returned an error on %s. Returning EFSCORRUPTED.", | ||
1988 | mp->m_fsname); | ||
1989 | return XFS_ERROR(EFSCORRUPTED); | ||
1990 | } | ||
1991 | /* | 1946 | /* |
1992 | * Get the index into the agi hash table for the | 1947 | * Get the index into the agi hash table for the |
1993 | * list this inode will go on. | 1948 | * list this inode will go on. |