aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_bmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_bmap.c')
-rw-r--r--fs/xfs/xfs_bmap.c2531
1 files changed, 1261 insertions, 1270 deletions
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 452a291383ab..c68baeb0974a 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -50,17 +50,22 @@
50#include "xfs_trace.h" 50#include "xfs_trace.h"
51 51
52 52
53#ifdef DEBUG
54STATIC void
55xfs_bmap_check_leaf_extents(xfs_btree_cur_t *cur, xfs_inode_t *ip, int whichfork);
56#endif
57
58kmem_zone_t *xfs_bmap_free_item_zone; 53kmem_zone_t *xfs_bmap_free_item_zone;
59 54
60/* 55/*
61 * Prototypes for internal bmap routines. 56 * Prototypes for internal bmap routines.
62 */ 57 */
63 58
59#ifdef DEBUG
60STATIC void
61xfs_bmap_check_leaf_extents(
62 struct xfs_btree_cur *cur,
63 struct xfs_inode *ip,
64 int whichfork);
65#else
66#define xfs_bmap_check_leaf_extents(cur, ip, whichfork) do { } while (0)
67#endif
68
64 69
65/* 70/*
66 * Called from xfs_bmap_add_attrfork to handle extents format files. 71 * Called from xfs_bmap_add_attrfork to handle extents format files.
@@ -85,58 +90,6 @@ xfs_bmap_add_attrfork_local(
85 int *flags); /* inode logging flags */ 90 int *flags); /* inode logging flags */
86 91
87/* 92/*
88 * Called by xfs_bmap_add_extent to handle cases converting a delayed
89 * allocation to a real allocation.
90 */
91STATIC int /* error */
92xfs_bmap_add_extent_delay_real(
93 struct xfs_trans *tp, /* transaction pointer */
94 xfs_inode_t *ip, /* incore inode pointer */
95 xfs_extnum_t *idx, /* extent number to update/insert */
96 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
97 xfs_bmbt_irec_t *new, /* new data to add to file extents */
98 xfs_filblks_t *dnew, /* new delayed-alloc indirect blocks */
99 xfs_fsblock_t *first, /* pointer to firstblock variable */
100 xfs_bmap_free_t *flist, /* list of extents to be freed */
101 int *logflagsp); /* inode logging flags */
102
103/*
104 * Called by xfs_bmap_add_extent to handle cases converting a hole
105 * to a delayed allocation.
106 */
107STATIC int /* error */
108xfs_bmap_add_extent_hole_delay(
109 xfs_inode_t *ip, /* incore inode pointer */
110 xfs_extnum_t *idx, /* extent number to update/insert */
111 xfs_bmbt_irec_t *new, /* new data to add to file extents */
112 int *logflagsp); /* inode logging flags */
113
114/*
115 * Called by xfs_bmap_add_extent to handle cases converting a hole
116 * to a real allocation.
117 */
118STATIC int /* error */
119xfs_bmap_add_extent_hole_real(
120 xfs_inode_t *ip, /* incore inode pointer */
121 xfs_extnum_t *idx, /* extent number to update/insert */
122 xfs_btree_cur_t *cur, /* if null, not a btree */
123 xfs_bmbt_irec_t *new, /* new data to add to file extents */
124 int *logflagsp, /* inode logging flags */
125 int whichfork); /* data or attr fork */
126
127/*
128 * Called by xfs_bmap_add_extent to handle cases converting an unwritten
129 * allocation to a real allocation or vice versa.
130 */
131STATIC int /* error */
132xfs_bmap_add_extent_unwritten_real(
133 xfs_inode_t *ip, /* incore inode pointer */
134 xfs_extnum_t *idx, /* extent number to update/insert */
135 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
136 xfs_bmbt_irec_t *new, /* new data to add to file extents */
137 int *logflagsp); /* inode logging flags */
138
139/*
140 * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file. 93 * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file.
141 * It figures out where to ask the underlying allocator to put the new extent. 94 * It figures out where to ask the underlying allocator to put the new extent.
142 */ 95 */
@@ -215,19 +168,6 @@ xfs_bmap_search_extents(
215 xfs_bmbt_irec_t *prevp); /* out: previous extent entry found */ 168 xfs_bmbt_irec_t *prevp); /* out: previous extent entry found */
216 169
217/* 170/*
218 * Check the last inode extent to determine whether this allocation will result
219 * in blocks being allocated at the end of the file. When we allocate new data
220 * blocks at the end of the file which do not start at the previous data block,
221 * we will try to align the new blocks at stripe unit boundaries.
222 */
223STATIC int /* error */
224xfs_bmap_isaeof(
225 xfs_inode_t *ip, /* incore inode pointer */
226 xfs_fileoff_t off, /* file offset in fsblocks */
227 int whichfork, /* data or attribute fork */
228 char *aeof); /* return value */
229
230/*
231 * Compute the worst-case number of indirect blocks that will be used 171 * Compute the worst-case number of indirect blocks that will be used
232 * for ip's delayed extent of length "len". 172 * for ip's delayed extent of length "len".
233 */ 173 */
@@ -431,188 +371,13 @@ xfs_bmap_add_attrfork_local(
431} 371}
432 372
433/* 373/*
434 * Called by xfs_bmapi to update file extent records and the btree 374 * Convert a delayed allocation to a real allocation.
435 * after allocating space (or doing a delayed allocation).
436 */
437STATIC int /* error */
438xfs_bmap_add_extent(
439 struct xfs_trans *tp, /* transaction pointer */
440 xfs_inode_t *ip, /* incore inode pointer */
441 xfs_extnum_t *idx, /* extent number to update/insert */
442 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
443 xfs_bmbt_irec_t *new, /* new data to add to file extents */
444 xfs_fsblock_t *first, /* pointer to firstblock variable */
445 xfs_bmap_free_t *flist, /* list of extents to be freed */
446 int *logflagsp, /* inode logging flags */
447 int whichfork) /* data or attr fork */
448{
449 xfs_btree_cur_t *cur; /* btree cursor or null */
450 xfs_filblks_t da_new; /* new count del alloc blocks used */
451 xfs_filblks_t da_old; /* old count del alloc blocks used */
452 int error; /* error return value */
453 xfs_ifork_t *ifp; /* inode fork ptr */
454 int logflags; /* returned value */
455 xfs_extnum_t nextents; /* number of extents in file now */
456
457 XFS_STATS_INC(xs_add_exlist);
458
459 cur = *curp;
460 ifp = XFS_IFORK_PTR(ip, whichfork);
461 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
462 da_old = da_new = 0;
463 error = 0;
464
465 ASSERT(*idx >= 0);
466 ASSERT(*idx <= nextents);
467
468 /*
469 * This is the first extent added to a new/empty file.
470 * Special case this one, so other routines get to assume there are
471 * already extents in the list.
472 */
473 if (nextents == 0) {
474 xfs_iext_insert(ip, *idx, 1, new,
475 whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0);
476
477 ASSERT(cur == NULL);
478
479 if (!isnullstartblock(new->br_startblock)) {
480 XFS_IFORK_NEXT_SET(ip, whichfork, 1);
481 logflags = XFS_ILOG_CORE | xfs_ilog_fext(whichfork);
482 } else
483 logflags = 0;
484 }
485 /*
486 * Any kind of new delayed allocation goes here.
487 */
488 else if (isnullstartblock(new->br_startblock)) {
489 if (cur)
490 ASSERT((cur->bc_private.b.flags &
491 XFS_BTCUR_BPRV_WASDEL) == 0);
492 error = xfs_bmap_add_extent_hole_delay(ip, idx, new,
493 &logflags);
494 }
495 /*
496 * Real allocation off the end of the file.
497 */
498 else if (*idx == nextents) {
499 if (cur)
500 ASSERT((cur->bc_private.b.flags &
501 XFS_BTCUR_BPRV_WASDEL) == 0);
502 error = xfs_bmap_add_extent_hole_real(ip, idx, cur, new,
503 &logflags, whichfork);
504 } else {
505 xfs_bmbt_irec_t prev; /* old extent at offset idx */
506
507 /*
508 * Get the record referred to by idx.
509 */
510 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx), &prev);
511 /*
512 * If it's a real allocation record, and the new allocation ends
513 * after the start of the referred to record, then we're filling
514 * in a delayed or unwritten allocation with a real one, or
515 * converting real back to unwritten.
516 */
517 if (!isnullstartblock(new->br_startblock) &&
518 new->br_startoff + new->br_blockcount > prev.br_startoff) {
519 if (prev.br_state != XFS_EXT_UNWRITTEN &&
520 isnullstartblock(prev.br_startblock)) {
521 da_old = startblockval(prev.br_startblock);
522 if (cur)
523 ASSERT(cur->bc_private.b.flags &
524 XFS_BTCUR_BPRV_WASDEL);
525 error = xfs_bmap_add_extent_delay_real(tp, ip,
526 idx, &cur, new, &da_new,
527 first, flist, &logflags);
528 } else {
529 ASSERT(new->br_state == XFS_EXT_NORM ||
530 new->br_state == XFS_EXT_UNWRITTEN);
531
532 error = xfs_bmap_add_extent_unwritten_real(ip,
533 idx, &cur, new, &logflags);
534 if (error)
535 goto done;
536 }
537 }
538 /*
539 * Otherwise we're filling in a hole with an allocation.
540 */
541 else {
542 if (cur)
543 ASSERT((cur->bc_private.b.flags &
544 XFS_BTCUR_BPRV_WASDEL) == 0);
545 error = xfs_bmap_add_extent_hole_real(ip, idx, cur,
546 new, &logflags, whichfork);
547 }
548 }
549
550 if (error)
551 goto done;
552 ASSERT(*curp == cur || *curp == NULL);
553
554 /*
555 * Convert to a btree if necessary.
556 */
557 if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS &&
558 XFS_IFORK_NEXTENTS(ip, whichfork) > ifp->if_ext_max) {
559 int tmp_logflags; /* partial log flag return val */
560
561 ASSERT(cur == NULL);
562 error = xfs_bmap_extents_to_btree(tp, ip, first,
563 flist, &cur, da_old > 0, &tmp_logflags, whichfork);
564 logflags |= tmp_logflags;
565 if (error)
566 goto done;
567 }
568 /*
569 * Adjust for changes in reserved delayed indirect blocks.
570 * Nothing to do for disk quotas here.
571 */
572 if (da_old || da_new) {
573 xfs_filblks_t nblks;
574
575 nblks = da_new;
576 if (cur)
577 nblks += cur->bc_private.b.allocated;
578 ASSERT(nblks <= da_old);
579 if (nblks < da_old)
580 xfs_icsb_modify_counters(ip->i_mount, XFS_SBS_FDBLOCKS,
581 (int64_t)(da_old - nblks), 0);
582 }
583 /*
584 * Clear out the allocated field, done with it now in any case.
585 */
586 if (cur) {
587 cur->bc_private.b.allocated = 0;
588 *curp = cur;
589 }
590done:
591#ifdef DEBUG
592 if (!error)
593 xfs_bmap_check_leaf_extents(*curp, ip, whichfork);
594#endif
595 *logflagsp = logflags;
596 return error;
597}
598
599/*
600 * Called by xfs_bmap_add_extent to handle cases converting a delayed
601 * allocation to a real allocation.
602 */ 375 */
603STATIC int /* error */ 376STATIC int /* error */
604xfs_bmap_add_extent_delay_real( 377xfs_bmap_add_extent_delay_real(
605 struct xfs_trans *tp, /* transaction pointer */ 378 struct xfs_bmalloca *bma)
606 xfs_inode_t *ip, /* incore inode pointer */
607 xfs_extnum_t *idx, /* extent number to update/insert */
608 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
609 xfs_bmbt_irec_t *new, /* new data to add to file extents */
610 xfs_filblks_t *dnew, /* new delayed-alloc indirect blocks */
611 xfs_fsblock_t *first, /* pointer to firstblock variable */
612 xfs_bmap_free_t *flist, /* list of extents to be freed */
613 int *logflagsp) /* inode logging flags */
614{ 379{
615 xfs_btree_cur_t *cur; /* btree cursor */ 380 struct xfs_bmbt_irec *new = &bma->got;
616 int diff; /* temp value */ 381 int diff; /* temp value */
617 xfs_bmbt_rec_host_t *ep; /* extent entry for idx */ 382 xfs_bmbt_rec_host_t *ep; /* extent entry for idx */
618 int error; /* error return value */ 383 int error; /* error return value */
@@ -623,10 +388,22 @@ xfs_bmap_add_extent_delay_real(
623 /* left is 0, right is 1, prev is 2 */ 388 /* left is 0, right is 1, prev is 2 */
624 int rval=0; /* return value (logging flags) */ 389 int rval=0; /* return value (logging flags) */
625 int state = 0;/* state bits, accessed thru macros */ 390 int state = 0;/* state bits, accessed thru macros */
626 xfs_filblks_t temp=0; /* value for dnew calculations */ 391 xfs_filblks_t da_new; /* new count del alloc blocks used */
627 xfs_filblks_t temp2=0;/* value for dnew calculations */ 392 xfs_filblks_t da_old; /* old count del alloc blocks used */
393 xfs_filblks_t temp=0; /* value for da_new calculations */
394 xfs_filblks_t temp2=0;/* value for da_new calculations */
628 int tmp_rval; /* partial logging flags */ 395 int tmp_rval; /* partial logging flags */
629 396
397 ifp = XFS_IFORK_PTR(bma->ip, XFS_DATA_FORK);
398
399 ASSERT(bma->idx >= 0);
400 ASSERT(bma->idx <= ifp->if_bytes / sizeof(struct xfs_bmbt_rec));
401 ASSERT(!isnullstartblock(new->br_startblock));
402 ASSERT(!bma->cur ||
403 (bma->cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL));
404
405 XFS_STATS_INC(xs_add_exlist);
406
630#define LEFT r[0] 407#define LEFT r[0]
631#define RIGHT r[1] 408#define RIGHT r[1]
632#define PREV r[2] 409#define PREV r[2]
@@ -634,14 +411,15 @@ xfs_bmap_add_extent_delay_real(
634 /* 411 /*
635 * Set up a bunch of variables to make the tests simpler. 412 * Set up a bunch of variables to make the tests simpler.
636 */ 413 */
637 cur = *curp; 414 ep = xfs_iext_get_ext(ifp, bma->idx);
638 ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
639 ep = xfs_iext_get_ext(ifp, *idx);
640 xfs_bmbt_get_all(ep, &PREV); 415 xfs_bmbt_get_all(ep, &PREV);
641 new_endoff = new->br_startoff + new->br_blockcount; 416 new_endoff = new->br_startoff + new->br_blockcount;
642 ASSERT(PREV.br_startoff <= new->br_startoff); 417 ASSERT(PREV.br_startoff <= new->br_startoff);
643 ASSERT(PREV.br_startoff + PREV.br_blockcount >= new_endoff); 418 ASSERT(PREV.br_startoff + PREV.br_blockcount >= new_endoff);
644 419
420 da_old = startblockval(PREV.br_startblock);
421 da_new = 0;
422
645 /* 423 /*
646 * Set flags determining what part of the previous delayed allocation 424 * Set flags determining what part of the previous delayed allocation
647 * extent is being replaced by a real allocation. 425 * extent is being replaced by a real allocation.
@@ -655,9 +433,9 @@ xfs_bmap_add_extent_delay_real(
655 * Check and set flags if this segment has a left neighbor. 433 * Check and set flags if this segment has a left neighbor.
656 * Don't set contiguous if the combined extent would be too large. 434 * Don't set contiguous if the combined extent would be too large.
657 */ 435 */
658 if (*idx > 0) { 436 if (bma->idx > 0) {
659 state |= BMAP_LEFT_VALID; 437 state |= BMAP_LEFT_VALID;
660 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx - 1), &LEFT); 438 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma->idx - 1), &LEFT);
661 439
662 if (isnullstartblock(LEFT.br_startblock)) 440 if (isnullstartblock(LEFT.br_startblock))
663 state |= BMAP_LEFT_DELAY; 441 state |= BMAP_LEFT_DELAY;
@@ -675,9 +453,9 @@ xfs_bmap_add_extent_delay_real(
675 * Don't set contiguous if the combined extent would be too large. 453 * Don't set contiguous if the combined extent would be too large.
676 * Also check for all-three-contiguous being too large. 454 * Also check for all-three-contiguous being too large.
677 */ 455 */
678 if (*idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1) { 456 if (bma->idx < bma->ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1) {
679 state |= BMAP_RIGHT_VALID; 457 state |= BMAP_RIGHT_VALID;
680 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx + 1), &RIGHT); 458 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma->idx + 1), &RIGHT);
681 459
682 if (isnullstartblock(RIGHT.br_startblock)) 460 if (isnullstartblock(RIGHT.br_startblock))
683 state |= BMAP_RIGHT_DELAY; 461 state |= BMAP_RIGHT_DELAY;
@@ -708,38 +486,41 @@ xfs_bmap_add_extent_delay_real(
708 * Filling in all of a previously delayed allocation extent. 486 * Filling in all of a previously delayed allocation extent.
709 * The left and right neighbors are both contiguous with new. 487 * The left and right neighbors are both contiguous with new.
710 */ 488 */
711 --*idx; 489 bma->idx--;
712 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 490 trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_);
713 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx), 491 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, bma->idx),
714 LEFT.br_blockcount + PREV.br_blockcount + 492 LEFT.br_blockcount + PREV.br_blockcount +
715 RIGHT.br_blockcount); 493 RIGHT.br_blockcount);
716 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 494 trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_);
717 495
718 xfs_iext_remove(ip, *idx + 1, 2, state); 496 xfs_iext_remove(bma->ip, bma->idx + 1, 2, state);
719 ip->i_d.di_nextents--; 497 bma->ip->i_d.di_nextents--;
720 if (cur == NULL) 498 if (bma->cur == NULL)
721 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 499 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
722 else { 500 else {
723 rval = XFS_ILOG_CORE; 501 rval = XFS_ILOG_CORE;
724 if ((error = xfs_bmbt_lookup_eq(cur, RIGHT.br_startoff, 502 error = xfs_bmbt_lookup_eq(bma->cur, RIGHT.br_startoff,
725 RIGHT.br_startblock, 503 RIGHT.br_startblock,
726 RIGHT.br_blockcount, &i))) 504 RIGHT.br_blockcount, &i);
505 if (error)
727 goto done; 506 goto done;
728 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 507 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
729 if ((error = xfs_btree_delete(cur, &i))) 508 error = xfs_btree_delete(bma->cur, &i);
509 if (error)
730 goto done; 510 goto done;
731 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 511 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
732 if ((error = xfs_btree_decrement(cur, 0, &i))) 512 error = xfs_btree_decrement(bma->cur, 0, &i);
513 if (error)
733 goto done; 514 goto done;
734 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 515 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
735 if ((error = xfs_bmbt_update(cur, LEFT.br_startoff, 516 error = xfs_bmbt_update(bma->cur, LEFT.br_startoff,
736 LEFT.br_startblock, 517 LEFT.br_startblock,
737 LEFT.br_blockcount + 518 LEFT.br_blockcount +
738 PREV.br_blockcount + 519 PREV.br_blockcount +
739 RIGHT.br_blockcount, LEFT.br_state))) 520 RIGHT.br_blockcount, LEFT.br_state);
521 if (error)
740 goto done; 522 goto done;
741 } 523 }
742 *dnew = 0;
743 break; 524 break;
744 525
745 case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG: 526 case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG:
@@ -747,30 +528,31 @@ xfs_bmap_add_extent_delay_real(
747 * Filling in all of a previously delayed allocation extent. 528 * Filling in all of a previously delayed allocation extent.
748 * The left neighbor is contiguous, the right is not. 529 * The left neighbor is contiguous, the right is not.
749 */ 530 */
750 --*idx; 531 bma->idx--;
751 532
752 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 533 trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_);
753 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx), 534 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, bma->idx),
754 LEFT.br_blockcount + PREV.br_blockcount); 535 LEFT.br_blockcount + PREV.br_blockcount);
755 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 536 trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_);
756 537
757 xfs_iext_remove(ip, *idx + 1, 1, state); 538 xfs_iext_remove(bma->ip, bma->idx + 1, 1, state);
758 if (cur == NULL) 539 if (bma->cur == NULL)
759 rval = XFS_ILOG_DEXT; 540 rval = XFS_ILOG_DEXT;
760 else { 541 else {
761 rval = 0; 542 rval = 0;
762 if ((error = xfs_bmbt_lookup_eq(cur, LEFT.br_startoff, 543 error = xfs_bmbt_lookup_eq(bma->cur, LEFT.br_startoff,
763 LEFT.br_startblock, LEFT.br_blockcount, 544 LEFT.br_startblock, LEFT.br_blockcount,
764 &i))) 545 &i);
546 if (error)
765 goto done; 547 goto done;
766 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 548 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
767 if ((error = xfs_bmbt_update(cur, LEFT.br_startoff, 549 error = xfs_bmbt_update(bma->cur, LEFT.br_startoff,
768 LEFT.br_startblock, 550 LEFT.br_startblock,
769 LEFT.br_blockcount + 551 LEFT.br_blockcount +
770 PREV.br_blockcount, LEFT.br_state))) 552 PREV.br_blockcount, LEFT.br_state);
553 if (error)
771 goto done; 554 goto done;
772 } 555 }
773 *dnew = 0;
774 break; 556 break;
775 557
776 case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: 558 case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG:
@@ -778,30 +560,30 @@ xfs_bmap_add_extent_delay_real(
778 * Filling in all of a previously delayed allocation extent. 560 * Filling in all of a previously delayed allocation extent.
779 * The right neighbor is contiguous, the left is not. 561 * The right neighbor is contiguous, the left is not.
780 */ 562 */
781 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 563 trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_);
782 xfs_bmbt_set_startblock(ep, new->br_startblock); 564 xfs_bmbt_set_startblock(ep, new->br_startblock);
783 xfs_bmbt_set_blockcount(ep, 565 xfs_bmbt_set_blockcount(ep,
784 PREV.br_blockcount + RIGHT.br_blockcount); 566 PREV.br_blockcount + RIGHT.br_blockcount);
785 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 567 trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_);
786 568
787 xfs_iext_remove(ip, *idx + 1, 1, state); 569 xfs_iext_remove(bma->ip, bma->idx + 1, 1, state);
788 if (cur == NULL) 570 if (bma->cur == NULL)
789 rval = XFS_ILOG_DEXT; 571 rval = XFS_ILOG_DEXT;
790 else { 572 else {
791 rval = 0; 573 rval = 0;
792 if ((error = xfs_bmbt_lookup_eq(cur, RIGHT.br_startoff, 574 error = xfs_bmbt_lookup_eq(bma->cur, RIGHT.br_startoff,
793 RIGHT.br_startblock, 575 RIGHT.br_startblock,
794 RIGHT.br_blockcount, &i))) 576 RIGHT.br_blockcount, &i);
577 if (error)
795 goto done; 578 goto done;
796 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 579 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
797 if ((error = xfs_bmbt_update(cur, PREV.br_startoff, 580 error = xfs_bmbt_update(bma->cur, PREV.br_startoff,
798 new->br_startblock, 581 new->br_startblock,
799 PREV.br_blockcount + 582 PREV.br_blockcount +
800 RIGHT.br_blockcount, PREV.br_state))) 583 RIGHT.br_blockcount, PREV.br_state);
584 if (error)
801 goto done; 585 goto done;
802 } 586 }
803
804 *dnew = 0;
805 break; 587 break;
806 588
807 case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING: 589 case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING:
@@ -810,27 +592,27 @@ xfs_bmap_add_extent_delay_real(
810 * Neither the left nor right neighbors are contiguous with 592 * Neither the left nor right neighbors are contiguous with
811 * the new one. 593 * the new one.
812 */ 594 */
813 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 595 trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_);
814 xfs_bmbt_set_startblock(ep, new->br_startblock); 596 xfs_bmbt_set_startblock(ep, new->br_startblock);
815 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 597 trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_);
816 598
817 ip->i_d.di_nextents++; 599 bma->ip->i_d.di_nextents++;
818 if (cur == NULL) 600 if (bma->cur == NULL)
819 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 601 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
820 else { 602 else {
821 rval = XFS_ILOG_CORE; 603 rval = XFS_ILOG_CORE;
822 if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, 604 error = xfs_bmbt_lookup_eq(bma->cur, new->br_startoff,
823 new->br_startblock, new->br_blockcount, 605 new->br_startblock, new->br_blockcount,
824 &i))) 606 &i);
607 if (error)
825 goto done; 608 goto done;
826 XFS_WANT_CORRUPTED_GOTO(i == 0, done); 609 XFS_WANT_CORRUPTED_GOTO(i == 0, done);
827 cur->bc_rec.b.br_state = XFS_EXT_NORM; 610 bma->cur->bc_rec.b.br_state = XFS_EXT_NORM;
828 if ((error = xfs_btree_insert(cur, &i))) 611 error = xfs_btree_insert(bma->cur, &i);
612 if (error)
829 goto done; 613 goto done;
830 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 614 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
831 } 615 }
832
833 *dnew = 0;
834 break; 616 break;
835 617
836 case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG: 618 case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG:
@@ -838,39 +620,40 @@ xfs_bmap_add_extent_delay_real(
838 * Filling in the first part of a previous delayed allocation. 620 * Filling in the first part of a previous delayed allocation.
839 * The left neighbor is contiguous. 621 * The left neighbor is contiguous.
840 */ 622 */
841 trace_xfs_bmap_pre_update(ip, *idx - 1, state, _THIS_IP_); 623 trace_xfs_bmap_pre_update(bma->ip, bma->idx - 1, state, _THIS_IP_);
842 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx - 1), 624 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, bma->idx - 1),
843 LEFT.br_blockcount + new->br_blockcount); 625 LEFT.br_blockcount + new->br_blockcount);
844 xfs_bmbt_set_startoff(ep, 626 xfs_bmbt_set_startoff(ep,
845 PREV.br_startoff + new->br_blockcount); 627 PREV.br_startoff + new->br_blockcount);
846 trace_xfs_bmap_post_update(ip, *idx - 1, state, _THIS_IP_); 628 trace_xfs_bmap_post_update(bma->ip, bma->idx - 1, state, _THIS_IP_);
847 629
848 temp = PREV.br_blockcount - new->br_blockcount; 630 temp = PREV.br_blockcount - new->br_blockcount;
849 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 631 trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_);
850 xfs_bmbt_set_blockcount(ep, temp); 632 xfs_bmbt_set_blockcount(ep, temp);
851 if (cur == NULL) 633 if (bma->cur == NULL)
852 rval = XFS_ILOG_DEXT; 634 rval = XFS_ILOG_DEXT;
853 else { 635 else {
854 rval = 0; 636 rval = 0;
855 if ((error = xfs_bmbt_lookup_eq(cur, LEFT.br_startoff, 637 error = xfs_bmbt_lookup_eq(bma->cur, LEFT.br_startoff,
856 LEFT.br_startblock, LEFT.br_blockcount, 638 LEFT.br_startblock, LEFT.br_blockcount,
857 &i))) 639 &i);
640 if (error)
858 goto done; 641 goto done;
859 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 642 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
860 if ((error = xfs_bmbt_update(cur, LEFT.br_startoff, 643 error = xfs_bmbt_update(bma->cur, LEFT.br_startoff,
861 LEFT.br_startblock, 644 LEFT.br_startblock,
862 LEFT.br_blockcount + 645 LEFT.br_blockcount +
863 new->br_blockcount, 646 new->br_blockcount,
864 LEFT.br_state))) 647 LEFT.br_state);
648 if (error)
865 goto done; 649 goto done;
866 } 650 }
867 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), 651 da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(bma->ip, temp),
868 startblockval(PREV.br_startblock)); 652 startblockval(PREV.br_startblock));
869 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); 653 xfs_bmbt_set_startblock(ep, nullstartblock(da_new));
870 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 654 trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_);
871 655
872 --*idx; 656 bma->idx--;
873 *dnew = temp;
874 break; 657 break;
875 658
876 case BMAP_LEFT_FILLING: 659 case BMAP_LEFT_FILLING:
@@ -878,43 +661,43 @@ xfs_bmap_add_extent_delay_real(
878 * Filling in the first part of a previous delayed allocation. 661 * Filling in the first part of a previous delayed allocation.
879 * The left neighbor is not contiguous. 662 * The left neighbor is not contiguous.
880 */ 663 */
881 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 664 trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_);
882 xfs_bmbt_set_startoff(ep, new_endoff); 665 xfs_bmbt_set_startoff(ep, new_endoff);
883 temp = PREV.br_blockcount - new->br_blockcount; 666 temp = PREV.br_blockcount - new->br_blockcount;
884 xfs_bmbt_set_blockcount(ep, temp); 667 xfs_bmbt_set_blockcount(ep, temp);
885 xfs_iext_insert(ip, *idx, 1, new, state); 668 xfs_iext_insert(bma->ip, bma->idx, 1, new, state);
886 ip->i_d.di_nextents++; 669 bma->ip->i_d.di_nextents++;
887 if (cur == NULL) 670 if (bma->cur == NULL)
888 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 671 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
889 else { 672 else {
890 rval = XFS_ILOG_CORE; 673 rval = XFS_ILOG_CORE;
891 if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, 674 error = xfs_bmbt_lookup_eq(bma->cur, new->br_startoff,
892 new->br_startblock, new->br_blockcount, 675 new->br_startblock, new->br_blockcount,
893 &i))) 676 &i);
677 if (error)
894 goto done; 678 goto done;
895 XFS_WANT_CORRUPTED_GOTO(i == 0, done); 679 XFS_WANT_CORRUPTED_GOTO(i == 0, done);
896 cur->bc_rec.b.br_state = XFS_EXT_NORM; 680 bma->cur->bc_rec.b.br_state = XFS_EXT_NORM;
897 if ((error = xfs_btree_insert(cur, &i))) 681 error = xfs_btree_insert(bma->cur, &i);
682 if (error)
898 goto done; 683 goto done;
899 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 684 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
900 } 685 }
901 if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && 686 if (bma->ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS &&
902 ip->i_d.di_nextents > ip->i_df.if_ext_max) { 687 bma->ip->i_d.di_nextents > bma->ip->i_df.if_ext_max) {
903 error = xfs_bmap_extents_to_btree(tp, ip, 688 error = xfs_bmap_extents_to_btree(bma->tp, bma->ip,
904 first, flist, &cur, 1, &tmp_rval, 689 bma->firstblock, bma->flist,
905 XFS_DATA_FORK); 690 &bma->cur, 1, &tmp_rval, XFS_DATA_FORK);
906 rval |= tmp_rval; 691 rval |= tmp_rval;
907 if (error) 692 if (error)
908 goto done; 693 goto done;
909 } 694 }
910 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), 695 da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(bma->ip, temp),
911 startblockval(PREV.br_startblock) - 696 startblockval(PREV.br_startblock) -
912 (cur ? cur->bc_private.b.allocated : 0)); 697 (bma->cur ? bma->cur->bc_private.b.allocated : 0));
913 ep = xfs_iext_get_ext(ifp, *idx + 1); 698 ep = xfs_iext_get_ext(ifp, bma->idx + 1);
914 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); 699 xfs_bmbt_set_startblock(ep, nullstartblock(da_new));
915 trace_xfs_bmap_post_update(ip, *idx + 1, state, _THIS_IP_); 700 trace_xfs_bmap_post_update(bma->ip, bma->idx + 1, state, _THIS_IP_);
916
917 *dnew = temp;
918 break; 701 break;
919 702
920 case BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: 703 case BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG:
@@ -923,38 +706,39 @@ xfs_bmap_add_extent_delay_real(
923 * The right neighbor is contiguous with the new allocation. 706 * The right neighbor is contiguous with the new allocation.
924 */ 707 */
925 temp = PREV.br_blockcount - new->br_blockcount; 708 temp = PREV.br_blockcount - new->br_blockcount;
926 trace_xfs_bmap_pre_update(ip, *idx + 1, state, _THIS_IP_); 709 trace_xfs_bmap_pre_update(bma->ip, bma->idx + 1, state, _THIS_IP_);
927 xfs_bmbt_set_blockcount(ep, temp); 710 xfs_bmbt_set_blockcount(ep, temp);
928 xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, *idx + 1), 711 xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, bma->idx + 1),
929 new->br_startoff, new->br_startblock, 712 new->br_startoff, new->br_startblock,
930 new->br_blockcount + RIGHT.br_blockcount, 713 new->br_blockcount + RIGHT.br_blockcount,
931 RIGHT.br_state); 714 RIGHT.br_state);
932 trace_xfs_bmap_post_update(ip, *idx + 1, state, _THIS_IP_); 715 trace_xfs_bmap_post_update(bma->ip, bma->idx + 1, state, _THIS_IP_);
933 if (cur == NULL) 716 if (bma->cur == NULL)
934 rval = XFS_ILOG_DEXT; 717 rval = XFS_ILOG_DEXT;
935 else { 718 else {
936 rval = 0; 719 rval = 0;
937 if ((error = xfs_bmbt_lookup_eq(cur, RIGHT.br_startoff, 720 error = xfs_bmbt_lookup_eq(bma->cur, RIGHT.br_startoff,
938 RIGHT.br_startblock, 721 RIGHT.br_startblock,
939 RIGHT.br_blockcount, &i))) 722 RIGHT.br_blockcount, &i);
723 if (error)
940 goto done; 724 goto done;
941 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 725 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
942 if ((error = xfs_bmbt_update(cur, new->br_startoff, 726 error = xfs_bmbt_update(bma->cur, new->br_startoff,
943 new->br_startblock, 727 new->br_startblock,
944 new->br_blockcount + 728 new->br_blockcount +
945 RIGHT.br_blockcount, 729 RIGHT.br_blockcount,
946 RIGHT.br_state))) 730 RIGHT.br_state);
731 if (error)
947 goto done; 732 goto done;
948 } 733 }
949 734
950 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), 735 da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(bma->ip, temp),
951 startblockval(PREV.br_startblock)); 736 startblockval(PREV.br_startblock));
952 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 737 trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_);
953 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); 738 xfs_bmbt_set_startblock(ep, nullstartblock(da_new));
954 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 739 trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_);
955 740
956 ++*idx; 741 bma->idx++;
957 *dnew = temp;
958 break; 742 break;
959 743
960 case BMAP_RIGHT_FILLING: 744 case BMAP_RIGHT_FILLING:
@@ -963,42 +747,43 @@ xfs_bmap_add_extent_delay_real(
963 * The right neighbor is not contiguous. 747 * The right neighbor is not contiguous.
964 */ 748 */
965 temp = PREV.br_blockcount - new->br_blockcount; 749 temp = PREV.br_blockcount - new->br_blockcount;
966 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 750 trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_);
967 xfs_bmbt_set_blockcount(ep, temp); 751 xfs_bmbt_set_blockcount(ep, temp);
968 xfs_iext_insert(ip, *idx + 1, 1, new, state); 752 xfs_iext_insert(bma->ip, bma->idx + 1, 1, new, state);
969 ip->i_d.di_nextents++; 753 bma->ip->i_d.di_nextents++;
970 if (cur == NULL) 754 if (bma->cur == NULL)
971 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 755 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
972 else { 756 else {
973 rval = XFS_ILOG_CORE; 757 rval = XFS_ILOG_CORE;
974 if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, 758 error = xfs_bmbt_lookup_eq(bma->cur, new->br_startoff,
975 new->br_startblock, new->br_blockcount, 759 new->br_startblock, new->br_blockcount,
976 &i))) 760 &i);
761 if (error)
977 goto done; 762 goto done;
978 XFS_WANT_CORRUPTED_GOTO(i == 0, done); 763 XFS_WANT_CORRUPTED_GOTO(i == 0, done);
979 cur->bc_rec.b.br_state = XFS_EXT_NORM; 764 bma->cur->bc_rec.b.br_state = XFS_EXT_NORM;
980 if ((error = xfs_btree_insert(cur, &i))) 765 error = xfs_btree_insert(bma->cur, &i);
766 if (error)
981 goto done; 767 goto done;
982 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 768 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
983 } 769 }
984 if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && 770 if (bma->ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS &&
985 ip->i_d.di_nextents > ip->i_df.if_ext_max) { 771 bma->ip->i_d.di_nextents > bma->ip->i_df.if_ext_max) {
986 error = xfs_bmap_extents_to_btree(tp, ip, 772 error = xfs_bmap_extents_to_btree(bma->tp, bma->ip,
987 first, flist, &cur, 1, &tmp_rval, 773 bma->firstblock, bma->flist, &bma->cur, 1,
988 XFS_DATA_FORK); 774 &tmp_rval, XFS_DATA_FORK);
989 rval |= tmp_rval; 775 rval |= tmp_rval;
990 if (error) 776 if (error)
991 goto done; 777 goto done;
992 } 778 }
993 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), 779 da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(bma->ip, temp),
994 startblockval(PREV.br_startblock) - 780 startblockval(PREV.br_startblock) -
995 (cur ? cur->bc_private.b.allocated : 0)); 781 (bma->cur ? bma->cur->bc_private.b.allocated : 0));
996 ep = xfs_iext_get_ext(ifp, *idx); 782 ep = xfs_iext_get_ext(ifp, bma->idx);
997 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); 783 xfs_bmbt_set_startblock(ep, nullstartblock(da_new));
998 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 784 trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_);
999 785
1000 ++*idx; 786 bma->idx++;
1001 *dnew = temp;
1002 break; 787 break;
1003 788
1004 case 0: 789 case 0:
@@ -1024,82 +809,65 @@ xfs_bmap_add_extent_delay_real(
1024 */ 809 */
1025 temp = new->br_startoff - PREV.br_startoff; 810 temp = new->br_startoff - PREV.br_startoff;
1026 temp2 = PREV.br_startoff + PREV.br_blockcount - new_endoff; 811 temp2 = PREV.br_startoff + PREV.br_blockcount - new_endoff;
1027 trace_xfs_bmap_pre_update(ip, *idx, 0, _THIS_IP_); 812 trace_xfs_bmap_pre_update(bma->ip, bma->idx, 0, _THIS_IP_);
1028 xfs_bmbt_set_blockcount(ep, temp); /* truncate PREV */ 813 xfs_bmbt_set_blockcount(ep, temp); /* truncate PREV */
1029 LEFT = *new; 814 LEFT = *new;
1030 RIGHT.br_state = PREV.br_state; 815 RIGHT.br_state = PREV.br_state;
1031 RIGHT.br_startblock = nullstartblock( 816 RIGHT.br_startblock = nullstartblock(
1032 (int)xfs_bmap_worst_indlen(ip, temp2)); 817 (int)xfs_bmap_worst_indlen(bma->ip, temp2));
1033 RIGHT.br_startoff = new_endoff; 818 RIGHT.br_startoff = new_endoff;
1034 RIGHT.br_blockcount = temp2; 819 RIGHT.br_blockcount = temp2;
1035 /* insert LEFT (r[0]) and RIGHT (r[1]) at the same time */ 820 /* insert LEFT (r[0]) and RIGHT (r[1]) at the same time */
1036 xfs_iext_insert(ip, *idx + 1, 2, &LEFT, state); 821 xfs_iext_insert(bma->ip, bma->idx + 1, 2, &LEFT, state);
1037 ip->i_d.di_nextents++; 822 bma->ip->i_d.di_nextents++;
1038 if (cur == NULL) 823 if (bma->cur == NULL)
1039 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 824 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
1040 else { 825 else {
1041 rval = XFS_ILOG_CORE; 826 rval = XFS_ILOG_CORE;
1042 if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, 827 error = xfs_bmbt_lookup_eq(bma->cur, new->br_startoff,
1043 new->br_startblock, new->br_blockcount, 828 new->br_startblock, new->br_blockcount,
1044 &i))) 829 &i);
830 if (error)
1045 goto done; 831 goto done;
1046 XFS_WANT_CORRUPTED_GOTO(i == 0, done); 832 XFS_WANT_CORRUPTED_GOTO(i == 0, done);
1047 cur->bc_rec.b.br_state = XFS_EXT_NORM; 833 bma->cur->bc_rec.b.br_state = XFS_EXT_NORM;
1048 if ((error = xfs_btree_insert(cur, &i))) 834 error = xfs_btree_insert(bma->cur, &i);
835 if (error)
1049 goto done; 836 goto done;
1050 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 837 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
1051 } 838 }
1052 if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && 839 if (bma->ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS &&
1053 ip->i_d.di_nextents > ip->i_df.if_ext_max) { 840 bma->ip->i_d.di_nextents > bma->ip->i_df.if_ext_max) {
1054 error = xfs_bmap_extents_to_btree(tp, ip, 841 error = xfs_bmap_extents_to_btree(bma->tp, bma->ip,
1055 first, flist, &cur, 1, &tmp_rval, 842 bma->firstblock, bma->flist, &bma->cur,
1056 XFS_DATA_FORK); 843 1, &tmp_rval, XFS_DATA_FORK);
1057 rval |= tmp_rval; 844 rval |= tmp_rval;
1058 if (error) 845 if (error)
1059 goto done; 846 goto done;
1060 } 847 }
1061 temp = xfs_bmap_worst_indlen(ip, temp); 848 temp = xfs_bmap_worst_indlen(bma->ip, temp);
1062 temp2 = xfs_bmap_worst_indlen(ip, temp2); 849 temp2 = xfs_bmap_worst_indlen(bma->ip, temp2);
1063 diff = (int)(temp + temp2 - startblockval(PREV.br_startblock) - 850 diff = (int)(temp + temp2 - startblockval(PREV.br_startblock) -
1064 (cur ? cur->bc_private.b.allocated : 0)); 851 (bma->cur ? bma->cur->bc_private.b.allocated : 0));
1065 if (diff > 0 && 852 if (diff > 0) {
1066 xfs_icsb_modify_counters(ip->i_mount, XFS_SBS_FDBLOCKS, 853 error = xfs_icsb_modify_counters(bma->ip->i_mount,
1067 -((int64_t)diff), 0)) { 854 XFS_SBS_FDBLOCKS,
1068 /* 855 -((int64_t)diff), 0);
1069 * Ick gross gag me with a spoon. 856 ASSERT(!error);
1070 */ 857 if (error)
1071 ASSERT(0); /* want to see if this ever happens! */ 858 goto done;
1072 while (diff > 0) {
1073 if (temp) {
1074 temp--;
1075 diff--;
1076 if (!diff ||
1077 !xfs_icsb_modify_counters(ip->i_mount,
1078 XFS_SBS_FDBLOCKS,
1079 -((int64_t)diff), 0))
1080 break;
1081 }
1082 if (temp2) {
1083 temp2--;
1084 diff--;
1085 if (!diff ||
1086 !xfs_icsb_modify_counters(ip->i_mount,
1087 XFS_SBS_FDBLOCKS,
1088 -((int64_t)diff), 0))
1089 break;
1090 }
1091 }
1092 } 859 }
1093 ep = xfs_iext_get_ext(ifp, *idx); 860
861 ep = xfs_iext_get_ext(ifp, bma->idx);
1094 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); 862 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp));
1095 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 863 trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_);
1096 trace_xfs_bmap_pre_update(ip, *idx + 2, state, _THIS_IP_); 864 trace_xfs_bmap_pre_update(bma->ip, bma->idx + 2, state, _THIS_IP_);
1097 xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, *idx + 2), 865 xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, bma->idx + 2),
1098 nullstartblock((int)temp2)); 866 nullstartblock((int)temp2));
1099 trace_xfs_bmap_post_update(ip, *idx + 2, state, _THIS_IP_); 867 trace_xfs_bmap_post_update(bma->ip, bma->idx + 2, state, _THIS_IP_);
1100 868
1101 ++*idx; 869 bma->idx++;
1102 *dnew = temp + temp2; 870 da_new = temp + temp2;
1103 break; 871 break;
1104 872
1105 case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: 873 case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG:
@@ -1114,9 +882,40 @@ xfs_bmap_add_extent_delay_real(
1114 */ 882 */
1115 ASSERT(0); 883 ASSERT(0);
1116 } 884 }
1117 *curp = cur; 885
886 /* convert to a btree if necessary */
887 if (XFS_IFORK_FORMAT(bma->ip, XFS_DATA_FORK) == XFS_DINODE_FMT_EXTENTS &&
888 XFS_IFORK_NEXTENTS(bma->ip, XFS_DATA_FORK) > ifp->if_ext_max) {
889 int tmp_logflags; /* partial log flag return val */
890
891 ASSERT(bma->cur == NULL);
892 error = xfs_bmap_extents_to_btree(bma->tp, bma->ip,
893 bma->firstblock, bma->flist, &bma->cur,
894 da_old > 0, &tmp_logflags, XFS_DATA_FORK);
895 bma->logflags |= tmp_logflags;
896 if (error)
897 goto done;
898 }
899
900 /* adjust for changes in reserved delayed indirect blocks */
901 if (da_old || da_new) {
902 temp = da_new;
903 if (bma->cur)
904 temp += bma->cur->bc_private.b.allocated;
905 ASSERT(temp <= da_old);
906 if (temp < da_old)
907 xfs_icsb_modify_counters(bma->ip->i_mount,
908 XFS_SBS_FDBLOCKS,
909 (int64_t)(da_old - temp), 0);
910 }
911
912 /* clear out the allocated field, done with it now in any case. */
913 if (bma->cur)
914 bma->cur->bc_private.b.allocated = 0;
915
916 xfs_bmap_check_leaf_extents(bma->cur, bma->ip, XFS_DATA_FORK);
1118done: 917done:
1119 *logflagsp = rval; 918 bma->logflags |= rval;
1120 return error; 919 return error;
1121#undef LEFT 920#undef LEFT
1122#undef RIGHT 921#undef RIGHT
@@ -1124,15 +923,17 @@ done:
1124} 923}
1125 924
1126/* 925/*
1127 * Called by xfs_bmap_add_extent to handle cases converting an unwritten 926 * Convert an unwritten allocation to a real allocation or vice versa.
1128 * allocation to a real allocation or vice versa.
1129 */ 927 */
1130STATIC int /* error */ 928STATIC int /* error */
1131xfs_bmap_add_extent_unwritten_real( 929xfs_bmap_add_extent_unwritten_real(
930 struct xfs_trans *tp,
1132 xfs_inode_t *ip, /* incore inode pointer */ 931 xfs_inode_t *ip, /* incore inode pointer */
1133 xfs_extnum_t *idx, /* extent number to update/insert */ 932 xfs_extnum_t *idx, /* extent number to update/insert */
1134 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ 933 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
1135 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 934 xfs_bmbt_irec_t *new, /* new data to add to file extents */
935 xfs_fsblock_t *first, /* pointer to firstblock variable */
936 xfs_bmap_free_t *flist, /* list of extents to be freed */
1136 int *logflagsp) /* inode logging flags */ 937 int *logflagsp) /* inode logging flags */
1137{ 938{
1138 xfs_btree_cur_t *cur; /* btree cursor */ 939 xfs_btree_cur_t *cur; /* btree cursor */
@@ -1148,15 +949,25 @@ xfs_bmap_add_extent_unwritten_real(
1148 int rval=0; /* return value (logging flags) */ 949 int rval=0; /* return value (logging flags) */
1149 int state = 0;/* state bits, accessed thru macros */ 950 int state = 0;/* state bits, accessed thru macros */
1150 951
952 *logflagsp = 0;
953
954 cur = *curp;
955 ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
956
957 ASSERT(*idx >= 0);
958 ASSERT(*idx <= ifp->if_bytes / sizeof(struct xfs_bmbt_rec));
959 ASSERT(!isnullstartblock(new->br_startblock));
960
961 XFS_STATS_INC(xs_add_exlist);
962
1151#define LEFT r[0] 963#define LEFT r[0]
1152#define RIGHT r[1] 964#define RIGHT r[1]
1153#define PREV r[2] 965#define PREV r[2]
966
1154 /* 967 /*
1155 * Set up a bunch of variables to make the tests simpler. 968 * Set up a bunch of variables to make the tests simpler.
1156 */ 969 */
1157 error = 0; 970 error = 0;
1158 cur = *curp;
1159 ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
1160 ep = xfs_iext_get_ext(ifp, *idx); 971 ep = xfs_iext_get_ext(ifp, *idx);
1161 xfs_bmbt_get_all(ep, &PREV); 972 xfs_bmbt_get_all(ep, &PREV);
1162 newext = new->br_state; 973 newext = new->br_state;
@@ -1406,10 +1217,11 @@ xfs_bmap_add_extent_unwritten_real(
1406 goto done; 1217 goto done;
1407 if ((error = xfs_btree_decrement(cur, 0, &i))) 1218 if ((error = xfs_btree_decrement(cur, 0, &i)))
1408 goto done; 1219 goto done;
1409 if (xfs_bmbt_update(cur, LEFT.br_startoff, 1220 error = xfs_bmbt_update(cur, LEFT.br_startoff,
1410 LEFT.br_startblock, 1221 LEFT.br_startblock,
1411 LEFT.br_blockcount + new->br_blockcount, 1222 LEFT.br_blockcount + new->br_blockcount,
1412 LEFT.br_state)) 1223 LEFT.br_state);
1224 if (error)
1413 goto done; 1225 goto done;
1414 } 1226 }
1415 break; 1227 break;
@@ -1607,9 +1419,29 @@ xfs_bmap_add_extent_unwritten_real(
1607 */ 1419 */
1608 ASSERT(0); 1420 ASSERT(0);
1609 } 1421 }
1610 *curp = cur; 1422
1423 /* convert to a btree if necessary */
1424 if (XFS_IFORK_FORMAT(ip, XFS_DATA_FORK) == XFS_DINODE_FMT_EXTENTS &&
1425 XFS_IFORK_NEXTENTS(ip, XFS_DATA_FORK) > ifp->if_ext_max) {
1426 int tmp_logflags; /* partial log flag return val */
1427
1428 ASSERT(cur == NULL);
1429 error = xfs_bmap_extents_to_btree(tp, ip, first, flist, &cur,
1430 0, &tmp_logflags, XFS_DATA_FORK);
1431 *logflagsp |= tmp_logflags;
1432 if (error)
1433 goto done;
1434 }
1435
1436 /* clear out the allocated field, done with it now in any case. */
1437 if (cur) {
1438 cur->bc_private.b.allocated = 0;
1439 *curp = cur;
1440 }
1441
1442 xfs_bmap_check_leaf_extents(*curp, ip, XFS_DATA_FORK);
1611done: 1443done:
1612 *logflagsp = rval; 1444 *logflagsp |= rval;
1613 return error; 1445 return error;
1614#undef LEFT 1446#undef LEFT
1615#undef RIGHT 1447#undef RIGHT
@@ -1617,16 +1449,13 @@ done:
1617} 1449}
1618 1450
1619/* 1451/*
1620 * Called by xfs_bmap_add_extent to handle cases converting a hole 1452 * Convert a hole to a delayed allocation.
1621 * to a delayed allocation.
1622 */ 1453 */
1623/*ARGSUSED*/ 1454STATIC void
1624STATIC int /* error */
1625xfs_bmap_add_extent_hole_delay( 1455xfs_bmap_add_extent_hole_delay(
1626 xfs_inode_t *ip, /* incore inode pointer */ 1456 xfs_inode_t *ip, /* incore inode pointer */
1627 xfs_extnum_t *idx, /* extent number to update/insert */ 1457 xfs_extnum_t *idx, /* extent number to update/insert */
1628 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 1458 xfs_bmbt_irec_t *new) /* new data to add to file extents */
1629 int *logflagsp) /* inode logging flags */
1630{ 1459{
1631 xfs_ifork_t *ifp; /* inode fork pointer */ 1460 xfs_ifork_t *ifp; /* inode fork pointer */
1632 xfs_bmbt_irec_t left; /* left neighbor extent entry */ 1461 xfs_bmbt_irec_t left; /* left neighbor extent entry */
@@ -1761,23 +1590,17 @@ xfs_bmap_add_extent_hole_delay(
1761 * Nothing to do for disk quota accounting here. 1590 * Nothing to do for disk quota accounting here.
1762 */ 1591 */
1763 } 1592 }
1764 *logflagsp = 0;
1765 return 0;
1766} 1593}
1767 1594
1768/* 1595/*
1769 * Called by xfs_bmap_add_extent to handle cases converting a hole 1596 * Convert a hole to a real allocation.
1770 * to a real allocation.
1771 */ 1597 */
1772STATIC int /* error */ 1598STATIC int /* error */
1773xfs_bmap_add_extent_hole_real( 1599xfs_bmap_add_extent_hole_real(
1774 xfs_inode_t *ip, /* incore inode pointer */ 1600 struct xfs_bmalloca *bma,
1775 xfs_extnum_t *idx, /* extent number to update/insert */ 1601 int whichfork)
1776 xfs_btree_cur_t *cur, /* if null, not a btree */
1777 xfs_bmbt_irec_t *new, /* new data to add to file extents */
1778 int *logflagsp, /* inode logging flags */
1779 int whichfork) /* data or attr fork */
1780{ 1602{
1603 struct xfs_bmbt_irec *new = &bma->got;
1781 int error; /* error return value */ 1604 int error; /* error return value */
1782 int i; /* temp state */ 1605 int i; /* temp state */
1783 xfs_ifork_t *ifp; /* inode fork pointer */ 1606 xfs_ifork_t *ifp; /* inode fork pointer */
@@ -1786,19 +1609,26 @@ xfs_bmap_add_extent_hole_real(
1786 int rval=0; /* return value (logging flags) */ 1609 int rval=0; /* return value (logging flags) */
1787 int state; /* state bits, accessed thru macros */ 1610 int state; /* state bits, accessed thru macros */
1788 1611
1789 ifp = XFS_IFORK_PTR(ip, whichfork); 1612 ifp = XFS_IFORK_PTR(bma->ip, whichfork);
1790 ASSERT(*idx <= ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)); 1613
1791 state = 0; 1614 ASSERT(bma->idx >= 0);
1615 ASSERT(bma->idx <= ifp->if_bytes / sizeof(struct xfs_bmbt_rec));
1616 ASSERT(!isnullstartblock(new->br_startblock));
1617 ASSERT(!bma->cur ||
1618 !(bma->cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL));
1619
1620 XFS_STATS_INC(xs_add_exlist);
1792 1621
1622 state = 0;
1793 if (whichfork == XFS_ATTR_FORK) 1623 if (whichfork == XFS_ATTR_FORK)
1794 state |= BMAP_ATTRFORK; 1624 state |= BMAP_ATTRFORK;
1795 1625
1796 /* 1626 /*
1797 * Check and set flags if this segment has a left neighbor. 1627 * Check and set flags if this segment has a left neighbor.
1798 */ 1628 */
1799 if (*idx > 0) { 1629 if (bma->idx > 0) {
1800 state |= BMAP_LEFT_VALID; 1630 state |= BMAP_LEFT_VALID;
1801 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx - 1), &left); 1631 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma->idx - 1), &left);
1802 if (isnullstartblock(left.br_startblock)) 1632 if (isnullstartblock(left.br_startblock))
1803 state |= BMAP_LEFT_DELAY; 1633 state |= BMAP_LEFT_DELAY;
1804 } 1634 }
@@ -1807,9 +1637,9 @@ xfs_bmap_add_extent_hole_real(
1807 * Check and set flags if this segment has a current value. 1637 * Check and set flags if this segment has a current value.
1808 * Not true if we're inserting into the "hole" at eof. 1638 * Not true if we're inserting into the "hole" at eof.
1809 */ 1639 */
1810 if (*idx < ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)) { 1640 if (bma->idx < ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)) {
1811 state |= BMAP_RIGHT_VALID; 1641 state |= BMAP_RIGHT_VALID;
1812 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx), &right); 1642 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma->idx), &right);
1813 if (isnullstartblock(right.br_startblock)) 1643 if (isnullstartblock(right.br_startblock))
1814 state |= BMAP_RIGHT_DELAY; 1644 state |= BMAP_RIGHT_DELAY;
1815 } 1645 }
@@ -1846,39 +1676,42 @@ xfs_bmap_add_extent_hole_real(
1846 * left and on the right. 1676 * left and on the right.
1847 * Merge all three into a single extent record. 1677 * Merge all three into a single extent record.
1848 */ 1678 */
1849 --*idx; 1679 --bma->idx;
1850 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 1680 trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_);
1851 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx), 1681 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, bma->idx),
1852 left.br_blockcount + new->br_blockcount + 1682 left.br_blockcount + new->br_blockcount +
1853 right.br_blockcount); 1683 right.br_blockcount);
1854 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 1684 trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_);
1855 1685
1856 xfs_iext_remove(ip, *idx + 1, 1, state); 1686 xfs_iext_remove(bma->ip, bma->idx + 1, 1, state);
1857 1687
1858 XFS_IFORK_NEXT_SET(ip, whichfork, 1688 XFS_IFORK_NEXT_SET(bma->ip, whichfork,
1859 XFS_IFORK_NEXTENTS(ip, whichfork) - 1); 1689 XFS_IFORK_NEXTENTS(bma->ip, whichfork) - 1);
1860 if (cur == NULL) { 1690 if (bma->cur == NULL) {
1861 rval = XFS_ILOG_CORE | xfs_ilog_fext(whichfork); 1691 rval = XFS_ILOG_CORE | xfs_ilog_fext(whichfork);
1862 } else { 1692 } else {
1863 rval = XFS_ILOG_CORE; 1693 rval = XFS_ILOG_CORE;
1864 if ((error = xfs_bmbt_lookup_eq(cur, 1694 error = xfs_bmbt_lookup_eq(bma->cur, right.br_startoff,
1865 right.br_startoff, 1695 right.br_startblock, right.br_blockcount,
1866 right.br_startblock, 1696 &i);
1867 right.br_blockcount, &i))) 1697 if (error)
1868 goto done; 1698 goto done;
1869 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 1699 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
1870 if ((error = xfs_btree_delete(cur, &i))) 1700 error = xfs_btree_delete(bma->cur, &i);
1701 if (error)
1871 goto done; 1702 goto done;
1872 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 1703 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
1873 if ((error = xfs_btree_decrement(cur, 0, &i))) 1704 error = xfs_btree_decrement(bma->cur, 0, &i);
1705 if (error)
1874 goto done; 1706 goto done;
1875 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 1707 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
1876 if ((error = xfs_bmbt_update(cur, left.br_startoff, 1708 error = xfs_bmbt_update(bma->cur, left.br_startoff,
1877 left.br_startblock, 1709 left.br_startblock,
1878 left.br_blockcount + 1710 left.br_blockcount +
1879 new->br_blockcount + 1711 new->br_blockcount +
1880 right.br_blockcount, 1712 right.br_blockcount,
1881 left.br_state))) 1713 left.br_state);
1714 if (error)
1882 goto done; 1715 goto done;
1883 } 1716 }
1884 break; 1717 break;
@@ -1889,27 +1722,28 @@ xfs_bmap_add_extent_hole_real(
1889 * on the left. 1722 * on the left.
1890 * Merge the new allocation with the left neighbor. 1723 * Merge the new allocation with the left neighbor.
1891 */ 1724 */
1892 --*idx; 1725 --bma->idx;
1893 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 1726 trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_);
1894 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx), 1727 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, bma->idx),
1895 left.br_blockcount + new->br_blockcount); 1728 left.br_blockcount + new->br_blockcount);
1896 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 1729 trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_);
1897 1730
1898 if (cur == NULL) { 1731 if (bma->cur == NULL) {
1899 rval = xfs_ilog_fext(whichfork); 1732 rval = xfs_ilog_fext(whichfork);
1900 } else { 1733 } else {
1901 rval = 0; 1734 rval = 0;
1902 if ((error = xfs_bmbt_lookup_eq(cur, 1735 error = xfs_bmbt_lookup_eq(bma->cur, left.br_startoff,
1903 left.br_startoff, 1736 left.br_startblock, left.br_blockcount,
1904 left.br_startblock, 1737 &i);
1905 left.br_blockcount, &i))) 1738 if (error)
1906 goto done; 1739 goto done;
1907 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 1740 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
1908 if ((error = xfs_bmbt_update(cur, left.br_startoff, 1741 error = xfs_bmbt_update(bma->cur, left.br_startoff,
1909 left.br_startblock, 1742 left.br_startblock,
1910 left.br_blockcount + 1743 left.br_blockcount +
1911 new->br_blockcount, 1744 new->br_blockcount,
1912 left.br_state))) 1745 left.br_state);
1746 if (error)
1913 goto done; 1747 goto done;
1914 } 1748 }
1915 break; 1749 break;
@@ -1920,28 +1754,30 @@ xfs_bmap_add_extent_hole_real(
1920 * on the right. 1754 * on the right.
1921 * Merge the new allocation with the right neighbor. 1755 * Merge the new allocation with the right neighbor.
1922 */ 1756 */
1923 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 1757 trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_);
1924 xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, *idx), 1758 xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, bma->idx),
1925 new->br_startoff, new->br_startblock, 1759 new->br_startoff, new->br_startblock,
1926 new->br_blockcount + right.br_blockcount, 1760 new->br_blockcount + right.br_blockcount,
1927 right.br_state); 1761 right.br_state);
1928 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 1762 trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_);
1929 1763
1930 if (cur == NULL) { 1764 if (bma->cur == NULL) {
1931 rval = xfs_ilog_fext(whichfork); 1765 rval = xfs_ilog_fext(whichfork);
1932 } else { 1766 } else {
1933 rval = 0; 1767 rval = 0;
1934 if ((error = xfs_bmbt_lookup_eq(cur, 1768 error = xfs_bmbt_lookup_eq(bma->cur,
1935 right.br_startoff, 1769 right.br_startoff,
1936 right.br_startblock, 1770 right.br_startblock,
1937 right.br_blockcount, &i))) 1771 right.br_blockcount, &i);
1772 if (error)
1938 goto done; 1773 goto done;
1939 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 1774 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
1940 if ((error = xfs_bmbt_update(cur, new->br_startoff, 1775 error = xfs_bmbt_update(bma->cur, new->br_startoff,
1941 new->br_startblock, 1776 new->br_startblock,
1942 new->br_blockcount + 1777 new->br_blockcount +
1943 right.br_blockcount, 1778 right.br_blockcount,
1944 right.br_state))) 1779 right.br_state);
1780 if (error)
1945 goto done; 1781 goto done;
1946 } 1782 }
1947 break; 1783 break;
@@ -1952,28 +1788,50 @@ xfs_bmap_add_extent_hole_real(
1952 * real allocation. 1788 * real allocation.
1953 * Insert a new entry. 1789 * Insert a new entry.
1954 */ 1790 */
1955 xfs_iext_insert(ip, *idx, 1, new, state); 1791 xfs_iext_insert(bma->ip, bma->idx, 1, new, state);
1956 XFS_IFORK_NEXT_SET(ip, whichfork, 1792 XFS_IFORK_NEXT_SET(bma->ip, whichfork,
1957 XFS_IFORK_NEXTENTS(ip, whichfork) + 1); 1793 XFS_IFORK_NEXTENTS(bma->ip, whichfork) + 1);
1958 if (cur == NULL) { 1794 if (bma->cur == NULL) {
1959 rval = XFS_ILOG_CORE | xfs_ilog_fext(whichfork); 1795 rval = XFS_ILOG_CORE | xfs_ilog_fext(whichfork);
1960 } else { 1796 } else {
1961 rval = XFS_ILOG_CORE; 1797 rval = XFS_ILOG_CORE;
1962 if ((error = xfs_bmbt_lookup_eq(cur, 1798 error = xfs_bmbt_lookup_eq(bma->cur,
1963 new->br_startoff, 1799 new->br_startoff,
1964 new->br_startblock, 1800 new->br_startblock,
1965 new->br_blockcount, &i))) 1801 new->br_blockcount, &i);
1802 if (error)
1966 goto done; 1803 goto done;
1967 XFS_WANT_CORRUPTED_GOTO(i == 0, done); 1804 XFS_WANT_CORRUPTED_GOTO(i == 0, done);
1968 cur->bc_rec.b.br_state = new->br_state; 1805 bma->cur->bc_rec.b.br_state = new->br_state;
1969 if ((error = xfs_btree_insert(cur, &i))) 1806 error = xfs_btree_insert(bma->cur, &i);
1807 if (error)
1970 goto done; 1808 goto done;
1971 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 1809 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
1972 } 1810 }
1973 break; 1811 break;
1974 } 1812 }
1813
1814 /* convert to a btree if necessary */
1815 if (XFS_IFORK_FORMAT(bma->ip, whichfork) == XFS_DINODE_FMT_EXTENTS &&
1816 XFS_IFORK_NEXTENTS(bma->ip, whichfork) > ifp->if_ext_max) {
1817 int tmp_logflags; /* partial log flag return val */
1818
1819 ASSERT(bma->cur == NULL);
1820 error = xfs_bmap_extents_to_btree(bma->tp, bma->ip,
1821 bma->firstblock, bma->flist, &bma->cur,
1822 0, &tmp_logflags, whichfork);
1823 bma->logflags |= tmp_logflags;
1824 if (error)
1825 goto done;
1826 }
1827
1828 /* clear out the allocated field, done with it now in any case. */
1829 if (bma->cur)
1830 bma->cur->bc_private.b.allocated = 0;
1831
1832 xfs_bmap_check_leaf_extents(bma->cur, bma->ip, whichfork);
1975done: 1833done:
1976 *logflagsp = rval; 1834 bma->logflags |= rval;
1977 return error; 1835 return error;
1978} 1836}
1979 1837
@@ -2160,26 +2018,26 @@ xfs_bmap_adjacent(
2160 XFS_FSB_TO_AGBNO(mp, x) < mp->m_sb.sb_agblocks) 2018 XFS_FSB_TO_AGBNO(mp, x) < mp->m_sb.sb_agblocks)
2161 2019
2162 mp = ap->ip->i_mount; 2020 mp = ap->ip->i_mount;
2163 nullfb = ap->firstblock == NULLFSBLOCK; 2021 nullfb = *ap->firstblock == NULLFSBLOCK;
2164 rt = XFS_IS_REALTIME_INODE(ap->ip) && ap->userdata; 2022 rt = XFS_IS_REALTIME_INODE(ap->ip) && ap->userdata;
2165 fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, ap->firstblock); 2023 fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, *ap->firstblock);
2166 /* 2024 /*
2167 * If allocating at eof, and there's a previous real block, 2025 * If allocating at eof, and there's a previous real block,
2168 * try to use its last block as our starting point. 2026 * try to use its last block as our starting point.
2169 */ 2027 */
2170 if (ap->eof && ap->prevp->br_startoff != NULLFILEOFF && 2028 if (ap->eof && ap->prev.br_startoff != NULLFILEOFF &&
2171 !isnullstartblock(ap->prevp->br_startblock) && 2029 !isnullstartblock(ap->prev.br_startblock) &&
2172 ISVALID(ap->prevp->br_startblock + ap->prevp->br_blockcount, 2030 ISVALID(ap->prev.br_startblock + ap->prev.br_blockcount,
2173 ap->prevp->br_startblock)) { 2031 ap->prev.br_startblock)) {
2174 ap->rval = ap->prevp->br_startblock + ap->prevp->br_blockcount; 2032 ap->blkno = ap->prev.br_startblock + ap->prev.br_blockcount;
2175 /* 2033 /*
2176 * Adjust for the gap between prevp and us. 2034 * Adjust for the gap between prevp and us.
2177 */ 2035 */
2178 adjust = ap->off - 2036 adjust = ap->offset -
2179 (ap->prevp->br_startoff + ap->prevp->br_blockcount); 2037 (ap->prev.br_startoff + ap->prev.br_blockcount);
2180 if (adjust && 2038 if (adjust &&
2181 ISVALID(ap->rval + adjust, ap->prevp->br_startblock)) 2039 ISVALID(ap->blkno + adjust, ap->prev.br_startblock))
2182 ap->rval += adjust; 2040 ap->blkno += adjust;
2183 } 2041 }
2184 /* 2042 /*
2185 * If not at eof, then compare the two neighbor blocks. 2043 * If not at eof, then compare the two neighbor blocks.
@@ -2196,17 +2054,17 @@ xfs_bmap_adjacent(
2196 * If there's a previous (left) block, select a requested 2054 * If there's a previous (left) block, select a requested
2197 * start block based on it. 2055 * start block based on it.
2198 */ 2056 */
2199 if (ap->prevp->br_startoff != NULLFILEOFF && 2057 if (ap->prev.br_startoff != NULLFILEOFF &&
2200 !isnullstartblock(ap->prevp->br_startblock) && 2058 !isnullstartblock(ap->prev.br_startblock) &&
2201 (prevbno = ap->prevp->br_startblock + 2059 (prevbno = ap->prev.br_startblock +
2202 ap->prevp->br_blockcount) && 2060 ap->prev.br_blockcount) &&
2203 ISVALID(prevbno, ap->prevp->br_startblock)) { 2061 ISVALID(prevbno, ap->prev.br_startblock)) {
2204 /* 2062 /*
2205 * Calculate gap to end of previous block. 2063 * Calculate gap to end of previous block.
2206 */ 2064 */
2207 adjust = prevdiff = ap->off - 2065 adjust = prevdiff = ap->offset -
2208 (ap->prevp->br_startoff + 2066 (ap->prev.br_startoff +
2209 ap->prevp->br_blockcount); 2067 ap->prev.br_blockcount);
2210 /* 2068 /*
2211 * Figure the startblock based on the previous block's 2069 * Figure the startblock based on the previous block's
2212 * end and the gap size. 2070 * end and the gap size.
@@ -2215,9 +2073,9 @@ xfs_bmap_adjacent(
2215 * allocating, or using it gives us an invalid block 2073 * allocating, or using it gives us an invalid block
2216 * number, then just use the end of the previous block. 2074 * number, then just use the end of the previous block.
2217 */ 2075 */
2218 if (prevdiff <= XFS_ALLOC_GAP_UNITS * ap->alen && 2076 if (prevdiff <= XFS_ALLOC_GAP_UNITS * ap->length &&
2219 ISVALID(prevbno + prevdiff, 2077 ISVALID(prevbno + prevdiff,
2220 ap->prevp->br_startblock)) 2078 ap->prev.br_startblock))
2221 prevbno += adjust; 2079 prevbno += adjust;
2222 else 2080 else
2223 prevdiff += adjust; 2081 prevdiff += adjust;
@@ -2238,16 +2096,16 @@ xfs_bmap_adjacent(
2238 * If there's a following (right) block, select a requested 2096 * If there's a following (right) block, select a requested
2239 * start block based on it. 2097 * start block based on it.
2240 */ 2098 */
2241 if (!isnullstartblock(ap->gotp->br_startblock)) { 2099 if (!isnullstartblock(ap->got.br_startblock)) {
2242 /* 2100 /*
2243 * Calculate gap to start of next block. 2101 * Calculate gap to start of next block.
2244 */ 2102 */
2245 adjust = gotdiff = ap->gotp->br_startoff - ap->off; 2103 adjust = gotdiff = ap->got.br_startoff - ap->offset;
2246 /* 2104 /*
2247 * Figure the startblock based on the next block's 2105 * Figure the startblock based on the next block's
2248 * start and the gap size. 2106 * start and the gap size.
2249 */ 2107 */
2250 gotbno = ap->gotp->br_startblock; 2108 gotbno = ap->got.br_startblock;
2251 /* 2109 /*
2252 * Heuristic! 2110 * Heuristic!
2253 * If the gap is large relative to the piece we're 2111 * If the gap is large relative to the piece we're
@@ -2255,12 +2113,12 @@ xfs_bmap_adjacent(
2255 * number, then just use the start of the next block 2113 * number, then just use the start of the next block
2256 * offset by our length. 2114 * offset by our length.
2257 */ 2115 */
2258 if (gotdiff <= XFS_ALLOC_GAP_UNITS * ap->alen && 2116 if (gotdiff <= XFS_ALLOC_GAP_UNITS * ap->length &&
2259 ISVALID(gotbno - gotdiff, gotbno)) 2117 ISVALID(gotbno - gotdiff, gotbno))
2260 gotbno -= adjust; 2118 gotbno -= adjust;
2261 else if (ISVALID(gotbno - ap->alen, gotbno)) { 2119 else if (ISVALID(gotbno - ap->length, gotbno)) {
2262 gotbno -= ap->alen; 2120 gotbno -= ap->length;
2263 gotdiff += adjust - ap->alen; 2121 gotdiff += adjust - ap->length;
2264 } else 2122 } else
2265 gotdiff += adjust; 2123 gotdiff += adjust;
2266 /* 2124 /*
@@ -2278,14 +2136,14 @@ xfs_bmap_adjacent(
2278 gotbno = NULLFSBLOCK; 2136 gotbno = NULLFSBLOCK;
2279 /* 2137 /*
2280 * If both valid, pick the better one, else the only good 2138 * If both valid, pick the better one, else the only good
2281 * one, else ap->rval is already set (to 0 or the inode block). 2139 * one, else ap->blkno is already set (to 0 or the inode block).
2282 */ 2140 */
2283 if (prevbno != NULLFSBLOCK && gotbno != NULLFSBLOCK) 2141 if (prevbno != NULLFSBLOCK && gotbno != NULLFSBLOCK)
2284 ap->rval = prevdiff <= gotdiff ? prevbno : gotbno; 2142 ap->blkno = prevdiff <= gotdiff ? prevbno : gotbno;
2285 else if (prevbno != NULLFSBLOCK) 2143 else if (prevbno != NULLFSBLOCK)
2286 ap->rval = prevbno; 2144 ap->blkno = prevbno;
2287 else if (gotbno != NULLFSBLOCK) 2145 else if (gotbno != NULLFSBLOCK)
2288 ap->rval = gotbno; 2146 ap->blkno = gotbno;
2289 } 2147 }
2290#undef ISVALID 2148#undef ISVALID
2291} 2149}
@@ -2305,24 +2163,24 @@ xfs_bmap_rtalloc(
2305 mp = ap->ip->i_mount; 2163 mp = ap->ip->i_mount;
2306 align = xfs_get_extsz_hint(ap->ip); 2164 align = xfs_get_extsz_hint(ap->ip);
2307 prod = align / mp->m_sb.sb_rextsize; 2165 prod = align / mp->m_sb.sb_rextsize;
2308 error = xfs_bmap_extsize_align(mp, ap->gotp, ap->prevp, 2166 error = xfs_bmap_extsize_align(mp, &ap->got, &ap->prev,
2309 align, 1, ap->eof, 0, 2167 align, 1, ap->eof, 0,
2310 ap->conv, &ap->off, &ap->alen); 2168 ap->conv, &ap->offset, &ap->length);
2311 if (error) 2169 if (error)
2312 return error; 2170 return error;
2313 ASSERT(ap->alen); 2171 ASSERT(ap->length);
2314 ASSERT(ap->alen % mp->m_sb.sb_rextsize == 0); 2172 ASSERT(ap->length % mp->m_sb.sb_rextsize == 0);
2315 2173
2316 /* 2174 /*
2317 * If the offset & length are not perfectly aligned 2175 * If the offset & length are not perfectly aligned
2318 * then kill prod, it will just get us in trouble. 2176 * then kill prod, it will just get us in trouble.
2319 */ 2177 */
2320 if (do_mod(ap->off, align) || ap->alen % align) 2178 if (do_mod(ap->offset, align) || ap->length % align)
2321 prod = 1; 2179 prod = 1;
2322 /* 2180 /*
2323 * Set ralen to be the actual requested length in rtextents. 2181 * Set ralen to be the actual requested length in rtextents.
2324 */ 2182 */
2325 ralen = ap->alen / mp->m_sb.sb_rextsize; 2183 ralen = ap->length / mp->m_sb.sb_rextsize;
2326 /* 2184 /*
2327 * If the old value was close enough to MAXEXTLEN that 2185 * If the old value was close enough to MAXEXTLEN that
2328 * we rounded up to it, cut it back so it's valid again. 2186 * we rounded up to it, cut it back so it's valid again.
@@ -2337,21 +2195,21 @@ xfs_bmap_rtalloc(
2337 * Lock out other modifications to the RT bitmap inode. 2195 * Lock out other modifications to the RT bitmap inode.
2338 */ 2196 */
2339 xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL); 2197 xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL);
2340 xfs_trans_ijoin_ref(ap->tp, mp->m_rbmip, XFS_ILOCK_EXCL); 2198 xfs_trans_ijoin(ap->tp, mp->m_rbmip, XFS_ILOCK_EXCL);
2341 2199
2342 /* 2200 /*
2343 * If it's an allocation to an empty file at offset 0, 2201 * If it's an allocation to an empty file at offset 0,
2344 * pick an extent that will space things out in the rt area. 2202 * pick an extent that will space things out in the rt area.
2345 */ 2203 */
2346 if (ap->eof && ap->off == 0) { 2204 if (ap->eof && ap->offset == 0) {
2347 xfs_rtblock_t uninitialized_var(rtx); /* realtime extent no */ 2205 xfs_rtblock_t uninitialized_var(rtx); /* realtime extent no */
2348 2206
2349 error = xfs_rtpick_extent(mp, ap->tp, ralen, &rtx); 2207 error = xfs_rtpick_extent(mp, ap->tp, ralen, &rtx);
2350 if (error) 2208 if (error)
2351 return error; 2209 return error;
2352 ap->rval = rtx * mp->m_sb.sb_rextsize; 2210 ap->blkno = rtx * mp->m_sb.sb_rextsize;
2353 } else { 2211 } else {
2354 ap->rval = 0; 2212 ap->blkno = 0;
2355 } 2213 }
2356 2214
2357 xfs_bmap_adjacent(ap); 2215 xfs_bmap_adjacent(ap);
@@ -2359,23 +2217,23 @@ xfs_bmap_rtalloc(
2359 /* 2217 /*
2360 * Realtime allocation, done through xfs_rtallocate_extent. 2218 * Realtime allocation, done through xfs_rtallocate_extent.
2361 */ 2219 */
2362 atype = ap->rval == 0 ? XFS_ALLOCTYPE_ANY_AG : XFS_ALLOCTYPE_NEAR_BNO; 2220 atype = ap->blkno == 0 ? XFS_ALLOCTYPE_ANY_AG : XFS_ALLOCTYPE_NEAR_BNO;
2363 do_div(ap->rval, mp->m_sb.sb_rextsize); 2221 do_div(ap->blkno, mp->m_sb.sb_rextsize);
2364 rtb = ap->rval; 2222 rtb = ap->blkno;
2365 ap->alen = ralen; 2223 ap->length = ralen;
2366 if ((error = xfs_rtallocate_extent(ap->tp, ap->rval, 1, ap->alen, 2224 if ((error = xfs_rtallocate_extent(ap->tp, ap->blkno, 1, ap->length,
2367 &ralen, atype, ap->wasdel, prod, &rtb))) 2225 &ralen, atype, ap->wasdel, prod, &rtb)))
2368 return error; 2226 return error;
2369 if (rtb == NULLFSBLOCK && prod > 1 && 2227 if (rtb == NULLFSBLOCK && prod > 1 &&
2370 (error = xfs_rtallocate_extent(ap->tp, ap->rval, 1, 2228 (error = xfs_rtallocate_extent(ap->tp, ap->blkno, 1,
2371 ap->alen, &ralen, atype, 2229 ap->length, &ralen, atype,
2372 ap->wasdel, 1, &rtb))) 2230 ap->wasdel, 1, &rtb)))
2373 return error; 2231 return error;
2374 ap->rval = rtb; 2232 ap->blkno = rtb;
2375 if (ap->rval != NULLFSBLOCK) { 2233 if (ap->blkno != NULLFSBLOCK) {
2376 ap->rval *= mp->m_sb.sb_rextsize; 2234 ap->blkno *= mp->m_sb.sb_rextsize;
2377 ralen *= mp->m_sb.sb_rextsize; 2235 ralen *= mp->m_sb.sb_rextsize;
2378 ap->alen = ralen; 2236 ap->length = ralen;
2379 ap->ip->i_d.di_nblocks += ralen; 2237 ap->ip->i_d.di_nblocks += ralen;
2380 xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE); 2238 xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE);
2381 if (ap->wasdel) 2239 if (ap->wasdel)
@@ -2388,7 +2246,7 @@ xfs_bmap_rtalloc(
2388 ap->wasdel ? XFS_TRANS_DQ_DELRTBCOUNT : 2246 ap->wasdel ? XFS_TRANS_DQ_DELRTBCOUNT :
2389 XFS_TRANS_DQ_RTBCOUNT, (long) ralen); 2247 XFS_TRANS_DQ_RTBCOUNT, (long) ralen);
2390 } else { 2248 } else {
2391 ap->alen = 0; 2249 ap->length = 0;
2392 } 2250 }
2393 return 0; 2251 return 0;
2394} 2252}
@@ -2503,7 +2361,7 @@ xfs_bmap_btalloc_nullfb(
2503 * AG as the stream may have moved. 2361 * AG as the stream may have moved.
2504 */ 2362 */
2505 if (xfs_inode_is_filestream(ap->ip)) 2363 if (xfs_inode_is_filestream(ap->ip))
2506 ap->rval = args->fsbno = XFS_AGB_TO_FSB(mp, ag, 0); 2364 ap->blkno = args->fsbno = XFS_AGB_TO_FSB(mp, ag, 0);
2507 2365
2508 return 0; 2366 return 0;
2509} 2367}
@@ -2528,52 +2386,52 @@ xfs_bmap_btalloc(
2528 mp = ap->ip->i_mount; 2386 mp = ap->ip->i_mount;
2529 align = ap->userdata ? xfs_get_extsz_hint(ap->ip) : 0; 2387 align = ap->userdata ? xfs_get_extsz_hint(ap->ip) : 0;
2530 if (unlikely(align)) { 2388 if (unlikely(align)) {
2531 error = xfs_bmap_extsize_align(mp, ap->gotp, ap->prevp, 2389 error = xfs_bmap_extsize_align(mp, &ap->got, &ap->prev,
2532 align, 0, ap->eof, 0, ap->conv, 2390 align, 0, ap->eof, 0, ap->conv,
2533 &ap->off, &ap->alen); 2391 &ap->offset, &ap->length);
2534 ASSERT(!error); 2392 ASSERT(!error);
2535 ASSERT(ap->alen); 2393 ASSERT(ap->length);
2536 } 2394 }
2537 nullfb = ap->firstblock == NULLFSBLOCK; 2395 nullfb = *ap->firstblock == NULLFSBLOCK;
2538 fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, ap->firstblock); 2396 fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, *ap->firstblock);
2539 if (nullfb) { 2397 if (nullfb) {
2540 if (ap->userdata && xfs_inode_is_filestream(ap->ip)) { 2398 if (ap->userdata && xfs_inode_is_filestream(ap->ip)) {
2541 ag = xfs_filestream_lookup_ag(ap->ip); 2399 ag = xfs_filestream_lookup_ag(ap->ip);
2542 ag = (ag != NULLAGNUMBER) ? ag : 0; 2400 ag = (ag != NULLAGNUMBER) ? ag : 0;
2543 ap->rval = XFS_AGB_TO_FSB(mp, ag, 0); 2401 ap->blkno = XFS_AGB_TO_FSB(mp, ag, 0);
2544 } else { 2402 } else {
2545 ap->rval = XFS_INO_TO_FSB(mp, ap->ip->i_ino); 2403 ap->blkno = XFS_INO_TO_FSB(mp, ap->ip->i_ino);
2546 } 2404 }
2547 } else 2405 } else
2548 ap->rval = ap->firstblock; 2406 ap->blkno = *ap->firstblock;
2549 2407
2550 xfs_bmap_adjacent(ap); 2408 xfs_bmap_adjacent(ap);
2551 2409
2552 /* 2410 /*
2553 * If allowed, use ap->rval; otherwise must use firstblock since 2411 * If allowed, use ap->blkno; otherwise must use firstblock since
2554 * it's in the right allocation group. 2412 * it's in the right allocation group.
2555 */ 2413 */
2556 if (nullfb || XFS_FSB_TO_AGNO(mp, ap->rval) == fb_agno) 2414 if (nullfb || XFS_FSB_TO_AGNO(mp, ap->blkno) == fb_agno)
2557 ; 2415 ;
2558 else 2416 else
2559 ap->rval = ap->firstblock; 2417 ap->blkno = *ap->firstblock;
2560 /* 2418 /*
2561 * Normal allocation, done through xfs_alloc_vextent. 2419 * Normal allocation, done through xfs_alloc_vextent.
2562 */ 2420 */
2563 tryagain = isaligned = 0; 2421 tryagain = isaligned = 0;
2564 args.tp = ap->tp; 2422 args.tp = ap->tp;
2565 args.mp = mp; 2423 args.mp = mp;
2566 args.fsbno = ap->rval; 2424 args.fsbno = ap->blkno;
2567 2425
2568 /* Trim the allocation back to the maximum an AG can fit. */ 2426 /* Trim the allocation back to the maximum an AG can fit. */
2569 args.maxlen = MIN(ap->alen, XFS_ALLOC_AG_MAX_USABLE(mp)); 2427 args.maxlen = MIN(ap->length, XFS_ALLOC_AG_MAX_USABLE(mp));
2570 args.firstblock = ap->firstblock; 2428 args.firstblock = *ap->firstblock;
2571 blen = 0; 2429 blen = 0;
2572 if (nullfb) { 2430 if (nullfb) {
2573 error = xfs_bmap_btalloc_nullfb(ap, &args, &blen); 2431 error = xfs_bmap_btalloc_nullfb(ap, &args, &blen);
2574 if (error) 2432 if (error)
2575 return error; 2433 return error;
2576 } else if (ap->low) { 2434 } else if (ap->flist->xbf_low) {
2577 if (xfs_inode_is_filestream(ap->ip)) 2435 if (xfs_inode_is_filestream(ap->ip))
2578 args.type = XFS_ALLOCTYPE_FIRST_AG; 2436 args.type = XFS_ALLOCTYPE_FIRST_AG;
2579 else 2437 else
@@ -2587,14 +2445,14 @@ xfs_bmap_btalloc(
2587 /* apply extent size hints if obtained earlier */ 2445 /* apply extent size hints if obtained earlier */
2588 if (unlikely(align)) { 2446 if (unlikely(align)) {
2589 args.prod = align; 2447 args.prod = align;
2590 if ((args.mod = (xfs_extlen_t)do_mod(ap->off, args.prod))) 2448 if ((args.mod = (xfs_extlen_t)do_mod(ap->offset, args.prod)))
2591 args.mod = (xfs_extlen_t)(args.prod - args.mod); 2449 args.mod = (xfs_extlen_t)(args.prod - args.mod);
2592 } else if (mp->m_sb.sb_blocksize >= PAGE_CACHE_SIZE) { 2450 } else if (mp->m_sb.sb_blocksize >= PAGE_CACHE_SIZE) {
2593 args.prod = 1; 2451 args.prod = 1;
2594 args.mod = 0; 2452 args.mod = 0;
2595 } else { 2453 } else {
2596 args.prod = PAGE_CACHE_SIZE >> mp->m_sb.sb_blocklog; 2454 args.prod = PAGE_CACHE_SIZE >> mp->m_sb.sb_blocklog;
2597 if ((args.mod = (xfs_extlen_t)(do_mod(ap->off, args.prod)))) 2455 if ((args.mod = (xfs_extlen_t)(do_mod(ap->offset, args.prod))))
2598 args.mod = (xfs_extlen_t)(args.prod - args.mod); 2456 args.mod = (xfs_extlen_t)(args.prod - args.mod);
2599 } 2457 }
2600 /* 2458 /*
@@ -2606,8 +2464,8 @@ xfs_bmap_btalloc(
2606 * is >= the stripe unit and the allocation offset is 2464 * is >= the stripe unit and the allocation offset is
2607 * at the end of file. 2465 * at the end of file.
2608 */ 2466 */
2609 if (!ap->low && ap->aeof) { 2467 if (!ap->flist->xbf_low && ap->aeof) {
2610 if (!ap->off) { 2468 if (!ap->offset) {
2611 args.alignment = mp->m_dalign; 2469 args.alignment = mp->m_dalign;
2612 atype = args.type; 2470 atype = args.type;
2613 isaligned = 1; 2471 isaligned = 1;
@@ -2660,7 +2518,7 @@ xfs_bmap_btalloc(
2660 * turned on. 2518 * turned on.
2661 */ 2519 */
2662 args.type = atype; 2520 args.type = atype;
2663 args.fsbno = ap->rval; 2521 args.fsbno = ap->blkno;
2664 args.alignment = mp->m_dalign; 2522 args.alignment = mp->m_dalign;
2665 args.minlen = nextminlen; 2523 args.minlen = nextminlen;
2666 args.minalignslop = 0; 2524 args.minalignslop = 0;
@@ -2674,7 +2532,7 @@ xfs_bmap_btalloc(
2674 * try again. 2532 * try again.
2675 */ 2533 */
2676 args.type = atype; 2534 args.type = atype;
2677 args.fsbno = ap->rval; 2535 args.fsbno = ap->blkno;
2678 args.alignment = 0; 2536 args.alignment = 0;
2679 if ((error = xfs_alloc_vextent(&args))) 2537 if ((error = xfs_alloc_vextent(&args)))
2680 return error; 2538 return error;
@@ -2683,7 +2541,7 @@ xfs_bmap_btalloc(
2683 args.minlen > ap->minlen) { 2541 args.minlen > ap->minlen) {
2684 args.minlen = ap->minlen; 2542 args.minlen = ap->minlen;
2685 args.type = XFS_ALLOCTYPE_START_BNO; 2543 args.type = XFS_ALLOCTYPE_START_BNO;
2686 args.fsbno = ap->rval; 2544 args.fsbno = ap->blkno;
2687 if ((error = xfs_alloc_vextent(&args))) 2545 if ((error = xfs_alloc_vextent(&args)))
2688 return error; 2546 return error;
2689 } 2547 }
@@ -2694,13 +2552,26 @@ xfs_bmap_btalloc(
2694 args.minleft = 0; 2552 args.minleft = 0;
2695 if ((error = xfs_alloc_vextent(&args))) 2553 if ((error = xfs_alloc_vextent(&args)))
2696 return error; 2554 return error;
2697 ap->low = 1; 2555 ap->flist->xbf_low = 1;
2698 } 2556 }
2699 if (args.fsbno != NULLFSBLOCK) { 2557 if (args.fsbno != NULLFSBLOCK) {
2700 ap->firstblock = ap->rval = args.fsbno; 2558 /*
2559 * check the allocation happened at the same or higher AG than
2560 * the first block that was allocated.
2561 */
2562 ASSERT(*ap->firstblock == NULLFSBLOCK ||
2563 XFS_FSB_TO_AGNO(mp, *ap->firstblock) ==
2564 XFS_FSB_TO_AGNO(mp, args.fsbno) ||
2565 (ap->flist->xbf_low &&
2566 XFS_FSB_TO_AGNO(mp, *ap->firstblock) <
2567 XFS_FSB_TO_AGNO(mp, args.fsbno)));
2568
2569 ap->blkno = args.fsbno;
2570 if (*ap->firstblock == NULLFSBLOCK)
2571 *ap->firstblock = args.fsbno;
2701 ASSERT(nullfb || fb_agno == args.agno || 2572 ASSERT(nullfb || fb_agno == args.agno ||
2702 (ap->low && fb_agno < args.agno)); 2573 (ap->flist->xbf_low && fb_agno < args.agno));
2703 ap->alen = args.len; 2574 ap->length = args.len;
2704 ap->ip->i_d.di_nblocks += args.len; 2575 ap->ip->i_d.di_nblocks += args.len;
2705 xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE); 2576 xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE);
2706 if (ap->wasdel) 2577 if (ap->wasdel)
@@ -2714,8 +2585,8 @@ xfs_bmap_btalloc(
2714 XFS_TRANS_DQ_BCOUNT, 2585 XFS_TRANS_DQ_BCOUNT,
2715 (long) args.len); 2586 (long) args.len);
2716 } else { 2587 } else {
2717 ap->rval = NULLFSBLOCK; 2588 ap->blkno = NULLFSBLOCK;
2718 ap->alen = 0; 2589 ap->length = 0;
2719 } 2590 }
2720 return 0; 2591 return 0;
2721} 2592}
@@ -3589,7 +3460,7 @@ xfs_bmap_add_attrfork(
3589 } 3460 }
3590 ASSERT(ip->i_d.di_anextents == 0); 3461 ASSERT(ip->i_d.di_anextents == 0);
3591 3462
3592 xfs_trans_ijoin_ref(tp, ip, XFS_ILOCK_EXCL); 3463 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
3593 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 3464 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
3594 3465
3595 switch (ip->i_d.di_format) { 3466 switch (ip->i_d.di_format) {
@@ -3782,19 +3653,11 @@ xfs_bmap_compute_maxlevels(
3782 * Routine to be called at transaction's end by xfs_bmapi, xfs_bunmapi 3653 * Routine to be called at transaction's end by xfs_bmapi, xfs_bunmapi
3783 * caller. Frees all the extents that need freeing, which must be done 3654 * caller. Frees all the extents that need freeing, which must be done
3784 * last due to locking considerations. We never free any extents in 3655 * last due to locking considerations. We never free any extents in
3785 * the first transaction. This is to allow the caller to make the first 3656 * the first transaction.
3786 * transaction a synchronous one so that the pointers to the data being
3787 * broken in this transaction will be permanent before the data is actually
3788 * freed. This is necessary to prevent blocks from being reallocated
3789 * and written to before the free and reallocation are actually permanent.
3790 * We do not just make the first transaction synchronous here, because
3791 * there are more efficient ways to gain the same protection in some cases
3792 * (see the file truncation code).
3793 * 3657 *
3794 * Return 1 if the given transaction was committed and a new one 3658 * Return 1 if the given transaction was committed and a new one
3795 * started, and 0 otherwise in the committed parameter. 3659 * started, and 0 otherwise in the committed parameter.
3796 */ 3660 */
3797/*ARGSUSED*/
3798int /* error */ 3661int /* error */
3799xfs_bmap_finish( 3662xfs_bmap_finish(
3800 xfs_trans_t **tp, /* transaction pointer addr */ 3663 xfs_trans_t **tp, /* transaction pointer addr */
@@ -3994,42 +3857,122 @@ xfs_bmap_last_before(
3994 return 0; 3857 return 0;
3995} 3858}
3996 3859
3860STATIC int
3861xfs_bmap_last_extent(
3862 struct xfs_trans *tp,
3863 struct xfs_inode *ip,
3864 int whichfork,
3865 struct xfs_bmbt_irec *rec,
3866 int *is_empty)
3867{
3868 struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
3869 int error;
3870 int nextents;
3871
3872 if (!(ifp->if_flags & XFS_IFEXTENTS)) {
3873 error = xfs_iread_extents(tp, ip, whichfork);
3874 if (error)
3875 return error;
3876 }
3877
3878 nextents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t);
3879 if (nextents == 0) {
3880 *is_empty = 1;
3881 return 0;
3882 }
3883
3884 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, nextents - 1), rec);
3885 *is_empty = 0;
3886 return 0;
3887}
3888
3889/*
3890 * Check the last inode extent to determine whether this allocation will result
3891 * in blocks being allocated at the end of the file. When we allocate new data
3892 * blocks at the end of the file which do not start at the previous data block,
3893 * we will try to align the new blocks at stripe unit boundaries.
3894 *
3895 * Returns 0 in bma->aeof if the file (fork) is empty as any new write will be
3896 * at, or past the EOF.
3897 */
3898STATIC int
3899xfs_bmap_isaeof(
3900 struct xfs_bmalloca *bma,
3901 int whichfork)
3902{
3903 struct xfs_bmbt_irec rec;
3904 int is_empty;
3905 int error;
3906
3907 bma->aeof = 0;
3908 error = xfs_bmap_last_extent(NULL, bma->ip, whichfork, &rec,
3909 &is_empty);
3910 if (error || is_empty)
3911 return error;
3912
3913 /*
3914 * Check if we are allocation or past the last extent, or at least into
3915 * the last delayed allocated extent.
3916 */
3917 bma->aeof = bma->offset >= rec.br_startoff + rec.br_blockcount ||
3918 (bma->offset >= rec.br_startoff &&
3919 isnullstartblock(rec.br_startblock));
3920 return 0;
3921}
3922
3923/*
3924 * Check if the endoff is outside the last extent. If so the caller will grow
3925 * the allocation to a stripe unit boundary. All offsets are considered outside
3926 * the end of file for an empty fork, so 1 is returned in *eof in that case.
3927 */
3928int
3929xfs_bmap_eof(
3930 struct xfs_inode *ip,
3931 xfs_fileoff_t endoff,
3932 int whichfork,
3933 int *eof)
3934{
3935 struct xfs_bmbt_irec rec;
3936 int error;
3937
3938 error = xfs_bmap_last_extent(NULL, ip, whichfork, &rec, eof);
3939 if (error || *eof)
3940 return error;
3941
3942 *eof = endoff >= rec.br_startoff + rec.br_blockcount;
3943 return 0;
3944}
3945
3997/* 3946/*
3998 * Returns the file-relative block number of the first block past eof in 3947 * Returns the file-relative block number of the first block past eof in
3999 * the file. This is not based on i_size, it is based on the extent records. 3948 * the file. This is not based on i_size, it is based on the extent records.
4000 * Returns 0 for local files, as they do not have extent records. 3949 * Returns 0 for local files, as they do not have extent records.
4001 */ 3950 */
4002int /* error */ 3951int
4003xfs_bmap_last_offset( 3952xfs_bmap_last_offset(
4004 xfs_trans_t *tp, /* transaction pointer */ 3953 struct xfs_trans *tp,
4005 xfs_inode_t *ip, /* incore inode */ 3954 struct xfs_inode *ip,
4006 xfs_fileoff_t *last_block, /* last block */ 3955 xfs_fileoff_t *last_block,
4007 int whichfork) /* data or attr fork */ 3956 int whichfork)
4008{ 3957{
4009 xfs_bmbt_rec_host_t *ep; /* pointer to last extent */ 3958 struct xfs_bmbt_irec rec;
4010 int error; /* error return value */ 3959 int is_empty;
4011 xfs_ifork_t *ifp; /* inode fork pointer */ 3960 int error;
4012 xfs_extnum_t nextents; /* number of extent entries */ 3961
3962 *last_block = 0;
3963
3964 if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL)
3965 return 0;
4013 3966
4014 if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE && 3967 if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE &&
4015 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && 3968 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS)
4016 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL)
4017 return XFS_ERROR(EIO); 3969 return XFS_ERROR(EIO);
4018 if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { 3970
4019 *last_block = 0; 3971 error = xfs_bmap_last_extent(NULL, ip, whichfork, &rec, &is_empty);
4020 return 0; 3972 if (error || is_empty)
4021 }
4022 ifp = XFS_IFORK_PTR(ip, whichfork);
4023 if (!(ifp->if_flags & XFS_IFEXTENTS) &&
4024 (error = xfs_iread_extents(tp, ip, whichfork)))
4025 return error; 3973 return error;
4026 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 3974
4027 if (!nextents) { 3975 *last_block = rec.br_startoff + rec.br_blockcount;
4028 *last_block = 0;
4029 return 0;
4030 }
4031 ep = xfs_iext_get_ext(ifp, nextents - 1);
4032 *last_block = xfs_bmbt_get_startoff(ep) + xfs_bmbt_get_blockcount(ep);
4033 return 0; 3976 return 0;
4034} 3977}
4035 3978
@@ -4159,7 +4102,6 @@ xfs_bmap_read_extents(
4159 xfs_extnum_t num_recs; 4102 xfs_extnum_t num_recs;
4160 xfs_extnum_t start; 4103 xfs_extnum_t start;
4161 4104
4162
4163 num_recs = xfs_btree_get_numrecs(block); 4105 num_recs = xfs_btree_get_numrecs(block);
4164 if (unlikely(i + num_recs > room)) { 4106 if (unlikely(i + num_recs > room)) {
4165 ASSERT(i + num_recs <= room); 4107 ASSERT(i + num_recs <= room);
@@ -4282,9 +4224,8 @@ xfs_bmap_validate_ret(
4282 ASSERT(i == 0 || 4224 ASSERT(i == 0 ||
4283 mval[i - 1].br_startoff + mval[i - 1].br_blockcount == 4225 mval[i - 1].br_startoff + mval[i - 1].br_blockcount ==
4284 mval[i].br_startoff); 4226 mval[i].br_startoff);
4285 if ((flags & XFS_BMAPI_WRITE) && !(flags & XFS_BMAPI_DELAY)) 4227 ASSERT(mval[i].br_startblock != DELAYSTARTBLOCK &&
4286 ASSERT(mval[i].br_startblock != DELAYSTARTBLOCK && 4228 mval[i].br_startblock != HOLESTARTBLOCK);
4287 mval[i].br_startblock != HOLESTARTBLOCK);
4288 ASSERT(mval[i].br_state == XFS_EXT_NORM || 4229 ASSERT(mval[i].br_state == XFS_EXT_NORM ||
4289 mval[i].br_state == XFS_EXT_UNWRITTEN); 4230 mval[i].br_state == XFS_EXT_UNWRITTEN);
4290 } 4231 }
@@ -4293,66 +4234,609 @@ xfs_bmap_validate_ret(
4293 4234
4294 4235
4295/* 4236/*
4296 * Map file blocks to filesystem blocks. 4237 * Trim the returned map to the required bounds
4297 * File range is given by the bno/len pair. 4238 */
4298 * Adds blocks to file if a write ("flags & XFS_BMAPI_WRITE" set) 4239STATIC void
4299 * into a hole or past eof. 4240xfs_bmapi_trim_map(
4300 * Only allocates blocks from a single allocation group, 4241 struct xfs_bmbt_irec *mval,
4301 * to avoid locking problems. 4242 struct xfs_bmbt_irec *got,
4243 xfs_fileoff_t *bno,
4244 xfs_filblks_t len,
4245 xfs_fileoff_t obno,
4246 xfs_fileoff_t end,
4247 int n,
4248 int flags)
4249{
4250 if ((flags & XFS_BMAPI_ENTIRE) ||
4251 got->br_startoff + got->br_blockcount <= obno) {
4252 *mval = *got;
4253 if (isnullstartblock(got->br_startblock))
4254 mval->br_startblock = DELAYSTARTBLOCK;
4255 return;
4256 }
4257
4258 if (obno > *bno)
4259 *bno = obno;
4260 ASSERT((*bno >= obno) || (n == 0));
4261 ASSERT(*bno < end);
4262 mval->br_startoff = *bno;
4263 if (isnullstartblock(got->br_startblock))
4264 mval->br_startblock = DELAYSTARTBLOCK;
4265 else
4266 mval->br_startblock = got->br_startblock +
4267 (*bno - got->br_startoff);
4268 /*
4269 * Return the minimum of what we got and what we asked for for
4270 * the length. We can use the len variable here because it is
4271 * modified below and we could have been there before coming
4272 * here if the first part of the allocation didn't overlap what
4273 * was asked for.
4274 */
4275 mval->br_blockcount = XFS_FILBLKS_MIN(end - *bno,
4276 got->br_blockcount - (*bno - got->br_startoff));
4277 mval->br_state = got->br_state;
4278 ASSERT(mval->br_blockcount <= len);
4279 return;
4280}
4281
4282/*
4283 * Update and validate the extent map to return
4284 */
4285STATIC void
4286xfs_bmapi_update_map(
4287 struct xfs_bmbt_irec **map,
4288 xfs_fileoff_t *bno,
4289 xfs_filblks_t *len,
4290 xfs_fileoff_t obno,
4291 xfs_fileoff_t end,
4292 int *n,
4293 int flags)
4294{
4295 xfs_bmbt_irec_t *mval = *map;
4296
4297 ASSERT((flags & XFS_BMAPI_ENTIRE) ||
4298 ((mval->br_startoff + mval->br_blockcount) <= end));
4299 ASSERT((flags & XFS_BMAPI_ENTIRE) || (mval->br_blockcount <= *len) ||
4300 (mval->br_startoff < obno));
4301
4302 *bno = mval->br_startoff + mval->br_blockcount;
4303 *len = end - *bno;
4304 if (*n > 0 && mval->br_startoff == mval[-1].br_startoff) {
4305 /* update previous map with new information */
4306 ASSERT(mval->br_startblock == mval[-1].br_startblock);
4307 ASSERT(mval->br_blockcount > mval[-1].br_blockcount);
4308 ASSERT(mval->br_state == mval[-1].br_state);
4309 mval[-1].br_blockcount = mval->br_blockcount;
4310 mval[-1].br_state = mval->br_state;
4311 } else if (*n > 0 && mval->br_startblock != DELAYSTARTBLOCK &&
4312 mval[-1].br_startblock != DELAYSTARTBLOCK &&
4313 mval[-1].br_startblock != HOLESTARTBLOCK &&
4314 mval->br_startblock == mval[-1].br_startblock +
4315 mval[-1].br_blockcount &&
4316 ((flags & XFS_BMAPI_IGSTATE) ||
4317 mval[-1].br_state == mval->br_state)) {
4318 ASSERT(mval->br_startoff ==
4319 mval[-1].br_startoff + mval[-1].br_blockcount);
4320 mval[-1].br_blockcount += mval->br_blockcount;
4321 } else if (*n > 0 &&
4322 mval->br_startblock == DELAYSTARTBLOCK &&
4323 mval[-1].br_startblock == DELAYSTARTBLOCK &&
4324 mval->br_startoff ==
4325 mval[-1].br_startoff + mval[-1].br_blockcount) {
4326 mval[-1].br_blockcount += mval->br_blockcount;
4327 mval[-1].br_state = mval->br_state;
4328 } else if (!((*n == 0) &&
4329 ((mval->br_startoff + mval->br_blockcount) <=
4330 obno))) {
4331 mval++;
4332 (*n)++;
4333 }
4334 *map = mval;
4335}
4336
4337/*
4338 * Map file blocks to filesystem blocks without allocation.
4339 */
4340int
4341xfs_bmapi_read(
4342 struct xfs_inode *ip,
4343 xfs_fileoff_t bno,
4344 xfs_filblks_t len,
4345 struct xfs_bmbt_irec *mval,
4346 int *nmap,
4347 int flags)
4348{
4349 struct xfs_mount *mp = ip->i_mount;
4350 struct xfs_ifork *ifp;
4351 struct xfs_bmbt_irec got;
4352 struct xfs_bmbt_irec prev;
4353 xfs_fileoff_t obno;
4354 xfs_fileoff_t end;
4355 xfs_extnum_t lastx;
4356 int error;
4357 int eof;
4358 int n = 0;
4359 int whichfork = (flags & XFS_BMAPI_ATTRFORK) ?
4360 XFS_ATTR_FORK : XFS_DATA_FORK;
4361
4362 ASSERT(*nmap >= 1);
4363 ASSERT(!(flags & ~(XFS_BMAPI_ATTRFORK|XFS_BMAPI_ENTIRE|
4364 XFS_BMAPI_IGSTATE)));
4365
4366 if (unlikely(XFS_TEST_ERROR(
4367 (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
4368 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE),
4369 mp, XFS_ERRTAG_BMAPIFORMAT, XFS_RANDOM_BMAPIFORMAT))) {
4370 XFS_ERROR_REPORT("xfs_bmapi_read", XFS_ERRLEVEL_LOW, mp);
4371 return XFS_ERROR(EFSCORRUPTED);
4372 }
4373
4374 if (XFS_FORCED_SHUTDOWN(mp))
4375 return XFS_ERROR(EIO);
4376
4377 XFS_STATS_INC(xs_blk_mapr);
4378
4379 ifp = XFS_IFORK_PTR(ip, whichfork);
4380 ASSERT(ifp->if_ext_max ==
4381 XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
4382
4383 if (!(ifp->if_flags & XFS_IFEXTENTS)) {
4384 error = xfs_iread_extents(NULL, ip, whichfork);
4385 if (error)
4386 return error;
4387 }
4388
4389 xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, &prev);
4390 end = bno + len;
4391 obno = bno;
4392
4393 while (bno < end && n < *nmap) {
4394 /* Reading past eof, act as though there's a hole up to end. */
4395 if (eof)
4396 got.br_startoff = end;
4397 if (got.br_startoff > bno) {
4398 /* Reading in a hole. */
4399 mval->br_startoff = bno;
4400 mval->br_startblock = HOLESTARTBLOCK;
4401 mval->br_blockcount =
4402 XFS_FILBLKS_MIN(len, got.br_startoff - bno);
4403 mval->br_state = XFS_EXT_NORM;
4404 bno += mval->br_blockcount;
4405 len -= mval->br_blockcount;
4406 mval++;
4407 n++;
4408 continue;
4409 }
4410
4411 /* set up the extent map to return. */
4412 xfs_bmapi_trim_map(mval, &got, &bno, len, obno, end, n, flags);
4413 xfs_bmapi_update_map(&mval, &bno, &len, obno, end, &n, flags);
4414
4415 /* If we're done, stop now. */
4416 if (bno >= end || n >= *nmap)
4417 break;
4418
4419 /* Else go on to the next record. */
4420 if (++lastx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t))
4421 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx), &got);
4422 else
4423 eof = 1;
4424 }
4425 *nmap = n;
4426 return 0;
4427}
4428
4429STATIC int
4430xfs_bmapi_reserve_delalloc(
4431 struct xfs_inode *ip,
4432 xfs_fileoff_t aoff,
4433 xfs_filblks_t len,
4434 struct xfs_bmbt_irec *got,
4435 struct xfs_bmbt_irec *prev,
4436 xfs_extnum_t *lastx,
4437 int eof)
4438{
4439 struct xfs_mount *mp = ip->i_mount;
4440 struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
4441 xfs_extlen_t alen;
4442 xfs_extlen_t indlen;
4443 char rt = XFS_IS_REALTIME_INODE(ip);
4444 xfs_extlen_t extsz;
4445 int error;
4446
4447 alen = XFS_FILBLKS_MIN(len, MAXEXTLEN);
4448 if (!eof)
4449 alen = XFS_FILBLKS_MIN(alen, got->br_startoff - aoff);
4450
4451 /* Figure out the extent size, adjust alen */
4452 extsz = xfs_get_extsz_hint(ip);
4453 if (extsz) {
4454 /*
4455 * Make sure we don't exceed a single extent length when we
4456 * align the extent by reducing length we are going to
4457 * allocate by the maximum amount extent size aligment may
4458 * require.
4459 */
4460 alen = XFS_FILBLKS_MIN(len, MAXEXTLEN - (2 * extsz - 1));
4461 error = xfs_bmap_extsize_align(mp, got, prev, extsz, rt, eof,
4462 1, 0, &aoff, &alen);
4463 ASSERT(!error);
4464 }
4465
4466 if (rt)
4467 extsz = alen / mp->m_sb.sb_rextsize;
4468
4469 /*
4470 * Make a transaction-less quota reservation for delayed allocation
4471 * blocks. This number gets adjusted later. We return if we haven't
4472 * allocated blocks already inside this loop.
4473 */
4474 error = xfs_trans_reserve_quota_nblks(NULL, ip, (long)alen, 0,
4475 rt ? XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS);
4476 if (error)
4477 return error;
4478
4479 /*
4480 * Split changing sb for alen and indlen since they could be coming
4481 * from different places.
4482 */
4483 indlen = (xfs_extlen_t)xfs_bmap_worst_indlen(ip, alen);
4484 ASSERT(indlen > 0);
4485
4486 if (rt) {
4487 error = xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS,
4488 -((int64_t)extsz), 0);
4489 } else {
4490 error = xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS,
4491 -((int64_t)alen), 0);
4492 }
4493
4494 if (error)
4495 goto out_unreserve_quota;
4496
4497 error = xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS,
4498 -((int64_t)indlen), 0);
4499 if (error)
4500 goto out_unreserve_blocks;
4501
4502
4503 ip->i_delayed_blks += alen;
4504
4505 got->br_startoff = aoff;
4506 got->br_startblock = nullstartblock(indlen);
4507 got->br_blockcount = alen;
4508 got->br_state = XFS_EXT_NORM;
4509 xfs_bmap_add_extent_hole_delay(ip, lastx, got);
4510
4511 /*
4512 * Update our extent pointer, given that xfs_bmap_add_extent_hole_delay
4513 * might have merged it into one of the neighbouring ones.
4514 */
4515 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *lastx), got);
4516
4517 ASSERT(got->br_startoff <= aoff);
4518 ASSERT(got->br_startoff + got->br_blockcount >= aoff + alen);
4519 ASSERT(isnullstartblock(got->br_startblock));
4520 ASSERT(got->br_state == XFS_EXT_NORM);
4521 return 0;
4522
4523out_unreserve_blocks:
4524 if (rt)
4525 xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS, extsz, 0);
4526 else
4527 xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, alen, 0);
4528out_unreserve_quota:
4529 if (XFS_IS_QUOTA_ON(mp))
4530 xfs_trans_unreserve_quota_nblks(NULL, ip, alen, 0, rt ?
4531 XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS);
4532 return error;
4533}
4534
4535/*
4536 * Map file blocks to filesystem blocks, adding delayed allocations as needed.
4537 */
4538int
4539xfs_bmapi_delay(
4540 struct xfs_inode *ip, /* incore inode */
4541 xfs_fileoff_t bno, /* starting file offs. mapped */
4542 xfs_filblks_t len, /* length to map in file */
4543 struct xfs_bmbt_irec *mval, /* output: map values */
4544 int *nmap, /* i/o: mval size/count */
4545 int flags) /* XFS_BMAPI_... */
4546{
4547 struct xfs_mount *mp = ip->i_mount;
4548 struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
4549 struct xfs_bmbt_irec got; /* current file extent record */
4550 struct xfs_bmbt_irec prev; /* previous file extent record */
4551 xfs_fileoff_t obno; /* old block number (offset) */
4552 xfs_fileoff_t end; /* end of mapped file region */
4553 xfs_extnum_t lastx; /* last useful extent number */
4554 int eof; /* we've hit the end of extents */
4555 int n = 0; /* current extent index */
4556 int error = 0;
4557
4558 ASSERT(*nmap >= 1);
4559 ASSERT(*nmap <= XFS_BMAP_MAX_NMAP);
4560 ASSERT(!(flags & ~XFS_BMAPI_ENTIRE));
4561
4562 if (unlikely(XFS_TEST_ERROR(
4563 (XFS_IFORK_FORMAT(ip, XFS_DATA_FORK) != XFS_DINODE_FMT_EXTENTS &&
4564 XFS_IFORK_FORMAT(ip, XFS_DATA_FORK) != XFS_DINODE_FMT_BTREE),
4565 mp, XFS_ERRTAG_BMAPIFORMAT, XFS_RANDOM_BMAPIFORMAT))) {
4566 XFS_ERROR_REPORT("xfs_bmapi_delay", XFS_ERRLEVEL_LOW, mp);
4567 return XFS_ERROR(EFSCORRUPTED);
4568 }
4569
4570 if (XFS_FORCED_SHUTDOWN(mp))
4571 return XFS_ERROR(EIO);
4572
4573 XFS_STATS_INC(xs_blk_mapw);
4574
4575 if (!(ifp->if_flags & XFS_IFEXTENTS)) {
4576 error = xfs_iread_extents(NULL, ip, XFS_DATA_FORK);
4577 if (error)
4578 return error;
4579 }
4580
4581 xfs_bmap_search_extents(ip, bno, XFS_DATA_FORK, &eof, &lastx, &got, &prev);
4582 end = bno + len;
4583 obno = bno;
4584
4585 while (bno < end && n < *nmap) {
4586 if (eof || got.br_startoff > bno) {
4587 error = xfs_bmapi_reserve_delalloc(ip, bno, len, &got,
4588 &prev, &lastx, eof);
4589 if (error) {
4590 if (n == 0) {
4591 *nmap = 0;
4592 return error;
4593 }
4594 break;
4595 }
4596 }
4597
4598 /* set up the extent map to return. */
4599 xfs_bmapi_trim_map(mval, &got, &bno, len, obno, end, n, flags);
4600 xfs_bmapi_update_map(&mval, &bno, &len, obno, end, &n, flags);
4601
4602 /* If we're done, stop now. */
4603 if (bno >= end || n >= *nmap)
4604 break;
4605
4606 /* Else go on to the next record. */
4607 prev = got;
4608 if (++lastx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t))
4609 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx), &got);
4610 else
4611 eof = 1;
4612 }
4613
4614 *nmap = n;
4615 return 0;
4616}
4617
4618
4619STATIC int
4620xfs_bmapi_allocate(
4621 struct xfs_bmalloca *bma,
4622 int flags)
4623{
4624 struct xfs_mount *mp = bma->ip->i_mount;
4625 int whichfork = (flags & XFS_BMAPI_ATTRFORK) ?
4626 XFS_ATTR_FORK : XFS_DATA_FORK;
4627 struct xfs_ifork *ifp = XFS_IFORK_PTR(bma->ip, whichfork);
4628 int tmp_logflags = 0;
4629 int error;
4630 int rt;
4631
4632 rt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(bma->ip);
4633
4634 /*
4635 * For the wasdelay case, we could also just allocate the stuff asked
4636 * for in this bmap call but that wouldn't be as good.
4637 */
4638 if (bma->wasdel) {
4639 bma->length = (xfs_extlen_t)bma->got.br_blockcount;
4640 bma->offset = bma->got.br_startoff;
4641 if (bma->idx != NULLEXTNUM && bma->idx) {
4642 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma->idx - 1),
4643 &bma->prev);
4644 }
4645 } else {
4646 bma->length = XFS_FILBLKS_MIN(bma->length, MAXEXTLEN);
4647 if (!bma->eof)
4648 bma->length = XFS_FILBLKS_MIN(bma->length,
4649 bma->got.br_startoff - bma->offset);
4650 }
4651
4652 /*
4653 * Indicate if this is the first user data in the file, or just any
4654 * user data.
4655 */
4656 if (!(flags & XFS_BMAPI_METADATA)) {
4657 bma->userdata = (bma->offset == 0) ?
4658 XFS_ALLOC_INITIAL_USER_DATA : XFS_ALLOC_USERDATA;
4659 }
4660
4661 bma->minlen = (flags & XFS_BMAPI_CONTIG) ? bma->length : 1;
4662
4663 /*
4664 * Only want to do the alignment at the eof if it is userdata and
4665 * allocation length is larger than a stripe unit.
4666 */
4667 if (mp->m_dalign && bma->length >= mp->m_dalign &&
4668 !(flags & XFS_BMAPI_METADATA) && whichfork == XFS_DATA_FORK) {
4669 error = xfs_bmap_isaeof(bma, whichfork);
4670 if (error)
4671 return error;
4672 }
4673
4674 error = xfs_bmap_alloc(bma);
4675 if (error)
4676 return error;
4677
4678 if (bma->flist->xbf_low)
4679 bma->minleft = 0;
4680 if (bma->cur)
4681 bma->cur->bc_private.b.firstblock = *bma->firstblock;
4682 if (bma->blkno == NULLFSBLOCK)
4683 return 0;
4684 if ((ifp->if_flags & XFS_IFBROOT) && !bma->cur) {
4685 bma->cur = xfs_bmbt_init_cursor(mp, bma->tp, bma->ip, whichfork);
4686 bma->cur->bc_private.b.firstblock = *bma->firstblock;
4687 bma->cur->bc_private.b.flist = bma->flist;
4688 }
4689 /*
4690 * Bump the number of extents we've allocated
4691 * in this call.
4692 */
4693 bma->nallocs++;
4694
4695 if (bma->cur)
4696 bma->cur->bc_private.b.flags =
4697 bma->wasdel ? XFS_BTCUR_BPRV_WASDEL : 0;
4698
4699 bma->got.br_startoff = bma->offset;
4700 bma->got.br_startblock = bma->blkno;
4701 bma->got.br_blockcount = bma->length;
4702 bma->got.br_state = XFS_EXT_NORM;
4703
4704 /*
4705 * A wasdelay extent has been initialized, so shouldn't be flagged
4706 * as unwritten.
4707 */
4708 if (!bma->wasdel && (flags & XFS_BMAPI_PREALLOC) &&
4709 xfs_sb_version_hasextflgbit(&mp->m_sb))
4710 bma->got.br_state = XFS_EXT_UNWRITTEN;
4711
4712 if (bma->wasdel)
4713 error = xfs_bmap_add_extent_delay_real(bma);
4714 else
4715 error = xfs_bmap_add_extent_hole_real(bma, whichfork);
4716
4717 bma->logflags |= tmp_logflags;
4718 if (error)
4719 return error;
4720
4721 /*
4722 * Update our extent pointer, given that xfs_bmap_add_extent_delay_real
4723 * or xfs_bmap_add_extent_hole_real might have merged it into one of
4724 * the neighbouring ones.
4725 */
4726 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma->idx), &bma->got);
4727
4728 ASSERT(bma->got.br_startoff <= bma->offset);
4729 ASSERT(bma->got.br_startoff + bma->got.br_blockcount >=
4730 bma->offset + bma->length);
4731 ASSERT(bma->got.br_state == XFS_EXT_NORM ||
4732 bma->got.br_state == XFS_EXT_UNWRITTEN);
4733 return 0;
4734}
4735
4736STATIC int
4737xfs_bmapi_convert_unwritten(
4738 struct xfs_bmalloca *bma,
4739 struct xfs_bmbt_irec *mval,
4740 xfs_filblks_t len,
4741 int flags)
4742{
4743 int whichfork = (flags & XFS_BMAPI_ATTRFORK) ?
4744 XFS_ATTR_FORK : XFS_DATA_FORK;
4745 struct xfs_ifork *ifp = XFS_IFORK_PTR(bma->ip, whichfork);
4746 int tmp_logflags = 0;
4747 int error;
4748
4749 /* check if we need to do unwritten->real conversion */
4750 if (mval->br_state == XFS_EXT_UNWRITTEN &&
4751 (flags & XFS_BMAPI_PREALLOC))
4752 return 0;
4753
4754 /* check if we need to do real->unwritten conversion */
4755 if (mval->br_state == XFS_EXT_NORM &&
4756 (flags & (XFS_BMAPI_PREALLOC | XFS_BMAPI_CONVERT)) !=
4757 (XFS_BMAPI_PREALLOC | XFS_BMAPI_CONVERT))
4758 return 0;
4759
4760 /*
4761 * Modify (by adding) the state flag, if writing.
4762 */
4763 ASSERT(mval->br_blockcount <= len);
4764 if ((ifp->if_flags & XFS_IFBROOT) && !bma->cur) {
4765 bma->cur = xfs_bmbt_init_cursor(bma->ip->i_mount, bma->tp,
4766 bma->ip, whichfork);
4767 bma->cur->bc_private.b.firstblock = *bma->firstblock;
4768 bma->cur->bc_private.b.flist = bma->flist;
4769 }
4770 mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN)
4771 ? XFS_EXT_NORM : XFS_EXT_UNWRITTEN;
4772
4773 error = xfs_bmap_add_extent_unwritten_real(bma->tp, bma->ip, &bma->idx,
4774 &bma->cur, mval, bma->firstblock, bma->flist,
4775 &tmp_logflags);
4776 bma->logflags |= tmp_logflags;
4777 if (error)
4778 return error;
4779
4780 /*
4781 * Update our extent pointer, given that
4782 * xfs_bmap_add_extent_unwritten_real might have merged it into one
4783 * of the neighbouring ones.
4784 */
4785 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma->idx), &bma->got);
4786
4787 /*
4788 * We may have combined previously unwritten space with written space,
4789 * so generate another request.
4790 */
4791 if (mval->br_blockcount < len)
4792 return EAGAIN;
4793 return 0;
4794}
4795
4796/*
4797 * Map file blocks to filesystem blocks, and allocate blocks or convert the
4798 * extent state if necessary. Details behaviour is controlled by the flags
4799 * parameter. Only allocates blocks from a single allocation group, to avoid
4800 * locking problems.
4801 *
4302 * The returned value in "firstblock" from the first call in a transaction 4802 * The returned value in "firstblock" from the first call in a transaction
4303 * must be remembered and presented to subsequent calls in "firstblock". 4803 * must be remembered and presented to subsequent calls in "firstblock".
4304 * An upper bound for the number of blocks to be allocated is supplied to 4804 * An upper bound for the number of blocks to be allocated is supplied to
4305 * the first call in "total"; if no allocation group has that many free 4805 * the first call in "total"; if no allocation group has that many free
4306 * blocks then the call will fail (return NULLFSBLOCK in "firstblock"). 4806 * blocks then the call will fail (return NULLFSBLOCK in "firstblock").
4307 */ 4807 */
4308int /* error */ 4808int
4309xfs_bmapi( 4809xfs_bmapi_write(
4310 xfs_trans_t *tp, /* transaction pointer */ 4810 struct xfs_trans *tp, /* transaction pointer */
4311 xfs_inode_t *ip, /* incore inode */ 4811 struct xfs_inode *ip, /* incore inode */
4312 xfs_fileoff_t bno, /* starting file offs. mapped */ 4812 xfs_fileoff_t bno, /* starting file offs. mapped */
4313 xfs_filblks_t len, /* length to map in file */ 4813 xfs_filblks_t len, /* length to map in file */
4314 int flags, /* XFS_BMAPI_... */ 4814 int flags, /* XFS_BMAPI_... */
4315 xfs_fsblock_t *firstblock, /* first allocated block 4815 xfs_fsblock_t *firstblock, /* first allocated block
4316 controls a.g. for allocs */ 4816 controls a.g. for allocs */
4317 xfs_extlen_t total, /* total blocks needed */ 4817 xfs_extlen_t total, /* total blocks needed */
4318 xfs_bmbt_irec_t *mval, /* output: map values */ 4818 struct xfs_bmbt_irec *mval, /* output: map values */
4319 int *nmap, /* i/o: mval size/count */ 4819 int *nmap, /* i/o: mval size/count */
4320 xfs_bmap_free_t *flist) /* i/o: list extents to free */ 4820 struct xfs_bmap_free *flist) /* i/o: list extents to free */
4321{ 4821{
4322 xfs_fsblock_t abno; /* allocated block number */ 4822 struct xfs_mount *mp = ip->i_mount;
4323 xfs_extlen_t alen; /* allocated extent length */ 4823 struct xfs_ifork *ifp;
4324 xfs_fileoff_t aoff; /* allocated file offset */ 4824 struct xfs_bmalloca bma = { 0 }; /* args for xfs_bmap_alloc */
4325 xfs_bmalloca_t bma = { 0 }; /* args for xfs_bmap_alloc */ 4825 xfs_fileoff_t end; /* end of mapped file region */
4326 xfs_btree_cur_t *cur; /* bmap btree cursor */ 4826 int eof; /* after the end of extents */
4327 xfs_fileoff_t end; /* end of mapped file region */ 4827 int error; /* error return */
4328 int eof; /* we've hit the end of extents */ 4828 int n; /* current extent index */
4329 xfs_bmbt_rec_host_t *ep; /* extent record pointer */ 4829 xfs_fileoff_t obno; /* old block number (offset) */
4330 int error; /* error return */ 4830 int whichfork; /* data or attr fork */
4331 xfs_bmbt_irec_t got; /* current file extent record */ 4831 char inhole; /* current location is hole in file */
4332 xfs_ifork_t *ifp; /* inode fork pointer */ 4832 char wasdelay; /* old extent was delayed */
4333 xfs_extlen_t indlen; /* indirect blocks length */ 4833
4334 xfs_extnum_t lastx; /* last useful extent number */
4335 int logflags; /* flags for transaction logging */
4336 xfs_extlen_t minleft; /* min blocks left after allocation */
4337 xfs_extlen_t minlen; /* min allocation size */
4338 xfs_mount_t *mp; /* xfs mount structure */
4339 int n; /* current extent index */
4340 int nallocs; /* number of extents alloc'd */
4341 xfs_extnum_t nextents; /* number of extents in file */
4342 xfs_fileoff_t obno; /* old block number (offset) */
4343 xfs_bmbt_irec_t prev; /* previous file extent record */
4344 int tmp_logflags; /* temp flags holder */
4345 int whichfork; /* data or attr fork */
4346 char inhole; /* current location is hole in file */
4347 char wasdelay; /* old extent was delayed */
4348 char wr; /* this is a write request */
4349 char rt; /* this is a realtime file */
4350#ifdef DEBUG 4834#ifdef DEBUG
4351 xfs_fileoff_t orig_bno; /* original block number value */ 4835 xfs_fileoff_t orig_bno; /* original block number value */
4352 int orig_flags; /* original flags arg value */ 4836 int orig_flags; /* original flags arg value */
4353 xfs_filblks_t orig_len; /* original value of len arg */ 4837 xfs_filblks_t orig_len; /* original value of len arg */
4354 xfs_bmbt_irec_t *orig_mval; /* original value of mval */ 4838 struct xfs_bmbt_irec *orig_mval; /* original value of mval */
4355 int orig_nmap; /* original value of *nmap */ 4839 int orig_nmap; /* original value of *nmap */
4356 4840
4357 orig_bno = bno; 4841 orig_bno = bno;
4358 orig_len = len; 4842 orig_len = len;
@@ -4360,488 +4844,133 @@ xfs_bmapi(
4360 orig_mval = mval; 4844 orig_mval = mval;
4361 orig_nmap = *nmap; 4845 orig_nmap = *nmap;
4362#endif 4846#endif
4847
4363 ASSERT(*nmap >= 1); 4848 ASSERT(*nmap >= 1);
4364 ASSERT(*nmap <= XFS_BMAP_MAX_NMAP || !(flags & XFS_BMAPI_WRITE)); 4849 ASSERT(*nmap <= XFS_BMAP_MAX_NMAP);
4850 ASSERT(!(flags & XFS_BMAPI_IGSTATE));
4851 ASSERT(tp != NULL);
4852
4365 whichfork = (flags & XFS_BMAPI_ATTRFORK) ? 4853 whichfork = (flags & XFS_BMAPI_ATTRFORK) ?
4366 XFS_ATTR_FORK : XFS_DATA_FORK; 4854 XFS_ATTR_FORK : XFS_DATA_FORK;
4367 mp = ip->i_mount; 4855
4368 if (unlikely(XFS_TEST_ERROR( 4856 if (unlikely(XFS_TEST_ERROR(
4369 (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && 4857 (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
4370 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE && 4858 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE &&
4371 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL), 4859 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL),
4372 mp, XFS_ERRTAG_BMAPIFORMAT, XFS_RANDOM_BMAPIFORMAT))) { 4860 mp, XFS_ERRTAG_BMAPIFORMAT, XFS_RANDOM_BMAPIFORMAT))) {
4373 XFS_ERROR_REPORT("xfs_bmapi", XFS_ERRLEVEL_LOW, mp); 4861 XFS_ERROR_REPORT("xfs_bmapi_write", XFS_ERRLEVEL_LOW, mp);
4374 return XFS_ERROR(EFSCORRUPTED); 4862 return XFS_ERROR(EFSCORRUPTED);
4375 } 4863 }
4864
4376 if (XFS_FORCED_SHUTDOWN(mp)) 4865 if (XFS_FORCED_SHUTDOWN(mp))
4377 return XFS_ERROR(EIO); 4866 return XFS_ERROR(EIO);
4378 rt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip); 4867
4379 ifp = XFS_IFORK_PTR(ip, whichfork); 4868 ifp = XFS_IFORK_PTR(ip, whichfork);
4380 ASSERT(ifp->if_ext_max == 4869 ASSERT(ifp->if_ext_max ==
4381 XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t)); 4870 XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
4382 if ((wr = (flags & XFS_BMAPI_WRITE)) != 0) 4871
4383 XFS_STATS_INC(xs_blk_mapw); 4872 XFS_STATS_INC(xs_blk_mapw);
4384 else 4873
4385 XFS_STATS_INC(xs_blk_mapr);
4386 /*
4387 * IGSTATE flag is used to combine extents which
4388 * differ only due to the state of the extents.
4389 * This technique is used from xfs_getbmap()
4390 * when the caller does not wish to see the
4391 * separation (which is the default).
4392 *
4393 * This technique is also used when writing a
4394 * buffer which has been partially written,
4395 * (usually by being flushed during a chunkread),
4396 * to ensure one write takes place. This also
4397 * prevents a change in the xfs inode extents at
4398 * this time, intentionally. This change occurs
4399 * on completion of the write operation, in
4400 * xfs_strat_comp(), where the xfs_bmapi() call
4401 * is transactioned, and the extents combined.
4402 */
4403 if ((flags & XFS_BMAPI_IGSTATE) && wr) /* if writing unwritten space */
4404 wr = 0; /* no allocations are allowed */
4405 ASSERT(wr || !(flags & XFS_BMAPI_DELAY));
4406 logflags = 0;
4407 nallocs = 0;
4408 cur = NULL;
4409 if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { 4874 if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) {
4410 ASSERT(wr && tp); 4875 error = xfs_bmap_local_to_extents(tp, ip, firstblock, total,
4411 if ((error = xfs_bmap_local_to_extents(tp, ip, 4876 &bma.logflags, whichfork);
4412 firstblock, total, &logflags, whichfork))) 4877 if (error)
4413 goto error0; 4878 goto error0;
4414 } 4879 }
4415 if (wr && *firstblock == NULLFSBLOCK) { 4880
4881 if (*firstblock == NULLFSBLOCK) {
4416 if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE) 4882 if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE)
4417 minleft = be16_to_cpu(ifp->if_broot->bb_level) + 1; 4883 bma.minleft = be16_to_cpu(ifp->if_broot->bb_level) + 1;
4418 else 4884 else
4419 minleft = 1; 4885 bma.minleft = 1;
4420 } else 4886 } else {
4421 minleft = 0; 4887 bma.minleft = 0;
4422 if (!(ifp->if_flags & XFS_IFEXTENTS) && 4888 }
4423 (error = xfs_iread_extents(tp, ip, whichfork))) 4889
4424 goto error0; 4890 if (!(ifp->if_flags & XFS_IFEXTENTS)) {
4425 ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, 4891 error = xfs_iread_extents(tp, ip, whichfork);
4426 &prev); 4892 if (error)
4427 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 4893 goto error0;
4894 }
4895
4896 xfs_bmap_search_extents(ip, bno, whichfork, &eof, &bma.idx, &bma.got,
4897 &bma.prev);
4428 n = 0; 4898 n = 0;
4429 end = bno + len; 4899 end = bno + len;
4430 obno = bno; 4900 obno = bno;
4431 bma.ip = NULL; 4901
4902 bma.tp = tp;
4903 bma.ip = ip;
4904 bma.total = total;
4905 bma.userdata = 0;
4906 bma.flist = flist;
4907 bma.firstblock = firstblock;
4432 4908
4433 while (bno < end && n < *nmap) { 4909 while (bno < end && n < *nmap) {
4434 /* 4910 inhole = eof || bma.got.br_startoff > bno;
4435 * Reading past eof, act as though there's a hole 4911 wasdelay = !inhole && isnullstartblock(bma.got.br_startblock);
4436 * up to end. 4912
4437 */
4438 if (eof && !wr)
4439 got.br_startoff = end;
4440 inhole = eof || got.br_startoff > bno;
4441 wasdelay = wr && !inhole && !(flags & XFS_BMAPI_DELAY) &&
4442 isnullstartblock(got.br_startblock);
4443 /* 4913 /*
4444 * First, deal with the hole before the allocated space 4914 * First, deal with the hole before the allocated space
4445 * that we found, if any. 4915 * that we found, if any.
4446 */ 4916 */
4447 if (wr && (inhole || wasdelay)) { 4917 if (inhole || wasdelay) {
4448 /* 4918 bma.eof = eof;
4449 * For the wasdelay case, we could also just 4919 bma.conv = !!(flags & XFS_BMAPI_CONVERT);
4450 * allocate the stuff asked for in this bmap call 4920 bma.wasdel = wasdelay;
4451 * but that wouldn't be as good. 4921 bma.length = len;
4452 */ 4922 bma.offset = bno;
4453 if (wasdelay) { 4923
4454 alen = (xfs_extlen_t)got.br_blockcount; 4924 error = xfs_bmapi_allocate(&bma, flags);
4455 aoff = got.br_startoff;
4456 if (lastx != NULLEXTNUM && lastx) {
4457 ep = xfs_iext_get_ext(ifp, lastx - 1);
4458 xfs_bmbt_get_all(ep, &prev);
4459 }
4460 } else {
4461 alen = (xfs_extlen_t)
4462 XFS_FILBLKS_MIN(len, MAXEXTLEN);
4463 if (!eof)
4464 alen = (xfs_extlen_t)
4465 XFS_FILBLKS_MIN(alen,
4466 got.br_startoff - bno);
4467 aoff = bno;
4468 }
4469 minlen = (flags & XFS_BMAPI_CONTIG) ? alen : 1;
4470 if (flags & XFS_BMAPI_DELAY) {
4471 xfs_extlen_t extsz;
4472
4473 /* Figure out the extent size, adjust alen */
4474 extsz = xfs_get_extsz_hint(ip);
4475 if (extsz) {
4476 /*
4477 * make sure we don't exceed a single
4478 * extent length when we align the
4479 * extent by reducing length we are
4480 * going to allocate by the maximum
4481 * amount extent size aligment may
4482 * require.
4483 */
4484 alen = XFS_FILBLKS_MIN(len,
4485 MAXEXTLEN - (2 * extsz - 1));
4486 error = xfs_bmap_extsize_align(mp,
4487 &got, &prev, extsz,
4488 rt, eof,
4489 flags&XFS_BMAPI_DELAY,
4490 flags&XFS_BMAPI_CONVERT,
4491 &aoff, &alen);
4492 ASSERT(!error);
4493 }
4494
4495 if (rt)
4496 extsz = alen / mp->m_sb.sb_rextsize;
4497
4498 /*
4499 * Make a transaction-less quota reservation for
4500 * delayed allocation blocks. This number gets
4501 * adjusted later. We return if we haven't
4502 * allocated blocks already inside this loop.
4503 */
4504 error = xfs_trans_reserve_quota_nblks(
4505 NULL, ip, (long)alen, 0,
4506 rt ? XFS_QMOPT_RES_RTBLKS :
4507 XFS_QMOPT_RES_REGBLKS);
4508 if (error) {
4509 if (n == 0) {
4510 *nmap = 0;
4511 ASSERT(cur == NULL);
4512 return error;
4513 }
4514 break;
4515 }
4516
4517 /*
4518 * Split changing sb for alen and indlen since
4519 * they could be coming from different places.
4520 */
4521 indlen = (xfs_extlen_t)
4522 xfs_bmap_worst_indlen(ip, alen);
4523 ASSERT(indlen > 0);
4524
4525 if (rt) {
4526 error = xfs_mod_incore_sb(mp,
4527 XFS_SBS_FREXTENTS,
4528 -((int64_t)extsz), 0);
4529 } else {
4530 error = xfs_icsb_modify_counters(mp,
4531 XFS_SBS_FDBLOCKS,
4532 -((int64_t)alen), 0);
4533 }
4534 if (!error) {
4535 error = xfs_icsb_modify_counters(mp,
4536 XFS_SBS_FDBLOCKS,
4537 -((int64_t)indlen), 0);
4538 if (error && rt)
4539 xfs_mod_incore_sb(mp,
4540 XFS_SBS_FREXTENTS,
4541 (int64_t)extsz, 0);
4542 else if (error)
4543 xfs_icsb_modify_counters(mp,
4544 XFS_SBS_FDBLOCKS,
4545 (int64_t)alen, 0);
4546 }
4547
4548 if (error) {
4549 if (XFS_IS_QUOTA_ON(mp))
4550 /* unreserve the blocks now */
4551 (void)
4552 xfs_trans_unreserve_quota_nblks(
4553 NULL, ip,
4554 (long)alen, 0, rt ?
4555 XFS_QMOPT_RES_RTBLKS :
4556 XFS_QMOPT_RES_REGBLKS);
4557 break;
4558 }
4559
4560 ip->i_delayed_blks += alen;
4561 abno = nullstartblock(indlen);
4562 } else {
4563 /*
4564 * If first time, allocate and fill in
4565 * once-only bma fields.
4566 */
4567 if (bma.ip == NULL) {
4568 bma.tp = tp;
4569 bma.ip = ip;
4570 bma.prevp = &prev;
4571 bma.gotp = &got;
4572 bma.total = total;
4573 bma.userdata = 0;
4574 }
4575 /* Indicate if this is the first user data
4576 * in the file, or just any user data.
4577 */
4578 if (!(flags & XFS_BMAPI_METADATA)) {
4579 bma.userdata = (aoff == 0) ?
4580 XFS_ALLOC_INITIAL_USER_DATA :
4581 XFS_ALLOC_USERDATA;
4582 }
4583 /*
4584 * Fill in changeable bma fields.
4585 */
4586 bma.eof = eof;
4587 bma.firstblock = *firstblock;
4588 bma.alen = alen;
4589 bma.off = aoff;
4590 bma.conv = !!(flags & XFS_BMAPI_CONVERT);
4591 bma.wasdel = wasdelay;
4592 bma.minlen = minlen;
4593 bma.low = flist->xbf_low;
4594 bma.minleft = minleft;
4595 /*
4596 * Only want to do the alignment at the
4597 * eof if it is userdata and allocation length
4598 * is larger than a stripe unit.
4599 */
4600 if (mp->m_dalign && alen >= mp->m_dalign &&
4601 (!(flags & XFS_BMAPI_METADATA)) &&
4602 (whichfork == XFS_DATA_FORK)) {
4603 if ((error = xfs_bmap_isaeof(ip, aoff,
4604 whichfork, &bma.aeof)))
4605 goto error0;
4606 } else
4607 bma.aeof = 0;
4608 /*
4609 * Call allocator.
4610 */
4611 if ((error = xfs_bmap_alloc(&bma)))
4612 goto error0;
4613 /*
4614 * Copy out result fields.
4615 */
4616 abno = bma.rval;
4617 if ((flist->xbf_low = bma.low))
4618 minleft = 0;
4619 alen = bma.alen;
4620 aoff = bma.off;
4621 ASSERT(*firstblock == NULLFSBLOCK ||
4622 XFS_FSB_TO_AGNO(mp, *firstblock) ==
4623 XFS_FSB_TO_AGNO(mp, bma.firstblock) ||
4624 (flist->xbf_low &&
4625 XFS_FSB_TO_AGNO(mp, *firstblock) <
4626 XFS_FSB_TO_AGNO(mp, bma.firstblock)));
4627 *firstblock = bma.firstblock;
4628 if (cur)
4629 cur->bc_private.b.firstblock =
4630 *firstblock;
4631 if (abno == NULLFSBLOCK)
4632 break;
4633 if ((ifp->if_flags & XFS_IFBROOT) && !cur) {
4634 cur = xfs_bmbt_init_cursor(mp, tp,
4635 ip, whichfork);
4636 cur->bc_private.b.firstblock =
4637 *firstblock;
4638 cur->bc_private.b.flist = flist;
4639 }
4640 /*
4641 * Bump the number of extents we've allocated
4642 * in this call.
4643 */
4644 nallocs++;
4645 }
4646 if (cur)
4647 cur->bc_private.b.flags =
4648 wasdelay ? XFS_BTCUR_BPRV_WASDEL : 0;
4649 got.br_startoff = aoff;
4650 got.br_startblock = abno;
4651 got.br_blockcount = alen;
4652 got.br_state = XFS_EXT_NORM; /* assume normal */
4653 /*
4654 * Determine state of extent, and the filesystem.
4655 * A wasdelay extent has been initialized, so
4656 * shouldn't be flagged as unwritten.
4657 */
4658 if (wr && xfs_sb_version_hasextflgbit(&mp->m_sb)) {
4659 if (!wasdelay && (flags & XFS_BMAPI_PREALLOC))
4660 got.br_state = XFS_EXT_UNWRITTEN;
4661 }
4662 error = xfs_bmap_add_extent(tp, ip, &lastx, &cur, &got,
4663 firstblock, flist, &tmp_logflags,
4664 whichfork);
4665 logflags |= tmp_logflags;
4666 if (error) 4925 if (error)
4667 goto error0; 4926 goto error0;
4668 ep = xfs_iext_get_ext(ifp, lastx); 4927 if (bma.blkno == NULLFSBLOCK)
4669 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 4928 break;
4670 xfs_bmbt_get_all(ep, &got);
4671 ASSERT(got.br_startoff <= aoff);
4672 ASSERT(got.br_startoff + got.br_blockcount >=
4673 aoff + alen);
4674#ifdef DEBUG
4675 if (flags & XFS_BMAPI_DELAY) {
4676 ASSERT(isnullstartblock(got.br_startblock));
4677 ASSERT(startblockval(got.br_startblock) > 0);
4678 }
4679 ASSERT(got.br_state == XFS_EXT_NORM ||
4680 got.br_state == XFS_EXT_UNWRITTEN);
4681#endif
4682 /*
4683 * Fall down into the found allocated space case.
4684 */
4685 } else if (inhole) {
4686 /*
4687 * Reading in a hole.
4688 */
4689 mval->br_startoff = bno;
4690 mval->br_startblock = HOLESTARTBLOCK;
4691 mval->br_blockcount =
4692 XFS_FILBLKS_MIN(len, got.br_startoff - bno);
4693 mval->br_state = XFS_EXT_NORM;
4694 bno += mval->br_blockcount;
4695 len -= mval->br_blockcount;
4696 mval++;
4697 n++;
4698 continue;
4699 }
4700 /*
4701 * Then deal with the allocated space we found.
4702 */
4703 ASSERT(ep != NULL);
4704 if (!(flags & XFS_BMAPI_ENTIRE) &&
4705 (got.br_startoff + got.br_blockcount > obno)) {
4706 if (obno > bno)
4707 bno = obno;
4708 ASSERT((bno >= obno) || (n == 0));
4709 ASSERT(bno < end);
4710 mval->br_startoff = bno;
4711 if (isnullstartblock(got.br_startblock)) {
4712 ASSERT(!wr || (flags & XFS_BMAPI_DELAY));
4713 mval->br_startblock = DELAYSTARTBLOCK;
4714 } else
4715 mval->br_startblock =
4716 got.br_startblock +
4717 (bno - got.br_startoff);
4718 /*
4719 * Return the minimum of what we got and what we
4720 * asked for for the length. We can use the len
4721 * variable here because it is modified below
4722 * and we could have been there before coming
4723 * here if the first part of the allocation
4724 * didn't overlap what was asked for.
4725 */
4726 mval->br_blockcount =
4727 XFS_FILBLKS_MIN(end - bno, got.br_blockcount -
4728 (bno - got.br_startoff));
4729 mval->br_state = got.br_state;
4730 ASSERT(mval->br_blockcount <= len);
4731 } else {
4732 *mval = got;
4733 if (isnullstartblock(mval->br_startblock)) {
4734 ASSERT(!wr || (flags & XFS_BMAPI_DELAY));
4735 mval->br_startblock = DELAYSTARTBLOCK;
4736 }
4737 } 4929 }
4738 4930
4739 /* 4931 /* Deal with the allocated space we found. */
4740 * Check if writing previously allocated but 4932 xfs_bmapi_trim_map(mval, &bma.got, &bno, len, obno,
4741 * unwritten extents. 4933 end, n, flags);
4742 */ 4934
4743 if (wr && 4935 /* Execute unwritten extent conversion if necessary */
4744 ((mval->br_state == XFS_EXT_UNWRITTEN && 4936 error = xfs_bmapi_convert_unwritten(&bma, mval, len, flags);
4745 ((flags & (XFS_BMAPI_PREALLOC|XFS_BMAPI_DELAY)) == 0)) || 4937 if (error == EAGAIN)
4746 (mval->br_state == XFS_EXT_NORM && 4938 continue;
4747 ((flags & (XFS_BMAPI_PREALLOC|XFS_BMAPI_CONVERT)) == 4939 if (error)
4748 (XFS_BMAPI_PREALLOC|XFS_BMAPI_CONVERT))))) { 4940 goto error0;
4749 /* 4941
4750 * Modify (by adding) the state flag, if writing. 4942 /* update the extent map to return */
4751 */ 4943 xfs_bmapi_update_map(&mval, &bno, &len, obno, end, &n, flags);
4752 ASSERT(mval->br_blockcount <= len);
4753 if ((ifp->if_flags & XFS_IFBROOT) && !cur) {
4754 cur = xfs_bmbt_init_cursor(mp,
4755 tp, ip, whichfork);
4756 cur->bc_private.b.firstblock =
4757 *firstblock;
4758 cur->bc_private.b.flist = flist;
4759 }
4760 mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN)
4761 ? XFS_EXT_NORM
4762 : XFS_EXT_UNWRITTEN;
4763 error = xfs_bmap_add_extent(tp, ip, &lastx, &cur, mval,
4764 firstblock, flist, &tmp_logflags,
4765 whichfork);
4766 logflags |= tmp_logflags;
4767 if (error)
4768 goto error0;
4769 ep = xfs_iext_get_ext(ifp, lastx);
4770 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
4771 xfs_bmbt_get_all(ep, &got);
4772 /*
4773 * We may have combined previously unwritten
4774 * space with written space, so generate
4775 * another request.
4776 */
4777 if (mval->br_blockcount < len)
4778 continue;
4779 }
4780 4944
4781 ASSERT((flags & XFS_BMAPI_ENTIRE) ||
4782 ((mval->br_startoff + mval->br_blockcount) <= end));
4783 ASSERT((flags & XFS_BMAPI_ENTIRE) ||
4784 (mval->br_blockcount <= len) ||
4785 (mval->br_startoff < obno));
4786 bno = mval->br_startoff + mval->br_blockcount;
4787 len = end - bno;
4788 if (n > 0 && mval->br_startoff == mval[-1].br_startoff) {
4789 ASSERT(mval->br_startblock == mval[-1].br_startblock);
4790 ASSERT(mval->br_blockcount > mval[-1].br_blockcount);
4791 ASSERT(mval->br_state == mval[-1].br_state);
4792 mval[-1].br_blockcount = mval->br_blockcount;
4793 mval[-1].br_state = mval->br_state;
4794 } else if (n > 0 && mval->br_startblock != DELAYSTARTBLOCK &&
4795 mval[-1].br_startblock != DELAYSTARTBLOCK &&
4796 mval[-1].br_startblock != HOLESTARTBLOCK &&
4797 mval->br_startblock ==
4798 mval[-1].br_startblock + mval[-1].br_blockcount &&
4799 ((flags & XFS_BMAPI_IGSTATE) ||
4800 mval[-1].br_state == mval->br_state)) {
4801 ASSERT(mval->br_startoff ==
4802 mval[-1].br_startoff + mval[-1].br_blockcount);
4803 mval[-1].br_blockcount += mval->br_blockcount;
4804 } else if (n > 0 &&
4805 mval->br_startblock == DELAYSTARTBLOCK &&
4806 mval[-1].br_startblock == DELAYSTARTBLOCK &&
4807 mval->br_startoff ==
4808 mval[-1].br_startoff + mval[-1].br_blockcount) {
4809 mval[-1].br_blockcount += mval->br_blockcount;
4810 mval[-1].br_state = mval->br_state;
4811 } else if (!((n == 0) &&
4812 ((mval->br_startoff + mval->br_blockcount) <=
4813 obno))) {
4814 mval++;
4815 n++;
4816 }
4817 /* 4945 /*
4818 * If we're done, stop now. Stop when we've allocated 4946 * If we're done, stop now. Stop when we've allocated
4819 * XFS_BMAP_MAX_NMAP extents no matter what. Otherwise 4947 * XFS_BMAP_MAX_NMAP extents no matter what. Otherwise
4820 * the transaction may get too big. 4948 * the transaction may get too big.
4821 */ 4949 */
4822 if (bno >= end || n >= *nmap || nallocs >= *nmap) 4950 if (bno >= end || n >= *nmap || bma.nallocs >= *nmap)
4823 break; 4951 break;
4824 /* 4952
4825 * Else go on to the next record. 4953 /* Else go on to the next record. */
4826 */ 4954 bma.prev = bma.got;
4827 prev = got; 4955 if (++bma.idx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t)) {
4828 if (++lastx < nextents) { 4956 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma.idx),
4829 ep = xfs_iext_get_ext(ifp, lastx); 4957 &bma.got);
4830 xfs_bmbt_get_all(ep, &got); 4958 } else
4831 } else {
4832 eof = 1; 4959 eof = 1;
4833 }
4834 } 4960 }
4835 *nmap = n; 4961 *nmap = n;
4962
4836 /* 4963 /*
4837 * Transform from btree to extents, give it cur. 4964 * Transform from btree to extents, give it cur.
4838 */ 4965 */
4839 if (tp && XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE && 4966 if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE &&
4840 XFS_IFORK_NEXTENTS(ip, whichfork) <= ifp->if_ext_max) { 4967 XFS_IFORK_NEXTENTS(ip, whichfork) <= ifp->if_ext_max) {
4841 ASSERT(wr && cur); 4968 int tmp_logflags = 0;
4842 error = xfs_bmap_btree_to_extents(tp, ip, cur, 4969
4970 ASSERT(bma.cur);
4971 error = xfs_bmap_btree_to_extents(tp, ip, bma.cur,
4843 &tmp_logflags, whichfork); 4972 &tmp_logflags, whichfork);
4844 logflags |= tmp_logflags; 4973 bma.logflags |= tmp_logflags;
4845 if (error) 4974 if (error)
4846 goto error0; 4975 goto error0;
4847 } 4976 }
@@ -4855,34 +4984,33 @@ error0:
4855 * Log everything. Do this after conversion, there's no point in 4984 * Log everything. Do this after conversion, there's no point in
4856 * logging the extent records if we've converted to btree format. 4985 * logging the extent records if we've converted to btree format.
4857 */ 4986 */
4858 if ((logflags & xfs_ilog_fext(whichfork)) && 4987 if ((bma.logflags & xfs_ilog_fext(whichfork)) &&
4859 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) 4988 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS)
4860 logflags &= ~xfs_ilog_fext(whichfork); 4989 bma.logflags &= ~xfs_ilog_fext(whichfork);
4861 else if ((logflags & xfs_ilog_fbroot(whichfork)) && 4990 else if ((bma.logflags & xfs_ilog_fbroot(whichfork)) &&
4862 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE) 4991 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)
4863 logflags &= ~xfs_ilog_fbroot(whichfork); 4992 bma.logflags &= ~xfs_ilog_fbroot(whichfork);
4864 /* 4993 /*
4865 * Log whatever the flags say, even if error. Otherwise we might miss 4994 * Log whatever the flags say, even if error. Otherwise we might miss
4866 * detecting a case where the data is changed, there's an error, 4995 * detecting a case where the data is changed, there's an error,
4867 * and it's not logged so we don't shutdown when we should. 4996 * and it's not logged so we don't shutdown when we should.
4868 */ 4997 */
4869 if (logflags) { 4998 if (bma.logflags)
4870 ASSERT(tp && wr); 4999 xfs_trans_log_inode(tp, ip, bma.logflags);
4871 xfs_trans_log_inode(tp, ip, logflags); 5000
4872 } 5001 if (bma.cur) {
4873 if (cur) {
4874 if (!error) { 5002 if (!error) {
4875 ASSERT(*firstblock == NULLFSBLOCK || 5003 ASSERT(*firstblock == NULLFSBLOCK ||
4876 XFS_FSB_TO_AGNO(mp, *firstblock) == 5004 XFS_FSB_TO_AGNO(mp, *firstblock) ==
4877 XFS_FSB_TO_AGNO(mp, 5005 XFS_FSB_TO_AGNO(mp,
4878 cur->bc_private.b.firstblock) || 5006 bma.cur->bc_private.b.firstblock) ||
4879 (flist->xbf_low && 5007 (flist->xbf_low &&
4880 XFS_FSB_TO_AGNO(mp, *firstblock) < 5008 XFS_FSB_TO_AGNO(mp, *firstblock) <
4881 XFS_FSB_TO_AGNO(mp, 5009 XFS_FSB_TO_AGNO(mp,
4882 cur->bc_private.b.firstblock))); 5010 bma.cur->bc_private.b.firstblock)));
4883 *firstblock = cur->bc_private.b.firstblock; 5011 *firstblock = bma.cur->bc_private.b.firstblock;
4884 } 5012 }
4885 xfs_btree_del_cursor(cur, 5013 xfs_btree_del_cursor(bma.cur,
4886 error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); 5014 error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR);
4887 } 5015 }
4888 if (!error) 5016 if (!error)
@@ -4892,58 +5020,6 @@ error0:
4892} 5020}
4893 5021
4894/* 5022/*
4895 * Map file blocks to filesystem blocks, simple version.
4896 * One block (extent) only, read-only.
4897 * For flags, only the XFS_BMAPI_ATTRFORK flag is examined.
4898 * For the other flag values, the effect is as if XFS_BMAPI_METADATA
4899 * was set and all the others were clear.
4900 */
4901int /* error */
4902xfs_bmapi_single(
4903 xfs_trans_t *tp, /* transaction pointer */
4904 xfs_inode_t *ip, /* incore inode */
4905 int whichfork, /* data or attr fork */
4906 xfs_fsblock_t *fsb, /* output: mapped block */
4907 xfs_fileoff_t bno) /* starting file offs. mapped */
4908{
4909 int eof; /* we've hit the end of extents */
4910 int error; /* error return */
4911 xfs_bmbt_irec_t got; /* current file extent record */
4912 xfs_ifork_t *ifp; /* inode fork pointer */
4913 xfs_extnum_t lastx; /* last useful extent number */
4914 xfs_bmbt_irec_t prev; /* previous file extent record */
4915
4916 ifp = XFS_IFORK_PTR(ip, whichfork);
4917 if (unlikely(
4918 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE &&
4919 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS)) {
4920 XFS_ERROR_REPORT("xfs_bmapi_single", XFS_ERRLEVEL_LOW,
4921 ip->i_mount);
4922 return XFS_ERROR(EFSCORRUPTED);
4923 }
4924 if (XFS_FORCED_SHUTDOWN(ip->i_mount))
4925 return XFS_ERROR(EIO);
4926 XFS_STATS_INC(xs_blk_mapr);
4927 if (!(ifp->if_flags & XFS_IFEXTENTS) &&
4928 (error = xfs_iread_extents(tp, ip, whichfork)))
4929 return error;
4930 (void)xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got,
4931 &prev);
4932 /*
4933 * Reading past eof, act as though there's a hole
4934 * up to end.
4935 */
4936 if (eof || got.br_startoff > bno) {
4937 *fsb = NULLFSBLOCK;
4938 return 0;
4939 }
4940 ASSERT(!isnullstartblock(got.br_startblock));
4941 ASSERT(bno < got.br_startoff + got.br_blockcount);
4942 *fsb = got.br_startblock + (bno - got.br_startoff);
4943 return 0;
4944}
4945
4946/*
4947 * Unmap (remove) blocks from a file. 5023 * Unmap (remove) blocks from a file.
4948 * If nexts is nonzero then the number of extents to remove is limited to 5024 * If nexts is nonzero then the number of extents to remove is limited to
4949 * that value. If not all extents in the block range can be removed then 5025 * that value. If not all extents in the block range can be removed then
@@ -5114,9 +5190,9 @@ xfs_bunmapi(
5114 del.br_blockcount = mod; 5190 del.br_blockcount = mod;
5115 } 5191 }
5116 del.br_state = XFS_EXT_UNWRITTEN; 5192 del.br_state = XFS_EXT_UNWRITTEN;
5117 error = xfs_bmap_add_extent(tp, ip, &lastx, &cur, &del, 5193 error = xfs_bmap_add_extent_unwritten_real(tp, ip,
5118 firstblock, flist, &logflags, 5194 &lastx, &cur, &del, firstblock, flist,
5119 XFS_DATA_FORK); 5195 &logflags);
5120 if (error) 5196 if (error)
5121 goto error0; 5197 goto error0;
5122 goto nodelete; 5198 goto nodelete;
@@ -5172,18 +5248,18 @@ xfs_bunmapi(
5172 } 5248 }
5173 prev.br_state = XFS_EXT_UNWRITTEN; 5249 prev.br_state = XFS_EXT_UNWRITTEN;
5174 lastx--; 5250 lastx--;
5175 error = xfs_bmap_add_extent(tp, ip, &lastx, 5251 error = xfs_bmap_add_extent_unwritten_real(tp,
5176 &cur, &prev, firstblock, flist, 5252 ip, &lastx, &cur, &prev,
5177 &logflags, XFS_DATA_FORK); 5253 firstblock, flist, &logflags);
5178 if (error) 5254 if (error)
5179 goto error0; 5255 goto error0;
5180 goto nodelete; 5256 goto nodelete;
5181 } else { 5257 } else {
5182 ASSERT(del.br_state == XFS_EXT_NORM); 5258 ASSERT(del.br_state == XFS_EXT_NORM);
5183 del.br_state = XFS_EXT_UNWRITTEN; 5259 del.br_state = XFS_EXT_UNWRITTEN;
5184 error = xfs_bmap_add_extent(tp, ip, &lastx, 5260 error = xfs_bmap_add_extent_unwritten_real(tp,
5185 &cur, &del, firstblock, flist, 5261 ip, &lastx, &cur, &del,
5186 &logflags, XFS_DATA_FORK); 5262 firstblock, flist, &logflags);
5187 if (error) 5263 if (error)
5188 goto error0; 5264 goto error0;
5189 goto nodelete; 5265 goto nodelete;
@@ -5505,10 +5581,9 @@ xfs_getbmap(
5505 5581
5506 do { 5582 do {
5507 nmap = (nexleft > subnex) ? subnex : nexleft; 5583 nmap = (nexleft > subnex) ? subnex : nexleft;
5508 error = xfs_bmapi(NULL, ip, XFS_BB_TO_FSBT(mp, bmv->bmv_offset), 5584 error = xfs_bmapi_read(ip, XFS_BB_TO_FSBT(mp, bmv->bmv_offset),
5509 XFS_BB_TO_FSB(mp, bmv->bmv_length), 5585 XFS_BB_TO_FSB(mp, bmv->bmv_length),
5510 bmapi_flags, NULL, 0, map, &nmap, 5586 map, &nmap, bmapi_flags);
5511 NULL);
5512 if (error) 5587 if (error)
5513 goto out_free_map; 5588 goto out_free_map;
5514 ASSERT(nmap <= subnex); 5589 ASSERT(nmap <= subnex);
@@ -5582,89 +5657,6 @@ xfs_getbmap(
5582 return error; 5657 return error;
5583} 5658}
5584 5659
5585/*
5586 * Check the last inode extent to determine whether this allocation will result
5587 * in blocks being allocated at the end of the file. When we allocate new data
5588 * blocks at the end of the file which do not start at the previous data block,
5589 * we will try to align the new blocks at stripe unit boundaries.
5590 */
5591STATIC int /* error */
5592xfs_bmap_isaeof(
5593 xfs_inode_t *ip, /* incore inode pointer */
5594 xfs_fileoff_t off, /* file offset in fsblocks */
5595 int whichfork, /* data or attribute fork */
5596 char *aeof) /* return value */
5597{
5598 int error; /* error return value */
5599 xfs_ifork_t *ifp; /* inode fork pointer */
5600 xfs_bmbt_rec_host_t *lastrec; /* extent record pointer */
5601 xfs_extnum_t nextents; /* number of file extents */
5602 xfs_bmbt_irec_t s; /* expanded extent record */
5603
5604 ASSERT(whichfork == XFS_DATA_FORK);
5605 ifp = XFS_IFORK_PTR(ip, whichfork);
5606 if (!(ifp->if_flags & XFS_IFEXTENTS) &&
5607 (error = xfs_iread_extents(NULL, ip, whichfork)))
5608 return error;
5609 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
5610 if (nextents == 0) {
5611 *aeof = 1;
5612 return 0;
5613 }
5614 /*
5615 * Go to the last extent
5616 */
5617 lastrec = xfs_iext_get_ext(ifp, nextents - 1);
5618 xfs_bmbt_get_all(lastrec, &s);
5619 /*
5620 * Check we are allocating in the last extent (for delayed allocations)
5621 * or past the last extent for non-delayed allocations.
5622 */
5623 *aeof = (off >= s.br_startoff &&
5624 off < s.br_startoff + s.br_blockcount &&
5625 isnullstartblock(s.br_startblock)) ||
5626 off >= s.br_startoff + s.br_blockcount;
5627 return 0;
5628}
5629
5630/*
5631 * Check if the endoff is outside the last extent. If so the caller will grow
5632 * the allocation to a stripe unit boundary.
5633 */
5634int /* error */
5635xfs_bmap_eof(
5636 xfs_inode_t *ip, /* incore inode pointer */
5637 xfs_fileoff_t endoff, /* file offset in fsblocks */
5638 int whichfork, /* data or attribute fork */
5639 int *eof) /* result value */
5640{
5641 xfs_fsblock_t blockcount; /* extent block count */
5642 int error; /* error return value */
5643 xfs_ifork_t *ifp; /* inode fork pointer */
5644 xfs_bmbt_rec_host_t *lastrec; /* extent record pointer */
5645 xfs_extnum_t nextents; /* number of file extents */
5646 xfs_fileoff_t startoff; /* extent starting file offset */
5647
5648 ASSERT(whichfork == XFS_DATA_FORK);
5649 ifp = XFS_IFORK_PTR(ip, whichfork);
5650 if (!(ifp->if_flags & XFS_IFEXTENTS) &&
5651 (error = xfs_iread_extents(NULL, ip, whichfork)))
5652 return error;
5653 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
5654 if (nextents == 0) {
5655 *eof = 1;
5656 return 0;
5657 }
5658 /*
5659 * Go to the last extent
5660 */
5661 lastrec = xfs_iext_get_ext(ifp, nextents - 1);
5662 startoff = xfs_bmbt_get_startoff(lastrec);
5663 blockcount = xfs_bmbt_get_blockcount(lastrec);
5664 *eof = endoff >= startoff + blockcount;
5665 return 0;
5666}
5667
5668#ifdef DEBUG 5660#ifdef DEBUG
5669STATIC struct xfs_buf * 5661STATIC struct xfs_buf *
5670xfs_bmap_get_bp( 5662xfs_bmap_get_bp(
@@ -6099,9 +6091,8 @@ xfs_bmap_punch_delalloc_range(
6099 * trying to remove a real extent (which requires a 6091 * trying to remove a real extent (which requires a
6100 * transaction) or a hole, which is probably a bad idea... 6092 * transaction) or a hole, which is probably a bad idea...
6101 */ 6093 */
6102 error = xfs_bmapi(NULL, ip, start_fsb, 1, 6094 error = xfs_bmapi_read(ip, start_fsb, 1, &imap, &nimaps,
6103 XFS_BMAPI_ENTIRE, NULL, 0, &imap, 6095 XFS_BMAPI_ENTIRE);
6104 &nimaps, NULL);
6105 6096
6106 if (error) { 6097 if (error) {
6107 /* something screwed, just bail */ 6098 /* something screwed, just bail */