diff options
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/xfs_buf_item.c | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_da_btree.c | 5 | ||||
-rw-r--r-- | fs/xfs/xfs_fs.h | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_icache.c | 9 | ||||
-rw-r--r-- | fs/xfs/xfs_log_recover.c | 73 |
5 files changed, 68 insertions, 22 deletions
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index 88c5ea75ebf6..f1d85cfc0a54 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c | |||
@@ -628,6 +628,7 @@ xfs_buf_item_unlock( | |||
628 | else if (aborted) { | 628 | else if (aborted) { |
629 | ASSERT(XFS_FORCED_SHUTDOWN(lip->li_mountp)); | 629 | ASSERT(XFS_FORCED_SHUTDOWN(lip->li_mountp)); |
630 | if (lip->li_flags & XFS_LI_IN_AIL) { | 630 | if (lip->li_flags & XFS_LI_IN_AIL) { |
631 | spin_lock(&lip->li_ailp->xa_lock); | ||
631 | xfs_trans_ail_delete(lip->li_ailp, lip, | 632 | xfs_trans_ail_delete(lip->li_ailp, lip, |
632 | SHUTDOWN_LOG_IO_ERROR); | 633 | SHUTDOWN_LOG_IO_ERROR); |
633 | } | 634 | } |
diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c index 069537c845e5..20bf8e8002d6 100644 --- a/fs/xfs/xfs_da_btree.c +++ b/fs/xfs/xfs_da_btree.c | |||
@@ -1224,6 +1224,7 @@ xfs_da3_node_toosmall( | |||
1224 | /* start with smaller blk num */ | 1224 | /* start with smaller blk num */ |
1225 | forward = nodehdr.forw < nodehdr.back; | 1225 | forward = nodehdr.forw < nodehdr.back; |
1226 | for (i = 0; i < 2; forward = !forward, i++) { | 1226 | for (i = 0; i < 2; forward = !forward, i++) { |
1227 | struct xfs_da3_icnode_hdr thdr; | ||
1227 | if (forward) | 1228 | if (forward) |
1228 | blkno = nodehdr.forw; | 1229 | blkno = nodehdr.forw; |
1229 | else | 1230 | else |
@@ -1236,10 +1237,10 @@ xfs_da3_node_toosmall( | |||
1236 | return(error); | 1237 | return(error); |
1237 | 1238 | ||
1238 | node = bp->b_addr; | 1239 | node = bp->b_addr; |
1239 | xfs_da3_node_hdr_from_disk(&nodehdr, node); | 1240 | xfs_da3_node_hdr_from_disk(&thdr, node); |
1240 | xfs_trans_brelse(state->args->trans, bp); | 1241 | xfs_trans_brelse(state->args->trans, bp); |
1241 | 1242 | ||
1242 | if (count - nodehdr.count >= 0) | 1243 | if (count - thdr.count >= 0) |
1243 | break; /* fits with at least 25% to spare */ | 1244 | break; /* fits with at least 25% to spare */ |
1244 | } | 1245 | } |
1245 | if (i >= 2) { | 1246 | if (i >= 2) { |
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h index 1edb5cc3e5f4..18272c766a50 100644 --- a/fs/xfs/xfs_fs.h +++ b/fs/xfs/xfs_fs.h | |||
@@ -515,7 +515,7 @@ typedef struct xfs_swapext | |||
515 | /* XFS_IOC_GETBIOSIZE ---- deprecated 47 */ | 515 | /* XFS_IOC_GETBIOSIZE ---- deprecated 47 */ |
516 | #define XFS_IOC_GETBMAPX _IOWR('X', 56, struct getbmap) | 516 | #define XFS_IOC_GETBMAPX _IOWR('X', 56, struct getbmap) |
517 | #define XFS_IOC_ZERO_RANGE _IOW ('X', 57, struct xfs_flock64) | 517 | #define XFS_IOC_ZERO_RANGE _IOW ('X', 57, struct xfs_flock64) |
518 | #define XFS_IOC_FREE_EOFBLOCKS _IOR ('X', 58, struct xfs_eofblocks) | 518 | #define XFS_IOC_FREE_EOFBLOCKS _IOR ('X', 58, struct xfs_fs_eofblocks) |
519 | 519 | ||
520 | /* | 520 | /* |
521 | * ioctl commands that replace IRIX syssgi()'s | 521 | * ioctl commands that replace IRIX syssgi()'s |
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 193206ba4358..474807a401c8 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c | |||
@@ -119,11 +119,6 @@ xfs_inode_free( | |||
119 | ip->i_itemp = NULL; | 119 | ip->i_itemp = NULL; |
120 | } | 120 | } |
121 | 121 | ||
122 | /* asserts to verify all state is correct here */ | ||
123 | ASSERT(atomic_read(&ip->i_pincount) == 0); | ||
124 | ASSERT(!spin_is_locked(&ip->i_flags_lock)); | ||
125 | ASSERT(!xfs_isiflocked(ip)); | ||
126 | |||
127 | /* | 122 | /* |
128 | * Because we use RCU freeing we need to ensure the inode always | 123 | * Because we use RCU freeing we need to ensure the inode always |
129 | * appears to be reclaimed with an invalid inode number when in the | 124 | * appears to be reclaimed with an invalid inode number when in the |
@@ -135,6 +130,10 @@ xfs_inode_free( | |||
135 | ip->i_ino = 0; | 130 | ip->i_ino = 0; |
136 | spin_unlock(&ip->i_flags_lock); | 131 | spin_unlock(&ip->i_flags_lock); |
137 | 132 | ||
133 | /* asserts to verify all state is correct here */ | ||
134 | ASSERT(atomic_read(&ip->i_pincount) == 0); | ||
135 | ASSERT(!xfs_isiflocked(ip)); | ||
136 | |||
138 | call_rcu(&VFS_I(ip)->i_rcu, xfs_inode_free_callback); | 137 | call_rcu(&VFS_I(ip)->i_rcu, xfs_inode_free_callback); |
139 | } | 138 | } |
140 | 139 | ||
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 |