Commit d58c6ff0 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for-linus-v3.10-rc6' of git://oss.sgi.com/xfs/xfs

Pull xfs fixes from Ben Myers:
 - Remove noisy warnings about experimental support which spams the logs
 - Add padding to align directory and attr structures correctly
 - Set block number on child buffer on a root btree split
 - Disable verifiers during log recovery for non-CRC filesystems

* tag 'for-linus-v3.10-rc6' of git://oss.sgi.com/xfs/xfs:
  xfs: don't shutdown log recovery on validation errors
  xfs: ensure btree root split sets blkno correctly
  xfs: fix implicit padding in directory and attr CRC formats
  xfs: don't emit v5 superblock warnings on write
parents 9bb92855 d302cf1d
...@@ -128,6 +128,7 @@ struct xfs_attr3_leaf_hdr { ...@@ -128,6 +128,7 @@ struct xfs_attr3_leaf_hdr {
__u8 holes; __u8 holes;
__u8 pad1; __u8 pad1;
struct xfs_attr_leaf_map freemap[XFS_ATTR_LEAF_MAPSIZE]; struct xfs_attr_leaf_map freemap[XFS_ATTR_LEAF_MAPSIZE];
__be32 pad2; /* 64 bit alignment */
}; };
#define XFS_ATTR3_LEAF_CRC_OFF (offsetof(struct xfs_attr3_leaf_hdr, info.crc)) #define XFS_ATTR3_LEAF_CRC_OFF (offsetof(struct xfs_attr3_leaf_hdr, info.crc))
......
...@@ -2544,7 +2544,17 @@ xfs_btree_new_iroot( ...@@ -2544,7 +2544,17 @@ xfs_btree_new_iroot(
if (error) if (error)
goto error0; goto error0;
/*
* we can't just memcpy() the root in for CRC enabled btree blocks.
* In that case have to also ensure the blkno remains correct
*/
memcpy(cblock, block, xfs_btree_block_len(cur)); memcpy(cblock, block, xfs_btree_block_len(cur));
if (cur->bc_flags & XFS_BTREE_CRC_BLOCKS) {
if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
cblock->bb_u.l.bb_blkno = cpu_to_be64(cbp->b_bn);
else
cblock->bb_u.s.bb_blkno = cpu_to_be64(cbp->b_bn);
}
be16_add_cpu(&block->bb_level, 1); be16_add_cpu(&block->bb_level, 1);
xfs_btree_set_numrecs(block, 1); xfs_btree_set_numrecs(block, 1);
......
...@@ -266,6 +266,7 @@ struct xfs_dir3_blk_hdr { ...@@ -266,6 +266,7 @@ struct xfs_dir3_blk_hdr {
struct xfs_dir3_data_hdr { struct xfs_dir3_data_hdr {
struct xfs_dir3_blk_hdr hdr; struct xfs_dir3_blk_hdr hdr;
xfs_dir2_data_free_t best_free[XFS_DIR2_DATA_FD_COUNT]; xfs_dir2_data_free_t best_free[XFS_DIR2_DATA_FD_COUNT];
__be32 pad; /* 64 bit alignment */
}; };
#define XFS_DIR3_DATA_CRC_OFF offsetof(struct xfs_dir3_data_hdr, hdr.crc) #define XFS_DIR3_DATA_CRC_OFF offsetof(struct xfs_dir3_data_hdr, hdr.crc)
...@@ -477,7 +478,7 @@ struct xfs_dir3_leaf_hdr { ...@@ -477,7 +478,7 @@ struct xfs_dir3_leaf_hdr {
struct xfs_da3_blkinfo info; /* header for da routines */ struct xfs_da3_blkinfo info; /* header for da routines */
__be16 count; /* count of entries */ __be16 count; /* count of entries */
__be16 stale; /* count of stale entries */ __be16 stale; /* count of stale entries */
__be32 pad; __be32 pad; /* 64 bit alignment */
}; };
struct xfs_dir3_icleaf_hdr { struct xfs_dir3_icleaf_hdr {
...@@ -715,7 +716,7 @@ struct xfs_dir3_free_hdr { ...@@ -715,7 +716,7 @@ struct xfs_dir3_free_hdr {
__be32 firstdb; /* db of first entry */ __be32 firstdb; /* db of first entry */
__be32 nvalid; /* count of valid entries */ __be32 nvalid; /* count of valid entries */
__be32 nused; /* count of used entries */ __be32 nused; /* count of used entries */
__be32 pad; /* 64 bit alignment. */ __be32 pad; /* 64 bit alignment */
}; };
struct xfs_dir3_free { struct xfs_dir3_free {
......
...@@ -1845,7 +1845,13 @@ xlog_recover_do_inode_buffer( ...@@ -1845,7 +1845,13 @@ xlog_recover_do_inode_buffer(
xfs_agino_t *buffer_nextp; xfs_agino_t *buffer_nextp;
trace_xfs_log_recover_buf_inode_buf(mp->m_log, buf_f); trace_xfs_log_recover_buf_inode_buf(mp->m_log, buf_f);
bp->b_ops = &xfs_inode_buf_ops;
/*
* Post recovery validation only works properly on CRC enabled
* filesystems.
*/
if (xfs_sb_version_hascrc(&mp->m_sb))
bp->b_ops = &xfs_inode_buf_ops;
inodes_per_buf = BBTOB(bp->b_io_length) >> mp->m_sb.sb_inodelog; inodes_per_buf = BBTOB(bp->b_io_length) >> mp->m_sb.sb_inodelog;
for (i = 0; i < inodes_per_buf; i++) { for (i = 0; i < inodes_per_buf; i++) {
...@@ -2205,7 +2211,16 @@ xlog_recover_do_reg_buffer( ...@@ -2205,7 +2211,16 @@ xlog_recover_do_reg_buffer(
/* Shouldn't be any more regions */ /* Shouldn't be any more regions */
ASSERT(i == item->ri_total); ASSERT(i == item->ri_total);
xlog_recovery_validate_buf_type(mp, bp, buf_f); /*
* We can only do post recovery validation on items on CRC enabled
* fielsystems as we need to know when the buffer was written to be able
* to determine if we should have replayed the item. If we replay old
* metadata over a newer buffer, then it will enter a temporarily
* inconsistent state resulting in verification failures. Hence for now
* just avoid the verification stage for non-crc filesystems
*/
if (xfs_sb_version_hascrc(&mp->m_sb))
xlog_recovery_validate_buf_type(mp, bp, buf_f);
} }
/* /*
......
...@@ -314,7 +314,8 @@ STATIC int ...@@ -314,7 +314,8 @@ STATIC int
xfs_mount_validate_sb( xfs_mount_validate_sb(
xfs_mount_t *mp, xfs_mount_t *mp,
xfs_sb_t *sbp, xfs_sb_t *sbp,
bool check_inprogress) bool check_inprogress,
bool check_version)
{ {
/* /*
...@@ -337,9 +338,10 @@ xfs_mount_validate_sb( ...@@ -337,9 +338,10 @@ xfs_mount_validate_sb(
/* /*
* Version 5 superblock feature mask validation. Reject combinations the * Version 5 superblock feature mask validation. Reject combinations the
* kernel cannot support up front before checking anything else. * kernel cannot support up front before checking anything else. For
* write validation, we don't need to check feature masks.
*/ */
if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) { if (check_version && XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) {
xfs_alert(mp, xfs_alert(mp,
"Version 5 superblock detected. This kernel has EXPERIMENTAL support enabled!\n" "Version 5 superblock detected. This kernel has EXPERIMENTAL support enabled!\n"
"Use of these features in this kernel is at your own risk!"); "Use of these features in this kernel is at your own risk!");
...@@ -675,7 +677,8 @@ xfs_sb_to_disk( ...@@ -675,7 +677,8 @@ xfs_sb_to_disk(
static int static int
xfs_sb_verify( xfs_sb_verify(
struct xfs_buf *bp) struct xfs_buf *bp,
bool check_version)
{ {
struct xfs_mount *mp = bp->b_target->bt_mount; struct xfs_mount *mp = bp->b_target->bt_mount;
struct xfs_sb sb; struct xfs_sb sb;
...@@ -686,7 +689,8 @@ xfs_sb_verify( ...@@ -686,7 +689,8 @@ xfs_sb_verify(
* Only check the in progress field for the primary superblock as * Only check the in progress field for the primary superblock as
* mkfs.xfs doesn't clear it from secondary superblocks. * mkfs.xfs doesn't clear it from secondary superblocks.
*/ */
return xfs_mount_validate_sb(mp, &sb, bp->b_bn == XFS_SB_DADDR); return xfs_mount_validate_sb(mp, &sb, bp->b_bn == XFS_SB_DADDR,
check_version);
} }
/* /*
...@@ -719,7 +723,7 @@ xfs_sb_read_verify( ...@@ -719,7 +723,7 @@ xfs_sb_read_verify(
goto out_error; goto out_error;
} }
} }
error = xfs_sb_verify(bp); error = xfs_sb_verify(bp, true);
out_error: out_error:
if (error) { if (error) {
...@@ -758,7 +762,7 @@ xfs_sb_write_verify( ...@@ -758,7 +762,7 @@ xfs_sb_write_verify(
struct xfs_buf_log_item *bip = bp->b_fspriv; struct xfs_buf_log_item *bip = bp->b_fspriv;
int error; int error;
error = xfs_sb_verify(bp); error = xfs_sb_verify(bp, false);
if (error) { if (error) {
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr); XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
xfs_buf_ioerror(bp, error); xfs_buf_ioerror(bp, error);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment