Commit ddd23eb1829988cc1ebc58a2f622c56c508e219e
Exists in
master
and in
20 other branches
Merge tag 'xfs-for-linus-v3.12-rc3' of git://oss.sgi.com/xfs/xfs
Pull xfs bugfixes from Ben Myers: - fix for directory node collapse regression - fix for recovery over stale on disk structures - fix for eofblocks ioctl - fix asserts in xfs_inode_free - lock the ail before removing an item from it * tag 'xfs-for-linus-v3.12-rc3' of git://oss.sgi.com/xfs/xfs: xfs: fix node forward in xfs_node_toosmall xfs: log recovery lsn ordering needs uuid check xfs: fix XFS_IOC_FREE_EOFBLOCKS definition xfs: asserting lock not held during freeing not valid xfs: lock the AIL before removing the buffer item
Showing 5 changed files Side-by-side Diff
fs/xfs/xfs_buf_item.c
fs/xfs/xfs_da_btree.c
... | ... | @@ -1224,6 +1224,7 @@ |
1224 | 1224 | /* start with smaller blk num */ |
1225 | 1225 | forward = nodehdr.forw < nodehdr.back; |
1226 | 1226 | for (i = 0; i < 2; forward = !forward, i++) { |
1227 | + struct xfs_da3_icnode_hdr thdr; | |
1227 | 1228 | if (forward) |
1228 | 1229 | blkno = nodehdr.forw; |
1229 | 1230 | else |
1230 | 1231 | |
... | ... | @@ -1236,10 +1237,10 @@ |
1236 | 1237 | return(error); |
1237 | 1238 | |
1238 | 1239 | node = bp->b_addr; |
1239 | - xfs_da3_node_hdr_from_disk(&nodehdr, node); | |
1240 | + xfs_da3_node_hdr_from_disk(&thdr, node); | |
1240 | 1241 | xfs_trans_brelse(state->args->trans, bp); |
1241 | 1242 | |
1242 | - if (count - nodehdr.count >= 0) | |
1243 | + if (count - thdr.count >= 0) | |
1243 | 1244 | break; /* fits with at least 25% to spare */ |
1244 | 1245 | } |
1245 | 1246 | if (i >= 2) { |
fs/xfs/xfs_fs.h
... | ... | @@ -515,7 +515,7 @@ |
515 | 515 | /* XFS_IOC_GETBIOSIZE ---- deprecated 47 */ |
516 | 516 | #define XFS_IOC_GETBMAPX _IOWR('X', 56, struct getbmap) |
517 | 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 | 521 | * ioctl commands that replace IRIX syssgi()'s |
fs/xfs/xfs_icache.c
... | ... | @@ -119,11 +119,6 @@ |
119 | 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 | 123 | * Because we use RCU freeing we need to ensure the inode always |
129 | 124 | * appears to be reclaimed with an invalid inode number when in the |
... | ... | @@ -134,6 +129,10 @@ |
134 | 129 | ip->i_flags = XFS_IRECLAIM; |
135 | 130 | ip->i_ino = 0; |
136 | 131 | spin_unlock(&ip->i_flags_lock); |
132 | + | |
133 | + /* asserts to verify all state is correct here */ | |
134 | + ASSERT(atomic_read(&ip->i_pincount) == 0); | |
135 | + ASSERT(!xfs_isiflocked(ip)); | |
137 | 136 | |
138 | 137 | call_rcu(&VFS_I(ip)->i_rcu, xfs_inode_free_callback); |
139 | 138 | } |
fs/xfs/xfs_log_recover.c
... | ... | @@ -1970,6 +1970,13 @@ |
1970 | 1970 | * magic number. If we don't recognise the magic number in the buffer, then |
1971 | 1971 | * return a LSN of -1 so that the caller knows it was an unrecognised block and |
1972 | 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 | 1981 | static xfs_lsn_t |
1975 | 1982 | xlog_recover_get_buf_lsn( |
... | ... | @@ -1980,6 +1987,8 @@ |
1980 | 1987 | __uint16_t magic16; |
1981 | 1988 | __uint16_t magicda; |
1982 | 1989 | void *blk = bp->b_addr; |
1990 | + uuid_t *uuid; | |
1991 | + xfs_lsn_t lsn = -1; | |
1983 | 1992 | |
1984 | 1993 | /* v4 filesystems always recover immediately */ |
1985 | 1994 | if (!xfs_sb_version_hascrc(&mp->m_sb)) |
1986 | 1995 | |
1987 | 1996 | |
1988 | 1997 | |
1989 | 1998 | |
1990 | 1999 | |
1991 | 2000 | |
1992 | 2001 | |
1993 | 2002 | |
1994 | 2003 | |
1995 | 2004 | |
1996 | 2005 | |
... | ... | @@ -1992,41 +2001,77 @@ |
1992 | 2001 | case XFS_ABTB_MAGIC: |
1993 | 2002 | case XFS_ABTC_MAGIC: |
1994 | 2003 | case XFS_IBT_CRC_MAGIC: |
1995 | - case XFS_IBT_MAGIC: | |
1996 | - return be64_to_cpu( | |
1997 | - ((struct xfs_btree_block *)blk)->bb_u.s.bb_lsn); | |
2004 | + case XFS_IBT_MAGIC: { | |
2005 | + struct xfs_btree_block *btb = blk; | |
2006 | + | |
2007 | + lsn = be64_to_cpu(btb->bb_u.s.bb_lsn); | |
2008 | + uuid = &btb->bb_u.s.bb_uuid; | |
2009 | + break; | |
2010 | + } | |
1998 | 2011 | case XFS_BMAP_CRC_MAGIC: |
1999 | - case XFS_BMAP_MAGIC: | |
2000 | - return be64_to_cpu( | |
2001 | - ((struct xfs_btree_block *)blk)->bb_u.l.bb_lsn); | |
2012 | + case XFS_BMAP_MAGIC: { | |
2013 | + struct xfs_btree_block *btb = blk; | |
2014 | + | |
2015 | + lsn = be64_to_cpu(btb->bb_u.l.bb_lsn); | |
2016 | + uuid = &btb->bb_u.l.bb_uuid; | |
2017 | + break; | |
2018 | + } | |
2002 | 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 | 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 | 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 | 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 | 2035 | case XFS_DIR3_BLOCK_MAGIC: |
2011 | 2036 | case XFS_DIR3_DATA_MAGIC: |
2012 | 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 | 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 | 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 | 2049 | default: |
2019 | 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 | 2059 | magicda = be16_to_cpu(((struct xfs_da_blkinfo *)blk)->magic); |
2023 | 2060 | switch (magicda) { |
2024 | 2061 | case XFS_DIR3_LEAF1_MAGIC: |
2025 | 2062 | case XFS_DIR3_LEAFN_MAGIC: |
2026 | 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 | 2067 | default: |
2029 | 2068 | break; |
2069 | + } | |
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; | |
2030 | 2075 | } |
2031 | 2076 | |
2032 | 2077 | /* |