Commit ddd23eb1829988cc1ebc58a2f622c56c508e219e

Authored by Linus Torvalds

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
... ... @@ -628,6 +628,7 @@
628 628 else if (aborted) {
629 629 ASSERT(XFS_FORCED_SHUTDOWN(lip->li_mountp));
630 630 if (lip->li_flags & XFS_LI_IN_AIL) {
  631 + spin_lock(&lip->li_ailp->xa_lock);
631 632 xfs_trans_ail_delete(lip->li_ailp, lip,
632 633 SHUTDOWN_LOG_IO_ERROR);
633 634 }
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) {
... ... @@ -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
... ... @@ -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 /*