aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_bmap.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /fs/xfs/xfs_bmap.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'fs/xfs/xfs_bmap.c')
-rw-r--r--fs/xfs/xfs_bmap.c749
1 files changed, 417 insertions, 332 deletions
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index f90dadd5a968..e546a33214c9 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -89,36 +89,19 @@ xfs_bmap_add_attrfork_local(
89 int *flags); /* inode logging flags */ 89 int *flags); /* inode logging flags */
90 90
91/* 91/*
92 * Called by xfs_bmapi to update file extent records and the btree
93 * after allocating space (or doing a delayed allocation).
94 */
95STATIC int /* error */
96xfs_bmap_add_extent(
97 xfs_inode_t *ip, /* incore inode pointer */
98 xfs_extnum_t idx, /* extent number to update/insert */
99 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
100 xfs_bmbt_irec_t *new, /* new data to add to file extents */
101 xfs_fsblock_t *first, /* pointer to firstblock variable */
102 xfs_bmap_free_t *flist, /* list of extents to be freed */
103 int *logflagsp, /* inode logging flags */
104 int whichfork, /* data or attr fork */
105 int rsvd); /* OK to allocate reserved blocks */
106
107/*
108 * Called by xfs_bmap_add_extent to handle cases converting a delayed 92 * Called by xfs_bmap_add_extent to handle cases converting a delayed
109 * allocation to a real allocation. 93 * allocation to a real allocation.
110 */ 94 */
111STATIC int /* error */ 95STATIC int /* error */
112xfs_bmap_add_extent_delay_real( 96xfs_bmap_add_extent_delay_real(
113 xfs_inode_t *ip, /* incore inode pointer */ 97 xfs_inode_t *ip, /* incore inode pointer */
114 xfs_extnum_t idx, /* extent number to update/insert */ 98 xfs_extnum_t *idx, /* extent number to update/insert */
115 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ 99 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
116 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 100 xfs_bmbt_irec_t *new, /* new data to add to file extents */
117 xfs_filblks_t *dnew, /* new delayed-alloc indirect blocks */ 101 xfs_filblks_t *dnew, /* new delayed-alloc indirect blocks */
118 xfs_fsblock_t *first, /* pointer to firstblock variable */ 102 xfs_fsblock_t *first, /* pointer to firstblock variable */
119 xfs_bmap_free_t *flist, /* list of extents to be freed */ 103 xfs_bmap_free_t *flist, /* list of extents to be freed */
120 int *logflagsp, /* inode logging flags */ 104 int *logflagsp); /* inode logging flags */
121 int rsvd); /* OK to allocate reserved blocks */
122 105
123/* 106/*
124 * Called by xfs_bmap_add_extent to handle cases converting a hole 107 * Called by xfs_bmap_add_extent to handle cases converting a hole
@@ -127,10 +110,9 @@ xfs_bmap_add_extent_delay_real(
127STATIC int /* error */ 110STATIC int /* error */
128xfs_bmap_add_extent_hole_delay( 111xfs_bmap_add_extent_hole_delay(
129 xfs_inode_t *ip, /* incore inode pointer */ 112 xfs_inode_t *ip, /* incore inode pointer */
130 xfs_extnum_t idx, /* extent number to update/insert */ 113 xfs_extnum_t *idx, /* extent number to update/insert */
131 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 114 xfs_bmbt_irec_t *new, /* new data to add to file extents */
132 int *logflagsp,/* inode logging flags */ 115 int *logflagsp); /* inode logging flags */
133 int rsvd); /* OK to allocate reserved blocks */
134 116
135/* 117/*
136 * Called by xfs_bmap_add_extent to handle cases converting a hole 118 * Called by xfs_bmap_add_extent to handle cases converting a hole
@@ -139,7 +121,7 @@ xfs_bmap_add_extent_hole_delay(
139STATIC int /* error */ 121STATIC int /* error */
140xfs_bmap_add_extent_hole_real( 122xfs_bmap_add_extent_hole_real(
141 xfs_inode_t *ip, /* incore inode pointer */ 123 xfs_inode_t *ip, /* incore inode pointer */
142 xfs_extnum_t idx, /* extent number to update/insert */ 124 xfs_extnum_t *idx, /* extent number to update/insert */
143 xfs_btree_cur_t *cur, /* if null, not a btree */ 125 xfs_btree_cur_t *cur, /* if null, not a btree */
144 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 126 xfs_bmbt_irec_t *new, /* new data to add to file extents */
145 int *logflagsp, /* inode logging flags */ 127 int *logflagsp, /* inode logging flags */
@@ -152,7 +134,7 @@ xfs_bmap_add_extent_hole_real(
152STATIC int /* error */ 134STATIC int /* error */
153xfs_bmap_add_extent_unwritten_real( 135xfs_bmap_add_extent_unwritten_real(
154 xfs_inode_t *ip, /* incore inode pointer */ 136 xfs_inode_t *ip, /* incore inode pointer */
155 xfs_extnum_t idx, /* extent number to update/insert */ 137 xfs_extnum_t *idx, /* extent number to update/insert */
156 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ 138 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
157 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 139 xfs_bmbt_irec_t *new, /* new data to add to file extents */
158 int *logflagsp); /* inode logging flags */ 140 int *logflagsp); /* inode logging flags */
@@ -180,22 +162,6 @@ xfs_bmap_btree_to_extents(
180 int whichfork); /* data or attr fork */ 162 int whichfork); /* data or attr fork */
181 163
182/* 164/*
183 * Called by xfs_bmapi to update file extent records and the btree
184 * after removing space (or undoing a delayed allocation).
185 */
186STATIC int /* error */
187xfs_bmap_del_extent(
188 xfs_inode_t *ip, /* incore inode pointer */
189 xfs_trans_t *tp, /* current trans pointer */
190 xfs_extnum_t idx, /* extent number to update/insert */
191 xfs_bmap_free_t *flist, /* list of extents to be freed */
192 xfs_btree_cur_t *cur, /* if null, not a btree */
193 xfs_bmbt_irec_t *new, /* new data to add to file extents */
194 int *logflagsp,/* inode logging flags */
195 int whichfork, /* data or attr fork */
196 int rsvd); /* OK to allocate reserved blocks */
197
198/*
199 * Remove the entry "free" from the free item list. Prev points to the 165 * Remove the entry "free" from the free item list. Prev points to the
200 * previous entry, unless "free" is the head of the list. 166 * previous entry, unless "free" is the head of the list.
201 */ 167 */
@@ -474,14 +440,13 @@ xfs_bmap_add_attrfork_local(
474STATIC int /* error */ 440STATIC int /* error */
475xfs_bmap_add_extent( 441xfs_bmap_add_extent(
476 xfs_inode_t *ip, /* incore inode pointer */ 442 xfs_inode_t *ip, /* incore inode pointer */
477 xfs_extnum_t idx, /* extent number to update/insert */ 443 xfs_extnum_t *idx, /* extent number to update/insert */
478 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ 444 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
479 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 445 xfs_bmbt_irec_t *new, /* new data to add to file extents */
480 xfs_fsblock_t *first, /* pointer to firstblock variable */ 446 xfs_fsblock_t *first, /* pointer to firstblock variable */
481 xfs_bmap_free_t *flist, /* list of extents to be freed */ 447 xfs_bmap_free_t *flist, /* list of extents to be freed */
482 int *logflagsp, /* inode logging flags */ 448 int *logflagsp, /* inode logging flags */
483 int whichfork, /* data or attr fork */ 449 int whichfork) /* data or attr fork */
484 int rsvd) /* OK to use reserved data blocks */
485{ 450{
486 xfs_btree_cur_t *cur; /* btree cursor or null */ 451 xfs_btree_cur_t *cur; /* btree cursor or null */
487 xfs_filblks_t da_new; /* new count del alloc blocks used */ 452 xfs_filblks_t da_new; /* new count del alloc blocks used */
@@ -492,23 +457,27 @@ xfs_bmap_add_extent(
492 xfs_extnum_t nextents; /* number of extents in file now */ 457 xfs_extnum_t nextents; /* number of extents in file now */
493 458
494 XFS_STATS_INC(xs_add_exlist); 459 XFS_STATS_INC(xs_add_exlist);
460
495 cur = *curp; 461 cur = *curp;
496 ifp = XFS_IFORK_PTR(ip, whichfork); 462 ifp = XFS_IFORK_PTR(ip, whichfork);
497 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 463 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
498 ASSERT(idx <= nextents);
499 da_old = da_new = 0; 464 da_old = da_new = 0;
500 error = 0; 465 error = 0;
466
467 ASSERT(*idx >= 0);
468 ASSERT(*idx <= nextents);
469
501 /* 470 /*
502 * This is the first extent added to a new/empty file. 471 * This is the first extent added to a new/empty file.
503 * Special case this one, so other routines get to assume there are 472 * Special case this one, so other routines get to assume there are
504 * already extents in the list. 473 * already extents in the list.
505 */ 474 */
506 if (nextents == 0) { 475 if (nextents == 0) {
507 xfs_iext_insert(ip, 0, 1, new, 476 xfs_iext_insert(ip, *idx, 1, new,
508 whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0); 477 whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0);
509 478
510 ASSERT(cur == NULL); 479 ASSERT(cur == NULL);
511 ifp->if_lastex = 0; 480
512 if (!isnullstartblock(new->br_startblock)) { 481 if (!isnullstartblock(new->br_startblock)) {
513 XFS_IFORK_NEXT_SET(ip, whichfork, 1); 482 XFS_IFORK_NEXT_SET(ip, whichfork, 1);
514 logflags = XFS_ILOG_CORE | xfs_ilog_fext(whichfork); 483 logflags = XFS_ILOG_CORE | xfs_ilog_fext(whichfork);
@@ -522,27 +491,25 @@ xfs_bmap_add_extent(
522 if (cur) 491 if (cur)
523 ASSERT((cur->bc_private.b.flags & 492 ASSERT((cur->bc_private.b.flags &
524 XFS_BTCUR_BPRV_WASDEL) == 0); 493 XFS_BTCUR_BPRV_WASDEL) == 0);
525 if ((error = xfs_bmap_add_extent_hole_delay(ip, idx, new, 494 error = xfs_bmap_add_extent_hole_delay(ip, idx, new,
526 &logflags, rsvd))) 495 &logflags);
527 goto done;
528 } 496 }
529 /* 497 /*
530 * Real allocation off the end of the file. 498 * Real allocation off the end of the file.
531 */ 499 */
532 else if (idx == nextents) { 500 else if (*idx == nextents) {
533 if (cur) 501 if (cur)
534 ASSERT((cur->bc_private.b.flags & 502 ASSERT((cur->bc_private.b.flags &
535 XFS_BTCUR_BPRV_WASDEL) == 0); 503 XFS_BTCUR_BPRV_WASDEL) == 0);
536 if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, new, 504 error = xfs_bmap_add_extent_hole_real(ip, idx, cur, new,
537 &logflags, whichfork))) 505 &logflags, whichfork);
538 goto done;
539 } else { 506 } else {
540 xfs_bmbt_irec_t prev; /* old extent at offset idx */ 507 xfs_bmbt_irec_t prev; /* old extent at offset idx */
541 508
542 /* 509 /*
543 * Get the record referred to by idx. 510 * Get the record referred to by idx.
544 */ 511 */
545 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx), &prev); 512 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx), &prev);
546 /* 513 /*
547 * If it's a real allocation record, and the new allocation ends 514 * If it's a real allocation record, and the new allocation ends
548 * after the start of the referred to record, then we're filling 515 * after the start of the referred to record, then we're filling
@@ -557,22 +524,18 @@ xfs_bmap_add_extent(
557 if (cur) 524 if (cur)
558 ASSERT(cur->bc_private.b.flags & 525 ASSERT(cur->bc_private.b.flags &
559 XFS_BTCUR_BPRV_WASDEL); 526 XFS_BTCUR_BPRV_WASDEL);
560 if ((error = xfs_bmap_add_extent_delay_real(ip, 527 error = xfs_bmap_add_extent_delay_real(ip,
561 idx, &cur, new, &da_new, first, flist, 528 idx, &cur, new, &da_new,
562 &logflags, rsvd))) 529 first, flist, &logflags);
563 goto done;
564 } else if (new->br_state == XFS_EXT_NORM) {
565 ASSERT(new->br_state == XFS_EXT_NORM);
566 if ((error = xfs_bmap_add_extent_unwritten_real(
567 ip, idx, &cur, new, &logflags)))
568 goto done;
569 } else { 530 } else {
570 ASSERT(new->br_state == XFS_EXT_UNWRITTEN); 531 ASSERT(new->br_state == XFS_EXT_NORM ||
571 if ((error = xfs_bmap_add_extent_unwritten_real( 532 new->br_state == XFS_EXT_UNWRITTEN);
572 ip, idx, &cur, new, &logflags))) 533
534 error = xfs_bmap_add_extent_unwritten_real(ip,
535 idx, &cur, new, &logflags);
536 if (error)
573 goto done; 537 goto done;
574 } 538 }
575 ASSERT(*curp == cur || *curp == NULL);
576 } 539 }
577 /* 540 /*
578 * Otherwise we're filling in a hole with an allocation. 541 * Otherwise we're filling in a hole with an allocation.
@@ -581,13 +544,15 @@ xfs_bmap_add_extent(
581 if (cur) 544 if (cur)
582 ASSERT((cur->bc_private.b.flags & 545 ASSERT((cur->bc_private.b.flags &
583 XFS_BTCUR_BPRV_WASDEL) == 0); 546 XFS_BTCUR_BPRV_WASDEL) == 0);
584 if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, 547 error = xfs_bmap_add_extent_hole_real(ip, idx, cur,
585 new, &logflags, whichfork))) 548 new, &logflags, whichfork);
586 goto done;
587 } 549 }
588 } 550 }
589 551
552 if (error)
553 goto done;
590 ASSERT(*curp == cur || *curp == NULL); 554 ASSERT(*curp == cur || *curp == NULL);
555
591 /* 556 /*
592 * Convert to a btree if necessary. 557 * Convert to a btree if necessary.
593 */ 558 */
@@ -614,8 +579,8 @@ xfs_bmap_add_extent(
614 nblks += cur->bc_private.b.allocated; 579 nblks += cur->bc_private.b.allocated;
615 ASSERT(nblks <= da_old); 580 ASSERT(nblks <= da_old);
616 if (nblks < da_old) 581 if (nblks < da_old)
617 xfs_mod_incore_sb(ip->i_mount, XFS_SBS_FDBLOCKS, 582 xfs_icsb_modify_counters(ip->i_mount, XFS_SBS_FDBLOCKS,
618 (int64_t)(da_old - nblks), rsvd); 583 (int64_t)(da_old - nblks), 0);
619 } 584 }
620 /* 585 /*
621 * Clear out the allocated field, done with it now in any case. 586 * Clear out the allocated field, done with it now in any case.
@@ -640,14 +605,13 @@ done:
640STATIC int /* error */ 605STATIC int /* error */
641xfs_bmap_add_extent_delay_real( 606xfs_bmap_add_extent_delay_real(
642 xfs_inode_t *ip, /* incore inode pointer */ 607 xfs_inode_t *ip, /* incore inode pointer */
643 xfs_extnum_t idx, /* extent number to update/insert */ 608 xfs_extnum_t *idx, /* extent number to update/insert */
644 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ 609 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
645 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 610 xfs_bmbt_irec_t *new, /* new data to add to file extents */
646 xfs_filblks_t *dnew, /* new delayed-alloc indirect blocks */ 611 xfs_filblks_t *dnew, /* new delayed-alloc indirect blocks */
647 xfs_fsblock_t *first, /* pointer to firstblock variable */ 612 xfs_fsblock_t *first, /* pointer to firstblock variable */
648 xfs_bmap_free_t *flist, /* list of extents to be freed */ 613 xfs_bmap_free_t *flist, /* list of extents to be freed */
649 int *logflagsp, /* inode logging flags */ 614 int *logflagsp) /* inode logging flags */
650 int rsvd) /* OK to use reserved data block allocation */
651{ 615{
652 xfs_btree_cur_t *cur; /* btree cursor */ 616 xfs_btree_cur_t *cur; /* btree cursor */
653 int diff; /* temp value */ 617 int diff; /* temp value */
@@ -673,7 +637,7 @@ xfs_bmap_add_extent_delay_real(
673 */ 637 */
674 cur = *curp; 638 cur = *curp;
675 ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); 639 ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
676 ep = xfs_iext_get_ext(ifp, idx); 640 ep = xfs_iext_get_ext(ifp, *idx);
677 xfs_bmbt_get_all(ep, &PREV); 641 xfs_bmbt_get_all(ep, &PREV);
678 new_endoff = new->br_startoff + new->br_blockcount; 642 new_endoff = new->br_startoff + new->br_blockcount;
679 ASSERT(PREV.br_startoff <= new->br_startoff); 643 ASSERT(PREV.br_startoff <= new->br_startoff);
@@ -692,9 +656,9 @@ xfs_bmap_add_extent_delay_real(
692 * Check and set flags if this segment has a left neighbor. 656 * Check and set flags if this segment has a left neighbor.
693 * Don't set contiguous if the combined extent would be too large. 657 * Don't set contiguous if the combined extent would be too large.
694 */ 658 */
695 if (idx > 0) { 659 if (*idx > 0) {
696 state |= BMAP_LEFT_VALID; 660 state |= BMAP_LEFT_VALID;
697 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &LEFT); 661 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx - 1), &LEFT);
698 662
699 if (isnullstartblock(LEFT.br_startblock)) 663 if (isnullstartblock(LEFT.br_startblock))
700 state |= BMAP_LEFT_DELAY; 664 state |= BMAP_LEFT_DELAY;
@@ -712,9 +676,9 @@ xfs_bmap_add_extent_delay_real(
712 * Don't set contiguous if the combined extent would be too large. 676 * Don't set contiguous if the combined extent would be too large.
713 * Also check for all-three-contiguous being too large. 677 * Also check for all-three-contiguous being too large.
714 */ 678 */
715 if (idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1) { 679 if (*idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1) {
716 state |= BMAP_RIGHT_VALID; 680 state |= BMAP_RIGHT_VALID;
717 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx + 1), &RIGHT); 681 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx + 1), &RIGHT);
718 682
719 if (isnullstartblock(RIGHT.br_startblock)) 683 if (isnullstartblock(RIGHT.br_startblock))
720 state |= BMAP_RIGHT_DELAY; 684 state |= BMAP_RIGHT_DELAY;
@@ -745,14 +709,14 @@ xfs_bmap_add_extent_delay_real(
745 * Filling in all of a previously delayed allocation extent. 709 * Filling in all of a previously delayed allocation extent.
746 * The left and right neighbors are both contiguous with new. 710 * The left and right neighbors are both contiguous with new.
747 */ 711 */
748 trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); 712 --*idx;
749 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), 713 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
714 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx),
750 LEFT.br_blockcount + PREV.br_blockcount + 715 LEFT.br_blockcount + PREV.br_blockcount +
751 RIGHT.br_blockcount); 716 RIGHT.br_blockcount);
752 trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); 717 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
753 718
754 xfs_iext_remove(ip, idx, 2, state); 719 xfs_iext_remove(ip, *idx + 1, 2, state);
755 ip->i_df.if_lastex = idx - 1;
756 ip->i_d.di_nextents--; 720 ip->i_d.di_nextents--;
757 if (cur == NULL) 721 if (cur == NULL)
758 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 722 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
@@ -784,13 +748,14 @@ xfs_bmap_add_extent_delay_real(
784 * Filling in all of a previously delayed allocation extent. 748 * Filling in all of a previously delayed allocation extent.
785 * The left neighbor is contiguous, the right is not. 749 * The left neighbor is contiguous, the right is not.
786 */ 750 */
787 trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); 751 --*idx;
788 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), 752
753 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
754 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx),
789 LEFT.br_blockcount + PREV.br_blockcount); 755 LEFT.br_blockcount + PREV.br_blockcount);
790 trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); 756 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
791 757
792 ip->i_df.if_lastex = idx - 1; 758 xfs_iext_remove(ip, *idx + 1, 1, state);
793 xfs_iext_remove(ip, idx, 1, state);
794 if (cur == NULL) 759 if (cur == NULL)
795 rval = XFS_ILOG_DEXT; 760 rval = XFS_ILOG_DEXT;
796 else { 761 else {
@@ -814,14 +779,13 @@ xfs_bmap_add_extent_delay_real(
814 * Filling in all of a previously delayed allocation extent. 779 * Filling in all of a previously delayed allocation extent.
815 * The right neighbor is contiguous, the left is not. 780 * The right neighbor is contiguous, the left is not.
816 */ 781 */
817 trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); 782 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
818 xfs_bmbt_set_startblock(ep, new->br_startblock); 783 xfs_bmbt_set_startblock(ep, new->br_startblock);
819 xfs_bmbt_set_blockcount(ep, 784 xfs_bmbt_set_blockcount(ep,
820 PREV.br_blockcount + RIGHT.br_blockcount); 785 PREV.br_blockcount + RIGHT.br_blockcount);
821 trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 786 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
822 787
823 ip->i_df.if_lastex = idx; 788 xfs_iext_remove(ip, *idx + 1, 1, state);
824 xfs_iext_remove(ip, idx + 1, 1, state);
825 if (cur == NULL) 789 if (cur == NULL)
826 rval = XFS_ILOG_DEXT; 790 rval = XFS_ILOG_DEXT;
827 else { 791 else {
@@ -837,6 +801,7 @@ xfs_bmap_add_extent_delay_real(
837 RIGHT.br_blockcount, PREV.br_state))) 801 RIGHT.br_blockcount, PREV.br_state)))
838 goto done; 802 goto done;
839 } 803 }
804
840 *dnew = 0; 805 *dnew = 0;
841 break; 806 break;
842 807
@@ -846,11 +811,10 @@ xfs_bmap_add_extent_delay_real(
846 * Neither the left nor right neighbors are contiguous with 811 * Neither the left nor right neighbors are contiguous with
847 * the new one. 812 * the new one.
848 */ 813 */
849 trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); 814 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
850 xfs_bmbt_set_startblock(ep, new->br_startblock); 815 xfs_bmbt_set_startblock(ep, new->br_startblock);
851 trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 816 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
852 817
853 ip->i_df.if_lastex = idx;
854 ip->i_d.di_nextents++; 818 ip->i_d.di_nextents++;
855 if (cur == NULL) 819 if (cur == NULL)
856 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 820 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
@@ -866,6 +830,7 @@ xfs_bmap_add_extent_delay_real(
866 goto done; 830 goto done;
867 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 831 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
868 } 832 }
833
869 *dnew = 0; 834 *dnew = 0;
870 break; 835 break;
871 836
@@ -874,17 +839,16 @@ xfs_bmap_add_extent_delay_real(
874 * Filling in the first part of a previous delayed allocation. 839 * Filling in the first part of a previous delayed allocation.
875 * The left neighbor is contiguous. 840 * The left neighbor is contiguous.
876 */ 841 */
877 trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); 842 trace_xfs_bmap_pre_update(ip, *idx - 1, state, _THIS_IP_);
878 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), 843 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx - 1),
879 LEFT.br_blockcount + new->br_blockcount); 844 LEFT.br_blockcount + new->br_blockcount);
880 xfs_bmbt_set_startoff(ep, 845 xfs_bmbt_set_startoff(ep,
881 PREV.br_startoff + new->br_blockcount); 846 PREV.br_startoff + new->br_blockcount);
882 trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); 847 trace_xfs_bmap_post_update(ip, *idx - 1, state, _THIS_IP_);
883 848
884 temp = PREV.br_blockcount - new->br_blockcount; 849 temp = PREV.br_blockcount - new->br_blockcount;
885 trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); 850 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
886 xfs_bmbt_set_blockcount(ep, temp); 851 xfs_bmbt_set_blockcount(ep, temp);
887 ip->i_df.if_lastex = idx - 1;
888 if (cur == NULL) 852 if (cur == NULL)
889 rval = XFS_ILOG_DEXT; 853 rval = XFS_ILOG_DEXT;
890 else { 854 else {
@@ -904,7 +868,9 @@ xfs_bmap_add_extent_delay_real(
904 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), 868 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
905 startblockval(PREV.br_startblock)); 869 startblockval(PREV.br_startblock));
906 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); 870 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp));
907 trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 871 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
872
873 --*idx;
908 *dnew = temp; 874 *dnew = temp;
909 break; 875 break;
910 876
@@ -913,12 +879,11 @@ xfs_bmap_add_extent_delay_real(
913 * Filling in the first part of a previous delayed allocation. 879 * Filling in the first part of a previous delayed allocation.
914 * The left neighbor is not contiguous. 880 * The left neighbor is not contiguous.
915 */ 881 */
916 trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); 882 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
917 xfs_bmbt_set_startoff(ep, new_endoff); 883 xfs_bmbt_set_startoff(ep, new_endoff);
918 temp = PREV.br_blockcount - new->br_blockcount; 884 temp = PREV.br_blockcount - new->br_blockcount;
919 xfs_bmbt_set_blockcount(ep, temp); 885 xfs_bmbt_set_blockcount(ep, temp);
920 xfs_iext_insert(ip, idx, 1, new, state); 886 xfs_iext_insert(ip, *idx, 1, new, state);
921 ip->i_df.if_lastex = idx;
922 ip->i_d.di_nextents++; 887 ip->i_d.di_nextents++;
923 if (cur == NULL) 888 if (cur == NULL)
924 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 889 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
@@ -946,9 +911,10 @@ xfs_bmap_add_extent_delay_real(
946 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), 911 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
947 startblockval(PREV.br_startblock) - 912 startblockval(PREV.br_startblock) -
948 (cur ? cur->bc_private.b.allocated : 0)); 913 (cur ? cur->bc_private.b.allocated : 0));
949 ep = xfs_iext_get_ext(ifp, idx + 1); 914 ep = xfs_iext_get_ext(ifp, *idx + 1);
950 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); 915 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp));
951 trace_xfs_bmap_post_update(ip, idx + 1, state, _THIS_IP_); 916 trace_xfs_bmap_post_update(ip, *idx + 1, state, _THIS_IP_);
917
952 *dnew = temp; 918 *dnew = temp;
953 break; 919 break;
954 920
@@ -958,15 +924,13 @@ xfs_bmap_add_extent_delay_real(
958 * The right neighbor is contiguous with the new allocation. 924 * The right neighbor is contiguous with the new allocation.
959 */ 925 */
960 temp = PREV.br_blockcount - new->br_blockcount; 926 temp = PREV.br_blockcount - new->br_blockcount;
961 trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); 927 trace_xfs_bmap_pre_update(ip, *idx + 1, state, _THIS_IP_);
962 trace_xfs_bmap_pre_update(ip, idx + 1, state, _THIS_IP_);
963 xfs_bmbt_set_blockcount(ep, temp); 928 xfs_bmbt_set_blockcount(ep, temp);
964 xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, idx + 1), 929 xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, *idx + 1),
965 new->br_startoff, new->br_startblock, 930 new->br_startoff, new->br_startblock,
966 new->br_blockcount + RIGHT.br_blockcount, 931 new->br_blockcount + RIGHT.br_blockcount,
967 RIGHT.br_state); 932 RIGHT.br_state);
968 trace_xfs_bmap_post_update(ip, idx + 1, state, _THIS_IP_); 933 trace_xfs_bmap_post_update(ip, *idx + 1, state, _THIS_IP_);
969 ip->i_df.if_lastex = idx + 1;
970 if (cur == NULL) 934 if (cur == NULL)
971 rval = XFS_ILOG_DEXT; 935 rval = XFS_ILOG_DEXT;
972 else { 936 else {
@@ -983,10 +947,14 @@ xfs_bmap_add_extent_delay_real(
983 RIGHT.br_state))) 947 RIGHT.br_state)))
984 goto done; 948 goto done;
985 } 949 }
950
986 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), 951 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
987 startblockval(PREV.br_startblock)); 952 startblockval(PREV.br_startblock));
953 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
988 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); 954 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp));
989 trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 955 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
956
957 ++*idx;
990 *dnew = temp; 958 *dnew = temp;
991 break; 959 break;
992 960
@@ -996,10 +964,9 @@ xfs_bmap_add_extent_delay_real(
996 * The right neighbor is not contiguous. 964 * The right neighbor is not contiguous.
997 */ 965 */
998 temp = PREV.br_blockcount - new->br_blockcount; 966 temp = PREV.br_blockcount - new->br_blockcount;
999 trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); 967 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
1000 xfs_bmbt_set_blockcount(ep, temp); 968 xfs_bmbt_set_blockcount(ep, temp);
1001 xfs_iext_insert(ip, idx + 1, 1, new, state); 969 xfs_iext_insert(ip, *idx + 1, 1, new, state);
1002 ip->i_df.if_lastex = idx + 1;
1003 ip->i_d.di_nextents++; 970 ip->i_d.di_nextents++;
1004 if (cur == NULL) 971 if (cur == NULL)
1005 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 972 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
@@ -1027,9 +994,11 @@ xfs_bmap_add_extent_delay_real(
1027 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), 994 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
1028 startblockval(PREV.br_startblock) - 995 startblockval(PREV.br_startblock) -
1029 (cur ? cur->bc_private.b.allocated : 0)); 996 (cur ? cur->bc_private.b.allocated : 0));
1030 ep = xfs_iext_get_ext(ifp, idx); 997 ep = xfs_iext_get_ext(ifp, *idx);
1031 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); 998 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp));
1032 trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 999 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
1000
1001 ++*idx;
1033 *dnew = temp; 1002 *dnew = temp;
1034 break; 1003 break;
1035 1004
@@ -1038,18 +1007,34 @@ xfs_bmap_add_extent_delay_real(
1038 * Filling in the middle part of a previous delayed allocation. 1007 * Filling in the middle part of a previous delayed allocation.
1039 * Contiguity is impossible here. 1008 * Contiguity is impossible here.
1040 * This case is avoided almost all the time. 1009 * This case is avoided almost all the time.
1010 *
1011 * We start with a delayed allocation:
1012 *
1013 * +ddddddddddddddddddddddddddddddddddddddddddddddddddddddd+
1014 * PREV @ idx
1015 *
1016 * and we are allocating:
1017 * +rrrrrrrrrrrrrrrrr+
1018 * new
1019 *
1020 * and we set it up for insertion as:
1021 * +ddddddddddddddddddd+rrrrrrrrrrrrrrrrr+ddddddddddddddddd+
1022 * new
1023 * PREV @ idx LEFT RIGHT
1024 * inserted at idx + 1
1041 */ 1025 */
1042 temp = new->br_startoff - PREV.br_startoff; 1026 temp = new->br_startoff - PREV.br_startoff;
1043 trace_xfs_bmap_pre_update(ip, idx, 0, _THIS_IP_);
1044 xfs_bmbt_set_blockcount(ep, temp);
1045 r[0] = *new;
1046 r[1].br_state = PREV.br_state;
1047 r[1].br_startblock = 0;
1048 r[1].br_startoff = new_endoff;
1049 temp2 = PREV.br_startoff + PREV.br_blockcount - new_endoff; 1027 temp2 = PREV.br_startoff + PREV.br_blockcount - new_endoff;
1050 r[1].br_blockcount = temp2; 1028 trace_xfs_bmap_pre_update(ip, *idx, 0, _THIS_IP_);
1051 xfs_iext_insert(ip, idx + 1, 2, &r[0], state); 1029 xfs_bmbt_set_blockcount(ep, temp); /* truncate PREV */
1052 ip->i_df.if_lastex = idx + 1; 1030 LEFT = *new;
1031 RIGHT.br_state = PREV.br_state;
1032 RIGHT.br_startblock = nullstartblock(
1033 (int)xfs_bmap_worst_indlen(ip, temp2));
1034 RIGHT.br_startoff = new_endoff;
1035 RIGHT.br_blockcount = temp2;
1036 /* insert LEFT (r[0]) and RIGHT (r[1]) at the same time */
1037 xfs_iext_insert(ip, *idx + 1, 2, &LEFT, state);
1053 ip->i_d.di_nextents++; 1038 ip->i_d.di_nextents++;
1054 if (cur == NULL) 1039 if (cur == NULL)
1055 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 1040 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
@@ -1079,7 +1064,8 @@ xfs_bmap_add_extent_delay_real(
1079 diff = (int)(temp + temp2 - startblockval(PREV.br_startblock) - 1064 diff = (int)(temp + temp2 - startblockval(PREV.br_startblock) -
1080 (cur ? cur->bc_private.b.allocated : 0)); 1065 (cur ? cur->bc_private.b.allocated : 0));
1081 if (diff > 0 && 1066 if (diff > 0 &&
1082 xfs_mod_incore_sb(ip->i_mount, XFS_SBS_FDBLOCKS, -((int64_t)diff), rsvd)) { 1067 xfs_icsb_modify_counters(ip->i_mount, XFS_SBS_FDBLOCKS,
1068 -((int64_t)diff), 0)) {
1083 /* 1069 /*
1084 * Ick gross gag me with a spoon. 1070 * Ick gross gag me with a spoon.
1085 */ 1071 */
@@ -1089,27 +1075,31 @@ xfs_bmap_add_extent_delay_real(
1089 temp--; 1075 temp--;
1090 diff--; 1076 diff--;
1091 if (!diff || 1077 if (!diff ||
1092 !xfs_mod_incore_sb(ip->i_mount, 1078 !xfs_icsb_modify_counters(ip->i_mount,
1093 XFS_SBS_FDBLOCKS, -((int64_t)diff), rsvd)) 1079 XFS_SBS_FDBLOCKS,
1080 -((int64_t)diff), 0))
1094 break; 1081 break;
1095 } 1082 }
1096 if (temp2) { 1083 if (temp2) {
1097 temp2--; 1084 temp2--;
1098 diff--; 1085 diff--;
1099 if (!diff || 1086 if (!diff ||
1100 !xfs_mod_incore_sb(ip->i_mount, 1087 !xfs_icsb_modify_counters(ip->i_mount,
1101 XFS_SBS_FDBLOCKS, -((int64_t)diff), rsvd)) 1088 XFS_SBS_FDBLOCKS,
1089 -((int64_t)diff), 0))
1102 break; 1090 break;
1103 } 1091 }
1104 } 1092 }
1105 } 1093 }
1106 ep = xfs_iext_get_ext(ifp, idx); 1094 ep = xfs_iext_get_ext(ifp, *idx);
1107 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); 1095 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp));
1108 trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 1096 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
1109 trace_xfs_bmap_pre_update(ip, idx + 2, state, _THIS_IP_); 1097 trace_xfs_bmap_pre_update(ip, *idx + 2, state, _THIS_IP_);
1110 xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx + 2), 1098 xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, *idx + 2),
1111 nullstartblock((int)temp2)); 1099 nullstartblock((int)temp2));
1112 trace_xfs_bmap_post_update(ip, idx + 2, state, _THIS_IP_); 1100 trace_xfs_bmap_post_update(ip, *idx + 2, state, _THIS_IP_);
1101
1102 ++*idx;
1113 *dnew = temp + temp2; 1103 *dnew = temp + temp2;
1114 break; 1104 break;
1115 1105
@@ -1141,7 +1131,7 @@ done:
1141STATIC int /* error */ 1131STATIC int /* error */
1142xfs_bmap_add_extent_unwritten_real( 1132xfs_bmap_add_extent_unwritten_real(
1143 xfs_inode_t *ip, /* incore inode pointer */ 1133 xfs_inode_t *ip, /* incore inode pointer */
1144 xfs_extnum_t idx, /* extent number to update/insert */ 1134 xfs_extnum_t *idx, /* extent number to update/insert */
1145 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ 1135 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
1146 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 1136 xfs_bmbt_irec_t *new, /* new data to add to file extents */
1147 int *logflagsp) /* inode logging flags */ 1137 int *logflagsp) /* inode logging flags */
@@ -1168,7 +1158,7 @@ xfs_bmap_add_extent_unwritten_real(
1168 error = 0; 1158 error = 0;
1169 cur = *curp; 1159 cur = *curp;
1170 ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); 1160 ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
1171 ep = xfs_iext_get_ext(ifp, idx); 1161 ep = xfs_iext_get_ext(ifp, *idx);
1172 xfs_bmbt_get_all(ep, &PREV); 1162 xfs_bmbt_get_all(ep, &PREV);
1173 newext = new->br_state; 1163 newext = new->br_state;
1174 oldext = (newext == XFS_EXT_UNWRITTEN) ? 1164 oldext = (newext == XFS_EXT_UNWRITTEN) ?
@@ -1191,9 +1181,9 @@ xfs_bmap_add_extent_unwritten_real(
1191 * Check and set flags if this segment has a left neighbor. 1181 * Check and set flags if this segment has a left neighbor.
1192 * Don't set contiguous if the combined extent would be too large. 1182 * Don't set contiguous if the combined extent would be too large.
1193 */ 1183 */
1194 if (idx > 0) { 1184 if (*idx > 0) {
1195 state |= BMAP_LEFT_VALID; 1185 state |= BMAP_LEFT_VALID;
1196 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &LEFT); 1186 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx - 1), &LEFT);
1197 1187
1198 if (isnullstartblock(LEFT.br_startblock)) 1188 if (isnullstartblock(LEFT.br_startblock))
1199 state |= BMAP_LEFT_DELAY; 1189 state |= BMAP_LEFT_DELAY;
@@ -1211,9 +1201,9 @@ xfs_bmap_add_extent_unwritten_real(
1211 * Don't set contiguous if the combined extent would be too large. 1201 * Don't set contiguous if the combined extent would be too large.
1212 * Also check for all-three-contiguous being too large. 1202 * Also check for all-three-contiguous being too large.
1213 */ 1203 */
1214 if (idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1) { 1204 if (*idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1) {
1215 state |= BMAP_RIGHT_VALID; 1205 state |= BMAP_RIGHT_VALID;
1216 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx + 1), &RIGHT); 1206 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx + 1), &RIGHT);
1217 if (isnullstartblock(RIGHT.br_startblock)) 1207 if (isnullstartblock(RIGHT.br_startblock))
1218 state |= BMAP_RIGHT_DELAY; 1208 state |= BMAP_RIGHT_DELAY;
1219 } 1209 }
@@ -1242,14 +1232,15 @@ xfs_bmap_add_extent_unwritten_real(
1242 * Setting all of a previous oldext extent to newext. 1232 * Setting all of a previous oldext extent to newext.
1243 * The left and right neighbors are both contiguous with new. 1233 * The left and right neighbors are both contiguous with new.
1244 */ 1234 */
1245 trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); 1235 --*idx;
1246 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), 1236
1237 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
1238 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx),
1247 LEFT.br_blockcount + PREV.br_blockcount + 1239 LEFT.br_blockcount + PREV.br_blockcount +
1248 RIGHT.br_blockcount); 1240 RIGHT.br_blockcount);
1249 trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); 1241 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
1250 1242
1251 xfs_iext_remove(ip, idx, 2, state); 1243 xfs_iext_remove(ip, *idx + 1, 2, state);
1252 ip->i_df.if_lastex = idx - 1;
1253 ip->i_d.di_nextents -= 2; 1244 ip->i_d.di_nextents -= 2;
1254 if (cur == NULL) 1245 if (cur == NULL)
1255 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 1246 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
@@ -1285,13 +1276,14 @@ xfs_bmap_add_extent_unwritten_real(
1285 * Setting all of a previous oldext extent to newext. 1276 * Setting all of a previous oldext extent to newext.
1286 * The left neighbor is contiguous, the right is not. 1277 * The left neighbor is contiguous, the right is not.
1287 */ 1278 */
1288 trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); 1279 --*idx;
1289 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), 1280
1281 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
1282 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx),
1290 LEFT.br_blockcount + PREV.br_blockcount); 1283 LEFT.br_blockcount + PREV.br_blockcount);
1291 trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); 1284 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
1292 1285
1293 ip->i_df.if_lastex = idx - 1; 1286 xfs_iext_remove(ip, *idx + 1, 1, state);
1294 xfs_iext_remove(ip, idx, 1, state);
1295 ip->i_d.di_nextents--; 1287 ip->i_d.di_nextents--;
1296 if (cur == NULL) 1288 if (cur == NULL)
1297 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 1289 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
@@ -1321,13 +1313,12 @@ xfs_bmap_add_extent_unwritten_real(
1321 * Setting all of a previous oldext extent to newext. 1313 * Setting all of a previous oldext extent to newext.
1322 * The right neighbor is contiguous, the left is not. 1314 * The right neighbor is contiguous, the left is not.
1323 */ 1315 */
1324 trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); 1316 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
1325 xfs_bmbt_set_blockcount(ep, 1317 xfs_bmbt_set_blockcount(ep,
1326 PREV.br_blockcount + RIGHT.br_blockcount); 1318 PREV.br_blockcount + RIGHT.br_blockcount);
1327 xfs_bmbt_set_state(ep, newext); 1319 xfs_bmbt_set_state(ep, newext);
1328 trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 1320 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
1329 ip->i_df.if_lastex = idx; 1321 xfs_iext_remove(ip, *idx + 1, 1, state);
1330 xfs_iext_remove(ip, idx + 1, 1, state);
1331 ip->i_d.di_nextents--; 1322 ip->i_d.di_nextents--;
1332 if (cur == NULL) 1323 if (cur == NULL)
1333 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 1324 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
@@ -1358,11 +1349,10 @@ xfs_bmap_add_extent_unwritten_real(
1358 * Neither the left nor right neighbors are contiguous with 1349 * Neither the left nor right neighbors are contiguous with
1359 * the new one. 1350 * the new one.
1360 */ 1351 */
1361 trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); 1352 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
1362 xfs_bmbt_set_state(ep, newext); 1353 xfs_bmbt_set_state(ep, newext);
1363 trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 1354 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
1364 1355
1365 ip->i_df.if_lastex = idx;
1366 if (cur == NULL) 1356 if (cur == NULL)
1367 rval = XFS_ILOG_DEXT; 1357 rval = XFS_ILOG_DEXT;
1368 else { 1358 else {
@@ -1384,21 +1374,22 @@ xfs_bmap_add_extent_unwritten_real(
1384 * Setting the first part of a previous oldext extent to newext. 1374 * Setting the first part of a previous oldext extent to newext.
1385 * The left neighbor is contiguous. 1375 * The left neighbor is contiguous.
1386 */ 1376 */
1387 trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); 1377 trace_xfs_bmap_pre_update(ip, *idx - 1, state, _THIS_IP_);
1388 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), 1378 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx - 1),
1389 LEFT.br_blockcount + new->br_blockcount); 1379 LEFT.br_blockcount + new->br_blockcount);
1390 xfs_bmbt_set_startoff(ep, 1380 xfs_bmbt_set_startoff(ep,
1391 PREV.br_startoff + new->br_blockcount); 1381 PREV.br_startoff + new->br_blockcount);
1392 trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); 1382 trace_xfs_bmap_post_update(ip, *idx - 1, state, _THIS_IP_);
1393 1383
1394 trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); 1384 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
1395 xfs_bmbt_set_startblock(ep, 1385 xfs_bmbt_set_startblock(ep,
1396 new->br_startblock + new->br_blockcount); 1386 new->br_startblock + new->br_blockcount);
1397 xfs_bmbt_set_blockcount(ep, 1387 xfs_bmbt_set_blockcount(ep,
1398 PREV.br_blockcount - new->br_blockcount); 1388 PREV.br_blockcount - new->br_blockcount);
1399 trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 1389 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
1390
1391 --*idx;
1400 1392
1401 ip->i_df.if_lastex = idx - 1;
1402 if (cur == NULL) 1393 if (cur == NULL)
1403 rval = XFS_ILOG_DEXT; 1394 rval = XFS_ILOG_DEXT;
1404 else { 1395 else {
@@ -1429,17 +1420,16 @@ xfs_bmap_add_extent_unwritten_real(
1429 * Setting the first part of a previous oldext extent to newext. 1420 * Setting the first part of a previous oldext extent to newext.
1430 * The left neighbor is not contiguous. 1421 * The left neighbor is not contiguous.
1431 */ 1422 */
1432 trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); 1423 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
1433 ASSERT(ep && xfs_bmbt_get_state(ep) == oldext); 1424 ASSERT(ep && xfs_bmbt_get_state(ep) == oldext);
1434 xfs_bmbt_set_startoff(ep, new_endoff); 1425 xfs_bmbt_set_startoff(ep, new_endoff);
1435 xfs_bmbt_set_blockcount(ep, 1426 xfs_bmbt_set_blockcount(ep,
1436 PREV.br_blockcount - new->br_blockcount); 1427 PREV.br_blockcount - new->br_blockcount);
1437 xfs_bmbt_set_startblock(ep, 1428 xfs_bmbt_set_startblock(ep,
1438 new->br_startblock + new->br_blockcount); 1429 new->br_startblock + new->br_blockcount);
1439 trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 1430 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
1440 1431
1441 xfs_iext_insert(ip, idx, 1, new, state); 1432 xfs_iext_insert(ip, *idx, 1, new, state);
1442 ip->i_df.if_lastex = idx;
1443 ip->i_d.di_nextents++; 1433 ip->i_d.di_nextents++;
1444 if (cur == NULL) 1434 if (cur == NULL)
1445 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 1435 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
@@ -1468,17 +1458,19 @@ xfs_bmap_add_extent_unwritten_real(
1468 * Setting the last part of a previous oldext extent to newext. 1458 * Setting the last part of a previous oldext extent to newext.
1469 * The right neighbor is contiguous with the new allocation. 1459 * The right neighbor is contiguous with the new allocation.
1470 */ 1460 */
1471 trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); 1461 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
1472 trace_xfs_bmap_pre_update(ip, idx + 1, state, _THIS_IP_);
1473 xfs_bmbt_set_blockcount(ep, 1462 xfs_bmbt_set_blockcount(ep,
1474 PREV.br_blockcount - new->br_blockcount); 1463 PREV.br_blockcount - new->br_blockcount);
1475 trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 1464 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
1476 xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, idx + 1), 1465
1466 ++*idx;
1467
1468 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
1469 xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, *idx),
1477 new->br_startoff, new->br_startblock, 1470 new->br_startoff, new->br_startblock,
1478 new->br_blockcount + RIGHT.br_blockcount, newext); 1471 new->br_blockcount + RIGHT.br_blockcount, newext);
1479 trace_xfs_bmap_post_update(ip, idx + 1, state, _THIS_IP_); 1472 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
1480 1473
1481 ip->i_df.if_lastex = idx + 1;
1482 if (cur == NULL) 1474 if (cur == NULL)
1483 rval = XFS_ILOG_DEXT; 1475 rval = XFS_ILOG_DEXT;
1484 else { 1476 else {
@@ -1508,13 +1500,14 @@ xfs_bmap_add_extent_unwritten_real(
1508 * Setting the last part of a previous oldext extent to newext. 1500 * Setting the last part of a previous oldext extent to newext.
1509 * The right neighbor is not contiguous. 1501 * The right neighbor is not contiguous.
1510 */ 1502 */
1511 trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); 1503 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
1512 xfs_bmbt_set_blockcount(ep, 1504 xfs_bmbt_set_blockcount(ep,
1513 PREV.br_blockcount - new->br_blockcount); 1505 PREV.br_blockcount - new->br_blockcount);
1514 trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 1506 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
1507
1508 ++*idx;
1509 xfs_iext_insert(ip, *idx, 1, new, state);
1515 1510
1516 xfs_iext_insert(ip, idx + 1, 1, new, state);
1517 ip->i_df.if_lastex = idx + 1;
1518 ip->i_d.di_nextents++; 1511 ip->i_d.di_nextents++;
1519 if (cur == NULL) 1512 if (cur == NULL)
1520 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 1513 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
@@ -1548,10 +1541,10 @@ xfs_bmap_add_extent_unwritten_real(
1548 * newext. Contiguity is impossible here. 1541 * newext. Contiguity is impossible here.
1549 * One extent becomes three extents. 1542 * One extent becomes three extents.
1550 */ 1543 */
1551 trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); 1544 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
1552 xfs_bmbt_set_blockcount(ep, 1545 xfs_bmbt_set_blockcount(ep,
1553 new->br_startoff - PREV.br_startoff); 1546 new->br_startoff - PREV.br_startoff);
1554 trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 1547 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
1555 1548
1556 r[0] = *new; 1549 r[0] = *new;
1557 r[1].br_startoff = new_endoff; 1550 r[1].br_startoff = new_endoff;
@@ -1559,8 +1552,10 @@ xfs_bmap_add_extent_unwritten_real(
1559 PREV.br_startoff + PREV.br_blockcount - new_endoff; 1552 PREV.br_startoff + PREV.br_blockcount - new_endoff;
1560 r[1].br_startblock = new->br_startblock + new->br_blockcount; 1553 r[1].br_startblock = new->br_startblock + new->br_blockcount;
1561 r[1].br_state = oldext; 1554 r[1].br_state = oldext;
1562 xfs_iext_insert(ip, idx + 1, 2, &r[0], state); 1555
1563 ip->i_df.if_lastex = idx + 1; 1556 ++*idx;
1557 xfs_iext_insert(ip, *idx, 2, &r[0], state);
1558
1564 ip->i_d.di_nextents += 2; 1559 ip->i_d.di_nextents += 2;
1565 if (cur == NULL) 1560 if (cur == NULL)
1566 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 1561 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
@@ -1630,12 +1625,10 @@ done:
1630STATIC int /* error */ 1625STATIC int /* error */
1631xfs_bmap_add_extent_hole_delay( 1626xfs_bmap_add_extent_hole_delay(
1632 xfs_inode_t *ip, /* incore inode pointer */ 1627 xfs_inode_t *ip, /* incore inode pointer */
1633 xfs_extnum_t idx, /* extent number to update/insert */ 1628 xfs_extnum_t *idx, /* extent number to update/insert */
1634 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 1629 xfs_bmbt_irec_t *new, /* new data to add to file extents */
1635 int *logflagsp, /* inode logging flags */ 1630 int *logflagsp) /* inode logging flags */
1636 int rsvd) /* OK to allocate reserved blocks */
1637{ 1631{
1638 xfs_bmbt_rec_host_t *ep; /* extent record for idx */
1639 xfs_ifork_t *ifp; /* inode fork pointer */ 1632 xfs_ifork_t *ifp; /* inode fork pointer */
1640 xfs_bmbt_irec_t left; /* left neighbor extent entry */ 1633 xfs_bmbt_irec_t left; /* left neighbor extent entry */
1641 xfs_filblks_t newlen=0; /* new indirect size */ 1634 xfs_filblks_t newlen=0; /* new indirect size */
@@ -1645,16 +1638,15 @@ xfs_bmap_add_extent_hole_delay(
1645 xfs_filblks_t temp=0; /* temp for indirect calculations */ 1638 xfs_filblks_t temp=0; /* temp for indirect calculations */
1646 1639
1647 ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); 1640 ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
1648 ep = xfs_iext_get_ext(ifp, idx);
1649 state = 0; 1641 state = 0;
1650 ASSERT(isnullstartblock(new->br_startblock)); 1642 ASSERT(isnullstartblock(new->br_startblock));
1651 1643
1652 /* 1644 /*
1653 * Check and set flags if this segment has a left neighbor 1645 * Check and set flags if this segment has a left neighbor
1654 */ 1646 */
1655 if (idx > 0) { 1647 if (*idx > 0) {
1656 state |= BMAP_LEFT_VALID; 1648 state |= BMAP_LEFT_VALID;
1657 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &left); 1649 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx - 1), &left);
1658 1650
1659 if (isnullstartblock(left.br_startblock)) 1651 if (isnullstartblock(left.br_startblock))
1660 state |= BMAP_LEFT_DELAY; 1652 state |= BMAP_LEFT_DELAY;
@@ -1664,9 +1656,9 @@ xfs_bmap_add_extent_hole_delay(
1664 * Check and set flags if the current (right) segment exists. 1656 * Check and set flags if the current (right) segment exists.
1665 * If it doesn't exist, we're converting the hole at end-of-file. 1657 * If it doesn't exist, we're converting the hole at end-of-file.
1666 */ 1658 */
1667 if (idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t)) { 1659 if (*idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t)) {
1668 state |= BMAP_RIGHT_VALID; 1660 state |= BMAP_RIGHT_VALID;
1669 xfs_bmbt_get_all(ep, &right); 1661 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx), &right);
1670 1662
1671 if (isnullstartblock(right.br_startblock)) 1663 if (isnullstartblock(right.br_startblock))
1672 state |= BMAP_RIGHT_DELAY; 1664 state |= BMAP_RIGHT_DELAY;
@@ -1699,21 +1691,21 @@ xfs_bmap_add_extent_hole_delay(
1699 * on the left and on the right. 1691 * on the left and on the right.
1700 * Merge all three into a single extent record. 1692 * Merge all three into a single extent record.
1701 */ 1693 */
1694 --*idx;
1702 temp = left.br_blockcount + new->br_blockcount + 1695 temp = left.br_blockcount + new->br_blockcount +
1703 right.br_blockcount; 1696 right.br_blockcount;
1704 1697
1705 trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); 1698 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
1706 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), temp); 1699 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx), temp);
1707 oldlen = startblockval(left.br_startblock) + 1700 oldlen = startblockval(left.br_startblock) +
1708 startblockval(new->br_startblock) + 1701 startblockval(new->br_startblock) +
1709 startblockval(right.br_startblock); 1702 startblockval(right.br_startblock);
1710 newlen = xfs_bmap_worst_indlen(ip, temp); 1703 newlen = xfs_bmap_worst_indlen(ip, temp);
1711 xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx - 1), 1704 xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, *idx),
1712 nullstartblock((int)newlen)); 1705 nullstartblock((int)newlen));
1713 trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); 1706 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
1714 1707
1715 xfs_iext_remove(ip, idx, 1, state); 1708 xfs_iext_remove(ip, *idx + 1, 1, state);
1716 ip->i_df.if_lastex = idx - 1;
1717 break; 1709 break;
1718 1710
1719 case BMAP_LEFT_CONTIG: 1711 case BMAP_LEFT_CONTIG:
@@ -1722,17 +1714,17 @@ xfs_bmap_add_extent_hole_delay(
1722 * on the left. 1714 * on the left.
1723 * Merge the new allocation with the left neighbor. 1715 * Merge the new allocation with the left neighbor.
1724 */ 1716 */
1717 --*idx;
1725 temp = left.br_blockcount + new->br_blockcount; 1718 temp = left.br_blockcount + new->br_blockcount;
1726 trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); 1719
1727 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), temp); 1720 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
1721 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx), temp);
1728 oldlen = startblockval(left.br_startblock) + 1722 oldlen = startblockval(left.br_startblock) +
1729 startblockval(new->br_startblock); 1723 startblockval(new->br_startblock);
1730 newlen = xfs_bmap_worst_indlen(ip, temp); 1724 newlen = xfs_bmap_worst_indlen(ip, temp);
1731 xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx - 1), 1725 xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, *idx),
1732 nullstartblock((int)newlen)); 1726 nullstartblock((int)newlen));
1733 trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); 1727 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
1734
1735 ip->i_df.if_lastex = idx - 1;
1736 break; 1728 break;
1737 1729
1738 case BMAP_RIGHT_CONTIG: 1730 case BMAP_RIGHT_CONTIG:
@@ -1741,16 +1733,15 @@ xfs_bmap_add_extent_hole_delay(
1741 * on the right. 1733 * on the right.
1742 * Merge the new allocation with the right neighbor. 1734 * Merge the new allocation with the right neighbor.
1743 */ 1735 */
1744 trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); 1736 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
1745 temp = new->br_blockcount + right.br_blockcount; 1737 temp = new->br_blockcount + right.br_blockcount;
1746 oldlen = startblockval(new->br_startblock) + 1738 oldlen = startblockval(new->br_startblock) +
1747 startblockval(right.br_startblock); 1739 startblockval(right.br_startblock);
1748 newlen = xfs_bmap_worst_indlen(ip, temp); 1740 newlen = xfs_bmap_worst_indlen(ip, temp);
1749 xfs_bmbt_set_allf(ep, new->br_startoff, 1741 xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, *idx),
1742 new->br_startoff,
1750 nullstartblock((int)newlen), temp, right.br_state); 1743 nullstartblock((int)newlen), temp, right.br_state);
1751 trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 1744 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
1752
1753 ip->i_df.if_lastex = idx;
1754 break; 1745 break;
1755 1746
1756 case 0: 1747 case 0:
@@ -1760,14 +1751,13 @@ xfs_bmap_add_extent_hole_delay(
1760 * Insert a new entry. 1751 * Insert a new entry.
1761 */ 1752 */
1762 oldlen = newlen = 0; 1753 oldlen = newlen = 0;
1763 xfs_iext_insert(ip, idx, 1, new, state); 1754 xfs_iext_insert(ip, *idx, 1, new, state);
1764 ip->i_df.if_lastex = idx;
1765 break; 1755 break;
1766 } 1756 }
1767 if (oldlen != newlen) { 1757 if (oldlen != newlen) {
1768 ASSERT(oldlen > newlen); 1758 ASSERT(oldlen > newlen);
1769 xfs_mod_incore_sb(ip->i_mount, XFS_SBS_FDBLOCKS, 1759 xfs_icsb_modify_counters(ip->i_mount, XFS_SBS_FDBLOCKS,
1770 (int64_t)(oldlen - newlen), rsvd); 1760 (int64_t)(oldlen - newlen), 0);
1771 /* 1761 /*
1772 * Nothing to do for disk quota accounting here. 1762 * Nothing to do for disk quota accounting here.
1773 */ 1763 */
@@ -1783,13 +1773,12 @@ xfs_bmap_add_extent_hole_delay(
1783STATIC int /* error */ 1773STATIC int /* error */
1784xfs_bmap_add_extent_hole_real( 1774xfs_bmap_add_extent_hole_real(
1785 xfs_inode_t *ip, /* incore inode pointer */ 1775 xfs_inode_t *ip, /* incore inode pointer */
1786 xfs_extnum_t idx, /* extent number to update/insert */ 1776 xfs_extnum_t *idx, /* extent number to update/insert */
1787 xfs_btree_cur_t *cur, /* if null, not a btree */ 1777 xfs_btree_cur_t *cur, /* if null, not a btree */
1788 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 1778 xfs_bmbt_irec_t *new, /* new data to add to file extents */
1789 int *logflagsp, /* inode logging flags */ 1779 int *logflagsp, /* inode logging flags */
1790 int whichfork) /* data or attr fork */ 1780 int whichfork) /* data or attr fork */
1791{ 1781{
1792 xfs_bmbt_rec_host_t *ep; /* pointer to extent entry ins. point */
1793 int error; /* error return value */ 1782 int error; /* error return value */
1794 int i; /* temp state */ 1783 int i; /* temp state */
1795 xfs_ifork_t *ifp; /* inode fork pointer */ 1784 xfs_ifork_t *ifp; /* inode fork pointer */
@@ -1799,8 +1788,7 @@ xfs_bmap_add_extent_hole_real(
1799 int state; /* state bits, accessed thru macros */ 1788 int state; /* state bits, accessed thru macros */
1800 1789
1801 ifp = XFS_IFORK_PTR(ip, whichfork); 1790 ifp = XFS_IFORK_PTR(ip, whichfork);
1802 ASSERT(idx <= ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)); 1791 ASSERT(*idx <= ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t));
1803 ep = xfs_iext_get_ext(ifp, idx);
1804 state = 0; 1792 state = 0;
1805 1793
1806 if (whichfork == XFS_ATTR_FORK) 1794 if (whichfork == XFS_ATTR_FORK)
@@ -1809,9 +1797,9 @@ xfs_bmap_add_extent_hole_real(
1809 /* 1797 /*
1810 * Check and set flags if this segment has a left neighbor. 1798 * Check and set flags if this segment has a left neighbor.
1811 */ 1799 */
1812 if (idx > 0) { 1800 if (*idx > 0) {
1813 state |= BMAP_LEFT_VALID; 1801 state |= BMAP_LEFT_VALID;
1814 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &left); 1802 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx - 1), &left);
1815 if (isnullstartblock(left.br_startblock)) 1803 if (isnullstartblock(left.br_startblock))
1816 state |= BMAP_LEFT_DELAY; 1804 state |= BMAP_LEFT_DELAY;
1817 } 1805 }
@@ -1820,9 +1808,9 @@ xfs_bmap_add_extent_hole_real(
1820 * Check and set flags if this segment has a current value. 1808 * Check and set flags if this segment has a current value.
1821 * Not true if we're inserting into the "hole" at eof. 1809 * Not true if we're inserting into the "hole" at eof.
1822 */ 1810 */
1823 if (idx < ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)) { 1811 if (*idx < ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)) {
1824 state |= BMAP_RIGHT_VALID; 1812 state |= BMAP_RIGHT_VALID;
1825 xfs_bmbt_get_all(ep, &right); 1813 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx), &right);
1826 if (isnullstartblock(right.br_startblock)) 1814 if (isnullstartblock(right.br_startblock))
1827 state |= BMAP_RIGHT_DELAY; 1815 state |= BMAP_RIGHT_DELAY;
1828 } 1816 }
@@ -1859,14 +1847,15 @@ xfs_bmap_add_extent_hole_real(
1859 * left and on the right. 1847 * left and on the right.
1860 * Merge all three into a single extent record. 1848 * Merge all three into a single extent record.
1861 */ 1849 */
1862 trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); 1850 --*idx;
1863 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), 1851 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
1852 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx),
1864 left.br_blockcount + new->br_blockcount + 1853 left.br_blockcount + new->br_blockcount +
1865 right.br_blockcount); 1854 right.br_blockcount);
1866 trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); 1855 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
1856
1857 xfs_iext_remove(ip, *idx + 1, 1, state);
1867 1858
1868 xfs_iext_remove(ip, idx, 1, state);
1869 ifp->if_lastex = idx - 1;
1870 XFS_IFORK_NEXT_SET(ip, whichfork, 1859 XFS_IFORK_NEXT_SET(ip, whichfork,
1871 XFS_IFORK_NEXTENTS(ip, whichfork) - 1); 1860 XFS_IFORK_NEXTENTS(ip, whichfork) - 1);
1872 if (cur == NULL) { 1861 if (cur == NULL) {
@@ -1901,12 +1890,12 @@ xfs_bmap_add_extent_hole_real(
1901 * on the left. 1890 * on the left.
1902 * Merge the new allocation with the left neighbor. 1891 * Merge the new allocation with the left neighbor.
1903 */ 1892 */
1904 trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); 1893 --*idx;
1905 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), 1894 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
1895 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx),
1906 left.br_blockcount + new->br_blockcount); 1896 left.br_blockcount + new->br_blockcount);
1907 trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); 1897 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
1908 1898
1909 ifp->if_lastex = idx - 1;
1910 if (cur == NULL) { 1899 if (cur == NULL) {
1911 rval = xfs_ilog_fext(whichfork); 1900 rval = xfs_ilog_fext(whichfork);
1912 } else { 1901 } else {
@@ -1932,13 +1921,13 @@ xfs_bmap_add_extent_hole_real(
1932 * on the right. 1921 * on the right.
1933 * Merge the new allocation with the right neighbor. 1922 * Merge the new allocation with the right neighbor.
1934 */ 1923 */
1935 trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); 1924 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
1936 xfs_bmbt_set_allf(ep, new->br_startoff, new->br_startblock, 1925 xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, *idx),
1926 new->br_startoff, new->br_startblock,
1937 new->br_blockcount + right.br_blockcount, 1927 new->br_blockcount + right.br_blockcount,
1938 right.br_state); 1928 right.br_state);
1939 trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 1929 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
1940 1930
1941 ifp->if_lastex = idx;
1942 if (cur == NULL) { 1931 if (cur == NULL) {
1943 rval = xfs_ilog_fext(whichfork); 1932 rval = xfs_ilog_fext(whichfork);
1944 } else { 1933 } else {
@@ -1964,8 +1953,7 @@ xfs_bmap_add_extent_hole_real(
1964 * real allocation. 1953 * real allocation.
1965 * Insert a new entry. 1954 * Insert a new entry.
1966 */ 1955 */
1967 xfs_iext_insert(ip, idx, 1, new, state); 1956 xfs_iext_insert(ip, *idx, 1, new, state);
1968 ifp->if_lastex = idx;
1969 XFS_IFORK_NEXT_SET(ip, whichfork, 1957 XFS_IFORK_NEXT_SET(ip, whichfork,
1970 XFS_IFORK_NEXTENTS(ip, whichfork) + 1); 1958 XFS_IFORK_NEXTENTS(ip, whichfork) + 1);
1971 if (cur == NULL) { 1959 if (cur == NULL) {
@@ -2345,6 +2333,13 @@ xfs_bmap_rtalloc(
2345 */ 2333 */
2346 if (ralen * mp->m_sb.sb_rextsize >= MAXEXTLEN) 2334 if (ralen * mp->m_sb.sb_rextsize >= MAXEXTLEN)
2347 ralen = MAXEXTLEN / mp->m_sb.sb_rextsize; 2335 ralen = MAXEXTLEN / mp->m_sb.sb_rextsize;
2336
2337 /*
2338 * Lock out other modifications to the RT bitmap inode.
2339 */
2340 xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL);
2341 xfs_trans_ijoin_ref(ap->tp, mp->m_rbmip, XFS_ILOCK_EXCL);
2342
2348 /* 2343 /*
2349 * If it's an allocation to an empty file at offset 0, 2344 * If it's an allocation to an empty file at offset 0,
2350 * pick an extent that will space things out in the rt area. 2345 * pick an extent that will space things out in the rt area.
@@ -2427,7 +2422,7 @@ xfs_bmap_btalloc_nullfb(
2427 startag = ag = 0; 2422 startag = ag = 0;
2428 2423
2429 pag = xfs_perag_get(mp, ag); 2424 pag = xfs_perag_get(mp, ag);
2430 while (*blen < ap->alen) { 2425 while (*blen < args->maxlen) {
2431 if (!pag->pagf_init) { 2426 if (!pag->pagf_init) {
2432 error = xfs_alloc_pagf_init(mp, args->tp, ag, 2427 error = xfs_alloc_pagf_init(mp, args->tp, ag,
2433 XFS_ALLOC_FLAG_TRYLOCK); 2428 XFS_ALLOC_FLAG_TRYLOCK);
@@ -2449,7 +2444,7 @@ xfs_bmap_btalloc_nullfb(
2449 notinit = 1; 2444 notinit = 1;
2450 2445
2451 if (xfs_inode_is_filestream(ap->ip)) { 2446 if (xfs_inode_is_filestream(ap->ip)) {
2452 if (*blen >= ap->alen) 2447 if (*blen >= args->maxlen)
2453 break; 2448 break;
2454 2449
2455 if (ap->userdata) { 2450 if (ap->userdata) {
@@ -2495,14 +2490,14 @@ xfs_bmap_btalloc_nullfb(
2495 * If the best seen length is less than the request 2490 * If the best seen length is less than the request
2496 * length, use the best as the minimum. 2491 * length, use the best as the minimum.
2497 */ 2492 */
2498 else if (*blen < ap->alen) 2493 else if (*blen < args->maxlen)
2499 args->minlen = *blen; 2494 args->minlen = *blen;
2500 /* 2495 /*
2501 * Otherwise we've seen an extent as big as alen, 2496 * Otherwise we've seen an extent as big as maxlen,
2502 * use that as the minimum. 2497 * use that as the minimum.
2503 */ 2498 */
2504 else 2499 else
2505 args->minlen = ap->alen; 2500 args->minlen = args->maxlen;
2506 2501
2507 /* 2502 /*
2508 * set the failure fallback case to look in the selected 2503 * set the failure fallback case to look in the selected
@@ -2570,7 +2565,9 @@ xfs_bmap_btalloc(
2570 args.tp = ap->tp; 2565 args.tp = ap->tp;
2571 args.mp = mp; 2566 args.mp = mp;
2572 args.fsbno = ap->rval; 2567 args.fsbno = ap->rval;
2573 args.maxlen = MIN(ap->alen, mp->m_sb.sb_agblocks); 2568
2569 /* Trim the allocation back to the maximum an AG can fit. */
2570 args.maxlen = MIN(ap->alen, XFS_ALLOC_AG_MAX_USABLE(mp));
2574 args.firstblock = ap->firstblock; 2571 args.firstblock = ap->firstblock;
2575 blen = 0; 2572 blen = 0;
2576 if (nullfb) { 2573 if (nullfb) {
@@ -2618,7 +2615,7 @@ xfs_bmap_btalloc(
2618 /* 2615 /*
2619 * Adjust for alignment 2616 * Adjust for alignment
2620 */ 2617 */
2621 if (blen > args.alignment && blen <= ap->alen) 2618 if (blen > args.alignment && blen <= args.maxlen)
2622 args.minlen = blen - args.alignment; 2619 args.minlen = blen - args.alignment;
2623 args.minalignslop = 0; 2620 args.minalignslop = 0;
2624 } else { 2621 } else {
@@ -2637,7 +2634,7 @@ xfs_bmap_btalloc(
2637 * of minlen+alignment+slop doesn't go up 2634 * of minlen+alignment+slop doesn't go up
2638 * between the calls. 2635 * between the calls.
2639 */ 2636 */
2640 if (blen > mp->m_dalign && blen <= ap->alen) 2637 if (blen > mp->m_dalign && blen <= args.maxlen)
2641 nextminlen = blen - mp->m_dalign; 2638 nextminlen = blen - mp->m_dalign;
2642 else 2639 else
2643 nextminlen = args.minlen; 2640 nextminlen = args.minlen;
@@ -2804,13 +2801,12 @@ STATIC int /* error */
2804xfs_bmap_del_extent( 2801xfs_bmap_del_extent(
2805 xfs_inode_t *ip, /* incore inode pointer */ 2802 xfs_inode_t *ip, /* incore inode pointer */
2806 xfs_trans_t *tp, /* current transaction pointer */ 2803 xfs_trans_t *tp, /* current transaction pointer */
2807 xfs_extnum_t idx, /* extent number to update/delete */ 2804 xfs_extnum_t *idx, /* extent number to update/delete */
2808 xfs_bmap_free_t *flist, /* list of extents to be freed */ 2805 xfs_bmap_free_t *flist, /* list of extents to be freed */
2809 xfs_btree_cur_t *cur, /* if null, not a btree */ 2806 xfs_btree_cur_t *cur, /* if null, not a btree */
2810 xfs_bmbt_irec_t *del, /* data to remove from extents */ 2807 xfs_bmbt_irec_t *del, /* data to remove from extents */
2811 int *logflagsp, /* inode logging flags */ 2808 int *logflagsp, /* inode logging flags */
2812 int whichfork, /* data or attr fork */ 2809 int whichfork) /* data or attr fork */
2813 int rsvd) /* OK to allocate reserved blocks */
2814{ 2810{
2815 xfs_filblks_t da_new; /* new delay-alloc indirect blocks */ 2811 xfs_filblks_t da_new; /* new delay-alloc indirect blocks */
2816 xfs_filblks_t da_old; /* old delay-alloc indirect blocks */ 2812 xfs_filblks_t da_old; /* old delay-alloc indirect blocks */
@@ -2841,10 +2837,10 @@ xfs_bmap_del_extent(
2841 2837
2842 mp = ip->i_mount; 2838 mp = ip->i_mount;
2843 ifp = XFS_IFORK_PTR(ip, whichfork); 2839 ifp = XFS_IFORK_PTR(ip, whichfork);
2844 ASSERT((idx >= 0) && (idx < ifp->if_bytes / 2840 ASSERT((*idx >= 0) && (*idx < ifp->if_bytes /
2845 (uint)sizeof(xfs_bmbt_rec_t))); 2841 (uint)sizeof(xfs_bmbt_rec_t)));
2846 ASSERT(del->br_blockcount > 0); 2842 ASSERT(del->br_blockcount > 0);
2847 ep = xfs_iext_get_ext(ifp, idx); 2843 ep = xfs_iext_get_ext(ifp, *idx);
2848 xfs_bmbt_get_all(ep, &got); 2844 xfs_bmbt_get_all(ep, &got);
2849 ASSERT(got.br_startoff <= del->br_startoff); 2845 ASSERT(got.br_startoff <= del->br_startoff);
2850 del_endoff = del->br_startoff + del->br_blockcount; 2846 del_endoff = del->br_startoff + del->br_blockcount;
@@ -2918,11 +2914,12 @@ xfs_bmap_del_extent(
2918 /* 2914 /*
2919 * Matches the whole extent. Delete the entry. 2915 * Matches the whole extent. Delete the entry.
2920 */ 2916 */
2921 xfs_iext_remove(ip, idx, 1, 2917 xfs_iext_remove(ip, *idx, 1,
2922 whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0); 2918 whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0);
2923 ifp->if_lastex = idx; 2919 --*idx;
2924 if (delay) 2920 if (delay)
2925 break; 2921 break;
2922
2926 XFS_IFORK_NEXT_SET(ip, whichfork, 2923 XFS_IFORK_NEXT_SET(ip, whichfork,
2927 XFS_IFORK_NEXTENTS(ip, whichfork) - 1); 2924 XFS_IFORK_NEXTENTS(ip, whichfork) - 1);
2928 flags |= XFS_ILOG_CORE; 2925 flags |= XFS_ILOG_CORE;
@@ -2939,21 +2936,20 @@ xfs_bmap_del_extent(
2939 /* 2936 /*
2940 * Deleting the first part of the extent. 2937 * Deleting the first part of the extent.
2941 */ 2938 */
2942 trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); 2939 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
2943 xfs_bmbt_set_startoff(ep, del_endoff); 2940 xfs_bmbt_set_startoff(ep, del_endoff);
2944 temp = got.br_blockcount - del->br_blockcount; 2941 temp = got.br_blockcount - del->br_blockcount;
2945 xfs_bmbt_set_blockcount(ep, temp); 2942 xfs_bmbt_set_blockcount(ep, temp);
2946 ifp->if_lastex = idx;
2947 if (delay) { 2943 if (delay) {
2948 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), 2944 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
2949 da_old); 2945 da_old);
2950 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); 2946 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp));
2951 trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 2947 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
2952 da_new = temp; 2948 da_new = temp;
2953 break; 2949 break;
2954 } 2950 }
2955 xfs_bmbt_set_startblock(ep, del_endblock); 2951 xfs_bmbt_set_startblock(ep, del_endblock);
2956 trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 2952 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
2957 if (!cur) { 2953 if (!cur) {
2958 flags |= xfs_ilog_fext(whichfork); 2954 flags |= xfs_ilog_fext(whichfork);
2959 break; 2955 break;
@@ -2969,18 +2965,17 @@ xfs_bmap_del_extent(
2969 * Deleting the last part of the extent. 2965 * Deleting the last part of the extent.
2970 */ 2966 */
2971 temp = got.br_blockcount - del->br_blockcount; 2967 temp = got.br_blockcount - del->br_blockcount;
2972 trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); 2968 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
2973 xfs_bmbt_set_blockcount(ep, temp); 2969 xfs_bmbt_set_blockcount(ep, temp);
2974 ifp->if_lastex = idx;
2975 if (delay) { 2970 if (delay) {
2976 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), 2971 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
2977 da_old); 2972 da_old);
2978 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); 2973 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp));
2979 trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 2974 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
2980 da_new = temp; 2975 da_new = temp;
2981 break; 2976 break;
2982 } 2977 }
2983 trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 2978 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
2984 if (!cur) { 2979 if (!cur) {
2985 flags |= xfs_ilog_fext(whichfork); 2980 flags |= xfs_ilog_fext(whichfork);
2986 break; 2981 break;
@@ -2997,7 +2992,7 @@ xfs_bmap_del_extent(
2997 * Deleting the middle of the extent. 2992 * Deleting the middle of the extent.
2998 */ 2993 */
2999 temp = del->br_startoff - got.br_startoff; 2994 temp = del->br_startoff - got.br_startoff;
3000 trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); 2995 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
3001 xfs_bmbt_set_blockcount(ep, temp); 2996 xfs_bmbt_set_blockcount(ep, temp);
3002 new.br_startoff = del_endoff; 2997 new.br_startoff = del_endoff;
3003 temp2 = got_endoff - del_endoff; 2998 temp2 = got_endoff - del_endoff;
@@ -3084,9 +3079,9 @@ xfs_bmap_del_extent(
3084 } 3079 }
3085 } 3080 }
3086 } 3081 }
3087 trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 3082 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
3088 xfs_iext_insert(ip, idx + 1, 1, &new, state); 3083 xfs_iext_insert(ip, *idx + 1, 1, &new, state);
3089 ifp->if_lastex = idx + 1; 3084 ++*idx;
3090 break; 3085 break;
3091 } 3086 }
3092 /* 3087 /*
@@ -3111,9 +3106,10 @@ xfs_bmap_del_extent(
3111 * Nothing to do for disk quota accounting here. 3106 * Nothing to do for disk quota accounting here.
3112 */ 3107 */
3113 ASSERT(da_old >= da_new); 3108 ASSERT(da_old >= da_new);
3114 if (da_old > da_new) 3109 if (da_old > da_new) {
3115 xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, (int64_t)(da_old - da_new), 3110 xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS,
3116 rsvd); 3111 (int64_t)(da_old - da_new), 0);
3112 }
3117done: 3113done:
3118 *logflagsp = flags; 3114 *logflagsp = flags;
3119 return error; 3115 return error;
@@ -3496,7 +3492,7 @@ xfs_bmap_search_extents(
3496 3492
3497 if (unlikely(!(gotp->br_startblock) && (*lastxp != NULLEXTNUM) && 3493 if (unlikely(!(gotp->br_startblock) && (*lastxp != NULLEXTNUM) &&
3498 !(XFS_IS_REALTIME_INODE(ip) && fork == XFS_DATA_FORK))) { 3494 !(XFS_IS_REALTIME_INODE(ip) && fork == XFS_DATA_FORK))) {
3499 xfs_cmn_err(XFS_PTAG_FSBLOCK_ZERO, CE_ALERT, ip->i_mount, 3495 xfs_alert_tag(ip->i_mount, XFS_PTAG_FSBLOCK_ZERO,
3500 "Access to block zero in inode %llu " 3496 "Access to block zero in inode %llu "
3501 "start_block: %llx start_off: %llx " 3497 "start_block: %llx start_off: %llx "
3502 "blkcnt: %llx extent-state: %x lastx: %x\n", 3498 "blkcnt: %llx extent-state: %x lastx: %x\n",
@@ -4170,12 +4166,11 @@ xfs_bmap_read_extents(
4170 num_recs = xfs_btree_get_numrecs(block); 4166 num_recs = xfs_btree_get_numrecs(block);
4171 if (unlikely(i + num_recs > room)) { 4167 if (unlikely(i + num_recs > room)) {
4172 ASSERT(i + num_recs <= room); 4168 ASSERT(i + num_recs <= room);
4173 xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, 4169 xfs_warn(ip->i_mount,
4174 "corrupt dinode %Lu, (btree extents).", 4170 "corrupt dinode %Lu, (btree extents).",
4175 (unsigned long long) ip->i_ino); 4171 (unsigned long long) ip->i_ino);
4176 XFS_ERROR_REPORT("xfs_bmap_read_extents(1)", 4172 XFS_CORRUPTION_ERROR("xfs_bmap_read_extents(1)",
4177 XFS_ERRLEVEL_LOW, 4173 XFS_ERRLEVEL_LOW, ip->i_mount, block);
4178 ip->i_mount);
4179 goto error0; 4174 goto error0;
4180 } 4175 }
4181 XFS_WANT_CORRUPTED_GOTO( 4176 XFS_WANT_CORRUPTED_GOTO(
@@ -4481,6 +4476,16 @@ xfs_bmapi(
4481 /* Figure out the extent size, adjust alen */ 4476 /* Figure out the extent size, adjust alen */
4482 extsz = xfs_get_extsz_hint(ip); 4477 extsz = xfs_get_extsz_hint(ip);
4483 if (extsz) { 4478 if (extsz) {
4479 /*
4480 * make sure we don't exceed a single
4481 * extent length when we align the
4482 * extent by reducing length we are
4483 * going to allocate by the maximum
4484 * amount extent size aligment may
4485 * require.
4486 */
4487 alen = XFS_FILBLKS_MIN(len,
4488 MAXEXTLEN - (2 * extsz - 1));
4484 error = xfs_bmap_extsize_align(mp, 4489 error = xfs_bmap_extsize_align(mp,
4485 &got, &prev, extsz, 4490 &got, &prev, extsz,
4486 rt, eof, 4491 rt, eof,
@@ -4523,29 +4528,24 @@ xfs_bmapi(
4523 if (rt) { 4528 if (rt) {
4524 error = xfs_mod_incore_sb(mp, 4529 error = xfs_mod_incore_sb(mp,
4525 XFS_SBS_FREXTENTS, 4530 XFS_SBS_FREXTENTS,
4526 -((int64_t)extsz), (flags & 4531 -((int64_t)extsz), 0);
4527 XFS_BMAPI_RSVBLOCKS));
4528 } else { 4532 } else {
4529 error = xfs_mod_incore_sb(mp, 4533 error = xfs_icsb_modify_counters(mp,
4530 XFS_SBS_FDBLOCKS, 4534 XFS_SBS_FDBLOCKS,
4531 -((int64_t)alen), (flags & 4535 -((int64_t)alen), 0);
4532 XFS_BMAPI_RSVBLOCKS));
4533 } 4536 }
4534 if (!error) { 4537 if (!error) {
4535 error = xfs_mod_incore_sb(mp, 4538 error = xfs_icsb_modify_counters(mp,
4536 XFS_SBS_FDBLOCKS, 4539 XFS_SBS_FDBLOCKS,
4537 -((int64_t)indlen), (flags & 4540 -((int64_t)indlen), 0);
4538 XFS_BMAPI_RSVBLOCKS));
4539 if (error && rt) 4541 if (error && rt)
4540 xfs_mod_incore_sb(mp, 4542 xfs_mod_incore_sb(mp,
4541 XFS_SBS_FREXTENTS, 4543 XFS_SBS_FREXTENTS,
4542 (int64_t)extsz, (flags & 4544 (int64_t)extsz, 0);
4543 XFS_BMAPI_RSVBLOCKS));
4544 else if (error) 4545 else if (error)
4545 xfs_mod_incore_sb(mp, 4546 xfs_icsb_modify_counters(mp,
4546 XFS_SBS_FDBLOCKS, 4547 XFS_SBS_FDBLOCKS,
4547 (int64_t)alen, (flags & 4548 (int64_t)alen, 0);
4548 XFS_BMAPI_RSVBLOCKS));
4549 } 4549 }
4550 4550
4551 if (error) { 4551 if (error) {
@@ -4662,13 +4662,12 @@ xfs_bmapi(
4662 if (!wasdelay && (flags & XFS_BMAPI_PREALLOC)) 4662 if (!wasdelay && (flags & XFS_BMAPI_PREALLOC))
4663 got.br_state = XFS_EXT_UNWRITTEN; 4663 got.br_state = XFS_EXT_UNWRITTEN;
4664 } 4664 }
4665 error = xfs_bmap_add_extent(ip, lastx, &cur, &got, 4665 error = xfs_bmap_add_extent(ip, &lastx, &cur, &got,
4666 firstblock, flist, &tmp_logflags, 4666 firstblock, flist, &tmp_logflags,
4667 whichfork, (flags & XFS_BMAPI_RSVBLOCKS)); 4667 whichfork);
4668 logflags |= tmp_logflags; 4668 logflags |= tmp_logflags;
4669 if (error) 4669 if (error)
4670 goto error0; 4670 goto error0;
4671 lastx = ifp->if_lastex;
4672 ep = xfs_iext_get_ext(ifp, lastx); 4671 ep = xfs_iext_get_ext(ifp, lastx);
4673 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 4672 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
4674 xfs_bmbt_get_all(ep, &got); 4673 xfs_bmbt_get_all(ep, &got);
@@ -4744,8 +4743,12 @@ xfs_bmapi(
4744 * Check if writing previously allocated but 4743 * Check if writing previously allocated but
4745 * unwritten extents. 4744 * unwritten extents.
4746 */ 4745 */
4747 if (wr && mval->br_state == XFS_EXT_UNWRITTEN && 4746 if (wr &&
4748 ((flags & (XFS_BMAPI_PREALLOC|XFS_BMAPI_DELAY)) == 0)) { 4747 ((mval->br_state == XFS_EXT_UNWRITTEN &&
4748 ((flags & (XFS_BMAPI_PREALLOC|XFS_BMAPI_DELAY)) == 0)) ||
4749 (mval->br_state == XFS_EXT_NORM &&
4750 ((flags & (XFS_BMAPI_PREALLOC|XFS_BMAPI_CONVERT)) ==
4751 (XFS_BMAPI_PREALLOC|XFS_BMAPI_CONVERT))))) {
4749 /* 4752 /*
4750 * Modify (by adding) the state flag, if writing. 4753 * Modify (by adding) the state flag, if writing.
4751 */ 4754 */
@@ -4757,14 +4760,15 @@ xfs_bmapi(
4757 *firstblock; 4760 *firstblock;
4758 cur->bc_private.b.flist = flist; 4761 cur->bc_private.b.flist = flist;
4759 } 4762 }
4760 mval->br_state = XFS_EXT_NORM; 4763 mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN)
4761 error = xfs_bmap_add_extent(ip, lastx, &cur, mval, 4764 ? XFS_EXT_NORM
4765 : XFS_EXT_UNWRITTEN;
4766 error = xfs_bmap_add_extent(ip, &lastx, &cur, mval,
4762 firstblock, flist, &tmp_logflags, 4767 firstblock, flist, &tmp_logflags,
4763 whichfork, (flags & XFS_BMAPI_RSVBLOCKS)); 4768 whichfork);
4764 logflags |= tmp_logflags; 4769 logflags |= tmp_logflags;
4765 if (error) 4770 if (error)
4766 goto error0; 4771 goto error0;
4767 lastx = ifp->if_lastex;
4768 ep = xfs_iext_get_ext(ifp, lastx); 4772 ep = xfs_iext_get_ext(ifp, lastx);
4769 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 4773 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
4770 xfs_bmbt_get_all(ep, &got); 4774 xfs_bmbt_get_all(ep, &got);
@@ -4823,14 +4827,14 @@ xfs_bmapi(
4823 /* 4827 /*
4824 * Else go on to the next record. 4828 * Else go on to the next record.
4825 */ 4829 */
4826 ep = xfs_iext_get_ext(ifp, ++lastx);
4827 prev = got; 4830 prev = got;
4828 if (lastx >= nextents) 4831 if (++lastx < nextents) {
4829 eof = 1; 4832 ep = xfs_iext_get_ext(ifp, lastx);
4830 else
4831 xfs_bmbt_get_all(ep, &got); 4833 xfs_bmbt_get_all(ep, &got);
4834 } else {
4835 eof = 1;
4836 }
4832 } 4837 }
4833 ifp->if_lastex = lastx;
4834 *nmap = n; 4838 *nmap = n;
4835 /* 4839 /*
4836 * Transform from btree to extents, give it cur. 4840 * Transform from btree to extents, give it cur.
@@ -4939,7 +4943,6 @@ xfs_bmapi_single(
4939 ASSERT(!isnullstartblock(got.br_startblock)); 4943 ASSERT(!isnullstartblock(got.br_startblock));
4940 ASSERT(bno < got.br_startoff + got.br_blockcount); 4944 ASSERT(bno < got.br_startoff + got.br_blockcount);
4941 *fsb = got.br_startblock + (bno - got.br_startoff); 4945 *fsb = got.br_startblock + (bno - got.br_startoff);
4942 ifp->if_lastex = lastx;
4943 return 0; 4946 return 0;
4944} 4947}
4945 4948
@@ -4981,7 +4984,6 @@ xfs_bunmapi(
4981 int tmp_logflags; /* partial logging flags */ 4984 int tmp_logflags; /* partial logging flags */
4982 int wasdel; /* was a delayed alloc extent */ 4985 int wasdel; /* was a delayed alloc extent */
4983 int whichfork; /* data or attribute fork */ 4986 int whichfork; /* data or attribute fork */
4984 int rsvd; /* OK to allocate reserved blocks */
4985 xfs_fsblock_t sum; 4987 xfs_fsblock_t sum;
4986 4988
4987 trace_xfs_bunmap(ip, bno, len, flags, _RET_IP_); 4989 trace_xfs_bunmap(ip, bno, len, flags, _RET_IP_);
@@ -4999,7 +5001,7 @@ xfs_bunmapi(
4999 mp = ip->i_mount; 5001 mp = ip->i_mount;
5000 if (XFS_FORCED_SHUTDOWN(mp)) 5002 if (XFS_FORCED_SHUTDOWN(mp))
5001 return XFS_ERROR(EIO); 5003 return XFS_ERROR(EIO);
5002 rsvd = (flags & XFS_BMAPI_RSVBLOCKS) != 0; 5004
5003 ASSERT(len > 0); 5005 ASSERT(len > 0);
5004 ASSERT(nexts >= 0); 5006 ASSERT(nexts >= 0);
5005 ASSERT(ifp->if_ext_max == 5007 ASSERT(ifp->if_ext_max ==
@@ -5115,9 +5117,9 @@ xfs_bunmapi(
5115 del.br_blockcount = mod; 5117 del.br_blockcount = mod;
5116 } 5118 }
5117 del.br_state = XFS_EXT_UNWRITTEN; 5119 del.br_state = XFS_EXT_UNWRITTEN;
5118 error = xfs_bmap_add_extent(ip, lastx, &cur, &del, 5120 error = xfs_bmap_add_extent(ip, &lastx, &cur, &del,
5119 firstblock, flist, &logflags, 5121 firstblock, flist, &logflags,
5120 XFS_DATA_FORK, 0); 5122 XFS_DATA_FORK);
5121 if (error) 5123 if (error)
5122 goto error0; 5124 goto error0;
5123 goto nodelete; 5125 goto nodelete;
@@ -5143,9 +5145,12 @@ xfs_bunmapi(
5143 */ 5145 */
5144 ASSERT(bno >= del.br_blockcount); 5146 ASSERT(bno >= del.br_blockcount);
5145 bno -= del.br_blockcount; 5147 bno -= del.br_blockcount;
5146 if (bno < got.br_startoff) { 5148 if (got.br_startoff > bno) {
5147 if (--lastx >= 0) 5149 if (--lastx >= 0) {
5148 xfs_bmbt_get_all(--ep, &got); 5150 ep = xfs_iext_get_ext(ifp,
5151 lastx);
5152 xfs_bmbt_get_all(ep, &got);
5153 }
5149 } 5154 }
5150 continue; 5155 continue;
5151 } else if (del.br_state == XFS_EXT_UNWRITTEN) { 5156 } else if (del.br_state == XFS_EXT_UNWRITTEN) {
@@ -5169,18 +5174,19 @@ xfs_bunmapi(
5169 prev.br_startoff = start; 5174 prev.br_startoff = start;
5170 } 5175 }
5171 prev.br_state = XFS_EXT_UNWRITTEN; 5176 prev.br_state = XFS_EXT_UNWRITTEN;
5172 error = xfs_bmap_add_extent(ip, lastx - 1, &cur, 5177 lastx--;
5178 error = xfs_bmap_add_extent(ip, &lastx, &cur,
5173 &prev, firstblock, flist, &logflags, 5179 &prev, firstblock, flist, &logflags,
5174 XFS_DATA_FORK, 0); 5180 XFS_DATA_FORK);
5175 if (error) 5181 if (error)
5176 goto error0; 5182 goto error0;
5177 goto nodelete; 5183 goto nodelete;
5178 } else { 5184 } else {
5179 ASSERT(del.br_state == XFS_EXT_NORM); 5185 ASSERT(del.br_state == XFS_EXT_NORM);
5180 del.br_state = XFS_EXT_UNWRITTEN; 5186 del.br_state = XFS_EXT_UNWRITTEN;
5181 error = xfs_bmap_add_extent(ip, lastx, &cur, 5187 error = xfs_bmap_add_extent(ip, &lastx, &cur,
5182 &del, firstblock, flist, &logflags, 5188 &del, firstblock, flist, &logflags,
5183 XFS_DATA_FORK, 0); 5189 XFS_DATA_FORK);
5184 if (error) 5190 if (error)
5185 goto error0; 5191 goto error0;
5186 goto nodelete; 5192 goto nodelete;
@@ -5195,13 +5201,13 @@ xfs_bunmapi(
5195 rtexts = XFS_FSB_TO_B(mp, del.br_blockcount); 5201 rtexts = XFS_FSB_TO_B(mp, del.br_blockcount);
5196 do_div(rtexts, mp->m_sb.sb_rextsize); 5202 do_div(rtexts, mp->m_sb.sb_rextsize);
5197 xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS, 5203 xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS,
5198 (int64_t)rtexts, rsvd); 5204 (int64_t)rtexts, 0);
5199 (void)xfs_trans_reserve_quota_nblks(NULL, 5205 (void)xfs_trans_reserve_quota_nblks(NULL,
5200 ip, -((long)del.br_blockcount), 0, 5206 ip, -((long)del.br_blockcount), 0,
5201 XFS_QMOPT_RES_RTBLKS); 5207 XFS_QMOPT_RES_RTBLKS);
5202 } else { 5208 } else {
5203 xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, 5209 xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS,
5204 (int64_t)del.br_blockcount, rsvd); 5210 (int64_t)del.br_blockcount, 0);
5205 (void)xfs_trans_reserve_quota_nblks(NULL, 5211 (void)xfs_trans_reserve_quota_nblks(NULL,
5206 ip, -((long)del.br_blockcount), 0, 5212 ip, -((long)del.br_blockcount), 0,
5207 XFS_QMOPT_RES_REGBLKS); 5213 XFS_QMOPT_RES_REGBLKS);
@@ -5232,31 +5238,29 @@ xfs_bunmapi(
5232 error = XFS_ERROR(ENOSPC); 5238 error = XFS_ERROR(ENOSPC);
5233 goto error0; 5239 goto error0;
5234 } 5240 }
5235 error = xfs_bmap_del_extent(ip, tp, lastx, flist, cur, &del, 5241 error = xfs_bmap_del_extent(ip, tp, &lastx, flist, cur, &del,
5236 &tmp_logflags, whichfork, rsvd); 5242 &tmp_logflags, whichfork);
5237 logflags |= tmp_logflags; 5243 logflags |= tmp_logflags;
5238 if (error) 5244 if (error)
5239 goto error0; 5245 goto error0;
5240 bno = del.br_startoff - 1; 5246 bno = del.br_startoff - 1;
5241nodelete: 5247nodelete:
5242 lastx = ifp->if_lastex;
5243 /* 5248 /*
5244 * If not done go on to the next (previous) record. 5249 * If not done go on to the next (previous) record.
5245 * Reset ep in case the extents array was re-alloced.
5246 */ 5250 */
5247 ep = xfs_iext_get_ext(ifp, lastx);
5248 if (bno != (xfs_fileoff_t)-1 && bno >= start) { 5251 if (bno != (xfs_fileoff_t)-1 && bno >= start) {
5249 if (lastx >= XFS_IFORK_NEXTENTS(ip, whichfork) || 5252 if (lastx >= 0) {
5250 xfs_bmbt_get_startoff(ep) > bno) { 5253 ep = xfs_iext_get_ext(ifp, lastx);
5251 if (--lastx >= 0) 5254 if (xfs_bmbt_get_startoff(ep) > bno) {
5252 ep = xfs_iext_get_ext(ifp, lastx); 5255 if (--lastx >= 0)
5253 } 5256 ep = xfs_iext_get_ext(ifp,
5254 if (lastx >= 0) 5257 lastx);
5258 }
5255 xfs_bmbt_get_all(ep, &got); 5259 xfs_bmbt_get_all(ep, &got);
5260 }
5256 extno++; 5261 extno++;
5257 } 5262 }
5258 } 5263 }
5259 ifp->if_lastex = lastx;
5260 *done = bno == (xfs_fileoff_t)-1 || bno < start || lastx < 0; 5264 *done = bno == (xfs_fileoff_t)-1 || bno < start || lastx < 0;
5261 ASSERT(ifp->if_ext_max == 5265 ASSERT(ifp->if_ext_max ==
5262 XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t)); 5266 XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
@@ -5461,8 +5465,13 @@ xfs_getbmap(
5461 if (error) 5465 if (error)
5462 goto out_unlock_iolock; 5466 goto out_unlock_iolock;
5463 } 5467 }
5464 5468 /*
5465 ASSERT(ip->i_delayed_blks == 0); 5469 * even after flushing the inode, there can still be delalloc
5470 * blocks on the inode beyond EOF due to speculative
5471 * preallocation. These are not removed until the release
5472 * function is called or the inode is inactivated. Hence we
5473 * cannot assert here that ip->i_delayed_blks == 0.
5474 */
5466 } 5475 }
5467 5476
5468 lock = xfs_ilock_map_shared(ip); 5477 lock = xfs_ilock_map_shared(ip);
@@ -5728,7 +5737,7 @@ xfs_check_block(
5728 else 5737 else
5729 thispa = XFS_BMBT_PTR_ADDR(mp, block, j, dmxr); 5738 thispa = XFS_BMBT_PTR_ADDR(mp, block, j, dmxr);
5730 if (*thispa == *pp) { 5739 if (*thispa == *pp) {
5731 cmn_err(CE_WARN, "%s: thispa(%d) == pp(%d) %Ld", 5740 xfs_warn(mp, "%s: thispa(%d) == pp(%d) %Ld",
5732 __func__, j, i, 5741 __func__, j, i,
5733 (unsigned long long)be64_to_cpu(*thispa)); 5742 (unsigned long long)be64_to_cpu(*thispa));
5734 panic("%s: ptrs are equal in node\n", 5743 panic("%s: ptrs are equal in node\n",
@@ -5893,11 +5902,11 @@ xfs_bmap_check_leaf_extents(
5893 return; 5902 return;
5894 5903
5895error0: 5904error0:
5896 cmn_err(CE_WARN, "%s: at error0", __func__); 5905 xfs_warn(mp, "%s: at error0", __func__);
5897 if (bp_release) 5906 if (bp_release)
5898 xfs_trans_brelse(NULL, bp); 5907 xfs_trans_brelse(NULL, bp);
5899error_norelse: 5908error_norelse:
5900 cmn_err(CE_WARN, "%s: BAD after btree leaves for %d extents", 5909 xfs_warn(mp, "%s: BAD after btree leaves for %d extents",
5901 __func__, i); 5910 __func__, i);
5902 panic("%s: CORRUPTED BTREE OR SOMETHING", __func__); 5911 panic("%s: CORRUPTED BTREE OR SOMETHING", __func__);
5903 return; 5912 return;
@@ -6060,3 +6069,79 @@ xfs_bmap_disk_count_leaves(
6060 *count += xfs_bmbt_disk_get_blockcount(frp); 6069 *count += xfs_bmbt_disk_get_blockcount(frp);
6061 } 6070 }
6062} 6071}
6072
6073/*
6074 * dead simple method of punching delalyed allocation blocks from a range in
6075 * the inode. Walks a block at a time so will be slow, but is only executed in
6076 * rare error cases so the overhead is not critical. This will alays punch out
6077 * both the start and end blocks, even if the ranges only partially overlap
6078 * them, so it is up to the caller to ensure that partial blocks are not
6079 * passed in.
6080 */
6081int
6082xfs_bmap_punch_delalloc_range(
6083 struct xfs_inode *ip,
6084 xfs_fileoff_t start_fsb,
6085 xfs_fileoff_t length)
6086{
6087 xfs_fileoff_t remaining = length;
6088 int error = 0;
6089
6090 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
6091
6092 do {
6093 int done;
6094 xfs_bmbt_irec_t imap;
6095 int nimaps = 1;
6096 xfs_fsblock_t firstblock;
6097 xfs_bmap_free_t flist;
6098
6099 /*
6100 * Map the range first and check that it is a delalloc extent
6101 * before trying to unmap the range. Otherwise we will be
6102 * trying to remove a real extent (which requires a
6103 * transaction) or a hole, which is probably a bad idea...
6104 */
6105 error = xfs_bmapi(NULL, ip, start_fsb, 1,
6106 XFS_BMAPI_ENTIRE, NULL, 0, &imap,
6107 &nimaps, NULL);
6108
6109 if (error) {
6110 /* something screwed, just bail */
6111 if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) {
6112 xfs_alert(ip->i_mount,
6113 "Failed delalloc mapping lookup ino %lld fsb %lld.",
6114 ip->i_ino, start_fsb);
6115 }
6116 break;
6117 }
6118 if (!nimaps) {
6119 /* nothing there */
6120 goto next_block;
6121 }
6122 if (imap.br_startblock != DELAYSTARTBLOCK) {
6123 /* been converted, ignore */
6124 goto next_block;
6125 }
6126 WARN_ON(imap.br_blockcount == 0);
6127
6128 /*
6129 * Note: while we initialise the firstblock/flist pair, they
6130 * should never be used because blocks should never be
6131 * allocated or freed for a delalloc extent and hence we need
6132 * don't cancel or finish them after the xfs_bunmapi() call.
6133 */
6134 xfs_bmap_init(&flist, &firstblock);
6135 error = xfs_bunmapi(NULL, ip, start_fsb, 1, 0, 1, &firstblock,
6136 &flist, &done);
6137 if (error)
6138 break;
6139
6140 ASSERT(!flist.xbf_count && !flist.xbf_first);
6141next_block:
6142 start_fsb++;
6143 remaining--;
6144 } while(remaining > 0);
6145
6146 return error;
6147}