aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_dir2_node.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_dir2_node.c')
-rw-r--r--fs/xfs/xfs_dir2_node.c475
1 files changed, 277 insertions, 198 deletions
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.