forked from Minki/linux
xfs: add buffer types to directory and attribute buffers
Add buffer types to the buffer log items so that log recovery can validate the buffers and calculate CRCs correctly after the buffers are recovered. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Ben Myers <bpm@sgi.com> Signed-off-by: Ben Myers <bpm@sgi.com>
This commit is contained in:
parent
d2e448d5fd
commit
d75afeb3d3
@ -271,8 +271,13 @@ xfs_attr3_leaf_read(
|
||||
xfs_daddr_t mappedbno,
|
||||
struct xfs_buf **bpp)
|
||||
{
|
||||
return xfs_da_read_buf(tp, dp, bno, mappedbno, bpp,
|
||||
int err;
|
||||
|
||||
err = xfs_da_read_buf(tp, dp, bno, mappedbno, bpp,
|
||||
XFS_ATTR_FORK, &xfs_attr3_leaf_buf_ops);
|
||||
if (!err && tp)
|
||||
xfs_trans_buf_set_type(tp, *bpp, XFS_BLF_ATTR_LEAF_BUF);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*========================================================================
|
||||
@ -1078,6 +1083,7 @@ xfs_attr3_leaf_to_node(
|
||||
goto out;
|
||||
|
||||
/* copy leaf to new buffer, update identifiers */
|
||||
xfs_trans_buf_set_type(args->trans, bp2, XFS_BLF_ATTR_LEAF_BUF);
|
||||
bp2->b_ops = bp1->b_ops;
|
||||
memcpy(bp2->b_addr, bp1->b_addr, XFS_LBSIZE(mp));
|
||||
if (xfs_sb_version_hascrc(&mp->m_sb)) {
|
||||
@ -1140,6 +1146,7 @@ xfs_attr3_leaf_create(
|
||||
if (error)
|
||||
return error;
|
||||
bp->b_ops = &xfs_attr3_leaf_buf_ops;
|
||||
xfs_trans_buf_set_type(args->trans, bp, XFS_BLF_ATTR_LEAF_BUF);
|
||||
leaf = bp->b_addr;
|
||||
memset(leaf, 0, XFS_LBSIZE(mp));
|
||||
|
||||
|
@ -37,6 +37,8 @@ struct xfs_attr3_rmt_hdr {
|
||||
((bufsize) - (xfs_sb_version_hascrc(&(mp)->m_sb) ? \
|
||||
sizeof(struct xfs_attr3_rmt_hdr) : 0))
|
||||
|
||||
extern const struct xfs_buf_ops xfs_attr3_rmt_buf_ops;
|
||||
|
||||
int xfs_attr_rmtval_get(struct xfs_da_args *args);
|
||||
int xfs_attr_rmtval_set(struct xfs_da_args *args);
|
||||
int xfs_attr_rmtval_remove(struct xfs_da_args *args);
|
||||
|
@ -50,6 +50,14 @@ extern kmem_zone_t *xfs_buf_item_zone;
|
||||
#define XFS_BLF_AGI_BUF (1<<8)
|
||||
#define XFS_BLF_DINO_BUF (1<<9)
|
||||
#define XFS_BLF_SYMLINK_BUF (1<<10)
|
||||
#define XFS_BLF_DIR_BLOCK_BUF (1<<11)
|
||||
#define XFS_BLF_DIR_DATA_BUF (1<<12)
|
||||
#define XFS_BLF_DIR_FREE_BUF (1<<13)
|
||||
#define XFS_BLF_DIR_LEAF1_BUF (1<<14)
|
||||
#define XFS_BLF_DIR_LEAFN_BUF (1<<15)
|
||||
#define XFS_BLF_DA_NODE_BUF (1<<16)
|
||||
#define XFS_BLF_ATTR_LEAF_BUF (1<<17)
|
||||
#define XFS_BLF_ATTR_RMT_BUF (1<<18)
|
||||
|
||||
#define XFS_BLF_TYPE_MASK \
|
||||
(XFS_BLF_UDQUOT_BUF | \
|
||||
@ -60,7 +68,15 @@ extern kmem_zone_t *xfs_buf_item_zone;
|
||||
XFS_BLF_AGFL_BUF | \
|
||||
XFS_BLF_AGI_BUF | \
|
||||
XFS_BLF_DINO_BUF | \
|
||||
XFS_BLF_SYMLINK_BUF)
|
||||
XFS_BLF_SYMLINK_BUF | \
|
||||
XFS_BLF_DIR_BLOCK_BUF | \
|
||||
XFS_BLF_DIR_DATA_BUF | \
|
||||
XFS_BLF_DIR_FREE_BUF | \
|
||||
XFS_BLF_DIR_LEAF1_BUF | \
|
||||
XFS_BLF_DIR_LEAFN_BUF | \
|
||||
XFS_BLF_DA_NODE_BUF | \
|
||||
XFS_BLF_ATTR_LEAF_BUF | \
|
||||
XFS_BLF_ATTR_RMT_BUF)
|
||||
|
||||
#define XFS_BLF_CHUNK 128
|
||||
#define XFS_BLF_SHIFT 7
|
||||
|
@ -292,7 +292,6 @@ const struct xfs_buf_ops xfs_da3_node_buf_ops = {
|
||||
.verify_write = xfs_da3_node_write_verify,
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
xfs_da3_node_read(
|
||||
struct xfs_trans *tp,
|
||||
@ -302,8 +301,35 @@ xfs_da3_node_read(
|
||||
struct xfs_buf **bpp,
|
||||
int which_fork)
|
||||
{
|
||||
return xfs_da_read_buf(tp, dp, bno, mappedbno, bpp,
|
||||
int err;
|
||||
|
||||
err = xfs_da_read_buf(tp, dp, bno, mappedbno, bpp,
|
||||
which_fork, &xfs_da3_node_buf_ops);
|
||||
if (!err && tp) {
|
||||
struct xfs_da_blkinfo *info = (*bpp)->b_addr;
|
||||
int type;
|
||||
|
||||
switch (be16_to_cpu(info->magic)) {
|
||||
case XFS_DA3_NODE_MAGIC:
|
||||
case XFS_DA_NODE_MAGIC:
|
||||
type = XFS_BLF_DA_NODE_BUF;
|
||||
break;
|
||||
case XFS_ATTR_LEAF_MAGIC:
|
||||
case XFS_ATTR3_LEAF_MAGIC:
|
||||
type = XFS_BLF_ATTR_LEAF_BUF;
|
||||
break;
|
||||
case XFS_DIR2_LEAFN_MAGIC:
|
||||
case XFS_DIR3_LEAFN_MAGIC:
|
||||
type = XFS_BLF_DIR_LEAFN_BUF;
|
||||
break;
|
||||
default:
|
||||
type = 0;
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
xfs_trans_buf_set_type(tp, *bpp, type);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
/*========================================================================
|
||||
@ -334,6 +360,8 @@ xfs_da3_node_create(
|
||||
error = xfs_da_get_buf(tp, args->dp, blkno, -1, &bp, whichfork);
|
||||
if (error)
|
||||
return(error);
|
||||
bp->b_ops = &xfs_da3_node_buf_ops;
|
||||
xfs_trans_buf_set_type(tp, bp, XFS_BLF_DA_NODE_BUF);
|
||||
node = bp->b_addr;
|
||||
|
||||
if (xfs_sb_version_hascrc(&mp->m_sb)) {
|
||||
@ -352,7 +380,6 @@ xfs_da3_node_create(
|
||||
xfs_trans_log_buf(tp, bp,
|
||||
XFS_DA_LOGRANGE(node, &node->hdr, xfs_da3_node_hdr_size(node)));
|
||||
|
||||
bp->b_ops = &xfs_da3_node_buf_ops;
|
||||
*bpp = bp;
|
||||
return(0);
|
||||
}
|
||||
@ -565,6 +592,12 @@ xfs_da3_root_split(
|
||||
btree = xfs_da3_node_tree_p(oldroot);
|
||||
size = (int)((char *)&btree[nodehdr.count] - (char *)oldroot);
|
||||
level = nodehdr.level;
|
||||
|
||||
/*
|
||||
* we are about to copy oldroot to bp, so set up the type
|
||||
* of bp while we know exactly what it will be.
|
||||
*/
|
||||
xfs_trans_buf_set_type(tp, bp, XFS_BLF_DA_NODE_BUF);
|
||||
} else {
|
||||
struct xfs_dir3_icleaf_hdr leafhdr;
|
||||
struct xfs_dir2_leaf_entry *ents;
|
||||
@ -577,6 +610,12 @@ xfs_da3_root_split(
|
||||
leafhdr.magic == XFS_DIR3_LEAFN_MAGIC);
|
||||
size = (int)((char *)&ents[leafhdr.count] - (char *)leaf);
|
||||
level = 0;
|
||||
|
||||
/*
|
||||
* we are about to copy oldroot to bp, so set up the type
|
||||
* of bp while we know exactly what it will be.
|
||||
*/
|
||||
xfs_trans_buf_set_type(tp, bp, XFS_BLF_DIR_LEAFN_BUF);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1092,6 +1131,7 @@ xfs_da3_root_join(
|
||||
*/
|
||||
memcpy(root_blk->bp->b_addr, bp->b_addr, state->blocksize);
|
||||
root_blk->bp->b_ops = bp->b_ops;
|
||||
xfs_trans_buf_copy_type(root_blk->bp, bp);
|
||||
if (oldroothdr.magic == XFS_DA3_NODE_MAGIC) {
|
||||
struct xfs_da3_blkinfo *da3 = root_blk->bp->b_addr;
|
||||
da3->blkno = cpu_to_be64(root_blk->bp->b_bn);
|
||||
|
@ -301,6 +301,8 @@ int xfs_da3_node_read(struct xfs_trans *tp, struct xfs_inode *dp,
|
||||
xfs_dablk_t bno, xfs_daddr_t mappedbno,
|
||||
struct xfs_buf **bpp, int which_fork);
|
||||
|
||||
extern const struct xfs_buf_ops xfs_da3_node_buf_ops;
|
||||
|
||||
/*
|
||||
* Utility routines.
|
||||
*/
|
||||
|
@ -132,20 +132,26 @@ xfs_dir3_block_read(
|
||||
struct xfs_buf **bpp)
|
||||
{
|
||||
struct xfs_mount *mp = dp->i_mount;
|
||||
int err;
|
||||
|
||||
return xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, bpp,
|
||||
err = xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, bpp,
|
||||
XFS_DATA_FORK, &xfs_dir3_block_buf_ops);
|
||||
if (!err && tp)
|
||||
xfs_trans_buf_set_type(tp, *bpp, XFS_BLF_DIR_BLOCK_BUF);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void
|
||||
xfs_dir3_block_init(
|
||||
struct xfs_mount *mp,
|
||||
struct xfs_trans *tp,
|
||||
struct xfs_buf *bp,
|
||||
struct xfs_inode *dp)
|
||||
{
|
||||
struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
|
||||
|
||||
bp->b_ops = &xfs_dir3_block_buf_ops;
|
||||
xfs_trans_buf_set_type(tp, bp, XFS_BLF_DIR_BLOCK_BUF);
|
||||
|
||||
if (xfs_sb_version_hascrc(&mp->m_sb)) {
|
||||
memset(hdr3, 0, sizeof(*hdr3));
|
||||
@ -1080,7 +1086,7 @@ xfs_dir2_leaf_to_block(
|
||||
/*
|
||||
* Start converting it to block form.
|
||||
*/
|
||||
xfs_dir3_block_init(mp, dbp, dp);
|
||||
xfs_dir3_block_init(mp, tp, dbp, dp);
|
||||
|
||||
needlog = 1;
|
||||
needscan = 0;
|
||||
@ -1209,7 +1215,7 @@ xfs_dir2_sf_to_block(
|
||||
kmem_free(sfp);
|
||||
return error;
|
||||
}
|
||||
xfs_dir3_block_init(mp, bp, dp);
|
||||
xfs_dir3_block_init(mp, tp, bp, dp);
|
||||
hdr = bp->b_addr;
|
||||
|
||||
/*
|
||||
|
@ -301,8 +301,13 @@ xfs_dir3_data_read(
|
||||
xfs_daddr_t mapped_bno,
|
||||
struct xfs_buf **bpp)
|
||||
{
|
||||
return xfs_da_read_buf(tp, dp, bno, mapped_bno, bpp,
|
||||
int err;
|
||||
|
||||
err = xfs_da_read_buf(tp, dp, bno, mapped_bno, bpp,
|
||||
XFS_DATA_FORK, &xfs_dir3_data_buf_ops);
|
||||
if (!err && tp)
|
||||
xfs_trans_buf_set_type(tp, *bpp, XFS_BLF_DIR_DATA_BUF);
|
||||
return err;
|
||||
}
|
||||
|
||||
int
|
||||
@ -571,6 +576,7 @@ xfs_dir3_data_init(
|
||||
if (error)
|
||||
return error;
|
||||
bp->b_ops = &xfs_dir3_data_buf_ops;
|
||||
xfs_trans_buf_set_type(tp, bp, XFS_BLF_DIR_DATA_BUF);
|
||||
|
||||
/*
|
||||
* Initialize the header.
|
||||
|
@ -279,7 +279,7 @@ xfs_dir3_leafn_write_verify(
|
||||
__write_verify(bp, XFS_DIR2_LEAFN_MAGIC);
|
||||
}
|
||||
|
||||
static const struct xfs_buf_ops xfs_dir3_leaf1_buf_ops = {
|
||||
const struct xfs_buf_ops xfs_dir3_leaf1_buf_ops = {
|
||||
.verify_read = xfs_dir3_leaf1_read_verify,
|
||||
.verify_write = xfs_dir3_leaf1_write_verify,
|
||||
};
|
||||
@ -297,8 +297,13 @@ xfs_dir3_leaf_read(
|
||||
xfs_daddr_t mappedbno,
|
||||
struct xfs_buf **bpp)
|
||||
{
|
||||
return xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp,
|
||||
int err;
|
||||
|
||||
err = xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp,
|
||||
XFS_DATA_FORK, &xfs_dir3_leaf1_buf_ops);
|
||||
if (!err && tp)
|
||||
xfs_trans_buf_set_type(tp, *bpp, XFS_BLF_DIR_LEAF1_BUF);
|
||||
return err;
|
||||
}
|
||||
|
||||
int
|
||||
@ -309,8 +314,13 @@ xfs_dir3_leafn_read(
|
||||
xfs_daddr_t mappedbno,
|
||||
struct xfs_buf **bpp)
|
||||
{
|
||||
return xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp,
|
||||
int err;
|
||||
|
||||
err = xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp,
|
||||
XFS_DATA_FORK, &xfs_dir3_leafn_buf_ops);
|
||||
if (!err && tp)
|
||||
xfs_trans_buf_set_type(tp, *bpp, XFS_BLF_DIR_LEAFN_BUF);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -319,6 +329,7 @@ xfs_dir3_leafn_read(
|
||||
static void
|
||||
xfs_dir3_leaf_init(
|
||||
struct xfs_mount *mp,
|
||||
struct xfs_trans *tp,
|
||||
struct xfs_buf *bp,
|
||||
xfs_ino_t owner,
|
||||
__uint16_t type)
|
||||
@ -353,8 +364,11 @@ xfs_dir3_leaf_init(
|
||||
ltp = xfs_dir2_leaf_tail_p(mp, leaf);
|
||||
ltp->bestcount = 0;
|
||||
bp->b_ops = &xfs_dir3_leaf1_buf_ops;
|
||||
} else
|
||||
xfs_trans_buf_set_type(tp, bp, XFS_BLF_DIR_LEAF1_BUF);
|
||||
} else {
|
||||
bp->b_ops = &xfs_dir3_leafn_buf_ops;
|
||||
xfs_trans_buf_set_type(tp, bp, XFS_BLF_DIR_LEAFN_BUF);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
@ -379,7 +393,7 @@ xfs_dir3_leaf_get_buf(
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
xfs_dir3_leaf_init(mp, bp, dp->i_ino, magic);
|
||||
xfs_dir3_leaf_init(mp, tp, bp, dp->i_ino, magic);
|
||||
xfs_dir3_leaf_log_header(tp, bp);
|
||||
if (magic == XFS_DIR2_LEAF1_MAGIC)
|
||||
xfs_dir3_leaf_log_tail(tp, bp);
|
||||
@ -474,6 +488,7 @@ xfs_dir2_block_to_leaf(
|
||||
* Fix up the block header, make it a data block.
|
||||
*/
|
||||
dbp->b_ops = &xfs_dir3_data_buf_ops;
|
||||
xfs_trans_buf_set_type(tp, dbp, XFS_BLF_DIR_DATA_BUF);
|
||||
if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC))
|
||||
hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC);
|
||||
else
|
||||
@ -2182,6 +2197,7 @@ xfs_dir2_node_to_leaf(
|
||||
xfs_dir3_leaf_compact(args, &leafhdr, lbp);
|
||||
|
||||
lbp->b_ops = &xfs_dir3_leaf1_buf_ops;
|
||||
xfs_trans_buf_set_type(tp, lbp, XFS_BLF_DIR_LEAF1_BUF);
|
||||
leafhdr.magic = (leafhdr.magic == XFS_DIR2_LEAFN_MAGIC)
|
||||
? XFS_DIR2_LEAF1_MAGIC
|
||||
: XFS_DIR3_LEAF1_MAGIC;
|
||||
|
@ -147,7 +147,7 @@ xfs_dir3_free_write_verify(
|
||||
xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length), XFS_DIR3_FREE_CRC_OFF);
|
||||
}
|
||||
|
||||
static const struct xfs_buf_ops xfs_dir3_free_buf_ops = {
|
||||
const struct xfs_buf_ops xfs_dir3_free_buf_ops = {
|
||||
.verify_read = xfs_dir3_free_read_verify,
|
||||
.verify_write = xfs_dir3_free_write_verify,
|
||||
};
|
||||
@ -161,8 +161,15 @@ __xfs_dir3_free_read(
|
||||
xfs_daddr_t mappedbno,
|
||||
struct xfs_buf **bpp)
|
||||
{
|
||||
return xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp,
|
||||
int err;
|
||||
|
||||
err = xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp,
|
||||
XFS_DATA_FORK, &xfs_dir3_free_buf_ops);
|
||||
|
||||
/* try read returns without an error or *bpp if it lands in a hole */
|
||||
if (!err && tp && *bpp)
|
||||
xfs_trans_buf_set_type(tp, *bpp, XFS_BLF_DIR_FREE_BUF);
|
||||
return err;
|
||||
}
|
||||
|
||||
int
|
||||
@ -249,6 +256,7 @@ xfs_dir3_free_get_buf(
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
xfs_trans_buf_set_type(tp, bp, XFS_BLF_DIR_FREE_BUF);
|
||||
bp->b_ops = &xfs_dir3_free_buf_ops;
|
||||
|
||||
/*
|
||||
@ -396,6 +404,7 @@ xfs_dir2_leaf_to_node(
|
||||
else
|
||||
leaf->hdr.info.magic = cpu_to_be16(XFS_DIR3_LEAFN_MAGIC);
|
||||
lbp->b_ops = &xfs_dir3_leafn_buf_ops;
|
||||
xfs_trans_buf_set_type(tp, lbp, XFS_BLF_DIR_LEAFN_BUF);
|
||||
xfs_dir3_leaf_log_header(tp, lbp);
|
||||
xfs_dir3_leaf_check(mp, lbp);
|
||||
return 0;
|
||||
@ -811,6 +820,7 @@ xfs_dir2_leafn_lookup_for_entry(
|
||||
(char *)curbp->b_addr);
|
||||
state->extrablk.magic = XFS_DIR2_DATA_MAGIC;
|
||||
curbp->b_ops = &xfs_dir3_data_buf_ops;
|
||||
xfs_trans_buf_set_type(tp, curbp, XFS_BLF_DIR_DATA_BUF);
|
||||
if (cmp == XFS_CMP_EXACT)
|
||||
return XFS_ERROR(EEXIST);
|
||||
}
|
||||
@ -825,6 +835,7 @@ xfs_dir2_leafn_lookup_for_entry(
|
||||
state->extrablk.blkno = curdb;
|
||||
state->extrablk.magic = XFS_DIR2_DATA_MAGIC;
|
||||
curbp->b_ops = &xfs_dir3_data_buf_ops;
|
||||
xfs_trans_buf_set_type(tp, curbp, XFS_BLF_DIR_DATA_BUF);
|
||||
} else {
|
||||
/* If the curbp is not the CI match block, drop it */
|
||||
if (state->extrablk.bp != curbp)
|
||||
|
@ -49,6 +49,7 @@ extern int xfs_dir2_leaf_to_block(struct xfs_da_args *args,
|
||||
#endif
|
||||
|
||||
extern const struct xfs_buf_ops xfs_dir3_data_buf_ops;
|
||||
extern const struct xfs_buf_ops xfs_dir3_free_buf_ops;
|
||||
|
||||
extern int __xfs_dir3_data_check(struct xfs_inode *dp, struct xfs_buf *bp);
|
||||
extern int xfs_dir3_data_read(struct xfs_trans *tp, struct xfs_inode *dp,
|
||||
@ -77,6 +78,7 @@ extern void xfs_dir2_data_use_free(struct xfs_trans *tp, struct xfs_buf *bp,
|
||||
xfs_dir2_data_aoff_t len, int *needlogp, int *needscanp);
|
||||
|
||||
/* xfs_dir2_leaf.c */
|
||||
extern const struct xfs_buf_ops xfs_dir3_leaf1_buf_ops;
|
||||
extern const struct xfs_buf_ops xfs_dir3_leafn_buf_ops;
|
||||
|
||||
extern int xfs_dir3_leafn_read(struct xfs_trans *tp, struct xfs_inode *dp,
|
||||
|
@ -45,7 +45,14 @@
|
||||
#include "xfs_cksum.h"
|
||||
#include "xfs_trace.h"
|
||||
#include "xfs_icache.h"
|
||||
|
||||
/* Need all the magic numbers and buffer ops structures from these headers */
|
||||
#include "xfs_symlink.h"
|
||||
#include "xfs_da_btree.h"
|
||||
#include "xfs_dir2_format.h"
|
||||
#include "xfs_dir2_priv.h"
|
||||
#include "xfs_attr_leaf.h"
|
||||
#include "xfs_attr_remote.h"
|
||||
|
||||
STATIC int
|
||||
xlog_find_zeroed(
|
||||
@ -1859,6 +1866,185 @@ xlog_recover_do_inode_buffer(
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Validate the recovered buffer is of the correct type and attach the
|
||||
* appropriate buffer operations to them for writeback. Magic numbers are in a
|
||||
* few places:
|
||||
* the first 16 bits of the buffer (inode buffer, dquot buffer),
|
||||
* the first 32 bits of the buffer (most blocks),
|
||||
* inside a struct xfs_da_blkinfo at the start of the buffer.
|
||||
*/
|
||||
static void
|
||||
xlog_recovery_validate_buf_type(
|
||||
struct xfs_mount *mp,
|
||||
struct xfs_buf *bp,
|
||||
xfs_buf_log_format_t *buf_f)
|
||||
{
|
||||
struct xfs_da_blkinfo *info = bp->b_addr;
|
||||
__uint32_t magic32;
|
||||
__uint16_t magic16;
|
||||
__uint16_t magicda;
|
||||
|
||||
magic32 = be32_to_cpu(*(__be32 *)bp->b_addr);
|
||||
magic16 = be16_to_cpu(*(__be16*)bp->b_addr);
|
||||
magicda = be16_to_cpu(info->magic);
|
||||
switch (buf_f->blf_flags & XFS_BLF_TYPE_MASK) {
|
||||
case XFS_BLF_BTREE_BUF:
|
||||
switch (magic32) {
|
||||
case XFS_ABTB_CRC_MAGIC:
|
||||
case XFS_ABTC_CRC_MAGIC:
|
||||
case XFS_ABTB_MAGIC:
|
||||
case XFS_ABTC_MAGIC:
|
||||
bp->b_ops = &xfs_allocbt_buf_ops;
|
||||
break;
|
||||
case XFS_IBT_CRC_MAGIC:
|
||||
case XFS_IBT_MAGIC:
|
||||
bp->b_ops = &xfs_inobt_buf_ops;
|
||||
break;
|
||||
case XFS_BMAP_CRC_MAGIC:
|
||||
case XFS_BMAP_MAGIC:
|
||||
bp->b_ops = &xfs_bmbt_buf_ops;
|
||||
break;
|
||||
default:
|
||||
xfs_warn(mp, "Bad btree block magic!");
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case XFS_BLF_AGF_BUF:
|
||||
if (magic32 != XFS_AGF_MAGIC) {
|
||||
xfs_warn(mp, "Bad AGF block magic!");
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
bp->b_ops = &xfs_agf_buf_ops;
|
||||
break;
|
||||
case XFS_BLF_AGFL_BUF:
|
||||
if (!xfs_sb_version_hascrc(&mp->m_sb))
|
||||
break;
|
||||
if (magic32 != XFS_AGFL_MAGIC) {
|
||||
xfs_warn(mp, "Bad AGFL block magic!");
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
bp->b_ops = &xfs_agfl_buf_ops;
|
||||
break;
|
||||
case XFS_BLF_AGI_BUF:
|
||||
if (magic32 != XFS_AGI_MAGIC) {
|
||||
xfs_warn(mp, "Bad AGI block magic!");
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
bp->b_ops = &xfs_agi_buf_ops;
|
||||
break;
|
||||
case XFS_BLF_UDQUOT_BUF:
|
||||
case XFS_BLF_PDQUOT_BUF:
|
||||
case XFS_BLF_GDQUOT_BUF:
|
||||
if (magic16 != XFS_DQUOT_MAGIC) {
|
||||
xfs_warn(mp, "Bad DQUOT block magic!");
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
bp->b_ops = &xfs_dquot_buf_ops;
|
||||
break;
|
||||
case XFS_BLF_DINO_BUF:
|
||||
/*
|
||||
* we get here with inode allocation buffers, not buffers that
|
||||
* track unlinked list changes.
|
||||
*/
|
||||
if (magic16 != XFS_DINODE_MAGIC) {
|
||||
xfs_warn(mp, "Bad INODE block magic!");
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
bp->b_ops = &xfs_inode_buf_ops;
|
||||
break;
|
||||
case XFS_BLF_SYMLINK_BUF:
|
||||
if (magic32 != XFS_SYMLINK_MAGIC) {
|
||||
xfs_warn(mp, "Bad symlink block magic!");
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
bp->b_ops = &xfs_symlink_buf_ops;
|
||||
break;
|
||||
case XFS_BLF_DIR_BLOCK_BUF:
|
||||
if (magic32 != XFS_DIR2_BLOCK_MAGIC &&
|
||||
magic32 != XFS_DIR3_BLOCK_MAGIC) {
|
||||
xfs_warn(mp, "Bad dir block magic!");
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
bp->b_ops = &xfs_dir3_block_buf_ops;
|
||||
break;
|
||||
case XFS_BLF_DIR_DATA_BUF:
|
||||
if (magic32 != XFS_DIR2_DATA_MAGIC &&
|
||||
magic32 != XFS_DIR3_DATA_MAGIC) {
|
||||
xfs_warn(mp, "Bad dir data magic!");
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
bp->b_ops = &xfs_dir3_data_buf_ops;
|
||||
break;
|
||||
case XFS_BLF_DIR_FREE_BUF:
|
||||
if (magic32 != XFS_DIR2_FREE_MAGIC &&
|
||||
magic32 != XFS_DIR3_FREE_MAGIC) {
|
||||
xfs_warn(mp, "Bad dir3 free magic!");
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
bp->b_ops = &xfs_dir3_free_buf_ops;
|
||||
break;
|
||||
case XFS_BLF_DIR_LEAF1_BUF:
|
||||
if (magicda != XFS_DIR2_LEAF1_MAGIC &&
|
||||
magicda != XFS_DIR3_LEAF1_MAGIC) {
|
||||
xfs_warn(mp, "Bad dir leaf1 magic!");
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
bp->b_ops = &xfs_dir3_leaf1_buf_ops;
|
||||
break;
|
||||
case XFS_BLF_DIR_LEAFN_BUF:
|
||||
if (magicda != XFS_DIR2_LEAFN_MAGIC &&
|
||||
magicda != XFS_DIR3_LEAFN_MAGIC) {
|
||||
xfs_warn(mp, "Bad dir leafn magic!");
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
bp->b_ops = &xfs_dir3_leafn_buf_ops;
|
||||
break;
|
||||
case XFS_BLF_DA_NODE_BUF:
|
||||
if (magicda != XFS_DA_NODE_MAGIC &&
|
||||
magicda != XFS_DA3_NODE_MAGIC) {
|
||||
xfs_warn(mp, "Bad da node magic!");
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
bp->b_ops = &xfs_da3_node_buf_ops;
|
||||
break;
|
||||
case XFS_BLF_ATTR_LEAF_BUF:
|
||||
if (magicda != XFS_ATTR_LEAF_MAGIC &&
|
||||
magicda != XFS_ATTR3_LEAF_MAGIC) {
|
||||
xfs_warn(mp, "Bad attr leaf magic!");
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
bp->b_ops = &xfs_attr3_leaf_buf_ops;
|
||||
break;
|
||||
case XFS_BLF_ATTR_RMT_BUF:
|
||||
if (!xfs_sb_version_hascrc(&mp->m_sb))
|
||||
break;
|
||||
if (magicda != XFS_ATTR3_RMT_MAGIC) {
|
||||
xfs_warn(mp, "Bad attr remote magic!");
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
bp->b_ops = &xfs_attr3_rmt_buf_ops;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform a 'normal' buffer recovery. Each logged region of the
|
||||
* buffer should be copied over the corresponding region in the
|
||||
@ -1932,88 +2118,8 @@ xlog_recover_do_reg_buffer(
|
||||
/* Shouldn't be any more regions */
|
||||
ASSERT(i == item->ri_total);
|
||||
|
||||
switch (buf_f->blf_flags & XFS_BLF_TYPE_MASK) {
|
||||
case XFS_BLF_BTREE_BUF:
|
||||
switch (be32_to_cpu(*(__be32 *)bp->b_addr)) {
|
||||
case XFS_ABTB_CRC_MAGIC:
|
||||
case XFS_ABTC_CRC_MAGIC:
|
||||
case XFS_ABTB_MAGIC:
|
||||
case XFS_ABTC_MAGIC:
|
||||
bp->b_ops = &xfs_allocbt_buf_ops;
|
||||
break;
|
||||
case XFS_IBT_CRC_MAGIC:
|
||||
case XFS_IBT_MAGIC:
|
||||
bp->b_ops = &xfs_inobt_buf_ops;
|
||||
break;
|
||||
case XFS_BMAP_CRC_MAGIC:
|
||||
case XFS_BMAP_MAGIC:
|
||||
bp->b_ops = &xfs_bmbt_buf_ops;
|
||||
break;
|
||||
default:
|
||||
xfs_warn(mp, "Bad btree block magic!");
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case XFS_BLF_AGF_BUF:
|
||||
if (*(__be32 *)bp->b_addr != cpu_to_be32(XFS_AGF_MAGIC)) {
|
||||
xfs_warn(mp, "Bad AGF block magic!");
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
bp->b_ops = &xfs_agf_buf_ops;
|
||||
break;
|
||||
case XFS_BLF_AGFL_BUF:
|
||||
if (!xfs_sb_version_hascrc(&mp->m_sb))
|
||||
break;
|
||||
if (*(__be32 *)bp->b_addr != cpu_to_be32(XFS_AGFL_MAGIC)) {
|
||||
xfs_warn(mp, "Bad AGFL block magic!");
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
bp->b_ops = &xfs_agfl_buf_ops;
|
||||
break;
|
||||
case XFS_BLF_AGI_BUF:
|
||||
if (*(__be32 *)bp->b_addr != cpu_to_be32(XFS_AGI_MAGIC)) {
|
||||
xfs_warn(mp, "Bad AGI block magic!");
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
bp->b_ops = &xfs_agi_buf_ops;
|
||||
break;
|
||||
case XFS_BLF_UDQUOT_BUF:
|
||||
case XFS_BLF_PDQUOT_BUF:
|
||||
case XFS_BLF_GDQUOT_BUF:
|
||||
if (*(__be16 *)bp->b_addr != cpu_to_be16(XFS_DQUOT_MAGIC)) {
|
||||
xfs_warn(mp, "Bad DQUOT block magic!");
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
bp->b_ops = &xfs_dquot_buf_ops;
|
||||
break;
|
||||
case XFS_BLF_DINO_BUF:
|
||||
/*
|
||||
* we get here with inode allocation buffers, not buffers that
|
||||
* track unlinked list changes.
|
||||
*/
|
||||
if (*(__be16 *)bp->b_addr != cpu_to_be16(XFS_DINODE_MAGIC)) {
|
||||
xfs_warn(mp, "Bad INODE block magic!");
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
bp->b_ops = &xfs_inode_buf_ops;
|
||||
break;
|
||||
case XFS_BLF_SYMLINK_BUF:
|
||||
if (*(__be32 *)bp->b_addr != cpu_to_be32(XFS_SYMLINK_MAGIC)) {
|
||||
xfs_warn(mp, "Bad symlink block magic!");
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
bp->b_ops = &xfs_symlink_buf_ops;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
xlog_recovery_validate_buf_type(mp, bp, buf_f);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -507,6 +507,8 @@ void xfs_trans_dquot_buf(xfs_trans_t *, struct xfs_buf *, uint);
|
||||
void xfs_trans_inode_alloc_buf(xfs_trans_t *, struct xfs_buf *);
|
||||
void xfs_trans_buf_set_type(struct xfs_trans *, struct xfs_buf *,
|
||||
uint);
|
||||
void xfs_trans_buf_copy_type(struct xfs_buf *dst_bp,
|
||||
struct xfs_buf *src_bp);
|
||||
void xfs_trans_ichgtime(struct xfs_trans *, struct xfs_inode *, int);
|
||||
void xfs_trans_ijoin(struct xfs_trans *, struct xfs_inode *, uint);
|
||||
void xfs_trans_log_buf(xfs_trans_t *, struct xfs_buf *, uint, uint);
|
||||
|
@ -768,6 +768,9 @@ xfs_trans_buf_set_type(
|
||||
{
|
||||
struct xfs_buf_log_item *bip = bp->b_fspriv;
|
||||
|
||||
if (!tp)
|
||||
return;
|
||||
|
||||
ASSERT(bp->b_transp == tp);
|
||||
ASSERT(bip != NULL);
|
||||
ASSERT(atomic_read(&bip->bli_refcount) > 0);
|
||||
@ -777,6 +780,20 @@ xfs_trans_buf_set_type(
|
||||
bip->__bli_format.blf_flags |= type;
|
||||
}
|
||||
|
||||
void
|
||||
xfs_trans_buf_copy_type(
|
||||
struct xfs_buf *dst_bp,
|
||||
struct xfs_buf *src_bp)
|
||||
{
|
||||
struct xfs_buf_log_item *sbip = src_bp->b_fspriv;
|
||||
struct xfs_buf_log_item *dbip = dst_bp->b_fspriv;
|
||||
uint type;
|
||||
|
||||
type = sbip->__bli_format.blf_flags & XFS_BLF_TYPE_MASK;
|
||||
dbip->__bli_format.blf_flags &= ~XFS_BLF_TYPE_MASK;
|
||||
dbip->__bli_format.blf_flags |= type;
|
||||
}
|
||||
|
||||
/*
|
||||
* Similar to xfs_trans_inode_buf(), this marks the buffer as a cluster of
|
||||
* dquots. However, unlike in inode buffer recovery, dquot buffers get
|
||||
|
Loading…
Reference in New Issue
Block a user