diff options
Diffstat (limited to 'fs/xfs/xfs_log_recover.c')
-rw-r--r-- | fs/xfs/xfs_log_recover.c | 73 |
1 files changed, 59 insertions, 14 deletions
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index dabda9521b4b..cc179878fe41 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
@@ -1970,6 +1970,13 @@ xlog_recover_do_inode_buffer( | |||
1970 | * magic number. If we don't recognise the magic number in the buffer, then | 1970 | * magic number. If we don't recognise the magic number in the buffer, then |
1971 | * return a LSN of -1 so that the caller knows it was an unrecognised block and | 1971 | * return a LSN of -1 so that the caller knows it was an unrecognised block and |
1972 | * so can recover the buffer. | 1972 | * so can recover the buffer. |
1973 | * | ||
1974 | * Note: we cannot rely solely on magic number matches to determine that the | ||
1975 | * buffer has a valid LSN - we also need to verify that it belongs to this | ||
1976 | * filesystem, so we need to extract the object's LSN and compare it to that | ||
1977 | * which we read from the superblock. If the UUIDs don't match, then we've got a | ||
1978 | * stale metadata block from an old filesystem instance that we need to recover | ||
1979 | * over the top of. | ||
1973 | */ | 1980 | */ |
1974 | static xfs_lsn_t | 1981 | static xfs_lsn_t |
1975 | xlog_recover_get_buf_lsn( | 1982 | xlog_recover_get_buf_lsn( |
@@ -1980,6 +1987,8 @@ xlog_recover_get_buf_lsn( | |||
1980 | __uint16_t magic16; | 1987 | __uint16_t magic16; |
1981 | __uint16_t magicda; | 1988 | __uint16_t magicda; |
1982 | void *blk = bp->b_addr; | 1989 | void *blk = bp->b_addr; |
1990 | uuid_t *uuid; | ||
1991 | xfs_lsn_t lsn = -1; | ||
1983 | 1992 | ||
1984 | /* v4 filesystems always recover immediately */ | 1993 | /* v4 filesystems always recover immediately */ |
1985 | if (!xfs_sb_version_hascrc(&mp->m_sb)) | 1994 | if (!xfs_sb_version_hascrc(&mp->m_sb)) |
@@ -1992,43 +2001,79 @@ xlog_recover_get_buf_lsn( | |||
1992 | case XFS_ABTB_MAGIC: | 2001 | case XFS_ABTB_MAGIC: |
1993 | case XFS_ABTC_MAGIC: | 2002 | case XFS_ABTC_MAGIC: |
1994 | case XFS_IBT_CRC_MAGIC: | 2003 | case XFS_IBT_CRC_MAGIC: |
1995 | case XFS_IBT_MAGIC: | 2004 | case XFS_IBT_MAGIC: { |
1996 | return be64_to_cpu( | 2005 | struct xfs_btree_block *btb = blk; |
1997 | ((struct xfs_btree_block *)blk)->bb_u.s.bb_lsn); | 2006 | |
2007 | lsn = be64_to_cpu(btb->bb_u.s.bb_lsn); | ||
2008 | uuid = &btb->bb_u.s.bb_uuid; | ||
2009 | break; | ||
2010 | } | ||
1998 | case XFS_BMAP_CRC_MAGIC: | 2011 | case XFS_BMAP_CRC_MAGIC: |
1999 | case XFS_BMAP_MAGIC: | 2012 | case XFS_BMAP_MAGIC: { |
2000 | return be64_to_cpu( | 2013 | struct xfs_btree_block *btb = blk; |
2001 | ((struct xfs_btree_block *)blk)->bb_u.l.bb_lsn); | 2014 | |
2015 | lsn = be64_to_cpu(btb->bb_u.l.bb_lsn); | ||
2016 | uuid = &btb->bb_u.l.bb_uuid; | ||
2017 | break; | ||
2018 | } | ||
2002 | case XFS_AGF_MAGIC: | 2019 | case XFS_AGF_MAGIC: |
2003 | return be64_to_cpu(((struct xfs_agf *)blk)->agf_lsn); | 2020 | lsn = be64_to_cpu(((struct xfs_agf *)blk)->agf_lsn); |
2021 | uuid = &((struct xfs_agf *)blk)->agf_uuid; | ||
2022 | break; | ||
2004 | case XFS_AGFL_MAGIC: | 2023 | case XFS_AGFL_MAGIC: |
2005 | return be64_to_cpu(((struct xfs_agfl *)blk)->agfl_lsn); | 2024 | lsn = be64_to_cpu(((struct xfs_agfl *)blk)->agfl_lsn); |
2025 | uuid = &((struct xfs_agfl *)blk)->agfl_uuid; | ||
2026 | break; | ||
2006 | case XFS_AGI_MAGIC: | 2027 | case XFS_AGI_MAGIC: |
2007 | return be64_to_cpu(((struct xfs_agi *)blk)->agi_lsn); | 2028 | lsn = be64_to_cpu(((struct xfs_agi *)blk)->agi_lsn); |
2029 | uuid = &((struct xfs_agi *)blk)->agi_uuid; | ||
2030 | break; | ||
2008 | case XFS_SYMLINK_MAGIC: | 2031 | case XFS_SYMLINK_MAGIC: |
2009 | return be64_to_cpu(((struct xfs_dsymlink_hdr *)blk)->sl_lsn); | 2032 | lsn = be64_to_cpu(((struct xfs_dsymlink_hdr *)blk)->sl_lsn); |
2033 | uuid = &((struct xfs_dsymlink_hdr *)blk)->sl_uuid; | ||
2034 | break; | ||
2010 | case XFS_DIR3_BLOCK_MAGIC: | 2035 | case XFS_DIR3_BLOCK_MAGIC: |
2011 | case XFS_DIR3_DATA_MAGIC: | 2036 | case XFS_DIR3_DATA_MAGIC: |
2012 | case XFS_DIR3_FREE_MAGIC: | 2037 | case XFS_DIR3_FREE_MAGIC: |
2013 | return be64_to_cpu(((struct xfs_dir3_blk_hdr *)blk)->lsn); | 2038 | lsn = be64_to_cpu(((struct xfs_dir3_blk_hdr *)blk)->lsn); |
2039 | uuid = &((struct xfs_dir3_blk_hdr *)blk)->uuid; | ||
2040 | break; | ||
2014 | case XFS_ATTR3_RMT_MAGIC: | 2041 | case XFS_ATTR3_RMT_MAGIC: |
2015 | return be64_to_cpu(((struct xfs_attr3_rmt_hdr *)blk)->rm_lsn); | 2042 | lsn = be64_to_cpu(((struct xfs_attr3_rmt_hdr *)blk)->rm_lsn); |
2043 | uuid = &((struct xfs_attr3_rmt_hdr *)blk)->rm_uuid; | ||
2044 | break; | ||
2016 | case XFS_SB_MAGIC: | 2045 | case XFS_SB_MAGIC: |
2017 | return be64_to_cpu(((struct xfs_dsb *)blk)->sb_lsn); | 2046 | lsn = be64_to_cpu(((struct xfs_dsb *)blk)->sb_lsn); |
2047 | uuid = &((struct xfs_dsb *)blk)->sb_uuid; | ||
2048 | break; | ||
2018 | default: | 2049 | default: |
2019 | break; | 2050 | break; |
2020 | } | 2051 | } |
2021 | 2052 | ||
2053 | if (lsn != (xfs_lsn_t)-1) { | ||
2054 | if (!uuid_equal(&mp->m_sb.sb_uuid, uuid)) | ||
2055 | goto recover_immediately; | ||
2056 | return lsn; | ||
2057 | } | ||
2058 | |||
2022 | magicda = be16_to_cpu(((struct xfs_da_blkinfo *)blk)->magic); | 2059 | magicda = be16_to_cpu(((struct xfs_da_blkinfo *)blk)->magic); |
2023 | switch (magicda) { | 2060 | switch (magicda) { |
2024 | case XFS_DIR3_LEAF1_MAGIC: | 2061 | case XFS_DIR3_LEAF1_MAGIC: |
2025 | case XFS_DIR3_LEAFN_MAGIC: | 2062 | case XFS_DIR3_LEAFN_MAGIC: |
2026 | case XFS_DA3_NODE_MAGIC: | 2063 | case XFS_DA3_NODE_MAGIC: |
2027 | return be64_to_cpu(((struct xfs_da3_blkinfo *)blk)->lsn); | 2064 | lsn = be64_to_cpu(((struct xfs_da3_blkinfo *)blk)->lsn); |
2065 | uuid = &((struct xfs_da3_blkinfo *)blk)->uuid; | ||
2066 | break; | ||
2028 | default: | 2067 | default: |
2029 | break; | 2068 | break; |
2030 | } | 2069 | } |
2031 | 2070 | ||
2071 | if (lsn != (xfs_lsn_t)-1) { | ||
2072 | if (!uuid_equal(&mp->m_sb.sb_uuid, uuid)) | ||
2073 | goto recover_immediately; | ||
2074 | return lsn; | ||
2075 | } | ||
2076 | |||
2032 | /* | 2077 | /* |
2033 | * We do individual object checks on dquot and inode buffers as they | 2078 | * We do individual object checks on dquot and inode buffers as they |
2034 | * have their own individual LSN records. Also, we could have a stale | 2079 | * have their own individual LSN records. Also, we could have a stale |