/*
- * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2001,2004-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * 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.
+ * 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.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * 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/libxfs.h>
+#include "libxfs.h"
#include "bit.h"
#include "type.h"
#include "faddr.h"
#include "attr.h"
#include "io.h"
#include "init.h"
+#include "output.h"
static int attr_leaf_entries_count(void *obj, int startoff);
static int attr_leaf_hdr_count(void *obj, int startoff);
FLD_COUNT, TYP_NONE },
{ "entries", FLDT_ATTR_LEAF_ENTRY, OI(LOFF(entries)),
attr_leaf_entries_count, FLD_ARRAY|FLD_COUNT, TYP_NONE },
- { "btree", FLDT_ATTR_NODE_ENTRY, OI(NOFF(btree)), attr_node_btree_count,
+ { "btree", FLDT_ATTR_NODE_ENTRY, OI(NOFF(__btree)), attr_node_btree_count,
FLD_ARRAY|FLD_COUNT, TYP_NONE },
{ "nvlist", FLDT_ATTR_LEAF_NAME, attr_leaf_nvlist_offset,
attr_leaf_nvlist_count, FLD_ARRAY|FLD_OFFSET|FLD_COUNT, TYP_NONE },
{ "root", FLDT_UINT1,
OI(LEOFF(flags) + bitsz(__uint8_t) - XFS_ATTR_ROOT_BIT - 1), C1, 0,
TYP_NONE },
+ { "secure", FLDT_UINT1,
+ OI(LEOFF(flags) + bitsz(__uint8_t) - XFS_ATTR_SECURE_BIT - 1), C1, 0,
+ TYP_NONE },
{ "local", FLDT_UINT1,
OI(LEOFF(flags) + bitsz(__uint8_t) - XFS_ATTR_LOCAL_BIT - 1), C1, 0,
TYP_NONE },
#define HOFF(f) bitize(offsetof(xfs_da_node_hdr_t, f))
const field_t attr_node_hdr_flds[] = {
{ "info", FLDT_ATTR_BLKINFO, OI(HOFF(info)), C1, 0, TYP_NONE },
- { "count", FLDT_UINT16D, OI(HOFF(count)), C1, 0, TYP_NONE },
- { "level", FLDT_UINT16D, OI(HOFF(level)), C1, 0, TYP_NONE },
+ { "count", FLDT_UINT16D, OI(HOFF(__count)), C1, 0, TYP_NONE },
+ { "level", FLDT_UINT16D, OI(HOFF(__level)), C1, 0, TYP_NONE },
{ NULL }
};
-/*ARGSUSED*/
static int
attr_leaf_entries_count(
void *obj,
int startoff)
{
- xfs_attr_leafblock_t *block;
+ struct xfs_attr_leafblock *leaf = obj;
ASSERT(startoff == 0);
- block = obj;
- if (INT_GET(block->hdr.info.magic, ARCH_CONVERT)
- != XFS_ATTR_LEAF_MAGIC) {
+ if (be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC)
return 0;
- }
+ return be16_to_cpu(leaf->hdr.count);
+}
- return INT_GET(block->hdr.count, ARCH_CONVERT);
+static int
+attr3_leaf_entries_count(
+ void *obj,
+ int startoff)
+{
+ struct xfs_attr3_leafblock *leaf = obj;
+
+ ASSERT(startoff == 0);
+ if (be16_to_cpu(leaf->hdr.info.hdr.magic) != XFS_ATTR3_LEAF_MAGIC)
+ return 0;
+ return be16_to_cpu(leaf->hdr.count);
}
-/*ARGSUSED*/
static int
attr_leaf_hdr_count(
void *obj,
int startoff)
{
- xfs_attr_leafblock_t *block;
+ struct xfs_attr_leafblock *leaf = obj;
ASSERT(startoff == 0);
- block = obj;
- return INT_GET(block->hdr.info.magic, ARCH_CONVERT)
- == XFS_ATTR_LEAF_MAGIC;
+ return be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC;
}
static int
-attr_leaf_name_local_count(
+attr3_leaf_hdr_count(
void *obj,
int startoff)
{
- xfs_attr_leafblock_t *block;
- xfs_attr_leaf_entry_t *e;
- int i;
- int off;
+ struct xfs_attr3_leafblock *leaf = obj;
+
+ ASSERT(startoff == 0);
+ return be16_to_cpu(leaf->hdr.info.hdr.magic) == XFS_ATTR3_LEAF_MAGIC;
+}
+
+typedef int (*attr_leaf_entry_walk_f)(struct xfs_attr_leafblock *,
+ struct xfs_attr_leaf_entry *, int);
+static int
+attr_leaf_entry_walk(
+ void *obj,
+ int startoff,
+ attr_leaf_entry_walk_f func)
+{
+ struct xfs_attr_leafblock *leaf = obj;
+ struct xfs_attr3_icleaf_hdr leafhdr;
+ struct xfs_attr_leaf_entry *entries;
+ struct xfs_attr_leaf_entry *e;
+ int i;
+ int off;
ASSERT(bitoffs(startoff) == 0);
- off = byteize(startoff);
- block = obj;
- if (INT_GET(block->hdr.info.magic, ARCH_CONVERT)
- != XFS_ATTR_LEAF_MAGIC)
+ if (be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC &&
+ be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR3_LEAF_MAGIC)
return 0;
- for (i = 0; i < INT_GET(block->hdr.count, ARCH_CONVERT); i++) {
- e = &block->entries[i];
- if (INT_GET(e->nameidx, ARCH_CONVERT) == off)
- return (INT_GET(e->flags, ARCH_CONVERT)
- & XFS_ATTR_LOCAL) != 0;
+
+ off = byteize(startoff);
+ xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &leafhdr, leaf);
+ entries = xfs_attr3_leaf_entryp(leaf);
+
+ for (i = 0; i < leafhdr.count; i++) {
+ e = &entries[i];
+ if (be16_to_cpu(e->nameidx) == off)
+ return func(leaf, e, i);
}
return 0;
}
+static int
+__attr_leaf_name_local_count(
+ struct xfs_attr_leafblock *leaf,
+ struct xfs_attr_leaf_entry *e,
+ int i)
+{
+ return (e->flags & XFS_ATTR_LOCAL) != 0;
+}
+
+static int
+attr_leaf_name_local_count(
+ void *obj,
+ int startoff)
+{
+ return attr_leaf_entry_walk(obj, startoff,
+ __attr_leaf_name_local_count);
+}
+
+static int
+__attr_leaf_name_local_name_count(
+ struct xfs_attr_leafblock *leaf,
+ struct xfs_attr_leaf_entry *e,
+ int i)
+{
+ struct xfs_attr_leaf_name_local *l;
+
+ if (!(e->flags & XFS_ATTR_LOCAL))
+ return 0;
+
+ l = xfs_attr3_leaf_name_local(leaf, i);
+ return l->namelen;
+}
+
static int
attr_leaf_name_local_name_count(
void *obj,
int startoff)
{
- xfs_attr_leafblock_t *block;
- xfs_attr_leaf_entry_t *e;
- int i;
- xfs_attr_leaf_name_local_t *l;
- int off;
+ return attr_leaf_entry_walk(obj, startoff,
+ __attr_leaf_name_local_name_count);
+}
- ASSERT(bitoffs(startoff) == 0);
- off = byteize(startoff);
- block = obj;
- if (INT_GET(block->hdr.info.magic, ARCH_CONVERT)
- != XFS_ATTR_LEAF_MAGIC)
+static int
+__attr_leaf_name_local_value_count(
+ struct xfs_attr_leafblock *leaf,
+ struct xfs_attr_leaf_entry *e,
+ int i)
+{
+ struct xfs_attr_leaf_name_local *l;
+
+ if (!(e->flags & XFS_ATTR_LOCAL))
return 0;
- for (i = 0; i < INT_GET(block->hdr.count, ARCH_CONVERT); i++) {
- e = &block->entries[i];
- if (INT_GET(e->nameidx, ARCH_CONVERT) == off) {
- if (INT_GET(e->flags, ARCH_CONVERT) & XFS_ATTR_LOCAL) {
- l = XFS_ATTR_LEAF_NAME_LOCAL(block, i);
- return INT_GET(l->namelen, ARCH_CONVERT);
- } else
- return 0;
- }
- }
- return 0;
+
+ l = xfs_attr3_leaf_name_local(leaf, i);
+ return be16_to_cpu(l->valuelen);
}
static int
void *obj,
int startoff)
{
- xfs_attr_leafblock_t *block;
- xfs_attr_leaf_entry_t *e;
- int i;
- xfs_attr_leaf_name_local_t *l;
- int off;
+ return attr_leaf_entry_walk(obj, startoff,
+ __attr_leaf_name_local_value_count);
+}
- ASSERT(bitoffs(startoff) == 0);
- off = byteize(startoff);
- block = obj;
- if (INT_GET(block->hdr.info.magic, ARCH_CONVERT)
- != XFS_ATTR_LEAF_MAGIC)
- return 0;
- for (i = 0; i < INT_GET(block->hdr.count, ARCH_CONVERT); i++) {
- e = &block->entries[i];
- if (INT_GET(e->nameidx, ARCH_CONVERT) == off) {
- if (INT_GET(e->flags, ARCH_CONVERT) & XFS_ATTR_LOCAL) {
- l = XFS_ATTR_LEAF_NAME_LOCAL(block, i);
- return INT_GET(l->valuelen, ARCH_CONVERT);
- } else
- return 0;
- }
- }
- return 0;
+static int
+__attr_leaf_name_local_value_offset(
+ struct xfs_attr_leafblock *leaf,
+ struct xfs_attr_leaf_entry *e,
+ int i)
+{
+ struct xfs_attr_leaf_name_local *l;
+ char *vp;
+
+ l = xfs_attr3_leaf_name_local(leaf, i);
+ vp = (char *)&l->nameval[l->namelen];
+
+ return (int)bitize(vp - (char *)l);
}
-/*ARGSUSED*/
static int
attr_leaf_name_local_value_offset(
void *obj,
int startoff,
int idx)
{
- xfs_attr_leafblock_t *block;
- xfs_attr_leaf_name_local_t *l;
- char *vp;
- int off;
- xfs_attr_leaf_entry_t *e;
- int i;
-
- ASSERT(bitoffs(startoff) == 0);
- off = byteize(startoff);
- block = obj;
- if (INT_GET(block->hdr.info.magic, ARCH_CONVERT)
- != XFS_ATTR_LEAF_MAGIC)
- return 0;
-
- for (i = 0; i < INT_GET(block->hdr.count, ARCH_CONVERT); i++) {
- e = &block->entries[i];
- if (INT_GET(e->nameidx, ARCH_CONVERT) == off)
- break;
- }
- if (i>=INT_GET(block->hdr.count, ARCH_CONVERT)) return 0;
+ return attr_leaf_entry_walk(obj, startoff,
+ __attr_leaf_name_local_value_offset);
+}
- l = XFS_ATTR_LEAF_NAME_LOCAL(block, i);
- vp = (char *)&l->nameval[l->namelen];
- return (int)bitize(vp - (char *)l);
+static int
+__attr_leaf_name_remote_count(
+ struct xfs_attr_leafblock *leaf,
+ struct xfs_attr_leaf_entry *e,
+ int i)
+{
+ return (e->flags & XFS_ATTR_LOCAL) == 0;
}
static int
attr_leaf_name_remote_count(
- void *obj,
- int startoff)
+ void *obj,
+ int startoff)
{
- xfs_attr_leafblock_t *block;
- xfs_attr_leaf_entry_t *e;
- int i;
- int off;
+ return attr_leaf_entry_walk(obj, startoff,
+ __attr_leaf_name_remote_count);
+}
- ASSERT(bitoffs(startoff) == 0);
- off = byteize(startoff);
- block = obj;
- if (INT_GET(block->hdr.info.magic, ARCH_CONVERT)
- != XFS_ATTR_LEAF_MAGIC)
+static int
+__attr_leaf_name_remote_name_count(
+ struct xfs_attr_leafblock *leaf,
+ struct xfs_attr_leaf_entry *e,
+ int i)
+{
+ struct xfs_attr_leaf_name_remote *r;
+
+ if (e->flags & XFS_ATTR_LOCAL)
return 0;
- for (i = 0; i < INT_GET(block->hdr.count, ARCH_CONVERT); i++) {
- e = &block->entries[i];
- if (INT_GET(e->nameidx, ARCH_CONVERT) == off)
- return (INT_GET(e->flags, ARCH_CONVERT) & XFS_ATTR_LOCAL) == 0;
- }
- return 0;
+
+ r = xfs_attr3_leaf_name_remote(leaf, i);
+ return r->namelen;
}
static int
void *obj,
int startoff)
{
- xfs_attr_leafblock_t *block;
- xfs_attr_leaf_entry_t *e;
- int i;
- int off;
- xfs_attr_leaf_name_remote_t *r;
-
- ASSERT(bitoffs(startoff) == 0);
- off = byteize(startoff);
- block = obj;
- if (INT_GET(block->hdr.info.magic, ARCH_CONVERT)
- != XFS_ATTR_LEAF_MAGIC)
- return 0;
- for (i = 0; i < INT_GET(block->hdr.count, ARCH_CONVERT); i++) {
- e = &block->entries[i];
- if (INT_GET(e->nameidx, ARCH_CONVERT) == off) {
- if (!(INT_GET(e->flags, ARCH_CONVERT) & XFS_ATTR_LOCAL)) {
- r = XFS_ATTR_LEAF_NAME_REMOTE(block, i);
- return INT_GET(r->namelen, ARCH_CONVERT);
- } else
- return 0;
- }
- }
- return 0;
+ return attr_leaf_entry_walk(obj, startoff,
+ __attr_leaf_name_remote_name_count);
}
-/*ARGSUSED*/
int
attr_leaf_name_size(
void *obj,
int startoff,
int idx)
{
- xfs_attr_leafblock_t *block;
- xfs_attr_leaf_entry_t *e;
- xfs_attr_leaf_name_local_t *l;
- xfs_attr_leaf_name_remote_t *r;
+ struct xfs_attr_leafblock *leaf = obj;
+ struct xfs_attr_leaf_entry *e;
+ struct xfs_attr_leaf_name_local *l;
+ struct xfs_attr_leaf_name_remote *r;
ASSERT(startoff == 0);
- block = obj;
- if (INT_GET(block->hdr.info.magic, ARCH_CONVERT)
- != XFS_ATTR_LEAF_MAGIC)
+ if (be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC &&
+ be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR3_LEAF_MAGIC)
return 0;
- e = &block->entries[idx];
- if (INT_GET(e->flags, ARCH_CONVERT) & XFS_ATTR_LOCAL) {
- l = XFS_ATTR_LEAF_NAME_LOCAL(block, idx);
- return (int)bitize(XFS_ATTR_LEAF_ENTSIZE_LOCAL(INT_GET(l->namelen, ARCH_CONVERT),
- INT_GET(l->valuelen, ARCH_CONVERT)));
+ e = &xfs_attr3_leaf_entryp(leaf)[idx];
+ if (e->flags & XFS_ATTR_LOCAL) {
+ l = xfs_attr3_leaf_name_local(leaf, idx);
+ return (int)bitize(xfs_attr_leaf_entsize_local(l->namelen,
+ be16_to_cpu(l->valuelen)));
} else {
- r = XFS_ATTR_LEAF_NAME_REMOTE(block, idx);
- return (int)bitize(XFS_ATTR_LEAF_ENTSIZE_REMOTE(INT_GET(r->namelen, ARCH_CONVERT)));
+ r = xfs_attr3_leaf_name_remote(leaf, idx);
+ return (int)bitize(xfs_attr_leaf_entsize_remote(r->namelen));
}
}
-/*ARGSUSED*/
static int
attr_leaf_nvlist_count(
void *obj,
int startoff)
{
- xfs_attr_leafblock_t *block;
+ struct xfs_attr_leafblock *leaf = obj;
+
+ ASSERT(startoff == 0);
+ if (be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC)
+ return 0;
+ return be16_to_cpu(leaf->hdr.count);
+}
+
+static int
+attr3_leaf_nvlist_count(
+ void *obj,
+ int startoff)
+{
+ struct xfs_attr3_leafblock *leaf = obj;
ASSERT(startoff == 0);
- block = obj;
- if (INT_GET(block->hdr.info.magic, ARCH_CONVERT)
- != XFS_ATTR_LEAF_MAGIC)
+ if (be16_to_cpu(leaf->hdr.info.hdr.magic) != XFS_ATTR3_LEAF_MAGIC)
return 0;
- return INT_GET(block->hdr.count, ARCH_CONVERT);
+ return be16_to_cpu(leaf->hdr.count);
}
-/*ARGSUSED*/
static int
attr_leaf_nvlist_offset(
void *obj,
int startoff,
int idx)
{
- xfs_attr_leafblock_t *block;
- xfs_attr_leaf_entry_t *e;
+ struct xfs_attr_leafblock *leaf = obj;
+ struct xfs_attr_leaf_entry *e;
ASSERT(startoff == 0);
- block = obj;
- e = &block->entries[idx];
- return bitize(INT_GET(e->nameidx, ARCH_CONVERT));
+ e = &xfs_attr3_leaf_entryp(leaf)[idx];
+ return bitize(be16_to_cpu(e->nameidx));
}
-/*ARGSUSED*/
static int
attr_node_btree_count(
void *obj,
int startoff)
{
- xfs_da_intnode_t *block;
+ struct xfs_da_intnode *node = obj;
ASSERT(startoff == 0); /* this is a base structure */
- block = obj;
- if (INT_GET(block->hdr.info.magic, ARCH_CONVERT)
- != XFS_DA_NODE_MAGIC)
+ if (be16_to_cpu(node->hdr.info.magic) != XFS_DA_NODE_MAGIC)
+ return 0;
+ return be16_to_cpu(node->hdr.__count);
+}
+
+static int
+attr3_node_btree_count(
+ void *obj,
+ int startoff)
+{
+ struct xfs_da3_intnode *node = obj;
+
+ ASSERT(startoff == 0);
+ if (be16_to_cpu(node->hdr.info.hdr.magic) != XFS_DA3_NODE_MAGIC)
return 0;
- return INT_GET(block->hdr.count, ARCH_CONVERT);
+ return be16_to_cpu(node->hdr.__count);
}
-/*ARGSUSED*/
+
static int
attr_node_hdr_count(
void *obj,
int startoff)
{
- xfs_da_intnode_t *block;
+ struct xfs_da_intnode *node = obj;
ASSERT(startoff == 0);
- block = obj;
- return INT_GET(block->hdr.info.magic, ARCH_CONVERT)
- == XFS_DA_NODE_MAGIC;
+ return be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC;
+}
+
+static int
+attr3_node_hdr_count(
+ void *obj,
+ int startoff)
+{
+ struct xfs_da3_intnode *node = obj;
+
+ ASSERT(startoff == 0);
+ return be16_to_cpu(node->hdr.info.hdr.magic) == XFS_DA3_NODE_MAGIC;
}
-/*ARGSUSED*/
int
attr_size(
void *obj,
{
return bitize(mp->m_sb.sb_blocksize);
}
+
+/*
+ * CRC enabled attribute block field definitions
+ */
+const field_t attr3_hfld[] = {
+ { "", FLDT_ATTR3, OI(0), C1, 0, TYP_NONE },
+ { NULL }
+};
+
+#define L3OFF(f) bitize(offsetof(struct xfs_attr3_leafblock, f))
+#define N3OFF(f) bitize(offsetof(struct xfs_da3_intnode, f))
+const field_t attr3_flds[] = {
+ { "hdr", FLDT_ATTR3_LEAF_HDR, OI(L3OFF(hdr)), attr3_leaf_hdr_count,
+ FLD_COUNT, TYP_NONE },
+ { "hdr", FLDT_DA3_NODE_HDR, OI(N3OFF(hdr)), attr3_node_hdr_count,
+ FLD_COUNT, TYP_NONE },
+ { "entries", FLDT_ATTR_LEAF_ENTRY, OI(L3OFF(entries)),
+ attr3_leaf_entries_count, FLD_ARRAY|FLD_COUNT, TYP_NONE },
+ { "btree", FLDT_ATTR_NODE_ENTRY, OI(N3OFF(__btree)),
+ attr3_node_btree_count, FLD_ARRAY|FLD_COUNT, TYP_NONE },
+ { "nvlist", FLDT_ATTR_LEAF_NAME, attr_leaf_nvlist_offset,
+ attr3_leaf_nvlist_count, FLD_ARRAY|FLD_OFFSET|FLD_COUNT, TYP_NONE },
+ { NULL }
+};
+
+#define LH3OFF(f) bitize(offsetof(struct xfs_attr3_leaf_hdr, f))
+const field_t attr3_leaf_hdr_flds[] = {
+ { "info", FLDT_DA3_BLKINFO, OI(LH3OFF(info)), C1, 0, TYP_NONE },
+ { "count", FLDT_UINT16D, OI(LH3OFF(count)), C1, 0, TYP_NONE },
+ { "usedbytes", FLDT_UINT16D, OI(LH3OFF(usedbytes)), C1, 0, TYP_NONE },
+ { "firstused", FLDT_UINT16D, OI(LH3OFF(firstused)), C1, 0, TYP_NONE },
+ { "holes", FLDT_UINT8D, OI(LH3OFF(holes)), C1, 0, TYP_NONE },
+ { "pad1", FLDT_UINT8X, OI(LH3OFF(pad1)), C1, FLD_SKIPALL, TYP_NONE },
+ { "freemap", FLDT_ATTR_LEAF_MAP, OI(LH3OFF(freemap)),
+ CI(XFS_ATTR_LEAF_MAPSIZE), FLD_ARRAY, TYP_NONE },
+ { NULL }
+};
+
+/*
+ * Special read verifier for attribute buffers. Detect the magic number
+ * appropriately and set the correct verifier and call it.
+ */
+static void
+xfs_attr3_db_read_verify(
+ struct xfs_buf *bp)
+{
+ __be32 magic32;
+ __be16 magic16;
+
+ magic32 = *(__be32 *)bp->b_addr;
+ magic16 = ((struct xfs_da_blkinfo *)bp->b_addr)->magic;
+
+ switch (magic16) {
+ case cpu_to_be16(XFS_ATTR3_LEAF_MAGIC):
+ bp->b_ops = &xfs_attr3_leaf_buf_ops;
+ goto verify;
+ case cpu_to_be16(XFS_DA3_NODE_MAGIC):
+ bp->b_ops = &xfs_da3_node_buf_ops;
+ goto verify;
+ default:
+ break;
+ }
+
+ switch (magic32) {
+ case cpu_to_be32(XFS_ATTR3_RMT_MAGIC):
+ bp->b_ops = &xfs_attr3_rmt_buf_ops;
+ break;
+ default:
+ dbprintf(_("Unknown attribute buffer type!\n"));
+ xfs_buf_ioerror(bp, -EFSCORRUPTED);
+ return;
+ }
+verify:
+ bp->b_ops->verify_read(bp);
+}
+
+static void
+xfs_attr3_db_write_verify(
+ struct xfs_buf *bp)
+{
+ dbprintf(_("Writing unknown attribute buffer type!\n"));
+ xfs_buf_ioerror(bp, -EFSCORRUPTED);
+}
+
+const struct xfs_buf_ops xfs_attr3_db_buf_ops = {
+ .name = "xfs_attr3",
+ .verify_read = xfs_attr3_db_read_verify,
+ .verify_write = xfs_attr3_db_write_verify,
+};