Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'for-linus' of git://oss.sgi.com/xfs/xfs

* 'for-linus' of git://oss.sgi.com/xfs/xfs:
xfs: correctly decrement the extent buffer index in xfs_bmap_del_extent
xfs: check for valid indices in xfs_iext_get_ext and xfs_iext_idx_to_irec
xfs: fix up asserts in xfs_iflush_fork
xfs: do not do pointer arithmetic on extent records
xfs: do not use unchecked extent indices in xfs_bunmapi
xfs: do not use unchecked extent indices in xfs_bmapi
xfs: do not use unchecked extent indices in xfs_bmap_add_extent_*
xfs: remove if_lastex
xfs: remove the unused XFS_BMAPI_RSVBLOCKS flag
xfs: do not discard alloc btree blocks
xfs: add online discard support

+368 -320
+6
Documentation/filesystems/xfs.txt
··· 39 39 drive level write caching to be enabled, for devices that 40 40 support write barriers. 41 41 42 + discard 43 + Issue command to let the block device reclaim space freed by the 44 + filesystem. This is useful for SSD devices, thinly provisioned 45 + LUNs and virtual machine images, but may have a performance 46 + impact. This option is incompatible with the nodelaylog option. 47 + 42 48 dmapi 43 49 Enable the DMAPI (Data Management API) event callouts. 44 50 Use with the "mtpt" option.
+29
fs/xfs/linux-2.6/xfs_discard.c
··· 191 191 return -XFS_ERROR(EFAULT); 192 192 return 0; 193 193 } 194 + 195 + int 196 + xfs_discard_extents( 197 + struct xfs_mount *mp, 198 + struct list_head *list) 199 + { 200 + struct xfs_busy_extent *busyp; 201 + int error = 0; 202 + 203 + list_for_each_entry(busyp, list, list) { 204 + trace_xfs_discard_extent(mp, busyp->agno, busyp->bno, 205 + busyp->length); 206 + 207 + error = -blkdev_issue_discard(mp->m_ddev_targp->bt_bdev, 208 + XFS_AGB_TO_DADDR(mp, busyp->agno, busyp->bno), 209 + XFS_FSB_TO_BB(mp, busyp->length), 210 + GFP_NOFS, 0); 211 + if (error && error != EOPNOTSUPP) { 212 + xfs_info(mp, 213 + "discard failed for extent [0x%llu,%u], error %d", 214 + (unsigned long long)busyp->bno, 215 + busyp->length, 216 + error); 217 + return error; 218 + } 219 + } 220 + 221 + return 0; 222 + }
+2
fs/xfs/linux-2.6/xfs_discard.h
··· 2 2 #define XFS_DISCARD_H 1 3 3 4 4 struct fstrim_range; 5 + struct list_head; 5 6 6 7 extern int xfs_ioc_trim(struct xfs_mount *, struct fstrim_range __user *); 8 + extern int xfs_discard_extents(struct xfs_mount *, struct list_head *); 7 9 8 10 #endif /* XFS_DISCARD_H */
+16 -2
fs/xfs/linux-2.6/xfs_super.c
··· 110 110 #define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */ 111 111 #define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */ 112 112 #define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */ 113 - #define MNTOPT_DELAYLOG "delaylog" /* Delayed loging enabled */ 114 - #define MNTOPT_NODELAYLOG "nodelaylog" /* Delayed loging disabled */ 113 + #define MNTOPT_DELAYLOG "delaylog" /* Delayed logging enabled */ 114 + #define MNTOPT_NODELAYLOG "nodelaylog" /* Delayed logging disabled */ 115 + #define MNTOPT_DISCARD "discard" /* Discard unused blocks */ 116 + #define MNTOPT_NODISCARD "nodiscard" /* Do not discard unused blocks */ 115 117 116 118 /* 117 119 * Table driven mount option parser. ··· 357 355 mp->m_flags |= XFS_MOUNT_DELAYLOG; 358 356 } else if (!strcmp(this_char, MNTOPT_NODELAYLOG)) { 359 357 mp->m_flags &= ~XFS_MOUNT_DELAYLOG; 358 + } else if (!strcmp(this_char, MNTOPT_DISCARD)) { 359 + mp->m_flags |= XFS_MOUNT_DISCARD; 360 + } else if (!strcmp(this_char, MNTOPT_NODISCARD)) { 361 + mp->m_flags &= ~XFS_MOUNT_DISCARD; 360 362 } else if (!strcmp(this_char, "ihashsize")) { 361 363 xfs_warn(mp, 362 364 "ihashsize no longer used, option is deprecated."); ··· 391 385 if ((mp->m_flags & XFS_MOUNT_NOALIGN) && (dsunit || dswidth)) { 392 386 xfs_warn(mp, 393 387 "sunit and swidth options incompatible with the noalign option"); 388 + return EINVAL; 389 + } 390 + 391 + if ((mp->m_flags & XFS_MOUNT_DISCARD) && 392 + !(mp->m_flags & XFS_MOUNT_DELAYLOG)) { 393 + xfs_warn(mp, 394 + "the discard option is incompatible with the nodelaylog option"); 394 395 return EINVAL; 395 396 } 396 397 ··· 501 488 { XFS_MOUNT_FILESTREAMS, "," MNTOPT_FILESTREAM }, 502 489 { XFS_MOUNT_GRPID, "," MNTOPT_GRPID }, 503 490 { XFS_MOUNT_DELAYLOG, "," MNTOPT_DELAYLOG }, 491 + { XFS_MOUNT_DISCARD, "," MNTOPT_DISCARD }, 504 492 { 0, NULL } 505 493 }; 506 494 static struct proc_xfs_info xfs_info_unset[] = {
+3
fs/xfs/xfs_ag.h
··· 187 187 xfs_agnumber_t agno; 188 188 xfs_agblock_t bno; 189 189 xfs_extlen_t length; 190 + unsigned int flags; 191 + #define XFS_ALLOC_BUSY_DISCARDED 0x01 /* undergoing a discard op. */ 192 + #define XFS_ALLOC_BUSY_SKIP_DISCARD 0x02 /* do not discard */ 190 193 }; 191 194 192 195 /*
+30 -5
fs/xfs/xfs_alloc.c
··· 2469 2469 2470 2470 error = xfs_free_ag_extent(tp, args.agbp, args.agno, args.agbno, len, 0); 2471 2471 if (!error) 2472 - xfs_alloc_busy_insert(tp, args.agno, args.agbno, len); 2472 + xfs_alloc_busy_insert(tp, args.agno, args.agbno, len, 0); 2473 2473 error0: 2474 2474 xfs_perag_put(args.pag); 2475 2475 return error; ··· 2480 2480 struct xfs_trans *tp, 2481 2481 xfs_agnumber_t agno, 2482 2482 xfs_agblock_t bno, 2483 - xfs_extlen_t len) 2483 + xfs_extlen_t len, 2484 + unsigned int flags) 2484 2485 { 2485 2486 struct xfs_busy_extent *new; 2486 2487 struct xfs_busy_extent *busyp; ··· 2505 2504 new->bno = bno; 2506 2505 new->length = len; 2507 2506 INIT_LIST_HEAD(&new->list); 2507 + new->flags = flags; 2508 2508 2509 2509 /* trace before insert to be able to see failed inserts */ 2510 2510 trace_xfs_alloc_busy(tp->t_mountp, agno, bno, len); ··· 2609 2607 xfs_agblock_t fend = fbno + flen; 2610 2608 xfs_agblock_t bbno = busyp->bno; 2611 2609 xfs_agblock_t bend = bbno + busyp->length; 2610 + 2611 + /* 2612 + * This extent is currently being discarded. Give the thread 2613 + * performing the discard a chance to mark the extent unbusy 2614 + * and retry. 2615 + */ 2616 + if (busyp->flags & XFS_ALLOC_BUSY_DISCARDED) { 2617 + spin_unlock(&pag->pagb_lock); 2618 + delay(1); 2619 + spin_lock(&pag->pagb_lock); 2620 + return false; 2621 + } 2612 2622 2613 2623 /* 2614 2624 * If there is a busy extent overlapping a user allocation, we have ··· 2827 2813 * If this is a metadata allocation, try to reuse the busy 2828 2814 * extent instead of trimming the allocation. 2829 2815 */ 2830 - if (!args->userdata) { 2816 + if (!args->userdata && 2817 + !(busyp->flags & XFS_ALLOC_BUSY_DISCARDED)) { 2831 2818 if (!xfs_alloc_busy_update_extent(args->mp, args->pag, 2832 2819 busyp, fbno, flen, 2833 2820 false)) ··· 2994 2979 kmem_free(busyp); 2995 2980 } 2996 2981 2982 + /* 2983 + * Remove all extents on the passed in list from the busy extents tree. 2984 + * If do_discard is set skip extents that need to be discarded, and mark 2985 + * these as undergoing a discard operation instead. 2986 + */ 2997 2987 void 2998 2988 xfs_alloc_busy_clear( 2999 2989 struct xfs_mount *mp, 3000 - struct list_head *list) 2990 + struct list_head *list, 2991 + bool do_discard) 3001 2992 { 3002 2993 struct xfs_busy_extent *busyp, *n; 3003 2994 struct xfs_perag *pag = NULL; ··· 3020 2999 agno = busyp->agno; 3021 3000 } 3022 3001 3023 - xfs_alloc_busy_clear_one(mp, pag, busyp); 3002 + if (do_discard && busyp->length && 3003 + !(busyp->flags & XFS_ALLOC_BUSY_SKIP_DISCARD)) 3004 + busyp->flags = XFS_ALLOC_BUSY_DISCARDED; 3005 + else 3006 + xfs_alloc_busy_clear_one(mp, pag, busyp); 3024 3007 } 3025 3008 3026 3009 if (pag) {
+3 -2
fs/xfs/xfs_alloc.h
··· 137 137 #ifdef __KERNEL__ 138 138 void 139 139 xfs_alloc_busy_insert(struct xfs_trans *tp, xfs_agnumber_t agno, 140 - xfs_agblock_t bno, xfs_extlen_t len); 140 + xfs_agblock_t bno, xfs_extlen_t len, unsigned int flags); 141 141 142 142 void 143 - xfs_alloc_busy_clear(struct xfs_mount *mp, struct list_head *list); 143 + xfs_alloc_busy_clear(struct xfs_mount *mp, struct list_head *list, 144 + bool do_discard); 144 145 145 146 int 146 147 xfs_alloc_busy_search(struct xfs_mount *mp, xfs_agnumber_t agno,
+2 -1
fs/xfs/xfs_alloc_btree.c
··· 120 120 if (error) 121 121 return error; 122 122 123 - xfs_alloc_busy_insert(cur->bc_tp, be32_to_cpu(agf->agf_seqno), bno, 1); 123 + xfs_alloc_busy_insert(cur->bc_tp, be32_to_cpu(agf->agf_seqno), bno, 1, 124 + XFS_ALLOC_BUSY_SKIP_DISCARD); 124 125 xfs_trans_agbtree_delta(cur->bc_tp, -1); 125 126 return 0; 126 127 }
+256 -297
fs/xfs/xfs_bmap.c
··· 89 89 int *flags); /* inode logging flags */ 90 90 91 91 /* 92 - * Called by xfs_bmapi to update file extent records and the btree 93 - * after allocating space (or doing a delayed allocation). 94 - */ 95 - STATIC int /* error */ 96 - xfs_bmap_add_extent( 97 - xfs_inode_t *ip, /* incore inode pointer */ 98 - xfs_extnum_t idx, /* extent number to update/insert */ 99 - xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ 100 - xfs_bmbt_irec_t *new, /* new data to add to file extents */ 101 - xfs_fsblock_t *first, /* pointer to firstblock variable */ 102 - xfs_bmap_free_t *flist, /* list of extents to be freed */ 103 - int *logflagsp, /* inode logging flags */ 104 - int whichfork, /* data or attr fork */ 105 - int rsvd); /* OK to allocate reserved blocks */ 106 - 107 - /* 108 92 * Called by xfs_bmap_add_extent to handle cases converting a delayed 109 93 * allocation to a real allocation. 110 94 */ 111 95 STATIC int /* error */ 112 96 xfs_bmap_add_extent_delay_real( 113 97 xfs_inode_t *ip, /* incore inode pointer */ 114 - xfs_extnum_t idx, /* extent number to update/insert */ 98 + xfs_extnum_t *idx, /* extent number to update/insert */ 115 99 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ 116 100 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 117 101 xfs_filblks_t *dnew, /* new delayed-alloc indirect blocks */ 118 102 xfs_fsblock_t *first, /* pointer to firstblock variable */ 119 103 xfs_bmap_free_t *flist, /* list of extents to be freed */ 120 - int *logflagsp, /* inode logging flags */ 121 - int rsvd); /* OK to allocate reserved blocks */ 104 + int *logflagsp); /* inode logging flags */ 122 105 123 106 /* 124 107 * Called by xfs_bmap_add_extent to handle cases converting a hole ··· 110 127 STATIC int /* error */ 111 128 xfs_bmap_add_extent_hole_delay( 112 129 xfs_inode_t *ip, /* incore inode pointer */ 113 - xfs_extnum_t idx, /* extent number to update/insert */ 130 + xfs_extnum_t *idx, /* extent number to update/insert */ 114 131 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 115 - int *logflagsp,/* inode logging flags */ 116 - int rsvd); /* OK to allocate reserved blocks */ 132 + int *logflagsp); /* inode logging flags */ 117 133 118 134 /* 119 135 * Called by xfs_bmap_add_extent to handle cases converting a hole ··· 121 139 STATIC int /* error */ 122 140 xfs_bmap_add_extent_hole_real( 123 141 xfs_inode_t *ip, /* incore inode pointer */ 124 - xfs_extnum_t idx, /* extent number to update/insert */ 142 + xfs_extnum_t *idx, /* extent number to update/insert */ 125 143 xfs_btree_cur_t *cur, /* if null, not a btree */ 126 144 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 127 145 int *logflagsp, /* inode logging flags */ ··· 134 152 STATIC int /* error */ 135 153 xfs_bmap_add_extent_unwritten_real( 136 154 xfs_inode_t *ip, /* incore inode pointer */ 137 - xfs_extnum_t idx, /* extent number to update/insert */ 155 + xfs_extnum_t *idx, /* extent number to update/insert */ 138 156 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ 139 157 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 140 158 int *logflagsp); /* inode logging flags */ ··· 160 178 xfs_btree_cur_t *cur, /* btree cursor */ 161 179 int *logflagsp, /* inode logging flags */ 162 180 int whichfork); /* data or attr fork */ 163 - 164 - /* 165 - * Called by xfs_bmapi to update file extent records and the btree 166 - * after removing space (or undoing a delayed allocation). 167 - */ 168 - STATIC int /* error */ 169 - xfs_bmap_del_extent( 170 - xfs_inode_t *ip, /* incore inode pointer */ 171 - xfs_trans_t *tp, /* current trans pointer */ 172 - xfs_extnum_t idx, /* extent number to update/insert */ 173 - xfs_bmap_free_t *flist, /* list of extents to be freed */ 174 - xfs_btree_cur_t *cur, /* if null, not a btree */ 175 - xfs_bmbt_irec_t *new, /* new data to add to file extents */ 176 - int *logflagsp,/* inode logging flags */ 177 - int whichfork, /* data or attr fork */ 178 - int rsvd); /* OK to allocate reserved blocks */ 179 181 180 182 /* 181 183 * Remove the entry "free" from the free item list. Prev points to the ··· 440 474 STATIC int /* error */ 441 475 xfs_bmap_add_extent( 442 476 xfs_inode_t *ip, /* incore inode pointer */ 443 - xfs_extnum_t idx, /* extent number to update/insert */ 477 + xfs_extnum_t *idx, /* extent number to update/insert */ 444 478 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ 445 479 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 446 480 xfs_fsblock_t *first, /* pointer to firstblock variable */ 447 481 xfs_bmap_free_t *flist, /* list of extents to be freed */ 448 482 int *logflagsp, /* inode logging flags */ 449 - int whichfork, /* data or attr fork */ 450 - int rsvd) /* OK to use reserved data blocks */ 483 + int whichfork) /* data or attr fork */ 451 484 { 452 485 xfs_btree_cur_t *cur; /* btree cursor or null */ 453 486 xfs_filblks_t da_new; /* new count del alloc blocks used */ ··· 457 492 xfs_extnum_t nextents; /* number of extents in file now */ 458 493 459 494 XFS_STATS_INC(xs_add_exlist); 495 + 460 496 cur = *curp; 461 497 ifp = XFS_IFORK_PTR(ip, whichfork); 462 498 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 463 - ASSERT(idx <= nextents); 464 499 da_old = da_new = 0; 465 500 error = 0; 501 + 502 + ASSERT(*idx >= 0); 503 + ASSERT(*idx <= nextents); 504 + 466 505 /* 467 506 * This is the first extent added to a new/empty file. 468 507 * Special case this one, so other routines get to assume there are 469 508 * already extents in the list. 470 509 */ 471 510 if (nextents == 0) { 472 - xfs_iext_insert(ip, 0, 1, new, 511 + xfs_iext_insert(ip, *idx, 1, new, 473 512 whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0); 474 513 475 514 ASSERT(cur == NULL); 476 - ifp->if_lastex = 0; 515 + 477 516 if (!isnullstartblock(new->br_startblock)) { 478 517 XFS_IFORK_NEXT_SET(ip, whichfork, 1); 479 518 logflags = XFS_ILOG_CORE | xfs_ilog_fext(whichfork); ··· 491 522 if (cur) 492 523 ASSERT((cur->bc_private.b.flags & 493 524 XFS_BTCUR_BPRV_WASDEL) == 0); 494 - if ((error = xfs_bmap_add_extent_hole_delay(ip, idx, new, 495 - &logflags, rsvd))) 496 - goto done; 525 + error = xfs_bmap_add_extent_hole_delay(ip, idx, new, 526 + &logflags); 497 527 } 498 528 /* 499 529 * Real allocation off the end of the file. 500 530 */ 501 - else if (idx == nextents) { 531 + else if (*idx == nextents) { 502 532 if (cur) 503 533 ASSERT((cur->bc_private.b.flags & 504 534 XFS_BTCUR_BPRV_WASDEL) == 0); 505 - if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, new, 506 - &logflags, whichfork))) 507 - goto done; 535 + error = xfs_bmap_add_extent_hole_real(ip, idx, cur, new, 536 + &logflags, whichfork); 508 537 } else { 509 538 xfs_bmbt_irec_t prev; /* old extent at offset idx */ 510 539 511 540 /* 512 541 * Get the record referred to by idx. 513 542 */ 514 - xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx), &prev); 543 + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx), &prev); 515 544 /* 516 545 * If it's a real allocation record, and the new allocation ends 517 546 * after the start of the referred to record, then we're filling ··· 524 557 if (cur) 525 558 ASSERT(cur->bc_private.b.flags & 526 559 XFS_BTCUR_BPRV_WASDEL); 527 - if ((error = xfs_bmap_add_extent_delay_real(ip, 528 - idx, &cur, new, &da_new, first, flist, 529 - &logflags, rsvd))) 530 - goto done; 531 - } else if (new->br_state == XFS_EXT_NORM) { 532 - ASSERT(new->br_state == XFS_EXT_NORM); 533 - if ((error = xfs_bmap_add_extent_unwritten_real( 534 - ip, idx, &cur, new, &logflags))) 535 - goto done; 560 + error = xfs_bmap_add_extent_delay_real(ip, 561 + idx, &cur, new, &da_new, 562 + first, flist, &logflags); 536 563 } else { 537 - ASSERT(new->br_state == XFS_EXT_UNWRITTEN); 538 - if ((error = xfs_bmap_add_extent_unwritten_real( 539 - ip, idx, &cur, new, &logflags))) 564 + ASSERT(new->br_state == XFS_EXT_NORM || 565 + new->br_state == XFS_EXT_UNWRITTEN); 566 + 567 + error = xfs_bmap_add_extent_unwritten_real(ip, 568 + idx, &cur, new, &logflags); 569 + if (error) 540 570 goto done; 541 571 } 542 - ASSERT(*curp == cur || *curp == NULL); 543 572 } 544 573 /* 545 574 * Otherwise we're filling in a hole with an allocation. ··· 544 581 if (cur) 545 582 ASSERT((cur->bc_private.b.flags & 546 583 XFS_BTCUR_BPRV_WASDEL) == 0); 547 - if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, 548 - new, &logflags, whichfork))) 549 - goto done; 584 + error = xfs_bmap_add_extent_hole_real(ip, idx, cur, 585 + new, &logflags, whichfork); 550 586 } 551 587 } 552 588 589 + if (error) 590 + goto done; 553 591 ASSERT(*curp == cur || *curp == NULL); 592 + 554 593 /* 555 594 * Convert to a btree if necessary. 556 595 */ ··· 580 615 ASSERT(nblks <= da_old); 581 616 if (nblks < da_old) 582 617 xfs_icsb_modify_counters(ip->i_mount, XFS_SBS_FDBLOCKS, 583 - (int64_t)(da_old - nblks), rsvd); 618 + (int64_t)(da_old - nblks), 0); 584 619 } 585 620 /* 586 621 * Clear out the allocated field, done with it now in any case. ··· 605 640 STATIC int /* error */ 606 641 xfs_bmap_add_extent_delay_real( 607 642 xfs_inode_t *ip, /* incore inode pointer */ 608 - xfs_extnum_t idx, /* extent number to update/insert */ 643 + xfs_extnum_t *idx, /* extent number to update/insert */ 609 644 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ 610 645 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 611 646 xfs_filblks_t *dnew, /* new delayed-alloc indirect blocks */ 612 647 xfs_fsblock_t *first, /* pointer to firstblock variable */ 613 648 xfs_bmap_free_t *flist, /* list of extents to be freed */ 614 - int *logflagsp, /* inode logging flags */ 615 - int rsvd) /* OK to use reserved data block allocation */ 649 + int *logflagsp) /* inode logging flags */ 616 650 { 617 651 xfs_btree_cur_t *cur; /* btree cursor */ 618 652 int diff; /* temp value */ ··· 637 673 */ 638 674 cur = *curp; 639 675 ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); 640 - ep = xfs_iext_get_ext(ifp, idx); 676 + ep = xfs_iext_get_ext(ifp, *idx); 641 677 xfs_bmbt_get_all(ep, &PREV); 642 678 new_endoff = new->br_startoff + new->br_blockcount; 643 679 ASSERT(PREV.br_startoff <= new->br_startoff); ··· 656 692 * Check and set flags if this segment has a left neighbor. 657 693 * Don't set contiguous if the combined extent would be too large. 658 694 */ 659 - if (idx > 0) { 695 + if (*idx > 0) { 660 696 state |= BMAP_LEFT_VALID; 661 - xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &LEFT); 697 + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx - 1), &LEFT); 662 698 663 699 if (isnullstartblock(LEFT.br_startblock)) 664 700 state |= BMAP_LEFT_DELAY; ··· 676 712 * Don't set contiguous if the combined extent would be too large. 677 713 * Also check for all-three-contiguous being too large. 678 714 */ 679 - if (idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1) { 715 + if (*idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1) { 680 716 state |= BMAP_RIGHT_VALID; 681 - xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx + 1), &RIGHT); 717 + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx + 1), &RIGHT); 682 718 683 719 if (isnullstartblock(RIGHT.br_startblock)) 684 720 state |= BMAP_RIGHT_DELAY; ··· 709 745 * Filling in all of a previously delayed allocation extent. 710 746 * The left and right neighbors are both contiguous with new. 711 747 */ 712 - trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); 713 - xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), 748 + --*idx; 749 + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 750 + xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx), 714 751 LEFT.br_blockcount + PREV.br_blockcount + 715 752 RIGHT.br_blockcount); 716 - trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); 753 + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 717 754 718 - xfs_iext_remove(ip, idx, 2, state); 719 - ip->i_df.if_lastex = idx - 1; 755 + xfs_iext_remove(ip, *idx + 1, 2, state); 720 756 ip->i_d.di_nextents--; 721 757 if (cur == NULL) 722 758 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; ··· 748 784 * Filling in all of a previously delayed allocation extent. 749 785 * The left neighbor is contiguous, the right is not. 750 786 */ 751 - trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); 752 - xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), 753 - LEFT.br_blockcount + PREV.br_blockcount); 754 - trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); 787 + --*idx; 755 788 756 - ip->i_df.if_lastex = idx - 1; 757 - xfs_iext_remove(ip, idx, 1, state); 789 + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 790 + xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx), 791 + LEFT.br_blockcount + PREV.br_blockcount); 792 + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 793 + 794 + xfs_iext_remove(ip, *idx + 1, 1, state); 758 795 if (cur == NULL) 759 796 rval = XFS_ILOG_DEXT; 760 797 else { ··· 779 814 * Filling in all of a previously delayed allocation extent. 780 815 * The right neighbor is contiguous, the left is not. 781 816 */ 782 - trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); 817 + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 783 818 xfs_bmbt_set_startblock(ep, new->br_startblock); 784 819 xfs_bmbt_set_blockcount(ep, 785 820 PREV.br_blockcount + RIGHT.br_blockcount); 786 - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 821 + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 787 822 788 - ip->i_df.if_lastex = idx; 789 - xfs_iext_remove(ip, idx + 1, 1, state); 823 + xfs_iext_remove(ip, *idx + 1, 1, state); 790 824 if (cur == NULL) 791 825 rval = XFS_ILOG_DEXT; 792 826 else { ··· 801 837 RIGHT.br_blockcount, PREV.br_state))) 802 838 goto done; 803 839 } 840 + 804 841 *dnew = 0; 805 842 break; 806 843 ··· 811 846 * Neither the left nor right neighbors are contiguous with 812 847 * the new one. 813 848 */ 814 - trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); 849 + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 815 850 xfs_bmbt_set_startblock(ep, new->br_startblock); 816 - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 851 + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 817 852 818 - ip->i_df.if_lastex = idx; 819 853 ip->i_d.di_nextents++; 820 854 if (cur == NULL) 821 855 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; ··· 830 866 goto done; 831 867 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 832 868 } 869 + 833 870 *dnew = 0; 834 871 break; 835 872 ··· 839 874 * Filling in the first part of a previous delayed allocation. 840 875 * The left neighbor is contiguous. 841 876 */ 842 - trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); 843 - xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), 877 + trace_xfs_bmap_pre_update(ip, *idx - 1, state, _THIS_IP_); 878 + xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx - 1), 844 879 LEFT.br_blockcount + new->br_blockcount); 845 880 xfs_bmbt_set_startoff(ep, 846 881 PREV.br_startoff + new->br_blockcount); 847 - trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); 882 + trace_xfs_bmap_post_update(ip, *idx - 1, state, _THIS_IP_); 848 883 849 884 temp = PREV.br_blockcount - new->br_blockcount; 850 - trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); 885 + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 851 886 xfs_bmbt_set_blockcount(ep, temp); 852 - ip->i_df.if_lastex = idx - 1; 853 887 if (cur == NULL) 854 888 rval = XFS_ILOG_DEXT; 855 889 else { ··· 868 904 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), 869 905 startblockval(PREV.br_startblock)); 870 906 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); 871 - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 907 + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 908 + 909 + --*idx; 872 910 *dnew = temp; 873 911 break; 874 912 ··· 879 913 * Filling in the first part of a previous delayed allocation. 880 914 * The left neighbor is not contiguous. 881 915 */ 882 - trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); 916 + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 883 917 xfs_bmbt_set_startoff(ep, new_endoff); 884 918 temp = PREV.br_blockcount - new->br_blockcount; 885 919 xfs_bmbt_set_blockcount(ep, temp); 886 - xfs_iext_insert(ip, idx, 1, new, state); 887 - ip->i_df.if_lastex = idx; 920 + xfs_iext_insert(ip, *idx, 1, new, state); 888 921 ip->i_d.di_nextents++; 889 922 if (cur == NULL) 890 923 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; ··· 911 946 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), 912 947 startblockval(PREV.br_startblock) - 913 948 (cur ? cur->bc_private.b.allocated : 0)); 914 - ep = xfs_iext_get_ext(ifp, idx + 1); 949 + ep = xfs_iext_get_ext(ifp, *idx + 1); 915 950 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); 916 - trace_xfs_bmap_post_update(ip, idx + 1, state, _THIS_IP_); 951 + trace_xfs_bmap_post_update(ip, *idx + 1, state, _THIS_IP_); 952 + 917 953 *dnew = temp; 918 954 break; 919 955 ··· 924 958 * The right neighbor is contiguous with the new allocation. 925 959 */ 926 960 temp = PREV.br_blockcount - new->br_blockcount; 927 - trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); 928 - trace_xfs_bmap_pre_update(ip, idx + 1, state, _THIS_IP_); 961 + trace_xfs_bmap_pre_update(ip, *idx + 1, state, _THIS_IP_); 929 962 xfs_bmbt_set_blockcount(ep, temp); 930 - xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, idx + 1), 963 + xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, *idx + 1), 931 964 new->br_startoff, new->br_startblock, 932 965 new->br_blockcount + RIGHT.br_blockcount, 933 966 RIGHT.br_state); 934 - trace_xfs_bmap_post_update(ip, idx + 1, state, _THIS_IP_); 935 - ip->i_df.if_lastex = idx + 1; 967 + trace_xfs_bmap_post_update(ip, *idx + 1, state, _THIS_IP_); 936 968 if (cur == NULL) 937 969 rval = XFS_ILOG_DEXT; 938 970 else { ··· 947 983 RIGHT.br_state))) 948 984 goto done; 949 985 } 986 + 950 987 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), 951 988 startblockval(PREV.br_startblock)); 989 + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 952 990 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); 953 - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 991 + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 992 + 993 + ++*idx; 954 994 *dnew = temp; 955 995 break; 956 996 ··· 964 996 * The right neighbor is not contiguous. 965 997 */ 966 998 temp = PREV.br_blockcount - new->br_blockcount; 967 - trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); 999 + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 968 1000 xfs_bmbt_set_blockcount(ep, temp); 969 - xfs_iext_insert(ip, idx + 1, 1, new, state); 970 - ip->i_df.if_lastex = idx + 1; 1001 + xfs_iext_insert(ip, *idx + 1, 1, new, state); 971 1002 ip->i_d.di_nextents++; 972 1003 if (cur == NULL) 973 1004 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; ··· 994 1027 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), 995 1028 startblockval(PREV.br_startblock) - 996 1029 (cur ? cur->bc_private.b.allocated : 0)); 997 - ep = xfs_iext_get_ext(ifp, idx); 1030 + ep = xfs_iext_get_ext(ifp, *idx); 998 1031 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); 999 - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 1032 + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 1033 + 1034 + ++*idx; 1000 1035 *dnew = temp; 1001 1036 break; 1002 1037 ··· 1025 1056 */ 1026 1057 temp = new->br_startoff - PREV.br_startoff; 1027 1058 temp2 = PREV.br_startoff + PREV.br_blockcount - new_endoff; 1028 - trace_xfs_bmap_pre_update(ip, idx, 0, _THIS_IP_); 1059 + trace_xfs_bmap_pre_update(ip, *idx, 0, _THIS_IP_); 1029 1060 xfs_bmbt_set_blockcount(ep, temp); /* truncate PREV */ 1030 1061 LEFT = *new; 1031 1062 RIGHT.br_state = PREV.br_state; ··· 1034 1065 RIGHT.br_startoff = new_endoff; 1035 1066 RIGHT.br_blockcount = temp2; 1036 1067 /* insert LEFT (r[0]) and RIGHT (r[1]) at the same time */ 1037 - xfs_iext_insert(ip, idx + 1, 2, &LEFT, state); 1038 - ip->i_df.if_lastex = idx + 1; 1068 + xfs_iext_insert(ip, *idx + 1, 2, &LEFT, state); 1039 1069 ip->i_d.di_nextents++; 1040 1070 if (cur == NULL) 1041 1071 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; ··· 1065 1097 (cur ? cur->bc_private.b.allocated : 0)); 1066 1098 if (diff > 0 && 1067 1099 xfs_icsb_modify_counters(ip->i_mount, XFS_SBS_FDBLOCKS, 1068 - -((int64_t)diff), rsvd)) { 1100 + -((int64_t)diff), 0)) { 1069 1101 /* 1070 1102 * Ick gross gag me with a spoon. 1071 1103 */ ··· 1077 1109 if (!diff || 1078 1110 !xfs_icsb_modify_counters(ip->i_mount, 1079 1111 XFS_SBS_FDBLOCKS, 1080 - -((int64_t)diff), rsvd)) 1112 + -((int64_t)diff), 0)) 1081 1113 break; 1082 1114 } 1083 1115 if (temp2) { ··· 1086 1118 if (!diff || 1087 1119 !xfs_icsb_modify_counters(ip->i_mount, 1088 1120 XFS_SBS_FDBLOCKS, 1089 - -((int64_t)diff), rsvd)) 1121 + -((int64_t)diff), 0)) 1090 1122 break; 1091 1123 } 1092 1124 } 1093 1125 } 1094 - ep = xfs_iext_get_ext(ifp, idx); 1126 + ep = xfs_iext_get_ext(ifp, *idx); 1095 1127 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); 1096 - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 1097 - trace_xfs_bmap_pre_update(ip, idx + 2, state, _THIS_IP_); 1098 - xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx + 2), 1128 + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 1129 + trace_xfs_bmap_pre_update(ip, *idx + 2, state, _THIS_IP_); 1130 + xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, *idx + 2), 1099 1131 nullstartblock((int)temp2)); 1100 - trace_xfs_bmap_post_update(ip, idx + 2, state, _THIS_IP_); 1132 + trace_xfs_bmap_post_update(ip, *idx + 2, state, _THIS_IP_); 1133 + 1134 + ++*idx; 1101 1135 *dnew = temp + temp2; 1102 1136 break; 1103 1137 ··· 1131 1161 STATIC int /* error */ 1132 1162 xfs_bmap_add_extent_unwritten_real( 1133 1163 xfs_inode_t *ip, /* incore inode pointer */ 1134 - xfs_extnum_t idx, /* extent number to update/insert */ 1164 + xfs_extnum_t *idx, /* extent number to update/insert */ 1135 1165 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ 1136 1166 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 1137 1167 int *logflagsp) /* inode logging flags */ ··· 1158 1188 error = 0; 1159 1189 cur = *curp; 1160 1190 ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); 1161 - ep = xfs_iext_get_ext(ifp, idx); 1191 + ep = xfs_iext_get_ext(ifp, *idx); 1162 1192 xfs_bmbt_get_all(ep, &PREV); 1163 1193 newext = new->br_state; 1164 1194 oldext = (newext == XFS_EXT_UNWRITTEN) ? ··· 1181 1211 * Check and set flags if this segment has a left neighbor. 1182 1212 * Don't set contiguous if the combined extent would be too large. 1183 1213 */ 1184 - if (idx > 0) { 1214 + if (*idx > 0) { 1185 1215 state |= BMAP_LEFT_VALID; 1186 - xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &LEFT); 1216 + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx - 1), &LEFT); 1187 1217 1188 1218 if (isnullstartblock(LEFT.br_startblock)) 1189 1219 state |= BMAP_LEFT_DELAY; ··· 1201 1231 * Don't set contiguous if the combined extent would be too large. 1202 1232 * Also check for all-three-contiguous being too large. 1203 1233 */ 1204 - if (idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1) { 1234 + if (*idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1) { 1205 1235 state |= BMAP_RIGHT_VALID; 1206 - xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx + 1), &RIGHT); 1236 + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx + 1), &RIGHT); 1207 1237 if (isnullstartblock(RIGHT.br_startblock)) 1208 1238 state |= BMAP_RIGHT_DELAY; 1209 1239 } ··· 1232 1262 * Setting all of a previous oldext extent to newext. 1233 1263 * The left and right neighbors are both contiguous with new. 1234 1264 */ 1235 - trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); 1236 - xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), 1265 + --*idx; 1266 + 1267 + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 1268 + xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx), 1237 1269 LEFT.br_blockcount + PREV.br_blockcount + 1238 1270 RIGHT.br_blockcount); 1239 - trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); 1271 + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 1240 1272 1241 - xfs_iext_remove(ip, idx, 2, state); 1242 - ip->i_df.if_lastex = idx - 1; 1273 + xfs_iext_remove(ip, *idx + 1, 2, state); 1243 1274 ip->i_d.di_nextents -= 2; 1244 1275 if (cur == NULL) 1245 1276 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; ··· 1276 1305 * Setting all of a previous oldext extent to newext. 1277 1306 * The left neighbor is contiguous, the right is not. 1278 1307 */ 1279 - trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); 1280 - xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), 1281 - LEFT.br_blockcount + PREV.br_blockcount); 1282 - trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); 1308 + --*idx; 1283 1309 1284 - ip->i_df.if_lastex = idx - 1; 1285 - xfs_iext_remove(ip, idx, 1, state); 1310 + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 1311 + xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx), 1312 + LEFT.br_blockcount + PREV.br_blockcount); 1313 + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 1314 + 1315 + xfs_iext_remove(ip, *idx + 1, 1, state); 1286 1316 ip->i_d.di_nextents--; 1287 1317 if (cur == NULL) 1288 1318 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; ··· 1313 1341 * Setting all of a previous oldext extent to newext. 1314 1342 * The right neighbor is contiguous, the left is not. 1315 1343 */ 1316 - trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); 1344 + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 1317 1345 xfs_bmbt_set_blockcount(ep, 1318 1346 PREV.br_blockcount + RIGHT.br_blockcount); 1319 1347 xfs_bmbt_set_state(ep, newext); 1320 - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 1321 - ip->i_df.if_lastex = idx; 1322 - xfs_iext_remove(ip, idx + 1, 1, state); 1348 + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 1349 + xfs_iext_remove(ip, *idx + 1, 1, state); 1323 1350 ip->i_d.di_nextents--; 1324 1351 if (cur == NULL) 1325 1352 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; ··· 1349 1378 * Neither the left nor right neighbors are contiguous with 1350 1379 * the new one. 1351 1380 */ 1352 - trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); 1381 + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 1353 1382 xfs_bmbt_set_state(ep, newext); 1354 - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 1383 + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 1355 1384 1356 - ip->i_df.if_lastex = idx; 1357 1385 if (cur == NULL) 1358 1386 rval = XFS_ILOG_DEXT; 1359 1387 else { ··· 1374 1404 * Setting the first part of a previous oldext extent to newext. 1375 1405 * The left neighbor is contiguous. 1376 1406 */ 1377 - trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); 1378 - xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), 1407 + trace_xfs_bmap_pre_update(ip, *idx - 1, state, _THIS_IP_); 1408 + xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx - 1), 1379 1409 LEFT.br_blockcount + new->br_blockcount); 1380 1410 xfs_bmbt_set_startoff(ep, 1381 1411 PREV.br_startoff + new->br_blockcount); 1382 - trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); 1412 + trace_xfs_bmap_post_update(ip, *idx - 1, state, _THIS_IP_); 1383 1413 1384 - trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); 1414 + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 1385 1415 xfs_bmbt_set_startblock(ep, 1386 1416 new->br_startblock + new->br_blockcount); 1387 1417 xfs_bmbt_set_blockcount(ep, 1388 1418 PREV.br_blockcount - new->br_blockcount); 1389 - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 1419 + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 1390 1420 1391 - ip->i_df.if_lastex = idx - 1; 1421 + --*idx; 1422 + 1392 1423 if (cur == NULL) 1393 1424 rval = XFS_ILOG_DEXT; 1394 1425 else { ··· 1420 1449 * Setting the first part of a previous oldext extent to newext. 1421 1450 * The left neighbor is not contiguous. 1422 1451 */ 1423 - trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); 1452 + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 1424 1453 ASSERT(ep && xfs_bmbt_get_state(ep) == oldext); 1425 1454 xfs_bmbt_set_startoff(ep, new_endoff); 1426 1455 xfs_bmbt_set_blockcount(ep, 1427 1456 PREV.br_blockcount - new->br_blockcount); 1428 1457 xfs_bmbt_set_startblock(ep, 1429 1458 new->br_startblock + new->br_blockcount); 1430 - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 1459 + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 1431 1460 1432 - xfs_iext_insert(ip, idx, 1, new, state); 1433 - ip->i_df.if_lastex = idx; 1461 + xfs_iext_insert(ip, *idx, 1, new, state); 1434 1462 ip->i_d.di_nextents++; 1435 1463 if (cur == NULL) 1436 1464 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; ··· 1458 1488 * Setting the last part of a previous oldext extent to newext. 1459 1489 * The right neighbor is contiguous with the new allocation. 1460 1490 */ 1461 - trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); 1462 - trace_xfs_bmap_pre_update(ip, idx + 1, state, _THIS_IP_); 1491 + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 1463 1492 xfs_bmbt_set_blockcount(ep, 1464 1493 PREV.br_blockcount - new->br_blockcount); 1465 - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 1466 - xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, idx + 1), 1494 + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 1495 + 1496 + ++*idx; 1497 + 1498 + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 1499 + xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, *idx), 1467 1500 new->br_startoff, new->br_startblock, 1468 1501 new->br_blockcount + RIGHT.br_blockcount, newext); 1469 - trace_xfs_bmap_post_update(ip, idx + 1, state, _THIS_IP_); 1502 + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 1470 1503 1471 - ip->i_df.if_lastex = idx + 1; 1472 1504 if (cur == NULL) 1473 1505 rval = XFS_ILOG_DEXT; 1474 1506 else { ··· 1500 1528 * Setting the last part of a previous oldext extent to newext. 1501 1529 * The right neighbor is not contiguous. 1502 1530 */ 1503 - trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); 1531 + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 1504 1532 xfs_bmbt_set_blockcount(ep, 1505 1533 PREV.br_blockcount - new->br_blockcount); 1506 - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 1534 + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 1507 1535 1508 - xfs_iext_insert(ip, idx + 1, 1, new, state); 1509 - ip->i_df.if_lastex = idx + 1; 1536 + ++*idx; 1537 + xfs_iext_insert(ip, *idx, 1, new, state); 1538 + 1510 1539 ip->i_d.di_nextents++; 1511 1540 if (cur == NULL) 1512 1541 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; ··· 1541 1568 * newext. Contiguity is impossible here. 1542 1569 * One extent becomes three extents. 1543 1570 */ 1544 - trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); 1571 + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 1545 1572 xfs_bmbt_set_blockcount(ep, 1546 1573 new->br_startoff - PREV.br_startoff); 1547 - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 1574 + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 1548 1575 1549 1576 r[0] = *new; 1550 1577 r[1].br_startoff = new_endoff; ··· 1552 1579 PREV.br_startoff + PREV.br_blockcount - new_endoff; 1553 1580 r[1].br_startblock = new->br_startblock + new->br_blockcount; 1554 1581 r[1].br_state = oldext; 1555 - xfs_iext_insert(ip, idx + 1, 2, &r[0], state); 1556 - ip->i_df.if_lastex = idx + 1; 1582 + 1583 + ++*idx; 1584 + xfs_iext_insert(ip, *idx, 2, &r[0], state); 1585 + 1557 1586 ip->i_d.di_nextents += 2; 1558 1587 if (cur == NULL) 1559 1588 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; ··· 1625 1650 STATIC int /* error */ 1626 1651 xfs_bmap_add_extent_hole_delay( 1627 1652 xfs_inode_t *ip, /* incore inode pointer */ 1628 - xfs_extnum_t idx, /* extent number to update/insert */ 1653 + xfs_extnum_t *idx, /* extent number to update/insert */ 1629 1654 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 1630 - int *logflagsp, /* inode logging flags */ 1631 - int rsvd) /* OK to allocate reserved blocks */ 1655 + int *logflagsp) /* inode logging flags */ 1632 1656 { 1633 - xfs_bmbt_rec_host_t *ep; /* extent record for idx */ 1634 1657 xfs_ifork_t *ifp; /* inode fork pointer */ 1635 1658 xfs_bmbt_irec_t left; /* left neighbor extent entry */ 1636 1659 xfs_filblks_t newlen=0; /* new indirect size */ ··· 1638 1665 xfs_filblks_t temp=0; /* temp for indirect calculations */ 1639 1666 1640 1667 ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); 1641 - ep = xfs_iext_get_ext(ifp, idx); 1642 1668 state = 0; 1643 1669 ASSERT(isnullstartblock(new->br_startblock)); 1644 1670 1645 1671 /* 1646 1672 * Check and set flags if this segment has a left neighbor 1647 1673 */ 1648 - if (idx > 0) { 1674 + if (*idx > 0) { 1649 1675 state |= BMAP_LEFT_VALID; 1650 - xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &left); 1676 + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx - 1), &left); 1651 1677 1652 1678 if (isnullstartblock(left.br_startblock)) 1653 1679 state |= BMAP_LEFT_DELAY; ··· 1656 1684 * Check and set flags if the current (right) segment exists. 1657 1685 * If it doesn't exist, we're converting the hole at end-of-file. 1658 1686 */ 1659 - if (idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t)) { 1687 + if (*idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t)) { 1660 1688 state |= BMAP_RIGHT_VALID; 1661 - xfs_bmbt_get_all(ep, &right); 1689 + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx), &right); 1662 1690 1663 1691 if (isnullstartblock(right.br_startblock)) 1664 1692 state |= BMAP_RIGHT_DELAY; ··· 1691 1719 * on the left and on the right. 1692 1720 * Merge all three into a single extent record. 1693 1721 */ 1722 + --*idx; 1694 1723 temp = left.br_blockcount + new->br_blockcount + 1695 1724 right.br_blockcount; 1696 1725 1697 - trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); 1698 - xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), temp); 1726 + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 1727 + xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx), temp); 1699 1728 oldlen = startblockval(left.br_startblock) + 1700 1729 startblockval(new->br_startblock) + 1701 1730 startblockval(right.br_startblock); 1702 1731 newlen = xfs_bmap_worst_indlen(ip, temp); 1703 - xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx - 1), 1732 + xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, *idx), 1704 1733 nullstartblock((int)newlen)); 1705 - trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); 1734 + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 1706 1735 1707 - xfs_iext_remove(ip, idx, 1, state); 1708 - ip->i_df.if_lastex = idx - 1; 1736 + xfs_iext_remove(ip, *idx + 1, 1, state); 1709 1737 break; 1710 1738 1711 1739 case BMAP_LEFT_CONTIG: ··· 1714 1742 * on the left. 1715 1743 * Merge the new allocation with the left neighbor. 1716 1744 */ 1745 + --*idx; 1717 1746 temp = left.br_blockcount + new->br_blockcount; 1718 - trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); 1719 - xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), temp); 1747 + 1748 + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 1749 + xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx), temp); 1720 1750 oldlen = startblockval(left.br_startblock) + 1721 1751 startblockval(new->br_startblock); 1722 1752 newlen = xfs_bmap_worst_indlen(ip, temp); 1723 - xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx - 1), 1753 + xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, *idx), 1724 1754 nullstartblock((int)newlen)); 1725 - trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); 1726 - 1727 - ip->i_df.if_lastex = idx - 1; 1755 + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 1728 1756 break; 1729 1757 1730 1758 case BMAP_RIGHT_CONTIG: ··· 1733 1761 * on the right. 1734 1762 * Merge the new allocation with the right neighbor. 1735 1763 */ 1736 - trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); 1764 + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 1737 1765 temp = new->br_blockcount + right.br_blockcount; 1738 1766 oldlen = startblockval(new->br_startblock) + 1739 1767 startblockval(right.br_startblock); 1740 1768 newlen = xfs_bmap_worst_indlen(ip, temp); 1741 - xfs_bmbt_set_allf(ep, new->br_startoff, 1769 + xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, *idx), 1770 + new->br_startoff, 1742 1771 nullstartblock((int)newlen), temp, right.br_state); 1743 - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 1744 - 1745 - ip->i_df.if_lastex = idx; 1772 + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 1746 1773 break; 1747 1774 1748 1775 case 0: ··· 1751 1780 * Insert a new entry. 1752 1781 */ 1753 1782 oldlen = newlen = 0; 1754 - xfs_iext_insert(ip, idx, 1, new, state); 1755 - ip->i_df.if_lastex = idx; 1783 + xfs_iext_insert(ip, *idx, 1, new, state); 1756 1784 break; 1757 1785 } 1758 1786 if (oldlen != newlen) { 1759 1787 ASSERT(oldlen > newlen); 1760 1788 xfs_icsb_modify_counters(ip->i_mount, XFS_SBS_FDBLOCKS, 1761 - (int64_t)(oldlen - newlen), rsvd); 1789 + (int64_t)(oldlen - newlen), 0); 1762 1790 /* 1763 1791 * Nothing to do for disk quota accounting here. 1764 1792 */ ··· 1773 1803 STATIC int /* error */ 1774 1804 xfs_bmap_add_extent_hole_real( 1775 1805 xfs_inode_t *ip, /* incore inode pointer */ 1776 - xfs_extnum_t idx, /* extent number to update/insert */ 1806 + xfs_extnum_t *idx, /* extent number to update/insert */ 1777 1807 xfs_btree_cur_t *cur, /* if null, not a btree */ 1778 1808 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 1779 1809 int *logflagsp, /* inode logging flags */ 1780 1810 int whichfork) /* data or attr fork */ 1781 1811 { 1782 - xfs_bmbt_rec_host_t *ep; /* pointer to extent entry ins. point */ 1783 1812 int error; /* error return value */ 1784 1813 int i; /* temp state */ 1785 1814 xfs_ifork_t *ifp; /* inode fork pointer */ ··· 1788 1819 int state; /* state bits, accessed thru macros */ 1789 1820 1790 1821 ifp = XFS_IFORK_PTR(ip, whichfork); 1791 - ASSERT(idx <= ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)); 1792 - ep = xfs_iext_get_ext(ifp, idx); 1822 + ASSERT(*idx <= ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)); 1793 1823 state = 0; 1794 1824 1795 1825 if (whichfork == XFS_ATTR_FORK) ··· 1797 1829 /* 1798 1830 * Check and set flags if this segment has a left neighbor. 1799 1831 */ 1800 - if (idx > 0) { 1832 + if (*idx > 0) { 1801 1833 state |= BMAP_LEFT_VALID; 1802 - xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &left); 1834 + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx - 1), &left); 1803 1835 if (isnullstartblock(left.br_startblock)) 1804 1836 state |= BMAP_LEFT_DELAY; 1805 1837 } ··· 1808 1840 * Check and set flags if this segment has a current value. 1809 1841 * Not true if we're inserting into the "hole" at eof. 1810 1842 */ 1811 - if (idx < ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)) { 1843 + if (*idx < ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)) { 1812 1844 state |= BMAP_RIGHT_VALID; 1813 - xfs_bmbt_get_all(ep, &right); 1845 + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx), &right); 1814 1846 if (isnullstartblock(right.br_startblock)) 1815 1847 state |= BMAP_RIGHT_DELAY; 1816 1848 } ··· 1847 1879 * left and on the right. 1848 1880 * Merge all three into a single extent record. 1849 1881 */ 1850 - trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); 1851 - xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), 1882 + --*idx; 1883 + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 1884 + xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx), 1852 1885 left.br_blockcount + new->br_blockcount + 1853 1886 right.br_blockcount); 1854 - trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); 1887 + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 1855 1888 1856 - xfs_iext_remove(ip, idx, 1, state); 1857 - ifp->if_lastex = idx - 1; 1889 + xfs_iext_remove(ip, *idx + 1, 1, state); 1890 + 1858 1891 XFS_IFORK_NEXT_SET(ip, whichfork, 1859 1892 XFS_IFORK_NEXTENTS(ip, whichfork) - 1); 1860 1893 if (cur == NULL) { ··· 1890 1921 * on the left. 1891 1922 * Merge the new allocation with the left neighbor. 1892 1923 */ 1893 - trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); 1894 - xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), 1924 + --*idx; 1925 + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 1926 + xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx), 1895 1927 left.br_blockcount + new->br_blockcount); 1896 - trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); 1928 + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 1897 1929 1898 - ifp->if_lastex = idx - 1; 1899 1930 if (cur == NULL) { 1900 1931 rval = xfs_ilog_fext(whichfork); 1901 1932 } else { ··· 1921 1952 * on the right. 1922 1953 * Merge the new allocation with the right neighbor. 1923 1954 */ 1924 - trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); 1925 - xfs_bmbt_set_allf(ep, new->br_startoff, new->br_startblock, 1955 + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 1956 + xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, *idx), 1957 + new->br_startoff, new->br_startblock, 1926 1958 new->br_blockcount + right.br_blockcount, 1927 1959 right.br_state); 1928 - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 1960 + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 1929 1961 1930 - ifp->if_lastex = idx; 1931 1962 if (cur == NULL) { 1932 1963 rval = xfs_ilog_fext(whichfork); 1933 1964 } else { ··· 1953 1984 * real allocation. 1954 1985 * Insert a new entry. 1955 1986 */ 1956 - xfs_iext_insert(ip, idx, 1, new, state); 1957 - ifp->if_lastex = idx; 1987 + xfs_iext_insert(ip, *idx, 1, new, state); 1958 1988 XFS_IFORK_NEXT_SET(ip, whichfork, 1959 1989 XFS_IFORK_NEXTENTS(ip, whichfork) + 1); 1960 1990 if (cur == NULL) { ··· 2801 2833 xfs_bmap_del_extent( 2802 2834 xfs_inode_t *ip, /* incore inode pointer */ 2803 2835 xfs_trans_t *tp, /* current transaction pointer */ 2804 - xfs_extnum_t idx, /* extent number to update/delete */ 2836 + xfs_extnum_t *idx, /* extent number to update/delete */ 2805 2837 xfs_bmap_free_t *flist, /* list of extents to be freed */ 2806 2838 xfs_btree_cur_t *cur, /* if null, not a btree */ 2807 2839 xfs_bmbt_irec_t *del, /* data to remove from extents */ 2808 2840 int *logflagsp, /* inode logging flags */ 2809 - int whichfork, /* data or attr fork */ 2810 - int rsvd) /* OK to allocate reserved blocks */ 2841 + int whichfork) /* data or attr fork */ 2811 2842 { 2812 2843 xfs_filblks_t da_new; /* new delay-alloc indirect blocks */ 2813 2844 xfs_filblks_t da_old; /* old delay-alloc indirect blocks */ ··· 2837 2870 2838 2871 mp = ip->i_mount; 2839 2872 ifp = XFS_IFORK_PTR(ip, whichfork); 2840 - ASSERT((idx >= 0) && (idx < ifp->if_bytes / 2873 + ASSERT((*idx >= 0) && (*idx < ifp->if_bytes / 2841 2874 (uint)sizeof(xfs_bmbt_rec_t))); 2842 2875 ASSERT(del->br_blockcount > 0); 2843 - ep = xfs_iext_get_ext(ifp, idx); 2876 + ep = xfs_iext_get_ext(ifp, *idx); 2844 2877 xfs_bmbt_get_all(ep, &got); 2845 2878 ASSERT(got.br_startoff <= del->br_startoff); 2846 2879 del_endoff = del->br_startoff + del->br_blockcount; ··· 2914 2947 /* 2915 2948 * Matches the whole extent. Delete the entry. 2916 2949 */ 2917 - xfs_iext_remove(ip, idx, 1, 2950 + xfs_iext_remove(ip, *idx, 1, 2918 2951 whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0); 2919 - ifp->if_lastex = idx; 2952 + --*idx; 2920 2953 if (delay) 2921 2954 break; 2955 + 2922 2956 XFS_IFORK_NEXT_SET(ip, whichfork, 2923 2957 XFS_IFORK_NEXTENTS(ip, whichfork) - 1); 2924 2958 flags |= XFS_ILOG_CORE; ··· 2936 2968 /* 2937 2969 * Deleting the first part of the extent. 2938 2970 */ 2939 - trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); 2971 + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 2940 2972 xfs_bmbt_set_startoff(ep, del_endoff); 2941 2973 temp = got.br_blockcount - del->br_blockcount; 2942 2974 xfs_bmbt_set_blockcount(ep, temp); 2943 - ifp->if_lastex = idx; 2944 2975 if (delay) { 2945 2976 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), 2946 2977 da_old); 2947 2978 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); 2948 - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 2979 + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 2949 2980 da_new = temp; 2950 2981 break; 2951 2982 } 2952 2983 xfs_bmbt_set_startblock(ep, del_endblock); 2953 - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 2984 + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 2954 2985 if (!cur) { 2955 2986 flags |= xfs_ilog_fext(whichfork); 2956 2987 break; ··· 2965 2998 * Deleting the last part of the extent. 2966 2999 */ 2967 3000 temp = got.br_blockcount - del->br_blockcount; 2968 - trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); 3001 + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 2969 3002 xfs_bmbt_set_blockcount(ep, temp); 2970 - ifp->if_lastex = idx; 2971 3003 if (delay) { 2972 3004 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), 2973 3005 da_old); 2974 3006 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); 2975 - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 3007 + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 2976 3008 da_new = temp; 2977 3009 break; 2978 3010 } 2979 - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 3011 + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 2980 3012 if (!cur) { 2981 3013 flags |= xfs_ilog_fext(whichfork); 2982 3014 break; ··· 2992 3026 * Deleting the middle of the extent. 2993 3027 */ 2994 3028 temp = del->br_startoff - got.br_startoff; 2995 - trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); 3029 + trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 2996 3030 xfs_bmbt_set_blockcount(ep, temp); 2997 3031 new.br_startoff = del_endoff; 2998 3032 temp2 = got_endoff - del_endoff; ··· 3079 3113 } 3080 3114 } 3081 3115 } 3082 - trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); 3083 - xfs_iext_insert(ip, idx + 1, 1, &new, state); 3084 - ifp->if_lastex = idx + 1; 3116 + trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 3117 + xfs_iext_insert(ip, *idx + 1, 1, &new, state); 3118 + ++*idx; 3085 3119 break; 3086 3120 } 3087 3121 /* ··· 3108 3142 ASSERT(da_old >= da_new); 3109 3143 if (da_old > da_new) { 3110 3144 xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, 3111 - (int64_t)(da_old - da_new), rsvd); 3145 + (int64_t)(da_old - da_new), 0); 3112 3146 } 3113 3147 done: 3114 3148 *logflagsp = flags; ··· 4528 4562 if (rt) { 4529 4563 error = xfs_mod_incore_sb(mp, 4530 4564 XFS_SBS_FREXTENTS, 4531 - -((int64_t)extsz), (flags & 4532 - XFS_BMAPI_RSVBLOCKS)); 4565 + -((int64_t)extsz), 0); 4533 4566 } else { 4534 4567 error = xfs_icsb_modify_counters(mp, 4535 4568 XFS_SBS_FDBLOCKS, 4536 - -((int64_t)alen), (flags & 4537 - XFS_BMAPI_RSVBLOCKS)); 4569 + -((int64_t)alen), 0); 4538 4570 } 4539 4571 if (!error) { 4540 4572 error = xfs_icsb_modify_counters(mp, 4541 4573 XFS_SBS_FDBLOCKS, 4542 - -((int64_t)indlen), (flags & 4543 - XFS_BMAPI_RSVBLOCKS)); 4574 + -((int64_t)indlen), 0); 4544 4575 if (error && rt) 4545 4576 xfs_mod_incore_sb(mp, 4546 4577 XFS_SBS_FREXTENTS, 4547 - (int64_t)extsz, (flags & 4548 - XFS_BMAPI_RSVBLOCKS)); 4578 + (int64_t)extsz, 0); 4549 4579 else if (error) 4550 4580 xfs_icsb_modify_counters(mp, 4551 4581 XFS_SBS_FDBLOCKS, 4552 - (int64_t)alen, (flags & 4553 - XFS_BMAPI_RSVBLOCKS)); 4582 + (int64_t)alen, 0); 4554 4583 } 4555 4584 4556 4585 if (error) { ··· 4662 4701 if (!wasdelay && (flags & XFS_BMAPI_PREALLOC)) 4663 4702 got.br_state = XFS_EXT_UNWRITTEN; 4664 4703 } 4665 - error = xfs_bmap_add_extent(ip, lastx, &cur, &got, 4704 + error = xfs_bmap_add_extent(ip, &lastx, &cur, &got, 4666 4705 firstblock, flist, &tmp_logflags, 4667 - whichfork, (flags & XFS_BMAPI_RSVBLOCKS)); 4706 + whichfork); 4668 4707 logflags |= tmp_logflags; 4669 4708 if (error) 4670 4709 goto error0; 4671 - lastx = ifp->if_lastex; 4672 4710 ep = xfs_iext_get_ext(ifp, lastx); 4673 4711 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 4674 4712 xfs_bmbt_get_all(ep, &got); ··· 4763 4803 mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN) 4764 4804 ? XFS_EXT_NORM 4765 4805 : XFS_EXT_UNWRITTEN; 4766 - error = xfs_bmap_add_extent(ip, lastx, &cur, mval, 4806 + error = xfs_bmap_add_extent(ip, &lastx, &cur, mval, 4767 4807 firstblock, flist, &tmp_logflags, 4768 - whichfork, (flags & XFS_BMAPI_RSVBLOCKS)); 4808 + whichfork); 4769 4809 logflags |= tmp_logflags; 4770 4810 if (error) 4771 4811 goto error0; 4772 - lastx = ifp->if_lastex; 4773 4812 ep = xfs_iext_get_ext(ifp, lastx); 4774 4813 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 4775 4814 xfs_bmbt_get_all(ep, &got); ··· 4827 4868 /* 4828 4869 * Else go on to the next record. 4829 4870 */ 4830 - ep = xfs_iext_get_ext(ifp, ++lastx); 4831 4871 prev = got; 4832 - if (lastx >= nextents) 4833 - eof = 1; 4834 - else 4872 + if (++lastx < nextents) { 4873 + ep = xfs_iext_get_ext(ifp, lastx); 4835 4874 xfs_bmbt_get_all(ep, &got); 4875 + } else { 4876 + eof = 1; 4877 + } 4836 4878 } 4837 - ifp->if_lastex = lastx; 4838 4879 *nmap = n; 4839 4880 /* 4840 4881 * Transform from btree to extents, give it cur. ··· 4943 4984 ASSERT(!isnullstartblock(got.br_startblock)); 4944 4985 ASSERT(bno < got.br_startoff + got.br_blockcount); 4945 4986 *fsb = got.br_startblock + (bno - got.br_startoff); 4946 - ifp->if_lastex = lastx; 4947 4987 return 0; 4948 4988 } 4949 4989 ··· 4984 5026 int tmp_logflags; /* partial logging flags */ 4985 5027 int wasdel; /* was a delayed alloc extent */ 4986 5028 int whichfork; /* data or attribute fork */ 4987 - int rsvd; /* OK to allocate reserved blocks */ 4988 5029 xfs_fsblock_t sum; 4989 5030 4990 5031 trace_xfs_bunmap(ip, bno, len, flags, _RET_IP_); ··· 5001 5044 mp = ip->i_mount; 5002 5045 if (XFS_FORCED_SHUTDOWN(mp)) 5003 5046 return XFS_ERROR(EIO); 5004 - rsvd = (flags & XFS_BMAPI_RSVBLOCKS) != 0; 5047 + 5005 5048 ASSERT(len > 0); 5006 5049 ASSERT(nexts >= 0); 5007 5050 ASSERT(ifp->if_ext_max == ··· 5117 5160 del.br_blockcount = mod; 5118 5161 } 5119 5162 del.br_state = XFS_EXT_UNWRITTEN; 5120 - error = xfs_bmap_add_extent(ip, lastx, &cur, &del, 5163 + error = xfs_bmap_add_extent(ip, &lastx, &cur, &del, 5121 5164 firstblock, flist, &logflags, 5122 - XFS_DATA_FORK, 0); 5165 + XFS_DATA_FORK); 5123 5166 if (error) 5124 5167 goto error0; 5125 5168 goto nodelete; ··· 5145 5188 */ 5146 5189 ASSERT(bno >= del.br_blockcount); 5147 5190 bno -= del.br_blockcount; 5148 - if (bno < got.br_startoff) { 5149 - if (--lastx >= 0) 5150 - xfs_bmbt_get_all(--ep, &got); 5191 + if (got.br_startoff > bno) { 5192 + if (--lastx >= 0) { 5193 + ep = xfs_iext_get_ext(ifp, 5194 + lastx); 5195 + xfs_bmbt_get_all(ep, &got); 5196 + } 5151 5197 } 5152 5198 continue; 5153 5199 } else if (del.br_state == XFS_EXT_UNWRITTEN) { ··· 5174 5214 prev.br_startoff = start; 5175 5215 } 5176 5216 prev.br_state = XFS_EXT_UNWRITTEN; 5177 - error = xfs_bmap_add_extent(ip, lastx - 1, &cur, 5217 + lastx--; 5218 + error = xfs_bmap_add_extent(ip, &lastx, &cur, 5178 5219 &prev, firstblock, flist, &logflags, 5179 - XFS_DATA_FORK, 0); 5220 + XFS_DATA_FORK); 5180 5221 if (error) 5181 5222 goto error0; 5182 5223 goto nodelete; 5183 5224 } else { 5184 5225 ASSERT(del.br_state == XFS_EXT_NORM); 5185 5226 del.br_state = XFS_EXT_UNWRITTEN; 5186 - error = xfs_bmap_add_extent(ip, lastx, &cur, 5227 + error = xfs_bmap_add_extent(ip, &lastx, &cur, 5187 5228 &del, firstblock, flist, &logflags, 5188 - XFS_DATA_FORK, 0); 5229 + XFS_DATA_FORK); 5189 5230 if (error) 5190 5231 goto error0; 5191 5232 goto nodelete; ··· 5201 5240 rtexts = XFS_FSB_TO_B(mp, del.br_blockcount); 5202 5241 do_div(rtexts, mp->m_sb.sb_rextsize); 5203 5242 xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS, 5204 - (int64_t)rtexts, rsvd); 5243 + (int64_t)rtexts, 0); 5205 5244 (void)xfs_trans_reserve_quota_nblks(NULL, 5206 5245 ip, -((long)del.br_blockcount), 0, 5207 5246 XFS_QMOPT_RES_RTBLKS); 5208 5247 } else { 5209 5248 xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, 5210 - (int64_t)del.br_blockcount, rsvd); 5249 + (int64_t)del.br_blockcount, 0); 5211 5250 (void)xfs_trans_reserve_quota_nblks(NULL, 5212 5251 ip, -((long)del.br_blockcount), 0, 5213 5252 XFS_QMOPT_RES_REGBLKS); ··· 5238 5277 error = XFS_ERROR(ENOSPC); 5239 5278 goto error0; 5240 5279 } 5241 - error = xfs_bmap_del_extent(ip, tp, lastx, flist, cur, &del, 5242 - &tmp_logflags, whichfork, rsvd); 5280 + error = xfs_bmap_del_extent(ip, tp, &lastx, flist, cur, &del, 5281 + &tmp_logflags, whichfork); 5243 5282 logflags |= tmp_logflags; 5244 5283 if (error) 5245 5284 goto error0; 5246 5285 bno = del.br_startoff - 1; 5247 5286 nodelete: 5248 - lastx = ifp->if_lastex; 5249 5287 /* 5250 5288 * If not done go on to the next (previous) record. 5251 - * Reset ep in case the extents array was re-alloced. 5252 5289 */ 5253 - ep = xfs_iext_get_ext(ifp, lastx); 5254 5290 if (bno != (xfs_fileoff_t)-1 && bno >= start) { 5255 - if (lastx >= XFS_IFORK_NEXTENTS(ip, whichfork) || 5256 - xfs_bmbt_get_startoff(ep) > bno) { 5257 - if (--lastx >= 0) 5258 - ep = xfs_iext_get_ext(ifp, lastx); 5259 - } 5260 - if (lastx >= 0) 5291 + if (lastx >= 0) { 5292 + ep = xfs_iext_get_ext(ifp, lastx); 5293 + if (xfs_bmbt_get_startoff(ep) > bno) { 5294 + if (--lastx >= 0) 5295 + ep = xfs_iext_get_ext(ifp, 5296 + lastx); 5297 + } 5261 5298 xfs_bmbt_get_all(ep, &got); 5299 + } 5262 5300 extno++; 5263 5301 } 5264 5302 } 5265 - ifp->if_lastex = lastx; 5266 5303 *done = bno == (xfs_fileoff_t)-1 || bno < start || lastx < 0; 5267 5304 ASSERT(ifp->if_ext_max == 5268 5305 XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
-2
fs/xfs/xfs_bmap.h
··· 69 69 #define XFS_BMAPI_ENTIRE 0x004 /* return entire extent, not trimmed */ 70 70 #define XFS_BMAPI_METADATA 0x008 /* mapping metadata not user data */ 71 71 #define XFS_BMAPI_ATTRFORK 0x010 /* use attribute fork not data */ 72 - #define XFS_BMAPI_RSVBLOCKS 0x020 /* OK to alloc. reserved data blocks */ 73 72 #define XFS_BMAPI_PREALLOC 0x040 /* preallocation op: unwritten space */ 74 73 #define XFS_BMAPI_IGSTATE 0x080 /* Ignore state - */ 75 74 /* combine contig. space */ ··· 86 87 { XFS_BMAPI_ENTIRE, "ENTIRE" }, \ 87 88 { XFS_BMAPI_METADATA, "METADATA" }, \ 88 89 { XFS_BMAPI_ATTRFORK, "ATTRFORK" }, \ 89 - { XFS_BMAPI_RSVBLOCKS, "RSVBLOCKS" }, \ 90 90 { XFS_BMAPI_PREALLOC, "PREALLOC" }, \ 91 91 { XFS_BMAPI_IGSTATE, "IGSTATE" }, \ 92 92 { XFS_BMAPI_CONTIG, "CONTIG" }, \
+7 -8
fs/xfs/xfs_inode.c
··· 920 920 /* 921 921 * We know that the size is valid (it's checked in iformat_btree) 922 922 */ 923 - ifp->if_lastex = NULLEXTNUM; 924 923 ifp->if_bytes = ifp->if_real_bytes = 0; 925 924 ifp->if_flags |= XFS_IFEXTENTS; 926 925 xfs_iext_add(ifp, 0, nextents); ··· 2557 2558 case XFS_DINODE_FMT_EXTENTS: 2558 2559 ASSERT((ifp->if_flags & XFS_IFEXTENTS) || 2559 2560 !(iip->ili_format.ilf_fields & extflag[whichfork])); 2560 - ASSERT((xfs_iext_get_ext(ifp, 0) != NULL) || 2561 - (ifp->if_bytes == 0)); 2562 - ASSERT((xfs_iext_get_ext(ifp, 0) == NULL) || 2563 - (ifp->if_bytes > 0)); 2564 2561 if ((iip->ili_format.ilf_fields & extflag[whichfork]) && 2565 2562 (ifp->if_bytes > 0)) { 2563 + ASSERT(xfs_iext_get_ext(ifp, 0)); 2566 2564 ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) > 0); 2567 2565 (void)xfs_iextents_copy(ip, (xfs_bmbt_rec_t *)cp, 2568 2566 whichfork); ··· 3108 3112 xfs_extnum_t idx) /* index of target extent */ 3109 3113 { 3110 3114 ASSERT(idx >= 0); 3115 + ASSERT(idx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t)); 3116 + 3111 3117 if ((ifp->if_flags & XFS_IFEXTIREC) && (idx == 0)) { 3112 3118 return ifp->if_u1.if_ext_irec->er_extbuf; 3113 3119 } else if (ifp->if_flags & XFS_IFEXTIREC) { ··· 3189 3191 } 3190 3192 ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext; 3191 3193 ifp->if_real_bytes = 0; 3192 - ifp->if_lastex = nextents + ext_diff; 3193 3194 } 3194 3195 /* 3195 3196 * Otherwise use a linear (direct) extent list. ··· 3883 3886 xfs_extnum_t page_idx = *idxp; /* extent index in target list */ 3884 3887 3885 3888 ASSERT(ifp->if_flags & XFS_IFEXTIREC); 3886 - ASSERT(page_idx >= 0 && page_idx <= 3887 - ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)); 3889 + ASSERT(page_idx >= 0); 3890 + ASSERT(page_idx <= ifp->if_bytes / sizeof(xfs_bmbt_rec_t)); 3891 + ASSERT(page_idx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t) || realloc); 3892 + 3888 3893 nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; 3889 3894 erp_idx = 0; 3890 3895 low = 0;
-1
fs/xfs/xfs_inode.h
··· 67 67 short if_broot_bytes; /* bytes allocated for root */ 68 68 unsigned char if_flags; /* per-fork flags */ 69 69 unsigned char if_ext_max; /* max # of extent records */ 70 - xfs_extnum_t if_lastex; /* last if_extents used */ 71 70 union { 72 71 xfs_bmbt_rec_host_t *if_extents;/* linear map file exts */ 73 72 xfs_ext_irec_t *if_ext_irec; /* irec map file exts */
+12 -1
fs/xfs/xfs_log_cil.c
··· 29 29 #include "xfs_mount.h" 30 30 #include "xfs_error.h" 31 31 #include "xfs_alloc.h" 32 + #include "xfs_discard.h" 32 33 33 34 /* 34 35 * Perform initial CIL structure initialisation. If the CIL is not ··· 362 361 int abort) 363 362 { 364 363 struct xfs_cil_ctx *ctx = args; 364 + struct xfs_mount *mp = ctx->cil->xc_log->l_mp; 365 365 366 366 xfs_trans_committed_bulk(ctx->cil->xc_log->l_ailp, ctx->lv_chain, 367 367 ctx->start_lsn, abort); 368 368 369 369 xfs_alloc_busy_sort(&ctx->busy_extents); 370 - xfs_alloc_busy_clear(ctx->cil->xc_log->l_mp, &ctx->busy_extents); 370 + xfs_alloc_busy_clear(mp, &ctx->busy_extents, 371 + (mp->m_flags & XFS_MOUNT_DISCARD) && !abort); 371 372 372 373 spin_lock(&ctx->cil->xc_cil_lock); 373 374 list_del(&ctx->committing); 374 375 spin_unlock(&ctx->cil->xc_cil_lock); 375 376 376 377 xlog_cil_free_logvec(ctx->lv_chain); 378 + 379 + if (!list_empty(&ctx->busy_extents)) { 380 + ASSERT(mp->m_flags & XFS_MOUNT_DISCARD); 381 + 382 + xfs_discard_extents(mp, &ctx->busy_extents); 383 + xfs_alloc_busy_clear(mp, &ctx->busy_extents, false); 384 + } 385 + 377 386 kmem_free(ctx); 378 387 } 379 388
+1
fs/xfs/xfs_mount.h
··· 224 224 #define XFS_MOUNT_FS_SHUTDOWN (1ULL << 4) /* atomic stop of all filesystem 225 225 operations, typically for 226 226 disk errors in metadata */ 227 + #define XFS_MOUNT_DISCARD (1ULL << 5) /* discard unused blocks */ 227 228 #define XFS_MOUNT_RETERR (1ULL << 6) /* return alignment errors to 228 229 user */ 229 230 #define XFS_MOUNT_NOALIGN (1ULL << 7) /* turn off stripe alignment
+1 -1
fs/xfs/xfs_trans.c
··· 609 609 struct xfs_trans *tp) 610 610 { 611 611 xfs_alloc_busy_sort(&tp->t_busy); 612 - xfs_alloc_busy_clear(tp->t_mountp, &tp->t_busy); 612 + xfs_alloc_busy_clear(tp->t_mountp, &tp->t_busy, false); 613 613 614 614 atomic_dec(&tp->t_mountp->m_active_trans); 615 615 xfs_trans_free_dqinfo(tp);