xfs
[Top] [All Lists]

[PATCH 25/48] xfs_repair: update for dir/attr crc format changes.

To: xfs@xxxxxxxxxxx
Subject: [PATCH 25/48] xfs_repair: update for dir/attr crc format changes.
From: Dave Chinner <david@xxxxxxxxxxxxx>
Date: Fri, 7 Jun 2013 10:25:48 +1000
Delivered-to: xfs@xxxxxxxxxxx
In-reply-to: <1370564771-4929-1-git-send-email-david@xxxxxxxxxxxxx>
References: <1370564771-4929-1-git-send-email-david@xxxxxxxxxxxxx>
From: Dave Chinner <dchinner@xxxxxxxxxx>

Signed-off-by: Dave Chinner <dchinner@xxxxxxxxxx>
---
 include/xfs_attr_leaf.h   |    2 +
 include/xfs_dir2_format.h |    3 ++
 libxfs/xfs_dir2_priv.h    |    2 -
 repair/attr_repair.c      |   77 +++++++++++++++++++++++----------------
 repair/dir2.c             |   43 +++++++++++++---------
 repair/dir2.h             |    6 +--
 repair/phase6.c           |   89 ++++++++++++++++++++++++---------------------
 7 files changed, 126 insertions(+), 96 deletions(-)

diff --git a/include/xfs_attr_leaf.h b/include/xfs_attr_leaf.h
index f9d7846..b3e93bb 100644
--- a/include/xfs_attr_leaf.h
+++ b/include/xfs_attr_leaf.h
@@ -332,6 +332,8 @@ int xfs_attr3_leaf_read(struct xfs_trans *tp, struct 
xfs_inode *dp,
                        struct xfs_buf **bpp);
 void   xfs_attr3_leaf_hdr_from_disk(struct xfs_attr3_icleaf_hdr *to,
                                     struct xfs_attr_leafblock *from);
+void   xfs_attr3_leaf_hdr_to_disk(struct xfs_attr_leafblock *to,
+                                  struct xfs_attr3_icleaf_hdr *from);
 
 extern const struct xfs_buf_ops xfs_attr3_leaf_buf_ops;
 
diff --git a/include/xfs_dir2_format.h b/include/xfs_dir2_format.h
index 6dc884a..47ef5f9 100644
--- a/include/xfs_dir2_format.h
+++ b/include/xfs_dir2_format.h
@@ -512,6 +512,9 @@ struct xfs_dir3_leaf {
 
 #define XFS_DIR3_LEAF_CRC_OFF  offsetof(struct xfs_dir3_leaf_hdr, info.crc)
 
+extern void xfs_dir3_leaf_hdr_from_disk(struct xfs_dir3_icleaf_hdr *to,
+               struct xfs_dir2_leaf *from);
+
 static inline int
 xfs_dir3_leaf_hdr_size(struct xfs_dir2_leaf *lp)
 {
diff --git a/libxfs/xfs_dir2_priv.h b/libxfs/xfs_dir2_priv.h
index 6743eda..7af3e92 100644
--- a/libxfs/xfs_dir2_priv.h
+++ b/libxfs/xfs_dir2_priv.h
@@ -104,8 +104,6 @@ xfs_dir3_leaf_find_entry(struct xfs_dir3_icleaf_hdr 
*leafhdr,
                int lowstale, int highstale, int *lfloglow, int *lfloghigh);
 extern int xfs_dir2_node_to_leaf(struct xfs_da_state *state);
 
-extern void xfs_dir3_leaf_hdr_from_disk(struct xfs_dir3_icleaf_hdr *to,
-               struct xfs_dir2_leaf *from);
 extern void xfs_dir3_leaf_hdr_to_disk(struct xfs_dir2_leaf *to,
                struct xfs_dir3_icleaf_hdr *from);
 extern bool xfs_dir3_leaf_check_int(struct xfs_mount *mp,
diff --git a/repair/attr_repair.c b/repair/attr_repair.c
index 13e9034..d42b85f 100644
--- a/repair/attr_repair.c
+++ b/repair/attr_repair.c
@@ -187,7 +187,8 @@ traverse_int_dablock(xfs_mount_t    *mp,
                btree = xfs_da3_node_tree_p(node);
                xfs_da3_node_hdr_from_disk(&nodehdr, node);
 
-               if (nodehdr.magic != XFS_DA_NODE_MAGIC)  {
+               if (nodehdr.magic != XFS_DA_NODE_MAGIC &&
+                   nodehdr.magic != XFS_DA3_NODE_MAGIC)  {
                        do_warn(_("bad dir/attr magic number in inode %" PRIu64 
", "
                                  "file bno = %u, fsbno = %" PRIu64 "\n"),
                                da_cursor->ino, bno, fsbno);
@@ -568,7 +569,8 @@ verify_da_path(xfs_mount_t  *mp,
                 * entry count, verify level
                 */
                bad = 0;
-               if (XFS_DA_NODE_MAGIC != nodehdr.magic) {
+               if (nodehdr.magic != XFS_DA_NODE_MAGIC ||
+                   nodehdr.magic != XFS_DA3_NODE_MAGIC)  {
                        do_warn(
        _("bad magic number %x in block %u (%" PRIu64 ") for directory inode %" 
PRIu64 "\n"),
                                nodehdr.magic,
@@ -1139,27 +1141,29 @@ process_leaf_attr_block(
        xfs_attr_leaf_entry_t *entry;
        int  i, start, stop, clearit, usedbs, firstb, thissize;
        da_freemap_t *attr_freemap;
+       struct xfs_attr3_icleaf_hdr leafhdr;
 
+       xfs_attr3_leaf_hdr_from_disk(&leafhdr, leaf);
        clearit = usedbs = 0;
        *repair = 0;
        firstb = mp->m_sb.sb_blocksize;
-       stop = sizeof(xfs_attr_leaf_hdr_t);
+       stop = xfs_attr3_leaf_hdr_size(leaf);
 
        /* does the count look sorta valid? */
-       if (be16_to_cpu(leaf->hdr.count) * sizeof(xfs_attr_leaf_entry_t)
-                       + sizeof(xfs_attr_leaf_hdr_t) > XFS_LBSIZE(mp)) {
+       if (leafhdr.count * sizeof(xfs_attr_leaf_entry_t) + stop >
+                                                       XFS_LBSIZE(mp)) {
                do_warn(
        _("bad attribute count %d in attr block %u, inode %" PRIu64 "\n"),
-                       be16_to_cpu(leaf->hdr.count), da_bno, ino);
-               return (1);
+                       leafhdr.count, da_bno, ino);
+               return 1;
        }
 
        attr_freemap = alloc_da_freemap(mp);
        (void) set_da_freemap(mp, attr_freemap, 0, stop);
 
        /* go thru each entry checking for problems */
-       for (i = 0, entry = &leaf->entries[0]; 
-                       i < be16_to_cpu(leaf->hdr.count); i++, entry++) {
+       for (i = 0, entry = xfs_attr3_leaf_entryp(leaf);
+                       i < leafhdr.count; i++, entry++) {
 
                /* check if index is within some boundary. */
                if (be16_to_cpu(entry->nameidx) > XFS_LBSIZE(mp)) {
@@ -1180,7 +1184,7 @@ process_leaf_attr_block(
                }
 
                /* mark the entry used */
-               start = (__psint_t)&leaf->entries[i] - (__psint_t)leaf;
+               start = (__psint_t)entry - (__psint_t)leaf;
                stop = start + sizeof(xfs_attr_leaf_entry_t);
                if (set_da_freemap(mp, attr_freemap, start, stop))  {
                        do_warn(
@@ -1226,40 +1230,40 @@ process_leaf_attr_block(
                 * since the block will get compacted anyhow by the kernel.
                 */
 
-               if ((leaf->hdr.holes == 0 && 
-                               firstb != be16_to_cpu(leaf->hdr.firstused)) ||
-                               be16_to_cpu(leaf->hdr.firstused) > firstb)  {
+               if ((leafhdr.holes == 0 && 
+                               firstb != leafhdr.firstused) ||
+                               leafhdr.firstused > firstb)  {
                        if (!no_modify)  {
                                do_warn(
        _("- resetting first used heap value from %d to %d in "
          "block %u of attribute fork of inode %" PRIu64 "\n"),
-                                       be16_to_cpu(leaf->hdr.firstused), 
+                                       leafhdr.firstused, 
                                        firstb, da_bno, ino);
-                               leaf->hdr.firstused = cpu_to_be16(firstb);
+                               leafhdr.firstused = firstb;
                                *repair = 1;
                        } else  {
                                do_warn(
        _("- would reset first used value from %d to %d in "
          "block %u of attribute fork of inode %" PRIu64 "\n"),
-                                       be16_to_cpu(leaf->hdr.firstused), 
+                                       leafhdr.firstused, 
                                        firstb, da_bno, ino);
                        }
                }
 
-               if (usedbs != be16_to_cpu(leaf->hdr.usedbytes))  {
+               if (usedbs != leafhdr.usedbytes)  {
                        if (!no_modify)  {
                                do_warn(
        _("- resetting usedbytes cnt from %d to %d in "
          "block %u of attribute fork of inode %" PRIu64 "\n"),
-                                       be16_to_cpu(leaf->hdr.usedbytes), 
+                                       leafhdr.usedbytes, 
                                        usedbs, da_bno, ino);
-                               leaf->hdr.usedbytes = cpu_to_be16(usedbs);
+                               leafhdr.usedbytes = usedbs;
                                *repair = 1;
                        } else  {
                                do_warn(
        _("- would reset usedbytes cnt from %d to %d in "
          "block %u of attribute fork of %" PRIu64 "\n"),
-                                       be16_to_cpu(leaf->hdr.usedbytes), 
+                                       leafhdr.usedbytes, 
                                        usedbs, da_bno, ino);
                        }
                }
@@ -1271,6 +1275,8 @@ process_leaf_attr_block(
                * we can add it then.
                */
        }
+       if (*repair)
+               xfs_attr3_leaf_hdr_to_disk(leaf, &leafhdr);
 
        free(attr_freemap);
        return (clearit);  /* and repair */
@@ -1293,6 +1299,7 @@ process_leaf_attr_level(xfs_mount_t       *mp,
        xfs_dablk_t             prev_bno;
        xfs_dahash_t            current_hashval = 0;
        xfs_dahash_t            greatest_hashval;
+       struct xfs_attr3_icleaf_hdr leafhdr;
 
        da_bno = da_cursor->level[0].bno;
        ino = da_cursor->ino;
@@ -1323,13 +1330,15 @@ process_leaf_attr_level(xfs_mount_t     *mp,
                        goto error_out;
                }
 
-               leaf = (xfs_attr_leafblock_t *)XFS_BUF_PTR(bp);
+               leaf = bp->b_addr;
+               xfs_attr3_leaf_hdr_from_disk(&leafhdr, leaf);
 
                /* check magic number for leaf directory btree block */
-               if (be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) {
+               if (!(leafhdr.magic == XFS_ATTR_LEAF_MAGIC ||
+                     leafhdr.magic == XFS_ATTR3_LEAF_MAGIC)) {
                        do_warn(
        _("bad attribute leaf magic %#x for inode %" PRIu64 "\n"),
-                                leaf->hdr.info.magic, ino);
+                                leafhdr.magic, ino);
                        libxfs_putbuf(bp);
                        goto error_out;
                }
@@ -1354,10 +1363,10 @@ process_leaf_attr_level(xfs_mount_t     *mp,
                da_cursor->level[0].hashval = greatest_hashval;
                da_cursor->level[0].bp = bp;
                da_cursor->level[0].bno = da_bno;
-               da_cursor->level[0].index = be16_to_cpu(leaf->hdr.count);
+               da_cursor->level[0].index = leafhdr.count;
                da_cursor->level[0].dirty = repair;
 
-               if (be32_to_cpu(leaf->hdr.info.back) != prev_bno)  {
+               if (leafhdr.back != prev_bno)  {
                        do_warn(
        _("bad sibling back pointer for block %u in attribute fork for inode %" 
PRIu64 "\n"),
                                da_bno, ino);
@@ -1366,7 +1375,7 @@ process_leaf_attr_level(xfs_mount_t       *mp,
                }
 
                prev_bno = da_bno;
-               da_bno = be32_to_cpu(leaf->hdr.info.forw);
+               da_bno = leafhdr.forw;
 
                if (da_bno != 0 && verify_da_path(mp, da_cursor, 0))  {
                        libxfs_putbuf(bp);
@@ -1475,6 +1484,7 @@ process_longform_attr(
        xfs_buf_t       *bp;
        xfs_dahash_t    next_hashval;
        int             repairlinks = 0;
+       struct xfs_attr3_icleaf_hdr leafhdr;
 
        *repair = 0;
 
@@ -1497,7 +1507,7 @@ process_longform_attr(
        }
 
        bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, bno),
-                               XFS_FSB_TO_BB(mp, 1), 0, NULL);
+                               XFS_FSB_TO_BB(mp, 1), 0, &xfs_da3_node_buf_ops);
        if (!bp) {
                do_warn(
        _("can't read block 0 of inode %" PRIu64 " attribute fork\n"),
@@ -1507,19 +1517,20 @@ process_longform_attr(
 
        /* verify leaf block */
        leaf = (xfs_attr_leafblock_t *)XFS_BUF_PTR(bp);
+       xfs_attr3_leaf_hdr_from_disk(&leafhdr, leaf);
 
        /* check sibling pointers in leaf block or root block 0 before
        * we have to release the btree block
        */
-       if (be32_to_cpu(leaf->hdr.info.forw) != 0 || 
-                               be32_to_cpu(leaf->hdr.info.back) != 0)  {
+       if (leafhdr.forw != 0 || leafhdr.back != 0)  {
                if (!no_modify)  {
                        do_warn(
        _("clearing forw/back pointers in block 0 for attributes in inode %" 
PRIu64 "\n"),
                                ino);
                        repairlinks = 1;
-                       leaf->hdr.info.forw = cpu_to_be32(0);
-                       leaf->hdr.info.back = cpu_to_be32(0);
+                       leafhdr.forw = 0;
+                       leafhdr.back = 0;
+                       xfs_attr3_leaf_hdr_to_disk(leaf, &leafhdr);
                } else  {
                        do_warn(
        _("would clear forw/back pointers in block 0 for attributes in inode %" 
PRIu64 "\n"), ino);
@@ -1531,8 +1542,9 @@ process_longform_attr(
         * it's possible to have a node or leaf attribute in either an
         * extent format or btree format attribute fork.
         */
-       switch (be16_to_cpu(leaf->hdr.info.magic)) {
+       switch (leafhdr.magic) {
        case XFS_ATTR_LEAF_MAGIC:       /* leaf-form attribute */
+       case XFS_ATTR3_LEAF_MAGIC:
                if (process_leaf_attr_block(mp, leaf, 0, ino, blkmap,
                                0, &next_hashval, repair)) {
                        /* the block is bad.  lose the attribute fork. */
@@ -1543,6 +1555,7 @@ process_longform_attr(
                break;
 
        case XFS_DA_NODE_MAGIC:         /* btree-form attribute */
+       case XFS_DA3_NODE_MAGIC:
                /* must do this now, to release block 0 before the traversal */
                if (repairlinks) {
                        *repair = 1;
diff --git a/repair/dir2.c b/repair/dir2.c
index a71a276..e41c5f9 100644
--- a/repair/dir2.c
+++ b/repair/dir2.c
@@ -186,7 +186,8 @@ _("can't read block %u for directory inode %" PRIu64 "\n"),
                node = bp->b_addr;
                xfs_da3_node_hdr_from_disk(&nodehdr, node);
 
-               if (nodehdr.magic == XFS_DIR2_LEAFN_MAGIC)  {
+               if (nodehdr.magic == XFS_DIR2_LEAFN_MAGIC ||
+                   nodehdr.magic == XFS_DIR3_LEAFN_MAGIC)  {
                        if ( i != -1 ) {
                                do_warn(
 _("found non-root LEAFN node in inode %" PRIu64 " bno = %u\n"),
@@ -195,7 +196,8 @@ _("found non-root LEAFN node in inode %" PRIu64 " bno = 
%u\n"),
                        *rbno = 0;
                        libxfs_putbuf(bp);
                        return(1);
-               } else if (nodehdr.magic != XFS_DA_NODE_MAGIC)  {
+               } else if (!(nodehdr.magic == XFS_DA_NODE_MAGIC ||
+                            nodehdr.magic == XFS_DA3_NODE_MAGIC))  {
                        libxfs_putbuf(bp);
                        do_warn(
 _("bad dir magic number 0x%x in inode %" PRIu64 " bno = %u\n"),
@@ -556,7 +558,8 @@ _("can't read block %u for directory inode %" PRIu64 "\n"),
                 * entry count, verify level
                 */
                bad = 0;
-               if (XFS_DA_NODE_MAGIC != nodehdr.magic) {
+               if (!(nodehdr.magic == XFS_DA_NODE_MAGIC ||
+                     nodehdr.magic == XFS_DA3_NODE_MAGIC)) {
                        do_warn(
 _("bad magic number %x in block %u for directory inode %" PRIu64 "\n"),
                                nodehdr.magic,
@@ -1219,8 +1222,8 @@ process_dir2_data(
        xfs_ino_t               ent_ino;
 
        d = bp->b_addr;
-       bf = d->hdr.bestfree;
-       ptr = (char *)d->u;
+       bf = xfs_dir3_data_bestfree_p(&d->hdr);
+       ptr = (char *)xfs_dir3_data_entry_p(&d->hdr);
        badbest = lastfree = freeseen = 0;
        if (be16_to_cpu(bf[0].length) == 0) {
                badbest |= be16_to_cpu(bf[0].offset) != 0;
@@ -1286,7 +1289,7 @@ process_dir2_data(
                        do_warn(_("\twould junk block\n"));
                return 1;
        }
-       ptr = (char *)d->u;
+       ptr = (char *)xfs_dir3_data_entry_p(&d->hdr);
        /*
         * Process the entries now.
         */
@@ -1595,7 +1598,8 @@ _("can't read block %u for directory inode %" PRIu64 
"\n"),
         * Verify the block
         */
        block = bp->b_addr;
-       if (be32_to_cpu(block->hdr.magic) != XFS_DIR2_BLOCK_MAGIC)
+       if (!(be32_to_cpu(block->hdr.magic) == XFS_DIR2_BLOCK_MAGIC ||
+             be32_to_cpu(block->hdr.magic) == XFS_DIR3_BLOCK_MAGIC))
                do_warn(
 _("bad directory block magic # %#x in block %u for directory inode %" PRIu64 
"\n"),
                        be32_to_cpu(block->hdr.magic), mp->m_dirdatablk, ino);
@@ -1638,10 +1642,12 @@ process_leaf_block_dir2(
        int                     i;
        int                     stale;
        struct xfs_dir2_leaf_entry *ents;
+       struct xfs_dir3_icleaf_hdr leafhdr;
 
+       xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
        ents = xfs_dir3_leaf_ents_p(leaf);
 
-       for (i = stale = 0; i < be16_to_cpu(leaf->hdr.count); i++) {
+       for (i = stale = 0; i < leafhdr.count; i++) {
                if ((char *)&ents[i] >= (char *)leaf + mp->m_dirblksize) {
                        do_warn(
 _("bad entry count in block %u of directory inode %" PRIu64 "\n"),
@@ -1658,7 +1664,7 @@ _("bad hash ordering in block %u of directory inode %" 
PRIu64 "\n"),
                }
                *next_hashval = last_hashval = be32_to_cpu(ents[i].hashval);
        }
-       if (stale != be16_to_cpu(leaf->hdr.stale)) {
+       if (stale != leafhdr.stale) {
                do_warn(
 _("bad stale count in block %u of directory inode %" PRIu64 "\n"),
                        da_bno, ino);
@@ -1687,6 +1693,7 @@ process_leaf_level_dir2(
        int                     nex;
        xfs_dablk_t             prev_bno;
        bmap_ext_t              lbmp;
+       struct xfs_dir3_icleaf_hdr leafhdr;
 
        da_bno = da_cursor->level[0].bno;
        ino = da_cursor->ino;
@@ -1723,15 +1730,15 @@ _("can't read file block %u for directory inode %" 
PRIu64 "\n"),
                        goto error_out;
                }
                leaf = bp->b_addr;
+               xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
                /*
                 * Check magic number for leaf directory btree block.
                 */
-               if (be16_to_cpu(leaf->hdr.info.magic) !=
-                  XFS_DIR2_LEAFN_MAGIC) {
+               if (!(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC ||
+                     leafhdr.magic == XFS_DIR3_LEAFN_MAGIC)) {
                        do_warn(
 _("bad directory leaf magic # %#x for directory inode %" PRIu64 " block %u\n"),
-                               be16_to_cpu(leaf->hdr.info.magic),
-                               ino, da_bno);
+                               leafhdr.magic, ino, da_bno);
                        libxfs_putbuf(bp);
                        goto error_out;
                }
@@ -1753,11 +1760,10 @@ _("bad directory leaf magic # %#x for directory inode 
%" PRIu64 " block %u\n"),
                da_cursor->level[0].hashval = greatest_hashval;
                da_cursor->level[0].bp = bp;
                da_cursor->level[0].bno = da_bno;
-               da_cursor->level[0].index =
-                       be16_to_cpu(leaf->hdr.count);
+               da_cursor->level[0].index = leafhdr.count;
                da_cursor->level[0].dirty = buf_dirty;
 
-               if (be32_to_cpu(leaf->hdr.info.back) != prev_bno) {
+               if (leafhdr.back != prev_bno) {
                        do_warn(
 _("bad sibling back pointer for block %u in directory inode %" PRIu64 "\n"),
                                da_bno, ino);
@@ -1765,7 +1771,7 @@ _("bad sibling back pointer for block %u in directory 
inode %" PRIu64 "\n"),
                        goto error_out;
                }
                prev_bno = da_bno;
-               da_bno = be32_to_cpu(leaf->hdr.info.forw);
+               da_bno = leafhdr.forw;
                if (da_bno != 0) {
                        if (verify_dir2_path(mp, da_cursor, 0)) {
                                libxfs_putbuf(bp);
@@ -1908,7 +1914,8 @@ _("can't read block %" PRIu64 " for directory inode %" 
PRIu64 "\n"),
                        continue;
                }
                data = bp->b_addr;
-               if (be32_to_cpu(data->hdr.magic) != XFS_DIR2_DATA_MAGIC)
+               if (!(be32_to_cpu(data->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
+                     be32_to_cpu(data->hdr.magic) == XFS_DIR3_DATA_MAGIC))
                        do_warn(
 _("bad directory block magic # %#x in block %" PRIu64 " for directory inode %" 
PRIu64 "\n"),
                                be32_to_cpu(data->hdr.magic), dbno, ino);
diff --git a/repair/dir2.h b/repair/dir2.h
index 5162028..6ba96bb 100644
--- a/repair/dir2.h
+++ b/repair/dir2.h
@@ -33,13 +33,13 @@ typedef union {
 
 typedef struct xfs_dir2_data {
        xfs_dir2_data_hdr_t     hdr;            /* magic XFS_DIR2_DATA_MAGIC */
-       xfs_dir2_data_union_t   u[1];
+       xfs_dir2_data_union_t   __u[1];
 } xfs_dir2_data_t;
 
 typedef struct xfs_dir2_block {
        xfs_dir2_data_hdr_t     hdr;            /* magic XFS_DIR2_BLOCK_MAGIC */
-       xfs_dir2_data_union_t   u[1];
-       xfs_dir2_leaf_entry_t   leaf[1];
+       xfs_dir2_data_union_t   __u[1];
+       xfs_dir2_leaf_entry_t   __leaf[1];
        xfs_dir2_block_tail_t   tail;
 } xfs_dir2_block_t;
 
diff --git a/repair/phase6.c b/repair/phase6.c
index 8b8df10..dc8145b 100644
--- a/repair/phase6.c
+++ b/repair/phase6.c
@@ -1421,7 +1421,7 @@ longform_dir2_entry_check_data(
 
        bp = *bpp;
        d = bp->b_addr;
-       ptr = (char *)d->u;
+       ptr = (char *)xfs_dir3_data_entry_p(&d->hdr);
        nbad = 0;
        needscan = needlog = 0;
        junkit = 0;
@@ -1432,10 +1432,16 @@ longform_dir2_entry_check_data(
                endptr = (char *)blp;
                if (endptr > (char *)btp)
                        endptr = (char *)btp;
-               wantmagic = XFS_DIR2_BLOCK_MAGIC;
+               if (xfs_sb_version_hascrc(&mp->m_sb))
+                       wantmagic = XFS_DIR3_BLOCK_MAGIC;
+               else
+                       wantmagic = XFS_DIR2_BLOCK_MAGIC;
        } else {
                endptr = (char *)d + mp->m_dirblksize;
-               wantmagic = XFS_DIR2_DATA_MAGIC;
+               if (xfs_sb_version_hascrc(&mp->m_sb))
+                       wantmagic = XFS_DIR3_DATA_MAGIC;
+               else
+                       wantmagic = XFS_DIR2_DATA_MAGIC;
        }
        db = xfs_dir2_da_to_db(mp, da_bno);
 
@@ -1476,8 +1482,8 @@ longform_dir2_entry_check_data(
                                break;
 
                        /* check for block with no data entries */
-                       if ((ptr == (char *)d->u) && (ptr +
-                                       be16_to_cpu(dup->length) >= endptr)) {
+                       if ((ptr == (char *)xfs_dir3_data_entry_p(&d->hdr)) &&
+                           (ptr + be16_to_cpu(dup->length) >= endptr)) {
                                junkit = 1;
                                *num_illegal += 1;
                                break;
@@ -1548,7 +1554,7 @@ longform_dir2_entry_check_data(
                        do_warn(_("would fix magic # to %#x\n"), wantmagic);
        }
        lastfree = 0;
-       ptr = (char *)d->u;
+       ptr = (char *)xfs_dir3_data_entry_p(&d->hdr);
        /*
         * look at each entry.  reference inode pointed to by each
         * entry in the incore inode tree.
@@ -1718,7 +1724,8 @@ longform_dir2_entry_check_data(
                if (ip->i_ino == inum)  {
                        ASSERT(dep->name[0] == '.' && dep->namelen == 1);
                        add_inode_ref(current_irec, current_ino_offset);
-                       if (da_bno != 0 || dep != (xfs_dir2_data_entry_t 
*)d->u) {
+                       if (da_bno != 0 ||
+                           dep != xfs_dir3_data_entry_p(&d->hdr)) {
                                /* "." should be the first entry */
                                nbad++;
                                if (entry_junked(
@@ -1827,6 +1834,7 @@ longform_dir2_check_leaf(
        xfs_dir2_leaf_tail_t    *ltp;
        int                     seeval;
        struct xfs_dir2_leaf_entry *ents;
+       struct xfs_dir3_icleaf_hdr leafhdr;
 
        da_bno = mp->m_dirleafblk;
        if (libxfs_da_read_buf(NULL, ip, da_bno, -1, &bp, XFS_DATA_FORK,
@@ -1837,27 +1845,24 @@ longform_dir2_check_leaf(
                /* NOTREACHED */
        }
        leaf = bp->b_addr;
+       xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
        ents = xfs_dir3_leaf_ents_p(leaf);
        ltp = xfs_dir2_leaf_tail_p(mp, leaf);
        bestsp = xfs_dir2_leaf_bests_p(ltp);
-       if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR2_LEAF1_MAGIC ||
-                               be32_to_cpu(leaf->hdr.info.forw) ||
-                               be32_to_cpu(leaf->hdr.info.back) ||
-                               be16_to_cpu(leaf->hdr.count) <
-                                       be16_to_cpu(leaf->hdr.stale) ||
-                               be16_to_cpu(leaf->hdr.count) >
+       if (!(leafhdr.magic == XFS_DIR2_LEAF1_MAGIC ||
+             leafhdr.magic == XFS_DIR3_LEAF1_MAGIC) ||
+                               leafhdr.forw || leafhdr.back ||
+                               leafhdr.count < leaf->hdr.stale ||
+                               leafhdr.count >
                                        xfs_dir3_max_leaf_ents(mp, leaf) ||
-                               (char *)&ents[be16_to_cpu(
-                                       leaf->hdr.count)] > (char *)bestsp) {
+                               (char *)&ents[leafhdr.count] > (char *)bestsp) {
                do_warn(
        _("leaf block %u for directory inode %" PRIu64 " bad header\n"),
                        da_bno, ip->i_ino);
                libxfs_putbuf(bp);
                return 1;
        }
-       seeval = dir_hash_see_all(hashtab, ents,
-                               be16_to_cpu(leaf->hdr.count),
-                               be16_to_cpu(leaf->hdr.stale));
+       seeval = dir_hash_see_all(hashtab, ents, leafhdr.count, leafhdr.stale);
        if (dir_hash_check(hashtab, ip, seeval)) {
                libxfs_putbuf(bp);
                return 1;
@@ -1899,6 +1904,9 @@ longform_dir2_check_node(
        int                     seeval = 0;
        int                     used;
        struct xfs_dir2_leaf_entry *ents;
+       struct xfs_dir3_icleaf_hdr leafhdr;
+       struct xfs_dir3_icfree_hdr freehdr;
+       __be16                  *bests;
 
        for (da_bno = mp->m_dirleafblk, next_da_bno = 0;
                        next_da_bno != NULLFILEOFF && da_bno < mp->m_dirfreeblk;
@@ -1914,23 +1922,23 @@ longform_dir2_check_node(
                        return 1;
                }
                leaf = bp->b_addr;
+               xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
                ents = xfs_dir3_leaf_ents_p(leaf);
-               if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR2_LEAFN_MAGIC) {
-                       if (be16_to_cpu(leaf->hdr.info.magic) ==
-                                                       XFS_DA_NODE_MAGIC) {
+               if (!(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC ||
+                     leafhdr.magic == XFS_DIR3_LEAFN_MAGIC)) {
+                       if (leafhdr.magic == XFS_DA_NODE_MAGIC ||
+                           leafhdr.magic == XFS_DA3_NODE_MAGIC) {
                                libxfs_putbuf(bp);
                                continue;
                        }
                        do_warn(
        _("unknown magic number %#x for block %u in directory inode %" PRIu64 
"\n"),
-                               be16_to_cpu(leaf->hdr.info.magic),
-                               da_bno, ip->i_ino);
+                               leafhdr.magic, da_bno, ip->i_ino);
                        libxfs_putbuf(bp);
                        return 1;
                }
-               if (be16_to_cpu(leaf->hdr.count) > xfs_dir3_max_leaf_ents(mp, 
leaf) ||
-                                       be16_to_cpu(leaf->hdr.count) <
-                                               be16_to_cpu(leaf->hdr.stale)) {
+               if (leafhdr.count > xfs_dir3_max_leaf_ents(mp, leaf) ||
+                   leafhdr.count < leafhdr.stale) {
                        do_warn(
        _("leaf block %u for directory inode %" PRIu64 " bad header\n"),
                                da_bno, ip->i_ino);
@@ -1938,8 +1946,7 @@ longform_dir2_check_node(
                        return 1;
                }
                seeval = dir_hash_see_all(hashtab, ents,
-                                       be16_to_cpu(leaf->hdr.count),
-                                       be16_to_cpu(leaf->hdr.stale));
+                                       leafhdr.count, leafhdr.stale);
                libxfs_putbuf(bp);
                if (seeval != DIR_HASH_CK_OK)
                        return 1;
@@ -1961,35 +1968,35 @@ longform_dir2_check_node(
                        return 1;
                }
                free = bp->b_addr;
+               xfs_dir3_free_hdr_from_disk(&freehdr, free);
+               bests = xfs_dir3_free_bests_p(mp, free);
                fdb = xfs_dir2_da_to_db(mp, da_bno);
-               if (be32_to_cpu(free->hdr.magic) != XFS_DIR2_FREE_MAGIC ||
-                               be32_to_cpu(free->hdr.firstdb) !=
+               if (!(freehdr.magic == XFS_DIR2_FREE_MAGIC ||
+                     freehdr.magic == XFS_DIR3_FREE_MAGIC) ||
+                               freehdr.firstdb !=
                                        (fdb - XFS_DIR2_FREE_FIRSTDB(mp)) *
                                                xfs_dir3_free_max_bests(mp) ||
-                               be32_to_cpu(free->hdr.nvalid) <
-                                       be32_to_cpu(free->hdr.nused)) {
+                               freehdr.nvalid < freehdr.nused) {
                        do_warn(
        _("free block %u for directory inode %" PRIu64 " bad header\n"),
                                da_bno, ip->i_ino);
                        libxfs_putbuf(bp);
                        return 1;
                }
-               for (i = used = 0; i < be32_to_cpu(free->hdr.nvalid); i++) {
-                       if (i + be32_to_cpu(free->hdr.firstdb) >=
-                                                       freetab->nents ||
-                                       freetab->ents[i + be32_to_cpu(
-                                               free->hdr.firstdb)].v !=
-                                               be16_to_cpu(free->bests[i])) {
+               for (i = used = 0; i < freehdr.nvalid; i++) {
+                       if (i + freehdr.firstdb >= freetab->nents ||
+                                       freetab->ents[i + freehdr.firstdb].v !=
+                                               be16_to_cpu(bests[i])) {
                                do_warn(
        _("free block %u entry %i for directory ino %" PRIu64 " bad\n"),
                                        da_bno, i, ip->i_ino);
                                libxfs_putbuf(bp);
                                return 1;
                        }
-                       used += be16_to_cpu(free->bests[i]) != NULLDATAOFF;
-                       freetab->ents[i + be32_to_cpu(free->hdr.firstdb)].s = 1;
+                       used += be16_to_cpu(bests[i]) != NULLDATAOFF;
+                       freetab->ents[i + freehdr.firstdb].s = 1;
                }
-               if (used != be32_to_cpu(free->hdr.nused)) {
+               if (used != freehdr.nused) {
                        do_warn(
        _("free block %u for directory inode %" PRIu64 " bad nused\n"),
                                da_bno, ip->i_ino);
-- 
1.7.10.4

<Prev in Thread] Current Thread [Next in Thread>