diff options
Diffstat (limited to 'fs/xfs/libxfs')
| -rw-r--r-- | fs/xfs/libxfs/xfs_alloc.c | 6 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_alloc_btree.c | 4 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_attr.c | 2 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_attr_leaf.c | 4 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_attr_remote.c | 53 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_bit.c | 118 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_bmap.c | 1 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_bmap_btree.c | 5 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_btree.c | 10 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_da_btree.c | 32 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_da_format.h | 11 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_dir2.c | 36 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_dir2_block.c | 4 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_dir2_data.c | 7 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_dir2_leaf.c | 4 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_dir2_node.c | 17 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_dquot_buf.c | 4 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_format.h | 22 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_ialloc.c | 7 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_ialloc_btree.c | 2 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_inode_buf.c | 4 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_sb.c | 27 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_symlink_remote.c | 4 | 
23 files changed, 290 insertions, 94 deletions
diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index f9e9ffe6fb46..ffad7f20342f 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -464,7 +464,7 @@ xfs_agfl_verify(  	struct xfs_agfl	*agfl = XFS_BUF_TO_AGFL(bp);  	int		i; -	if (!uuid_equal(&agfl->agfl_uuid, &mp->m_sb.sb_uuid)) +	if (!uuid_equal(&agfl->agfl_uuid, &mp->m_sb.sb_meta_uuid))  		return false;  	if (be32_to_cpu(agfl->agfl_magicnum) != XFS_AGFL_MAGIC)  		return false; @@ -1937,7 +1937,7 @@ xfs_alloc_fix_freelist(  	struct xfs_alloc_arg	targs;	/* local allocation arguments */  	xfs_agblock_t		bno;	/* freelist block */  	xfs_extlen_t		need;	/* total blocks needed in freelist */ -	int			error; +	int			error = 0;  	if (!pag->pagf_init) {  		error = xfs_alloc_read_agf(mp, tp, args->agno, flags, &agbp); @@ -2260,7 +2260,7 @@ xfs_agf_verify(  	struct xfs_agf	*agf = XFS_BUF_TO_AGF(bp);  	if (xfs_sb_version_hascrc(&mp->m_sb) && -	    !uuid_equal(&agf->agf_uuid, &mp->m_sb.sb_uuid)) +	    !uuid_equal(&agf->agf_uuid, &mp->m_sb.sb_meta_uuid))  			return false;  	if (!(agf->agf_magicnum == cpu_to_be32(XFS_AGF_MAGIC) && diff --git a/fs/xfs/libxfs/xfs_alloc_btree.c b/fs/xfs/libxfs/xfs_alloc_btree.c index 59d521c09a17..90de071dd4c2 100644 --- a/fs/xfs/libxfs/xfs_alloc_btree.c +++ b/fs/xfs/libxfs/xfs_alloc_btree.c @@ -295,7 +295,7 @@ xfs_allocbt_verify(  	case cpu_to_be32(XFS_ABTB_CRC_MAGIC):  		if (!xfs_sb_version_hascrc(&mp->m_sb))  			return false; -		if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) +		if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))  			return false;  		if (block->bb_u.s.bb_blkno != cpu_to_be64(bp->b_bn))  			return false; @@ -313,7 +313,7 @@ xfs_allocbt_verify(  	case cpu_to_be32(XFS_ABTC_CRC_MAGIC):  		if (!xfs_sb_version_hascrc(&mp->m_sb))  			return false; -		if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) +		if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))  			return false;  		if (block->bb_u.s.bb_blkno != cpu_to_be64(bp->b_bn))  			return false; diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index 3349c9a1e845..ff065578969f 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -139,6 +139,8 @@ xfs_attr_get(  	args.value = value;  	args.valuelen = *valuelenp; +	/* Entirely possible to look up a name which doesn't exist */ +	args.op_flags = XFS_DA_OP_OKNOENT;  	lock_mode = xfs_ilock_attr_map_shared(ip);  	if (!xfs_inode_hasattr(ip)) diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index e9d401ce93bb..33df52d97ec7 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c @@ -262,7 +262,7 @@ xfs_attr3_leaf_verify(  		if (ichdr.magic != XFS_ATTR3_LEAF_MAGIC)  			return false; -		if (!uuid_equal(&hdr3->info.uuid, &mp->m_sb.sb_uuid)) +		if (!uuid_equal(&hdr3->info.uuid, &mp->m_sb.sb_meta_uuid))  			return false;  		if (be64_to_cpu(hdr3->info.blkno) != bp->b_bn)  			return false; @@ -1056,7 +1056,7 @@ xfs_attr3_leaf_create(  		hdr3->blkno = cpu_to_be64(bp->b_bn);  		hdr3->owner = cpu_to_be64(dp->i_ino); -		uuid_copy(&hdr3->uuid, &mp->m_sb.sb_uuid); +		uuid_copy(&hdr3->uuid, &mp->m_sb.sb_meta_uuid);  		ichdr.freemap[0].base = sizeof(struct xfs_attr3_leaf_hdr);  	} else { diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c index 20de88d1bf86..f38f9bd81557 100644 --- a/fs/xfs/libxfs/xfs_attr_remote.c +++ b/fs/xfs/libxfs/xfs_attr_remote.c @@ -100,7 +100,7 @@ xfs_attr3_rmt_verify(  		return false;  	if (rmt->rm_magic != cpu_to_be32(XFS_ATTR3_RMT_MAGIC))  		return false; -	if (!uuid_equal(&rmt->rm_uuid, &mp->m_sb.sb_uuid)) +	if (!uuid_equal(&rmt->rm_uuid, &mp->m_sb.sb_meta_uuid))  		return false;  	if (be64_to_cpu(rmt->rm_blkno) != bno)  		return false; @@ -159,11 +159,10 @@ xfs_attr3_rmt_write_verify(  	struct xfs_buf	*bp)  {  	struct xfs_mount *mp = bp->b_target->bt_mount; -	struct xfs_buf_log_item	*bip = bp->b_fspriv; +	int		blksize = mp->m_attr_geo->blksize;  	char		*ptr;  	int		len;  	xfs_daddr_t	bno; -	int		blksize = mp->m_attr_geo->blksize;  	/* no verification of non-crc buffers */  	if (!xfs_sb_version_hascrc(&mp->m_sb)) @@ -175,16 +174,22 @@ xfs_attr3_rmt_write_verify(  	ASSERT(len >= blksize);  	while (len > 0) { +		struct xfs_attr3_rmt_hdr *rmt = (struct xfs_attr3_rmt_hdr *)ptr; +  		if (!xfs_attr3_rmt_verify(mp, ptr, blksize, bno)) {  			xfs_buf_ioerror(bp, -EFSCORRUPTED);  			xfs_verifier_error(bp);  			return;  		} -		if (bip) { -			struct xfs_attr3_rmt_hdr *rmt; -			rmt = (struct xfs_attr3_rmt_hdr *)ptr; -			rmt->rm_lsn = cpu_to_be64(bip->bli_item.li_lsn); +		/* +		 * Ensure we aren't writing bogus LSNs to disk. See +		 * xfs_attr3_rmt_hdr_set() for the explanation. +		 */ +		if (rmt->rm_lsn != cpu_to_be64(NULLCOMMITLSN)) { +			xfs_buf_ioerror(bp, -EFSCORRUPTED); +			xfs_verifier_error(bp); +			return;  		}  		xfs_update_cksum(ptr, blksize, XFS_ATTR3_RMT_CRC_OFF); @@ -217,10 +222,22 @@ xfs_attr3_rmt_hdr_set(  	rmt->rm_magic = cpu_to_be32(XFS_ATTR3_RMT_MAGIC);  	rmt->rm_offset = cpu_to_be32(offset);  	rmt->rm_bytes = cpu_to_be32(size); -	uuid_copy(&rmt->rm_uuid, &mp->m_sb.sb_uuid); +	uuid_copy(&rmt->rm_uuid, &mp->m_sb.sb_meta_uuid);  	rmt->rm_owner = cpu_to_be64(ino);  	rmt->rm_blkno = cpu_to_be64(bno); +	/* +	 * Remote attribute blocks are written synchronously, so we don't +	 * have an LSN that we can stamp in them that makes any sense to log +	 * recovery. To ensure that log recovery handles overwrites of these +	 * blocks sanely (i.e. once they've been freed and reallocated as some +	 * other type of metadata) we need to ensure that the LSN has a value +	 * that tells log recovery to ignore the LSN and overwrite the buffer +	 * with whatever is in it's log. To do this, we use the magic +	 * NULLCOMMITLSN to indicate that the LSN is invalid. +	 */ +	rmt->rm_lsn = cpu_to_be64(NULLCOMMITLSN); +  	return sizeof(struct xfs_attr3_rmt_hdr);  } @@ -434,14 +451,21 @@ xfs_attr_rmtval_set(  		/*  		 * Allocate a single extent, up to the size of the value. +		 * +		 * Note that we have to consider this a data allocation as we +		 * write the remote attribute without logging the contents. +		 * Hence we must ensure that we aren't using blocks that are on +		 * the busy list so that we don't overwrite blocks which have +		 * recently been freed but their transactions are not yet +		 * committed to disk. If we overwrite the contents of a busy +		 * extent and then crash then the block may not contain the +		 * correct metadata after log recovery occurs.  		 */  		xfs_bmap_init(args->flist, args->firstblock);  		nmap = 1;  		error = xfs_bmapi_write(args->trans, dp, (xfs_fileoff_t)lblkno, -				  blkcnt, -				  XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, -				  args->firstblock, args->total, &map, &nmap, -				  args->flist); +				  blkcnt, XFS_BMAPI_ATTRFORK, args->firstblock, +				  args->total, &map, &nmap, args->flist);  		if (!error) {  			error = xfs_bmap_finish(&args->trans, args->flist,  						&committed); @@ -594,9 +618,8 @@ xfs_attr_rmtval_remove(  		xfs_bmap_init(args->flist, args->firstblock);  		error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt, -				    XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, -				    1, args->firstblock, args->flist, -				    &done); +				    XFS_BMAPI_ATTRFORK, 1, args->firstblock, +				    args->flist, &done);  		if (!error) {  			error = xfs_bmap_finish(&args->trans, args->flist,  						&committed); diff --git a/fs/xfs/libxfs/xfs_bit.c b/fs/xfs/libxfs/xfs_bit.c new file mode 100644 index 000000000000..0e8885a59646 --- /dev/null +++ b/fs/xfs/libxfs/xfs_bit.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2000-2005 Silicon Graphics, Inc. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA + */ +#include "xfs.h" +#include "xfs_log_format.h" +#include "xfs_bit.h" + +/* + * XFS bit manipulation routines, used in non-realtime code. + */ + +/* + * Return whether bitmap is empty. + * Size is number of words in the bitmap, which is padded to word boundary + * Returns 1 for empty, 0 for non-empty. + */ +int +xfs_bitmap_empty(uint *map, uint size) +{ +	uint i; +	uint ret = 0; + +	for (i = 0; i < size; i++) { +		ret |= map[i]; +	} + +	return (ret == 0); +} + +/* + * Count the number of contiguous bits set in the bitmap starting with bit + * start_bit.  Size is the size of the bitmap in words. + */ +int +xfs_contig_bits(uint *map, uint	size, uint start_bit) +{ +	uint * p = ((unsigned int *) map) + (start_bit >> BIT_TO_WORD_SHIFT); +	uint result = 0; +	uint tmp; + +	size <<= BIT_TO_WORD_SHIFT; + +	ASSERT(start_bit < size); +	size -= start_bit & ~(NBWORD - 1); +	start_bit &= (NBWORD - 1); +	if (start_bit) { +		tmp = *p++; +		/* set to one first offset bits prior to start */ +		tmp |= (~0U >> (NBWORD-start_bit)); +		if (tmp != ~0U) +			goto found; +		result += NBWORD; +		size -= NBWORD; +	} +	while (size) { +		if ((tmp = *p++) != ~0U) +			goto found; +		result += NBWORD; +		size -= NBWORD; +	} +	return result - start_bit; +found: +	return result + ffz(tmp) - start_bit; +} + +/* + * This takes the bit number to start looking from and + * returns the next set bit from there.  It returns -1 + * if there are no more bits set or the start bit is + * beyond the end of the bitmap. + * + * Size is the number of words, not bytes, in the bitmap. + */ +int xfs_next_bit(uint *map, uint size, uint start_bit) +{ +	uint * p = ((unsigned int *) map) + (start_bit >> BIT_TO_WORD_SHIFT); +	uint result = start_bit & ~(NBWORD - 1); +	uint tmp; + +	size <<= BIT_TO_WORD_SHIFT; + +	if (start_bit >= size) +		return -1; +	size -= result; +	start_bit &= (NBWORD - 1); +	if (start_bit) { +		tmp = *p++; +		/* set to zero first offset bits prior to start */ +		tmp &= (~0U << start_bit); +		if (tmp != 0U) +			goto found; +		result += NBWORD; +		size -= NBWORD; +	} +	while (size) { +		if ((tmp = *p++) != 0U) +			goto found; +		result += NBWORD; +		size -= NBWORD; +	} +	return -1; +found: +	return result + ffs(tmp) - 1; +} diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 63e05b663380..8e2010d53b07 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -5945,6 +5945,7 @@ xfs_bmap_split_extent(  	return xfs_trans_commit(tp);  out: +	xfs_bmap_cancel(&free_list);  	xfs_trans_cancel(tp);  	return error;  } diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index 2c44c8e50782..6b0cf6546a82 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c @@ -349,7 +349,8 @@ xfs_bmbt_to_bmdr(  	if (xfs_sb_version_hascrc(&mp->m_sb)) {  		ASSERT(rblock->bb_magic == cpu_to_be32(XFS_BMAP_CRC_MAGIC)); -		ASSERT(uuid_equal(&rblock->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid)); +		ASSERT(uuid_equal(&rblock->bb_u.l.bb_uuid, +		       &mp->m_sb.sb_meta_uuid));  		ASSERT(rblock->bb_u.l.bb_blkno ==  		       cpu_to_be64(XFS_BUF_DADDR_NULL));  	} else @@ -647,7 +648,7 @@ xfs_bmbt_verify(  	case cpu_to_be32(XFS_BMAP_CRC_MAGIC):  		if (!xfs_sb_version_hascrc(&mp->m_sb))  			return false; -		if (!uuid_equal(&block->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid)) +		if (!uuid_equal(&block->bb_u.l.bb_uuid, &mp->m_sb.sb_meta_uuid))  			return false;  		if (be64_to_cpu(block->bb_u.l.bb_blkno) != bp->b_bn)  			return false; diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index c72283dd8d44..f7d7ee7a2607 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c @@ -65,7 +65,8 @@ xfs_btree_check_lblock(  	if (xfs_sb_version_hascrc(&mp->m_sb)) {  		lblock_ok = lblock_ok && -			uuid_equal(&block->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid) && +			uuid_equal(&block->bb_u.l.bb_uuid, +				   &mp->m_sb.sb_meta_uuid) &&  			block->bb_u.l.bb_blkno == cpu_to_be64(  				bp ? bp->b_bn : XFS_BUF_DADDR_NULL);  	} @@ -115,7 +116,8 @@ xfs_btree_check_sblock(  	if (xfs_sb_version_hascrc(&mp->m_sb)) {  		sblock_ok = sblock_ok && -			uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid) && +			uuid_equal(&block->bb_u.s.bb_uuid, +				   &mp->m_sb.sb_meta_uuid) &&  			block->bb_u.s.bb_blkno == cpu_to_be64(  				bp ? bp->b_bn : XFS_BUF_DADDR_NULL);  	} @@ -1000,7 +1002,7 @@ xfs_btree_init_block_int(  		if (flags & XFS_BTREE_CRC_BLOCKS) {  			buf->bb_u.l.bb_blkno = cpu_to_be64(blkno);  			buf->bb_u.l.bb_owner = cpu_to_be64(owner); -			uuid_copy(&buf->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid); +			uuid_copy(&buf->bb_u.l.bb_uuid, &mp->m_sb.sb_meta_uuid);  			buf->bb_u.l.bb_pad = 0;  			buf->bb_u.l.bb_lsn = 0;  		} @@ -1013,7 +1015,7 @@ xfs_btree_init_block_int(  		if (flags & XFS_BTREE_CRC_BLOCKS) {  			buf->bb_u.s.bb_blkno = cpu_to_be64(blkno);  			buf->bb_u.s.bb_owner = cpu_to_be32(__owner); -			uuid_copy(&buf->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid); +			uuid_copy(&buf->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid);  			buf->bb_u.s.bb_lsn = 0;  		}  	} diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c index 2385f8cd08ab..be43248a5822 100644 --- a/fs/xfs/libxfs/xfs_da_btree.c +++ b/fs/xfs/libxfs/xfs_da_btree.c @@ -146,7 +146,7 @@ xfs_da3_node_verify(  		if (ichdr.magic != XFS_DA3_NODE_MAGIC)  			return false; -		if (!uuid_equal(&hdr3->info.uuid, &mp->m_sb.sb_uuid)) +		if (!uuid_equal(&hdr3->info.uuid, &mp->m_sb.sb_meta_uuid))  			return false;  		if (be64_to_cpu(hdr3->info.blkno) != bp->b_bn)  			return false; @@ -233,6 +233,7 @@ xfs_da3_node_read_verify(  			bp->b_ops->verify_read(bp);  			return;  		default: +			xfs_buf_ioerror(bp, -EFSCORRUPTED);  			break;  	} @@ -324,7 +325,7 @@ xfs_da3_node_create(  		ichdr.magic = XFS_DA3_NODE_MAGIC;  		hdr3->info.blkno = cpu_to_be64(bp->b_bn);  		hdr3->info.owner = cpu_to_be64(args->dp->i_ino); -		uuid_copy(&hdr3->info.uuid, &mp->m_sb.sb_uuid); +		uuid_copy(&hdr3->info.uuid, &mp->m_sb.sb_meta_uuid);  	} else {  		ichdr.magic = XFS_DA_NODE_MAGIC;  	} @@ -1822,6 +1823,7 @@ xfs_da3_path_shift(  	struct xfs_da_args	*args;  	struct xfs_da_node_entry *btree;  	struct xfs_da3_icnode_hdr nodehdr; +	struct xfs_buf		*bp;  	xfs_dablk_t		blkno = 0;  	int			level;  	int			error; @@ -1866,20 +1868,24 @@ xfs_da3_path_shift(  	 */  	for (blk++, level++; level < path->active; blk++, level++) {  		/* -		 * Release the old block. -		 * (if it's dirty, trans won't actually let go) +		 * Read the next child block into a local buffer.  		 */ -		if (release) -			xfs_trans_brelse(args->trans, blk->bp); +		error = xfs_da3_node_read(args->trans, dp, blkno, -1, &bp, +					  args->whichfork); +		if (error) +			return error;  		/* -		 * Read the next child block. +		 * Release the old block (if it's dirty, the trans doesn't +		 * actually let go) and swap the local buffer into the path +		 * structure. This ensures failure of the above read doesn't set +		 * a NULL buffer in an active slot in the path.  		 */ +		if (release) +			xfs_trans_brelse(args->trans, blk->bp);  		blk->blkno = blkno; -		error = xfs_da3_node_read(args->trans, dp, blkno, -1, -					&blk->bp, args->whichfork); -		if (error) -			return error; +		blk->bp = bp; +  		info = blk->bp->b_addr;  		ASSERT(info->magic == cpu_to_be16(XFS_DA_NODE_MAGIC) ||  		       info->magic == cpu_to_be16(XFS_DA3_NODE_MAGIC) || @@ -2351,8 +2357,8 @@ xfs_da_shrink_inode(  		 * the last block to the place we want to kill.  		 */  		error = xfs_bunmapi(tp, dp, dead_blkno, count, -				    xfs_bmapi_aflag(w)|XFS_BMAPI_METADATA, -				    0, args->firstblock, args->flist, &done); +				    xfs_bmapi_aflag(w), 0, args->firstblock, +				    args->flist, &done);  		if (error == -ENOSPC) {  			if (w != XFS_DATA_FORK)  				break; diff --git a/fs/xfs/libxfs/xfs_da_format.h b/fs/xfs/libxfs/xfs_da_format.h index 74bcbabfa523..b14bbd6bb05f 100644 --- a/fs/xfs/libxfs/xfs_da_format.h +++ b/fs/xfs/libxfs/xfs_da_format.h @@ -680,8 +680,15 @@ typedef struct xfs_attr_leaf_name_remote {  typedef struct xfs_attr_leafblock {  	xfs_attr_leaf_hdr_t	hdr;	/* constant-structure header block */  	xfs_attr_leaf_entry_t	entries[1];	/* sorted on key, not name */ -	xfs_attr_leaf_name_local_t namelist;	/* grows from bottom of buf */ -	xfs_attr_leaf_name_remote_t valuelist;	/* grows from bottom of buf */ +	/* +	 * The rest of the block contains the following structures after the +	 * leaf entries, growing from the bottom up. The variables are never +	 * referenced and definining them can actually make gcc optimize away +	 * accesses to the 'entries' array above index 0 so don't do that. +	 * +	 * xfs_attr_leaf_name_local_t namelist; +	 * xfs_attr_leaf_name_remote_t valuelist; +	 */  } xfs_attr_leafblock_t;  /* diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index a69fb3a1e161..9de401d297e5 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -362,6 +362,7 @@ xfs_dir_lookup(  	struct xfs_da_args *args;  	int		rval;  	int		v;		/* type-checking value */ +	int		lock_mode;  	ASSERT(S_ISDIR(dp->i_d.di_mode));  	XFS_STATS_INC(xs_dir_lookup); @@ -387,6 +388,7 @@ xfs_dir_lookup(  	if (ci_name)  		args->op_flags |= XFS_DA_OP_CILOOKUP; +	lock_mode = xfs_ilock_data_map_shared(dp);  	if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {  		rval = xfs_dir2_sf_lookup(args);  		goto out_check_rval; @@ -419,6 +421,7 @@ out_check_rval:  		}  	}  out_free: +	xfs_iunlock(dp, lock_mode);  	kmem_free(args);  	return rval;  } @@ -674,25 +677,22 @@ xfs_dir2_shrink_inode(  	mp = dp->i_mount;  	tp = args->trans;  	da = xfs_dir2_db_to_da(args->geo, db); -	/* -	 * Unmap the fsblock(s). -	 */ -	if ((error = xfs_bunmapi(tp, dp, da, args->geo->fsbcount, -			XFS_BMAPI_METADATA, 0, args->firstblock, args->flist, -			&done))) { + +	/* Unmap the fsblock(s). */ +	error = xfs_bunmapi(tp, dp, da, args->geo->fsbcount, 0, 0, +			    args->firstblock, args->flist, &done); +	if (error) {  		/* -		 * ENOSPC actually can happen if we're in a removename with -		 * no space reservation, and the resulting block removal -		 * would cause a bmap btree split or conversion from extents -		 * to btree.  This can only happen for un-fragmented -		 * directory blocks, since you need to be punching out -		 * the middle of an extent. -		 * In this case we need to leave the block in the file, -		 * and not binval it. -		 * So the block has to be in a consistent empty state -		 * and appropriately logged. -		 * We don't free up the buffer, the caller can tell it -		 * hasn't happened since it got an error back. +		 * ENOSPC actually can happen if we're in a removename with no +		 * space reservation, and the resulting block removal would +		 * cause a bmap btree split or conversion from extents to btree. +		 * This can only happen for un-fragmented directory blocks, +		 * since you need to be punching out the middle of an extent. +		 * In this case we need to leave the block in the file, and not +		 * binval it.  So the block has to be in a consistent empty +		 * state and appropriately logged.  We don't free up the buffer, +		 * the caller can tell it hasn't happened since it got an error +		 * back.  		 */  		return error;  	} diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c index 9354e190b82e..4778d1dd511a 100644 --- a/fs/xfs/libxfs/xfs_dir2_block.c +++ b/fs/xfs/libxfs/xfs_dir2_block.c @@ -67,7 +67,7 @@ xfs_dir3_block_verify(  	if (xfs_sb_version_hascrc(&mp->m_sb)) {  		if (hdr3->magic != cpu_to_be32(XFS_DIR3_BLOCK_MAGIC))  			return false; -		if (!uuid_equal(&hdr3->uuid, &mp->m_sb.sb_uuid)) +		if (!uuid_equal(&hdr3->uuid, &mp->m_sb.sb_meta_uuid))  			return false;  		if (be64_to_cpu(hdr3->blkno) != bp->b_bn)  			return false; @@ -157,7 +157,7 @@ xfs_dir3_block_init(  		hdr3->magic = cpu_to_be32(XFS_DIR3_BLOCK_MAGIC);  		hdr3->blkno = cpu_to_be64(bp->b_bn);  		hdr3->owner = cpu_to_be64(dp->i_ino); -		uuid_copy(&hdr3->uuid, &mp->m_sb.sb_uuid); +		uuid_copy(&hdr3->uuid, &mp->m_sb.sb_meta_uuid);  		return;  	} diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c index de1ea16f5748..824131e71bc5 100644 --- a/fs/xfs/libxfs/xfs_dir2_data.c +++ b/fs/xfs/libxfs/xfs_dir2_data.c @@ -220,7 +220,7 @@ xfs_dir3_data_verify(  	if (xfs_sb_version_hascrc(&mp->m_sb)) {  		if (hdr3->magic != cpu_to_be32(XFS_DIR3_DATA_MAGIC))  			return false; -		if (!uuid_equal(&hdr3->uuid, &mp->m_sb.sb_uuid)) +		if (!uuid_equal(&hdr3->uuid, &mp->m_sb.sb_meta_uuid))  			return false;  		if (be64_to_cpu(hdr3->blkno) != bp->b_bn)  			return false; @@ -252,7 +252,8 @@ xfs_dir3_data_reada_verify(  		return;  	case cpu_to_be32(XFS_DIR2_DATA_MAGIC):  	case cpu_to_be32(XFS_DIR3_DATA_MAGIC): -		xfs_dir3_data_verify(bp); +		bp->b_ops = &xfs_dir3_data_buf_ops; +		bp->b_ops->verify_read(bp);  		return;  	default:  		xfs_buf_ioerror(bp, -EFSCORRUPTED); @@ -604,7 +605,7 @@ xfs_dir3_data_init(  		hdr3->magic = cpu_to_be32(XFS_DIR3_DATA_MAGIC);  		hdr3->blkno = cpu_to_be64(bp->b_bn);  		hdr3->owner = cpu_to_be64(dp->i_ino); -		uuid_copy(&hdr3->uuid, &mp->m_sb.sb_uuid); +		uuid_copy(&hdr3->uuid, &mp->m_sb.sb_meta_uuid);  	} else  		hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC); diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c index 106119955400..f300240ebb8d 100644 --- a/fs/xfs/libxfs/xfs_dir2_leaf.c +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c @@ -160,7 +160,7 @@ xfs_dir3_leaf_verify(  		if (leaf3->info.hdr.magic != cpu_to_be16(magic3))  			return false; -		if (!uuid_equal(&leaf3->info.uuid, &mp->m_sb.sb_uuid)) +		if (!uuid_equal(&leaf3->info.uuid, &mp->m_sb.sb_meta_uuid))  			return false;  		if (be64_to_cpu(leaf3->info.blkno) != bp->b_bn)  			return false; @@ -310,7 +310,7 @@ xfs_dir3_leaf_init(  					 : cpu_to_be16(XFS_DIR3_LEAFN_MAGIC);  		leaf3->info.blkno = cpu_to_be64(bp->b_bn);  		leaf3->info.owner = cpu_to_be64(owner); -		uuid_copy(&leaf3->info.uuid, &mp->m_sb.sb_uuid); +		uuid_copy(&leaf3->info.uuid, &mp->m_sb.sb_meta_uuid);  	} else {  		memset(leaf, 0, sizeof(*leaf));  		leaf->hdr.info.magic = cpu_to_be16(type); diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c index 41b80d3d3877..cc28e924545b 100644 --- a/fs/xfs/libxfs/xfs_dir2_node.c +++ b/fs/xfs/libxfs/xfs_dir2_node.c @@ -93,7 +93,7 @@ xfs_dir3_free_verify(  		if (hdr3->magic != cpu_to_be32(XFS_DIR3_FREE_MAGIC))  			return false; -		if (!uuid_equal(&hdr3->uuid, &mp->m_sb.sb_uuid)) +		if (!uuid_equal(&hdr3->uuid, &mp->m_sb.sb_meta_uuid))  			return false;  		if (be64_to_cpu(hdr3->blkno) != bp->b_bn)  			return false; @@ -226,7 +226,7 @@ xfs_dir3_free_get_buf(  		hdr3->hdr.blkno = cpu_to_be64(bp->b_bn);  		hdr3->hdr.owner = cpu_to_be64(dp->i_ino); -		uuid_copy(&hdr3->hdr.uuid, &mp->m_sb.sb_uuid); +		uuid_copy(&hdr3->hdr.uuid, &mp->m_sb.sb_meta_uuid);  	} else  		hdr.magic = XFS_DIR2_FREE_MAGIC;  	dp->d_ops->free_hdr_to_disk(bp->b_addr, &hdr); @@ -1845,8 +1845,7 @@ xfs_dir2_node_addname_int(  			if (dp->d_ops->db_to_fdb(args->geo, dbno) != fbno) {  				xfs_alert(mp, -			"%s: dir ino %llu needed freesp block %lld for\n" -			"  data block %lld, got %lld ifbno %llu lastfbno %d", +"%s: dir ino %llu needed freesp block %lld for data block %lld, got %lld ifbno %llu lastfbno %d",  					__func__, (unsigned long long)dp->i_ino,  					(long long)dp->d_ops->db_to_fdb(  								args->geo, dbno), @@ -2132,6 +2131,7 @@ xfs_dir2_node_replace(  	int			error;		/* error return value */  	int			i;		/* btree level */  	xfs_ino_t		inum;		/* new inode number */ +	int			ftype;		/* new file type */  	xfs_dir2_leaf_t		*leaf;		/* leaf structure */  	xfs_dir2_leaf_entry_t	*lep;		/* leaf entry being changed */  	int			rval;		/* internal return value */ @@ -2145,7 +2145,14 @@ xfs_dir2_node_replace(  	state = xfs_da_state_alloc();  	state->args = args;  	state->mp = args->dp->i_mount; + +	/* +	 * We have to save new inode number and ftype since +	 * xfs_da3_node_lookup_int() is going to overwrite them +	 */  	inum = args->inumber; +	ftype = args->filetype; +  	/*  	 * Lookup the entry to change in the btree.  	 */ @@ -2183,7 +2190,7 @@ xfs_dir2_node_replace(  		 * Fill in the new inode number and log the entry.  		 */  		dep->inumber = cpu_to_be64(inum); -		args->dp->d_ops->data_put_ftype(dep, args->filetype); +		args->dp->d_ops->data_put_ftype(dep, ftype);  		xfs_dir2_data_log_entry(args, state->extrablk.bp, dep);  		rval = 0;  	} diff --git a/fs/xfs/libxfs/xfs_dquot_buf.c b/fs/xfs/libxfs/xfs_dquot_buf.c index 6fbf2d853a54..5331b7f0460c 100644 --- a/fs/xfs/libxfs/xfs_dquot_buf.c +++ b/fs/xfs/libxfs/xfs_dquot_buf.c @@ -163,7 +163,7 @@ xfs_dqcheck(  	d->dd_diskdq.d_id = cpu_to_be32(id);  	if (xfs_sb_version_hascrc(&mp->m_sb)) { -		uuid_copy(&d->dd_uuid, &mp->m_sb.sb_uuid); +		uuid_copy(&d->dd_uuid, &mp->m_sb.sb_meta_uuid);  		xfs_update_cksum((char *)d, sizeof(struct xfs_dqblk),  				 XFS_DQUOT_CRC_OFF);  	} @@ -198,7 +198,7 @@ xfs_dquot_buf_verify_crc(  		if (!xfs_verify_cksum((char *)d, sizeof(struct xfs_dqblk),  				 XFS_DQUOT_CRC_OFF))  			return false; -		if (!uuid_equal(&d->dd_uuid, &mp->m_sb.sb_uuid)) +		if (!uuid_equal(&d->dd_uuid, &mp->m_sb.sb_meta_uuid))  			return false;  	}  	return true; diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index a0ae572051de..9590a069e556 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -100,7 +100,7 @@ typedef struct xfs_sb {  	xfs_rfsblock_t	sb_dblocks;	/* number of data blocks */  	xfs_rfsblock_t	sb_rblocks;	/* number of realtime blocks */  	xfs_rtblock_t	sb_rextents;	/* number of realtime extents */ -	uuid_t		sb_uuid;	/* file system unique id */ +	uuid_t		sb_uuid;	/* user-visible file system unique id */  	xfs_fsblock_t	sb_logstart;	/* starting block of log if internal */  	xfs_ino_t	sb_rootino;	/* root inode number */  	xfs_ino_t	sb_rbmino;	/* bitmap inode for realtime extents */ @@ -174,6 +174,7 @@ typedef struct xfs_sb {  	xfs_ino_t	sb_pquotino;	/* project quota inode */  	xfs_lsn_t	sb_lsn;		/* last write sequence */ +	uuid_t		sb_meta_uuid;	/* metadata file system unique id */  	/* must be padded to 64 bit alignment */  } xfs_sb_t; @@ -190,7 +191,7 @@ typedef struct xfs_dsb {  	__be64		sb_dblocks;	/* number of data blocks */  	__be64		sb_rblocks;	/* number of realtime blocks */  	__be64		sb_rextents;	/* number of realtime extents */ -	uuid_t		sb_uuid;	/* file system unique id */ +	uuid_t		sb_uuid;	/* user-visible file system unique id */  	__be64		sb_logstart;	/* starting block of log if internal */  	__be64		sb_rootino;	/* root inode number */  	__be64		sb_rbmino;	/* bitmap inode for realtime extents */ @@ -260,6 +261,7 @@ typedef struct xfs_dsb {  	__be64		sb_pquotino;	/* project quota inode */  	__be64		sb_lsn;		/* last write sequence */ +	uuid_t		sb_meta_uuid;	/* metadata file system unique id */  	/* must be padded to 64 bit alignment */  } xfs_dsb_t; @@ -458,9 +460,11 @@ xfs_sb_has_ro_compat_feature(  #define XFS_SB_FEAT_INCOMPAT_FTYPE	(1 << 0)	/* filetype in dirent */  #define XFS_SB_FEAT_INCOMPAT_SPINODES	(1 << 1)	/* sparse inode chunks */ +#define XFS_SB_FEAT_INCOMPAT_META_UUID	(1 << 2)	/* metadata UUID */  #define XFS_SB_FEAT_INCOMPAT_ALL \  		(XFS_SB_FEAT_INCOMPAT_FTYPE|	\ -		 XFS_SB_FEAT_INCOMPAT_SPINODES) +		 XFS_SB_FEAT_INCOMPAT_SPINODES|	\ +		 XFS_SB_FEAT_INCOMPAT_META_UUID)  #define XFS_SB_FEAT_INCOMPAT_UNKNOWN	~XFS_SB_FEAT_INCOMPAT_ALL  static inline bool @@ -515,6 +519,18 @@ static inline bool xfs_sb_version_hassparseinodes(struct xfs_sb *sbp)  }  /* + * XFS_SB_FEAT_INCOMPAT_META_UUID indicates that the metadata UUID + * is stored separately from the user-visible UUID; this allows the + * user-visible UUID to be changed on V5 filesystems which have a + * filesystem UUID stamped into every piece of metadata. + */ +static inline bool xfs_sb_version_hasmetauuid(struct xfs_sb *sbp) +{ +	return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) && +		(sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_META_UUID); +} + +/*   * end of superblock version macros   */ diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index 66efc702452a..54deb2d12ac6 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -338,7 +338,8 @@ xfs_ialloc_inode_init(  			if (version == 3) {  				free->di_ino = cpu_to_be64(ino);  				ino++; -				uuid_copy(&free->di_uuid, &mp->m_sb.sb_uuid); +				uuid_copy(&free->di_uuid, +					  &mp->m_sb.sb_meta_uuid);  				xfs_dinode_calc_crc(mp, free);  			} else if (tp) {  				/* just log the inode core */ @@ -2232,7 +2233,7 @@ xfs_imap_lookup(  	}  	xfs_trans_brelse(tp, agbp); -	xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); +	xfs_btree_del_cursor(cur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR);  	if (error)  		return error; @@ -2500,7 +2501,7 @@ xfs_agi_verify(  	struct xfs_agi	*agi = XFS_BUF_TO_AGI(bp);  	if (xfs_sb_version_hascrc(&mp->m_sb) && -	    !uuid_equal(&agi->agi_uuid, &mp->m_sb.sb_uuid)) +	    !uuid_equal(&agi->agi_uuid, &mp->m_sb.sb_meta_uuid))  			return false;  	/*  	 * Validate the magic number of the agi block. diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c index 674ad8f760be..f39b285beb19 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.c +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c @@ -239,7 +239,7 @@ xfs_inobt_verify(  	case cpu_to_be32(XFS_FIBT_CRC_MAGIC):  		if (!xfs_sb_version_hascrc(&mp->m_sb))  			return false; -		if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) +		if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))  			return false;  		if (block->bb_u.s.bb_blkno != cpu_to_be64(bp->b_bn))  			return false; diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c index 6526e7696184..268c00f4f83a 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.c +++ b/fs/xfs/libxfs/xfs_inode_buf.c @@ -304,7 +304,7 @@ xfs_dinode_verify(  		return false;  	if (be64_to_cpu(dip->di_ino) != ip->i_ino)  		return false; -	if (!uuid_equal(&dip->di_uuid, &mp->m_sb.sb_uuid)) +	if (!uuid_equal(&dip->di_uuid, &mp->m_sb.sb_meta_uuid))  		return false;  	return true;  } @@ -366,7 +366,7 @@ xfs_iread(  		if (xfs_sb_version_hascrc(&mp->m_sb)) {  			ip->i_d.di_version = 3;  			ip->i_d.di_ino = ip->i_ino; -			uuid_copy(&ip->i_d.di_uuid, &mp->m_sb.sb_uuid); +			uuid_copy(&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid);  		} else  			ip->i_d.di_version = 2;  		return 0; diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index df9851c46b5c..47425140f343 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c @@ -131,10 +131,11 @@ xfs_mount_validate_sb(  		if (xfs_sb_has_compat_feature(sbp,  					XFS_SB_FEAT_COMPAT_UNKNOWN)) {  			xfs_warn(mp, -"Superblock has unknown compatible features (0x%x) enabled.\n" -"Using a more recent kernel is recommended.", +"Superblock has unknown compatible features (0x%x) enabled.",  				(sbp->sb_features_compat &  						XFS_SB_FEAT_COMPAT_UNKNOWN)); +			xfs_warn(mp, +"Using a more recent kernel is recommended.");  		}  		if (xfs_sb_has_ro_compat_feature(sbp, @@ -145,18 +146,21 @@ xfs_mount_validate_sb(  						XFS_SB_FEAT_RO_COMPAT_UNKNOWN));  			if (!(mp->m_flags & XFS_MOUNT_RDONLY)) {  				xfs_warn(mp, -"Attempted to mount read-only compatible filesystem read-write.\n" +"Attempted to mount read-only compatible filesystem read-write."); +				xfs_warn(mp,  "Filesystem can only be safely mounted read only."); +  				return -EINVAL;  			}  		}  		if (xfs_sb_has_incompat_feature(sbp,  					XFS_SB_FEAT_INCOMPAT_UNKNOWN)) {  			xfs_warn(mp, -"Superblock has unknown incompatible features (0x%x) enabled.\n" -"Filesystem can not be safely mounted by this kernel.", +"Superblock has unknown incompatible features (0x%x) enabled.",  				(sbp->sb_features_incompat &  						XFS_SB_FEAT_INCOMPAT_UNKNOWN)); +			xfs_warn(mp, +"Filesystem can not be safely mounted by this kernel.");  			return -EINVAL;  		}  	} @@ -182,9 +186,6 @@ xfs_mount_validate_sb(  	if (xfs_sb_version_hassparseinodes(sbp)) {  		uint32_t	align; -		xfs_alert(mp, -	"EXPERIMENTAL sparse inode feature enabled. Use at your own risk!"); -  		align = XFS_INODES_PER_CHUNK * sbp->sb_inodesize  				>> sbp->sb_blocklog;  		if (sbp->sb_inoalignmt != align) { @@ -398,6 +399,14 @@ __xfs_sb_from_disk(  	to->sb_spino_align = be32_to_cpu(from->sb_spino_align);  	to->sb_pquotino = be64_to_cpu(from->sb_pquotino);  	to->sb_lsn = be64_to_cpu(from->sb_lsn); +	/* +	 * sb_meta_uuid is only on disk if it differs from sb_uuid and the +	 * feature flag is set; if not set we keep it only in memory. +	 */ +	if (xfs_sb_version_hasmetauuid(to)) +		uuid_copy(&to->sb_meta_uuid, &from->sb_meta_uuid); +	else +		uuid_copy(&to->sb_meta_uuid, &from->sb_uuid);  	/* Convert on-disk flags to in-memory flags? */  	if (convert_xquota)  		xfs_sb_quota_from_disk(to); @@ -539,6 +548,8 @@ xfs_sb_to_disk(  				cpu_to_be32(from->sb_features_log_incompat);  		to->sb_spino_align = cpu_to_be32(from->sb_spino_align);  		to->sb_lsn = cpu_to_be64(from->sb_lsn); +		if (xfs_sb_version_hasmetauuid(from)) +			uuid_copy(&to->sb_meta_uuid, &from->sb_meta_uuid);  	}  } diff --git a/fs/xfs/libxfs/xfs_symlink_remote.c b/fs/xfs/libxfs/xfs_symlink_remote.c index e7e26bd6468f..8f8af05b3f13 100644 --- a/fs/xfs/libxfs/xfs_symlink_remote.c +++ b/fs/xfs/libxfs/xfs_symlink_remote.c @@ -63,7 +63,7 @@ xfs_symlink_hdr_set(  	dsl->sl_magic = cpu_to_be32(XFS_SYMLINK_MAGIC);  	dsl->sl_offset = cpu_to_be32(offset);  	dsl->sl_bytes = cpu_to_be32(size); -	uuid_copy(&dsl->sl_uuid, &mp->m_sb.sb_uuid); +	uuid_copy(&dsl->sl_uuid, &mp->m_sb.sb_meta_uuid);  	dsl->sl_owner = cpu_to_be64(ino);  	dsl->sl_blkno = cpu_to_be64(bp->b_bn);  	bp->b_ops = &xfs_symlink_buf_ops; @@ -107,7 +107,7 @@ xfs_symlink_verify(  		return false;  	if (dsl->sl_magic != cpu_to_be32(XFS_SYMLINK_MAGIC))  		return false; -	if (!uuid_equal(&dsl->sl_uuid, &mp->m_sb.sb_uuid)) +	if (!uuid_equal(&dsl->sl_uuid, &mp->m_sb.sb_meta_uuid))  		return false;  	if (bp->b_bn != be64_to_cpu(dsl->sl_blkno))  		return false;  |