aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_da_btree.c45
-rw-r--r--fs/xfs/xfs_da_btree.h23
-rw-r--r--fs/xfs/xfs_dir2_block.c19
-rw-r--r--fs/xfs/xfs_dir2_format.h60
-rw-r--r--fs/xfs/xfs_dir2_leaf.c792
-rw-r--r--fs/xfs/xfs_dir2_node.c475
-rw-r--r--fs/xfs/xfs_dir2_priv.h32
7 files changed, 924 insertions, 522 deletions
diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c
index 4d7696a02418..2f23b14e3adf 100644
--- a/fs/xfs/xfs_da_btree.c
+++ b/fs/xfs/xfs_da_btree.c
@@ -139,7 +139,8 @@ xfs_da_node_read_verify(
139 bp->b_ops->verify_read(bp); 139 bp->b_ops->verify_read(bp);
140 return; 140 return;
141 case XFS_DIR2_LEAFN_MAGIC: 141 case XFS_DIR2_LEAFN_MAGIC:
142 bp->b_ops = &xfs_dir2_leafn_buf_ops; 142 case XFS_DIR3_LEAFN_MAGIC:
143 bp->b_ops = &xfs_dir3_leafn_buf_ops;
143 bp->b_ops->verify_read(bp); 144 bp->b_ops->verify_read(bp);
144 return; 145 return;
145 default: 146 default:
@@ -396,11 +397,18 @@ xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
396 size = (int)((char *)&oldroot->btree[be16_to_cpu(oldroot->hdr.count)] - 397 size = (int)((char *)&oldroot->btree[be16_to_cpu(oldroot->hdr.count)] -
397 (char *)oldroot); 398 (char *)oldroot);
398 } else { 399 } else {
399 ASSERT(oldroot->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); 400 struct xfs_dir3_icleaf_hdr leafhdr;
401 struct xfs_dir2_leaf_entry *ents;
402
400 leaf = (xfs_dir2_leaf_t *)oldroot; 403 leaf = (xfs_dir2_leaf_t *)oldroot;
401 size = (int)((char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] - 404 xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
402 (char *)leaf); 405 ents = xfs_dir3_leaf_ents_p(leaf);
406
407 ASSERT(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC ||
408 leafhdr.magic == XFS_DIR3_LEAFN_MAGIC);
409 size = (int)((char *)&ents[leafhdr.count] - (char *)leaf);
403 } 410 }
411 /* XXX: can't just copy CRC headers from one block to another */
404 memcpy(node, oldroot, size); 412 memcpy(node, oldroot, size);
405 xfs_trans_log_buf(tp, bp, 0, size - 1); 413 xfs_trans_log_buf(tp, bp, 0, size - 1);
406 414
@@ -424,7 +432,8 @@ xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
424 node->hdr.count = cpu_to_be16(2); 432 node->hdr.count = cpu_to_be16(2);
425 433
426#ifdef DEBUG 434#ifdef DEBUG
427 if (oldroot->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)) { 435 if (oldroot->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
436 oldroot->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC)) {
428 ASSERT(blk1->blkno >= mp->m_dirleafblk && 437 ASSERT(blk1->blkno >= mp->m_dirleafblk &&
429 blk1->blkno < mp->m_dirfreeblk); 438 blk1->blkno < mp->m_dirfreeblk);
430 ASSERT(blk2->blkno >= mp->m_dirleafblk && 439 ASSERT(blk2->blkno >= mp->m_dirleafblk &&
@@ -782,6 +791,7 @@ xfs_da_blkinfo_onlychild_validate(struct xfs_da_blkinfo *blkinfo, __u16 level)
782 791
783 if (level == 1) { 792 if (level == 1) {
784 ASSERT(magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) || 793 ASSERT(magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
794 magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC) ||
785 magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 795 magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
786 } else 796 } else
787 ASSERT(magic == cpu_to_be16(XFS_DA_NODE_MAGIC)); 797 ASSERT(magic == cpu_to_be16(XFS_DA_NODE_MAGIC));
@@ -1565,6 +1575,7 @@ xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path,
1565 info = blk->bp->b_addr; 1575 info = blk->bp->b_addr;
1566 ASSERT(info->magic == cpu_to_be16(XFS_DA_NODE_MAGIC) || 1576 ASSERT(info->magic == cpu_to_be16(XFS_DA_NODE_MAGIC) ||
1567 info->magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) || 1577 info->magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
1578 info->magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC) ||
1568 info->magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 1579 info->magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
1569 blk->magic = be16_to_cpu(info->magic); 1580 blk->magic = be16_to_cpu(info->magic);
1570 if (blk->magic == XFS_DA_NODE_MAGIC) { 1581 if (blk->magic == XFS_DA_NODE_MAGIC) {
@@ -1584,12 +1595,13 @@ xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path,
1584 NULL); 1595 NULL);
1585 break; 1596 break;
1586 case XFS_DIR2_LEAFN_MAGIC: 1597 case XFS_DIR2_LEAFN_MAGIC:
1598 case XFS_DIR3_LEAFN_MAGIC:
1599 blk->magic = XFS_DIR2_LEAFN_MAGIC;
1587 blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, 1600 blk->hashval = xfs_dir2_leafn_lasthash(blk->bp,
1588 NULL); 1601 NULL);
1589 break; 1602 break;
1590 default: 1603 default:
1591 ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC || 1604 ASSERT(0);
1592 blk->magic == XFS_DIR2_LEAFN_MAGIC);
1593 break; 1605 break;
1594 } 1606 }
1595 } 1607 }
@@ -1833,10 +1845,16 @@ xfs_da_swap_lastblock(
1833 /* 1845 /*
1834 * Get values from the moved block. 1846 * Get values from the moved block.
1835 */ 1847 */
1836 if (dead_info->magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)) { 1848 if (dead_info->magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
1849 dead_info->magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC)) {
1850 struct xfs_dir3_icleaf_hdr leafhdr;
1851 struct xfs_dir2_leaf_entry *ents;
1852
1837 dead_leaf2 = (xfs_dir2_leaf_t *)dead_info; 1853 dead_leaf2 = (xfs_dir2_leaf_t *)dead_info;
1854 xfs_dir3_leaf_hdr_from_disk(&leafhdr, dead_leaf2);
1855 ents = xfs_dir3_leaf_ents_p(dead_leaf2);
1838 dead_level = 0; 1856 dead_level = 0;
1839 dead_hash = be32_to_cpu(dead_leaf2->ents[be16_to_cpu(dead_leaf2->hdr.count) - 1].hashval); 1857 dead_hash = be32_to_cpu(ents[leafhdr.count - 1].hashval);
1840 } else { 1858 } else {
1841 ASSERT(dead_info->magic == cpu_to_be16(XFS_DA_NODE_MAGIC)); 1859 ASSERT(dead_info->magic == cpu_to_be16(XFS_DA_NODE_MAGIC));
1842 dead_node = (xfs_da_intnode_t *)dead_info; 1860 dead_node = (xfs_da_intnode_t *)dead_info;
@@ -2281,10 +2299,17 @@ xfs_da_read_buf(
2281 XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) && 2299 XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) &&
2282 (magic != XFS_ATTR_LEAF_MAGIC) && 2300 (magic != XFS_ATTR_LEAF_MAGIC) &&
2283 (magic != XFS_DIR2_LEAF1_MAGIC) && 2301 (magic != XFS_DIR2_LEAF1_MAGIC) &&
2302 (magic != XFS_DIR3_LEAF1_MAGIC) &&
2284 (magic != XFS_DIR2_LEAFN_MAGIC) && 2303 (magic != XFS_DIR2_LEAFN_MAGIC) &&
2304 (magic != XFS_DIR3_LEAFN_MAGIC) &&
2285 (magic1 != XFS_DIR2_BLOCK_MAGIC) && 2305 (magic1 != XFS_DIR2_BLOCK_MAGIC) &&
2306 (magic1 != XFS_DIR3_BLOCK_MAGIC) &&
2286 (magic1 != XFS_DIR2_DATA_MAGIC) && 2307 (magic1 != XFS_DIR2_DATA_MAGIC) &&
2287 (free->hdr.magic != cpu_to_be32(XFS_DIR2_FREE_MAGIC)), 2308 (magic1 != XFS_DIR3_DATA_MAGIC) &&
2309 (free->hdr.magic !=
2310 cpu_to_be32(XFS_DIR2_FREE_MAGIC)) &&
2311 (free->hdr.magic !=
2312 cpu_to_be32(XFS_DIR3_FREE_MAGIC)),
2288 mp, XFS_ERRTAG_DA_READ_BUF, 2313 mp, XFS_ERRTAG_DA_READ_BUF,
2289 XFS_RANDOM_DA_READ_BUF))) { 2314 XFS_RANDOM_DA_READ_BUF))) {
2290 trace_xfs_da_btree_corrupt(bp, _RET_IP_); 2315 trace_xfs_da_btree_corrupt(bp, _RET_IP_);
diff --git a/fs/xfs/xfs_da_btree.h b/fs/xfs/xfs_da_btree.h
index ee5170c46ae1..0854b95b1dc1 100644
--- a/fs/xfs/xfs_da_btree.h
+++ b/fs/xfs/xfs_da_btree.h
@@ -47,6 +47,29 @@ typedef struct xfs_da_blkinfo {
47} xfs_da_blkinfo_t; 47} xfs_da_blkinfo_t;
48 48
49/* 49/*
50 * CRC enabled directory structure types
51 *
52 * The headers change size for the additional verification information, but
53 * otherwise the tree layouts and contents are unchanged.
54 */
55#define XFS_DIR3_LEAF1_MAGIC 0x3df1 /* magic number: v2 dirlf single blks */
56#define XFS_DIR3_LEAFN_MAGIC 0x3dff /* magic number: v2 dirlf multi blks */
57
58struct xfs_da3_blkinfo {
59 /*
60 * the node link manipulation code relies on the fact that the first
61 * element of this structure is the struct xfs_da_blkinfo so it can
62 * ignore the differences in the rest of the structures.
63 */
64 struct xfs_da_blkinfo hdr;
65 __be32 crc; /* CRC of block */
66 __be64 blkno; /* first block of the buffer */
67 __be64 lsn; /* sequence number of last write */
68 uuid_t uuid; /* filesystem we belong to */
69 __be64 owner; /* inode that owns the block */
70};
71
72/*
50 * This is the structure of the root and intermediate nodes in the Btree. 73 * This is the structure of the root and intermediate nodes in the Btree.
51 * The leaf nodes are defined above. 74 * The leaf nodes are defined above.
52 * 75 *
diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c
index 7ec87c20cbd2..d2e445f92ffb 100644
--- a/fs/xfs/xfs_dir2_block.c
+++ b/fs/xfs/xfs_dir2_block.c
@@ -1013,6 +1013,8 @@ xfs_dir2_leaf_to_block(
1013 __be16 *tagp; /* end of entry (tag) */ 1013 __be16 *tagp; /* end of entry (tag) */
1014 int to; /* block/leaf to index */ 1014 int to; /* block/leaf to index */
1015 xfs_trans_t *tp; /* transaction pointer */ 1015 xfs_trans_t *tp; /* transaction pointer */
1016 struct xfs_dir2_leaf_entry *ents;
1017 struct xfs_dir3_icleaf_hdr leafhdr;
1016 1018
1017 trace_xfs_dir2_leaf_to_block(args); 1019 trace_xfs_dir2_leaf_to_block(args);
1018 1020
@@ -1020,8 +1022,12 @@ xfs_dir2_leaf_to_block(
1020 tp = args->trans; 1022 tp = args->trans;
1021 mp = dp->i_mount; 1023 mp = dp->i_mount;
1022 leaf = lbp->b_addr; 1024 leaf = lbp->b_addr;
1023 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC)); 1025 xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
1026 ents = xfs_dir3_leaf_ents_p(leaf);
1024 ltp = xfs_dir2_leaf_tail_p(mp, leaf); 1027 ltp = xfs_dir2_leaf_tail_p(mp, leaf);
1028
1029 ASSERT(leafhdr.magic == XFS_DIR2_LEAF1_MAGIC ||
1030 leafhdr.magic == XFS_DIR3_LEAF1_MAGIC);
1025 /* 1031 /*
1026 * If there are data blocks other than the first one, take this 1032 * If there are data blocks other than the first one, take this
1027 * opportunity to remove trailing empty data blocks that may have 1033 * opportunity to remove trailing empty data blocks that may have
@@ -1058,7 +1064,7 @@ xfs_dir2_leaf_to_block(
1058 * Size of the "leaf" area in the block. 1064 * Size of the "leaf" area in the block.
1059 */ 1065 */
1060 size = (uint)sizeof(xfs_dir2_block_tail_t) + 1066 size = (uint)sizeof(xfs_dir2_block_tail_t) +
1061 (uint)sizeof(*lep) * (be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale)); 1067 (uint)sizeof(*lep) * (leafhdr.count - leafhdr.stale);
1062 /* 1068 /*
1063 * Look at the last data entry. 1069 * Look at the last data entry.
1064 */ 1070 */
@@ -1087,18 +1093,17 @@ xfs_dir2_leaf_to_block(
1087 * Initialize the block tail. 1093 * Initialize the block tail.
1088 */ 1094 */
1089 btp = xfs_dir2_block_tail_p(mp, hdr); 1095 btp = xfs_dir2_block_tail_p(mp, hdr);
1090 btp->count = cpu_to_be32(be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale)); 1096 btp->count = cpu_to_be32(leafhdr.count - leafhdr.stale);
1091 btp->stale = 0; 1097 btp->stale = 0;
1092 xfs_dir2_block_log_tail(tp, dbp); 1098 xfs_dir2_block_log_tail(tp, dbp);
1093 /* 1099 /*
1094 * Initialize the block leaf area. We compact out stale entries. 1100 * Initialize the block leaf area. We compact out stale entries.
1095 */ 1101 */
1096 lep = xfs_dir2_block_leaf_p(btp); 1102 lep = xfs_dir2_block_leaf_p(btp);
1097 for (from = to = 0; from < be16_to_cpu(leaf->hdr.count); from++) { 1103 for (from = to = 0; from < leafhdr.count; from++) {
1098 if (leaf->ents[from].address == 1104 if (ents[from].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
1099 cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
1100 continue; 1105 continue;
1101 lep[to++] = leaf->ents[from]; 1106 lep[to++] = ents[from];
1102 } 1107 }
1103 ASSERT(to == be32_to_cpu(btp->count)); 1108 ASSERT(to == be32_to_cpu(btp->count));
1104 xfs_dir2_block_log_leaf(tp, dbp, 0, be32_to_cpu(btp->count) - 1); 1109 xfs_dir2_block_log_leaf(tp, dbp, 0, be32_to_cpu(btp->count) - 1);
diff --git a/fs/xfs/xfs_dir2_format.h b/fs/xfs/xfs_dir2_format.h
index 0ac09502b830..7b986d334b33 100644
--- a/fs/xfs/xfs_dir2_format.h
+++ b/fs/xfs/xfs_dir2_format.h
@@ -470,6 +470,21 @@ typedef struct xfs_dir2_leaf_hdr {
470 __be16 stale; /* count of stale entries */ 470 __be16 stale; /* count of stale entries */
471} xfs_dir2_leaf_hdr_t; 471} xfs_dir2_leaf_hdr_t;
472 472
473struct xfs_dir3_leaf_hdr {
474 struct xfs_da3_blkinfo info; /* header for da routines */
475 __be16 count; /* count of entries */
476 __be16 stale; /* count of stale entries */
477 __be32 pad;
478};
479
480struct xfs_dir3_icleaf_hdr {
481 __uint32_t forw;
482 __uint32_t back;
483 __uint16_t magic;
484 __uint16_t count;
485 __uint16_t stale;
486};
487
473/* 488/*
474 * Leaf block entry. 489 * Leaf block entry.
475 */ 490 */
@@ -489,23 +504,50 @@ typedef struct xfs_dir2_leaf_tail {
489 * Leaf block. 504 * Leaf block.
490 */ 505 */
491typedef struct xfs_dir2_leaf { 506typedef struct xfs_dir2_leaf {
492 xfs_dir2_leaf_hdr_t hdr; /* leaf header */ 507 xfs_dir2_leaf_hdr_t hdr; /* leaf header */
493 xfs_dir2_leaf_entry_t ents[]; /* entries */ 508 xfs_dir2_leaf_entry_t __ents[]; /* entries */
494} xfs_dir2_leaf_t; 509} xfs_dir2_leaf_t;
495 510
496/* 511struct xfs_dir3_leaf {
497 * DB blocks here are logical directory block numbers, not filesystem blocks. 512 struct xfs_dir3_leaf_hdr hdr; /* leaf header */
498 */ 513 struct xfs_dir2_leaf_entry __ents[]; /* entries */
514};
515
516#define XFS_DIR3_LEAF_CRC_OFF offsetof(struct xfs_dir3_leaf_hdr, info.crc)
517
518static inline int
519xfs_dir3_leaf_hdr_size(struct xfs_dir2_leaf *lp)
520{
521 if (lp->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAF1_MAGIC) ||
522 lp->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC))
523 return sizeof(struct xfs_dir3_leaf_hdr);
524 return sizeof(struct xfs_dir2_leaf_hdr);
525}
499 526
500static inline int xfs_dir2_max_leaf_ents(struct xfs_mount *mp) 527static inline int
528xfs_dir3_max_leaf_ents(struct xfs_mount *mp, struct xfs_dir2_leaf *lp)
501{ 529{
502 return (mp->m_dirblksize - (uint)sizeof(struct xfs_dir2_leaf_hdr)) / 530 return (mp->m_dirblksize - xfs_dir3_leaf_hdr_size(lp)) /
503 (uint)sizeof(struct xfs_dir2_leaf_entry); 531 (uint)sizeof(struct xfs_dir2_leaf_entry);
504} 532}
505 533
506/* 534/*
507 * Get address of the bestcount field in the single-leaf block. 535 * Get address of the bestcount field in the single-leaf block.
508 */ 536 */
537static inline struct xfs_dir2_leaf_entry *
538xfs_dir3_leaf_ents_p(struct xfs_dir2_leaf *lp)
539{
540 if (lp->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAF1_MAGIC) ||
541 lp->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC)) {
542 struct xfs_dir3_leaf *lp3 = (struct xfs_dir3_leaf *)lp;
543 return lp3->__ents;
544 }
545 return lp->__ents;
546}
547
548/*
549 * Get address of the bestcount field in the single-leaf block.
550 */
509static inline struct xfs_dir2_leaf_tail * 551static inline struct xfs_dir2_leaf_tail *
510xfs_dir2_leaf_tail_p(struct xfs_mount *mp, struct xfs_dir2_leaf *lp) 552xfs_dir2_leaf_tail_p(struct xfs_mount *mp, struct xfs_dir2_leaf *lp)
511{ 553{
@@ -524,6 +566,10 @@ xfs_dir2_leaf_bests_p(struct xfs_dir2_leaf_tail *ltp)
524} 566}
525 567
526/* 568/*
569 * DB blocks here are logical directory block numbers, not filesystem blocks.
570 */
571
572/*
527 * Convert dataptr to byte in file space 573 * Convert dataptr to byte in file space
528 */ 574 */
529static inline xfs_dir2_off_t 575static inline xfs_dir2_off_t
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c
index c7dca950f768..7352e41d2aaa 100644
--- a/fs/xfs/xfs_dir2_leaf.c
+++ b/fs/xfs/xfs_dir2_leaf.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
3 * Copyright (c) 2013 Red Hat, Inc.
3 * All Rights Reserved. 4 * All Rights Reserved.
4 * 5 *
5 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
@@ -33,77 +34,263 @@
33#include "xfs_dir2_priv.h" 34#include "xfs_dir2_priv.h"
34#include "xfs_error.h" 35#include "xfs_error.h"
35#include "xfs_trace.h" 36#include "xfs_trace.h"
37#include "xfs_buf_item.h"
38#include "xfs_cksum.h"
36 39
37/* 40/*
38 * Local function declarations. 41 * Local function declarations.
39 */ 42 */
40#ifdef DEBUG
41static void xfs_dir2_leaf_check(struct xfs_inode *dp, struct xfs_buf *bp);
42#else
43#define xfs_dir2_leaf_check(dp, bp)
44#endif
45static int xfs_dir2_leaf_lookup_int(xfs_da_args_t *args, struct xfs_buf **lbpp, 43static int xfs_dir2_leaf_lookup_int(xfs_da_args_t *args, struct xfs_buf **lbpp,
46 int *indexp, struct xfs_buf **dbpp); 44 int *indexp, struct xfs_buf **dbpp);
47static void xfs_dir2_leaf_log_bests(struct xfs_trans *tp, struct xfs_buf *bp, 45static void xfs_dir3_leaf_log_bests(struct xfs_trans *tp, struct xfs_buf *bp,
48 int first, int last); 46 int first, int last);
49static void xfs_dir2_leaf_log_tail(struct xfs_trans *tp, struct xfs_buf *bp); 47static void xfs_dir3_leaf_log_tail(struct xfs_trans *tp, struct xfs_buf *bp);
50 48
51static void 49/*
52xfs_dir2_leaf_verify( 50 * Check the internal consistency of a leaf1 block.
51 * Pop an assert if something is wrong.
52 */
53#ifdef DEBUG
54#define xfs_dir3_leaf_check(mp, bp) \
55do { \
56 if (!xfs_dir3_leaf1_check((mp), (bp))) \
57 ASSERT(0); \
58} while (0);
59
60STATIC bool
61xfs_dir3_leaf1_check(
62 struct xfs_mount *mp,
63 struct xfs_buf *bp)
64{
65 struct xfs_dir2_leaf *leaf = bp->b_addr;
66 struct xfs_dir3_icleaf_hdr leafhdr;
67
68 xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
69
70 if (leafhdr.magic == XFS_DIR3_LEAF1_MAGIC) {
71 struct xfs_dir3_leaf_hdr *leaf3 = bp->b_addr;
72 if (be64_to_cpu(leaf3->info.blkno) != bp->b_bn)
73 return false;
74 } else if (leafhdr.magic != XFS_DIR2_LEAF1_MAGIC)
75 return false;
76
77 return xfs_dir3_leaf_check_int(mp, &leafhdr, leaf);
78}
79#else
80#define xfs_dir3_leaf_check(mp, bp)
81#endif
82
83void
84xfs_dir3_leaf_hdr_from_disk(
85 struct xfs_dir3_icleaf_hdr *to,
86 struct xfs_dir2_leaf *from)
87{
88 if (from->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) ||
89 from->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)) {
90 to->forw = be32_to_cpu(from->hdr.info.forw);
91 to->back = be32_to_cpu(from->hdr.info.back);
92 to->magic = be16_to_cpu(from->hdr.info.magic);
93 to->count = be16_to_cpu(from->hdr.count);
94 to->stale = be16_to_cpu(from->hdr.stale);
95 } else {
96 struct xfs_dir3_leaf_hdr *hdr3 = (struct xfs_dir3_leaf_hdr *)from;
97
98 to->forw = be32_to_cpu(hdr3->info.hdr.forw);
99 to->back = be32_to_cpu(hdr3->info.hdr.back);
100 to->magic = be16_to_cpu(hdr3->info.hdr.magic);
101 to->count = be16_to_cpu(hdr3->count);
102 to->stale = be16_to_cpu(hdr3->stale);
103 }
104
105 ASSERT(to->magic == XFS_DIR2_LEAF1_MAGIC ||
106 to->magic == XFS_DIR3_LEAF1_MAGIC ||
107 to->magic == XFS_DIR2_LEAFN_MAGIC ||
108 to->magic == XFS_DIR3_LEAFN_MAGIC);
109}
110
111void
112xfs_dir3_leaf_hdr_to_disk(
113 struct xfs_dir2_leaf *to,
114 struct xfs_dir3_icleaf_hdr *from)
115{
116 ASSERT(from->magic == XFS_DIR2_LEAF1_MAGIC ||
117 from->magic == XFS_DIR3_LEAF1_MAGIC ||
118 from->magic == XFS_DIR2_LEAFN_MAGIC ||
119 from->magic == XFS_DIR3_LEAFN_MAGIC);
120
121 if (from->magic == XFS_DIR2_LEAF1_MAGIC ||
122 from->magic == XFS_DIR2_LEAFN_MAGIC) {
123 to->hdr.info.forw = cpu_to_be32(from->forw);
124 to->hdr.info.back = cpu_to_be32(from->back);
125 to->hdr.info.magic = cpu_to_be16(from->magic);
126 to->hdr.count = cpu_to_be16(from->count);
127 to->hdr.stale = cpu_to_be16(from->stale);
128 } else {
129 struct xfs_dir3_leaf_hdr *hdr3 = (struct xfs_dir3_leaf_hdr *)to;
130
131 hdr3->info.hdr.forw = cpu_to_be32(from->forw);
132 hdr3->info.hdr.back = cpu_to_be32(from->back);
133 hdr3->info.hdr.magic = cpu_to_be16(from->magic);
134 hdr3->count = cpu_to_be16(from->count);
135 hdr3->stale = cpu_to_be16(from->stale);
136 }
137}
138
139bool
140xfs_dir3_leaf_check_int(
141 struct xfs_mount *mp,
142 struct xfs_dir3_icleaf_hdr *hdr,
143 struct xfs_dir2_leaf *leaf)
144{
145 struct xfs_dir2_leaf_entry *ents;
146 xfs_dir2_leaf_tail_t *ltp;
147 int stale;
148 int i;
149
150 ents = xfs_dir3_leaf_ents_p(leaf);
151 ltp = xfs_dir2_leaf_tail_p(mp, leaf);
152
153 /*
154 * XXX (dgc): This value is not restrictive enough.
155 * Should factor in the size of the bests table as well.
156 * We can deduce a value for that from di_size.
157 */
158 if (hdr->count > xfs_dir3_max_leaf_ents(mp, leaf))
159 return false;
160
161 /* Leaves and bests don't overlap in leaf format. */
162 if ((hdr->magic == XFS_DIR2_LEAF1_MAGIC ||
163 hdr->magic == XFS_DIR3_LEAF1_MAGIC) &&
164 (char *)&ents[hdr->count] > (char *)xfs_dir2_leaf_bests_p(ltp))
165 return false;
166
167 /* Check hash value order, count stale entries. */
168 for (i = stale = 0; i < hdr->count; i++) {
169 if (i + 1 < hdr->count) {
170 if (be32_to_cpu(ents[i].hashval) >
171 be32_to_cpu(ents[i + 1].hashval))
172 return false;
173 }
174 if (ents[i].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
175 stale++;
176 }
177 if (hdr->stale != stale)
178 return false;
179 return true;
180}
181
182static bool
183xfs_dir3_leaf_verify(
53 struct xfs_buf *bp, 184 struct xfs_buf *bp,
54 __be16 magic) 185 __uint16_t magic)
186{
187 struct xfs_mount *mp = bp->b_target->bt_mount;
188 struct xfs_dir2_leaf *leaf = bp->b_addr;
189 struct xfs_dir3_icleaf_hdr leafhdr;
190
191 ASSERT(magic == XFS_DIR2_LEAF1_MAGIC || magic == XFS_DIR2_LEAFN_MAGIC);
192
193 xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
194 if (xfs_sb_version_hascrc(&mp->m_sb)) {
195 struct xfs_dir3_leaf_hdr *leaf3 = bp->b_addr;
196
197 if ((magic == XFS_DIR2_LEAF1_MAGIC &&
198 leafhdr.magic != XFS_DIR3_LEAF1_MAGIC) ||
199 (magic == XFS_DIR2_LEAFN_MAGIC &&
200 leafhdr.magic != XFS_DIR3_LEAFN_MAGIC))
201 return false;
202
203 if (!uuid_equal(&leaf3->info.uuid, &mp->m_sb.sb_uuid))
204 return false;
205 if (be64_to_cpu(leaf3->info.blkno) != bp->b_bn)
206 return false;
207 } else {
208 if (leafhdr.magic != magic)
209 return false;
210 }
211 return xfs_dir3_leaf_check_int(mp, &leafhdr, leaf);
212}
213
214static void
215__read_verify(
216 struct xfs_buf *bp,
217 __uint16_t magic)
218{
219 struct xfs_mount *mp = bp->b_target->bt_mount;
220
221 if ((xfs_sb_version_hascrc(&mp->m_sb) &&
222 !xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
223 XFS_DIR3_LEAF_CRC_OFF)) ||
224 !xfs_dir3_leaf_verify(bp, magic)) {
225 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
226 xfs_buf_ioerror(bp, EFSCORRUPTED);
227 }
228}
229
230static void
231__write_verify(
232 struct xfs_buf *bp,
233 __uint16_t magic)
55{ 234{
56 struct xfs_mount *mp = bp->b_target->bt_mount; 235 struct xfs_mount *mp = bp->b_target->bt_mount;
57 struct xfs_dir2_leaf_hdr *hdr = bp->b_addr; 236 struct xfs_buf_log_item *bip = bp->b_fspriv;
58 int block_ok = 0; 237 struct xfs_dir3_leaf_hdr *hdr3 = bp->b_addr;
59 238
60 block_ok = hdr->info.magic == magic; 239 if (!xfs_dir3_leaf_verify(bp, magic)) {
61 if (!block_ok) { 240 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
62 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, hdr);
63 xfs_buf_ioerror(bp, EFSCORRUPTED); 241 xfs_buf_ioerror(bp, EFSCORRUPTED);
242 return;
64 } 243 }
244
245 if (!xfs_sb_version_hascrc(&mp->m_sb))
246 return;
247
248 if (bip)
249 hdr3->info.lsn = cpu_to_be64(bip->bli_item.li_lsn);
250
251 xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length), XFS_DIR3_LEAF_CRC_OFF);
65} 252}
66 253
67static void 254static void
68xfs_dir2_leaf1_read_verify( 255xfs_dir3_leaf1_read_verify(
69 struct xfs_buf *bp) 256 struct xfs_buf *bp)
70{ 257{
71 xfs_dir2_leaf_verify(bp, cpu_to_be16(XFS_DIR2_LEAF1_MAGIC)); 258 __read_verify(bp, XFS_DIR2_LEAF1_MAGIC);
72} 259}
73 260
74static void 261static void
75xfs_dir2_leaf1_write_verify( 262xfs_dir3_leaf1_write_verify(
76 struct xfs_buf *bp) 263 struct xfs_buf *bp)
77{ 264{
78 xfs_dir2_leaf_verify(bp, cpu_to_be16(XFS_DIR2_LEAF1_MAGIC)); 265 __write_verify(bp, XFS_DIR2_LEAF1_MAGIC);
79} 266}
80 267
81void 268static void
82xfs_dir2_leafn_read_verify( 269xfs_dir3_leafn_read_verify(
83 struct xfs_buf *bp) 270 struct xfs_buf *bp)
84{ 271{
85 xfs_dir2_leaf_verify(bp, cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); 272 __read_verify(bp, XFS_DIR2_LEAFN_MAGIC);
86} 273}
87 274
88void 275static void
89xfs_dir2_leafn_write_verify( 276xfs_dir3_leafn_write_verify(
90 struct xfs_buf *bp) 277 struct xfs_buf *bp)
91{ 278{
92 xfs_dir2_leaf_verify(bp, cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); 279 __write_verify(bp, XFS_DIR2_LEAFN_MAGIC);
93} 280}
94 281
95static const struct xfs_buf_ops xfs_dir2_leaf1_buf_ops = { 282static const struct xfs_buf_ops xfs_dir3_leaf1_buf_ops = {
96 .verify_read = xfs_dir2_leaf1_read_verify, 283 .verify_read = xfs_dir3_leaf1_read_verify,
97 .verify_write = xfs_dir2_leaf1_write_verify, 284 .verify_write = xfs_dir3_leaf1_write_verify,
98}; 285};
99 286
100const struct xfs_buf_ops xfs_dir2_leafn_buf_ops = { 287const struct xfs_buf_ops xfs_dir3_leafn_buf_ops = {
101 .verify_read = xfs_dir2_leafn_read_verify, 288 .verify_read = xfs_dir3_leafn_read_verify,
102 .verify_write = xfs_dir2_leafn_write_verify, 289 .verify_write = xfs_dir3_leafn_write_verify,
103}; 290};
104 291
105static int 292static int
106xfs_dir2_leaf_read( 293xfs_dir3_leaf_read(
107 struct xfs_trans *tp, 294 struct xfs_trans *tp,
108 struct xfs_inode *dp, 295 struct xfs_inode *dp,
109 xfs_dablk_t fbno, 296 xfs_dablk_t fbno,
@@ -111,11 +298,11 @@ xfs_dir2_leaf_read(
111 struct xfs_buf **bpp) 298 struct xfs_buf **bpp)
112{ 299{
113 return xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp, 300 return xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp,
114 XFS_DATA_FORK, &xfs_dir2_leaf1_buf_ops); 301 XFS_DATA_FORK, &xfs_dir3_leaf1_buf_ops);
115} 302}
116 303
117int 304int
118xfs_dir2_leafn_read( 305xfs_dir3_leafn_read(
119 struct xfs_trans *tp, 306 struct xfs_trans *tp,
120 struct xfs_inode *dp, 307 struct xfs_inode *dp,
121 xfs_dablk_t fbno, 308 xfs_dablk_t fbno,
@@ -123,7 +310,81 @@ xfs_dir2_leafn_read(
123 struct xfs_buf **bpp) 310 struct xfs_buf **bpp)
124{ 311{
125 return xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp, 312 return xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp,
126 XFS_DATA_FORK, &xfs_dir2_leafn_buf_ops); 313 XFS_DATA_FORK, &xfs_dir3_leafn_buf_ops);
314}
315
316/*
317 * Initialize a new leaf block, leaf1 or leafn magic accepted.
318 */
319static void
320xfs_dir3_leaf_init(
321 struct xfs_mount *mp,
322 struct xfs_buf *bp,
323 xfs_ino_t owner,
324 __uint16_t type)
325{
326 struct xfs_dir2_leaf *leaf = bp->b_addr;
327
328 ASSERT(type == XFS_DIR2_LEAF1_MAGIC || type == XFS_DIR2_LEAFN_MAGIC);
329
330 if (xfs_sb_version_hascrc(&mp->m_sb)) {
331 struct xfs_dir3_leaf_hdr *leaf3 = bp->b_addr;
332
333 memset(leaf3, 0, sizeof(*leaf3));
334
335 leaf3->info.hdr.magic = (type == XFS_DIR2_LEAF1_MAGIC)
336 ? cpu_to_be16(XFS_DIR3_LEAF1_MAGIC)
337 : cpu_to_be16(XFS_DIR3_LEAFN_MAGIC);
338 leaf3->info.blkno = cpu_to_be64(bp->b_bn);
339 leaf3->info.owner = cpu_to_be64(owner);
340 uuid_copy(&leaf3->info.uuid, &mp->m_sb.sb_uuid);
341 } else {
342 memset(leaf, 0, sizeof(*leaf));
343 leaf->hdr.info.magic = cpu_to_be16(type);
344 }
345
346 /*
347 * If it's a leaf-format directory initialize the tail.
348 * Caller is responsible for initialising the bests table.
349 */
350 if (type == XFS_DIR2_LEAF1_MAGIC) {
351 struct xfs_dir2_leaf_tail *ltp;
352
353 ltp = xfs_dir2_leaf_tail_p(mp, leaf);
354 ltp->bestcount = 0;
355 bp->b_ops = &xfs_dir3_leaf1_buf_ops;
356 } else
357 bp->b_ops = &xfs_dir3_leafn_buf_ops;
358}
359
360int
361xfs_dir3_leaf_get_buf(
362 xfs_da_args_t *args,
363 xfs_dir2_db_t bno,
364 struct xfs_buf **bpp,
365 __uint16_t magic)
366{
367 struct xfs_inode *dp = args->dp;
368 struct xfs_trans *tp = args->trans;
369 struct xfs_mount *mp = dp->i_mount;
370 struct xfs_buf *bp;
371 int error;
372
373 ASSERT(magic == XFS_DIR2_LEAF1_MAGIC || magic == XFS_DIR2_LEAFN_MAGIC);
374 ASSERT(bno >= XFS_DIR2_LEAF_FIRSTDB(mp) &&
375 bno < XFS_DIR2_FREE_FIRSTDB(mp));
376
377 error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(mp, bno), -1, &bp,
378 XFS_DATA_FORK);
379 if (error)
380 return error;
381
382 xfs_dir3_leaf_init(mp, bp, dp->i_ino, magic);
383 xfs_dir3_leaf_log_header(tp, bp);
384 if (magic == XFS_DIR2_LEAF1_MAGIC)
385 xfs_dir3_leaf_log_tail(tp, bp);
386 *bpp = bp;
387 return 0;
127} 388}
128 389
129/* 390/*
@@ -150,6 +411,8 @@ xfs_dir2_block_to_leaf(
150 int needscan; /* need to rescan bestfree */ 411 int needscan; /* need to rescan bestfree */
151 xfs_trans_t *tp; /* transaction pointer */ 412 xfs_trans_t *tp; /* transaction pointer */
152 struct xfs_dir2_data_free *bf; 413 struct xfs_dir2_data_free *bf;
414 struct xfs_dir2_leaf_entry *ents;
415 struct xfs_dir3_icleaf_hdr leafhdr;
153 416
154 trace_xfs_dir2_block_to_leaf(args); 417 trace_xfs_dir2_block_to_leaf(args);
155 418
@@ -169,27 +432,33 @@ xfs_dir2_block_to_leaf(
169 /* 432 /*
170 * Initialize the leaf block, get a buffer for it. 433 * Initialize the leaf block, get a buffer for it.
171 */ 434 */
172 if ((error = xfs_dir2_leaf_init(args, ldb, &lbp, XFS_DIR2_LEAF1_MAGIC))) { 435 error = xfs_dir3_leaf_get_buf(args, ldb, &lbp, XFS_DIR2_LEAF1_MAGIC);
436 if (error)
173 return error; 437 return error;
174 } 438
175 ASSERT(lbp != NULL);
176 leaf = lbp->b_addr; 439 leaf = lbp->b_addr;
177 hdr = dbp->b_addr; 440 hdr = dbp->b_addr;
178 xfs_dir3_data_check(dp, dbp); 441 xfs_dir3_data_check(dp, dbp);
179 btp = xfs_dir2_block_tail_p(mp, hdr); 442 btp = xfs_dir2_block_tail_p(mp, hdr);
180 blp = xfs_dir2_block_leaf_p(btp); 443 blp = xfs_dir2_block_leaf_p(btp);
181 bf = xfs_dir3_data_bestfree_p(hdr); 444 bf = xfs_dir3_data_bestfree_p(hdr);
445 ents = xfs_dir3_leaf_ents_p(leaf);
446
182 /* 447 /*
183 * Set the counts in the leaf header. 448 * Set the counts in the leaf header.
184 */ 449 */
185 leaf->hdr.count = cpu_to_be16(be32_to_cpu(btp->count)); 450 xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
186 leaf->hdr.stale = cpu_to_be16(be32_to_cpu(btp->stale)); 451 leafhdr.count = be32_to_cpu(btp->count);
452 leafhdr.stale = be32_to_cpu(btp->stale);
453 xfs_dir3_leaf_hdr_to_disk(leaf, &leafhdr);
454 xfs_dir3_leaf_log_header(tp, lbp);
455
187 /* 456 /*
188 * Could compact these but I think we always do the conversion 457 * Could compact these but I think we always do the conversion
189 * after squeezing out stale entries. 458 * after squeezing out stale entries.
190 */ 459 */
191 memcpy(leaf->ents, blp, be32_to_cpu(btp->count) * sizeof(xfs_dir2_leaf_entry_t)); 460 memcpy(ents, blp, be32_to_cpu(btp->count) * sizeof(xfs_dir2_leaf_entry_t));
192 xfs_dir2_leaf_log_ents(tp, lbp, 0, be16_to_cpu(leaf->hdr.count) - 1); 461 xfs_dir3_leaf_log_ents(tp, lbp, 0, leafhdr.count - 1);
193 needscan = 0; 462 needscan = 0;
194 needlog = 1; 463 needlog = 1;
195 /* 464 /*
@@ -224,15 +493,16 @@ xfs_dir2_block_to_leaf(
224 */ 493 */
225 if (needlog) 494 if (needlog)
226 xfs_dir2_data_log_header(tp, dbp); 495 xfs_dir2_data_log_header(tp, dbp);
227 xfs_dir2_leaf_check(dp, lbp); 496 xfs_dir3_leaf_check(mp, lbp);
228 xfs_dir3_data_check(dp, dbp); 497 xfs_dir3_data_check(dp, dbp);
229 xfs_dir2_leaf_log_bests(tp, lbp, 0, 0); 498 xfs_dir3_leaf_log_bests(tp, lbp, 0, 0);
230 return 0; 499 return 0;
231} 500}
232 501
233STATIC void 502STATIC void
234xfs_dir2_leaf_find_stale( 503xfs_dir3_leaf_find_stale(
235 struct xfs_dir2_leaf *leaf, 504 struct xfs_dir3_icleaf_hdr *leafhdr,
505 struct xfs_dir2_leaf_entry *ents,
236 int index, 506 int index,
237 int *lowstale, 507 int *lowstale,
238 int *highstale) 508 int *highstale)
@@ -241,7 +511,7 @@ xfs_dir2_leaf_find_stale(
241 * Find the first stale entry before our index, if any. 511 * Find the first stale entry before our index, if any.
242 */ 512 */
243 for (*lowstale = index - 1; *lowstale >= 0; --*lowstale) { 513 for (*lowstale = index - 1; *lowstale >= 0; --*lowstale) {
244 if (leaf->ents[*lowstale].address == 514 if (ents[*lowstale].address ==
245 cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) 515 cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
246 break; 516 break;
247 } 517 }
@@ -251,10 +521,8 @@ xfs_dir2_leaf_find_stale(
251 * Stop if the result would require moving more entries than using 521 * Stop if the result would require moving more entries than using
252 * lowstale. 522 * lowstale.
253 */ 523 */
254 for (*highstale = index; 524 for (*highstale = index; *highstale < leafhdr->count; ++*highstale) {
255 *highstale < be16_to_cpu(leaf->hdr.count); 525 if (ents[*highstale].address ==
256 ++*highstale) {
257 if (leaf->ents[*highstale].address ==
258 cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) 526 cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
259 break; 527 break;
260 if (*lowstale >= 0 && index - *lowstale <= *highstale - index) 528 if (*lowstale >= 0 && index - *lowstale <= *highstale - index)
@@ -263,8 +531,9 @@ xfs_dir2_leaf_find_stale(
263} 531}
264 532
265struct xfs_dir2_leaf_entry * 533struct xfs_dir2_leaf_entry *
266xfs_dir2_leaf_find_entry( 534xfs_dir3_leaf_find_entry(
267 xfs_dir2_leaf_t *leaf, /* leaf structure */ 535 struct xfs_dir3_icleaf_hdr *leafhdr,
536 struct xfs_dir2_leaf_entry *ents,
268 int index, /* leaf table position */ 537 int index, /* leaf table position */
269 int compact, /* need to compact leaves */ 538 int compact, /* need to compact leaves */
270 int lowstale, /* index of prev stale leaf */ 539 int lowstale, /* index of prev stale leaf */
@@ -272,7 +541,7 @@ xfs_dir2_leaf_find_entry(
272 int *lfloglow, /* low leaf logging index */ 541 int *lfloglow, /* low leaf logging index */
273 int *lfloghigh) /* high leaf logging index */ 542 int *lfloghigh) /* high leaf logging index */
274{ 543{
275 if (!leaf->hdr.stale) { 544 if (!leafhdr->stale) {
276 xfs_dir2_leaf_entry_t *lep; /* leaf entry table pointer */ 545 xfs_dir2_leaf_entry_t *lep; /* leaf entry table pointer */
277 546
278 /* 547 /*
@@ -280,18 +549,16 @@ xfs_dir2_leaf_find_entry(
280 * 549 *
281 * If there are no stale entries, just insert a hole at index. 550 * If there are no stale entries, just insert a hole at index.
282 */ 551 */
283 lep = &leaf->ents[index]; 552 lep = &ents[index];
284 if (index < be16_to_cpu(leaf->hdr.count)) 553 if (index < leafhdr->count)
285 memmove(lep + 1, lep, 554 memmove(lep + 1, lep,
286 (be16_to_cpu(leaf->hdr.count) - index) * 555 (leafhdr->count - index) * sizeof(*lep));
287 sizeof(*lep));
288 556
289 /* 557 /*
290 * Record low and high logging indices for the leaf. 558 * Record low and high logging indices for the leaf.
291 */ 559 */
292 *lfloglow = index; 560 *lfloglow = index;
293 *lfloghigh = be16_to_cpu(leaf->hdr.count); 561 *lfloghigh = leafhdr->count++;
294 be16_add_cpu(&leaf->hdr.count, 1);
295 return lep; 562 return lep;
296 } 563 }
297 564
@@ -305,16 +572,17 @@ xfs_dir2_leaf_find_entry(
305 * entries before and after our insertion point. 572 * entries before and after our insertion point.
306 */ 573 */
307 if (compact == 0) 574 if (compact == 0)
308 xfs_dir2_leaf_find_stale(leaf, index, &lowstale, &highstale); 575 xfs_dir3_leaf_find_stale(leafhdr, ents, index,
576 &lowstale, &highstale);
309 577
310 /* 578 /*
311 * If the low one is better, use it. 579 * If the low one is better, use it.
312 */ 580 */
313 if (lowstale >= 0 && 581 if (lowstale >= 0 &&
314 (highstale == be16_to_cpu(leaf->hdr.count) || 582 (highstale == leafhdr->count ||
315 index - lowstale - 1 < highstale - index)) { 583 index - lowstale - 1 < highstale - index)) {
316 ASSERT(index - lowstale - 1 >= 0); 584 ASSERT(index - lowstale - 1 >= 0);
317 ASSERT(leaf->ents[lowstale].address == 585 ASSERT(ents[lowstale].address ==
318 cpu_to_be32(XFS_DIR2_NULL_DATAPTR)); 586 cpu_to_be32(XFS_DIR2_NULL_DATAPTR));
319 587
320 /* 588 /*
@@ -322,37 +590,34 @@ xfs_dir2_leaf_find_entry(
322 * for the new entry. 590 * for the new entry.
323 */ 591 */
324 if (index - lowstale - 1 > 0) { 592 if (index - lowstale - 1 > 0) {
325 memmove(&leaf->ents[lowstale], 593 memmove(&ents[lowstale], &ents[lowstale + 1],
326 &leaf->ents[lowstale + 1],
327 (index - lowstale - 1) * 594 (index - lowstale - 1) *
328 sizeof(xfs_dir2_leaf_entry_t)); 595 sizeof(xfs_dir2_leaf_entry_t));
329 } 596 }
330 *lfloglow = MIN(lowstale, *lfloglow); 597 *lfloglow = MIN(lowstale, *lfloglow);
331 *lfloghigh = MAX(index - 1, *lfloghigh); 598 *lfloghigh = MAX(index - 1, *lfloghigh);
332 be16_add_cpu(&leaf->hdr.stale, -1); 599 leafhdr->stale--;
333 return &leaf->ents[index - 1]; 600 return &ents[index - 1];
334 } 601 }
335 602
336 /* 603 /*
337 * The high one is better, so use that one. 604 * The high one is better, so use that one.
338 */ 605 */
339 ASSERT(highstale - index >= 0); 606 ASSERT(highstale - index >= 0);
340 ASSERT(leaf->ents[highstale].address == 607 ASSERT(ents[highstale].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR));
341 cpu_to_be32(XFS_DIR2_NULL_DATAPTR));
342 608
343 /* 609 /*
344 * Copy entries down to cover the stale entry and make room for the 610 * Copy entries down to cover the stale entry and make room for the
345 * new entry. 611 * new entry.
346 */ 612 */
347 if (highstale - index > 0) { 613 if (highstale - index > 0) {
348 memmove(&leaf->ents[index + 1], 614 memmove(&ents[index + 1], &ents[index],
349 &leaf->ents[index],
350 (highstale - index) * sizeof(xfs_dir2_leaf_entry_t)); 615 (highstale - index) * sizeof(xfs_dir2_leaf_entry_t));
351 } 616 }
352 *lfloglow = MIN(index, *lfloglow); 617 *lfloglow = MIN(index, *lfloglow);
353 *lfloghigh = MAX(highstale, *lfloghigh); 618 *lfloghigh = MAX(highstale, *lfloghigh);
354 be16_add_cpu(&leaf->hdr.stale, -1); 619 leafhdr->stale--;
355 return &leaf->ents[index]; 620 return &ents[index];
356} 621}
357 622
358/* 623/*
@@ -390,6 +655,8 @@ xfs_dir2_leaf_addname(
390 xfs_trans_t *tp; /* transaction pointer */ 655 xfs_trans_t *tp; /* transaction pointer */
391 xfs_dir2_db_t use_block; /* data block number */ 656 xfs_dir2_db_t use_block; /* data block number */
392 struct xfs_dir2_data_free *bf; /* bestfree table */ 657 struct xfs_dir2_data_free *bf; /* bestfree table */
658 struct xfs_dir2_leaf_entry *ents;
659 struct xfs_dir3_icleaf_hdr leafhdr;
393 660
394 trace_xfs_dir2_leaf_addname(args); 661 trace_xfs_dir2_leaf_addname(args);
395 662
@@ -397,7 +664,7 @@ xfs_dir2_leaf_addname(
397 tp = args->trans; 664 tp = args->trans;
398 mp = dp->i_mount; 665 mp = dp->i_mount;
399 666
400 error = xfs_dir2_leaf_read(tp, dp, mp->m_dirleafblk, -1, &lbp); 667 error = xfs_dir3_leaf_read(tp, dp, mp->m_dirleafblk, -1, &lbp);
401 if (error) 668 if (error)
402 return error; 669 return error;
403 670
@@ -410,16 +677,19 @@ xfs_dir2_leaf_addname(
410 index = xfs_dir2_leaf_search_hash(args, lbp); 677 index = xfs_dir2_leaf_search_hash(args, lbp);
411 leaf = lbp->b_addr; 678 leaf = lbp->b_addr;
412 ltp = xfs_dir2_leaf_tail_p(mp, leaf); 679 ltp = xfs_dir2_leaf_tail_p(mp, leaf);
680 ents = xfs_dir3_leaf_ents_p(leaf);
681 xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
413 bestsp = xfs_dir2_leaf_bests_p(ltp); 682 bestsp = xfs_dir2_leaf_bests_p(ltp);
414 length = xfs_dir2_data_entsize(args->namelen); 683 length = xfs_dir2_data_entsize(args->namelen);
684
415 /* 685 /*
416 * See if there are any entries with the same hash value 686 * See if there are any entries with the same hash value
417 * and space in their block for the new entry. 687 * and space in their block for the new entry.
418 * This is good because it puts multiple same-hash value entries 688 * This is good because it puts multiple same-hash value entries
419 * in a data block, improving the lookup of those entries. 689 * in a data block, improving the lookup of those entries.
420 */ 690 */
421 for (use_block = -1, lep = &leaf->ents[index]; 691 for (use_block = -1, lep = &ents[index];
422 index < be16_to_cpu(leaf->hdr.count) && be32_to_cpu(lep->hashval) == args->hashval; 692 index < leafhdr.count && be32_to_cpu(lep->hashval) == args->hashval;
423 index++, lep++) { 693 index++, lep++) {
424 if (be32_to_cpu(lep->address) == XFS_DIR2_NULL_DATAPTR) 694 if (be32_to_cpu(lep->address) == XFS_DIR2_NULL_DATAPTR)
425 continue; 695 continue;
@@ -452,7 +722,7 @@ xfs_dir2_leaf_addname(
452 * How many bytes do we need in the leaf block? 722 * How many bytes do we need in the leaf block?
453 */ 723 */
454 needbytes = 0; 724 needbytes = 0;
455 if (!leaf->hdr.stale) 725 if (!leafhdr.stale)
456 needbytes += sizeof(xfs_dir2_leaf_entry_t); 726 needbytes += sizeof(xfs_dir2_leaf_entry_t);
457 if (use_block == -1) 727 if (use_block == -1)
458 needbytes += sizeof(xfs_dir2_data_off_t); 728 needbytes += sizeof(xfs_dir2_data_off_t);
@@ -467,16 +737,15 @@ xfs_dir2_leaf_addname(
467 * If we don't have enough free bytes but we can make enough 737 * If we don't have enough free bytes but we can make enough
468 * by compacting out stale entries, we'll do that. 738 * by compacting out stale entries, we'll do that.
469 */ 739 */
470 if ((char *)bestsp - (char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] < 740 if ((char *)bestsp - (char *)&ents[leafhdr.count] < needbytes &&
471 needbytes && be16_to_cpu(leaf->hdr.stale) > 1) { 741 leafhdr.stale > 1)
472 compact = 1; 742 compact = 1;
473 } 743
474 /* 744 /*
475 * Otherwise if we don't have enough free bytes we need to 745 * Otherwise if we don't have enough free bytes we need to
476 * convert to node form. 746 * convert to node form.
477 */ 747 */
478 else if ((char *)bestsp - (char *)&leaf->ents[be16_to_cpu( 748 else if ((char *)bestsp - (char *)&ents[leafhdr.count] < needbytes) {
479 leaf->hdr.count)] < needbytes) {
480 /* 749 /*
481 * Just checking or no space reservation, give up. 750 * Just checking or no space reservation, give up.
482 */ 751 */
@@ -524,15 +793,15 @@ xfs_dir2_leaf_addname(
524 * point later. 793 * point later.
525 */ 794 */
526 if (compact) { 795 if (compact) {
527 xfs_dir2_leaf_compact_x1(lbp, &index, &lowstale, &highstale, 796 xfs_dir3_leaf_compact_x1(&leafhdr, ents, &index, &lowstale,
528 &lfloglow, &lfloghigh); 797 &highstale, &lfloglow, &lfloghigh);
529 } 798 }
530 /* 799 /*
531 * There are stale entries, so we'll need log-low and log-high 800 * There are stale entries, so we'll need log-low and log-high
532 * impossibly bad values later. 801 * impossibly bad values later.
533 */ 802 */
534 else if (be16_to_cpu(leaf->hdr.stale)) { 803 else if (leafhdr.stale) {
535 lfloglow = be16_to_cpu(leaf->hdr.count); 804 lfloglow = leafhdr.count;
536 lfloghigh = -1; 805 lfloghigh = -1;
537 } 806 }
538 /* 807 /*
@@ -564,14 +833,14 @@ xfs_dir2_leaf_addname(
564 memmove(&bestsp[0], &bestsp[1], 833 memmove(&bestsp[0], &bestsp[1],
565 be32_to_cpu(ltp->bestcount) * sizeof(bestsp[0])); 834 be32_to_cpu(ltp->bestcount) * sizeof(bestsp[0]));
566 be32_add_cpu(&ltp->bestcount, 1); 835 be32_add_cpu(&ltp->bestcount, 1);
567 xfs_dir2_leaf_log_tail(tp, lbp); 836 xfs_dir3_leaf_log_tail(tp, lbp);
568 xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); 837 xfs_dir3_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
569 } 838 }
570 /* 839 /*
571 * If we're filling in a previously empty block just log it. 840 * If we're filling in a previously empty block just log it.
572 */ 841 */
573 else 842 else
574 xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block); 843 xfs_dir3_leaf_log_bests(tp, lbp, use_block, use_block);
575 hdr = dbp->b_addr; 844 hdr = dbp->b_addr;
576 bf = xfs_dir3_data_bestfree_p(hdr); 845 bf = xfs_dir3_data_bestfree_p(hdr);
577 bestsp[use_block] = bf[0].length; 846 bestsp[use_block] = bf[0].length;
@@ -632,10 +901,10 @@ xfs_dir2_leaf_addname(
632 if (be16_to_cpu(bestsp[use_block]) != be16_to_cpu(bf[0].length)) { 901 if (be16_to_cpu(bestsp[use_block]) != be16_to_cpu(bf[0].length)) {
633 bestsp[use_block] = bf[0].length; 902 bestsp[use_block] = bf[0].length;
634 if (!grown) 903 if (!grown)
635 xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block); 904 xfs_dir3_leaf_log_bests(tp, lbp, use_block, use_block);
636 } 905 }
637 906
638 lep = xfs_dir2_leaf_find_entry(leaf, index, compact, lowstale, 907 lep = xfs_dir3_leaf_find_entry(&leafhdr, ents, index, compact, lowstale,
639 highstale, &lfloglow, &lfloghigh); 908 highstale, &lfloglow, &lfloghigh);
640 909
641 /* 910 /*
@@ -647,82 +916,40 @@ xfs_dir2_leaf_addname(
647 /* 916 /*
648 * Log the leaf fields and give up the buffers. 917 * Log the leaf fields and give up the buffers.
649 */ 918 */
650 xfs_dir2_leaf_log_header(tp, lbp); 919 xfs_dir3_leaf_hdr_to_disk(leaf, &leafhdr);
651 xfs_dir2_leaf_log_ents(tp, lbp, lfloglow, lfloghigh); 920 xfs_dir3_leaf_log_header(tp, lbp);
652 xfs_dir2_leaf_check(dp, lbp); 921 xfs_dir3_leaf_log_ents(tp, lbp, lfloglow, lfloghigh);
922 xfs_dir3_leaf_check(mp, lbp);
653 xfs_dir3_data_check(dp, dbp); 923 xfs_dir3_data_check(dp, dbp);
654 return 0; 924 return 0;
655} 925}
656 926
657#ifdef DEBUG
658/*
659 * Check the internal consistency of a leaf1 block.
660 * Pop an assert if something is wrong.
661 */
662STATIC void
663xfs_dir2_leaf_check(
664 struct xfs_inode *dp, /* incore directory inode */
665 struct xfs_buf *bp) /* leaf's buffer */
666{
667 int i; /* leaf index */
668 xfs_dir2_leaf_t *leaf; /* leaf structure */
669 xfs_dir2_leaf_tail_t *ltp; /* leaf tail pointer */
670 xfs_mount_t *mp; /* filesystem mount point */
671 int stale; /* count of stale leaves */
672
673 leaf = bp->b_addr;
674 mp = dp->i_mount;
675 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC));
676 /*
677 * This value is not restrictive enough.
678 * Should factor in the size of the bests table as well.
679 * We can deduce a value for that from di_size.
680 */
681 ASSERT(be16_to_cpu(leaf->hdr.count) <= xfs_dir2_max_leaf_ents(mp));
682 ltp = xfs_dir2_leaf_tail_p(mp, leaf);
683 /*
684 * Leaves and bests don't overlap.
685 */
686 ASSERT((char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] <=
687 (char *)xfs_dir2_leaf_bests_p(ltp));
688 /*
689 * Check hash value order, count stale entries.
690 */
691 for (i = stale = 0; i < be16_to_cpu(leaf->hdr.count); i++) {
692 if (i + 1 < be16_to_cpu(leaf->hdr.count))
693 ASSERT(be32_to_cpu(leaf->ents[i].hashval) <=
694 be32_to_cpu(leaf->ents[i + 1].hashval));
695 if (leaf->ents[i].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
696 stale++;
697 }
698 ASSERT(be16_to_cpu(leaf->hdr.stale) == stale);
699}
700#endif /* DEBUG */
701
702/* 927/*
703 * Compact out any stale entries in the leaf. 928 * Compact out any stale entries in the leaf.
704 * Log the header and changed leaf entries, if any. 929 * Log the header and changed leaf entries, if any.
705 */ 930 */
706void 931void
707xfs_dir2_leaf_compact( 932xfs_dir3_leaf_compact(
708 xfs_da_args_t *args, /* operation arguments */ 933 xfs_da_args_t *args, /* operation arguments */
934 struct xfs_dir3_icleaf_hdr *leafhdr,
709 struct xfs_buf *bp) /* leaf buffer */ 935 struct xfs_buf *bp) /* leaf buffer */
710{ 936{
711 int from; /* source leaf index */ 937 int from; /* source leaf index */
712 xfs_dir2_leaf_t *leaf; /* leaf structure */ 938 xfs_dir2_leaf_t *leaf; /* leaf structure */
713 int loglow; /* first leaf entry to log */ 939 int loglow; /* first leaf entry to log */
714 int to; /* target leaf index */ 940 int to; /* target leaf index */
941 struct xfs_dir2_leaf_entry *ents;
715 942
716 leaf = bp->b_addr; 943 leaf = bp->b_addr;
717 if (!leaf->hdr.stale) { 944 if (!leafhdr->stale)
718 return; 945 return;
719 } 946
720 /* 947 /*
721 * Compress out the stale entries in place. 948 * Compress out the stale entries in place.
722 */ 949 */
723 for (from = to = 0, loglow = -1; from < be16_to_cpu(leaf->hdr.count); from++) { 950 ents = xfs_dir3_leaf_ents_p(leaf);
724 if (leaf->ents[from].address == 951 for (from = to = 0, loglow = -1; from < leafhdr->count; from++) {
725 cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) 952 if (ents[from].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
726 continue; 953 continue;
727 /* 954 /*
728 * Only actually copy the entries that are different. 955 * Only actually copy the entries that are different.
@@ -730,19 +957,21 @@ xfs_dir2_leaf_compact(
730 if (from > to) { 957 if (from > to) {
731 if (loglow == -1) 958 if (loglow == -1)
732 loglow = to; 959 loglow = to;
733 leaf->ents[to] = leaf->ents[from]; 960 ents[to] = ents[from];
734 } 961 }
735 to++; 962 to++;
736 } 963 }
737 /* 964 /*
738 * Update and log the header, log the leaf entries. 965 * Update and log the header, log the leaf entries.
739 */ 966 */
740 ASSERT(be16_to_cpu(leaf->hdr.stale) == from - to); 967 ASSERT(leafhdr->stale == from - to);
741 be16_add_cpu(&leaf->hdr.count, -(be16_to_cpu(leaf->hdr.stale))); 968 leafhdr->count -= leafhdr->stale;
742 leaf->hdr.stale = 0; 969 leafhdr->stale = 0;
743 xfs_dir2_leaf_log_header(args->trans, bp); 970
971 xfs_dir3_leaf_hdr_to_disk(leaf, leafhdr);
972 xfs_dir3_leaf_log_header(args->trans, bp);
744 if (loglow != -1) 973 if (loglow != -1)
745 xfs_dir2_leaf_log_ents(args->trans, bp, loglow, to - 1); 974 xfs_dir3_leaf_log_ents(args->trans, bp, loglow, to - 1);
746} 975}
747 976
748/* 977/*
@@ -754,8 +983,9 @@ xfs_dir2_leaf_compact(
754 * and leaf logging indices. 983 * and leaf logging indices.
755 */ 984 */
756void 985void
757xfs_dir2_leaf_compact_x1( 986xfs_dir3_leaf_compact_x1(
758 struct xfs_buf *bp, /* leaf buffer */ 987 struct xfs_dir3_icleaf_hdr *leafhdr,
988 struct xfs_dir2_leaf_entry *ents,
759 int *indexp, /* insertion index */ 989 int *indexp, /* insertion index */
760 int *lowstalep, /* out: stale entry before us */ 990 int *lowstalep, /* out: stale entry before us */
761 int *highstalep, /* out: stale entry after us */ 991 int *highstalep, /* out: stale entry after us */
@@ -766,22 +996,20 @@ xfs_dir2_leaf_compact_x1(
766 int highstale; /* stale entry at/after index */ 996 int highstale; /* stale entry at/after index */
767 int index; /* insertion index */ 997 int index; /* insertion index */
768 int keepstale; /* source index of kept stale */ 998 int keepstale; /* source index of kept stale */
769 xfs_dir2_leaf_t *leaf; /* leaf structure */
770 int lowstale; /* stale entry before index */ 999 int lowstale; /* stale entry before index */
771 int newindex=0; /* new insertion index */ 1000 int newindex=0; /* new insertion index */
772 int to; /* destination copy index */ 1001 int to; /* destination copy index */
773 1002
774 leaf = bp->b_addr; 1003 ASSERT(leafhdr->stale > 1);
775 ASSERT(be16_to_cpu(leaf->hdr.stale) > 1);
776 index = *indexp; 1004 index = *indexp;
777 1005
778 xfs_dir2_leaf_find_stale(leaf, index, &lowstale, &highstale); 1006 xfs_dir3_leaf_find_stale(leafhdr, ents, index, &lowstale, &highstale);
779 1007
780 /* 1008 /*
781 * Pick the better of lowstale and highstale. 1009 * Pick the better of lowstale and highstale.
782 */ 1010 */
783 if (lowstale >= 0 && 1011 if (lowstale >= 0 &&
784 (highstale == be16_to_cpu(leaf->hdr.count) || 1012 (highstale == leafhdr->count ||
785 index - lowstale <= highstale - index)) 1013 index - lowstale <= highstale - index))
786 keepstale = lowstale; 1014 keepstale = lowstale;
787 else 1015 else
@@ -790,15 +1018,14 @@ xfs_dir2_leaf_compact_x1(
790 * Copy the entries in place, removing all the stale entries 1018 * Copy the entries in place, removing all the stale entries
791 * except keepstale. 1019 * except keepstale.
792 */ 1020 */
793 for (from = to = 0; from < be16_to_cpu(leaf->hdr.count); from++) { 1021 for (from = to = 0; from < leafhdr->count; from++) {
794 /* 1022 /*
795 * Notice the new value of index. 1023 * Notice the new value of index.
796 */ 1024 */
797 if (index == from) 1025 if (index == from)
798 newindex = to; 1026 newindex = to;
799 if (from != keepstale && 1027 if (from != keepstale &&
800 leaf->ents[from].address == 1028 ents[from].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) {
801 cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) {
802 if (from == to) 1029 if (from == to)
803 *lowlogp = to; 1030 *lowlogp = to;
804 continue; 1031 continue;
@@ -812,7 +1039,7 @@ xfs_dir2_leaf_compact_x1(
812 * Copy only the entries that have moved. 1039 * Copy only the entries that have moved.
813 */ 1040 */
814 if (from > to) 1041 if (from > to)
815 leaf->ents[to] = leaf->ents[from]; 1042 ents[to] = ents[from];
816 to++; 1043 to++;
817 } 1044 }
818 ASSERT(from > to); 1045 ASSERT(from > to);
@@ -826,8 +1053,8 @@ xfs_dir2_leaf_compact_x1(
826 /* 1053 /*
827 * Adjust the leaf header values. 1054 * Adjust the leaf header values.
828 */ 1055 */
829 be16_add_cpu(&leaf->hdr.count, -(from - to)); 1056 leafhdr->count -= from - to;
830 leaf->hdr.stale = cpu_to_be16(1); 1057 leafhdr->stale = 1;
831 /* 1058 /*
832 * Remember the low/high stale value only in the "right" 1059 * Remember the low/high stale value only in the "right"
833 * direction. 1060 * direction.
@@ -835,8 +1062,8 @@ xfs_dir2_leaf_compact_x1(
835 if (lowstale >= newindex) 1062 if (lowstale >= newindex)
836 lowstale = -1; 1063 lowstale = -1;
837 else 1064 else
838 highstale = be16_to_cpu(leaf->hdr.count); 1065 highstale = leafhdr->count;
839 *highlogp = be16_to_cpu(leaf->hdr.count) - 1; 1066 *highlogp = leafhdr->count - 1;
840 *lowstalep = lowstale; 1067 *lowstalep = lowstale;
841 *highstalep = highstale; 1068 *highstalep = highstale;
842} 1069}
@@ -1229,69 +1456,12 @@ xfs_dir2_leaf_getdents(
1229 return error; 1456 return error;
1230} 1457}
1231 1458
1232/*
1233 * Initialize a new leaf block, leaf1 or leafn magic accepted.
1234 */
1235int
1236xfs_dir2_leaf_init(
1237 xfs_da_args_t *args, /* operation arguments */
1238 xfs_dir2_db_t bno, /* directory block number */
1239 struct xfs_buf **bpp, /* out: leaf buffer */
1240 int magic) /* magic number for block */
1241{
1242 struct xfs_buf *bp; /* leaf buffer */
1243 xfs_inode_t *dp; /* incore directory inode */
1244 int error; /* error return code */
1245 xfs_dir2_leaf_t *leaf; /* leaf structure */
1246 xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */
1247 xfs_mount_t *mp; /* filesystem mount point */
1248 xfs_trans_t *tp; /* transaction pointer */
1249
1250 dp = args->dp;
1251 ASSERT(dp != NULL);
1252 tp = args->trans;
1253 mp = dp->i_mount;
1254 ASSERT(bno >= XFS_DIR2_LEAF_FIRSTDB(mp) &&
1255 bno < XFS_DIR2_FREE_FIRSTDB(mp));
1256 /*
1257 * Get the buffer for the block.
1258 */
1259 error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(mp, bno), -1, &bp,
1260 XFS_DATA_FORK);
1261 if (error)
1262 return error;
1263
1264 /*
1265 * Initialize the header.
1266 */
1267 leaf = bp->b_addr;
1268 leaf->hdr.info.magic = cpu_to_be16(magic);
1269 leaf->hdr.info.forw = 0;
1270 leaf->hdr.info.back = 0;
1271 leaf->hdr.count = 0;
1272 leaf->hdr.stale = 0;
1273 xfs_dir2_leaf_log_header(tp, bp);
1274 /*
1275 * If it's a leaf-format directory initialize the tail.
1276 * In this case our caller has the real bests table to copy into
1277 * the block.
1278 */
1279 if (magic == XFS_DIR2_LEAF1_MAGIC) {
1280 bp->b_ops = &xfs_dir2_leaf1_buf_ops;
1281 ltp = xfs_dir2_leaf_tail_p(mp, leaf);
1282 ltp->bestcount = 0;
1283 xfs_dir2_leaf_log_tail(tp, bp);
1284 } else
1285 bp->b_ops = &xfs_dir2_leafn_buf_ops;
1286 *bpp = bp;
1287 return 0;
1288}
1289 1459
1290/* 1460/*
1291 * Log the bests entries indicated from a leaf1 block. 1461 * Log the bests entries indicated from a leaf1 block.
1292 */ 1462 */
1293static void 1463static void
1294xfs_dir2_leaf_log_bests( 1464xfs_dir3_leaf_log_bests(
1295 xfs_trans_t *tp, /* transaction pointer */ 1465 xfs_trans_t *tp, /* transaction pointer */
1296 struct xfs_buf *bp, /* leaf buffer */ 1466 struct xfs_buf *bp, /* leaf buffer */
1297 int first, /* first entry to log */ 1467 int first, /* first entry to log */
@@ -1299,11 +1469,12 @@ xfs_dir2_leaf_log_bests(
1299{ 1469{
1300 __be16 *firstb; /* pointer to first entry */ 1470 __be16 *firstb; /* pointer to first entry */
1301 __be16 *lastb; /* pointer to last entry */ 1471 __be16 *lastb; /* pointer to last entry */
1302 xfs_dir2_leaf_t *leaf; /* leaf structure */ 1472 struct xfs_dir2_leaf *leaf = bp->b_addr;
1303 xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ 1473 xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */
1304 1474
1305 leaf = bp->b_addr; 1475 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) ||
1306 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC)); 1476 leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAF1_MAGIC));
1477
1307 ltp = xfs_dir2_leaf_tail_p(tp->t_mountp, leaf); 1478 ltp = xfs_dir2_leaf_tail_p(tp->t_mountp, leaf);
1308 firstb = xfs_dir2_leaf_bests_p(ltp) + first; 1479 firstb = xfs_dir2_leaf_bests_p(ltp) + first;
1309 lastb = xfs_dir2_leaf_bests_p(ltp) + last; 1480 lastb = xfs_dir2_leaf_bests_p(ltp) + last;
@@ -1315,7 +1486,7 @@ xfs_dir2_leaf_log_bests(
1315 * Log the leaf entries indicated from a leaf1 or leafn block. 1486 * Log the leaf entries indicated from a leaf1 or leafn block.
1316 */ 1487 */
1317void 1488void
1318xfs_dir2_leaf_log_ents( 1489xfs_dir3_leaf_log_ents(
1319 xfs_trans_t *tp, /* transaction pointer */ 1490 xfs_trans_t *tp, /* transaction pointer */
1320 struct xfs_buf *bp, /* leaf buffer */ 1491 struct xfs_buf *bp, /* leaf buffer */
1321 int first, /* first entry to log */ 1492 int first, /* first entry to log */
@@ -1323,13 +1494,17 @@ xfs_dir2_leaf_log_ents(
1323{ 1494{
1324 xfs_dir2_leaf_entry_t *firstlep; /* pointer to first entry */ 1495 xfs_dir2_leaf_entry_t *firstlep; /* pointer to first entry */
1325 xfs_dir2_leaf_entry_t *lastlep; /* pointer to last entry */ 1496 xfs_dir2_leaf_entry_t *lastlep; /* pointer to last entry */
1326 xfs_dir2_leaf_t *leaf; /* leaf structure */ 1497 struct xfs_dir2_leaf *leaf = bp->b_addr;
1498 struct xfs_dir2_leaf_entry *ents;
1327 1499
1328 leaf = bp->b_addr;
1329 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) || 1500 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) ||
1330 leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); 1501 leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAF1_MAGIC) ||
1331 firstlep = &leaf->ents[first]; 1502 leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
1332 lastlep = &leaf->ents[last]; 1503 leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC));
1504
1505 ents = xfs_dir3_leaf_ents_p(leaf);
1506 firstlep = &ents[first];
1507 lastlep = &ents[last];
1333 xfs_trans_log_buf(tp, bp, (uint)((char *)firstlep - (char *)leaf), 1508 xfs_trans_log_buf(tp, bp, (uint)((char *)firstlep - (char *)leaf),
1334 (uint)((char *)lastlep - (char *)leaf + sizeof(*lastlep) - 1)); 1509 (uint)((char *)lastlep - (char *)leaf + sizeof(*lastlep) - 1));
1335} 1510}
@@ -1338,34 +1513,38 @@ xfs_dir2_leaf_log_ents(
1338 * Log the header of the leaf1 or leafn block. 1513 * Log the header of the leaf1 or leafn block.
1339 */ 1514 */
1340void 1515void
1341xfs_dir2_leaf_log_header( 1516xfs_dir3_leaf_log_header(
1342 struct xfs_trans *tp, 1517 struct xfs_trans *tp,
1343 struct xfs_buf *bp) 1518 struct xfs_buf *bp)
1344{ 1519{
1345 xfs_dir2_leaf_t *leaf; /* leaf structure */ 1520 struct xfs_dir2_leaf *leaf = bp->b_addr;
1346 1521
1347 leaf = bp->b_addr;
1348 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) || 1522 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) ||
1349 leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); 1523 leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAF1_MAGIC) ||
1524 leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
1525 leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC));
1526
1350 xfs_trans_log_buf(tp, bp, (uint)((char *)&leaf->hdr - (char *)leaf), 1527 xfs_trans_log_buf(tp, bp, (uint)((char *)&leaf->hdr - (char *)leaf),
1351 (uint)(sizeof(leaf->hdr) - 1)); 1528 xfs_dir3_leaf_hdr_size(leaf) - 1);
1352} 1529}
1353 1530
1354/* 1531/*
1355 * Log the tail of the leaf1 block. 1532 * Log the tail of the leaf1 block.
1356 */ 1533 */
1357STATIC void 1534STATIC void
1358xfs_dir2_leaf_log_tail( 1535xfs_dir3_leaf_log_tail(
1359 struct xfs_trans *tp, 1536 struct xfs_trans *tp,
1360 struct xfs_buf *bp) 1537 struct xfs_buf *bp)
1361{ 1538{
1362 xfs_dir2_leaf_t *leaf; /* leaf structure */ 1539 struct xfs_dir2_leaf *leaf = bp->b_addr;
1363 xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ 1540 xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */
1364 xfs_mount_t *mp; /* filesystem mount point */ 1541 struct xfs_mount *mp = tp->t_mountp;
1542
1543 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) ||
1544 leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAF1_MAGIC) ||
1545 leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
1546 leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC));
1365 1547
1366 mp = tp->t_mountp;
1367 leaf = bp->b_addr;
1368 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC));
1369 ltp = xfs_dir2_leaf_tail_p(mp, leaf); 1548 ltp = xfs_dir2_leaf_tail_p(mp, leaf);
1370 xfs_trans_log_buf(tp, bp, (uint)((char *)ltp - (char *)leaf), 1549 xfs_trans_log_buf(tp, bp, (uint)((char *)ltp - (char *)leaf),
1371 (uint)(mp->m_dirblksize - 1)); 1550 (uint)(mp->m_dirblksize - 1));
@@ -1389,6 +1568,7 @@ xfs_dir2_leaf_lookup(
1389 xfs_dir2_leaf_t *leaf; /* leaf structure */ 1568 xfs_dir2_leaf_t *leaf; /* leaf structure */
1390 xfs_dir2_leaf_entry_t *lep; /* leaf entry */ 1569 xfs_dir2_leaf_entry_t *lep; /* leaf entry */
1391 xfs_trans_t *tp; /* transaction pointer */ 1570 xfs_trans_t *tp; /* transaction pointer */
1571 struct xfs_dir2_leaf_entry *ents;
1392 1572
1393 trace_xfs_dir2_leaf_lookup(args); 1573 trace_xfs_dir2_leaf_lookup(args);
1394 1574
@@ -1400,12 +1580,14 @@ xfs_dir2_leaf_lookup(
1400 } 1580 }
1401 tp = args->trans; 1581 tp = args->trans;
1402 dp = args->dp; 1582 dp = args->dp;
1403 xfs_dir2_leaf_check(dp, lbp); 1583 xfs_dir3_leaf_check(dp->i_mount, lbp);
1404 leaf = lbp->b_addr; 1584 leaf = lbp->b_addr;
1585 ents = xfs_dir3_leaf_ents_p(leaf);
1405 /* 1586 /*
1406 * Get to the leaf entry and contained data entry address. 1587 * Get to the leaf entry and contained data entry address.
1407 */ 1588 */
1408 lep = &leaf->ents[index]; 1589 lep = &ents[index];
1590
1409 /* 1591 /*
1410 * Point to the data entry. 1592 * Point to the data entry.
1411 */ 1593 */
@@ -1449,18 +1631,23 @@ xfs_dir2_leaf_lookup_int(
1449 xfs_trans_t *tp; /* transaction pointer */ 1631 xfs_trans_t *tp; /* transaction pointer */
1450 xfs_dir2_db_t cidb = -1; /* case match data block no. */ 1632 xfs_dir2_db_t cidb = -1; /* case match data block no. */
1451 enum xfs_dacmp cmp; /* name compare result */ 1633 enum xfs_dacmp cmp; /* name compare result */
1634 struct xfs_dir2_leaf_entry *ents;
1635 struct xfs_dir3_icleaf_hdr leafhdr;
1452 1636
1453 dp = args->dp; 1637 dp = args->dp;
1454 tp = args->trans; 1638 tp = args->trans;
1455 mp = dp->i_mount; 1639 mp = dp->i_mount;
1456 1640
1457 error = xfs_dir2_leaf_read(tp, dp, mp->m_dirleafblk, -1, &lbp); 1641 error = xfs_dir3_leaf_read(tp, dp, mp->m_dirleafblk, -1, &lbp);
1458 if (error) 1642 if (error)
1459 return error; 1643 return error;
1460 1644
1461 *lbpp = lbp; 1645 *lbpp = lbp;
1462 leaf = lbp->b_addr; 1646 leaf = lbp->b_addr;
1463 xfs_dir2_leaf_check(dp, lbp); 1647 xfs_dir3_leaf_check(mp, lbp);
1648 ents = xfs_dir3_leaf_ents_p(leaf);
1649 xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
1650
1464 /* 1651 /*
1465 * Look for the first leaf entry with our hash value. 1652 * Look for the first leaf entry with our hash value.
1466 */ 1653 */
@@ -1469,9 +1656,9 @@ xfs_dir2_leaf_lookup_int(
1469 * Loop over all the entries with the right hash value 1656 * Loop over all the entries with the right hash value
1470 * looking to match the name. 1657 * looking to match the name.
1471 */ 1658 */
1472 for (lep = &leaf->ents[index]; index < be16_to_cpu(leaf->hdr.count) && 1659 for (lep = &ents[index];
1473 be32_to_cpu(lep->hashval) == args->hashval; 1660 index < leafhdr.count && be32_to_cpu(lep->hashval) == args->hashval;
1474 lep++, index++) { 1661 lep++, index++) {
1475 /* 1662 /*
1476 * Skip over stale leaf entries. 1663 * Skip over stale leaf entries.
1477 */ 1664 */
@@ -1576,6 +1763,8 @@ xfs_dir2_leaf_removename(
1576 xfs_dir2_data_off_t oldbest; /* old value of best free */ 1763 xfs_dir2_data_off_t oldbest; /* old value of best free */
1577 xfs_trans_t *tp; /* transaction pointer */ 1764 xfs_trans_t *tp; /* transaction pointer */
1578 struct xfs_dir2_data_free *bf; /* bestfree table */ 1765 struct xfs_dir2_data_free *bf; /* bestfree table */
1766 struct xfs_dir2_leaf_entry *ents;
1767 struct xfs_dir3_icleaf_hdr leafhdr;
1579 1768
1580 trace_xfs_dir2_leaf_removename(args); 1769 trace_xfs_dir2_leaf_removename(args);
1581 1770
@@ -1590,12 +1779,14 @@ xfs_dir2_leaf_removename(
1590 mp = dp->i_mount; 1779 mp = dp->i_mount;
1591 leaf = lbp->b_addr; 1780 leaf = lbp->b_addr;
1592 hdr = dbp->b_addr; 1781 hdr = dbp->b_addr;
1593 bf = xfs_dir3_data_bestfree_p(hdr);
1594 xfs_dir3_data_check(dp, dbp); 1782 xfs_dir3_data_check(dp, dbp);
1783 bf = xfs_dir3_data_bestfree_p(hdr);
1784 xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
1785 ents = xfs_dir3_leaf_ents_p(leaf);
1595 /* 1786 /*
1596 * Point to the leaf entry, use that to point to the data entry. 1787 * Point to the leaf entry, use that to point to the data entry.
1597 */ 1788 */
1598 lep = &leaf->ents[index]; 1789 lep = &ents[index];
1599 db = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); 1790 db = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address));
1600 dep = (xfs_dir2_data_entry_t *) 1791 dep = (xfs_dir2_data_entry_t *)
1601 ((char *)hdr + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address))); 1792 ((char *)hdr + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address)));
@@ -1613,10 +1804,13 @@ xfs_dir2_leaf_removename(
1613 /* 1804 /*
1614 * We just mark the leaf entry stale by putting a null in it. 1805 * We just mark the leaf entry stale by putting a null in it.
1615 */ 1806 */
1616 be16_add_cpu(&leaf->hdr.stale, 1); 1807 leafhdr.stale++;
1617 xfs_dir2_leaf_log_header(tp, lbp); 1808 xfs_dir3_leaf_hdr_to_disk(leaf, &leafhdr);
1809 xfs_dir3_leaf_log_header(tp, lbp);
1810
1618 lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR); 1811 lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR);
1619 xfs_dir2_leaf_log_ents(tp, lbp, index, index); 1812 xfs_dir3_leaf_log_ents(tp, lbp, index, index);
1813
1620 /* 1814 /*
1621 * Scan the freespace in the data block again if necessary, 1815 * Scan the freespace in the data block again if necessary,
1622 * log the data block header if necessary. 1816 * log the data block header if necessary.
@@ -1631,7 +1825,7 @@ xfs_dir2_leaf_removename(
1631 */ 1825 */
1632 if (be16_to_cpu(bf[0].length) != oldbest) { 1826 if (be16_to_cpu(bf[0].length) != oldbest) {
1633 bestsp[db] = bf[0].length; 1827 bestsp[db] = bf[0].length;
1634 xfs_dir2_leaf_log_bests(tp, lbp, db, db); 1828 xfs_dir3_leaf_log_bests(tp, lbp, db, db);
1635 } 1829 }
1636 xfs_dir3_data_check(dp, dbp); 1830 xfs_dir3_data_check(dp, dbp);
1637 /* 1831 /*
@@ -1649,7 +1843,7 @@ xfs_dir2_leaf_removename(
1649 */ 1843 */
1650 if (error == ENOSPC && args->total == 0) 1844 if (error == ENOSPC && args->total == 0)
1651 error = 0; 1845 error = 0;
1652 xfs_dir2_leaf_check(dp, lbp); 1846 xfs_dir3_leaf_check(mp, lbp);
1653 return error; 1847 return error;
1654 } 1848 }
1655 dbp = NULL; 1849 dbp = NULL;
@@ -1672,8 +1866,8 @@ xfs_dir2_leaf_removename(
1672 memmove(&bestsp[db - i], bestsp, 1866 memmove(&bestsp[db - i], bestsp,
1673 (be32_to_cpu(ltp->bestcount) - (db - i)) * sizeof(*bestsp)); 1867 (be32_to_cpu(ltp->bestcount) - (db - i)) * sizeof(*bestsp));
1674 be32_add_cpu(&ltp->bestcount, -(db - i)); 1868 be32_add_cpu(&ltp->bestcount, -(db - i));
1675 xfs_dir2_leaf_log_tail(tp, lbp); 1869 xfs_dir3_leaf_log_tail(tp, lbp);
1676 xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); 1870 xfs_dir3_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
1677 } else 1871 } else
1678 bestsp[db] = cpu_to_be16(NULLDATAOFF); 1872 bestsp[db] = cpu_to_be16(NULLDATAOFF);
1679 } 1873 }
@@ -1683,7 +1877,7 @@ xfs_dir2_leaf_removename(
1683 else if (db != mp->m_dirdatablk) 1877 else if (db != mp->m_dirdatablk)
1684 dbp = NULL; 1878 dbp = NULL;
1685 1879
1686 xfs_dir2_leaf_check(dp, lbp); 1880 xfs_dir3_leaf_check(mp, lbp);
1687 /* 1881 /*
1688 * See if we can convert to block form. 1882 * See if we can convert to block form.
1689 */ 1883 */
@@ -1706,6 +1900,7 @@ xfs_dir2_leaf_replace(
1706 xfs_dir2_leaf_t *leaf; /* leaf structure */ 1900 xfs_dir2_leaf_t *leaf; /* leaf structure */
1707 xfs_dir2_leaf_entry_t *lep; /* leaf entry */ 1901 xfs_dir2_leaf_entry_t *lep; /* leaf entry */
1708 xfs_trans_t *tp; /* transaction pointer */ 1902 xfs_trans_t *tp; /* transaction pointer */
1903 struct xfs_dir2_leaf_entry *ents;
1709 1904
1710 trace_xfs_dir2_leaf_replace(args); 1905 trace_xfs_dir2_leaf_replace(args);
1711 1906
@@ -1717,10 +1912,11 @@ xfs_dir2_leaf_replace(
1717 } 1912 }
1718 dp = args->dp; 1913 dp = args->dp;
1719 leaf = lbp->b_addr; 1914 leaf = lbp->b_addr;
1915 ents = xfs_dir3_leaf_ents_p(leaf);
1720 /* 1916 /*
1721 * Point to the leaf entry, get data address from it. 1917 * Point to the leaf entry, get data address from it.
1722 */ 1918 */
1723 lep = &leaf->ents[index]; 1919 lep = &ents[index];
1724 /* 1920 /*
1725 * Point to the data entry. 1921 * Point to the data entry.
1726 */ 1922 */
@@ -1734,7 +1930,7 @@ xfs_dir2_leaf_replace(
1734 dep->inumber = cpu_to_be64(args->inumber); 1930 dep->inumber = cpu_to_be64(args->inumber);
1735 tp = args->trans; 1931 tp = args->trans;
1736 xfs_dir2_data_log_entry(tp, dbp, dep); 1932 xfs_dir2_data_log_entry(tp, dbp, dep);
1737 xfs_dir2_leaf_check(dp, lbp); 1933 xfs_dir3_leaf_check(dp->i_mount, lbp);
1738 xfs_trans_brelse(tp, lbp); 1934 xfs_trans_brelse(tp, lbp);
1739 return 0; 1935 return 0;
1740} 1936}
@@ -1756,17 +1952,22 @@ xfs_dir2_leaf_search_hash(
1756 xfs_dir2_leaf_t *leaf; /* leaf structure */ 1952 xfs_dir2_leaf_t *leaf; /* leaf structure */
1757 xfs_dir2_leaf_entry_t *lep; /* leaf entry */ 1953 xfs_dir2_leaf_entry_t *lep; /* leaf entry */
1758 int mid=0; /* current leaf index */ 1954 int mid=0; /* current leaf index */
1955 struct xfs_dir2_leaf_entry *ents;
1956 struct xfs_dir3_icleaf_hdr leafhdr;
1759 1957
1760 leaf = lbp->b_addr; 1958 leaf = lbp->b_addr;
1959 ents = xfs_dir3_leaf_ents_p(leaf);
1960 xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
1961
1761#ifndef __KERNEL__ 1962#ifndef __KERNEL__
1762 if (!leaf->hdr.count) 1963 if (!leafhdr.count)
1763 return 0; 1964 return 0;
1764#endif 1965#endif
1765 /* 1966 /*
1766 * Note, the table cannot be empty, so we have to go through the loop. 1967 * Note, the table cannot be empty, so we have to go through the loop.
1767 * Binary search the leaf entries looking for our hash value. 1968 * Binary search the leaf entries looking for our hash value.
1768 */ 1969 */
1769 for (lep = leaf->ents, low = 0, high = be16_to_cpu(leaf->hdr.count) - 1, 1970 for (lep = ents, low = 0, high = leafhdr.count - 1,
1770 hashwant = args->hashval; 1971 hashwant = args->hashval;
1771 low <= high; ) { 1972 low <= high; ) {
1772 mid = (low + high) >> 1; 1973 mid = (low + high) >> 1;
@@ -1852,23 +2053,29 @@ xfs_dir2_leaf_trim_data(
1852 bestsp = xfs_dir2_leaf_bests_p(ltp); 2053 bestsp = xfs_dir2_leaf_bests_p(ltp);
1853 be32_add_cpu(&ltp->bestcount, -1); 2054 be32_add_cpu(&ltp->bestcount, -1);
1854 memmove(&bestsp[1], &bestsp[0], be32_to_cpu(ltp->bestcount) * sizeof(*bestsp)); 2055 memmove(&bestsp[1], &bestsp[0], be32_to_cpu(ltp->bestcount) * sizeof(*bestsp));
1855 xfs_dir2_leaf_log_tail(tp, lbp); 2056 xfs_dir3_leaf_log_tail(tp, lbp);
1856 xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); 2057 xfs_dir3_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
1857 return 0; 2058 return 0;
1858} 2059}
1859 2060
1860static inline size_t 2061static inline size_t
1861xfs_dir2_leaf_size( 2062xfs_dir3_leaf_size(
1862 struct xfs_dir2_leaf_hdr *hdr, 2063 struct xfs_dir3_icleaf_hdr *hdr,
1863 int counts) 2064 int counts)
1864{ 2065{
1865 int entries; 2066 int entries;
2067 int hdrsize;
2068
2069 entries = hdr->count - hdr->stale;
2070 if (hdr->magic == XFS_DIR2_LEAF1_MAGIC ||
2071 hdr->magic == XFS_DIR2_LEAFN_MAGIC)
2072 hdrsize = sizeof(struct xfs_dir2_leaf_hdr);
2073 else
2074 hdrsize = sizeof(struct xfs_dir3_leaf_hdr);
1866 2075
1867 entries = be16_to_cpu(hdr->count) - be16_to_cpu(hdr->stale); 2076 return hdrsize + entries * sizeof(xfs_dir2_leaf_entry_t)
1868 return sizeof(xfs_dir2_leaf_hdr_t) + 2077 + counts * sizeof(xfs_dir2_data_off_t)
1869 entries * sizeof(xfs_dir2_leaf_entry_t) + 2078 + sizeof(xfs_dir2_leaf_tail_t);
1870 counts * sizeof(xfs_dir2_data_off_t) +
1871 sizeof(xfs_dir2_leaf_tail_t);
1872} 2079}
1873 2080
1874/* 2081/*
@@ -1892,6 +2099,7 @@ xfs_dir2_node_to_leaf(
1892 xfs_mount_t *mp; /* filesystem mount point */ 2099 xfs_mount_t *mp; /* filesystem mount point */
1893 int rval; /* successful free trim? */ 2100 int rval; /* successful free trim? */
1894 xfs_trans_t *tp; /* transaction pointer */ 2101 xfs_trans_t *tp; /* transaction pointer */
2102 struct xfs_dir3_icleaf_hdr leafhdr;
1895 struct xfs_dir3_icfree_hdr freehdr; 2103 struct xfs_dir3_icfree_hdr freehdr;
1896 2104
1897 /* 2105 /*
@@ -1942,7 +2150,11 @@ xfs_dir2_node_to_leaf(
1942 return 0; 2150 return 0;
1943 lbp = state->path.blk[0].bp; 2151 lbp = state->path.blk[0].bp;
1944 leaf = lbp->b_addr; 2152 leaf = lbp->b_addr;
1945 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); 2153 xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
2154
2155 ASSERT(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC ||
2156 leafhdr.magic == XFS_DIR3_LEAFN_MAGIC);
2157
1946 /* 2158 /*
1947 * Read the freespace block. 2159 * Read the freespace block.
1948 */ 2160 */
@@ -1958,36 +2170,40 @@ xfs_dir2_node_to_leaf(
1958 * Now see if the leafn and free data will fit in a leaf1. 2170 * Now see if the leafn and free data will fit in a leaf1.
1959 * If not, release the buffer and give up. 2171 * If not, release the buffer and give up.
1960 */ 2172 */
1961 if (xfs_dir2_leaf_size(&leaf->hdr, freehdr.nvalid) > mp->m_dirblksize) { 2173 if (xfs_dir3_leaf_size(&leafhdr, freehdr.nvalid) > mp->m_dirblksize) {
1962 xfs_trans_brelse(tp, fbp); 2174 xfs_trans_brelse(tp, fbp);
1963 return 0; 2175 return 0;
1964 } 2176 }
1965 2177
1966 /* 2178 /*
1967 * If the leaf has any stale entries in it, compress them out. 2179 * If the leaf has any stale entries in it, compress them out.
1968 * The compact routine will log the header.
1969 */ 2180 */
1970 if (be16_to_cpu(leaf->hdr.stale)) 2181 if (leafhdr.stale)
1971 xfs_dir2_leaf_compact(args, lbp); 2182 xfs_dir3_leaf_compact(args, &leafhdr, lbp);
1972 else
1973 xfs_dir2_leaf_log_header(tp, lbp);
1974 2183
1975 lbp->b_ops = &xfs_dir2_leaf1_buf_ops; 2184 lbp->b_ops = &xfs_dir3_leaf1_buf_ops;
1976 leaf->hdr.info.magic = cpu_to_be16(XFS_DIR2_LEAF1_MAGIC); 2185 leafhdr.magic = (leafhdr.magic == XFS_DIR2_LEAFN_MAGIC)
2186 ? XFS_DIR2_LEAF1_MAGIC
2187 : XFS_DIR3_LEAF1_MAGIC;
1977 2188
1978 /* 2189 /*
1979 * Set up the leaf tail from the freespace block. 2190 * Set up the leaf tail from the freespace block.
1980 */ 2191 */
1981 ltp = xfs_dir2_leaf_tail_p(mp, leaf); 2192 ltp = xfs_dir2_leaf_tail_p(mp, leaf);
1982 ltp->bestcount = cpu_to_be32(freehdr.nvalid); 2193 ltp->bestcount = cpu_to_be32(freehdr.nvalid);
2194
1983 /* 2195 /*
1984 * Set up the leaf bests table. 2196 * Set up the leaf bests table.
1985 */ 2197 */
1986 memcpy(xfs_dir2_leaf_bests_p(ltp), xfs_dir3_free_bests_p(mp, free), 2198 memcpy(xfs_dir2_leaf_bests_p(ltp), xfs_dir3_free_bests_p(mp, free),
1987 freehdr.nvalid * sizeof(xfs_dir2_data_off_t)); 2199 freehdr.nvalid * sizeof(xfs_dir2_data_off_t));
1988 xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); 2200
1989 xfs_dir2_leaf_log_tail(tp, lbp); 2201 xfs_dir3_leaf_hdr_to_disk(leaf, &leafhdr);
1990 xfs_dir2_leaf_check(dp, lbp); 2202 xfs_dir3_leaf_log_header(tp, lbp);
2203 xfs_dir3_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
2204 xfs_dir3_leaf_log_tail(tp, lbp);
2205 xfs_dir3_leaf_check(mp, lbp);
2206
1991 /* 2207 /*
1992 * Get rid of the freespace block. 2208 * Get rid of the freespace block.
1993 */ 2209 */
diff --git a/fs/xfs/xfs_dir2_node.c b/fs/xfs/xfs_dir2_node.c
index abf617d5060b..baaf9d96e354 100644
--- a/fs/xfs/xfs_dir2_node.c
+++ b/fs/xfs/xfs_dir2_node.c
@@ -41,14 +41,6 @@
41 */ 41 */
42static int xfs_dir2_leafn_add(struct xfs_buf *bp, xfs_da_args_t *args, 42static int xfs_dir2_leafn_add(struct xfs_buf *bp, xfs_da_args_t *args,
43 int index); 43 int index);
44#ifdef DEBUG
45static void xfs_dir2_leafn_check(struct xfs_inode *dp, struct xfs_buf *bp);
46#else
47#define xfs_dir2_leafn_check(dp, bp)
48#endif
49static void xfs_dir2_leafn_moveents(xfs_da_args_t *args, struct xfs_buf *bp_s,
50 int start_s, struct xfs_buf *bp_d,
51 int start_d, int count);
52static void xfs_dir2_leafn_rebalance(xfs_da_state_t *state, 44static void xfs_dir2_leafn_rebalance(xfs_da_state_t *state,
53 xfs_da_state_blk_t *blk1, 45 xfs_da_state_blk_t *blk1,
54 xfs_da_state_blk_t *blk2); 46 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,
58static int xfs_dir2_node_addname_int(xfs_da_args_t *args, 50static int xfs_dir2_node_addname_int(xfs_da_args_t *args,
59 xfs_da_state_blk_t *fblk); 51 xfs_da_state_blk_t *fblk);
60 52
53/*
54 * Check internal consistency of a leafn block.
55 */
56#ifdef DEBUG
57#define xfs_dir3_leaf_check(mp, bp) \
58do { \
59 if (!xfs_dir3_leafn_check((mp), (bp))) \
60 ASSERT(0); \
61} while (0);
62
63static bool
64xfs_dir3_leafn_check(
65 struct xfs_mount *mp,
66 struct xfs_buf *bp)
67{
68 struct xfs_dir2_leaf *leaf = bp->b_addr;
69 struct xfs_dir3_icleaf_hdr leafhdr;
70
71 xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
72
73 if (leafhdr.magic == XFS_DIR3_LEAFN_MAGIC) {
74 struct xfs_dir3_leaf_hdr *leaf3 = bp->b_addr;
75 if (be64_to_cpu(leaf3->info.blkno) != bp->b_bn)
76 return false;
77 } else if (leafhdr.magic != XFS_DIR2_LEAFN_MAGIC)
78 return false;
79
80 return xfs_dir3_leaf_check_int(mp, &leafhdr, leaf);
81}
82#else
83#define xfs_dir3_leaf_check(mp, bp)
84#endif
85
61static bool 86static bool
62xfs_dir3_free_verify( 87xfs_dir3_free_verify(
63 struct xfs_buf *bp) 88 struct xfs_buf *bp)
@@ -360,11 +385,19 @@ xfs_dir2_leaf_to_node(
360 xfs_dir2_free_log_bests(tp, fbp, 0, freehdr.nvalid - 1); 385 xfs_dir2_free_log_bests(tp, fbp, 0, freehdr.nvalid - 1);
361 xfs_dir2_free_log_header(tp, fbp); 386 xfs_dir2_free_log_header(tp, fbp);
362 387
363 /* convert the leaf to a leafnode */ 388 /*
364 leaf->hdr.info.magic = cpu_to_be16(XFS_DIR2_LEAFN_MAGIC); 389 * Converting the leaf to a leafnode is just a matter of changing the
365 lbp->b_ops = &xfs_dir2_leafn_buf_ops; 390 * magic number and the ops. Do the change directly to the buffer as
366 xfs_dir2_leaf_log_header(tp, lbp); 391 * it's less work (and less code) than decoding the header to host
367 xfs_dir2_leafn_check(dp, lbp); 392 * format and back again.
393 */
394 if (leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC))
395 leaf->hdr.info.magic = cpu_to_be16(XFS_DIR2_LEAFN_MAGIC);
396 else
397 leaf->hdr.info.magic = cpu_to_be16(XFS_DIR3_LEAFN_MAGIC);
398 lbp->b_ops = &xfs_dir3_leafn_buf_ops;
399 xfs_dir3_leaf_log_header(tp, lbp);
400 xfs_dir3_leaf_check(mp, lbp);
368 return 0; 401 return 0;
369} 402}
370 403
@@ -388,6 +421,8 @@ xfs_dir2_leafn_add(
388 int lowstale; /* previous stale entry */ 421 int lowstale; /* previous stale entry */
389 xfs_mount_t *mp; /* filesystem mount point */ 422 xfs_mount_t *mp; /* filesystem mount point */
390 xfs_trans_t *tp; /* transaction pointer */ 423 xfs_trans_t *tp; /* transaction pointer */
424 struct xfs_dir3_icleaf_hdr leafhdr;
425 struct xfs_dir2_leaf_entry *ents;
391 426
392 trace_xfs_dir2_leafn_add(args, index); 427 trace_xfs_dir2_leafn_add(args, index);
393 428
@@ -395,6 +430,8 @@ xfs_dir2_leafn_add(
395 mp = dp->i_mount; 430 mp = dp->i_mount;
396 tp = args->trans; 431 tp = args->trans;
397 leaf = bp->b_addr; 432 leaf = bp->b_addr;
433 xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
434 ents = xfs_dir3_leaf_ents_p(leaf);
398 435
399 /* 436 /*
400 * Quick check just to make sure we are not going to index 437 * Quick check just to make sure we are not going to index
@@ -410,15 +447,15 @@ xfs_dir2_leafn_add(
410 * a compact. 447 * a compact.
411 */ 448 */
412 449
413 if (be16_to_cpu(leaf->hdr.count) == xfs_dir2_max_leaf_ents(mp)) { 450 if (leafhdr.count == xfs_dir3_max_leaf_ents(mp, leaf)) {
414 if (!leaf->hdr.stale) 451 if (!leafhdr.stale)
415 return XFS_ERROR(ENOSPC); 452 return XFS_ERROR(ENOSPC);
416 compact = be16_to_cpu(leaf->hdr.stale) > 1; 453 compact = leafhdr.stale > 1;
417 } else 454 } else
418 compact = 0; 455 compact = 0;
419 ASSERT(index == 0 || be32_to_cpu(leaf->ents[index - 1].hashval) <= args->hashval); 456 ASSERT(index == 0 || be32_to_cpu(ents[index - 1].hashval) <= args->hashval);
420 ASSERT(index == be16_to_cpu(leaf->hdr.count) || 457 ASSERT(index == leafhdr.count ||
421 be32_to_cpu(leaf->ents[index].hashval) >= args->hashval); 458 be32_to_cpu(ents[index].hashval) >= args->hashval);
422 459
423 if (args->op_flags & XFS_DA_OP_JUSTCHECK) 460 if (args->op_flags & XFS_DA_OP_JUSTCHECK)
424 return 0; 461 return 0;
@@ -427,62 +464,35 @@ xfs_dir2_leafn_add(
427 * Compact out all but one stale leaf entry. Leaves behind 464 * Compact out all but one stale leaf entry. Leaves behind
428 * the entry closest to index. 465 * the entry closest to index.
429 */ 466 */
430 if (compact) { 467 if (compact)
431 xfs_dir2_leaf_compact_x1(bp, &index, &lowstale, &highstale, 468 xfs_dir3_leaf_compact_x1(&leafhdr, ents, &index, &lowstale,
432 &lfloglow, &lfloghigh); 469 &highstale, &lfloglow, &lfloghigh);
433 } 470 else if (leafhdr.stale) {
434 /* 471 /*
435 * Set impossible logging indices for this case. 472 * Set impossible logging indices for this case.
436 */ 473 */
437 else if (leaf->hdr.stale) { 474 lfloglow = leafhdr.count;
438 lfloglow = be16_to_cpu(leaf->hdr.count);
439 lfloghigh = -1; 475 lfloghigh = -1;
440 } 476 }
441 477
442 /* 478 /*
443 * Insert the new entry, log everything. 479 * Insert the new entry, log everything.
444 */ 480 */
445 lep = xfs_dir2_leaf_find_entry(leaf, index, compact, lowstale, 481 lep = xfs_dir3_leaf_find_entry(&leafhdr, ents, index, compact, lowstale,
446 highstale, &lfloglow, &lfloghigh); 482 highstale, &lfloglow, &lfloghigh);
447 483
448 lep->hashval = cpu_to_be32(args->hashval); 484 lep->hashval = cpu_to_be32(args->hashval);
449 lep->address = cpu_to_be32(xfs_dir2_db_off_to_dataptr(mp, 485 lep->address = cpu_to_be32(xfs_dir2_db_off_to_dataptr(mp,
450 args->blkno, args->index)); 486 args->blkno, args->index));
451 xfs_dir2_leaf_log_header(tp, bp); 487
452 xfs_dir2_leaf_log_ents(tp, bp, lfloglow, lfloghigh); 488 xfs_dir3_leaf_hdr_to_disk(leaf, &leafhdr);
453 xfs_dir2_leafn_check(dp, bp); 489 xfs_dir3_leaf_log_header(tp, bp);
490 xfs_dir3_leaf_log_ents(tp, bp, lfloglow, lfloghigh);
491 xfs_dir3_leaf_check(mp, bp);
454 return 0; 492 return 0;
455} 493}
456 494
457#ifdef DEBUG 495#ifdef DEBUG
458/*
459 * Check internal consistency of a leafn block.
460 */
461void
462xfs_dir2_leafn_check(
463 struct xfs_inode *dp,
464 struct xfs_buf *bp)
465{
466 int i; /* leaf index */
467 xfs_dir2_leaf_t *leaf; /* leaf structure */
468 xfs_mount_t *mp; /* filesystem mount point */
469 int stale; /* count of stale leaves */
470
471 leaf = bp->b_addr;
472 mp = dp->i_mount;
473 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC));
474 ASSERT(be16_to_cpu(leaf->hdr.count) <= xfs_dir2_max_leaf_ents(mp));
475 for (i = stale = 0; i < be16_to_cpu(leaf->hdr.count); i++) {
476 if (i + 1 < be16_to_cpu(leaf->hdr.count)) {
477 ASSERT(be32_to_cpu(leaf->ents[i].hashval) <=
478 be32_to_cpu(leaf->ents[i + 1].hashval));
479 }
480 if (leaf->ents[i].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
481 stale++;
482 }
483 ASSERT(be16_to_cpu(leaf->hdr.stale) == stale);
484}
485
486static void 496static void
487xfs_dir2_free_hdr_check( 497xfs_dir2_free_hdr_check(
488 struct xfs_mount *mp, 498 struct xfs_mount *mp,
@@ -510,15 +520,22 @@ xfs_dir2_leafn_lasthash(
510 struct xfs_buf *bp, /* leaf buffer */ 520 struct xfs_buf *bp, /* leaf buffer */
511 int *count) /* count of entries in leaf */ 521 int *count) /* count of entries in leaf */
512{ 522{
513 xfs_dir2_leaf_t *leaf; /* leaf structure */ 523 struct xfs_dir2_leaf *leaf = bp->b_addr;
524 struct xfs_dir2_leaf_entry *ents;
525 struct xfs_dir3_icleaf_hdr leafhdr;
526
527 xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
528
529 ASSERT(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC ||
530 leafhdr.magic == XFS_DIR3_LEAFN_MAGIC);
514 531
515 leaf = bp->b_addr;
516 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC));
517 if (count) 532 if (count)
518 *count = be16_to_cpu(leaf->hdr.count); 533 *count = leafhdr.count;
519 if (!leaf->hdr.count) 534 if (!leafhdr.count)
520 return 0; 535 return 0;
521 return be32_to_cpu(leaf->ents[be16_to_cpu(leaf->hdr.count) - 1].hashval); 536
537 ents = xfs_dir3_leaf_ents_p(leaf);
538 return be32_to_cpu(ents[leafhdr.count - 1].hashval);
522} 539}
523 540
524/* 541/*
@@ -547,16 +564,19 @@ xfs_dir2_leafn_lookup_for_addname(
547 xfs_dir2_db_t newdb; /* new data block number */ 564 xfs_dir2_db_t newdb; /* new data block number */
548 xfs_dir2_db_t newfdb; /* new free block number */ 565 xfs_dir2_db_t newfdb; /* new free block number */
549 xfs_trans_t *tp; /* transaction pointer */ 566 xfs_trans_t *tp; /* transaction pointer */
567 struct xfs_dir2_leaf_entry *ents;
568 struct xfs_dir3_icleaf_hdr leafhdr;
550 569
551 dp = args->dp; 570 dp = args->dp;
552 tp = args->trans; 571 tp = args->trans;
553 mp = dp->i_mount; 572 mp = dp->i_mount;
554 leaf = bp->b_addr; 573 leaf = bp->b_addr;
555 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); 574 xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
556#ifdef __KERNEL__ 575 ents = xfs_dir3_leaf_ents_p(leaf);
557 ASSERT(be16_to_cpu(leaf->hdr.count) > 0); 576
558#endif 577 xfs_dir3_leaf_check(mp, bp);
559 xfs_dir2_leafn_check(dp, bp); 578 ASSERT(leafhdr.count > 0);
579
560 /* 580 /*
561 * Look up the hash value in the leaf entries. 581 * Look up the hash value in the leaf entries.
562 */ 582 */
@@ -576,9 +596,9 @@ xfs_dir2_leafn_lookup_for_addname(
576 /* 596 /*
577 * Loop over leaf entries with the right hash value. 597 * Loop over leaf entries with the right hash value.
578 */ 598 */
579 for (lep = &leaf->ents[index]; index < be16_to_cpu(leaf->hdr.count) && 599 for (lep = &ents[index];
580 be32_to_cpu(lep->hashval) == args->hashval; 600 index < leafhdr.count && be32_to_cpu(lep->hashval) == args->hashval;
581 lep++, index++) { 601 lep++, index++) {
582 /* 602 /*
583 * Skip stale leaf entries. 603 * Skip stale leaf entries.
584 */ 604 */
@@ -694,16 +714,19 @@ xfs_dir2_leafn_lookup_for_entry(
694 xfs_dir2_db_t newdb; /* new data block number */ 714 xfs_dir2_db_t newdb; /* new data block number */
695 xfs_trans_t *tp; /* transaction pointer */ 715 xfs_trans_t *tp; /* transaction pointer */
696 enum xfs_dacmp cmp; /* comparison result */ 716 enum xfs_dacmp cmp; /* comparison result */
717 struct xfs_dir2_leaf_entry *ents;
718 struct xfs_dir3_icleaf_hdr leafhdr;
697 719
698 dp = args->dp; 720 dp = args->dp;
699 tp = args->trans; 721 tp = args->trans;
700 mp = dp->i_mount; 722 mp = dp->i_mount;
701 leaf = bp->b_addr; 723 leaf = bp->b_addr;
702 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); 724 xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
703#ifdef __KERNEL__ 725 ents = xfs_dir3_leaf_ents_p(leaf);
704 ASSERT(be16_to_cpu(leaf->hdr.count) > 0); 726
705#endif 727 xfs_dir3_leaf_check(mp, bp);
706 xfs_dir2_leafn_check(dp, bp); 728 ASSERT(leafhdr.count > 0);
729
707 /* 730 /*
708 * Look up the hash value in the leaf entries. 731 * Look up the hash value in the leaf entries.
709 */ 732 */
@@ -718,9 +741,9 @@ xfs_dir2_leafn_lookup_for_entry(
718 /* 741 /*
719 * Loop over leaf entries with the right hash value. 742 * Loop over leaf entries with the right hash value.
720 */ 743 */
721 for (lep = &leaf->ents[index]; index < be16_to_cpu(leaf->hdr.count) && 744 for (lep = &ents[index];
722 be32_to_cpu(lep->hashval) == args->hashval; 745 index < leafhdr.count && be32_to_cpu(lep->hashval) == args->hashval;
723 lep++, index++) { 746 lep++, index++) {
724 /* 747 /*
725 * Skip stale leaf entries. 748 * Skip stale leaf entries.
726 */ 749 */
@@ -792,8 +815,7 @@ xfs_dir2_leafn_lookup_for_entry(
792 return XFS_ERROR(EEXIST); 815 return XFS_ERROR(EEXIST);
793 } 816 }
794 } 817 }
795 ASSERT(index == be16_to_cpu(leaf->hdr.count) || 818 ASSERT(index == leafhdr.count || (args->op_flags & XFS_DA_OP_OKNOENT));
796 (args->op_flags & XFS_DA_OP_OKNOENT));
797 if (curbp) { 819 if (curbp) {
798 if (args->cmpresult == XFS_CMP_DIFFERENT) { 820 if (args->cmpresult == XFS_CMP_DIFFERENT) {
799 /* Giving back last used data block. */ 821 /* Giving back last used data block. */
@@ -838,52 +860,50 @@ xfs_dir2_leafn_lookup_int(
838 * Log entries and headers. Stale entries are preserved. 860 * Log entries and headers. Stale entries are preserved.
839 */ 861 */
840static void 862static void
841xfs_dir2_leafn_moveents( 863xfs_dir3_leafn_moveents(
842 xfs_da_args_t *args, /* operation arguments */ 864 xfs_da_args_t *args, /* operation arguments */
843 struct xfs_buf *bp_s, /* source leaf buffer */ 865 struct xfs_buf *bp_s, /* source */
844 int start_s, /* source leaf index */ 866 struct xfs_dir3_icleaf_hdr *shdr,
845 struct xfs_buf *bp_d, /* destination leaf buffer */ 867 struct xfs_dir2_leaf_entry *sents,
846 int start_d, /* destination leaf index */ 868 int start_s,/* source leaf index */
847 int count) /* count of leaves to copy */ 869 struct xfs_buf *bp_d, /* destination */
870 struct xfs_dir3_icleaf_hdr *dhdr,
871 struct xfs_dir2_leaf_entry *dents,
872 int start_d,/* destination leaf index */
873 int count) /* count of leaves to copy */
848{ 874{
849 xfs_dir2_leaf_t *leaf_d; /* destination leaf structure */ 875 struct xfs_trans *tp = args->trans;
850 xfs_dir2_leaf_t *leaf_s; /* source leaf structure */ 876 int stale; /* count stale leaves copied */
851 int stale; /* count stale leaves copied */
852 xfs_trans_t *tp; /* transaction pointer */
853 877
854 trace_xfs_dir2_leafn_moveents(args, start_s, start_d, count); 878 trace_xfs_dir2_leafn_moveents(args, start_s, start_d, count);
855 879
856 /* 880 /*
857 * Silently return if nothing to do. 881 * Silently return if nothing to do.
858 */ 882 */
859 if (count == 0) { 883 if (count == 0)
860 return; 884 return;
861 } 885
862 tp = args->trans;
863 leaf_s = bp_s->b_addr;
864 leaf_d = bp_d->b_addr;
865 /* 886 /*
866 * If the destination index is not the end of the current 887 * If the destination index is not the end of the current
867 * destination leaf entries, open up a hole in the destination 888 * destination leaf entries, open up a hole in the destination
868 * to hold the new entries. 889 * to hold the new entries.
869 */ 890 */
870 if (start_d < be16_to_cpu(leaf_d->hdr.count)) { 891 if (start_d < dhdr->count) {
871 memmove(&leaf_d->ents[start_d + count], &leaf_d->ents[start_d], 892 memmove(&dents[start_d + count], &dents[start_d],
872 (be16_to_cpu(leaf_d->hdr.count) - start_d) * 893 (dhdr->count - start_d) * sizeof(xfs_dir2_leaf_entry_t));
873 sizeof(xfs_dir2_leaf_entry_t)); 894 xfs_dir3_leaf_log_ents(tp, bp_d, start_d + count,
874 xfs_dir2_leaf_log_ents(tp, bp_d, start_d + count, 895 count + dhdr->count - 1);
875 count + be16_to_cpu(leaf_d->hdr.count) - 1);
876 } 896 }
877 /* 897 /*
878 * If the source has stale leaves, count the ones in the copy range 898 * If the source has stale leaves, count the ones in the copy range
879 * so we can update the header correctly. 899 * so we can update the header correctly.
880 */ 900 */
881 if (leaf_s->hdr.stale) { 901 if (shdr->stale) {
882 int i; /* temp leaf index */ 902 int i; /* temp leaf index */
883 903
884 for (i = start_s, stale = 0; i < start_s + count; i++) { 904 for (i = start_s, stale = 0; i < start_s + count; i++) {
885 if (leaf_s->ents[i].address == 905 if (sents[i].address ==
886 cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) 906 cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
887 stale++; 907 stale++;
888 } 908 }
889 } else 909 } else
@@ -891,29 +911,27 @@ xfs_dir2_leafn_moveents(
891 /* 911 /*
892 * Copy the leaf entries from source to destination. 912 * Copy the leaf entries from source to destination.
893 */ 913 */
894 memcpy(&leaf_d->ents[start_d], &leaf_s->ents[start_s], 914 memcpy(&dents[start_d], &sents[start_s],
895 count * sizeof(xfs_dir2_leaf_entry_t)); 915 count * sizeof(xfs_dir2_leaf_entry_t));
896 xfs_dir2_leaf_log_ents(tp, bp_d, start_d, start_d + count - 1); 916 xfs_dir3_leaf_log_ents(tp, bp_d, start_d, start_d + count - 1);
917
897 /* 918 /*
898 * If there are source entries after the ones we copied, 919 * If there are source entries after the ones we copied,
899 * delete the ones we copied by sliding the next ones down. 920 * delete the ones we copied by sliding the next ones down.
900 */ 921 */
901 if (start_s + count < be16_to_cpu(leaf_s->hdr.count)) { 922 if (start_s + count < shdr->count) {
902 memmove(&leaf_s->ents[start_s], &leaf_s->ents[start_s + count], 923 memmove(&sents[start_s], &sents[start_s + count],
903 count * sizeof(xfs_dir2_leaf_entry_t)); 924 count * sizeof(xfs_dir2_leaf_entry_t));
904 xfs_dir2_leaf_log_ents(tp, bp_s, start_s, start_s + count - 1); 925 xfs_dir3_leaf_log_ents(tp, bp_s, start_s, start_s + count - 1);
905 } 926 }
927
906 /* 928 /*
907 * Update the headers and log them. 929 * Update the headers and log them.
908 */ 930 */
909 be16_add_cpu(&leaf_s->hdr.count, -(count)); 931 shdr->count -= count;
910 be16_add_cpu(&leaf_s->hdr.stale, -(stale)); 932 shdr->stale -= stale;
911 be16_add_cpu(&leaf_d->hdr.count, count); 933 dhdr->count += count;
912 be16_add_cpu(&leaf_d->hdr.stale, stale); 934 dhdr->stale += stale;
913 xfs_dir2_leaf_log_header(tp, bp_s);
914 xfs_dir2_leaf_log_header(tp, bp_d);
915 xfs_dir2_leafn_check(args->dp, bp_s);
916 xfs_dir2_leafn_check(args->dp, bp_d);
917} 935}
918 936
919/* 937/*
@@ -922,21 +940,25 @@ xfs_dir2_leafn_moveents(
922 */ 940 */
923int /* sort order */ 941int /* sort order */
924xfs_dir2_leafn_order( 942xfs_dir2_leafn_order(
925 struct xfs_buf *leaf1_bp, /* leaf1 buffer */ 943 struct xfs_buf *leaf1_bp, /* leaf1 buffer */
926 struct xfs_buf *leaf2_bp) /* leaf2 buffer */ 944 struct xfs_buf *leaf2_bp) /* leaf2 buffer */
927{ 945{
928 xfs_dir2_leaf_t *leaf1; /* leaf1 structure */ 946 struct xfs_dir2_leaf *leaf1 = leaf1_bp->b_addr;
929 xfs_dir2_leaf_t *leaf2; /* leaf2 structure */ 947 struct xfs_dir2_leaf *leaf2 = leaf2_bp->b_addr;
930 948 struct xfs_dir2_leaf_entry *ents1;
931 leaf1 = leaf1_bp->b_addr; 949 struct xfs_dir2_leaf_entry *ents2;
932 leaf2 = leaf2_bp->b_addr; 950 struct xfs_dir3_icleaf_hdr hdr1;
933 ASSERT(leaf1->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); 951 struct xfs_dir3_icleaf_hdr hdr2;
934 ASSERT(leaf2->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); 952
935 if (be16_to_cpu(leaf1->hdr.count) > 0 && 953 xfs_dir3_leaf_hdr_from_disk(&hdr1, leaf1);
936 be16_to_cpu(leaf2->hdr.count) > 0 && 954 xfs_dir3_leaf_hdr_from_disk(&hdr2, leaf2);
937 (be32_to_cpu(leaf2->ents[0].hashval) < be32_to_cpu(leaf1->ents[0].hashval) || 955 ents1 = xfs_dir3_leaf_ents_p(leaf1);
938 be32_to_cpu(leaf2->ents[be16_to_cpu(leaf2->hdr.count) - 1].hashval) < 956 ents2 = xfs_dir3_leaf_ents_p(leaf2);
939 be32_to_cpu(leaf1->ents[be16_to_cpu(leaf1->hdr.count) - 1].hashval))) 957
958 if (hdr1.count > 0 && hdr2.count > 0 &&
959 (be32_to_cpu(ents2[0].hashval) < be32_to_cpu(ents1[0].hashval) ||
960 be32_to_cpu(ents2[hdr2.count - 1].hashval) <
961 be32_to_cpu(ents1[hdr1.count - 1].hashval)))
940 return 1; 962 return 1;
941 return 0; 963 return 0;
942} 964}
@@ -965,6 +987,10 @@ xfs_dir2_leafn_rebalance(
965#endif 987#endif
966 int oldsum; /* old total leaf count */ 988 int oldsum; /* old total leaf count */
967 int swap; /* swapped leaf blocks */ 989 int swap; /* swapped leaf blocks */
990 struct xfs_dir2_leaf_entry *ents1;
991 struct xfs_dir2_leaf_entry *ents2;
992 struct xfs_dir3_icleaf_hdr hdr1;
993 struct xfs_dir3_icleaf_hdr hdr2;
968 994
969 args = state->args; 995 args = state->args;
970 /* 996 /*
@@ -979,11 +1005,17 @@ xfs_dir2_leafn_rebalance(
979 } 1005 }
980 leaf1 = blk1->bp->b_addr; 1006 leaf1 = blk1->bp->b_addr;
981 leaf2 = blk2->bp->b_addr; 1007 leaf2 = blk2->bp->b_addr;
982 oldsum = be16_to_cpu(leaf1->hdr.count) + be16_to_cpu(leaf2->hdr.count); 1008 xfs_dir3_leaf_hdr_from_disk(&hdr1, leaf1);
1009 xfs_dir3_leaf_hdr_from_disk(&hdr2, leaf2);
1010 ents1 = xfs_dir3_leaf_ents_p(leaf1);
1011 ents2 = xfs_dir3_leaf_ents_p(leaf2);
1012
1013 oldsum = hdr1.count + hdr2.count;
983#ifdef DEBUG 1014#ifdef DEBUG
984 oldstale = be16_to_cpu(leaf1->hdr.stale) + be16_to_cpu(leaf2->hdr.stale); 1015 oldstale = hdr1.stale + hdr2.stale;
985#endif 1016#endif
986 mid = oldsum >> 1; 1017 mid = oldsum >> 1;
1018
987 /* 1019 /*
988 * If the old leaf count was odd then the new one will be even, 1020 * If the old leaf count was odd then the new one will be even,
989 * so we need to divide the new count evenly. 1021 * so we need to divide the new count evenly.
@@ -991,10 +1023,10 @@ xfs_dir2_leafn_rebalance(
991 if (oldsum & 1) { 1023 if (oldsum & 1) {
992 xfs_dahash_t midhash; /* middle entry hash value */ 1024 xfs_dahash_t midhash; /* middle entry hash value */
993 1025
994 if (mid >= be16_to_cpu(leaf1->hdr.count)) 1026 if (mid >= hdr1.count)
995 midhash = be32_to_cpu(leaf2->ents[mid - be16_to_cpu(leaf1->hdr.count)].hashval); 1027 midhash = be32_to_cpu(ents2[mid - hdr1.count].hashval);
996 else 1028 else
997 midhash = be32_to_cpu(leaf1->ents[mid].hashval); 1029 midhash = be32_to_cpu(ents1[mid].hashval);
998 isleft = args->hashval <= midhash; 1030 isleft = args->hashval <= midhash;
999 } 1031 }
1000 /* 1032 /*
@@ -1008,30 +1040,42 @@ xfs_dir2_leafn_rebalance(
1008 * Calculate moved entry count. Positive means left-to-right, 1040 * Calculate moved entry count. Positive means left-to-right,
1009 * negative means right-to-left. Then move the entries. 1041 * negative means right-to-left. Then move the entries.
1010 */ 1042 */
1011 count = be16_to_cpu(leaf1->hdr.count) - mid + (isleft == 0); 1043 count = hdr1.count - mid + (isleft == 0);
1012 if (count > 0) 1044 if (count > 0)
1013 xfs_dir2_leafn_moveents(args, blk1->bp, 1045 xfs_dir3_leafn_moveents(args, blk1->bp, &hdr1, ents1,
1014 be16_to_cpu(leaf1->hdr.count) - count, blk2->bp, 0, count); 1046 hdr1.count - count, blk2->bp,
1047 &hdr2, ents2, 0, count);
1015 else if (count < 0) 1048 else if (count < 0)
1016 xfs_dir2_leafn_moveents(args, blk2->bp, 0, blk1->bp, 1049 xfs_dir3_leafn_moveents(args, blk2->bp, &hdr2, ents2, 0,
1017 be16_to_cpu(leaf1->hdr.count), count); 1050 blk1->bp, &hdr1, ents1,
1018 ASSERT(be16_to_cpu(leaf1->hdr.count) + be16_to_cpu(leaf2->hdr.count) == oldsum); 1051 hdr1.count, count);
1019 ASSERT(be16_to_cpu(leaf1->hdr.stale) + be16_to_cpu(leaf2->hdr.stale) == oldstale); 1052
1053 ASSERT(hdr1.count + hdr2.count == oldsum);
1054 ASSERT(hdr1.stale + hdr2.stale == oldstale);
1055
1056 /* log the changes made when moving the entries */
1057 xfs_dir3_leaf_hdr_to_disk(leaf1, &hdr1);
1058 xfs_dir3_leaf_hdr_to_disk(leaf2, &hdr2);
1059 xfs_dir3_leaf_log_header(args->trans, blk1->bp);
1060 xfs_dir3_leaf_log_header(args->trans, blk2->bp);
1061
1062 xfs_dir3_leaf_check(args->dp->i_mount, blk1->bp);
1063 xfs_dir3_leaf_check(args->dp->i_mount, blk2->bp);
1064
1020 /* 1065 /*
1021 * Mark whether we're inserting into the old or new leaf. 1066 * Mark whether we're inserting into the old or new leaf.
1022 */ 1067 */
1023 if (be16_to_cpu(leaf1->hdr.count) < be16_to_cpu(leaf2->hdr.count)) 1068 if (hdr1.count < hdr2.count)
1024 state->inleaf = swap; 1069 state->inleaf = swap;
1025 else if (be16_to_cpu(leaf1->hdr.count) > be16_to_cpu(leaf2->hdr.count)) 1070 else if (hdr1.count > hdr2.count)
1026 state->inleaf = !swap; 1071 state->inleaf = !swap;
1027 else 1072 else
1028 state->inleaf = 1073 state->inleaf = swap ^ (blk1->index <= hdr1.count);
1029 swap ^ (blk1->index <= be16_to_cpu(leaf1->hdr.count));
1030 /* 1074 /*
1031 * Adjust the expected index for insertion. 1075 * Adjust the expected index for insertion.
1032 */ 1076 */
1033 if (!state->inleaf) 1077 if (!state->inleaf)
1034 blk2->index = blk1->index - be16_to_cpu(leaf1->hdr.count); 1078 blk2->index = blk1->index - hdr1.count;
1035 1079
1036 /* 1080 /*
1037 * Finally sanity check just to make sure we are not returning a 1081 * Finally sanity check just to make sure we are not returning a
@@ -1153,6 +1197,8 @@ xfs_dir2_leafn_remove(
1153 int needscan; /* need to rescan data frees */ 1197 int needscan; /* need to rescan data frees */
1154 xfs_trans_t *tp; /* transaction pointer */ 1198 xfs_trans_t *tp; /* transaction pointer */
1155 struct xfs_dir2_data_free *bf; /* bestfree table */ 1199 struct xfs_dir2_data_free *bf; /* bestfree table */
1200 struct xfs_dir3_icleaf_hdr leafhdr;
1201 struct xfs_dir2_leaf_entry *ents;
1156 1202
1157 trace_xfs_dir2_leafn_remove(args, index); 1203 trace_xfs_dir2_leafn_remove(args, index);
1158 1204
@@ -1160,11 +1206,14 @@ xfs_dir2_leafn_remove(
1160 tp = args->trans; 1206 tp = args->trans;
1161 mp = dp->i_mount; 1207 mp = dp->i_mount;
1162 leaf = bp->b_addr; 1208 leaf = bp->b_addr;
1163 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); 1209 xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
1210 ents = xfs_dir3_leaf_ents_p(leaf);
1211
1164 /* 1212 /*
1165 * Point to the entry we're removing. 1213 * Point to the entry we're removing.
1166 */ 1214 */
1167 lep = &leaf->ents[index]; 1215 lep = &ents[index];
1216
1168 /* 1217 /*
1169 * Extract the data block and offset from the entry. 1218 * Extract the data block and offset from the entry.
1170 */ 1219 */
@@ -1172,14 +1221,18 @@ xfs_dir2_leafn_remove(
1172 ASSERT(dblk->blkno == db); 1221 ASSERT(dblk->blkno == db);
1173 off = xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address)); 1222 off = xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address));
1174 ASSERT(dblk->index == off); 1223 ASSERT(dblk->index == off);
1224
1175 /* 1225 /*
1176 * Kill the leaf entry by marking it stale. 1226 * Kill the leaf entry by marking it stale.
1177 * Log the leaf block changes. 1227 * Log the leaf block changes.
1178 */ 1228 */
1179 be16_add_cpu(&leaf->hdr.stale, 1); 1229 leafhdr.stale++;
1180 xfs_dir2_leaf_log_header(tp, bp); 1230 xfs_dir3_leaf_hdr_to_disk(leaf, &leafhdr);
1231 xfs_dir3_leaf_log_header(tp, bp);
1232
1181 lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR); 1233 lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR);
1182 xfs_dir2_leaf_log_ents(tp, bp, index, index); 1234 xfs_dir3_leaf_log_ents(tp, bp, index, index);
1235
1183 /* 1236 /*
1184 * Make the data entry free. Keep track of the longest freespace 1237 * Make the data entry free. Keep track of the longest freespace
1185 * in the data block in case it changes. 1238 * in the data block in case it changes.
@@ -1267,15 +1320,13 @@ xfs_dir2_leafn_remove(
1267 return error; 1320 return error;
1268 } 1321 }
1269 1322
1270 xfs_dir2_leafn_check(dp, bp); 1323 xfs_dir3_leaf_check(mp, bp);
1271 /* 1324 /*
1272 * Return indication of whether this leaf block is empty enough 1325 * Return indication of whether this leaf block is empty enough
1273 * to justify trying to join it with a neighbor. 1326 * to justify trying to join it with a neighbor.
1274 */ 1327 */
1275 *rval = 1328 *rval = (xfs_dir3_leaf_hdr_size(leaf) +
1276 ((uint)sizeof(leaf->hdr) + 1329 (uint)sizeof(ents[0]) * (leafhdr.count - leafhdr.stale)) <
1277 (uint)sizeof(leaf->ents[0]) *
1278 (be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale))) <
1279 mp->m_dir_magicpct; 1330 mp->m_dir_magicpct;
1280 return 0; 1331 return 0;
1281} 1332}
@@ -1308,11 +1359,11 @@ xfs_dir2_leafn_split(
1308 /* 1359 /*
1309 * Initialize the new leaf block. 1360 * Initialize the new leaf block.
1310 */ 1361 */
1311 error = xfs_dir2_leaf_init(args, xfs_dir2_da_to_db(mp, blkno), 1362 error = xfs_dir3_leaf_get_buf(args, xfs_dir2_da_to_db(mp, blkno),
1312 &newblk->bp, XFS_DIR2_LEAFN_MAGIC); 1363 &newblk->bp, XFS_DIR2_LEAFN_MAGIC);
1313 if (error) { 1364 if (error)
1314 return error; 1365 return error;
1315 } 1366
1316 newblk->blkno = blkno; 1367 newblk->blkno = blkno;
1317 newblk->magic = XFS_DIR2_LEAFN_MAGIC; 1368 newblk->magic = XFS_DIR2_LEAFN_MAGIC;
1318 /* 1369 /*
@@ -1336,8 +1387,8 @@ xfs_dir2_leafn_split(
1336 */ 1387 */
1337 oldblk->hashval = xfs_dir2_leafn_lasthash(oldblk->bp, NULL); 1388 oldblk->hashval = xfs_dir2_leafn_lasthash(oldblk->bp, NULL);
1338 newblk->hashval = xfs_dir2_leafn_lasthash(newblk->bp, NULL); 1389 newblk->hashval = xfs_dir2_leafn_lasthash(newblk->bp, NULL);
1339 xfs_dir2_leafn_check(args->dp, oldblk->bp); 1390 xfs_dir3_leaf_check(mp, oldblk->bp);
1340 xfs_dir2_leafn_check(args->dp, newblk->bp); 1391 xfs_dir3_leaf_check(mp, newblk->bp);
1341 return error; 1392 return error;
1342} 1393}
1343 1394
@@ -1363,9 +1414,10 @@ xfs_dir2_leafn_toosmall(
1363 int error; /* error return value */ 1414 int error; /* error return value */
1364 int forward; /* sibling block direction */ 1415 int forward; /* sibling block direction */
1365 int i; /* sibling counter */ 1416 int i; /* sibling counter */
1366 xfs_da_blkinfo_t *info; /* leaf block header */
1367 xfs_dir2_leaf_t *leaf; /* leaf structure */ 1417 xfs_dir2_leaf_t *leaf; /* leaf structure */
1368 int rval; /* result from path_shift */ 1418 int rval; /* result from path_shift */
1419 struct xfs_dir3_icleaf_hdr leafhdr;
1420 struct xfs_dir2_leaf_entry *ents;
1369 1421
1370 /* 1422 /*
1371 * Check for the degenerate case of the block being over 50% full. 1423 * Check for the degenerate case of the block being over 50% full.
@@ -1373,11 +1425,13 @@ xfs_dir2_leafn_toosmall(
1373 * to coalesce with a sibling. 1425 * to coalesce with a sibling.
1374 */ 1426 */
1375 blk = &state->path.blk[state->path.active - 1]; 1427 blk = &state->path.blk[state->path.active - 1];
1376 info = blk->bp->b_addr; 1428 leaf = blk->bp->b_addr;
1377 ASSERT(info->magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); 1429 xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
1378 leaf = (xfs_dir2_leaf_t *)info; 1430 ents = xfs_dir3_leaf_ents_p(leaf);
1379 count = be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale); 1431 xfs_dir3_leaf_check(state->args->dp->i_mount, blk->bp);
1380 bytes = (uint)sizeof(leaf->hdr) + count * (uint)sizeof(leaf->ents[0]); 1432
1433 count = leafhdr.count - leafhdr.stale;
1434 bytes = xfs_dir3_leaf_hdr_size(leaf) + count * sizeof(ents[0]);
1381 if (bytes > (state->blocksize >> 1)) { 1435 if (bytes > (state->blocksize >> 1)) {
1382 /* 1436 /*
1383 * Blk over 50%, don't try to join. 1437 * Blk over 50%, don't try to join.
@@ -1396,7 +1450,7 @@ xfs_dir2_leafn_toosmall(
1396 * Make altpath point to the block we want to keep and 1450 * Make altpath point to the block we want to keep and
1397 * path point to the block we want to drop (this one). 1451 * path point to the block we want to drop (this one).
1398 */ 1452 */
1399 forward = (info->forw != 0); 1453 forward = (leafhdr.forw != 0);
1400 memcpy(&state->altpath, &state->path, sizeof(state->path)); 1454 memcpy(&state->altpath, &state->path, sizeof(state->path));
1401 error = xfs_da_path_shift(state, &state->altpath, forward, 0, 1455 error = xfs_da_path_shift(state, &state->altpath, forward, 0,
1402 &rval); 1456 &rval);
@@ -1412,15 +1466,17 @@ xfs_dir2_leafn_toosmall(
1412 * We prefer coalescing with the lower numbered sibling so as 1466 * We prefer coalescing with the lower numbered sibling so as
1413 * to shrink a directory over time. 1467 * to shrink a directory over time.
1414 */ 1468 */
1415 forward = be32_to_cpu(info->forw) < be32_to_cpu(info->back); 1469 forward = leafhdr.forw < leafhdr.back;
1416 for (i = 0, bp = NULL; i < 2; forward = !forward, i++) { 1470 for (i = 0, bp = NULL; i < 2; forward = !forward, i++) {
1417 blkno = forward ? be32_to_cpu(info->forw) : be32_to_cpu(info->back); 1471 struct xfs_dir3_icleaf_hdr hdr2;
1472
1473 blkno = forward ? leafhdr.forw : leafhdr.back;
1418 if (blkno == 0) 1474 if (blkno == 0)
1419 continue; 1475 continue;
1420 /* 1476 /*
1421 * Read the sibling leaf block. 1477 * Read the sibling leaf block.
1422 */ 1478 */
1423 error = xfs_dir2_leafn_read(state->args->trans, state->args->dp, 1479 error = xfs_dir3_leafn_read(state->args->trans, state->args->dp,
1424 blkno, -1, &bp); 1480 blkno, -1, &bp);
1425 if (error) 1481 if (error)
1426 return error; 1482 return error;
@@ -1428,13 +1484,15 @@ xfs_dir2_leafn_toosmall(
1428 /* 1484 /*
1429 * Count bytes in the two blocks combined. 1485 * Count bytes in the two blocks combined.
1430 */ 1486 */
1431 leaf = (xfs_dir2_leaf_t *)info; 1487 count = leafhdr.count - leafhdr.stale;
1432 count = be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale);
1433 bytes = state->blocksize - (state->blocksize >> 2); 1488 bytes = state->blocksize - (state->blocksize >> 2);
1489
1434 leaf = bp->b_addr; 1490 leaf = bp->b_addr;
1435 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); 1491 xfs_dir3_leaf_hdr_from_disk(&hdr2, leaf);
1436 count += be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale); 1492 ents = xfs_dir3_leaf_ents_p(leaf);
1437 bytes -= count * (uint)sizeof(leaf->ents[0]); 1493 count += hdr2.count - hdr2.stale;
1494 bytes -= count * sizeof(ents[0]);
1495
1438 /* 1496 /*
1439 * Fits with at least 25% to spare. 1497 * Fits with at least 25% to spare.
1440 */ 1498 */
@@ -1481,34 +1539,53 @@ xfs_dir2_leafn_unbalance(
1481 xfs_da_args_t *args; /* operation arguments */ 1539 xfs_da_args_t *args; /* operation arguments */
1482 xfs_dir2_leaf_t *drop_leaf; /* dead leaf structure */ 1540 xfs_dir2_leaf_t *drop_leaf; /* dead leaf structure */
1483 xfs_dir2_leaf_t *save_leaf; /* surviving leaf structure */ 1541 xfs_dir2_leaf_t *save_leaf; /* surviving leaf structure */
1542 struct xfs_dir3_icleaf_hdr savehdr;
1543 struct xfs_dir3_icleaf_hdr drophdr;
1544 struct xfs_dir2_leaf_entry *sents;
1545 struct xfs_dir2_leaf_entry *dents;
1484 1546
1485 args = state->args; 1547 args = state->args;
1486 ASSERT(drop_blk->magic == XFS_DIR2_LEAFN_MAGIC); 1548 ASSERT(drop_blk->magic == XFS_DIR2_LEAFN_MAGIC);
1487 ASSERT(save_blk->magic == XFS_DIR2_LEAFN_MAGIC); 1549 ASSERT(save_blk->magic == XFS_DIR2_LEAFN_MAGIC);
1488 drop_leaf = drop_blk->bp->b_addr; 1550 drop_leaf = drop_blk->bp->b_addr;
1489 save_leaf = save_blk->bp->b_addr; 1551 save_leaf = save_blk->bp->b_addr;
1490 ASSERT(drop_leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); 1552
1491 ASSERT(save_leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); 1553 xfs_dir3_leaf_hdr_from_disk(&savehdr, save_leaf);
1554 xfs_dir3_leaf_hdr_from_disk(&drophdr, drop_leaf);
1555 sents = xfs_dir3_leaf_ents_p(save_leaf);
1556 dents = xfs_dir3_leaf_ents_p(drop_leaf);
1557
1492 /* 1558 /*
1493 * If there are any stale leaf entries, take this opportunity 1559 * If there are any stale leaf entries, take this opportunity
1494 * to purge them. 1560 * to purge them.
1495 */ 1561 */
1496 if (drop_leaf->hdr.stale) 1562 if (drophdr.stale)
1497 xfs_dir2_leaf_compact(args, drop_blk->bp); 1563 xfs_dir3_leaf_compact(args, &drophdr, drop_blk->bp);
1498 if (save_leaf->hdr.stale) 1564 if (savehdr.stale)
1499 xfs_dir2_leaf_compact(args, save_blk->bp); 1565 xfs_dir3_leaf_compact(args, &savehdr, save_blk->bp);
1566
1500 /* 1567 /*
1501 * Move the entries from drop to the appropriate end of save. 1568 * Move the entries from drop to the appropriate end of save.
1502 */ 1569 */
1503 drop_blk->hashval = be32_to_cpu(drop_leaf->ents[be16_to_cpu(drop_leaf->hdr.count) - 1].hashval); 1570 drop_blk->hashval = be32_to_cpu(dents[drophdr.count - 1].hashval);
1504 if (xfs_dir2_leafn_order(save_blk->bp, drop_blk->bp)) 1571 if (xfs_dir2_leafn_order(save_blk->bp, drop_blk->bp))
1505 xfs_dir2_leafn_moveents(args, drop_blk->bp, 0, save_blk->bp, 0, 1572 xfs_dir3_leafn_moveents(args, drop_blk->bp, &drophdr, dents, 0,
1506 be16_to_cpu(drop_leaf->hdr.count)); 1573 save_blk->bp, &savehdr, sents, 0,
1574 drophdr.count);
1507 else 1575 else
1508 xfs_dir2_leafn_moveents(args, drop_blk->bp, 0, save_blk->bp, 1576 xfs_dir3_leafn_moveents(args, drop_blk->bp, &drophdr, dents, 0,
1509 be16_to_cpu(save_leaf->hdr.count), be16_to_cpu(drop_leaf->hdr.count)); 1577 save_blk->bp, &savehdr, sents,
1510 save_blk->hashval = be32_to_cpu(save_leaf->ents[be16_to_cpu(save_leaf->hdr.count) - 1].hashval); 1578 savehdr.count, drophdr.count);
1511 xfs_dir2_leafn_check(args->dp, save_blk->bp); 1579 save_blk->hashval = be32_to_cpu(sents[savehdr.count - 1].hashval);
1580
1581 /* log the changes made when moving the entries */
1582 xfs_dir3_leaf_hdr_to_disk(save_leaf, &savehdr);
1583 xfs_dir3_leaf_hdr_to_disk(drop_leaf, &drophdr);
1584 xfs_dir3_leaf_log_header(args->trans, save_blk->bp);
1585 xfs_dir3_leaf_log_header(args->trans, drop_blk->bp);
1586
1587 xfs_dir3_leaf_check(args->dp->i_mount, save_blk->bp);
1588 xfs_dir3_leaf_check(args->dp->i_mount, drop_blk->bp);
1512} 1589}
1513 1590
1514/* 1591/*
@@ -2113,13 +2190,15 @@ xfs_dir2_node_replace(
2113 * and locked it. But paranoia is good. 2190 * and locked it. But paranoia is good.
2114 */ 2191 */
2115 if (rval == EEXIST) { 2192 if (rval == EEXIST) {
2193 struct xfs_dir2_leaf_entry *ents;
2116 /* 2194 /*
2117 * Find the leaf entry. 2195 * Find the leaf entry.
2118 */ 2196 */
2119 blk = &state->path.blk[state->path.active - 1]; 2197 blk = &state->path.blk[state->path.active - 1];
2120 ASSERT(blk->magic == XFS_DIR2_LEAFN_MAGIC); 2198 ASSERT(blk->magic == XFS_DIR2_LEAFN_MAGIC);
2121 leaf = blk->bp->b_addr; 2199 leaf = blk->bp->b_addr;
2122 lep = &leaf->ents[blk->index]; 2200 ents = xfs_dir3_leaf_ents_p(leaf);
2201 lep = &ents[blk->index];
2123 ASSERT(state->extravalid); 2202 ASSERT(state->extravalid);
2124 /* 2203 /*
2125 * Point to the data entry. 2204 * Point to the data entry.
diff --git a/fs/xfs/xfs_dir2_priv.h b/fs/xfs/xfs_dir2_priv.h
index 910e64413316..932565d6ef2a 100644
--- a/fs/xfs/xfs_dir2_priv.h
+++ b/fs/xfs/xfs_dir2_priv.h
@@ -77,24 +77,25 @@ extern void xfs_dir2_data_use_free(struct xfs_trans *tp, struct xfs_buf *bp,
77 xfs_dir2_data_aoff_t len, int *needlogp, int *needscanp); 77 xfs_dir2_data_aoff_t len, int *needlogp, int *needscanp);
78 78
79/* xfs_dir2_leaf.c */ 79/* xfs_dir2_leaf.c */
80extern const struct xfs_buf_ops xfs_dir2_leafn_buf_ops; 80extern const struct xfs_buf_ops xfs_dir3_leafn_buf_ops;
81 81
82extern int xfs_dir2_leafn_read(struct xfs_trans *tp, struct xfs_inode *dp, 82extern int xfs_dir3_leafn_read(struct xfs_trans *tp, struct xfs_inode *dp,
83 xfs_dablk_t fbno, xfs_daddr_t mappedbno, struct xfs_buf **bpp); 83 xfs_dablk_t fbno, xfs_daddr_t mappedbno, struct xfs_buf **bpp);
84extern int xfs_dir2_block_to_leaf(struct xfs_da_args *args, 84extern int xfs_dir2_block_to_leaf(struct xfs_da_args *args,
85 struct xfs_buf *dbp); 85 struct xfs_buf *dbp);
86extern int xfs_dir2_leaf_addname(struct xfs_da_args *args); 86extern int xfs_dir2_leaf_addname(struct xfs_da_args *args);
87extern void xfs_dir2_leaf_compact(struct xfs_da_args *args, 87extern void xfs_dir3_leaf_compact(struct xfs_da_args *args,
88 struct xfs_buf *bp); 88 struct xfs_dir3_icleaf_hdr *leafhdr, struct xfs_buf *bp);
89extern void xfs_dir2_leaf_compact_x1(struct xfs_buf *bp, int *indexp, 89extern void xfs_dir3_leaf_compact_x1(struct xfs_dir3_icleaf_hdr *leafhdr,
90 struct xfs_dir2_leaf_entry *ents, int *indexp,
90 int *lowstalep, int *highstalep, int *lowlogp, int *highlogp); 91 int *lowstalep, int *highstalep, int *lowlogp, int *highlogp);
91extern int xfs_dir2_leaf_getdents(struct xfs_inode *dp, void *dirent, 92extern int xfs_dir2_leaf_getdents(struct xfs_inode *dp, void *dirent,
92 size_t bufsize, xfs_off_t *offset, filldir_t filldir); 93 size_t bufsize, xfs_off_t *offset, filldir_t filldir);
93extern int xfs_dir2_leaf_init(struct xfs_da_args *args, xfs_dir2_db_t bno, 94extern int xfs_dir3_leaf_get_buf(struct xfs_da_args *args, xfs_dir2_db_t bno,
94 struct xfs_buf **bpp, int magic); 95 struct xfs_buf **bpp, __uint16_t magic);
95extern void xfs_dir2_leaf_log_ents(struct xfs_trans *tp, struct xfs_buf *bp, 96extern void xfs_dir3_leaf_log_ents(struct xfs_trans *tp, struct xfs_buf *bp,
96 int first, int last); 97 int first, int last);
97extern void xfs_dir2_leaf_log_header(struct xfs_trans *tp, 98extern void xfs_dir3_leaf_log_header(struct xfs_trans *tp,
98 struct xfs_buf *bp); 99 struct xfs_buf *bp);
99extern int xfs_dir2_leaf_lookup(struct xfs_da_args *args); 100extern int xfs_dir2_leaf_lookup(struct xfs_da_args *args);
100extern int xfs_dir2_leaf_removename(struct xfs_da_args *args); 101extern int xfs_dir2_leaf_removename(struct xfs_da_args *args);
@@ -104,11 +105,18 @@ extern int xfs_dir2_leaf_search_hash(struct xfs_da_args *args,
104extern int xfs_dir2_leaf_trim_data(struct xfs_da_args *args, 105extern int xfs_dir2_leaf_trim_data(struct xfs_da_args *args,
105 struct xfs_buf *lbp, xfs_dir2_db_t db); 106 struct xfs_buf *lbp, xfs_dir2_db_t db);
106extern struct xfs_dir2_leaf_entry * 107extern struct xfs_dir2_leaf_entry *
107xfs_dir2_leaf_find_entry(struct xfs_dir2_leaf *leaf, int index, int compact, 108xfs_dir3_leaf_find_entry(struct xfs_dir3_icleaf_hdr *leafhdr,
108 int lowstale, int highstale, 109 struct xfs_dir2_leaf_entry *ents, int index, int compact,
109 int *lfloglow, int *lfloghigh); 110 int lowstale, int highstale, int *lfloglow, int *lfloghigh);
110extern int xfs_dir2_node_to_leaf(struct xfs_da_state *state); 111extern int xfs_dir2_node_to_leaf(struct xfs_da_state *state);
111 112
113extern void xfs_dir3_leaf_hdr_from_disk(struct xfs_dir3_icleaf_hdr *to,
114 struct xfs_dir2_leaf *from);
115extern void xfs_dir3_leaf_hdr_to_disk(struct xfs_dir2_leaf *to,
116 struct xfs_dir3_icleaf_hdr *from);
117extern bool xfs_dir3_leaf_check_int(struct xfs_mount *mp,
118 struct xfs_dir3_icleaf_hdr *hdr, struct xfs_dir2_leaf *leaf);
119
112/* xfs_dir2_node.c */ 120/* xfs_dir2_node.c */
113extern int xfs_dir2_leaf_to_node(struct xfs_da_args *args, 121extern int xfs_dir2_leaf_to_node(struct xfs_da_args *args,
114 struct xfs_buf *lbp); 122 struct xfs_buf *lbp);