Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ddd23eb1 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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
parents 057d5e98 997def25
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -628,6 +628,7 @@ xfs_buf_item_unlock(
		else if (aborted) {
			ASSERT(XFS_FORCED_SHUTDOWN(lip->li_mountp));
			if (lip->li_flags & XFS_LI_IN_AIL) {
				spin_lock(&lip->li_ailp->xa_lock);
				xfs_trans_ail_delete(lip->li_ailp, lip,
						     SHUTDOWN_LOG_IO_ERROR);
			}
+3 −2
Original line number Diff line number Diff line
@@ -1224,6 +1224,7 @@ xfs_da3_node_toosmall(
	/* start with smaller blk num */
	forward = nodehdr.forw < nodehdr.back;
	for (i = 0; i < 2; forward = !forward, i++) {
		struct xfs_da3_icnode_hdr thdr;
		if (forward)
			blkno = nodehdr.forw;
		else
@@ -1236,10 +1237,10 @@ xfs_da3_node_toosmall(
			return(error);

		node = bp->b_addr;
		xfs_da3_node_hdr_from_disk(&nodehdr, node);
		xfs_da3_node_hdr_from_disk(&thdr, node);
		xfs_trans_brelse(state->args->trans, bp);

		if (count - nodehdr.count >= 0)
		if (count - thdr.count >= 0)
			break;	/* fits with at least 25% to spare */
	}
	if (i >= 2) {
+1 −1
Original line number Diff line number Diff line
@@ -515,7 +515,7 @@ typedef struct xfs_swapext
/*	XFS_IOC_GETBIOSIZE ---- deprecated 47	   */
#define XFS_IOC_GETBMAPX	_IOWR('X', 56, struct getbmap)
#define XFS_IOC_ZERO_RANGE	_IOW ('X', 57, struct xfs_flock64)
#define XFS_IOC_FREE_EOFBLOCKS	_IOR ('X', 58, struct xfs_eofblocks)
#define XFS_IOC_FREE_EOFBLOCKS	_IOR ('X', 58, struct xfs_fs_eofblocks)

/*
 * ioctl commands that replace IRIX syssgi()'s
+4 −5
Original line number Diff line number Diff line
@@ -119,11 +119,6 @@ xfs_inode_free(
		ip->i_itemp = NULL;
	}

	/* asserts to verify all state is correct here */
	ASSERT(atomic_read(&ip->i_pincount) == 0);
	ASSERT(!spin_is_locked(&ip->i_flags_lock));
	ASSERT(!xfs_isiflocked(ip));

	/*
	 * Because we use RCU freeing we need to ensure the inode always
	 * appears to be reclaimed with an invalid inode number when in the
@@ -135,6 +130,10 @@ xfs_inode_free(
	ip->i_ino = 0;
	spin_unlock(&ip->i_flags_lock);

	/* asserts to verify all state is correct here */
	ASSERT(atomic_read(&ip->i_pincount) == 0);
	ASSERT(!xfs_isiflocked(ip));

	call_rcu(&VFS_I(ip)->i_rcu, xfs_inode_free_callback);
}

+59 −14
Original line number Diff line number Diff line
@@ -1970,6 +1970,13 @@ xlog_recover_do_inode_buffer(
 * magic number.  If we don't recognise the magic number in the buffer, then
 * return a LSN of -1 so that the caller knows it was an unrecognised block and
 * so can recover the buffer.
 *
 * Note: we cannot rely solely on magic number matches to determine that the
 * buffer has a valid LSN - we also need to verify that it belongs to this
 * filesystem, so we need to extract the object's LSN and compare it to that
 * which we read from the superblock. If the UUIDs don't match, then we've got a
 * stale metadata block from an old filesystem instance that we need to recover
 * over the top of.
 */
static xfs_lsn_t
xlog_recover_get_buf_lsn(
@@ -1980,6 +1987,8 @@ xlog_recover_get_buf_lsn(
	__uint16_t		magic16;
	__uint16_t		magicda;
	void			*blk = bp->b_addr;
	uuid_t			*uuid;
	xfs_lsn_t		lsn = -1;

	/* v4 filesystems always recover immediately */
	if (!xfs_sb_version_hascrc(&mp->m_sb))
@@ -1992,43 +2001,79 @@ xlog_recover_get_buf_lsn(
	case XFS_ABTB_MAGIC:
	case XFS_ABTC_MAGIC:
	case XFS_IBT_CRC_MAGIC:
	case XFS_IBT_MAGIC:
		return be64_to_cpu(
				((struct xfs_btree_block *)blk)->bb_u.s.bb_lsn);
	case XFS_IBT_MAGIC: {
		struct xfs_btree_block *btb = blk;

		lsn = be64_to_cpu(btb->bb_u.s.bb_lsn);
		uuid = &btb->bb_u.s.bb_uuid;
		break;
	}
	case XFS_BMAP_CRC_MAGIC:
	case XFS_BMAP_MAGIC:
		return be64_to_cpu(
				((struct xfs_btree_block *)blk)->bb_u.l.bb_lsn);
	case XFS_BMAP_MAGIC: {
		struct xfs_btree_block *btb = blk;

		lsn = be64_to_cpu(btb->bb_u.l.bb_lsn);
		uuid = &btb->bb_u.l.bb_uuid;
		break;
	}
	case XFS_AGF_MAGIC:
		return be64_to_cpu(((struct xfs_agf *)blk)->agf_lsn);
		lsn = be64_to_cpu(((struct xfs_agf *)blk)->agf_lsn);
		uuid = &((struct xfs_agf *)blk)->agf_uuid;
		break;
	case XFS_AGFL_MAGIC:
		return be64_to_cpu(((struct xfs_agfl *)blk)->agfl_lsn);
		lsn = be64_to_cpu(((struct xfs_agfl *)blk)->agfl_lsn);
		uuid = &((struct xfs_agfl *)blk)->agfl_uuid;
		break;
	case XFS_AGI_MAGIC:
		return be64_to_cpu(((struct xfs_agi *)blk)->agi_lsn);
		lsn = be64_to_cpu(((struct xfs_agi *)blk)->agi_lsn);
		uuid = &((struct xfs_agi *)blk)->agi_uuid;
		break;
	case XFS_SYMLINK_MAGIC:
		return be64_to_cpu(((struct xfs_dsymlink_hdr *)blk)->sl_lsn);
		lsn = be64_to_cpu(((struct xfs_dsymlink_hdr *)blk)->sl_lsn);
		uuid = &((struct xfs_dsymlink_hdr *)blk)->sl_uuid;
		break;
	case XFS_DIR3_BLOCK_MAGIC:
	case XFS_DIR3_DATA_MAGIC:
	case XFS_DIR3_FREE_MAGIC:
		return be64_to_cpu(((struct xfs_dir3_blk_hdr *)blk)->lsn);
		lsn = be64_to_cpu(((struct xfs_dir3_blk_hdr *)blk)->lsn);
		uuid = &((struct xfs_dir3_blk_hdr *)blk)->uuid;
		break;
	case XFS_ATTR3_RMT_MAGIC:
		return be64_to_cpu(((struct xfs_attr3_rmt_hdr *)blk)->rm_lsn);
		lsn = be64_to_cpu(((struct xfs_attr3_rmt_hdr *)blk)->rm_lsn);
		uuid = &((struct xfs_attr3_rmt_hdr *)blk)->rm_uuid;
		break;
	case XFS_SB_MAGIC:
		return be64_to_cpu(((struct xfs_dsb *)blk)->sb_lsn);
		lsn = be64_to_cpu(((struct xfs_dsb *)blk)->sb_lsn);
		uuid = &((struct xfs_dsb *)blk)->sb_uuid;
		break;
	default:
		break;
	}

	if (lsn != (xfs_lsn_t)-1) {
		if (!uuid_equal(&mp->m_sb.sb_uuid, uuid))
			goto recover_immediately;
		return lsn;
	}

	magicda = be16_to_cpu(((struct xfs_da_blkinfo *)blk)->magic);
	switch (magicda) {
	case XFS_DIR3_LEAF1_MAGIC:
	case XFS_DIR3_LEAFN_MAGIC:
	case XFS_DA3_NODE_MAGIC:
		return be64_to_cpu(((struct xfs_da3_blkinfo *)blk)->lsn);
		lsn = be64_to_cpu(((struct xfs_da3_blkinfo *)blk)->lsn);
		uuid = &((struct xfs_da3_blkinfo *)blk)->uuid;
		break;
	default:
		break;
	}

	if (lsn != (xfs_lsn_t)-1) {
		if (!uuid_equal(&mp->m_sb.sb_uuid, uuid))
			goto recover_immediately;
		return lsn;
	}

	/*
	 * We do individual object checks on dquot and inode buffers as they
	 * have their own individual LSN records. Also, we could have a stale