diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /fs/xfs/xfs_bmap.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (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.c | 749 |
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 | */ | ||
95 | STATIC int /* error */ | ||
96 | xfs_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 | */ |
111 | STATIC int /* error */ | 95 | STATIC int /* error */ |
112 | xfs_bmap_add_extent_delay_real( | 96 | xfs_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( | |||
127 | STATIC int /* error */ | 110 | STATIC int /* error */ |
128 | xfs_bmap_add_extent_hole_delay( | 111 | xfs_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( | |||
139 | STATIC int /* error */ | 121 | STATIC int /* error */ |
140 | xfs_bmap_add_extent_hole_real( | 122 | xfs_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( | |||
152 | STATIC int /* error */ | 134 | STATIC int /* error */ |
153 | xfs_bmap_add_extent_unwritten_real( | 135 | xfs_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 | */ | ||
186 | STATIC int /* error */ | ||
187 | xfs_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( | |||
474 | STATIC int /* error */ | 440 | STATIC int /* error */ |
475 | xfs_bmap_add_extent( | 441 | xfs_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: | |||
640 | STATIC int /* error */ | 605 | STATIC int /* error */ |
641 | xfs_bmap_add_extent_delay_real( | 606 | xfs_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: | |||
1141 | STATIC int /* error */ | 1131 | STATIC int /* error */ |
1142 | xfs_bmap_add_extent_unwritten_real( | 1132 | xfs_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: | |||
1630 | STATIC int /* error */ | 1625 | STATIC int /* error */ |
1631 | xfs_bmap_add_extent_hole_delay( | 1626 | xfs_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( | |||
1783 | STATIC int /* error */ | 1773 | STATIC int /* error */ |
1784 | xfs_bmap_add_extent_hole_real( | 1774 | xfs_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 */ | |||
2804 | xfs_bmap_del_extent( | 2801 | xfs_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 | } | ||
3117 | done: | 3113 | done: |
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; |
5241 | nodelete: | 5247 | nodelete: |
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 | ||
5895 | error0: | 5904 | error0: |
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); |
5899 | error_norelse: | 5908 | error_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 | */ | ||
6081 | int | ||
6082 | xfs_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); | ||
6141 | next_block: | ||
6142 | start_fsb++; | ||
6143 | remaining--; | ||
6144 | } while(remaining > 0); | ||
6145 | |||
6146 | return error; | ||
6147 | } | ||