aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2013-04-11 17:30:21 -0400
committerBen Myers <bpm@sgi.com>2013-04-27 13:19:53 -0400
commit24df33b45ecf5ca413ef1530e0aca5506d9be2cc (patch)
treec4f3ca2bfdd25b09706ad3d4ccd4f45fff6710a9 /fs
parent33363feed1614def83d0a6870051f0a7828cd61b (diff)
xfs: add CRC checking to dir2 leaf blocks
This addition follows the same pattern as the dir2 block CRCs. Seeing as both LEAF1 and LEAFN types need to changed at the same time, this is a pretty large amount of change. leaf block headers need to be abstracted away from the on-disk structures (struct xfs_dir3_icleaf_hdr), as do the base leaf entry locations. This header abstract allows the in-core header and leaf entry location to be passed around instead of the leaf block itself. This saves a lot of converting individual variables from on-disk format to host format where they are used, so there's a good chance that the compiler will be able to produce much more optimal code as it's not having to byteswap variables all over the place. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Ben Myers <bpm@sgi.com> Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs')
-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);