xen/tmem: Fix compile warning.
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / fs / xfs / xfs_dir2_node.c
index 0fe39b9fde7eeb7dfbb4f7f7226b4d853eb31d84..5246de4912d4b07d3fda2940bfe30a15d77a09f1 100644 (file)
  */
 static int xfs_dir2_leafn_add(struct xfs_buf *bp, xfs_da_args_t *args,
                              int index);
-#ifdef DEBUG
-static void xfs_dir2_leafn_check(struct xfs_inode *dp, struct xfs_buf *bp);
-#else
-#define        xfs_dir2_leafn_check(dp, bp)
-#endif
-static void xfs_dir2_leafn_moveents(xfs_da_args_t *args, struct xfs_buf *bp_s,
-                                   int start_s, struct xfs_buf *bp_d,
-                                   int start_d, int count);
 static void xfs_dir2_leafn_rebalance(xfs_da_state_t *state,
                                     xfs_da_state_blk_t *blk1,
                                     xfs_da_state_blk_t *blk2);
@@ -58,6 +50,39 @@ static int xfs_dir2_leafn_remove(xfs_da_args_t *args, struct xfs_buf *bp,
 static int xfs_dir2_node_addname_int(xfs_da_args_t *args,
                                     xfs_da_state_blk_t *fblk);
 
+/*
+ * Check internal consistency of a leafn block.
+ */
+#ifdef DEBUG
+#define        xfs_dir3_leaf_check(mp, bp) \
+do { \
+       if (!xfs_dir3_leafn_check((mp), (bp))) \
+               ASSERT(0); \
+} while (0);
+
+static bool
+xfs_dir3_leafn_check(
+       struct xfs_mount        *mp,
+       struct xfs_buf          *bp)
+{
+       struct xfs_dir2_leaf    *leaf = bp->b_addr;
+       struct xfs_dir3_icleaf_hdr leafhdr;
+
+       xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
+
+       if (leafhdr.magic == XFS_DIR3_LEAFN_MAGIC) {
+               struct xfs_dir3_leaf_hdr *leaf3 = bp->b_addr;
+               if (be64_to_cpu(leaf3->info.blkno) != bp->b_bn)
+                       return false;
+       } else if (leafhdr.magic != XFS_DIR2_LEAFN_MAGIC)
+               return false;
+
+       return xfs_dir3_leaf_check_int(mp, &leafhdr, leaf);
+}
+#else
+#define        xfs_dir3_leaf_check(mp, bp)
+#endif
+
 static bool
 xfs_dir3_free_verify(
        struct xfs_buf          *bp)
@@ -122,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,
 };
@@ -136,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_BLFT_DIR_FREE_BUF);
+       return err;
 }
 
 int
@@ -224,6 +256,7 @@ xfs_dir3_free_get_buf(
        if (error)
                return error;
 
+       xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DIR_FREE_BUF);
        bp->b_ops = &xfs_dir3_free_buf_ops;
 
        /*
@@ -360,11 +393,20 @@ xfs_dir2_leaf_to_node(
        xfs_dir2_free_log_bests(tp, fbp, 0, freehdr.nvalid - 1);
        xfs_dir2_free_log_header(tp, fbp);
 
-       /* convert the leaf to a leafnode */
-       leaf->hdr.info.magic = cpu_to_be16(XFS_DIR2_LEAFN_MAGIC);
-       lbp->b_ops = &xfs_dir2_leafn_buf_ops;
-       xfs_dir2_leaf_log_header(tp, lbp);
-       xfs_dir2_leafn_check(dp, lbp);
+       /*
+        * Converting the leaf to a leafnode is just a matter of changing the
+        * magic number and the ops. Do the change directly to the buffer as
+        * it's less work (and less code) than decoding the header to host
+        * format and back again.
+        */
+       if (leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC))
+               leaf->hdr.info.magic = cpu_to_be16(XFS_DIR2_LEAFN_MAGIC);
+       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_BLFT_DIR_LEAFN_BUF);
+       xfs_dir3_leaf_log_header(tp, lbp);
+       xfs_dir3_leaf_check(mp, lbp);
        return 0;
 }
 
@@ -388,6 +430,8 @@ xfs_dir2_leafn_add(
        int                     lowstale;       /* previous stale entry */
        xfs_mount_t             *mp;            /* filesystem mount point */
        xfs_trans_t             *tp;            /* transaction pointer */
+       struct xfs_dir3_icleaf_hdr leafhdr;
+       struct xfs_dir2_leaf_entry *ents;
 
        trace_xfs_dir2_leafn_add(args, index);
 
@@ -395,6 +439,8 @@ xfs_dir2_leafn_add(
        mp = dp->i_mount;
        tp = args->trans;
        leaf = bp->b_addr;
+       xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
+       ents = xfs_dir3_leaf_ents_p(leaf);
 
        /*
         * Quick check just to make sure we are not going to index
@@ -410,15 +456,15 @@ xfs_dir2_leafn_add(
         * a compact.
         */
 
-       if (be16_to_cpu(leaf->hdr.count) == xfs_dir2_max_leaf_ents(mp)) {
-               if (!leaf->hdr.stale)
+       if (leafhdr.count == xfs_dir3_max_leaf_ents(mp, leaf)) {
+               if (!leafhdr.stale)
                        return XFS_ERROR(ENOSPC);
-               compact = be16_to_cpu(leaf->hdr.stale) > 1;
+               compact = leafhdr.stale > 1;
        } else
                compact = 0;
-       ASSERT(index == 0 || be32_to_cpu(leaf->ents[index - 1].hashval) <= args->hashval);
-       ASSERT(index == be16_to_cpu(leaf->hdr.count) ||
-              be32_to_cpu(leaf->ents[index].hashval) >= args->hashval);
+       ASSERT(index == 0 || be32_to_cpu(ents[index - 1].hashval) <= args->hashval);
+       ASSERT(index == leafhdr.count ||
+              be32_to_cpu(ents[index].hashval) >= args->hashval);
 
        if (args->op_flags & XFS_DA_OP_JUSTCHECK)
                return 0;
@@ -427,62 +473,35 @@ xfs_dir2_leafn_add(
         * Compact out all but one stale leaf entry.  Leaves behind
         * the entry closest to index.
         */
-       if (compact) {
-               xfs_dir2_leaf_compact_x1(bp, &index, &lowstale, &highstale,
-                       &lfloglow, &lfloghigh);
-       }
-       /*
-        * Set impossible logging indices for this case.
-        */
-       else if (leaf->hdr.stale) {
-               lfloglow = be16_to_cpu(leaf->hdr.count);
+       if (compact)
+               xfs_dir3_leaf_compact_x1(&leafhdr, ents, &index, &lowstale,
+                                        &highstale, &lfloglow, &lfloghigh);
+       else if (leafhdr.stale) {
+               /*
+                * Set impossible logging indices for this case.
+                */
+               lfloglow = leafhdr.count;
                lfloghigh = -1;
        }
 
        /*
         * Insert the new entry, log everything.
         */
-       lep = xfs_dir2_leaf_find_entry(leaf, index, compact, lowstale,
+       lep = xfs_dir3_leaf_find_entry(&leafhdr, ents, index, compact, lowstale,
                                       highstale, &lfloglow, &lfloghigh);
 
        lep->hashval = cpu_to_be32(args->hashval);
        lep->address = cpu_to_be32(xfs_dir2_db_off_to_dataptr(mp,
                                args->blkno, args->index));
-       xfs_dir2_leaf_log_header(tp, bp);
-       xfs_dir2_leaf_log_ents(tp, bp, lfloglow, lfloghigh);
-       xfs_dir2_leafn_check(dp, bp);
+
+       xfs_dir3_leaf_hdr_to_disk(leaf, &leafhdr);
+       xfs_dir3_leaf_log_header(tp, bp);
+       xfs_dir3_leaf_log_ents(tp, bp, lfloglow, lfloghigh);
+       xfs_dir3_leaf_check(mp, bp);
        return 0;
 }
 
 #ifdef DEBUG
-/*
- * Check internal consistency of a leafn block.
- */
-void
-xfs_dir2_leafn_check(
-       struct xfs_inode *dp,
-       struct xfs_buf  *bp)
-{
-       int             i;                      /* leaf index */
-       xfs_dir2_leaf_t *leaf;                  /* leaf structure */
-       xfs_mount_t     *mp;                    /* filesystem mount point */
-       int             stale;                  /* count of stale leaves */
-
-       leaf = bp->b_addr;
-       mp = dp->i_mount;
-       ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC));
-       ASSERT(be16_to_cpu(leaf->hdr.count) <= xfs_dir2_max_leaf_ents(mp));
-       for (i = stale = 0; i < be16_to_cpu(leaf->hdr.count); i++) {
-               if (i + 1 < be16_to_cpu(leaf->hdr.count)) {
-                       ASSERT(be32_to_cpu(leaf->ents[i].hashval) <=
-                              be32_to_cpu(leaf->ents[i + 1].hashval));
-               }
-               if (leaf->ents[i].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
-                       stale++;
-       }
-       ASSERT(be16_to_cpu(leaf->hdr.stale) == stale);
-}
-
 static void
 xfs_dir2_free_hdr_check(
        struct xfs_mount *mp,
@@ -510,15 +529,22 @@ xfs_dir2_leafn_lasthash(
        struct xfs_buf  *bp,                    /* leaf buffer */
        int             *count)                 /* count of entries in leaf */
 {
-       xfs_dir2_leaf_t *leaf;                  /* leaf structure */
+       struct xfs_dir2_leaf    *leaf = bp->b_addr;
+       struct xfs_dir2_leaf_entry *ents;
+       struct xfs_dir3_icleaf_hdr leafhdr;
+
+       xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
+
+       ASSERT(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC ||
+              leafhdr.magic == XFS_DIR3_LEAFN_MAGIC);
 
-       leaf = bp->b_addr;
-       ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC));
        if (count)
-               *count = be16_to_cpu(leaf->hdr.count);
-       if (!leaf->hdr.count)
+               *count = leafhdr.count;
+       if (!leafhdr.count)
                return 0;
-       return be32_to_cpu(leaf->ents[be16_to_cpu(leaf->hdr.count) - 1].hashval);
+
+       ents = xfs_dir3_leaf_ents_p(leaf);
+       return be32_to_cpu(ents[leafhdr.count - 1].hashval);
 }
 
 /*
@@ -547,16 +573,19 @@ xfs_dir2_leafn_lookup_for_addname(
        xfs_dir2_db_t           newdb;          /* new data block number */
        xfs_dir2_db_t           newfdb;         /* new free block number */
        xfs_trans_t             *tp;            /* transaction pointer */
+       struct xfs_dir2_leaf_entry *ents;
+       struct xfs_dir3_icleaf_hdr leafhdr;
 
        dp = args->dp;
        tp = args->trans;
        mp = dp->i_mount;
        leaf = bp->b_addr;
-       ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC));
-#ifdef __KERNEL__
-       ASSERT(be16_to_cpu(leaf->hdr.count) > 0);
-#endif
-       xfs_dir2_leafn_check(dp, bp);
+       xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
+       ents = xfs_dir3_leaf_ents_p(leaf);
+
+       xfs_dir3_leaf_check(mp, bp);
+       ASSERT(leafhdr.count > 0);
+
        /*
         * Look up the hash value in the leaf entries.
         */
@@ -576,9 +605,9 @@ xfs_dir2_leafn_lookup_for_addname(
        /*
         * Loop over leaf entries with the right hash value.
         */
-       for (lep = &leaf->ents[index]; index < be16_to_cpu(leaf->hdr.count) &&
-                               be32_to_cpu(lep->hashval) == args->hashval;
-                               lep++, index++) {
+       for (lep = &ents[index];
+            index < leafhdr.count && be32_to_cpu(lep->hashval) == args->hashval;
+            lep++, index++) {
                /*
                 * Skip stale leaf entries.
                 */
@@ -694,16 +723,19 @@ xfs_dir2_leafn_lookup_for_entry(
        xfs_dir2_db_t           newdb;          /* new data block number */
        xfs_trans_t             *tp;            /* transaction pointer */
        enum xfs_dacmp          cmp;            /* comparison result */
+       struct xfs_dir2_leaf_entry *ents;
+       struct xfs_dir3_icleaf_hdr leafhdr;
 
        dp = args->dp;
        tp = args->trans;
        mp = dp->i_mount;
        leaf = bp->b_addr;
-       ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC));
-#ifdef __KERNEL__
-       ASSERT(be16_to_cpu(leaf->hdr.count) > 0);
-#endif
-       xfs_dir2_leafn_check(dp, bp);
+       xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
+       ents = xfs_dir3_leaf_ents_p(leaf);
+
+       xfs_dir3_leaf_check(mp, bp);
+       ASSERT(leafhdr.count > 0);
+
        /*
         * Look up the hash value in the leaf entries.
         */
@@ -718,9 +750,9 @@ xfs_dir2_leafn_lookup_for_entry(
        /*
         * Loop over leaf entries with the right hash value.
         */
-       for (lep = &leaf->ents[index]; index < be16_to_cpu(leaf->hdr.count) &&
-                               be32_to_cpu(lep->hashval) == args->hashval;
-                               lep++, index++) {
+       for (lep = &ents[index];
+            index < leafhdr.count && be32_to_cpu(lep->hashval) == args->hashval;
+            lep++, index++) {
                /*
                 * Skip stale leaf entries.
                 */
@@ -753,13 +785,13 @@ xfs_dir2_leafn_lookup_for_entry(
                                ASSERT(state->extravalid);
                                curbp = state->extrablk.bp;
                        } else {
-                               error = xfs_dir2_data_read(tp, dp,
+                               error = xfs_dir3_data_read(tp, dp,
                                                xfs_dir2_db_to_da(mp, newdb),
                                                -1, &curbp);
                                if (error)
                                        return error;
                        }
-                       xfs_dir2_data_check(dp, curbp);
+                       xfs_dir3_data_check(dp, curbp);
                        curdb = newdb;
                }
                /*
@@ -787,13 +819,13 @@ xfs_dir2_leafn_lookup_for_entry(
                        state->extrablk.index = (int)((char *)dep -
                                                        (char *)curbp->b_addr);
                        state->extrablk.magic = XFS_DIR2_DATA_MAGIC;
-                       curbp->b_ops = &xfs_dir2_data_buf_ops;
+                       curbp->b_ops = &xfs_dir3_data_buf_ops;
+                       xfs_trans_buf_set_type(tp, curbp, XFS_BLFT_DIR_DATA_BUF);
                        if (cmp == XFS_CMP_EXACT)
                                return XFS_ERROR(EEXIST);
                }
        }
-       ASSERT(index == be16_to_cpu(leaf->hdr.count) ||
-                                       (args->op_flags & XFS_DA_OP_OKNOENT));
+       ASSERT(index == leafhdr.count || (args->op_flags & XFS_DA_OP_OKNOENT));
        if (curbp) {
                if (args->cmpresult == XFS_CMP_DIFFERENT) {
                        /* Giving back last used data block. */
@@ -802,7 +834,8 @@ xfs_dir2_leafn_lookup_for_entry(
                        state->extrablk.index = -1;
                        state->extrablk.blkno = curdb;
                        state->extrablk.magic = XFS_DIR2_DATA_MAGIC;
-                       curbp->b_ops = &xfs_dir2_data_buf_ops;
+                       curbp->b_ops = &xfs_dir3_data_buf_ops;
+                       xfs_trans_buf_set_type(tp, curbp, XFS_BLFT_DIR_DATA_BUF);
                } else {
                        /* If the curbp is not the CI match block, drop it */
                        if (state->extrablk.bp != curbp)
@@ -838,52 +871,50 @@ xfs_dir2_leafn_lookup_int(
  * Log entries and headers.  Stale entries are preserved.
  */
 static void
-xfs_dir2_leafn_moveents(
-       xfs_da_args_t   *args,                  /* operation arguments */
-       struct xfs_buf  *bp_s,                  /* source leaf buffer */
-       int             start_s,                /* source leaf index */
-       struct xfs_buf  *bp_d,                  /* destination leaf buffer */
-       int             start_d,                /* destination leaf index */
-       int             count)                  /* count of leaves to copy */
+xfs_dir3_leafn_moveents(
+       xfs_da_args_t                   *args,  /* operation arguments */
+       struct xfs_buf                  *bp_s,  /* source */
+       struct xfs_dir3_icleaf_hdr      *shdr,
+       struct xfs_dir2_leaf_entry      *sents,
+       int                             start_s,/* source leaf index */
+       struct xfs_buf                  *bp_d,  /* destination */
+       struct xfs_dir3_icleaf_hdr      *dhdr,
+       struct xfs_dir2_leaf_entry      *dents,
+       int                             start_d,/* destination leaf index */
+       int                             count)  /* count of leaves to copy */
 {
-       xfs_dir2_leaf_t *leaf_d;                /* destination leaf structure */
-       xfs_dir2_leaf_t *leaf_s;                /* source leaf structure */
-       int             stale;                  /* count stale leaves copied */
-       xfs_trans_t     *tp;                    /* transaction pointer */
+       struct xfs_trans                *tp = args->trans;
+       int                             stale;  /* count stale leaves copied */
 
        trace_xfs_dir2_leafn_moveents(args, start_s, start_d, count);
 
        /*
         * Silently return if nothing to do.
         */
-       if (count == 0) {
+       if (count == 0)
                return;
-       }
-       tp = args->trans;
-       leaf_s = bp_s->b_addr;
-       leaf_d = bp_d->b_addr;
+
        /*
         * If the destination index is not the end of the current
         * destination leaf entries, open up a hole in the destination
         * to hold the new entries.
         */
-       if (start_d < be16_to_cpu(leaf_d->hdr.count)) {
-               memmove(&leaf_d->ents[start_d + count], &leaf_d->ents[start_d],
-                       (be16_to_cpu(leaf_d->hdr.count) - start_d) *
-                       sizeof(xfs_dir2_leaf_entry_t));
-               xfs_dir2_leaf_log_ents(tp, bp_d, start_d + count,
-                       count + be16_to_cpu(leaf_d->hdr.count) - 1);
+       if (start_d < dhdr->count) {
+               memmove(&dents[start_d + count], &dents[start_d],
+                       (dhdr->count - start_d) * sizeof(xfs_dir2_leaf_entry_t));
+               xfs_dir3_leaf_log_ents(tp, bp_d, start_d + count,
+                                      count + dhdr->count - 1);
        }
        /*
         * If the source has stale leaves, count the ones in the copy range
         * so we can update the header correctly.
         */
-       if (leaf_s->hdr.stale) {
+       if (shdr->stale) {
                int     i;                      /* temp leaf index */
 
                for (i = start_s, stale = 0; i < start_s + count; i++) {
-                       if (leaf_s->ents[i].address ==
-                           cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
+                       if (sents[i].address ==
+                                       cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
                                stale++;
                }
        } else
@@ -891,29 +922,27 @@ xfs_dir2_leafn_moveents(
        /*
         * Copy the leaf entries from source to destination.
         */
-       memcpy(&leaf_d->ents[start_d], &leaf_s->ents[start_s],
+       memcpy(&dents[start_d], &sents[start_s],
                count * sizeof(xfs_dir2_leaf_entry_t));
-       xfs_dir2_leaf_log_ents(tp, bp_d, start_d, start_d + count - 1);
+       xfs_dir3_leaf_log_ents(tp, bp_d, start_d, start_d + count - 1);
+
        /*
         * If there are source entries after the ones we copied,
         * delete the ones we copied by sliding the next ones down.
         */
-       if (start_s + count < be16_to_cpu(leaf_s->hdr.count)) {
-               memmove(&leaf_s->ents[start_s], &leaf_s->ents[start_s + count],
+       if (start_s + count < shdr->count) {
+               memmove(&sents[start_s], &sents[start_s + count],
                        count * sizeof(xfs_dir2_leaf_entry_t));
-               xfs_dir2_leaf_log_ents(tp, bp_s, start_s, start_s + count - 1);
+               xfs_dir3_leaf_log_ents(tp, bp_s, start_s, start_s + count - 1);
        }
+
        /*
         * Update the headers and log them.
         */
-       be16_add_cpu(&leaf_s->hdr.count, -(count));
-       be16_add_cpu(&leaf_s->hdr.stale, -(stale));
-       be16_add_cpu(&leaf_d->hdr.count, count);
-       be16_add_cpu(&leaf_d->hdr.stale, stale);
-       xfs_dir2_leaf_log_header(tp, bp_s);
-       xfs_dir2_leaf_log_header(tp, bp_d);
-       xfs_dir2_leafn_check(args->dp, bp_s);
-       xfs_dir2_leafn_check(args->dp, bp_d);
+       shdr->count -= count;
+       shdr->stale -= stale;
+       dhdr->count += count;
+       dhdr->stale += stale;
 }
 
 /*
@@ -922,21 +951,25 @@ xfs_dir2_leafn_moveents(
  */
 int                                            /* sort order */
 xfs_dir2_leafn_order(
-       struct xfs_buf  *leaf1_bp,              /* leaf1 buffer */
-       struct xfs_buf  *leaf2_bp)              /* leaf2 buffer */
+       struct xfs_buf          *leaf1_bp,              /* leaf1 buffer */
+       struct xfs_buf          *leaf2_bp)              /* leaf2 buffer */
 {
-       xfs_dir2_leaf_t *leaf1;                 /* leaf1 structure */
-       xfs_dir2_leaf_t *leaf2;                 /* leaf2 structure */
-
-       leaf1 = leaf1_bp->b_addr;
-       leaf2 = leaf2_bp->b_addr;
-       ASSERT(leaf1->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC));
-       ASSERT(leaf2->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC));
-       if (be16_to_cpu(leaf1->hdr.count) > 0 &&
-           be16_to_cpu(leaf2->hdr.count) > 0 &&
-           (be32_to_cpu(leaf2->ents[0].hashval) < be32_to_cpu(leaf1->ents[0].hashval) ||
-            be32_to_cpu(leaf2->ents[be16_to_cpu(leaf2->hdr.count) - 1].hashval) <
-            be32_to_cpu(leaf1->ents[be16_to_cpu(leaf1->hdr.count) - 1].hashval)))
+       struct xfs_dir2_leaf    *leaf1 = leaf1_bp->b_addr;
+       struct xfs_dir2_leaf    *leaf2 = leaf2_bp->b_addr;
+       struct xfs_dir2_leaf_entry *ents1;
+       struct xfs_dir2_leaf_entry *ents2;
+       struct xfs_dir3_icleaf_hdr hdr1;
+       struct xfs_dir3_icleaf_hdr hdr2;
+
+       xfs_dir3_leaf_hdr_from_disk(&hdr1, leaf1);
+       xfs_dir3_leaf_hdr_from_disk(&hdr2, leaf2);
+       ents1 = xfs_dir3_leaf_ents_p(leaf1);
+       ents2 = xfs_dir3_leaf_ents_p(leaf2);
+
+       if (hdr1.count > 0 && hdr2.count > 0 &&
+           (be32_to_cpu(ents2[0].hashval) < be32_to_cpu(ents1[0].hashval) ||
+            be32_to_cpu(ents2[hdr2.count - 1].hashval) <
+                               be32_to_cpu(ents1[hdr1.count - 1].hashval)))
                return 1;
        return 0;
 }
@@ -960,11 +993,15 @@ xfs_dir2_leafn_rebalance(
        xfs_dir2_leaf_t         *leaf1;         /* first leaf structure */
        xfs_dir2_leaf_t         *leaf2;         /* second leaf structure */
        int                     mid;            /* midpoint leaf index */
-#ifdef DEBUG
+#if defined(DEBUG) || defined(XFS_WARN)
        int                     oldstale;       /* old count of stale leaves */
 #endif
        int                     oldsum;         /* old total leaf count */
        int                     swap;           /* swapped leaf blocks */
+       struct xfs_dir2_leaf_entry *ents1;
+       struct xfs_dir2_leaf_entry *ents2;
+       struct xfs_dir3_icleaf_hdr hdr1;
+       struct xfs_dir3_icleaf_hdr hdr2;
 
        args = state->args;
        /*
@@ -979,11 +1016,17 @@ xfs_dir2_leafn_rebalance(
        }
        leaf1 = blk1->bp->b_addr;
        leaf2 = blk2->bp->b_addr;
-       oldsum = be16_to_cpu(leaf1->hdr.count) + be16_to_cpu(leaf2->hdr.count);
-#ifdef DEBUG
-       oldstale = be16_to_cpu(leaf1->hdr.stale) + be16_to_cpu(leaf2->hdr.stale);
+       xfs_dir3_leaf_hdr_from_disk(&hdr1, leaf1);
+       xfs_dir3_leaf_hdr_from_disk(&hdr2, leaf2);
+       ents1 = xfs_dir3_leaf_ents_p(leaf1);
+       ents2 = xfs_dir3_leaf_ents_p(leaf2);
+
+       oldsum = hdr1.count + hdr2.count;
+#if defined(DEBUG) || defined(XFS_WARN)
+       oldstale = hdr1.stale + hdr2.stale;
 #endif
        mid = oldsum >> 1;
+
        /*
         * If the old leaf count was odd then the new one will be even,
         * so we need to divide the new count evenly.
@@ -991,10 +1034,10 @@ xfs_dir2_leafn_rebalance(
        if (oldsum & 1) {
                xfs_dahash_t    midhash;        /* middle entry hash value */
 
-               if (mid >= be16_to_cpu(leaf1->hdr.count))
-                       midhash = be32_to_cpu(leaf2->ents[mid - be16_to_cpu(leaf1->hdr.count)].hashval);
+               if (mid >= hdr1.count)
+                       midhash = be32_to_cpu(ents2[mid - hdr1.count].hashval);
                else
-                       midhash = be32_to_cpu(leaf1->ents[mid].hashval);
+                       midhash = be32_to_cpu(ents1[mid].hashval);
                isleft = args->hashval <= midhash;
        }
        /*
@@ -1008,30 +1051,42 @@ xfs_dir2_leafn_rebalance(
         * Calculate moved entry count.  Positive means left-to-right,
         * negative means right-to-left.  Then move the entries.
         */
-       count = be16_to_cpu(leaf1->hdr.count) - mid + (isleft == 0);
+       count = hdr1.count - mid + (isleft == 0);
        if (count > 0)
-               xfs_dir2_leafn_moveents(args, blk1->bp,
-                       be16_to_cpu(leaf1->hdr.count) - count, blk2->bp, 0, count);
+               xfs_dir3_leafn_moveents(args, blk1->bp, &hdr1, ents1,
+                                       hdr1.count - count, blk2->bp,
+                                       &hdr2, ents2, 0, count);
        else if (count < 0)
-               xfs_dir2_leafn_moveents(args, blk2->bp, 0, blk1->bp,
-                       be16_to_cpu(leaf1->hdr.count), count);
-       ASSERT(be16_to_cpu(leaf1->hdr.count) + be16_to_cpu(leaf2->hdr.count) == oldsum);
-       ASSERT(be16_to_cpu(leaf1->hdr.stale) + be16_to_cpu(leaf2->hdr.stale) == oldstale);
+               xfs_dir3_leafn_moveents(args, blk2->bp, &hdr2, ents2, 0,
+                                       blk1->bp, &hdr1, ents1,
+                                       hdr1.count, count);
+
+       ASSERT(hdr1.count + hdr2.count == oldsum);
+       ASSERT(hdr1.stale + hdr2.stale == oldstale);
+
+       /* log the changes made when moving the entries */
+       xfs_dir3_leaf_hdr_to_disk(leaf1, &hdr1);
+       xfs_dir3_leaf_hdr_to_disk(leaf2, &hdr2);
+       xfs_dir3_leaf_log_header(args->trans, blk1->bp);
+       xfs_dir3_leaf_log_header(args->trans, blk2->bp);
+
+       xfs_dir3_leaf_check(args->dp->i_mount, blk1->bp);
+       xfs_dir3_leaf_check(args->dp->i_mount, blk2->bp);
+
        /*
         * Mark whether we're inserting into the old or new leaf.
         */
-       if (be16_to_cpu(leaf1->hdr.count) < be16_to_cpu(leaf2->hdr.count))
+       if (hdr1.count < hdr2.count)
                state->inleaf = swap;
-       else if (be16_to_cpu(leaf1->hdr.count) > be16_to_cpu(leaf2->hdr.count))
+       else if (hdr1.count > hdr2.count)
                state->inleaf = !swap;
        else
-               state->inleaf =
-                       swap ^ (blk1->index <= be16_to_cpu(leaf1->hdr.count));
+               state->inleaf = swap ^ (blk1->index <= hdr1.count);
        /*
         * Adjust the expected index for insertion.
         */
        if (!state->inleaf)
-               blk2->index = blk1->index - be16_to_cpu(leaf1->hdr.count);
+               blk2->index = blk1->index - hdr1.count;
 
        /*
         * Finally sanity check just to make sure we are not returning a
@@ -1152,6 +1207,9 @@ xfs_dir2_leafn_remove(
        int                     needlog;        /* need to log data header */
        int                     needscan;       /* need to rescan data frees */
        xfs_trans_t             *tp;            /* transaction pointer */
+       struct xfs_dir2_data_free *bf;          /* bestfree table */
+       struct xfs_dir3_icleaf_hdr leafhdr;
+       struct xfs_dir2_leaf_entry *ents;
 
        trace_xfs_dir2_leafn_remove(args, index);
 
@@ -1159,11 +1217,14 @@ xfs_dir2_leafn_remove(
        tp = args->trans;
        mp = dp->i_mount;
        leaf = bp->b_addr;
-       ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC));
+       xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
+       ents = xfs_dir3_leaf_ents_p(leaf);
+
        /*
         * Point to the entry we're removing.
         */
-       lep = &leaf->ents[index];
+       lep = &ents[index];
+
        /*
         * Extract the data block and offset from the entry.
         */
@@ -1171,14 +1232,18 @@ xfs_dir2_leafn_remove(
        ASSERT(dblk->blkno == db);
        off = xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address));
        ASSERT(dblk->index == off);
+
        /*
         * Kill the leaf entry by marking it stale.
         * Log the leaf block changes.
         */
-       be16_add_cpu(&leaf->hdr.stale, 1);
-       xfs_dir2_leaf_log_header(tp, bp);
+       leafhdr.stale++;
+       xfs_dir3_leaf_hdr_to_disk(leaf, &leafhdr);
+       xfs_dir3_leaf_log_header(tp, bp);
+
        lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR);
-       xfs_dir2_leaf_log_ents(tp, bp, index, index);
+       xfs_dir3_leaf_log_ents(tp, bp, index, index);
+
        /*
         * Make the data entry free.  Keep track of the longest freespace
         * in the data block in case it changes.
@@ -1186,7 +1251,8 @@ xfs_dir2_leafn_remove(
        dbp = dblk->bp;
        hdr = dbp->b_addr;
        dep = (xfs_dir2_data_entry_t *)((char *)hdr + off);
-       longest = be16_to_cpu(hdr->bestfree[0].length);
+       bf = xfs_dir3_data_bestfree_p(hdr);
+       longest = be16_to_cpu(bf[0].length);
        needlog = needscan = 0;
        xfs_dir2_data_make_free(tp, dbp, off,
                xfs_dir2_data_entsize(dep->namelen), &needlog, &needscan);
@@ -1198,12 +1264,12 @@ xfs_dir2_leafn_remove(
                xfs_dir2_data_freescan(mp, hdr, &needlog);
        if (needlog)
                xfs_dir2_data_log_header(tp, dbp);
-       xfs_dir2_data_check(dp, dbp);
+       xfs_dir3_data_check(dp, dbp);
        /*
         * If the longest data block freespace changes, need to update
         * the corresponding freeblock entry.
         */
-       if (longest < be16_to_cpu(hdr->bestfree[0].length)) {
+       if (longest < be16_to_cpu(bf[0].length)) {
                int             error;          /* error return value */
                struct xfs_buf  *fbp;           /* freeblock buffer */
                xfs_dir2_db_t   fdb;            /* freeblock block number */
@@ -1232,12 +1298,13 @@ xfs_dir2_leafn_remove(
                 * Calculate which entry we need to fix.
                 */
                findex = xfs_dir2_db_to_fdindex(mp, db);
-               longest = be16_to_cpu(hdr->bestfree[0].length);
+               longest = be16_to_cpu(bf[0].length);
                /*
                 * If the data block is now empty we can get rid of it
                 * (usually).
                 */
-               if (longest == mp->m_dirblksize - (uint)sizeof(*hdr)) {
+               if (longest == mp->m_dirblksize -
+                              xfs_dir3_data_entry_offset(hdr)) {
                        /*
                         * Try to punch out the data block.
                         */
@@ -1264,15 +1331,13 @@ xfs_dir2_leafn_remove(
                        return error;
        }
 
-       xfs_dir2_leafn_check(dp, bp);
+       xfs_dir3_leaf_check(mp, bp);
        /*
         * Return indication of whether this leaf block is empty enough
         * to justify trying to join it with a neighbor.
         */
-       *rval =
-               ((uint)sizeof(leaf->hdr) +
-                (uint)sizeof(leaf->ents[0]) *
-                (be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale))) <
+       *rval = (xfs_dir3_leaf_hdr_size(leaf) +
+                (uint)sizeof(ents[0]) * (leafhdr.count - leafhdr.stale)) <
                mp->m_dir_magicpct;
        return 0;
 }
@@ -1305,11 +1370,11 @@ xfs_dir2_leafn_split(
        /*
         * Initialize the new leaf block.
         */
-       error = xfs_dir2_leaf_init(args, xfs_dir2_da_to_db(mp, blkno),
-               &newblk->bp, XFS_DIR2_LEAFN_MAGIC);
-       if (error) {
+       error = xfs_dir3_leaf_get_buf(args, xfs_dir2_da_to_db(mp, blkno),
+                                     &newblk->bp, XFS_DIR2_LEAFN_MAGIC);
+       if (error)
                return error;
-       }
+
        newblk->blkno = blkno;
        newblk->magic = XFS_DIR2_LEAFN_MAGIC;
        /*
@@ -1317,7 +1382,7 @@ xfs_dir2_leafn_split(
         * block into the leaves.
         */
        xfs_dir2_leafn_rebalance(state, oldblk, newblk);
-       error = xfs_da_blk_link(state, oldblk, newblk);
+       error = xfs_da3_blk_link(state, oldblk, newblk);
        if (error) {
                return error;
        }
@@ -1333,8 +1398,8 @@ xfs_dir2_leafn_split(
         */
        oldblk->hashval = xfs_dir2_leafn_lasthash(oldblk->bp, NULL);
        newblk->hashval = xfs_dir2_leafn_lasthash(newblk->bp, NULL);
-       xfs_dir2_leafn_check(args->dp, oldblk->bp);
-       xfs_dir2_leafn_check(args->dp, newblk->bp);
+       xfs_dir3_leaf_check(mp, oldblk->bp);
+       xfs_dir3_leaf_check(mp, newblk->bp);
        return error;
 }
 
@@ -1360,9 +1425,10 @@ xfs_dir2_leafn_toosmall(
        int                     error;          /* error return value */
        int                     forward;        /* sibling block direction */
        int                     i;              /* sibling counter */
-       xfs_da_blkinfo_t        *info;          /* leaf block header */
        xfs_dir2_leaf_t         *leaf;          /* leaf structure */
        int                     rval;           /* result from path_shift */
+       struct xfs_dir3_icleaf_hdr leafhdr;
+       struct xfs_dir2_leaf_entry *ents;
 
        /*
         * Check for the degenerate case of the block being over 50% full.
@@ -1370,11 +1436,13 @@ xfs_dir2_leafn_toosmall(
         * to coalesce with a sibling.
         */
        blk = &state->path.blk[state->path.active - 1];
-       info = blk->bp->b_addr;
-       ASSERT(info->magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC));
-       leaf = (xfs_dir2_leaf_t *)info;
-       count = be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale);
-       bytes = (uint)sizeof(leaf->hdr) + count * (uint)sizeof(leaf->ents[0]);
+       leaf = blk->bp->b_addr;
+       xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
+       ents = xfs_dir3_leaf_ents_p(leaf);
+       xfs_dir3_leaf_check(state->args->dp->i_mount, blk->bp);
+
+       count = leafhdr.count - leafhdr.stale;
+       bytes = xfs_dir3_leaf_hdr_size(leaf) + count * sizeof(ents[0]);
        if (bytes > (state->blocksize >> 1)) {
                /*
                 * Blk over 50%, don't try to join.
@@ -1393,9 +1461,9 @@ xfs_dir2_leafn_toosmall(
                 * Make altpath point to the block we want to keep and
                 * path point to the block we want to drop (this one).
                 */
-               forward = (info->forw != 0);
+               forward = (leafhdr.forw != 0);
                memcpy(&state->altpath, &state->path, sizeof(state->path));
-               error = xfs_da_path_shift(state, &state->altpath, forward, 0,
+               error = xfs_da3_path_shift(state, &state->altpath, forward, 0,
                        &rval);
                if (error)
                        return error;
@@ -1409,15 +1477,17 @@ xfs_dir2_leafn_toosmall(
         * We prefer coalescing with the lower numbered sibling so as
         * to shrink a directory over time.
         */
-       forward = be32_to_cpu(info->forw) < be32_to_cpu(info->back);
+       forward = leafhdr.forw < leafhdr.back;
        for (i = 0, bp = NULL; i < 2; forward = !forward, i++) {
-               blkno = forward ? be32_to_cpu(info->forw) : be32_to_cpu(info->back);
+               struct xfs_dir3_icleaf_hdr hdr2;
+
+               blkno = forward ? leafhdr.forw : leafhdr.back;
                if (blkno == 0)
                        continue;
                /*
                 * Read the sibling leaf block.
                 */
-               error = xfs_dir2_leafn_read(state->args->trans, state->args->dp,
+               error = xfs_dir3_leafn_read(state->args->trans, state->args->dp,
                                            blkno, -1, &bp);
                if (error)
                        return error;
@@ -1425,13 +1495,15 @@ xfs_dir2_leafn_toosmall(
                /*
                 * Count bytes in the two blocks combined.
                 */
-               leaf = (xfs_dir2_leaf_t *)info;
-               count = be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale);
+               count = leafhdr.count - leafhdr.stale;
                bytes = state->blocksize - (state->blocksize >> 2);
+
                leaf = bp->b_addr;
-               ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC));
-               count += be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale);
-               bytes -= count * (uint)sizeof(leaf->ents[0]);
+               xfs_dir3_leaf_hdr_from_disk(&hdr2, leaf);
+               ents = xfs_dir3_leaf_ents_p(leaf);
+               count += hdr2.count - hdr2.stale;
+               bytes -= count * sizeof(ents[0]);
+
                /*
                 * Fits with at least 25% to spare.
                 */
@@ -1453,10 +1525,10 @@ xfs_dir2_leafn_toosmall(
         */
        memcpy(&state->altpath, &state->path, sizeof(state->path));
        if (blkno < blk->blkno)
-               error = xfs_da_path_shift(state, &state->altpath, forward, 0,
+               error = xfs_da3_path_shift(state, &state->altpath, forward, 0,
                        &rval);
        else
-               error = xfs_da_path_shift(state, &state->path, forward, 0,
+               error = xfs_da3_path_shift(state, &state->path, forward, 0,
                        &rval);
        if (error) {
                return error;
@@ -1478,34 +1550,53 @@ xfs_dir2_leafn_unbalance(
        xfs_da_args_t           *args;          /* operation arguments */
        xfs_dir2_leaf_t         *drop_leaf;     /* dead leaf structure */
        xfs_dir2_leaf_t         *save_leaf;     /* surviving leaf structure */
+       struct xfs_dir3_icleaf_hdr savehdr;
+       struct xfs_dir3_icleaf_hdr drophdr;
+       struct xfs_dir2_leaf_entry *sents;
+       struct xfs_dir2_leaf_entry *dents;
 
        args = state->args;
        ASSERT(drop_blk->magic == XFS_DIR2_LEAFN_MAGIC);
        ASSERT(save_blk->magic == XFS_DIR2_LEAFN_MAGIC);
        drop_leaf = drop_blk->bp->b_addr;
        save_leaf = save_blk->bp->b_addr;
-       ASSERT(drop_leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC));
-       ASSERT(save_leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC));
+
+       xfs_dir3_leaf_hdr_from_disk(&savehdr, save_leaf);
+       xfs_dir3_leaf_hdr_from_disk(&drophdr, drop_leaf);
+       sents = xfs_dir3_leaf_ents_p(save_leaf);
+       dents = xfs_dir3_leaf_ents_p(drop_leaf);
+
        /*
         * If there are any stale leaf entries, take this opportunity
         * to purge them.
         */
-       if (drop_leaf->hdr.stale)
-               xfs_dir2_leaf_compact(args, drop_blk->bp);
-       if (save_leaf->hdr.stale)
-               xfs_dir2_leaf_compact(args, save_blk->bp);
+       if (drophdr.stale)
+               xfs_dir3_leaf_compact(args, &drophdr, drop_blk->bp);
+       if (savehdr.stale)
+               xfs_dir3_leaf_compact(args, &savehdr, save_blk->bp);
+
        /*
         * Move the entries from drop to the appropriate end of save.
         */
-       drop_blk->hashval = be32_to_cpu(drop_leaf->ents[be16_to_cpu(drop_leaf->hdr.count) - 1].hashval);
+       drop_blk->hashval = be32_to_cpu(dents[drophdr.count - 1].hashval);
        if (xfs_dir2_leafn_order(save_blk->bp, drop_blk->bp))
-               xfs_dir2_leafn_moveents(args, drop_blk->bp, 0, save_blk->bp, 0,
-                       be16_to_cpu(drop_leaf->hdr.count));
+               xfs_dir3_leafn_moveents(args, drop_blk->bp, &drophdr, dents, 0,
+                                       save_blk->bp, &savehdr, sents, 0,
+                                       drophdr.count);
        else
-               xfs_dir2_leafn_moveents(args, drop_blk->bp, 0, save_blk->bp,
-                       be16_to_cpu(save_leaf->hdr.count), be16_to_cpu(drop_leaf->hdr.count));
-       save_blk->hashval = be32_to_cpu(save_leaf->ents[be16_to_cpu(save_leaf->hdr.count) - 1].hashval);
-       xfs_dir2_leafn_check(args->dp, save_blk->bp);
+               xfs_dir3_leafn_moveents(args, drop_blk->bp, &drophdr, dents, 0,
+                                       save_blk->bp, &savehdr, sents,
+                                       savehdr.count, drophdr.count);
+       save_blk->hashval = be32_to_cpu(sents[savehdr.count - 1].hashval);
+
+       /* log the changes made when moving the entries */
+       xfs_dir3_leaf_hdr_to_disk(save_leaf, &savehdr);
+       xfs_dir3_leaf_hdr_to_disk(drop_leaf, &drophdr);
+       xfs_dir3_leaf_log_header(args->trans, save_blk->bp);
+       xfs_dir3_leaf_log_header(args->trans, drop_blk->bp);
+
+       xfs_dir3_leaf_check(args->dp->i_mount, save_blk->bp);
+       xfs_dir3_leaf_check(args->dp->i_mount, drop_blk->bp);
 }
 
 /*
@@ -1534,7 +1625,7 @@ xfs_dir2_node_addname(
         * Look up the name.  We're not supposed to find it, but
         * this gives us the insertion point.
         */
-       error = xfs_da_node_lookup_int(state, &rval);
+       error = xfs_da3_node_lookup_int(state, &rval);
        if (error)
                rval = error;
        if (rval != ENOENT) {
@@ -1560,7 +1651,7 @@ xfs_dir2_node_addname(
                 * It worked, fix the hash values up the btree.
                 */
                if (!(args->op_flags & XFS_DA_OP_JUSTCHECK))
-                       xfs_da_fixhashpath(state, &state->path);
+                       xfs_da3_fixhashpath(state, &state->path);
        } else {
                /*
                 * It didn't work, we need to split the leaf block.
@@ -1572,7 +1663,7 @@ xfs_dir2_node_addname(
                /*
                 * Split the leaf block and insert the new entry.
                 */
-               rval = xfs_da_split(state);
+               rval = xfs_da3_split(state);
        }
 done:
        xfs_da_state_free(state);
@@ -1611,6 +1702,7 @@ xfs_dir2_node_addname_int(
        xfs_trans_t             *tp;            /* transaction pointer */
        __be16                  *bests;
        struct xfs_dir3_icfree_hdr freehdr;
+       struct xfs_dir2_data_free *bf;
 
        dp = args->dp;
        mp = dp->i_mount;
@@ -1868,7 +1960,8 @@ xfs_dir2_node_addname_int(
                 * change again.
                 */
                hdr = dbp->b_addr;
-               bests[findex] = hdr->bestfree[0].length;
+               bf = xfs_dir3_data_bestfree_p(hdr);
+               bests[findex] = bf[0].length;
                logfree = 1;
        }
        /*
@@ -1884,19 +1977,20 @@ xfs_dir2_node_addname_int(
                /*
                 * Read the data block in.
                 */
-               error = xfs_dir2_data_read(tp, dp, xfs_dir2_db_to_da(mp, dbno),
+               error = xfs_dir3_data_read(tp, dp, xfs_dir2_db_to_da(mp, dbno),
                                           -1, &dbp);
                if (error)
                        return error;
                hdr = dbp->b_addr;
+               bf = xfs_dir3_data_bestfree_p(hdr);
                logfree = 0;
        }
-       ASSERT(be16_to_cpu(hdr->bestfree[0].length) >= length);
+       ASSERT(be16_to_cpu(bf[0].length) >= length);
        /*
         * Point to the existing unused space.
         */
        dup = (xfs_dir2_data_unused_t *)
-             ((char *)hdr + be16_to_cpu(hdr->bestfree[0].offset));
+             ((char *)hdr + be16_to_cpu(bf[0].offset));
        needscan = needlog = 0;
        /*
         * Mark the first part of the unused space, inuse for us.
@@ -1928,8 +2022,8 @@ xfs_dir2_node_addname_int(
         * If the freespace entry is now wrong, update it.
         */
        bests = xfs_dir3_free_bests_p(mp, free); /* gcc is so stupid */
-       if (be16_to_cpu(bests[findex]) != be16_to_cpu(hdr->bestfree[0].length)) {
-               bests[findex] = hdr->bestfree[0].length;
+       if (be16_to_cpu(bests[findex]) != be16_to_cpu(bf[0].length)) {
+               bests[findex] = bf[0].length;
                logfree = 1;
        }
        /*
@@ -1947,7 +2041,7 @@ xfs_dir2_node_addname_int(
 
 /*
  * Lookup an entry in a node-format directory.
- * All the real work happens in xfs_da_node_lookup_int.
+ * All the real work happens in xfs_da3_node_lookup_int.
  * The only real output is the inode number of the entry.
  */
 int                                            /* error */
@@ -1972,7 +2066,7 @@ xfs_dir2_node_lookup(
        /*
         * Fill in the path to the entry in the cursor.
         */
-       error = xfs_da_node_lookup_int(state, &rval);
+       error = xfs_da3_node_lookup_int(state, &rval);
        if (error)
                rval = error;
        else if (rval == ENOENT && args->cmpresult == XFS_CMP_CASE) {
@@ -2027,7 +2121,7 @@ xfs_dir2_node_removename(
        /*
         * Look up the entry we're deleting, set up the cursor.
         */
-       error = xfs_da_node_lookup_int(state, &rval);
+       error = xfs_da3_node_lookup_int(state, &rval);
        if (error)
                rval = error;
        /*
@@ -2051,12 +2145,12 @@ xfs_dir2_node_removename(
        /*
         * Fix the hash values up the btree.
         */
-       xfs_da_fixhashpath(state, &state->path);
+       xfs_da3_fixhashpath(state, &state->path);
        /*
         * If we need to join leaf blocks, do it.
         */
        if (rval && state->path.active > 1)
-               error = xfs_da_join(state);
+               error = xfs_da3_join(state);
        /*
         * If no errors so far, try conversion to leaf format.
         */
@@ -2098,7 +2192,7 @@ xfs_dir2_node_replace(
        /*
         * Lookup the entry to change in the btree.
         */
-       error = xfs_da_node_lookup_int(state, &rval);
+       error = xfs_da3_node_lookup_int(state, &rval);
        if (error) {
                rval = error;
        }
@@ -2107,19 +2201,22 @@ xfs_dir2_node_replace(
         * and locked it.  But paranoia is good.
         */
        if (rval == EEXIST) {
+               struct xfs_dir2_leaf_entry *ents;
                /*
                 * Find the leaf entry.
                 */
                blk = &state->path.blk[state->path.active - 1];
                ASSERT(blk->magic == XFS_DIR2_LEAFN_MAGIC);
                leaf = blk->bp->b_addr;
-               lep = &leaf->ents[blk->index];
+               ents = xfs_dir3_leaf_ents_p(leaf);
+               lep = &ents[blk->index];
                ASSERT(state->extravalid);
                /*
                 * Point to the data entry.
                 */
                hdr = state->extrablk.bp->b_addr;
-               ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC));
+               ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
+                      hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC));
                dep = (xfs_dir2_data_entry_t *)
                      ((char *)hdr +
                       xfs_dir2_dataptr_to_off(state->mp, be32_to_cpu(lep->address)));