mirror of https://gitee.com/openkylin/linux.git
xfs: add CRCs to attr leaf blocks
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
f5ea110044
commit
517c22207b
|
@ -819,7 +819,7 @@ xfs_attr_inactive(xfs_inode_t *dp)
|
|||
error = 0;
|
||||
goto out;
|
||||
}
|
||||
error = xfs_attr_root_inactive(&trans, dp);
|
||||
error = xfs_attr3_root_inactive(&trans, dp);
|
||||
if (error)
|
||||
goto out;
|
||||
|
||||
|
@ -905,7 +905,7 @@ xfs_attr_leaf_addname(xfs_da_args_t *args)
|
|||
*/
|
||||
dp = args->dp;
|
||||
args->blkno = 0;
|
||||
error = xfs_attr_leaf_read(args->trans, args->dp, args->blkno, -1, &bp);
|
||||
error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, -1, &bp);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
|
@ -913,14 +913,14 @@ xfs_attr_leaf_addname(xfs_da_args_t *args)
|
|||
* Look up the given attribute in the leaf block. Figure out if
|
||||
* the given flags produce an error or call for an atomic rename.
|
||||
*/
|
||||
retval = xfs_attr_leaf_lookup_int(bp, args);
|
||||
retval = xfs_attr3_leaf_lookup_int(bp, args);
|
||||
if ((args->flags & ATTR_REPLACE) && (retval == ENOATTR)) {
|
||||
xfs_trans_brelse(args->trans, bp);
|
||||
return(retval);
|
||||
return retval;
|
||||
} else if (retval == EEXIST) {
|
||||
if (args->flags & ATTR_CREATE) { /* pure create op */
|
||||
xfs_trans_brelse(args->trans, bp);
|
||||
return(retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
trace_xfs_attr_leaf_replace(args);
|
||||
|
@ -936,7 +936,7 @@ xfs_attr_leaf_addname(xfs_da_args_t *args)
|
|||
* Add the attribute to the leaf block, transitioning to a Btree
|
||||
* if required.
|
||||
*/
|
||||
retval = xfs_attr_leaf_add(bp, args);
|
||||
retval = xfs_attr3_leaf_add(bp, args);
|
||||
if (retval == ENOSPC) {
|
||||
/*
|
||||
* Promote the attribute list to the Btree format, then
|
||||
|
@ -944,7 +944,7 @@ xfs_attr_leaf_addname(xfs_da_args_t *args)
|
|||
* can manage its own transactions.
|
||||
*/
|
||||
xfs_bmap_init(args->flist, args->firstblock);
|
||||
error = xfs_attr_leaf_to_node(args);
|
||||
error = xfs_attr3_leaf_to_node(args);
|
||||
if (!error) {
|
||||
error = xfs_bmap_finish(&args->trans, args->flist,
|
||||
&committed);
|
||||
|
@ -1009,7 +1009,7 @@ xfs_attr_leaf_addname(xfs_da_args_t *args)
|
|||
* In a separate transaction, set the incomplete flag on the
|
||||
* "old" attr and clear the incomplete flag on the "new" attr.
|
||||
*/
|
||||
error = xfs_attr_leaf_flipflags(args);
|
||||
error = xfs_attr3_leaf_flipflags(args);
|
||||
if (error)
|
||||
return(error);
|
||||
|
||||
|
@ -1031,19 +1031,19 @@ xfs_attr_leaf_addname(xfs_da_args_t *args)
|
|||
* Read in the block containing the "old" attr, then
|
||||
* remove the "old" attr from that block (neat, huh!)
|
||||
*/
|
||||
error = xfs_attr_leaf_read(args->trans, args->dp, args->blkno,
|
||||
error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno,
|
||||
-1, &bp);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
xfs_attr_leaf_remove(bp, args);
|
||||
xfs_attr3_leaf_remove(bp, args);
|
||||
|
||||
/*
|
||||
* If the result is small enough, shrink it all into the inode.
|
||||
*/
|
||||
if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) {
|
||||
xfs_bmap_init(args->flist, args->firstblock);
|
||||
error = xfs_attr_leaf_to_shortform(bp, args, forkoff);
|
||||
error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
|
||||
/* bp is gone due to xfs_da_shrink_inode */
|
||||
if (!error) {
|
||||
error = xfs_bmap_finish(&args->trans,
|
||||
|
@ -1075,9 +1075,9 @@ xfs_attr_leaf_addname(xfs_da_args_t *args)
|
|||
/*
|
||||
* Added a "remote" value, just clear the incomplete flag.
|
||||
*/
|
||||
error = xfs_attr_leaf_clearflag(args);
|
||||
error = xfs_attr3_leaf_clearflag(args);
|
||||
}
|
||||
return(error);
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1100,24 +1100,24 @@ xfs_attr_leaf_removename(xfs_da_args_t *args)
|
|||
*/
|
||||
dp = args->dp;
|
||||
args->blkno = 0;
|
||||
error = xfs_attr_leaf_read(args->trans, args->dp, args->blkno, -1, &bp);
|
||||
error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, -1, &bp);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
error = xfs_attr_leaf_lookup_int(bp, args);
|
||||
error = xfs_attr3_leaf_lookup_int(bp, args);
|
||||
if (error == ENOATTR) {
|
||||
xfs_trans_brelse(args->trans, bp);
|
||||
return(error);
|
||||
return error;
|
||||
}
|
||||
|
||||
xfs_attr_leaf_remove(bp, args);
|
||||
xfs_attr3_leaf_remove(bp, args);
|
||||
|
||||
/*
|
||||
* If the result is small enough, shrink it all into the inode.
|
||||
*/
|
||||
if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) {
|
||||
xfs_bmap_init(args->flist, args->firstblock);
|
||||
error = xfs_attr_leaf_to_shortform(bp, args, forkoff);
|
||||
error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
|
||||
/* bp is gone due to xfs_da_shrink_inode */
|
||||
if (!error) {
|
||||
error = xfs_bmap_finish(&args->trans, args->flist,
|
||||
|
@ -1127,7 +1127,7 @@ xfs_attr_leaf_removename(xfs_da_args_t *args)
|
|||
ASSERT(committed);
|
||||
args->trans = NULL;
|
||||
xfs_bmap_cancel(args->flist);
|
||||
return(error);
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1137,7 +1137,7 @@ xfs_attr_leaf_removename(xfs_da_args_t *args)
|
|||
if (committed)
|
||||
xfs_trans_ijoin(args->trans, dp, 0);
|
||||
}
|
||||
return(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1155,21 +1155,21 @@ xfs_attr_leaf_get(xfs_da_args_t *args)
|
|||
trace_xfs_attr_leaf_get(args);
|
||||
|
||||
args->blkno = 0;
|
||||
error = xfs_attr_leaf_read(args->trans, args->dp, args->blkno, -1, &bp);
|
||||
error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, -1, &bp);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
error = xfs_attr_leaf_lookup_int(bp, args);
|
||||
error = xfs_attr3_leaf_lookup_int(bp, args);
|
||||
if (error != EEXIST) {
|
||||
xfs_trans_brelse(args->trans, bp);
|
||||
return(error);
|
||||
return error;
|
||||
}
|
||||
error = xfs_attr_leaf_getvalue(bp, args);
|
||||
error = xfs_attr3_leaf_getvalue(bp, args);
|
||||
xfs_trans_brelse(args->trans, bp);
|
||||
if (!error && (args->rmtblkno > 0) && !(args->flags & ATTR_KERNOVAL)) {
|
||||
error = xfs_attr_rmtval_get(args);
|
||||
}
|
||||
return(error);
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1184,11 +1184,11 @@ xfs_attr_leaf_list(xfs_attr_list_context_t *context)
|
|||
trace_xfs_attr_leaf_list(context);
|
||||
|
||||
context->cursor->blkno = 0;
|
||||
error = xfs_attr_leaf_read(NULL, context->dp, 0, -1, &bp);
|
||||
error = xfs_attr3_leaf_read(NULL, context->dp, 0, -1, &bp);
|
||||
if (error)
|
||||
return XFS_ERROR(error);
|
||||
|
||||
error = xfs_attr_leaf_list_int(bp, context);
|
||||
error = xfs_attr3_leaf_list_int(bp, context);
|
||||
xfs_trans_brelse(NULL, bp);
|
||||
return XFS_ERROR(error);
|
||||
}
|
||||
|
@ -1257,7 +1257,7 @@ xfs_attr_node_addname(xfs_da_args_t *args)
|
|||
args->rmtblkcnt = 0;
|
||||
}
|
||||
|
||||
retval = xfs_attr_leaf_add(blk->bp, state->args);
|
||||
retval = xfs_attr3_leaf_add(blk->bp, state->args);
|
||||
if (retval == ENOSPC) {
|
||||
if (state->path.active == 1) {
|
||||
/*
|
||||
|
@ -1267,7 +1267,7 @@ xfs_attr_node_addname(xfs_da_args_t *args)
|
|||
*/
|
||||
xfs_da_state_free(state);
|
||||
xfs_bmap_init(args->flist, args->firstblock);
|
||||
error = xfs_attr_leaf_to_node(args);
|
||||
error = xfs_attr3_leaf_to_node(args);
|
||||
if (!error) {
|
||||
error = xfs_bmap_finish(&args->trans,
|
||||
args->flist,
|
||||
|
@ -1369,7 +1369,7 @@ xfs_attr_node_addname(xfs_da_args_t *args)
|
|||
* In a separate transaction, set the incomplete flag on the
|
||||
* "old" attr and clear the incomplete flag on the "new" attr.
|
||||
*/
|
||||
error = xfs_attr_leaf_flipflags(args);
|
||||
error = xfs_attr3_leaf_flipflags(args);
|
||||
if (error)
|
||||
goto out;
|
||||
|
||||
|
@ -1408,7 +1408,7 @@ xfs_attr_node_addname(xfs_da_args_t *args)
|
|||
*/
|
||||
blk = &state->path.blk[ state->path.active-1 ];
|
||||
ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
|
||||
error = xfs_attr_leaf_remove(blk->bp, args);
|
||||
error = xfs_attr3_leaf_remove(blk->bp, args);
|
||||
xfs_da3_fixhashpath(state, &state->path);
|
||||
|
||||
/*
|
||||
|
@ -1449,7 +1449,7 @@ xfs_attr_node_addname(xfs_da_args_t *args)
|
|||
/*
|
||||
* Added a "remote" value, just clear the incomplete flag.
|
||||
*/
|
||||
error = xfs_attr_leaf_clearflag(args);
|
||||
error = xfs_attr3_leaf_clearflag(args);
|
||||
if (error)
|
||||
goto out;
|
||||
}
|
||||
|
@ -1523,7 +1523,7 @@ xfs_attr_node_removename(xfs_da_args_t *args)
|
|||
* Mark the attribute as INCOMPLETE, then bunmapi() the
|
||||
* remote value.
|
||||
*/
|
||||
error = xfs_attr_leaf_setflag(args);
|
||||
error = xfs_attr3_leaf_setflag(args);
|
||||
if (error)
|
||||
goto out;
|
||||
error = xfs_attr_rmtval_remove(args);
|
||||
|
@ -1544,7 +1544,7 @@ xfs_attr_node_removename(xfs_da_args_t *args)
|
|||
*/
|
||||
blk = &state->path.blk[ state->path.active-1 ];
|
||||
ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
|
||||
retval = xfs_attr_leaf_remove(blk->bp, args);
|
||||
retval = xfs_attr3_leaf_remove(blk->bp, args);
|
||||
xfs_da3_fixhashpath(state, &state->path);
|
||||
|
||||
/*
|
||||
|
@ -1590,13 +1590,13 @@ xfs_attr_node_removename(xfs_da_args_t *args)
|
|||
ASSERT(state->path.blk[0].bp);
|
||||
state->path.blk[0].bp = NULL;
|
||||
|
||||
error = xfs_attr_leaf_read(args->trans, args->dp, 0, -1, &bp);
|
||||
error = xfs_attr3_leaf_read(args->trans, args->dp, 0, -1, &bp);
|
||||
if (error)
|
||||
goto out;
|
||||
|
||||
if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) {
|
||||
xfs_bmap_init(args->flist, args->firstblock);
|
||||
error = xfs_attr_leaf_to_shortform(bp, args, forkoff);
|
||||
error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
|
||||
/* bp is gone due to xfs_da_shrink_inode */
|
||||
if (!error) {
|
||||
error = xfs_bmap_finish(&args->trans,
|
||||
|
@ -1768,7 +1768,7 @@ xfs_attr_node_get(xfs_da_args_t *args)
|
|||
/*
|
||||
* Get the value, local or "remote"
|
||||
*/
|
||||
retval = xfs_attr_leaf_getvalue(blk->bp, args);
|
||||
retval = xfs_attr3_leaf_getvalue(blk->bp, args);
|
||||
if (!retval && (args->rmtblkno > 0)
|
||||
&& !(args->flags & ATTR_KERNOVAL)) {
|
||||
retval = xfs_attr_rmtval_get(args);
|
||||
|
@ -1793,7 +1793,9 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
|
|||
attrlist_cursor_kern_t *cursor;
|
||||
xfs_attr_leafblock_t *leaf;
|
||||
xfs_da_intnode_t *node;
|
||||
xfs_da_node_entry_t *btree;
|
||||
struct xfs_attr3_icleaf_hdr leafhdr;
|
||||
struct xfs_da3_icnode_hdr nodehdr;
|
||||
struct xfs_da_node_entry *btree;
|
||||
int error, i;
|
||||
struct xfs_buf *bp;
|
||||
|
||||
|
@ -1814,22 +1816,28 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
|
|||
if ((error != 0) && (error != EFSCORRUPTED))
|
||||
return(error);
|
||||
if (bp) {
|
||||
struct xfs_attr_leaf_entry *entries;
|
||||
|
||||
node = bp->b_addr;
|
||||
switch (be16_to_cpu(node->hdr.info.magic)) {
|
||||
case XFS_DA_NODE_MAGIC:
|
||||
case XFS_DA3_NODE_MAGIC:
|
||||
trace_xfs_attr_list_wrong_blk(context);
|
||||
xfs_trans_brelse(NULL, bp);
|
||||
bp = NULL;
|
||||
break;
|
||||
case XFS_ATTR_LEAF_MAGIC:
|
||||
case XFS_ATTR3_LEAF_MAGIC:
|
||||
leaf = bp->b_addr;
|
||||
if (cursor->hashval > be32_to_cpu(leaf->entries[
|
||||
be16_to_cpu(leaf->hdr.count)-1].hashval)) {
|
||||
xfs_attr3_leaf_hdr_from_disk(&leafhdr, leaf);
|
||||
entries = xfs_attr3_leaf_entryp(leaf);
|
||||
if (cursor->hashval > be32_to_cpu(
|
||||
entries[leafhdr.count - 1].hashval)) {
|
||||
trace_xfs_attr_list_wrong_blk(context);
|
||||
xfs_trans_brelse(NULL, bp);
|
||||
bp = NULL;
|
||||
} else if (cursor->hashval <=
|
||||
be32_to_cpu(leaf->entries[0].hashval)) {
|
||||
} else if (cursor->hashval <= be32_to_cpu(
|
||||
entries[0].hashval)) {
|
||||
trace_xfs_attr_list_wrong_blk(context);
|
||||
xfs_trans_brelse(NULL, bp);
|
||||
bp = NULL;
|
||||
|
@ -1851,27 +1859,31 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
|
|||
if (bp == NULL) {
|
||||
cursor->blkno = 0;
|
||||
for (;;) {
|
||||
__uint16_t magic;
|
||||
|
||||
error = xfs_da3_node_read(NULL, context->dp,
|
||||
cursor->blkno, -1, &bp,
|
||||
XFS_ATTR_FORK);
|
||||
if (error)
|
||||
return(error);
|
||||
node = bp->b_addr;
|
||||
if (node->hdr.info.magic ==
|
||||
cpu_to_be16(XFS_ATTR_LEAF_MAGIC))
|
||||
magic = be16_to_cpu(node->hdr.info.magic);
|
||||
if (magic == XFS_ATTR_LEAF_MAGIC ||
|
||||
magic == XFS_ATTR3_LEAF_MAGIC)
|
||||
break;
|
||||
if (unlikely(node->hdr.info.magic !=
|
||||
cpu_to_be16(XFS_DA_NODE_MAGIC))) {
|
||||
if (magic != XFS_DA_NODE_MAGIC &&
|
||||
magic != XFS_DA3_NODE_MAGIC) {
|
||||
XFS_CORRUPTION_ERROR("xfs_attr_node_list(3)",
|
||||
XFS_ERRLEVEL_LOW,
|
||||
context->dp->i_mount,
|
||||
node);
|
||||
xfs_trans_brelse(NULL, bp);
|
||||
return(XFS_ERROR(EFSCORRUPTED));
|
||||
return XFS_ERROR(EFSCORRUPTED);
|
||||
}
|
||||
|
||||
xfs_da3_node_hdr_from_disk(&nodehdr, node);
|
||||
btree = xfs_da3_node_tree_p(node);
|
||||
for (i = 0; i < be16_to_cpu(node->hdr.count);
|
||||
btree++, i++) {
|
||||
for (i = 0; i < nodehdr.count; btree++, i++) {
|
||||
if (cursor->hashval
|
||||
<= be32_to_cpu(btree->hashval)) {
|
||||
cursor->blkno = be32_to_cpu(btree->before);
|
||||
|
@ -1880,9 +1892,9 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (i == be16_to_cpu(node->hdr.count)) {
|
||||
if (i == nodehdr.count) {
|
||||
xfs_trans_brelse(NULL, bp);
|
||||
return(0);
|
||||
return 0;
|
||||
}
|
||||
xfs_trans_brelse(NULL, bp);
|
||||
}
|
||||
|
@ -1896,22 +1908,23 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
|
|||
*/
|
||||
for (;;) {
|
||||
leaf = bp->b_addr;
|
||||
error = xfs_attr_leaf_list_int(bp, context);
|
||||
error = xfs_attr3_leaf_list_int(bp, context);
|
||||
if (error) {
|
||||
xfs_trans_brelse(NULL, bp);
|
||||
return error;
|
||||
}
|
||||
if (context->seen_enough || leaf->hdr.info.forw == 0)
|
||||
xfs_attr3_leaf_hdr_from_disk(&leafhdr, leaf);
|
||||
if (context->seen_enough || leafhdr.forw == 0)
|
||||
break;
|
||||
cursor->blkno = be32_to_cpu(leaf->hdr.info.forw);
|
||||
cursor->blkno = leafhdr.forw;
|
||||
xfs_trans_brelse(NULL, bp);
|
||||
error = xfs_attr_leaf_read(NULL, context->dp, cursor->blkno, -1,
|
||||
error = xfs_attr3_leaf_read(NULL, context->dp, cursor->blkno, -1,
|
||||
&bp);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
xfs_trans_brelse(NULL, bp);
|
||||
return(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2000,2002-2003,2005 Silicon Graphics, Inc.
|
||||
* Copyright (c) 2013 Red Hat, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -89,7 +90,7 @@ typedef struct xfs_attr_leaf_hdr { /* constant-structure header block */
|
|||
|
||||
typedef struct xfs_attr_leaf_entry { /* sorted on key, not name */
|
||||
__be32 hashval; /* hash value of name */
|
||||
__be16 nameidx; /* index into buffer of name/value */
|
||||
__be16 nameidx; /* index into buffer of name/value */
|
||||
__u8 flags; /* LOCAL/ROOT/SECURE/INCOMPLETE flag */
|
||||
__u8 pad2; /* unused pad byte */
|
||||
} xfs_attr_leaf_entry_t;
|
||||
|
@ -114,6 +115,54 @@ typedef struct xfs_attr_leafblock {
|
|||
xfs_attr_leaf_name_remote_t valuelist; /* grows from bottom of buf */
|
||||
} xfs_attr_leafblock_t;
|
||||
|
||||
/*
|
||||
* CRC enabled leaf structures. Called "version 3" structures to match the
|
||||
* version number of the directory and dablk structures for this feature, and
|
||||
* attr2 is already taken by the variable inode attribute fork size feature.
|
||||
*/
|
||||
struct xfs_attr3_leaf_hdr {
|
||||
struct xfs_da3_blkinfo info;
|
||||
__be16 count;
|
||||
__be16 usedbytes;
|
||||
__be16 firstused;
|
||||
__u8 holes;
|
||||
__u8 pad1;
|
||||
struct xfs_attr_leaf_map freemap[XFS_ATTR_LEAF_MAPSIZE];
|
||||
};
|
||||
|
||||
#define XFS_ATTR3_LEAF_CRC_OFF (offsetof(struct xfs_attr3_leaf_hdr, info.crc))
|
||||
|
||||
struct xfs_attr3_leafblock {
|
||||
struct xfs_attr3_leaf_hdr hdr;
|
||||
struct xfs_attr_leaf_entry entries[1];
|
||||
|
||||
/*
|
||||
* The rest of the block contains the following structures after the
|
||||
* leaf entries, growing from the bottom up. The variables are never
|
||||
* referenced, the locations accessed purely from helper functions.
|
||||
*
|
||||
* struct xfs_attr_leaf_name_local
|
||||
* struct xfs_attr_leaf_name_remote
|
||||
*/
|
||||
};
|
||||
|
||||
/*
|
||||
* incore, neutral version of the attribute leaf header
|
||||
*/
|
||||
struct xfs_attr3_icleaf_hdr {
|
||||
__uint32_t forw;
|
||||
__uint32_t back;
|
||||
__uint16_t magic;
|
||||
__uint16_t count;
|
||||
__uint16_t usedbytes;
|
||||
__uint16_t firstused;
|
||||
__u8 holes;
|
||||
struct {
|
||||
__uint16_t base;
|
||||
__uint16_t size;
|
||||
} freemap[XFS_ATTR_LEAF_MAPSIZE];
|
||||
};
|
||||
|
||||
/*
|
||||
* Flags used in the leaf_entry[i].flags field.
|
||||
* NOTE: the INCOMPLETE bit must not collide with the flags bits specified
|
||||
|
@ -147,26 +196,43 @@ typedef struct xfs_attr_leafblock {
|
|||
*/
|
||||
#define XFS_ATTR_LEAF_NAME_ALIGN ((uint)sizeof(xfs_dablk_t))
|
||||
|
||||
static inline int
|
||||
xfs_attr3_leaf_hdr_size(struct xfs_attr_leafblock *leafp)
|
||||
{
|
||||
if (leafp->hdr.info.magic == cpu_to_be16(XFS_ATTR3_LEAF_MAGIC))
|
||||
return sizeof(struct xfs_attr3_leaf_hdr);
|
||||
return sizeof(struct xfs_attr_leaf_hdr);
|
||||
}
|
||||
|
||||
static inline struct xfs_attr_leaf_entry *
|
||||
xfs_attr3_leaf_entryp(xfs_attr_leafblock_t *leafp)
|
||||
{
|
||||
if (leafp->hdr.info.magic == cpu_to_be16(XFS_ATTR3_LEAF_MAGIC))
|
||||
return &((struct xfs_attr3_leafblock *)leafp)->entries[0];
|
||||
return &leafp->entries[0];
|
||||
}
|
||||
|
||||
/*
|
||||
* Cast typed pointers for "local" and "remote" name/value structs.
|
||||
*/
|
||||
static inline xfs_attr_leaf_name_remote_t *
|
||||
xfs_attr_leaf_name_remote(xfs_attr_leafblock_t *leafp, int idx)
|
||||
static inline char *
|
||||
xfs_attr3_leaf_name(xfs_attr_leafblock_t *leafp, int idx)
|
||||
{
|
||||
return (xfs_attr_leaf_name_remote_t *)
|
||||
&((char *)leafp)[be16_to_cpu(leafp->entries[idx].nameidx)];
|
||||
struct xfs_attr_leaf_entry *entries = xfs_attr3_leaf_entryp(leafp);
|
||||
|
||||
return &((char *)leafp)[be16_to_cpu(entries[idx].nameidx)];
|
||||
}
|
||||
|
||||
static inline xfs_attr_leaf_name_remote_t *
|
||||
xfs_attr3_leaf_name_remote(xfs_attr_leafblock_t *leafp, int idx)
|
||||
{
|
||||
return (xfs_attr_leaf_name_remote_t *)xfs_attr3_leaf_name(leafp, idx);
|
||||
}
|
||||
|
||||
static inline xfs_attr_leaf_name_local_t *
|
||||
xfs_attr_leaf_name_local(xfs_attr_leafblock_t *leafp, int idx)
|
||||
xfs_attr3_leaf_name_local(xfs_attr_leafblock_t *leafp, int idx)
|
||||
{
|
||||
return (xfs_attr_leaf_name_local_t *)
|
||||
&((char *)leafp)[be16_to_cpu(leafp->entries[idx].nameidx)];
|
||||
}
|
||||
|
||||
static inline char *xfs_attr_leaf_name(xfs_attr_leafblock_t *leafp, int idx)
|
||||
{
|
||||
return &((char *)leafp)[be16_to_cpu(leafp->entries[idx].nameidx)];
|
||||
return (xfs_attr_leaf_name_local_t *)xfs_attr3_leaf_name(leafp, idx);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -221,37 +287,37 @@ int xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes);
|
|||
/*
|
||||
* Internal routines when attribute fork size == XFS_LBSIZE(mp).
|
||||
*/
|
||||
int xfs_attr_leaf_to_node(struct xfs_da_args *args);
|
||||
int xfs_attr_leaf_to_shortform(struct xfs_buf *bp,
|
||||
int xfs_attr3_leaf_to_node(struct xfs_da_args *args);
|
||||
int xfs_attr3_leaf_to_shortform(struct xfs_buf *bp,
|
||||
struct xfs_da_args *args, int forkoff);
|
||||
int xfs_attr_leaf_clearflag(struct xfs_da_args *args);
|
||||
int xfs_attr_leaf_setflag(struct xfs_da_args *args);
|
||||
int xfs_attr_leaf_flipflags(xfs_da_args_t *args);
|
||||
int xfs_attr3_leaf_clearflag(struct xfs_da_args *args);
|
||||
int xfs_attr3_leaf_setflag(struct xfs_da_args *args);
|
||||
int xfs_attr3_leaf_flipflags(struct xfs_da_args *args);
|
||||
|
||||
/*
|
||||
* Routines used for growing the Btree.
|
||||
*/
|
||||
int xfs_attr_leaf_split(struct xfs_da_state *state,
|
||||
int xfs_attr3_leaf_split(struct xfs_da_state *state,
|
||||
struct xfs_da_state_blk *oldblk,
|
||||
struct xfs_da_state_blk *newblk);
|
||||
int xfs_attr_leaf_lookup_int(struct xfs_buf *leaf,
|
||||
int xfs_attr3_leaf_lookup_int(struct xfs_buf *leaf,
|
||||
struct xfs_da_args *args);
|
||||
int xfs_attr_leaf_getvalue(struct xfs_buf *bp, struct xfs_da_args *args);
|
||||
int xfs_attr_leaf_add(struct xfs_buf *leaf_buffer,
|
||||
int xfs_attr3_leaf_getvalue(struct xfs_buf *bp, struct xfs_da_args *args);
|
||||
int xfs_attr3_leaf_add(struct xfs_buf *leaf_buffer,
|
||||
struct xfs_da_args *args);
|
||||
int xfs_attr_leaf_remove(struct xfs_buf *leaf_buffer,
|
||||
int xfs_attr3_leaf_remove(struct xfs_buf *leaf_buffer,
|
||||
struct xfs_da_args *args);
|
||||
int xfs_attr_leaf_list_int(struct xfs_buf *bp,
|
||||
int xfs_attr3_leaf_list_int(struct xfs_buf *bp,
|
||||
struct xfs_attr_list_context *context);
|
||||
|
||||
/*
|
||||
* Routines used for shrinking the Btree.
|
||||
*/
|
||||
int xfs_attr_leaf_toosmall(struct xfs_da_state *state, int *retval);
|
||||
void xfs_attr_leaf_unbalance(struct xfs_da_state *state,
|
||||
int xfs_attr3_leaf_toosmall(struct xfs_da_state *state, int *retval);
|
||||
void xfs_attr3_leaf_unbalance(struct xfs_da_state *state,
|
||||
struct xfs_da_state_blk *drop_blk,
|
||||
struct xfs_da_state_blk *save_blk);
|
||||
int xfs_attr_root_inactive(struct xfs_trans **trans, struct xfs_inode *dp);
|
||||
int xfs_attr3_root_inactive(struct xfs_trans **trans, struct xfs_inode *dp);
|
||||
|
||||
/*
|
||||
* Utility routines.
|
||||
|
@ -261,10 +327,12 @@ int xfs_attr_leaf_order(struct xfs_buf *leaf1_bp,
|
|||
struct xfs_buf *leaf2_bp);
|
||||
int xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize,
|
||||
int *local);
|
||||
int xfs_attr_leaf_read(struct xfs_trans *tp, struct xfs_inode *dp,
|
||||
int xfs_attr3_leaf_read(struct xfs_trans *tp, struct xfs_inode *dp,
|
||||
xfs_dablk_t bno, xfs_daddr_t mappedbno,
|
||||
struct xfs_buf **bpp);
|
||||
void xfs_attr3_leaf_hdr_from_disk(struct xfs_attr3_icleaf_hdr *to,
|
||||
struct xfs_attr_leafblock *from);
|
||||
|
||||
extern const struct xfs_buf_ops xfs_attr_leaf_buf_ops;
|
||||
extern const struct xfs_buf_ops xfs_attr3_leaf_buf_ops;
|
||||
|
||||
#endif /* __XFS_ATTR_LEAF_H__ */
|
||||
|
|
|
@ -143,14 +143,14 @@ xfs_da3_node_hdr_from_disk(
|
|||
to->forw = be32_to_cpu(hdr3->info.hdr.forw);
|
||||
to->back = be32_to_cpu(hdr3->info.hdr.back);
|
||||
to->magic = be16_to_cpu(hdr3->info.hdr.magic);
|
||||
to->count = be16_to_cpu(hdr3->count);
|
||||
to->count = be16_to_cpu(hdr3->__count);
|
||||
to->level = be16_to_cpu(hdr3->__level);
|
||||
return;
|
||||
}
|
||||
to->forw = be32_to_cpu(from->hdr.info.forw);
|
||||
to->back = be32_to_cpu(from->hdr.info.back);
|
||||
to->magic = be16_to_cpu(from->hdr.info.magic);
|
||||
to->count = be16_to_cpu(from->hdr.count);
|
||||
to->count = be16_to_cpu(from->hdr.__count);
|
||||
to->level = be16_to_cpu(from->hdr.__level);
|
||||
}
|
||||
|
||||
|
@ -168,14 +168,14 @@ xfs_da3_node_hdr_to_disk(
|
|||
hdr3->info.hdr.forw = cpu_to_be32(from->forw);
|
||||
hdr3->info.hdr.back = cpu_to_be32(from->back);
|
||||
hdr3->info.hdr.magic = cpu_to_be16(from->magic);
|
||||
hdr3->count = cpu_to_be16(from->count);
|
||||
hdr3->__count = cpu_to_be16(from->count);
|
||||
hdr3->__level = cpu_to_be16(from->level);
|
||||
return;
|
||||
}
|
||||
to->hdr.info.forw = cpu_to_be32(from->forw);
|
||||
to->hdr.info.back = cpu_to_be32(from->back);
|
||||
to->hdr.info.magic = cpu_to_be16(from->magic);
|
||||
to->hdr.count = cpu_to_be16(from->count);
|
||||
to->hdr.__count = cpu_to_be16(from->count);
|
||||
to->hdr.__level = cpu_to_be16(from->level);
|
||||
}
|
||||
|
||||
|
@ -270,7 +270,7 @@ xfs_da3_node_read_verify(
|
|||
break;
|
||||
return;
|
||||
case XFS_ATTR_LEAF_MAGIC:
|
||||
bp->b_ops = &xfs_attr_leaf_buf_ops;
|
||||
bp->b_ops = &xfs_attr3_leaf_buf_ops;
|
||||
bp->b_ops->verify_read(bp);
|
||||
return;
|
||||
case XFS_DIR2_LEAFN_MAGIC:
|
||||
|
@ -401,7 +401,7 @@ xfs_da3_split(
|
|||
*/
|
||||
switch (oldblk->magic) {
|
||||
case XFS_ATTR_LEAF_MAGIC:
|
||||
error = xfs_attr_leaf_split(state, oldblk, newblk);
|
||||
error = xfs_attr3_leaf_split(state, oldblk, newblk);
|
||||
if ((error != 0) && (error != ENOSPC)) {
|
||||
return(error); /* GROT: attr is inconsistent */
|
||||
}
|
||||
|
@ -416,12 +416,12 @@ xfs_da3_split(
|
|||
if (state->inleaf) {
|
||||
state->extraafter = 0; /* before newblk */
|
||||
trace_xfs_attr_leaf_split_before(state->args);
|
||||
error = xfs_attr_leaf_split(state, oldblk,
|
||||
error = xfs_attr3_leaf_split(state, oldblk,
|
||||
&state->extrablk);
|
||||
} else {
|
||||
state->extraafter = 1; /* after newblk */
|
||||
trace_xfs_attr_leaf_split_after(state->args);
|
||||
error = xfs_attr_leaf_split(state, newblk,
|
||||
error = xfs_attr3_leaf_split(state, newblk,
|
||||
&state->extrablk);
|
||||
}
|
||||
if (error)
|
||||
|
@ -963,12 +963,12 @@ xfs_da3_join(
|
|||
*/
|
||||
switch (drop_blk->magic) {
|
||||
case XFS_ATTR_LEAF_MAGIC:
|
||||
error = xfs_attr_leaf_toosmall(state, &action);
|
||||
error = xfs_attr3_leaf_toosmall(state, &action);
|
||||
if (error)
|
||||
return(error);
|
||||
if (action == 0)
|
||||
return(0);
|
||||
xfs_attr_leaf_unbalance(state, drop_blk, save_blk);
|
||||
xfs_attr3_leaf_unbalance(state, drop_blk, save_blk);
|
||||
break;
|
||||
case XFS_DIR2_LEAFN_MAGIC:
|
||||
error = xfs_dir2_leafn_toosmall(state, &action);
|
||||
|
@ -1024,7 +1024,8 @@ xfs_da_blkinfo_onlychild_validate(struct xfs_da_blkinfo *blkinfo, __u16 level)
|
|||
if (level == 1) {
|
||||
ASSERT(magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
|
||||
magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC) ||
|
||||
magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
|
||||
magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC) ||
|
||||
magic == cpu_to_be16(XFS_ATTR3_LEAF_MAGIC));
|
||||
} else {
|
||||
ASSERT(magic == cpu_to_be16(XFS_DA_NODE_MAGIC) ||
|
||||
magic == cpu_to_be16(XFS_DA3_NODE_MAGIC));
|
||||
|
@ -1482,7 +1483,9 @@ xfs_da3_node_lookup_int(
|
|||
curr = blk->bp->b_addr;
|
||||
blk->magic = be16_to_cpu(curr->magic);
|
||||
|
||||
if (blk->magic == XFS_ATTR_LEAF_MAGIC) {
|
||||
if (blk->magic == XFS_ATTR_LEAF_MAGIC ||
|
||||
blk->magic == XFS_ATTR3_LEAF_MAGIC) {
|
||||
blk->magic = XFS_ATTR_LEAF_MAGIC;
|
||||
blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL);
|
||||
break;
|
||||
}
|
||||
|
@ -1562,7 +1565,7 @@ xfs_da3_node_lookup_int(
|
|||
retval = xfs_dir2_leafn_lookup_int(blk->bp, args,
|
||||
&blk->index, state);
|
||||
} else if (blk->magic == XFS_ATTR_LEAF_MAGIC) {
|
||||
retval = xfs_attr_leaf_lookup_int(blk->bp, args);
|
||||
retval = xfs_attr3_leaf_lookup_int(blk->bp, args);
|
||||
blk->index = args->index;
|
||||
args->blkno = blk->blkno;
|
||||
} else {
|
||||
|
@ -1874,7 +1877,8 @@ xfs_da3_path_shift(
|
|||
info->magic == cpu_to_be16(XFS_DA3_NODE_MAGIC) ||
|
||||
info->magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
|
||||
info->magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC) ||
|
||||
info->magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
|
||||
info->magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC) ||
|
||||
info->magic == cpu_to_be16(XFS_ATTR3_LEAF_MAGIC));
|
||||
|
||||
|
||||
/*
|
||||
|
@ -1896,6 +1900,7 @@ xfs_da3_path_shift(
|
|||
blkno = be32_to_cpu(btree[blk->index].before);
|
||||
break;
|
||||
case XFS_ATTR_LEAF_MAGIC:
|
||||
case XFS_ATTR3_LEAF_MAGIC:
|
||||
blk->magic = XFS_ATTR_LEAF_MAGIC;
|
||||
ASSERT(level == path->active-1);
|
||||
blk->index = 0;
|
||||
|
@ -2626,6 +2631,7 @@ xfs_da_read_buf(
|
|||
XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) &&
|
||||
(magic != XFS_DA3_NODE_MAGIC) &&
|
||||
(magic != XFS_ATTR_LEAF_MAGIC) &&
|
||||
(magic != XFS_ATTR3_LEAF_MAGIC) &&
|
||||
(magic != XFS_DIR2_LEAF1_MAGIC) &&
|
||||
(magic != XFS_DIR3_LEAF1_MAGIC) &&
|
||||
(magic != XFS_DIR2_LEAFN_MAGIC) &&
|
||||
|
|
|
@ -55,6 +55,7 @@ typedef struct xfs_da_blkinfo {
|
|||
* magic numbers without modification for both v2 and v3 nodes.
|
||||
*/
|
||||
#define XFS_DA3_NODE_MAGIC 0x3ebe /* magic number: non-leaf blocks */
|
||||
#define XFS_ATTR3_LEAF_MAGIC 0x3bee /* magic number: attribute leaf blks */
|
||||
#define XFS_DIR3_LEAF1_MAGIC 0x3df1 /* magic number: v2 dirlf single blks */
|
||||
#define XFS_DIR3_LEAFN_MAGIC 0x3dff /* magic number: v2 dirlf multi blks */
|
||||
|
||||
|
@ -85,13 +86,13 @@ struct xfs_da3_blkinfo {
|
|||
|
||||
typedef struct xfs_da_node_hdr {
|
||||
struct xfs_da_blkinfo info; /* block type, links, etc. */
|
||||
__be16 count; /* count of active entries */
|
||||
__be16 __count; /* count of active entries */
|
||||
__be16 __level; /* level above leaves (leaf == 0) */
|
||||
} xfs_da_node_hdr_t;
|
||||
|
||||
struct xfs_da3_node_hdr {
|
||||
struct xfs_da3_blkinfo info; /* block type, links, etc. */
|
||||
__be16 count; /* count of active entries */
|
||||
__be16 __count; /* count of active entries */
|
||||
__be16 __level; /* level above leaves (leaf == 0) */
|
||||
__be32 __pad32;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue