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

Configure Feed

Select the types of activity you want to include in your feed.

at v3.15 5578 lines 164 kB view raw
1/* 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc. 3 * All Rights Reserved. 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it would be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write the Free Software Foundation, 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18#include "xfs.h" 19#include "xfs_fs.h" 20#include "xfs_shared.h" 21#include "xfs_format.h" 22#include "xfs_log_format.h" 23#include "xfs_trans_resv.h" 24#include "xfs_bit.h" 25#include "xfs_inum.h" 26#include "xfs_sb.h" 27#include "xfs_ag.h" 28#include "xfs_mount.h" 29#include "xfs_da_format.h" 30#include "xfs_da_btree.h" 31#include "xfs_dir2.h" 32#include "xfs_inode.h" 33#include "xfs_btree.h" 34#include "xfs_trans.h" 35#include "xfs_inode_item.h" 36#include "xfs_extfree_item.h" 37#include "xfs_alloc.h" 38#include "xfs_bmap.h" 39#include "xfs_bmap_util.h" 40#include "xfs_bmap_btree.h" 41#include "xfs_rtalloc.h" 42#include "xfs_error.h" 43#include "xfs_quota.h" 44#include "xfs_trans_space.h" 45#include "xfs_buf_item.h" 46#include "xfs_trace.h" 47#include "xfs_symlink.h" 48#include "xfs_attr_leaf.h" 49#include "xfs_dinode.h" 50#include "xfs_filestream.h" 51 52 53kmem_zone_t *xfs_bmap_free_item_zone; 54 55/* 56 * Miscellaneous helper functions 57 */ 58 59/* 60 * Compute and fill in the value of the maximum depth of a bmap btree 61 * in this filesystem. Done once, during mount. 62 */ 63void 64xfs_bmap_compute_maxlevels( 65 xfs_mount_t *mp, /* file system mount structure */ 66 int whichfork) /* data or attr fork */ 67{ 68 int level; /* btree level */ 69 uint maxblocks; /* max blocks at this level */ 70 uint maxleafents; /* max leaf entries possible */ 71 int maxrootrecs; /* max records in root block */ 72 int minleafrecs; /* min records in leaf block */ 73 int minnoderecs; /* min records in node block */ 74 int sz; /* root block size */ 75 76 /* 77 * The maximum number of extents in a file, hence the maximum 78 * number of leaf entries, is controlled by the type of di_nextents 79 * (a signed 32-bit number, xfs_extnum_t), or by di_anextents 80 * (a signed 16-bit number, xfs_aextnum_t). 81 * 82 * Note that we can no longer assume that if we are in ATTR1 that 83 * the fork offset of all the inodes will be 84 * (xfs_default_attroffset(ip) >> 3) because we could have mounted 85 * with ATTR2 and then mounted back with ATTR1, keeping the 86 * di_forkoff's fixed but probably at various positions. Therefore, 87 * for both ATTR1 and ATTR2 we have to assume the worst case scenario 88 * of a minimum size available. 89 */ 90 if (whichfork == XFS_DATA_FORK) { 91 maxleafents = MAXEXTNUM; 92 sz = XFS_BMDR_SPACE_CALC(MINDBTPTRS); 93 } else { 94 maxleafents = MAXAEXTNUM; 95 sz = XFS_BMDR_SPACE_CALC(MINABTPTRS); 96 } 97 maxrootrecs = xfs_bmdr_maxrecs(mp, sz, 0); 98 minleafrecs = mp->m_bmap_dmnr[0]; 99 minnoderecs = mp->m_bmap_dmnr[1]; 100 maxblocks = (maxleafents + minleafrecs - 1) / minleafrecs; 101 for (level = 1; maxblocks > 1; level++) { 102 if (maxblocks <= maxrootrecs) 103 maxblocks = 1; 104 else 105 maxblocks = (maxblocks + minnoderecs - 1) / minnoderecs; 106 } 107 mp->m_bm_maxlevels[whichfork] = level; 108} 109 110STATIC int /* error */ 111xfs_bmbt_lookup_eq( 112 struct xfs_btree_cur *cur, 113 xfs_fileoff_t off, 114 xfs_fsblock_t bno, 115 xfs_filblks_t len, 116 int *stat) /* success/failure */ 117{ 118 cur->bc_rec.b.br_startoff = off; 119 cur->bc_rec.b.br_startblock = bno; 120 cur->bc_rec.b.br_blockcount = len; 121 return xfs_btree_lookup(cur, XFS_LOOKUP_EQ, stat); 122} 123 124STATIC int /* error */ 125xfs_bmbt_lookup_ge( 126 struct xfs_btree_cur *cur, 127 xfs_fileoff_t off, 128 xfs_fsblock_t bno, 129 xfs_filblks_t len, 130 int *stat) /* success/failure */ 131{ 132 cur->bc_rec.b.br_startoff = off; 133 cur->bc_rec.b.br_startblock = bno; 134 cur->bc_rec.b.br_blockcount = len; 135 return xfs_btree_lookup(cur, XFS_LOOKUP_GE, stat); 136} 137 138/* 139 * Check if the inode needs to be converted to btree format. 140 */ 141static inline bool xfs_bmap_needs_btree(struct xfs_inode *ip, int whichfork) 142{ 143 return XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS && 144 XFS_IFORK_NEXTENTS(ip, whichfork) > 145 XFS_IFORK_MAXEXT(ip, whichfork); 146} 147 148/* 149 * Check if the inode should be converted to extent format. 150 */ 151static inline bool xfs_bmap_wants_extents(struct xfs_inode *ip, int whichfork) 152{ 153 return XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE && 154 XFS_IFORK_NEXTENTS(ip, whichfork) <= 155 XFS_IFORK_MAXEXT(ip, whichfork); 156} 157 158/* 159 * Update the record referred to by cur to the value given 160 * by [off, bno, len, state]. 161 * This either works (return 0) or gets an EFSCORRUPTED error. 162 */ 163STATIC int 164xfs_bmbt_update( 165 struct xfs_btree_cur *cur, 166 xfs_fileoff_t off, 167 xfs_fsblock_t bno, 168 xfs_filblks_t len, 169 xfs_exntst_t state) 170{ 171 union xfs_btree_rec rec; 172 173 xfs_bmbt_disk_set_allf(&rec.bmbt, off, bno, len, state); 174 return xfs_btree_update(cur, &rec); 175} 176 177/* 178 * Compute the worst-case number of indirect blocks that will be used 179 * for ip's delayed extent of length "len". 180 */ 181STATIC xfs_filblks_t 182xfs_bmap_worst_indlen( 183 xfs_inode_t *ip, /* incore inode pointer */ 184 xfs_filblks_t len) /* delayed extent length */ 185{ 186 int level; /* btree level number */ 187 int maxrecs; /* maximum record count at this level */ 188 xfs_mount_t *mp; /* mount structure */ 189 xfs_filblks_t rval; /* return value */ 190 191 mp = ip->i_mount; 192 maxrecs = mp->m_bmap_dmxr[0]; 193 for (level = 0, rval = 0; 194 level < XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK); 195 level++) { 196 len += maxrecs - 1; 197 do_div(len, maxrecs); 198 rval += len; 199 if (len == 1) 200 return rval + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 201 level - 1; 202 if (level == 0) 203 maxrecs = mp->m_bmap_dmxr[1]; 204 } 205 return rval; 206} 207 208/* 209 * Calculate the default attribute fork offset for newly created inodes. 210 */ 211uint 212xfs_default_attroffset( 213 struct xfs_inode *ip) 214{ 215 struct xfs_mount *mp = ip->i_mount; 216 uint offset; 217 218 if (mp->m_sb.sb_inodesize == 256) { 219 offset = XFS_LITINO(mp, ip->i_d.di_version) - 220 XFS_BMDR_SPACE_CALC(MINABTPTRS); 221 } else { 222 offset = XFS_BMDR_SPACE_CALC(6 * MINABTPTRS); 223 } 224 225 ASSERT(offset < XFS_LITINO(mp, ip->i_d.di_version)); 226 return offset; 227} 228 229/* 230 * Helper routine to reset inode di_forkoff field when switching 231 * attribute fork from local to extent format - we reset it where 232 * possible to make space available for inline data fork extents. 233 */ 234STATIC void 235xfs_bmap_forkoff_reset( 236 xfs_mount_t *mp, 237 xfs_inode_t *ip, 238 int whichfork) 239{ 240 if (whichfork == XFS_ATTR_FORK && 241 ip->i_d.di_format != XFS_DINODE_FMT_DEV && 242 ip->i_d.di_format != XFS_DINODE_FMT_UUID && 243 ip->i_d.di_format != XFS_DINODE_FMT_BTREE) { 244 uint dfl_forkoff = xfs_default_attroffset(ip) >> 3; 245 246 if (dfl_forkoff > ip->i_d.di_forkoff) 247 ip->i_d.di_forkoff = dfl_forkoff; 248 } 249} 250 251/* 252 * Debug/sanity checking code 253 */ 254 255STATIC int 256xfs_bmap_sanity_check( 257 struct xfs_mount *mp, 258 struct xfs_buf *bp, 259 int level) 260{ 261 struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); 262 263 if (block->bb_magic != cpu_to_be32(XFS_BMAP_CRC_MAGIC) && 264 block->bb_magic != cpu_to_be32(XFS_BMAP_MAGIC)) 265 return 0; 266 267 if (be16_to_cpu(block->bb_level) != level || 268 be16_to_cpu(block->bb_numrecs) == 0 || 269 be16_to_cpu(block->bb_numrecs) > mp->m_bmap_dmxr[level != 0]) 270 return 0; 271 272 return 1; 273} 274 275#ifdef DEBUG 276STATIC struct xfs_buf * 277xfs_bmap_get_bp( 278 struct xfs_btree_cur *cur, 279 xfs_fsblock_t bno) 280{ 281 struct xfs_log_item_desc *lidp; 282 int i; 283 284 if (!cur) 285 return NULL; 286 287 for (i = 0; i < XFS_BTREE_MAXLEVELS; i++) { 288 if (!cur->bc_bufs[i]) 289 break; 290 if (XFS_BUF_ADDR(cur->bc_bufs[i]) == bno) 291 return cur->bc_bufs[i]; 292 } 293 294 /* Chase down all the log items to see if the bp is there */ 295 list_for_each_entry(lidp, &cur->bc_tp->t_items, lid_trans) { 296 struct xfs_buf_log_item *bip; 297 bip = (struct xfs_buf_log_item *)lidp->lid_item; 298 if (bip->bli_item.li_type == XFS_LI_BUF && 299 XFS_BUF_ADDR(bip->bli_buf) == bno) 300 return bip->bli_buf; 301 } 302 303 return NULL; 304} 305 306STATIC void 307xfs_check_block( 308 struct xfs_btree_block *block, 309 xfs_mount_t *mp, 310 int root, 311 short sz) 312{ 313 int i, j, dmxr; 314 __be64 *pp, *thispa; /* pointer to block address */ 315 xfs_bmbt_key_t *prevp, *keyp; 316 317 ASSERT(be16_to_cpu(block->bb_level) > 0); 318 319 prevp = NULL; 320 for( i = 1; i <= xfs_btree_get_numrecs(block); i++) { 321 dmxr = mp->m_bmap_dmxr[0]; 322 keyp = XFS_BMBT_KEY_ADDR(mp, block, i); 323 324 if (prevp) { 325 ASSERT(be64_to_cpu(prevp->br_startoff) < 326 be64_to_cpu(keyp->br_startoff)); 327 } 328 prevp = keyp; 329 330 /* 331 * Compare the block numbers to see if there are dups. 332 */ 333 if (root) 334 pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, i, sz); 335 else 336 pp = XFS_BMBT_PTR_ADDR(mp, block, i, dmxr); 337 338 for (j = i+1; j <= be16_to_cpu(block->bb_numrecs); j++) { 339 if (root) 340 thispa = XFS_BMAP_BROOT_PTR_ADDR(mp, block, j, sz); 341 else 342 thispa = XFS_BMBT_PTR_ADDR(mp, block, j, dmxr); 343 if (*thispa == *pp) { 344 xfs_warn(mp, "%s: thispa(%d) == pp(%d) %Ld", 345 __func__, j, i, 346 (unsigned long long)be64_to_cpu(*thispa)); 347 panic("%s: ptrs are equal in node\n", 348 __func__); 349 } 350 } 351 } 352} 353 354/* 355 * Check that the extents for the inode ip are in the right order in all 356 * btree leaves. 357 */ 358 359STATIC void 360xfs_bmap_check_leaf_extents( 361 xfs_btree_cur_t *cur, /* btree cursor or null */ 362 xfs_inode_t *ip, /* incore inode pointer */ 363 int whichfork) /* data or attr fork */ 364{ 365 struct xfs_btree_block *block; /* current btree block */ 366 xfs_fsblock_t bno; /* block # of "block" */ 367 xfs_buf_t *bp; /* buffer for "block" */ 368 int error; /* error return value */ 369 xfs_extnum_t i=0, j; /* index into the extents list */ 370 xfs_ifork_t *ifp; /* fork structure */ 371 int level; /* btree level, for checking */ 372 xfs_mount_t *mp; /* file system mount structure */ 373 __be64 *pp; /* pointer to block address */ 374 xfs_bmbt_rec_t *ep; /* pointer to current extent */ 375 xfs_bmbt_rec_t last = {0, 0}; /* last extent in prev block */ 376 xfs_bmbt_rec_t *nextp; /* pointer to next extent */ 377 int bp_release = 0; 378 379 if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE) { 380 return; 381 } 382 383 bno = NULLFSBLOCK; 384 mp = ip->i_mount; 385 ifp = XFS_IFORK_PTR(ip, whichfork); 386 block = ifp->if_broot; 387 /* 388 * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out. 389 */ 390 level = be16_to_cpu(block->bb_level); 391 ASSERT(level > 0); 392 xfs_check_block(block, mp, 1, ifp->if_broot_bytes); 393 pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, 1, ifp->if_broot_bytes); 394 bno = be64_to_cpu(*pp); 395 396 ASSERT(bno != NULLDFSBNO); 397 ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount); 398 ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks); 399 400 /* 401 * Go down the tree until leaf level is reached, following the first 402 * pointer (leftmost) at each level. 403 */ 404 while (level-- > 0) { 405 /* See if buf is in cur first */ 406 bp_release = 0; 407 bp = xfs_bmap_get_bp(cur, XFS_FSB_TO_DADDR(mp, bno)); 408 if (!bp) { 409 bp_release = 1; 410 error = xfs_btree_read_bufl(mp, NULL, bno, 0, &bp, 411 XFS_BMAP_BTREE_REF, 412 &xfs_bmbt_buf_ops); 413 if (error) 414 goto error_norelse; 415 } 416 block = XFS_BUF_TO_BLOCK(bp); 417 XFS_WANT_CORRUPTED_GOTO( 418 xfs_bmap_sanity_check(mp, bp, level), 419 error0); 420 if (level == 0) 421 break; 422 423 /* 424 * Check this block for basic sanity (increasing keys and 425 * no duplicate blocks). 426 */ 427 428 xfs_check_block(block, mp, 0, 0); 429 pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]); 430 bno = be64_to_cpu(*pp); 431 XFS_WANT_CORRUPTED_GOTO(XFS_FSB_SANITY_CHECK(mp, bno), error0); 432 if (bp_release) { 433 bp_release = 0; 434 xfs_trans_brelse(NULL, bp); 435 } 436 } 437 438 /* 439 * Here with bp and block set to the leftmost leaf node in the tree. 440 */ 441 i = 0; 442 443 /* 444 * Loop over all leaf nodes checking that all extents are in the right order. 445 */ 446 for (;;) { 447 xfs_fsblock_t nextbno; 448 xfs_extnum_t num_recs; 449 450 451 num_recs = xfs_btree_get_numrecs(block); 452 453 /* 454 * Read-ahead the next leaf block, if any. 455 */ 456 457 nextbno = be64_to_cpu(block->bb_u.l.bb_rightsib); 458 459 /* 460 * Check all the extents to make sure they are OK. 461 * If we had a previous block, the last entry should 462 * conform with the first entry in this one. 463 */ 464 465 ep = XFS_BMBT_REC_ADDR(mp, block, 1); 466 if (i) { 467 ASSERT(xfs_bmbt_disk_get_startoff(&last) + 468 xfs_bmbt_disk_get_blockcount(&last) <= 469 xfs_bmbt_disk_get_startoff(ep)); 470 } 471 for (j = 1; j < num_recs; j++) { 472 nextp = XFS_BMBT_REC_ADDR(mp, block, j + 1); 473 ASSERT(xfs_bmbt_disk_get_startoff(ep) + 474 xfs_bmbt_disk_get_blockcount(ep) <= 475 xfs_bmbt_disk_get_startoff(nextp)); 476 ep = nextp; 477 } 478 479 last = *ep; 480 i += num_recs; 481 if (bp_release) { 482 bp_release = 0; 483 xfs_trans_brelse(NULL, bp); 484 } 485 bno = nextbno; 486 /* 487 * If we've reached the end, stop. 488 */ 489 if (bno == NULLFSBLOCK) 490 break; 491 492 bp_release = 0; 493 bp = xfs_bmap_get_bp(cur, XFS_FSB_TO_DADDR(mp, bno)); 494 if (!bp) { 495 bp_release = 1; 496 error = xfs_btree_read_bufl(mp, NULL, bno, 0, &bp, 497 XFS_BMAP_BTREE_REF, 498 &xfs_bmbt_buf_ops); 499 if (error) 500 goto error_norelse; 501 } 502 block = XFS_BUF_TO_BLOCK(bp); 503 } 504 if (bp_release) { 505 bp_release = 0; 506 xfs_trans_brelse(NULL, bp); 507 } 508 return; 509 510error0: 511 xfs_warn(mp, "%s: at error0", __func__); 512 if (bp_release) 513 xfs_trans_brelse(NULL, bp); 514error_norelse: 515 xfs_warn(mp, "%s: BAD after btree leaves for %d extents", 516 __func__, i); 517 panic("%s: CORRUPTED BTREE OR SOMETHING", __func__); 518 return; 519} 520 521/* 522 * Add bmap trace insert entries for all the contents of the extent records. 523 */ 524void 525xfs_bmap_trace_exlist( 526 xfs_inode_t *ip, /* incore inode pointer */ 527 xfs_extnum_t cnt, /* count of entries in the list */ 528 int whichfork, /* data or attr fork */ 529 unsigned long caller_ip) 530{ 531 xfs_extnum_t idx; /* extent record index */ 532 xfs_ifork_t *ifp; /* inode fork pointer */ 533 int state = 0; 534 535 if (whichfork == XFS_ATTR_FORK) 536 state |= BMAP_ATTRFORK; 537 538 ifp = XFS_IFORK_PTR(ip, whichfork); 539 ASSERT(cnt == (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))); 540 for (idx = 0; idx < cnt; idx++) 541 trace_xfs_extlist(ip, idx, whichfork, caller_ip); 542} 543 544/* 545 * Validate that the bmbt_irecs being returned from bmapi are valid 546 * given the caller's original parameters. Specifically check the 547 * ranges of the returned irecs to ensure that they only extend beyond 548 * the given parameters if the XFS_BMAPI_ENTIRE flag was set. 549 */ 550STATIC void 551xfs_bmap_validate_ret( 552 xfs_fileoff_t bno, 553 xfs_filblks_t len, 554 int flags, 555 xfs_bmbt_irec_t *mval, 556 int nmap, 557 int ret_nmap) 558{ 559 int i; /* index to map values */ 560 561 ASSERT(ret_nmap <= nmap); 562 563 for (i = 0; i < ret_nmap; i++) { 564 ASSERT(mval[i].br_blockcount > 0); 565 if (!(flags & XFS_BMAPI_ENTIRE)) { 566 ASSERT(mval[i].br_startoff >= bno); 567 ASSERT(mval[i].br_blockcount <= len); 568 ASSERT(mval[i].br_startoff + mval[i].br_blockcount <= 569 bno + len); 570 } else { 571 ASSERT(mval[i].br_startoff < bno + len); 572 ASSERT(mval[i].br_startoff + mval[i].br_blockcount > 573 bno); 574 } 575 ASSERT(i == 0 || 576 mval[i - 1].br_startoff + mval[i - 1].br_blockcount == 577 mval[i].br_startoff); 578 ASSERT(mval[i].br_startblock != DELAYSTARTBLOCK && 579 mval[i].br_startblock != HOLESTARTBLOCK); 580 ASSERT(mval[i].br_state == XFS_EXT_NORM || 581 mval[i].br_state == XFS_EXT_UNWRITTEN); 582 } 583} 584 585#else 586#define xfs_bmap_check_leaf_extents(cur, ip, whichfork) do { } while (0) 587#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) 588#endif /* DEBUG */ 589 590/* 591 * bmap free list manipulation functions 592 */ 593 594/* 595 * Add the extent to the list of extents to be free at transaction end. 596 * The list is maintained sorted (by block number). 597 */ 598void 599xfs_bmap_add_free( 600 xfs_fsblock_t bno, /* fs block number of extent */ 601 xfs_filblks_t len, /* length of extent */ 602 xfs_bmap_free_t *flist, /* list of extents */ 603 xfs_mount_t *mp) /* mount point structure */ 604{ 605 xfs_bmap_free_item_t *cur; /* current (next) element */ 606 xfs_bmap_free_item_t *new; /* new element */ 607 xfs_bmap_free_item_t *prev; /* previous element */ 608#ifdef DEBUG 609 xfs_agnumber_t agno; 610 xfs_agblock_t agbno; 611 612 ASSERT(bno != NULLFSBLOCK); 613 ASSERT(len > 0); 614 ASSERT(len <= MAXEXTLEN); 615 ASSERT(!isnullstartblock(bno)); 616 agno = XFS_FSB_TO_AGNO(mp, bno); 617 agbno = XFS_FSB_TO_AGBNO(mp, bno); 618 ASSERT(agno < mp->m_sb.sb_agcount); 619 ASSERT(agbno < mp->m_sb.sb_agblocks); 620 ASSERT(len < mp->m_sb.sb_agblocks); 621 ASSERT(agbno + len <= mp->m_sb.sb_agblocks); 622#endif 623 ASSERT(xfs_bmap_free_item_zone != NULL); 624 new = kmem_zone_alloc(xfs_bmap_free_item_zone, KM_SLEEP); 625 new->xbfi_startblock = bno; 626 new->xbfi_blockcount = (xfs_extlen_t)len; 627 for (prev = NULL, cur = flist->xbf_first; 628 cur != NULL; 629 prev = cur, cur = cur->xbfi_next) { 630 if (cur->xbfi_startblock >= bno) 631 break; 632 } 633 if (prev) 634 prev->xbfi_next = new; 635 else 636 flist->xbf_first = new; 637 new->xbfi_next = cur; 638 flist->xbf_count++; 639} 640 641/* 642 * Remove the entry "free" from the free item list. Prev points to the 643 * previous entry, unless "free" is the head of the list. 644 */ 645void 646xfs_bmap_del_free( 647 xfs_bmap_free_t *flist, /* free item list header */ 648 xfs_bmap_free_item_t *prev, /* previous item on list, if any */ 649 xfs_bmap_free_item_t *free) /* list item to be freed */ 650{ 651 if (prev) 652 prev->xbfi_next = free->xbfi_next; 653 else 654 flist->xbf_first = free->xbfi_next; 655 flist->xbf_count--; 656 kmem_zone_free(xfs_bmap_free_item_zone, free); 657} 658 659/* 660 * Free up any items left in the list. 661 */ 662void 663xfs_bmap_cancel( 664 xfs_bmap_free_t *flist) /* list of bmap_free_items */ 665{ 666 xfs_bmap_free_item_t *free; /* free list item */ 667 xfs_bmap_free_item_t *next; 668 669 if (flist->xbf_count == 0) 670 return; 671 ASSERT(flist->xbf_first != NULL); 672 for (free = flist->xbf_first; free; free = next) { 673 next = free->xbfi_next; 674 xfs_bmap_del_free(flist, NULL, free); 675 } 676 ASSERT(flist->xbf_count == 0); 677} 678 679/* 680 * Inode fork format manipulation functions 681 */ 682 683/* 684 * Transform a btree format file with only one leaf node, where the 685 * extents list will fit in the inode, into an extents format file. 686 * Since the file extents are already in-core, all we have to do is 687 * give up the space for the btree root and pitch the leaf block. 688 */ 689STATIC int /* error */ 690xfs_bmap_btree_to_extents( 691 xfs_trans_t *tp, /* transaction pointer */ 692 xfs_inode_t *ip, /* incore inode pointer */ 693 xfs_btree_cur_t *cur, /* btree cursor */ 694 int *logflagsp, /* inode logging flags */ 695 int whichfork) /* data or attr fork */ 696{ 697 /* REFERENCED */ 698 struct xfs_btree_block *cblock;/* child btree block */ 699 xfs_fsblock_t cbno; /* child block number */ 700 xfs_buf_t *cbp; /* child block's buffer */ 701 int error; /* error return value */ 702 xfs_ifork_t *ifp; /* inode fork data */ 703 xfs_mount_t *mp; /* mount point structure */ 704 __be64 *pp; /* ptr to block address */ 705 struct xfs_btree_block *rblock;/* root btree block */ 706 707 mp = ip->i_mount; 708 ifp = XFS_IFORK_PTR(ip, whichfork); 709 ASSERT(ifp->if_flags & XFS_IFEXTENTS); 710 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE); 711 rblock = ifp->if_broot; 712 ASSERT(be16_to_cpu(rblock->bb_level) == 1); 713 ASSERT(be16_to_cpu(rblock->bb_numrecs) == 1); 714 ASSERT(xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0) == 1); 715 pp = XFS_BMAP_BROOT_PTR_ADDR(mp, rblock, 1, ifp->if_broot_bytes); 716 cbno = be64_to_cpu(*pp); 717 *logflagsp = 0; 718#ifdef DEBUG 719 if ((error = xfs_btree_check_lptr(cur, cbno, 1))) 720 return error; 721#endif 722 error = xfs_btree_read_bufl(mp, tp, cbno, 0, &cbp, XFS_BMAP_BTREE_REF, 723 &xfs_bmbt_buf_ops); 724 if (error) 725 return error; 726 cblock = XFS_BUF_TO_BLOCK(cbp); 727 if ((error = xfs_btree_check_block(cur, cblock, 0, cbp))) 728 return error; 729 xfs_bmap_add_free(cbno, 1, cur->bc_private.b.flist, mp); 730 ip->i_d.di_nblocks--; 731 xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L); 732 xfs_trans_binval(tp, cbp); 733 if (cur->bc_bufs[0] == cbp) 734 cur->bc_bufs[0] = NULL; 735 xfs_iroot_realloc(ip, -1, whichfork); 736 ASSERT(ifp->if_broot == NULL); 737 ASSERT((ifp->if_flags & XFS_IFBROOT) == 0); 738 XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS); 739 *logflagsp = XFS_ILOG_CORE | xfs_ilog_fext(whichfork); 740 return 0; 741} 742 743/* 744 * Convert an extents-format file into a btree-format file. 745 * The new file will have a root block (in the inode) and a single child block. 746 */ 747STATIC int /* error */ 748xfs_bmap_extents_to_btree( 749 xfs_trans_t *tp, /* transaction pointer */ 750 xfs_inode_t *ip, /* incore inode pointer */ 751 xfs_fsblock_t *firstblock, /* first-block-allocated */ 752 xfs_bmap_free_t *flist, /* blocks freed in xaction */ 753 xfs_btree_cur_t **curp, /* cursor returned to caller */ 754 int wasdel, /* converting a delayed alloc */ 755 int *logflagsp, /* inode logging flags */ 756 int whichfork) /* data or attr fork */ 757{ 758 struct xfs_btree_block *ablock; /* allocated (child) bt block */ 759 xfs_buf_t *abp; /* buffer for ablock */ 760 xfs_alloc_arg_t args; /* allocation arguments */ 761 xfs_bmbt_rec_t *arp; /* child record pointer */ 762 struct xfs_btree_block *block; /* btree root block */ 763 xfs_btree_cur_t *cur; /* bmap btree cursor */ 764 xfs_bmbt_rec_host_t *ep; /* extent record pointer */ 765 int error; /* error return value */ 766 xfs_extnum_t i, cnt; /* extent record index */ 767 xfs_ifork_t *ifp; /* inode fork pointer */ 768 xfs_bmbt_key_t *kp; /* root block key pointer */ 769 xfs_mount_t *mp; /* mount structure */ 770 xfs_extnum_t nextents; /* number of file extents */ 771 xfs_bmbt_ptr_t *pp; /* root block address pointer */ 772 773 mp = ip->i_mount; 774 ifp = XFS_IFORK_PTR(ip, whichfork); 775 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS); 776 777 /* 778 * Make space in the inode incore. 779 */ 780 xfs_iroot_realloc(ip, 1, whichfork); 781 ifp->if_flags |= XFS_IFBROOT; 782 783 /* 784 * Fill in the root. 785 */ 786 block = ifp->if_broot; 787 if (xfs_sb_version_hascrc(&mp->m_sb)) 788 xfs_btree_init_block_int(mp, block, XFS_BUF_DADDR_NULL, 789 XFS_BMAP_CRC_MAGIC, 1, 1, ip->i_ino, 790 XFS_BTREE_LONG_PTRS | XFS_BTREE_CRC_BLOCKS); 791 else 792 xfs_btree_init_block_int(mp, block, XFS_BUF_DADDR_NULL, 793 XFS_BMAP_MAGIC, 1, 1, ip->i_ino, 794 XFS_BTREE_LONG_PTRS); 795 796 /* 797 * Need a cursor. Can't allocate until bb_level is filled in. 798 */ 799 cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); 800 cur->bc_private.b.firstblock = *firstblock; 801 cur->bc_private.b.flist = flist; 802 cur->bc_private.b.flags = wasdel ? XFS_BTCUR_BPRV_WASDEL : 0; 803 /* 804 * Convert to a btree with two levels, one record in root. 805 */ 806 XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_BTREE); 807 memset(&args, 0, sizeof(args)); 808 args.tp = tp; 809 args.mp = mp; 810 args.firstblock = *firstblock; 811 if (*firstblock == NULLFSBLOCK) { 812 args.type = XFS_ALLOCTYPE_START_BNO; 813 args.fsbno = XFS_INO_TO_FSB(mp, ip->i_ino); 814 } else if (flist->xbf_low) { 815 args.type = XFS_ALLOCTYPE_START_BNO; 816 args.fsbno = *firstblock; 817 } else { 818 args.type = XFS_ALLOCTYPE_NEAR_BNO; 819 args.fsbno = *firstblock; 820 } 821 args.minlen = args.maxlen = args.prod = 1; 822 args.wasdel = wasdel; 823 *logflagsp = 0; 824 if ((error = xfs_alloc_vextent(&args))) { 825 xfs_iroot_realloc(ip, -1, whichfork); 826 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); 827 return error; 828 } 829 /* 830 * Allocation can't fail, the space was reserved. 831 */ 832 ASSERT(args.fsbno != NULLFSBLOCK); 833 ASSERT(*firstblock == NULLFSBLOCK || 834 args.agno == XFS_FSB_TO_AGNO(mp, *firstblock) || 835 (flist->xbf_low && 836 args.agno > XFS_FSB_TO_AGNO(mp, *firstblock))); 837 *firstblock = cur->bc_private.b.firstblock = args.fsbno; 838 cur->bc_private.b.allocated++; 839 ip->i_d.di_nblocks++; 840 xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, 1L); 841 abp = xfs_btree_get_bufl(mp, tp, args.fsbno, 0); 842 /* 843 * Fill in the child block. 844 */ 845 abp->b_ops = &xfs_bmbt_buf_ops; 846 ablock = XFS_BUF_TO_BLOCK(abp); 847 if (xfs_sb_version_hascrc(&mp->m_sb)) 848 xfs_btree_init_block_int(mp, ablock, abp->b_bn, 849 XFS_BMAP_CRC_MAGIC, 0, 0, ip->i_ino, 850 XFS_BTREE_LONG_PTRS | XFS_BTREE_CRC_BLOCKS); 851 else 852 xfs_btree_init_block_int(mp, ablock, abp->b_bn, 853 XFS_BMAP_MAGIC, 0, 0, ip->i_ino, 854 XFS_BTREE_LONG_PTRS); 855 856 arp = XFS_BMBT_REC_ADDR(mp, ablock, 1); 857 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 858 for (cnt = i = 0; i < nextents; i++) { 859 ep = xfs_iext_get_ext(ifp, i); 860 if (!isnullstartblock(xfs_bmbt_get_startblock(ep))) { 861 arp->l0 = cpu_to_be64(ep->l0); 862 arp->l1 = cpu_to_be64(ep->l1); 863 arp++; cnt++; 864 } 865 } 866 ASSERT(cnt == XFS_IFORK_NEXTENTS(ip, whichfork)); 867 xfs_btree_set_numrecs(ablock, cnt); 868 869 /* 870 * Fill in the root key and pointer. 871 */ 872 kp = XFS_BMBT_KEY_ADDR(mp, block, 1); 873 arp = XFS_BMBT_REC_ADDR(mp, ablock, 1); 874 kp->br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(arp)); 875 pp = XFS_BMBT_PTR_ADDR(mp, block, 1, xfs_bmbt_get_maxrecs(cur, 876 be16_to_cpu(block->bb_level))); 877 *pp = cpu_to_be64(args.fsbno); 878 879 /* 880 * Do all this logging at the end so that 881 * the root is at the right level. 882 */ 883 xfs_btree_log_block(cur, abp, XFS_BB_ALL_BITS); 884 xfs_btree_log_recs(cur, abp, 1, be16_to_cpu(ablock->bb_numrecs)); 885 ASSERT(*curp == NULL); 886 *curp = cur; 887 *logflagsp = XFS_ILOG_CORE | xfs_ilog_fbroot(whichfork); 888 return 0; 889} 890 891/* 892 * Convert a local file to an extents file. 893 * This code is out of bounds for data forks of regular files, 894 * since the file data needs to get logged so things will stay consistent. 895 * (The bmap-level manipulations are ok, though). 896 */ 897void 898xfs_bmap_local_to_extents_empty( 899 struct xfs_inode *ip, 900 int whichfork) 901{ 902 struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); 903 904 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL); 905 ASSERT(ifp->if_bytes == 0); 906 ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) == 0); 907 908 xfs_bmap_forkoff_reset(ip->i_mount, ip, whichfork); 909 ifp->if_flags &= ~XFS_IFINLINE; 910 ifp->if_flags |= XFS_IFEXTENTS; 911 XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS); 912} 913 914 915STATIC int /* error */ 916xfs_bmap_local_to_extents( 917 xfs_trans_t *tp, /* transaction pointer */ 918 xfs_inode_t *ip, /* incore inode pointer */ 919 xfs_fsblock_t *firstblock, /* first block allocated in xaction */ 920 xfs_extlen_t total, /* total blocks needed by transaction */ 921 int *logflagsp, /* inode logging flags */ 922 int whichfork, 923 void (*init_fn)(struct xfs_trans *tp, 924 struct xfs_buf *bp, 925 struct xfs_inode *ip, 926 struct xfs_ifork *ifp)) 927{ 928 int error = 0; 929 int flags; /* logging flags returned */ 930 xfs_ifork_t *ifp; /* inode fork pointer */ 931 xfs_alloc_arg_t args; /* allocation arguments */ 932 xfs_buf_t *bp; /* buffer for extent block */ 933 xfs_bmbt_rec_host_t *ep; /* extent record pointer */ 934 935 /* 936 * We don't want to deal with the case of keeping inode data inline yet. 937 * So sending the data fork of a regular inode is invalid. 938 */ 939 ASSERT(!(S_ISREG(ip->i_d.di_mode) && whichfork == XFS_DATA_FORK)); 940 ifp = XFS_IFORK_PTR(ip, whichfork); 941 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL); 942 943 if (!ifp->if_bytes) { 944 xfs_bmap_local_to_extents_empty(ip, whichfork); 945 flags = XFS_ILOG_CORE; 946 goto done; 947 } 948 949 flags = 0; 950 error = 0; 951 ASSERT((ifp->if_flags & (XFS_IFINLINE|XFS_IFEXTENTS|XFS_IFEXTIREC)) == 952 XFS_IFINLINE); 953 memset(&args, 0, sizeof(args)); 954 args.tp = tp; 955 args.mp = ip->i_mount; 956 args.firstblock = *firstblock; 957 /* 958 * Allocate a block. We know we need only one, since the 959 * file currently fits in an inode. 960 */ 961 if (*firstblock == NULLFSBLOCK) { 962 args.fsbno = XFS_INO_TO_FSB(args.mp, ip->i_ino); 963 args.type = XFS_ALLOCTYPE_START_BNO; 964 } else { 965 args.fsbno = *firstblock; 966 args.type = XFS_ALLOCTYPE_NEAR_BNO; 967 } 968 args.total = total; 969 args.minlen = args.maxlen = args.prod = 1; 970 error = xfs_alloc_vextent(&args); 971 if (error) 972 goto done; 973 974 /* Can't fail, the space was reserved. */ 975 ASSERT(args.fsbno != NULLFSBLOCK); 976 ASSERT(args.len == 1); 977 *firstblock = args.fsbno; 978 bp = xfs_btree_get_bufl(args.mp, tp, args.fsbno, 0); 979 980 /* initialise the block and copy the data */ 981 init_fn(tp, bp, ip, ifp); 982 983 /* account for the change in fork size and log everything */ 984 xfs_trans_log_buf(tp, bp, 0, ifp->if_bytes - 1); 985 xfs_idata_realloc(ip, -ifp->if_bytes, whichfork); 986 xfs_bmap_local_to_extents_empty(ip, whichfork); 987 flags |= XFS_ILOG_CORE; 988 989 xfs_iext_add(ifp, 0, 1); 990 ep = xfs_iext_get_ext(ifp, 0); 991 xfs_bmbt_set_allf(ep, 0, args.fsbno, 1, XFS_EXT_NORM); 992 trace_xfs_bmap_post_update(ip, 0, 993 whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0, 994 _THIS_IP_); 995 XFS_IFORK_NEXT_SET(ip, whichfork, 1); 996 ip->i_d.di_nblocks = 1; 997 xfs_trans_mod_dquot_byino(tp, ip, 998 XFS_TRANS_DQ_BCOUNT, 1L); 999 flags |= xfs_ilog_fext(whichfork); 1000 1001done: 1002 *logflagsp = flags; 1003 return error; 1004} 1005 1006/* 1007 * Called from xfs_bmap_add_attrfork to handle btree format files. 1008 */ 1009STATIC int /* error */ 1010xfs_bmap_add_attrfork_btree( 1011 xfs_trans_t *tp, /* transaction pointer */ 1012 xfs_inode_t *ip, /* incore inode pointer */ 1013 xfs_fsblock_t *firstblock, /* first block allocated */ 1014 xfs_bmap_free_t *flist, /* blocks to free at commit */ 1015 int *flags) /* inode logging flags */ 1016{ 1017 xfs_btree_cur_t *cur; /* btree cursor */ 1018 int error; /* error return value */ 1019 xfs_mount_t *mp; /* file system mount struct */ 1020 int stat; /* newroot status */ 1021 1022 mp = ip->i_mount; 1023 if (ip->i_df.if_broot_bytes <= XFS_IFORK_DSIZE(ip)) 1024 *flags |= XFS_ILOG_DBROOT; 1025 else { 1026 cur = xfs_bmbt_init_cursor(mp, tp, ip, XFS_DATA_FORK); 1027 cur->bc_private.b.flist = flist; 1028 cur->bc_private.b.firstblock = *firstblock; 1029 if ((error = xfs_bmbt_lookup_ge(cur, 0, 0, 0, &stat))) 1030 goto error0; 1031 /* must be at least one entry */ 1032 XFS_WANT_CORRUPTED_GOTO(stat == 1, error0); 1033 if ((error = xfs_btree_new_iroot(cur, flags, &stat))) 1034 goto error0; 1035 if (stat == 0) { 1036 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); 1037 return XFS_ERROR(ENOSPC); 1038 } 1039 *firstblock = cur->bc_private.b.firstblock; 1040 cur->bc_private.b.allocated = 0; 1041 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); 1042 } 1043 return 0; 1044error0: 1045 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); 1046 return error; 1047} 1048 1049/* 1050 * Called from xfs_bmap_add_attrfork to handle extents format files. 1051 */ 1052STATIC int /* error */ 1053xfs_bmap_add_attrfork_extents( 1054 xfs_trans_t *tp, /* transaction pointer */ 1055 xfs_inode_t *ip, /* incore inode pointer */ 1056 xfs_fsblock_t *firstblock, /* first block allocated */ 1057 xfs_bmap_free_t *flist, /* blocks to free at commit */ 1058 int *flags) /* inode logging flags */ 1059{ 1060 xfs_btree_cur_t *cur; /* bmap btree cursor */ 1061 int error; /* error return value */ 1062 1063 if (ip->i_d.di_nextents * sizeof(xfs_bmbt_rec_t) <= XFS_IFORK_DSIZE(ip)) 1064 return 0; 1065 cur = NULL; 1066 error = xfs_bmap_extents_to_btree(tp, ip, firstblock, flist, &cur, 0, 1067 flags, XFS_DATA_FORK); 1068 if (cur) { 1069 cur->bc_private.b.allocated = 0; 1070 xfs_btree_del_cursor(cur, 1071 error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); 1072 } 1073 return error; 1074} 1075 1076/* 1077 * Called from xfs_bmap_add_attrfork to handle local format files. Each 1078 * different data fork content type needs a different callout to do the 1079 * conversion. Some are basic and only require special block initialisation 1080 * callouts for the data formating, others (directories) are so specialised they 1081 * handle everything themselves. 1082 * 1083 * XXX (dgc): investigate whether directory conversion can use the generic 1084 * formatting callout. It should be possible - it's just a very complex 1085 * formatter. 1086 */ 1087STATIC int /* error */ 1088xfs_bmap_add_attrfork_local( 1089 xfs_trans_t *tp, /* transaction pointer */ 1090 xfs_inode_t *ip, /* incore inode pointer */ 1091 xfs_fsblock_t *firstblock, /* first block allocated */ 1092 xfs_bmap_free_t *flist, /* blocks to free at commit */ 1093 int *flags) /* inode logging flags */ 1094{ 1095 xfs_da_args_t dargs; /* args for dir/attr code */ 1096 1097 if (ip->i_df.if_bytes <= XFS_IFORK_DSIZE(ip)) 1098 return 0; 1099 1100 if (S_ISDIR(ip->i_d.di_mode)) { 1101 memset(&dargs, 0, sizeof(dargs)); 1102 dargs.dp = ip; 1103 dargs.firstblock = firstblock; 1104 dargs.flist = flist; 1105 dargs.total = ip->i_mount->m_dirblkfsbs; 1106 dargs.whichfork = XFS_DATA_FORK; 1107 dargs.trans = tp; 1108 return xfs_dir2_sf_to_block(&dargs); 1109 } 1110 1111 if (S_ISLNK(ip->i_d.di_mode)) 1112 return xfs_bmap_local_to_extents(tp, ip, firstblock, 1, 1113 flags, XFS_DATA_FORK, 1114 xfs_symlink_local_to_remote); 1115 1116 /* should only be called for types that support local format data */ 1117 ASSERT(0); 1118 return EFSCORRUPTED; 1119} 1120 1121/* 1122 * Convert inode from non-attributed to attributed. 1123 * Must not be in a transaction, ip must not be locked. 1124 */ 1125int /* error code */ 1126xfs_bmap_add_attrfork( 1127 xfs_inode_t *ip, /* incore inode pointer */ 1128 int size, /* space new attribute needs */ 1129 int rsvd) /* xact may use reserved blks */ 1130{ 1131 xfs_fsblock_t firstblock; /* 1st block/ag allocated */ 1132 xfs_bmap_free_t flist; /* freed extent records */ 1133 xfs_mount_t *mp; /* mount structure */ 1134 xfs_trans_t *tp; /* transaction pointer */ 1135 int blks; /* space reservation */ 1136 int version = 1; /* superblock attr version */ 1137 int committed; /* xaction was committed */ 1138 int logflags; /* logging flags */ 1139 int error; /* error return value */ 1140 int cancel_flags = 0; 1141 1142 ASSERT(XFS_IFORK_Q(ip) == 0); 1143 1144 mp = ip->i_mount; 1145 ASSERT(!XFS_NOT_DQATTACHED(mp, ip)); 1146 tp = xfs_trans_alloc(mp, XFS_TRANS_ADDAFORK); 1147 blks = XFS_ADDAFORK_SPACE_RES(mp); 1148 if (rsvd) 1149 tp->t_flags |= XFS_TRANS_RESERVE; 1150 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_addafork, blks, 0); 1151 if (error) { 1152 xfs_trans_cancel(tp, 0); 1153 return error; 1154 } 1155 cancel_flags = XFS_TRANS_RELEASE_LOG_RES; 1156 xfs_ilock(ip, XFS_ILOCK_EXCL); 1157 error = xfs_trans_reserve_quota_nblks(tp, ip, blks, 0, rsvd ? 1158 XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES : 1159 XFS_QMOPT_RES_REGBLKS); 1160 if (error) 1161 goto trans_cancel; 1162 cancel_flags |= XFS_TRANS_ABORT; 1163 if (XFS_IFORK_Q(ip)) 1164 goto trans_cancel; 1165 if (ip->i_d.di_aformat != XFS_DINODE_FMT_EXTENTS) { 1166 /* 1167 * For inodes coming from pre-6.2 filesystems. 1168 */ 1169 ASSERT(ip->i_d.di_aformat == 0); 1170 ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; 1171 } 1172 ASSERT(ip->i_d.di_anextents == 0); 1173 1174 xfs_trans_ijoin(tp, ip, 0); 1175 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 1176 1177 switch (ip->i_d.di_format) { 1178 case XFS_DINODE_FMT_DEV: 1179 ip->i_d.di_forkoff = roundup(sizeof(xfs_dev_t), 8) >> 3; 1180 break; 1181 case XFS_DINODE_FMT_UUID: 1182 ip->i_d.di_forkoff = roundup(sizeof(uuid_t), 8) >> 3; 1183 break; 1184 case XFS_DINODE_FMT_LOCAL: 1185 case XFS_DINODE_FMT_EXTENTS: 1186 case XFS_DINODE_FMT_BTREE: 1187 ip->i_d.di_forkoff = xfs_attr_shortform_bytesfit(ip, size); 1188 if (!ip->i_d.di_forkoff) 1189 ip->i_d.di_forkoff = xfs_default_attroffset(ip) >> 3; 1190 else if (mp->m_flags & XFS_MOUNT_ATTR2) 1191 version = 2; 1192 break; 1193 default: 1194 ASSERT(0); 1195 error = XFS_ERROR(EINVAL); 1196 goto trans_cancel; 1197 } 1198 1199 ASSERT(ip->i_afp == NULL); 1200 ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP); 1201 ip->i_afp->if_flags = XFS_IFEXTENTS; 1202 logflags = 0; 1203 xfs_bmap_init(&flist, &firstblock); 1204 switch (ip->i_d.di_format) { 1205 case XFS_DINODE_FMT_LOCAL: 1206 error = xfs_bmap_add_attrfork_local(tp, ip, &firstblock, &flist, 1207 &logflags); 1208 break; 1209 case XFS_DINODE_FMT_EXTENTS: 1210 error = xfs_bmap_add_attrfork_extents(tp, ip, &firstblock, 1211 &flist, &logflags); 1212 break; 1213 case XFS_DINODE_FMT_BTREE: 1214 error = xfs_bmap_add_attrfork_btree(tp, ip, &firstblock, &flist, 1215 &logflags); 1216 break; 1217 default: 1218 error = 0; 1219 break; 1220 } 1221 if (logflags) 1222 xfs_trans_log_inode(tp, ip, logflags); 1223 if (error) 1224 goto bmap_cancel; 1225 if (!xfs_sb_version_hasattr(&mp->m_sb) || 1226 (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2)) { 1227 __int64_t sbfields = 0; 1228 1229 spin_lock(&mp->m_sb_lock); 1230 if (!xfs_sb_version_hasattr(&mp->m_sb)) { 1231 xfs_sb_version_addattr(&mp->m_sb); 1232 sbfields |= XFS_SB_VERSIONNUM; 1233 } 1234 if (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2) { 1235 xfs_sb_version_addattr2(&mp->m_sb); 1236 sbfields |= (XFS_SB_VERSIONNUM | XFS_SB_FEATURES2); 1237 } 1238 if (sbfields) { 1239 spin_unlock(&mp->m_sb_lock); 1240 xfs_mod_sb(tp, sbfields); 1241 } else 1242 spin_unlock(&mp->m_sb_lock); 1243 } 1244 1245 error = xfs_bmap_finish(&tp, &flist, &committed); 1246 if (error) 1247 goto bmap_cancel; 1248 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); 1249 xfs_iunlock(ip, XFS_ILOCK_EXCL); 1250 return error; 1251 1252bmap_cancel: 1253 xfs_bmap_cancel(&flist); 1254trans_cancel: 1255 xfs_trans_cancel(tp, cancel_flags); 1256 xfs_iunlock(ip, XFS_ILOCK_EXCL); 1257 return error; 1258} 1259 1260/* 1261 * Internal and external extent tree search functions. 1262 */ 1263 1264/* 1265 * Read in the extents to if_extents. 1266 * All inode fields are set up by caller, we just traverse the btree 1267 * and copy the records in. If the file system cannot contain unwritten 1268 * extents, the records are checked for no "state" flags. 1269 */ 1270int /* error */ 1271xfs_bmap_read_extents( 1272 xfs_trans_t *tp, /* transaction pointer */ 1273 xfs_inode_t *ip, /* incore inode */ 1274 int whichfork) /* data or attr fork */ 1275{ 1276 struct xfs_btree_block *block; /* current btree block */ 1277 xfs_fsblock_t bno; /* block # of "block" */ 1278 xfs_buf_t *bp; /* buffer for "block" */ 1279 int error; /* error return value */ 1280 xfs_exntfmt_t exntf; /* XFS_EXTFMT_NOSTATE, if checking */ 1281 xfs_extnum_t i, j; /* index into the extents list */ 1282 xfs_ifork_t *ifp; /* fork structure */ 1283 int level; /* btree level, for checking */ 1284 xfs_mount_t *mp; /* file system mount structure */ 1285 __be64 *pp; /* pointer to block address */ 1286 /* REFERENCED */ 1287 xfs_extnum_t room; /* number of entries there's room for */ 1288 1289 bno = NULLFSBLOCK; 1290 mp = ip->i_mount; 1291 ifp = XFS_IFORK_PTR(ip, whichfork); 1292 exntf = (whichfork != XFS_DATA_FORK) ? XFS_EXTFMT_NOSTATE : 1293 XFS_EXTFMT_INODE(ip); 1294 block = ifp->if_broot; 1295 /* 1296 * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out. 1297 */ 1298 level = be16_to_cpu(block->bb_level); 1299 ASSERT(level > 0); 1300 pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, 1, ifp->if_broot_bytes); 1301 bno = be64_to_cpu(*pp); 1302 ASSERT(bno != NULLDFSBNO); 1303 ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount); 1304 ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks); 1305 /* 1306 * Go down the tree until leaf level is reached, following the first 1307 * pointer (leftmost) at each level. 1308 */ 1309 while (level-- > 0) { 1310 error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp, 1311 XFS_BMAP_BTREE_REF, &xfs_bmbt_buf_ops); 1312 if (error) 1313 return error; 1314 block = XFS_BUF_TO_BLOCK(bp); 1315 XFS_WANT_CORRUPTED_GOTO( 1316 xfs_bmap_sanity_check(mp, bp, level), 1317 error0); 1318 if (level == 0) 1319 break; 1320 pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]); 1321 bno = be64_to_cpu(*pp); 1322 XFS_WANT_CORRUPTED_GOTO(XFS_FSB_SANITY_CHECK(mp, bno), error0); 1323 xfs_trans_brelse(tp, bp); 1324 } 1325 /* 1326 * Here with bp and block set to the leftmost leaf node in the tree. 1327 */ 1328 room = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 1329 i = 0; 1330 /* 1331 * Loop over all leaf nodes. Copy information to the extent records. 1332 */ 1333 for (;;) { 1334 xfs_bmbt_rec_t *frp; 1335 xfs_fsblock_t nextbno; 1336 xfs_extnum_t num_recs; 1337 xfs_extnum_t start; 1338 1339 num_recs = xfs_btree_get_numrecs(block); 1340 if (unlikely(i + num_recs > room)) { 1341 ASSERT(i + num_recs <= room); 1342 xfs_warn(ip->i_mount, 1343 "corrupt dinode %Lu, (btree extents).", 1344 (unsigned long long) ip->i_ino); 1345 XFS_CORRUPTION_ERROR("xfs_bmap_read_extents(1)", 1346 XFS_ERRLEVEL_LOW, ip->i_mount, block); 1347 goto error0; 1348 } 1349 XFS_WANT_CORRUPTED_GOTO( 1350 xfs_bmap_sanity_check(mp, bp, 0), 1351 error0); 1352 /* 1353 * Read-ahead the next leaf block, if any. 1354 */ 1355 nextbno = be64_to_cpu(block->bb_u.l.bb_rightsib); 1356 if (nextbno != NULLFSBLOCK) 1357 xfs_btree_reada_bufl(mp, nextbno, 1, 1358 &xfs_bmbt_buf_ops); 1359 /* 1360 * Copy records into the extent records. 1361 */ 1362 frp = XFS_BMBT_REC_ADDR(mp, block, 1); 1363 start = i; 1364 for (j = 0; j < num_recs; j++, i++, frp++) { 1365 xfs_bmbt_rec_host_t *trp = xfs_iext_get_ext(ifp, i); 1366 trp->l0 = be64_to_cpu(frp->l0); 1367 trp->l1 = be64_to_cpu(frp->l1); 1368 } 1369 if (exntf == XFS_EXTFMT_NOSTATE) { 1370 /* 1371 * Check all attribute bmap btree records and 1372 * any "older" data bmap btree records for a 1373 * set bit in the "extent flag" position. 1374 */ 1375 if (unlikely(xfs_check_nostate_extents(ifp, 1376 start, num_recs))) { 1377 XFS_ERROR_REPORT("xfs_bmap_read_extents(2)", 1378 XFS_ERRLEVEL_LOW, 1379 ip->i_mount); 1380 goto error0; 1381 } 1382 } 1383 xfs_trans_brelse(tp, bp); 1384 bno = nextbno; 1385 /* 1386 * If we've reached the end, stop. 1387 */ 1388 if (bno == NULLFSBLOCK) 1389 break; 1390 error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp, 1391 XFS_BMAP_BTREE_REF, &xfs_bmbt_buf_ops); 1392 if (error) 1393 return error; 1394 block = XFS_BUF_TO_BLOCK(bp); 1395 } 1396 ASSERT(i == (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))); 1397 ASSERT(i == XFS_IFORK_NEXTENTS(ip, whichfork)); 1398 XFS_BMAP_TRACE_EXLIST(ip, i, whichfork); 1399 return 0; 1400error0: 1401 xfs_trans_brelse(tp, bp); 1402 return XFS_ERROR(EFSCORRUPTED); 1403} 1404 1405 1406/* 1407 * Search the extent records for the entry containing block bno. 1408 * If bno lies in a hole, point to the next entry. If bno lies 1409 * past eof, *eofp will be set, and *prevp will contain the last 1410 * entry (null if none). Else, *lastxp will be set to the index 1411 * of the found entry; *gotp will contain the entry. 1412 */ 1413STATIC xfs_bmbt_rec_host_t * /* pointer to found extent entry */ 1414xfs_bmap_search_multi_extents( 1415 xfs_ifork_t *ifp, /* inode fork pointer */ 1416 xfs_fileoff_t bno, /* block number searched for */ 1417 int *eofp, /* out: end of file found */ 1418 xfs_extnum_t *lastxp, /* out: last extent index */ 1419 xfs_bmbt_irec_t *gotp, /* out: extent entry found */ 1420 xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */ 1421{ 1422 xfs_bmbt_rec_host_t *ep; /* extent record pointer */ 1423 xfs_extnum_t lastx; /* last extent index */ 1424 1425 /* 1426 * Initialize the extent entry structure to catch access to 1427 * uninitialized br_startblock field. 1428 */ 1429 gotp->br_startoff = 0xffa5a5a5a5a5a5a5LL; 1430 gotp->br_blockcount = 0xa55a5a5a5a5a5a5aLL; 1431 gotp->br_state = XFS_EXT_INVALID; 1432#if XFS_BIG_BLKNOS 1433 gotp->br_startblock = 0xffffa5a5a5a5a5a5LL; 1434#else 1435 gotp->br_startblock = 0xffffa5a5; 1436#endif 1437 prevp->br_startoff = NULLFILEOFF; 1438 1439 ep = xfs_iext_bno_to_ext(ifp, bno, &lastx); 1440 if (lastx > 0) { 1441 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx - 1), prevp); 1442 } 1443 if (lastx < (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))) { 1444 xfs_bmbt_get_all(ep, gotp); 1445 *eofp = 0; 1446 } else { 1447 if (lastx > 0) { 1448 *gotp = *prevp; 1449 } 1450 *eofp = 1; 1451 ep = NULL; 1452 } 1453 *lastxp = lastx; 1454 return ep; 1455} 1456 1457/* 1458 * Search the extents list for the inode, for the extent containing bno. 1459 * If bno lies in a hole, point to the next entry. If bno lies past eof, 1460 * *eofp will be set, and *prevp will contain the last entry (null if none). 1461 * Else, *lastxp will be set to the index of the found 1462 * entry; *gotp will contain the entry. 1463 */ 1464STATIC xfs_bmbt_rec_host_t * /* pointer to found extent entry */ 1465xfs_bmap_search_extents( 1466 xfs_inode_t *ip, /* incore inode pointer */ 1467 xfs_fileoff_t bno, /* block number searched for */ 1468 int fork, /* data or attr fork */ 1469 int *eofp, /* out: end of file found */ 1470 xfs_extnum_t *lastxp, /* out: last extent index */ 1471 xfs_bmbt_irec_t *gotp, /* out: extent entry found */ 1472 xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */ 1473{ 1474 xfs_ifork_t *ifp; /* inode fork pointer */ 1475 xfs_bmbt_rec_host_t *ep; /* extent record pointer */ 1476 1477 XFS_STATS_INC(xs_look_exlist); 1478 ifp = XFS_IFORK_PTR(ip, fork); 1479 1480 ep = xfs_bmap_search_multi_extents(ifp, bno, eofp, lastxp, gotp, prevp); 1481 1482 if (unlikely(!(gotp->br_startblock) && (*lastxp != NULLEXTNUM) && 1483 !(XFS_IS_REALTIME_INODE(ip) && fork == XFS_DATA_FORK))) { 1484 xfs_alert_tag(ip->i_mount, XFS_PTAG_FSBLOCK_ZERO, 1485 "Access to block zero in inode %llu " 1486 "start_block: %llx start_off: %llx " 1487 "blkcnt: %llx extent-state: %x lastx: %x", 1488 (unsigned long long)ip->i_ino, 1489 (unsigned long long)gotp->br_startblock, 1490 (unsigned long long)gotp->br_startoff, 1491 (unsigned long long)gotp->br_blockcount, 1492 gotp->br_state, *lastxp); 1493 *lastxp = NULLEXTNUM; 1494 *eofp = 1; 1495 return NULL; 1496 } 1497 return ep; 1498} 1499 1500/* 1501 * Returns the file-relative block number of the first unused block(s) 1502 * in the file with at least "len" logically contiguous blocks free. 1503 * This is the lowest-address hole if the file has holes, else the first block 1504 * past the end of file. 1505 * Return 0 if the file is currently local (in-inode). 1506 */ 1507int /* error */ 1508xfs_bmap_first_unused( 1509 xfs_trans_t *tp, /* transaction pointer */ 1510 xfs_inode_t *ip, /* incore inode */ 1511 xfs_extlen_t len, /* size of hole to find */ 1512 xfs_fileoff_t *first_unused, /* unused block */ 1513 int whichfork) /* data or attr fork */ 1514{ 1515 int error; /* error return value */ 1516 int idx; /* extent record index */ 1517 xfs_ifork_t *ifp; /* inode fork pointer */ 1518 xfs_fileoff_t lastaddr; /* last block number seen */ 1519 xfs_fileoff_t lowest; /* lowest useful block */ 1520 xfs_fileoff_t max; /* starting useful block */ 1521 xfs_fileoff_t off; /* offset for this block */ 1522 xfs_extnum_t nextents; /* number of extent entries */ 1523 1524 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE || 1525 XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS || 1526 XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL); 1527 if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { 1528 *first_unused = 0; 1529 return 0; 1530 } 1531 ifp = XFS_IFORK_PTR(ip, whichfork); 1532 if (!(ifp->if_flags & XFS_IFEXTENTS) && 1533 (error = xfs_iread_extents(tp, ip, whichfork))) 1534 return error; 1535 lowest = *first_unused; 1536 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 1537 for (idx = 0, lastaddr = 0, max = lowest; idx < nextents; idx++) { 1538 xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, idx); 1539 off = xfs_bmbt_get_startoff(ep); 1540 /* 1541 * See if the hole before this extent will work. 1542 */ 1543 if (off >= lowest + len && off - max >= len) { 1544 *first_unused = max; 1545 return 0; 1546 } 1547 lastaddr = off + xfs_bmbt_get_blockcount(ep); 1548 max = XFS_FILEOFF_MAX(lastaddr, lowest); 1549 } 1550 *first_unused = max; 1551 return 0; 1552} 1553 1554/* 1555 * Returns the file-relative block number of the last block - 1 before 1556 * last_block (input value) in the file. 1557 * This is not based on i_size, it is based on the extent records. 1558 * Returns 0 for local files, as they do not have extent records. 1559 */ 1560int /* error */ 1561xfs_bmap_last_before( 1562 xfs_trans_t *tp, /* transaction pointer */ 1563 xfs_inode_t *ip, /* incore inode */ 1564 xfs_fileoff_t *last_block, /* last block */ 1565 int whichfork) /* data or attr fork */ 1566{ 1567 xfs_fileoff_t bno; /* input file offset */ 1568 int eof; /* hit end of file */ 1569 xfs_bmbt_rec_host_t *ep; /* pointer to last extent */ 1570 int error; /* error return value */ 1571 xfs_bmbt_irec_t got; /* current extent value */ 1572 xfs_ifork_t *ifp; /* inode fork pointer */ 1573 xfs_extnum_t lastx; /* last extent used */ 1574 xfs_bmbt_irec_t prev; /* previous extent value */ 1575 1576 if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE && 1577 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && 1578 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL) 1579 return XFS_ERROR(EIO); 1580 if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { 1581 *last_block = 0; 1582 return 0; 1583 } 1584 ifp = XFS_IFORK_PTR(ip, whichfork); 1585 if (!(ifp->if_flags & XFS_IFEXTENTS) && 1586 (error = xfs_iread_extents(tp, ip, whichfork))) 1587 return error; 1588 bno = *last_block - 1; 1589 ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, 1590 &prev); 1591 if (eof || xfs_bmbt_get_startoff(ep) > bno) { 1592 if (prev.br_startoff == NULLFILEOFF) 1593 *last_block = 0; 1594 else 1595 *last_block = prev.br_startoff + prev.br_blockcount; 1596 } 1597 /* 1598 * Otherwise *last_block is already the right answer. 1599 */ 1600 return 0; 1601} 1602 1603int 1604xfs_bmap_last_extent( 1605 struct xfs_trans *tp, 1606 struct xfs_inode *ip, 1607 int whichfork, 1608 struct xfs_bmbt_irec *rec, 1609 int *is_empty) 1610{ 1611 struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); 1612 int error; 1613 int nextents; 1614 1615 if (!(ifp->if_flags & XFS_IFEXTENTS)) { 1616 error = xfs_iread_extents(tp, ip, whichfork); 1617 if (error) 1618 return error; 1619 } 1620 1621 nextents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t); 1622 if (nextents == 0) { 1623 *is_empty = 1; 1624 return 0; 1625 } 1626 1627 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, nextents - 1), rec); 1628 *is_empty = 0; 1629 return 0; 1630} 1631 1632/* 1633 * Check the last inode extent to determine whether this allocation will result 1634 * in blocks being allocated at the end of the file. When we allocate new data 1635 * blocks at the end of the file which do not start at the previous data block, 1636 * we will try to align the new blocks at stripe unit boundaries. 1637 * 1638 * Returns 1 in bma->aeof if the file (fork) is empty as any new write will be 1639 * at, or past the EOF. 1640 */ 1641STATIC int 1642xfs_bmap_isaeof( 1643 struct xfs_bmalloca *bma, 1644 int whichfork) 1645{ 1646 struct xfs_bmbt_irec rec; 1647 int is_empty; 1648 int error; 1649 1650 bma->aeof = 0; 1651 error = xfs_bmap_last_extent(NULL, bma->ip, whichfork, &rec, 1652 &is_empty); 1653 if (error) 1654 return error; 1655 1656 if (is_empty) { 1657 bma->aeof = 1; 1658 return 0; 1659 } 1660 1661 /* 1662 * Check if we are allocation or past the last extent, or at least into 1663 * the last delayed allocated extent. 1664 */ 1665 bma->aeof = bma->offset >= rec.br_startoff + rec.br_blockcount || 1666 (bma->offset >= rec.br_startoff && 1667 isnullstartblock(rec.br_startblock)); 1668 return 0; 1669} 1670 1671/* 1672 * Returns the file-relative block number of the first block past eof in 1673 * the file. This is not based on i_size, it is based on the extent records. 1674 * Returns 0 for local files, as they do not have extent records. 1675 */ 1676int 1677xfs_bmap_last_offset( 1678 struct xfs_trans *tp, 1679 struct xfs_inode *ip, 1680 xfs_fileoff_t *last_block, 1681 int whichfork) 1682{ 1683 struct xfs_bmbt_irec rec; 1684 int is_empty; 1685 int error; 1686 1687 *last_block = 0; 1688 1689 if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) 1690 return 0; 1691 1692 if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE && 1693 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) 1694 return XFS_ERROR(EIO); 1695 1696 error = xfs_bmap_last_extent(NULL, ip, whichfork, &rec, &is_empty); 1697 if (error || is_empty) 1698 return error; 1699 1700 *last_block = rec.br_startoff + rec.br_blockcount; 1701 return 0; 1702} 1703 1704/* 1705 * Returns whether the selected fork of the inode has exactly one 1706 * block or not. For the data fork we check this matches di_size, 1707 * implying the file's range is 0..bsize-1. 1708 */ 1709int /* 1=>1 block, 0=>otherwise */ 1710xfs_bmap_one_block( 1711 xfs_inode_t *ip, /* incore inode */ 1712 int whichfork) /* data or attr fork */ 1713{ 1714 xfs_bmbt_rec_host_t *ep; /* ptr to fork's extent */ 1715 xfs_ifork_t *ifp; /* inode fork pointer */ 1716 int rval; /* return value */ 1717 xfs_bmbt_irec_t s; /* internal version of extent */ 1718 1719#ifndef DEBUG 1720 if (whichfork == XFS_DATA_FORK) 1721 return XFS_ISIZE(ip) == ip->i_mount->m_sb.sb_blocksize; 1722#endif /* !DEBUG */ 1723 if (XFS_IFORK_NEXTENTS(ip, whichfork) != 1) 1724 return 0; 1725 if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) 1726 return 0; 1727 ifp = XFS_IFORK_PTR(ip, whichfork); 1728 ASSERT(ifp->if_flags & XFS_IFEXTENTS); 1729 ep = xfs_iext_get_ext(ifp, 0); 1730 xfs_bmbt_get_all(ep, &s); 1731 rval = s.br_startoff == 0 && s.br_blockcount == 1; 1732 if (rval && whichfork == XFS_DATA_FORK) 1733 ASSERT(XFS_ISIZE(ip) == ip->i_mount->m_sb.sb_blocksize); 1734 return rval; 1735} 1736 1737/* 1738 * Extent tree manipulation functions used during allocation. 1739 */ 1740 1741/* 1742 * Convert a delayed allocation to a real allocation. 1743 */ 1744STATIC int /* error */ 1745xfs_bmap_add_extent_delay_real( 1746 struct xfs_bmalloca *bma) 1747{ 1748 struct xfs_bmbt_irec *new = &bma->got; 1749 int diff; /* temp value */ 1750 xfs_bmbt_rec_host_t *ep; /* extent entry for idx */ 1751 int error; /* error return value */ 1752 int i; /* temp state */ 1753 xfs_ifork_t *ifp; /* inode fork pointer */ 1754 xfs_fileoff_t new_endoff; /* end offset of new entry */ 1755 xfs_bmbt_irec_t r[3]; /* neighbor extent entries */ 1756 /* left is 0, right is 1, prev is 2 */ 1757 int rval=0; /* return value (logging flags) */ 1758 int state = 0;/* state bits, accessed thru macros */ 1759 xfs_filblks_t da_new; /* new count del alloc blocks used */ 1760 xfs_filblks_t da_old; /* old count del alloc blocks used */ 1761 xfs_filblks_t temp=0; /* value for da_new calculations */ 1762 xfs_filblks_t temp2=0;/* value for da_new calculations */ 1763 int tmp_rval; /* partial logging flags */ 1764 1765 ifp = XFS_IFORK_PTR(bma->ip, XFS_DATA_FORK); 1766 1767 ASSERT(bma->idx >= 0); 1768 ASSERT(bma->idx <= ifp->if_bytes / sizeof(struct xfs_bmbt_rec)); 1769 ASSERT(!isnullstartblock(new->br_startblock)); 1770 ASSERT(!bma->cur || 1771 (bma->cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL)); 1772 1773 XFS_STATS_INC(xs_add_exlist); 1774 1775#define LEFT r[0] 1776#define RIGHT r[1] 1777#define PREV r[2] 1778 1779 /* 1780 * Set up a bunch of variables to make the tests simpler. 1781 */ 1782 ep = xfs_iext_get_ext(ifp, bma->idx); 1783 xfs_bmbt_get_all(ep, &PREV); 1784 new_endoff = new->br_startoff + new->br_blockcount; 1785 ASSERT(PREV.br_startoff <= new->br_startoff); 1786 ASSERT(PREV.br_startoff + PREV.br_blockcount >= new_endoff); 1787 1788 da_old = startblockval(PREV.br_startblock); 1789 da_new = 0; 1790 1791 /* 1792 * Set flags determining what part of the previous delayed allocation 1793 * extent is being replaced by a real allocation. 1794 */ 1795 if (PREV.br_startoff == new->br_startoff) 1796 state |= BMAP_LEFT_FILLING; 1797 if (PREV.br_startoff + PREV.br_blockcount == new_endoff) 1798 state |= BMAP_RIGHT_FILLING; 1799 1800 /* 1801 * Check and set flags if this segment has a left neighbor. 1802 * Don't set contiguous if the combined extent would be too large. 1803 */ 1804 if (bma->idx > 0) { 1805 state |= BMAP_LEFT_VALID; 1806 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma->idx - 1), &LEFT); 1807 1808 if (isnullstartblock(LEFT.br_startblock)) 1809 state |= BMAP_LEFT_DELAY; 1810 } 1811 1812 if ((state & BMAP_LEFT_VALID) && !(state & BMAP_LEFT_DELAY) && 1813 LEFT.br_startoff + LEFT.br_blockcount == new->br_startoff && 1814 LEFT.br_startblock + LEFT.br_blockcount == new->br_startblock && 1815 LEFT.br_state == new->br_state && 1816 LEFT.br_blockcount + new->br_blockcount <= MAXEXTLEN) 1817 state |= BMAP_LEFT_CONTIG; 1818 1819 /* 1820 * Check and set flags if this segment has a right neighbor. 1821 * Don't set contiguous if the combined extent would be too large. 1822 * Also check for all-three-contiguous being too large. 1823 */ 1824 if (bma->idx < bma->ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1) { 1825 state |= BMAP_RIGHT_VALID; 1826 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma->idx + 1), &RIGHT); 1827 1828 if (isnullstartblock(RIGHT.br_startblock)) 1829 state |= BMAP_RIGHT_DELAY; 1830 } 1831 1832 if ((state & BMAP_RIGHT_VALID) && !(state & BMAP_RIGHT_DELAY) && 1833 new_endoff == RIGHT.br_startoff && 1834 new->br_startblock + new->br_blockcount == RIGHT.br_startblock && 1835 new->br_state == RIGHT.br_state && 1836 new->br_blockcount + RIGHT.br_blockcount <= MAXEXTLEN && 1837 ((state & (BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING | 1838 BMAP_RIGHT_FILLING)) != 1839 (BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING | 1840 BMAP_RIGHT_FILLING) || 1841 LEFT.br_blockcount + new->br_blockcount + RIGHT.br_blockcount 1842 <= MAXEXTLEN)) 1843 state |= BMAP_RIGHT_CONTIG; 1844 1845 error = 0; 1846 /* 1847 * Switch out based on the FILLING and CONTIG state bits. 1848 */ 1849 switch (state & (BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | 1850 BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG)) { 1851 case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | 1852 BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: 1853 /* 1854 * Filling in all of a previously delayed allocation extent. 1855 * The left and right neighbors are both contiguous with new. 1856 */ 1857 bma->idx--; 1858 trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_); 1859 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, bma->idx), 1860 LEFT.br_blockcount + PREV.br_blockcount + 1861 RIGHT.br_blockcount); 1862 trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_); 1863 1864 xfs_iext_remove(bma->ip, bma->idx + 1, 2, state); 1865 bma->ip->i_d.di_nextents--; 1866 if (bma->cur == NULL) 1867 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 1868 else { 1869 rval = XFS_ILOG_CORE; 1870 error = xfs_bmbt_lookup_eq(bma->cur, RIGHT.br_startoff, 1871 RIGHT.br_startblock, 1872 RIGHT.br_blockcount, &i); 1873 if (error) 1874 goto done; 1875 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 1876 error = xfs_btree_delete(bma->cur, &i); 1877 if (error) 1878 goto done; 1879 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 1880 error = xfs_btree_decrement(bma->cur, 0, &i); 1881 if (error) 1882 goto done; 1883 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 1884 error = xfs_bmbt_update(bma->cur, LEFT.br_startoff, 1885 LEFT.br_startblock, 1886 LEFT.br_blockcount + 1887 PREV.br_blockcount + 1888 RIGHT.br_blockcount, LEFT.br_state); 1889 if (error) 1890 goto done; 1891 } 1892 break; 1893 1894 case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG: 1895 /* 1896 * Filling in all of a previously delayed allocation extent. 1897 * The left neighbor is contiguous, the right is not. 1898 */ 1899 bma->idx--; 1900 1901 trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_); 1902 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, bma->idx), 1903 LEFT.br_blockcount + PREV.br_blockcount); 1904 trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_); 1905 1906 xfs_iext_remove(bma->ip, bma->idx + 1, 1, state); 1907 if (bma->cur == NULL) 1908 rval = XFS_ILOG_DEXT; 1909 else { 1910 rval = 0; 1911 error = xfs_bmbt_lookup_eq(bma->cur, LEFT.br_startoff, 1912 LEFT.br_startblock, LEFT.br_blockcount, 1913 &i); 1914 if (error) 1915 goto done; 1916 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 1917 error = xfs_bmbt_update(bma->cur, LEFT.br_startoff, 1918 LEFT.br_startblock, 1919 LEFT.br_blockcount + 1920 PREV.br_blockcount, LEFT.br_state); 1921 if (error) 1922 goto done; 1923 } 1924 break; 1925 1926 case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: 1927 /* 1928 * Filling in all of a previously delayed allocation extent. 1929 * The right neighbor is contiguous, the left is not. 1930 */ 1931 trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_); 1932 xfs_bmbt_set_startblock(ep, new->br_startblock); 1933 xfs_bmbt_set_blockcount(ep, 1934 PREV.br_blockcount + RIGHT.br_blockcount); 1935 trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_); 1936 1937 xfs_iext_remove(bma->ip, bma->idx + 1, 1, state); 1938 if (bma->cur == NULL) 1939 rval = XFS_ILOG_DEXT; 1940 else { 1941 rval = 0; 1942 error = xfs_bmbt_lookup_eq(bma->cur, RIGHT.br_startoff, 1943 RIGHT.br_startblock, 1944 RIGHT.br_blockcount, &i); 1945 if (error) 1946 goto done; 1947 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 1948 error = xfs_bmbt_update(bma->cur, PREV.br_startoff, 1949 new->br_startblock, 1950 PREV.br_blockcount + 1951 RIGHT.br_blockcount, PREV.br_state); 1952 if (error) 1953 goto done; 1954 } 1955 break; 1956 1957 case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING: 1958 /* 1959 * Filling in all of a previously delayed allocation extent. 1960 * Neither the left nor right neighbors are contiguous with 1961 * the new one. 1962 */ 1963 trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_); 1964 xfs_bmbt_set_startblock(ep, new->br_startblock); 1965 trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_); 1966 1967 bma->ip->i_d.di_nextents++; 1968 if (bma->cur == NULL) 1969 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 1970 else { 1971 rval = XFS_ILOG_CORE; 1972 error = xfs_bmbt_lookup_eq(bma->cur, new->br_startoff, 1973 new->br_startblock, new->br_blockcount, 1974 &i); 1975 if (error) 1976 goto done; 1977 XFS_WANT_CORRUPTED_GOTO(i == 0, done); 1978 bma->cur->bc_rec.b.br_state = XFS_EXT_NORM; 1979 error = xfs_btree_insert(bma->cur, &i); 1980 if (error) 1981 goto done; 1982 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 1983 } 1984 break; 1985 1986 case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG: 1987 /* 1988 * Filling in the first part of a previous delayed allocation. 1989 * The left neighbor is contiguous. 1990 */ 1991 trace_xfs_bmap_pre_update(bma->ip, bma->idx - 1, state, _THIS_IP_); 1992 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, bma->idx - 1), 1993 LEFT.br_blockcount + new->br_blockcount); 1994 xfs_bmbt_set_startoff(ep, 1995 PREV.br_startoff + new->br_blockcount); 1996 trace_xfs_bmap_post_update(bma->ip, bma->idx - 1, state, _THIS_IP_); 1997 1998 temp = PREV.br_blockcount - new->br_blockcount; 1999 trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_); 2000 xfs_bmbt_set_blockcount(ep, temp); 2001 if (bma->cur == NULL) 2002 rval = XFS_ILOG_DEXT; 2003 else { 2004 rval = 0; 2005 error = xfs_bmbt_lookup_eq(bma->cur, LEFT.br_startoff, 2006 LEFT.br_startblock, LEFT.br_blockcount, 2007 &i); 2008 if (error) 2009 goto done; 2010 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 2011 error = xfs_bmbt_update(bma->cur, LEFT.br_startoff, 2012 LEFT.br_startblock, 2013 LEFT.br_blockcount + 2014 new->br_blockcount, 2015 LEFT.br_state); 2016 if (error) 2017 goto done; 2018 } 2019 da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(bma->ip, temp), 2020 startblockval(PREV.br_startblock)); 2021 xfs_bmbt_set_startblock(ep, nullstartblock(da_new)); 2022 trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_); 2023 2024 bma->idx--; 2025 break; 2026 2027 case BMAP_LEFT_FILLING: 2028 /* 2029 * Filling in the first part of a previous delayed allocation. 2030 * The left neighbor is not contiguous. 2031 */ 2032 trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_); 2033 xfs_bmbt_set_startoff(ep, new_endoff); 2034 temp = PREV.br_blockcount - new->br_blockcount; 2035 xfs_bmbt_set_blockcount(ep, temp); 2036 xfs_iext_insert(bma->ip, bma->idx, 1, new, state); 2037 bma->ip->i_d.di_nextents++; 2038 if (bma->cur == NULL) 2039 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 2040 else { 2041 rval = XFS_ILOG_CORE; 2042 error = xfs_bmbt_lookup_eq(bma->cur, new->br_startoff, 2043 new->br_startblock, new->br_blockcount, 2044 &i); 2045 if (error) 2046 goto done; 2047 XFS_WANT_CORRUPTED_GOTO(i == 0, done); 2048 bma->cur->bc_rec.b.br_state = XFS_EXT_NORM; 2049 error = xfs_btree_insert(bma->cur, &i); 2050 if (error) 2051 goto done; 2052 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 2053 } 2054 2055 if (xfs_bmap_needs_btree(bma->ip, XFS_DATA_FORK)) { 2056 error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, 2057 bma->firstblock, bma->flist, 2058 &bma->cur, 1, &tmp_rval, XFS_DATA_FORK); 2059 rval |= tmp_rval; 2060 if (error) 2061 goto done; 2062 } 2063 da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(bma->ip, temp), 2064 startblockval(PREV.br_startblock) - 2065 (bma->cur ? bma->cur->bc_private.b.allocated : 0)); 2066 ep = xfs_iext_get_ext(ifp, bma->idx + 1); 2067 xfs_bmbt_set_startblock(ep, nullstartblock(da_new)); 2068 trace_xfs_bmap_post_update(bma->ip, bma->idx + 1, state, _THIS_IP_); 2069 break; 2070 2071 case BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: 2072 /* 2073 * Filling in the last part of a previous delayed allocation. 2074 * The right neighbor is contiguous with the new allocation. 2075 */ 2076 temp = PREV.br_blockcount - new->br_blockcount; 2077 trace_xfs_bmap_pre_update(bma->ip, bma->idx + 1, state, _THIS_IP_); 2078 xfs_bmbt_set_blockcount(ep, temp); 2079 xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, bma->idx + 1), 2080 new->br_startoff, new->br_startblock, 2081 new->br_blockcount + RIGHT.br_blockcount, 2082 RIGHT.br_state); 2083 trace_xfs_bmap_post_update(bma->ip, bma->idx + 1, state, _THIS_IP_); 2084 if (bma->cur == NULL) 2085 rval = XFS_ILOG_DEXT; 2086 else { 2087 rval = 0; 2088 error = xfs_bmbt_lookup_eq(bma->cur, RIGHT.br_startoff, 2089 RIGHT.br_startblock, 2090 RIGHT.br_blockcount, &i); 2091 if (error) 2092 goto done; 2093 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 2094 error = xfs_bmbt_update(bma->cur, new->br_startoff, 2095 new->br_startblock, 2096 new->br_blockcount + 2097 RIGHT.br_blockcount, 2098 RIGHT.br_state); 2099 if (error) 2100 goto done; 2101 } 2102 2103 da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(bma->ip, temp), 2104 startblockval(PREV.br_startblock)); 2105 trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_); 2106 xfs_bmbt_set_startblock(ep, nullstartblock(da_new)); 2107 trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_); 2108 2109 bma->idx++; 2110 break; 2111 2112 case BMAP_RIGHT_FILLING: 2113 /* 2114 * Filling in the last part of a previous delayed allocation. 2115 * The right neighbor is not contiguous. 2116 */ 2117 temp = PREV.br_blockcount - new->br_blockcount; 2118 trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_); 2119 xfs_bmbt_set_blockcount(ep, temp); 2120 xfs_iext_insert(bma->ip, bma->idx + 1, 1, new, state); 2121 bma->ip->i_d.di_nextents++; 2122 if (bma->cur == NULL) 2123 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 2124 else { 2125 rval = XFS_ILOG_CORE; 2126 error = xfs_bmbt_lookup_eq(bma->cur, new->br_startoff, 2127 new->br_startblock, new->br_blockcount, 2128 &i); 2129 if (error) 2130 goto done; 2131 XFS_WANT_CORRUPTED_GOTO(i == 0, done); 2132 bma->cur->bc_rec.b.br_state = XFS_EXT_NORM; 2133 error = xfs_btree_insert(bma->cur, &i); 2134 if (error) 2135 goto done; 2136 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 2137 } 2138 2139 if (xfs_bmap_needs_btree(bma->ip, XFS_DATA_FORK)) { 2140 error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, 2141 bma->firstblock, bma->flist, &bma->cur, 1, 2142 &tmp_rval, XFS_DATA_FORK); 2143 rval |= tmp_rval; 2144 if (error) 2145 goto done; 2146 } 2147 da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(bma->ip, temp), 2148 startblockval(PREV.br_startblock) - 2149 (bma->cur ? bma->cur->bc_private.b.allocated : 0)); 2150 ep = xfs_iext_get_ext(ifp, bma->idx); 2151 xfs_bmbt_set_startblock(ep, nullstartblock(da_new)); 2152 trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_); 2153 2154 bma->idx++; 2155 break; 2156 2157 case 0: 2158 /* 2159 * Filling in the middle part of a previous delayed allocation. 2160 * Contiguity is impossible here. 2161 * This case is avoided almost all the time. 2162 * 2163 * We start with a delayed allocation: 2164 * 2165 * +ddddddddddddddddddddddddddddddddddddddddddddddddddddddd+ 2166 * PREV @ idx 2167 * 2168 * and we are allocating: 2169 * +rrrrrrrrrrrrrrrrr+ 2170 * new 2171 * 2172 * and we set it up for insertion as: 2173 * +ddddddddddddddddddd+rrrrrrrrrrrrrrrrr+ddddddddddddddddd+ 2174 * new 2175 * PREV @ idx LEFT RIGHT 2176 * inserted at idx + 1 2177 */ 2178 temp = new->br_startoff - PREV.br_startoff; 2179 temp2 = PREV.br_startoff + PREV.br_blockcount - new_endoff; 2180 trace_xfs_bmap_pre_update(bma->ip, bma->idx, 0, _THIS_IP_); 2181 xfs_bmbt_set_blockcount(ep, temp); /* truncate PREV */ 2182 LEFT = *new; 2183 RIGHT.br_state = PREV.br_state; 2184 RIGHT.br_startblock = nullstartblock( 2185 (int)xfs_bmap_worst_indlen(bma->ip, temp2)); 2186 RIGHT.br_startoff = new_endoff; 2187 RIGHT.br_blockcount = temp2; 2188 /* insert LEFT (r[0]) and RIGHT (r[1]) at the same time */ 2189 xfs_iext_insert(bma->ip, bma->idx + 1, 2, &LEFT, state); 2190 bma->ip->i_d.di_nextents++; 2191 if (bma->cur == NULL) 2192 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 2193 else { 2194 rval = XFS_ILOG_CORE; 2195 error = xfs_bmbt_lookup_eq(bma->cur, new->br_startoff, 2196 new->br_startblock, new->br_blockcount, 2197 &i); 2198 if (error) 2199 goto done; 2200 XFS_WANT_CORRUPTED_GOTO(i == 0, done); 2201 bma->cur->bc_rec.b.br_state = XFS_EXT_NORM; 2202 error = xfs_btree_insert(bma->cur, &i); 2203 if (error) 2204 goto done; 2205 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 2206 } 2207 2208 if (xfs_bmap_needs_btree(bma->ip, XFS_DATA_FORK)) { 2209 error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, 2210 bma->firstblock, bma->flist, &bma->cur, 2211 1, &tmp_rval, XFS_DATA_FORK); 2212 rval |= tmp_rval; 2213 if (error) 2214 goto done; 2215 } 2216 temp = xfs_bmap_worst_indlen(bma->ip, temp); 2217 temp2 = xfs_bmap_worst_indlen(bma->ip, temp2); 2218 diff = (int)(temp + temp2 - startblockval(PREV.br_startblock) - 2219 (bma->cur ? bma->cur->bc_private.b.allocated : 0)); 2220 if (diff > 0) { 2221 error = xfs_icsb_modify_counters(bma->ip->i_mount, 2222 XFS_SBS_FDBLOCKS, 2223 -((int64_t)diff), 0); 2224 ASSERT(!error); 2225 if (error) 2226 goto done; 2227 } 2228 2229 ep = xfs_iext_get_ext(ifp, bma->idx); 2230 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); 2231 trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_); 2232 trace_xfs_bmap_pre_update(bma->ip, bma->idx + 2, state, _THIS_IP_); 2233 xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, bma->idx + 2), 2234 nullstartblock((int)temp2)); 2235 trace_xfs_bmap_post_update(bma->ip, bma->idx + 2, state, _THIS_IP_); 2236 2237 bma->idx++; 2238 da_new = temp + temp2; 2239 break; 2240 2241 case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: 2242 case BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: 2243 case BMAP_LEFT_FILLING | BMAP_RIGHT_CONTIG: 2244 case BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG: 2245 case BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: 2246 case BMAP_LEFT_CONTIG: 2247 case BMAP_RIGHT_CONTIG: 2248 /* 2249 * These cases are all impossible. 2250 */ 2251 ASSERT(0); 2252 } 2253 2254 /* convert to a btree if necessary */ 2255 if (xfs_bmap_needs_btree(bma->ip, XFS_DATA_FORK)) { 2256 int tmp_logflags; /* partial log flag return val */ 2257 2258 ASSERT(bma->cur == NULL); 2259 error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, 2260 bma->firstblock, bma->flist, &bma->cur, 2261 da_old > 0, &tmp_logflags, XFS_DATA_FORK); 2262 bma->logflags |= tmp_logflags; 2263 if (error) 2264 goto done; 2265 } 2266 2267 /* adjust for changes in reserved delayed indirect blocks */ 2268 if (da_old || da_new) { 2269 temp = da_new; 2270 if (bma->cur) 2271 temp += bma->cur->bc_private.b.allocated; 2272 ASSERT(temp <= da_old); 2273 if (temp < da_old) 2274 xfs_icsb_modify_counters(bma->ip->i_mount, 2275 XFS_SBS_FDBLOCKS, 2276 (int64_t)(da_old - temp), 0); 2277 } 2278 2279 /* clear out the allocated field, done with it now in any case. */ 2280 if (bma->cur) 2281 bma->cur->bc_private.b.allocated = 0; 2282 2283 xfs_bmap_check_leaf_extents(bma->cur, bma->ip, XFS_DATA_FORK); 2284done: 2285 bma->logflags |= rval; 2286 return error; 2287#undef LEFT 2288#undef RIGHT 2289#undef PREV 2290} 2291 2292/* 2293 * Convert an unwritten allocation to a real allocation or vice versa. 2294 */ 2295STATIC int /* error */ 2296xfs_bmap_add_extent_unwritten_real( 2297 struct xfs_trans *tp, 2298 xfs_inode_t *ip, /* incore inode pointer */ 2299 xfs_extnum_t *idx, /* extent number to update/insert */ 2300 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ 2301 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 2302 xfs_fsblock_t *first, /* pointer to firstblock variable */ 2303 xfs_bmap_free_t *flist, /* list of extents to be freed */ 2304 int *logflagsp) /* inode logging flags */ 2305{ 2306 xfs_btree_cur_t *cur; /* btree cursor */ 2307 xfs_bmbt_rec_host_t *ep; /* extent entry for idx */ 2308 int error; /* error return value */ 2309 int i; /* temp state */ 2310 xfs_ifork_t *ifp; /* inode fork pointer */ 2311 xfs_fileoff_t new_endoff; /* end offset of new entry */ 2312 xfs_exntst_t newext; /* new extent state */ 2313 xfs_exntst_t oldext; /* old extent state */ 2314 xfs_bmbt_irec_t r[3]; /* neighbor extent entries */ 2315 /* left is 0, right is 1, prev is 2 */ 2316 int rval=0; /* return value (logging flags) */ 2317 int state = 0;/* state bits, accessed thru macros */ 2318 2319 *logflagsp = 0; 2320 2321 cur = *curp; 2322 ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); 2323 2324 ASSERT(*idx >= 0); 2325 ASSERT(*idx <= ifp->if_bytes / sizeof(struct xfs_bmbt_rec)); 2326 ASSERT(!isnullstartblock(new->br_startblock)); 2327 2328 XFS_STATS_INC(xs_add_exlist); 2329 2330#define LEFT r[0] 2331#define RIGHT r[1] 2332#define PREV r[2] 2333 2334 /* 2335 * Set up a bunch of variables to make the tests simpler. 2336 */ 2337 error = 0; 2338 ep = xfs_iext_get_ext(ifp, *idx); 2339 xfs_bmbt_get_all(ep, &PREV); 2340 newext = new->br_state; 2341 oldext = (newext == XFS_EXT_UNWRITTEN) ? 2342 XFS_EXT_NORM : XFS_EXT_UNWRITTEN; 2343 ASSERT(PREV.br_state == oldext); 2344 new_endoff = new->br_startoff + new->br_blockcount; 2345 ASSERT(PREV.br_startoff <= new->br_startoff); 2346 ASSERT(PREV.br_startoff + PREV.br_blockcount >= new_endoff); 2347 2348 /* 2349 * Set flags determining what part of the previous oldext allocation 2350 * extent is being replaced by a newext allocation. 2351 */ 2352 if (PREV.br_startoff == new->br_startoff) 2353 state |= BMAP_LEFT_FILLING; 2354 if (PREV.br_startoff + PREV.br_blockcount == new_endoff) 2355 state |= BMAP_RIGHT_FILLING; 2356 2357 /* 2358 * Check and set flags if this segment has a left neighbor. 2359 * Don't set contiguous if the combined extent would be too large. 2360 */ 2361 if (*idx > 0) { 2362 state |= BMAP_LEFT_VALID; 2363 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx - 1), &LEFT); 2364 2365 if (isnullstartblock(LEFT.br_startblock)) 2366 state |= BMAP_LEFT_DELAY; 2367 } 2368 2369 if ((state & BMAP_LEFT_VALID) && !(state & BMAP_LEFT_DELAY) && 2370 LEFT.br_startoff + LEFT.br_blockcount == new->br_startoff && 2371 LEFT.br_startblock + LEFT.br_blockcount == new->br_startblock && 2372 LEFT.br_state == newext && 2373 LEFT.br_blockcount + new->br_blockcount <= MAXEXTLEN) 2374 state |= BMAP_LEFT_CONTIG; 2375 2376 /* 2377 * Check and set flags if this segment has a right neighbor. 2378 * Don't set contiguous if the combined extent would be too large. 2379 * Also check for all-three-contiguous being too large. 2380 */ 2381 if (*idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1) { 2382 state |= BMAP_RIGHT_VALID; 2383 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx + 1), &RIGHT); 2384 if (isnullstartblock(RIGHT.br_startblock)) 2385 state |= BMAP_RIGHT_DELAY; 2386 } 2387 2388 if ((state & BMAP_RIGHT_VALID) && !(state & BMAP_RIGHT_DELAY) && 2389 new_endoff == RIGHT.br_startoff && 2390 new->br_startblock + new->br_blockcount == RIGHT.br_startblock && 2391 newext == RIGHT.br_state && 2392 new->br_blockcount + RIGHT.br_blockcount <= MAXEXTLEN && 2393 ((state & (BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING | 2394 BMAP_RIGHT_FILLING)) != 2395 (BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING | 2396 BMAP_RIGHT_FILLING) || 2397 LEFT.br_blockcount + new->br_blockcount + RIGHT.br_blockcount 2398 <= MAXEXTLEN)) 2399 state |= BMAP_RIGHT_CONTIG; 2400 2401 /* 2402 * Switch out based on the FILLING and CONTIG state bits. 2403 */ 2404 switch (state & (BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | 2405 BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG)) { 2406 case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | 2407 BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: 2408 /* 2409 * Setting all of a previous oldext extent to newext. 2410 * The left and right neighbors are both contiguous with new. 2411 */ 2412 --*idx; 2413 2414 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 2415 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx), 2416 LEFT.br_blockcount + PREV.br_blockcount + 2417 RIGHT.br_blockcount); 2418 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 2419 2420 xfs_iext_remove(ip, *idx + 1, 2, state); 2421 ip->i_d.di_nextents -= 2; 2422 if (cur == NULL) 2423 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 2424 else { 2425 rval = XFS_ILOG_CORE; 2426 if ((error = xfs_bmbt_lookup_eq(cur, RIGHT.br_startoff, 2427 RIGHT.br_startblock, 2428 RIGHT.br_blockcount, &i))) 2429 goto done; 2430 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 2431 if ((error = xfs_btree_delete(cur, &i))) 2432 goto done; 2433 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 2434 if ((error = xfs_btree_decrement(cur, 0, &i))) 2435 goto done; 2436 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 2437 if ((error = xfs_btree_delete(cur, &i))) 2438 goto done; 2439 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 2440 if ((error = xfs_btree_decrement(cur, 0, &i))) 2441 goto done; 2442 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 2443 if ((error = xfs_bmbt_update(cur, LEFT.br_startoff, 2444 LEFT.br_startblock, 2445 LEFT.br_blockcount + PREV.br_blockcount + 2446 RIGHT.br_blockcount, LEFT.br_state))) 2447 goto done; 2448 } 2449 break; 2450 2451 case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG: 2452 /* 2453 * Setting all of a previous oldext extent to newext. 2454 * The left neighbor is contiguous, the right is not. 2455 */ 2456 --*idx; 2457 2458 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 2459 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx), 2460 LEFT.br_blockcount + PREV.br_blockcount); 2461 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 2462 2463 xfs_iext_remove(ip, *idx + 1, 1, state); 2464 ip->i_d.di_nextents--; 2465 if (cur == NULL) 2466 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 2467 else { 2468 rval = XFS_ILOG_CORE; 2469 if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff, 2470 PREV.br_startblock, PREV.br_blockcount, 2471 &i))) 2472 goto done; 2473 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 2474 if ((error = xfs_btree_delete(cur, &i))) 2475 goto done; 2476 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 2477 if ((error = xfs_btree_decrement(cur, 0, &i))) 2478 goto done; 2479 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 2480 if ((error = xfs_bmbt_update(cur, LEFT.br_startoff, 2481 LEFT.br_startblock, 2482 LEFT.br_blockcount + PREV.br_blockcount, 2483 LEFT.br_state))) 2484 goto done; 2485 } 2486 break; 2487 2488 case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: 2489 /* 2490 * Setting all of a previous oldext extent to newext. 2491 * The right neighbor is contiguous, the left is not. 2492 */ 2493 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 2494 xfs_bmbt_set_blockcount(ep, 2495 PREV.br_blockcount + RIGHT.br_blockcount); 2496 xfs_bmbt_set_state(ep, newext); 2497 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 2498 xfs_iext_remove(ip, *idx + 1, 1, state); 2499 ip->i_d.di_nextents--; 2500 if (cur == NULL) 2501 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 2502 else { 2503 rval = XFS_ILOG_CORE; 2504 if ((error = xfs_bmbt_lookup_eq(cur, RIGHT.br_startoff, 2505 RIGHT.br_startblock, 2506 RIGHT.br_blockcount, &i))) 2507 goto done; 2508 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 2509 if ((error = xfs_btree_delete(cur, &i))) 2510 goto done; 2511 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 2512 if ((error = xfs_btree_decrement(cur, 0, &i))) 2513 goto done; 2514 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 2515 if ((error = xfs_bmbt_update(cur, new->br_startoff, 2516 new->br_startblock, 2517 new->br_blockcount + RIGHT.br_blockcount, 2518 newext))) 2519 goto done; 2520 } 2521 break; 2522 2523 case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING: 2524 /* 2525 * Setting all of a previous oldext extent to newext. 2526 * Neither the left nor right neighbors are contiguous with 2527 * the new one. 2528 */ 2529 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 2530 xfs_bmbt_set_state(ep, newext); 2531 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 2532 2533 if (cur == NULL) 2534 rval = XFS_ILOG_DEXT; 2535 else { 2536 rval = 0; 2537 if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, 2538 new->br_startblock, new->br_blockcount, 2539 &i))) 2540 goto done; 2541 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 2542 if ((error = xfs_bmbt_update(cur, new->br_startoff, 2543 new->br_startblock, new->br_blockcount, 2544 newext))) 2545 goto done; 2546 } 2547 break; 2548 2549 case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG: 2550 /* 2551 * Setting the first part of a previous oldext extent to newext. 2552 * The left neighbor is contiguous. 2553 */ 2554 trace_xfs_bmap_pre_update(ip, *idx - 1, state, _THIS_IP_); 2555 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx - 1), 2556 LEFT.br_blockcount + new->br_blockcount); 2557 xfs_bmbt_set_startoff(ep, 2558 PREV.br_startoff + new->br_blockcount); 2559 trace_xfs_bmap_post_update(ip, *idx - 1, state, _THIS_IP_); 2560 2561 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 2562 xfs_bmbt_set_startblock(ep, 2563 new->br_startblock + new->br_blockcount); 2564 xfs_bmbt_set_blockcount(ep, 2565 PREV.br_blockcount - new->br_blockcount); 2566 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 2567 2568 --*idx; 2569 2570 if (cur == NULL) 2571 rval = XFS_ILOG_DEXT; 2572 else { 2573 rval = 0; 2574 if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff, 2575 PREV.br_startblock, PREV.br_blockcount, 2576 &i))) 2577 goto done; 2578 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 2579 if ((error = xfs_bmbt_update(cur, 2580 PREV.br_startoff + new->br_blockcount, 2581 PREV.br_startblock + new->br_blockcount, 2582 PREV.br_blockcount - new->br_blockcount, 2583 oldext))) 2584 goto done; 2585 if ((error = xfs_btree_decrement(cur, 0, &i))) 2586 goto done; 2587 error = xfs_bmbt_update(cur, LEFT.br_startoff, 2588 LEFT.br_startblock, 2589 LEFT.br_blockcount + new->br_blockcount, 2590 LEFT.br_state); 2591 if (error) 2592 goto done; 2593 } 2594 break; 2595 2596 case BMAP_LEFT_FILLING: 2597 /* 2598 * Setting the first part of a previous oldext extent to newext. 2599 * The left neighbor is not contiguous. 2600 */ 2601 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 2602 ASSERT(ep && xfs_bmbt_get_state(ep) == oldext); 2603 xfs_bmbt_set_startoff(ep, new_endoff); 2604 xfs_bmbt_set_blockcount(ep, 2605 PREV.br_blockcount - new->br_blockcount); 2606 xfs_bmbt_set_startblock(ep, 2607 new->br_startblock + new->br_blockcount); 2608 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 2609 2610 xfs_iext_insert(ip, *idx, 1, new, state); 2611 ip->i_d.di_nextents++; 2612 if (cur == NULL) 2613 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 2614 else { 2615 rval = XFS_ILOG_CORE; 2616 if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff, 2617 PREV.br_startblock, PREV.br_blockcount, 2618 &i))) 2619 goto done; 2620 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 2621 if ((error = xfs_bmbt_update(cur, 2622 PREV.br_startoff + new->br_blockcount, 2623 PREV.br_startblock + new->br_blockcount, 2624 PREV.br_blockcount - new->br_blockcount, 2625 oldext))) 2626 goto done; 2627 cur->bc_rec.b = *new; 2628 if ((error = xfs_btree_insert(cur, &i))) 2629 goto done; 2630 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 2631 } 2632 break; 2633 2634 case BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: 2635 /* 2636 * Setting the last part of a previous oldext extent to newext. 2637 * The right neighbor is contiguous with the new allocation. 2638 */ 2639 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 2640 xfs_bmbt_set_blockcount(ep, 2641 PREV.br_blockcount - new->br_blockcount); 2642 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 2643 2644 ++*idx; 2645 2646 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 2647 xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, *idx), 2648 new->br_startoff, new->br_startblock, 2649 new->br_blockcount + RIGHT.br_blockcount, newext); 2650 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 2651 2652 if (cur == NULL) 2653 rval = XFS_ILOG_DEXT; 2654 else { 2655 rval = 0; 2656 if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff, 2657 PREV.br_startblock, 2658 PREV.br_blockcount, &i))) 2659 goto done; 2660 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 2661 if ((error = xfs_bmbt_update(cur, PREV.br_startoff, 2662 PREV.br_startblock, 2663 PREV.br_blockcount - new->br_blockcount, 2664 oldext))) 2665 goto done; 2666 if ((error = xfs_btree_increment(cur, 0, &i))) 2667 goto done; 2668 if ((error = xfs_bmbt_update(cur, new->br_startoff, 2669 new->br_startblock, 2670 new->br_blockcount + RIGHT.br_blockcount, 2671 newext))) 2672 goto done; 2673 } 2674 break; 2675 2676 case BMAP_RIGHT_FILLING: 2677 /* 2678 * Setting the last part of a previous oldext extent to newext. 2679 * The right neighbor is not contiguous. 2680 */ 2681 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 2682 xfs_bmbt_set_blockcount(ep, 2683 PREV.br_blockcount - new->br_blockcount); 2684 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 2685 2686 ++*idx; 2687 xfs_iext_insert(ip, *idx, 1, new, state); 2688 2689 ip->i_d.di_nextents++; 2690 if (cur == NULL) 2691 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 2692 else { 2693 rval = XFS_ILOG_CORE; 2694 if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff, 2695 PREV.br_startblock, PREV.br_blockcount, 2696 &i))) 2697 goto done; 2698 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 2699 if ((error = xfs_bmbt_update(cur, PREV.br_startoff, 2700 PREV.br_startblock, 2701 PREV.br_blockcount - new->br_blockcount, 2702 oldext))) 2703 goto done; 2704 if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, 2705 new->br_startblock, new->br_blockcount, 2706 &i))) 2707 goto done; 2708 XFS_WANT_CORRUPTED_GOTO(i == 0, done); 2709 cur->bc_rec.b.br_state = XFS_EXT_NORM; 2710 if ((error = xfs_btree_insert(cur, &i))) 2711 goto done; 2712 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 2713 } 2714 break; 2715 2716 case 0: 2717 /* 2718 * Setting the middle part of a previous oldext extent to 2719 * newext. Contiguity is impossible here. 2720 * One extent becomes three extents. 2721 */ 2722 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 2723 xfs_bmbt_set_blockcount(ep, 2724 new->br_startoff - PREV.br_startoff); 2725 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 2726 2727 r[0] = *new; 2728 r[1].br_startoff = new_endoff; 2729 r[1].br_blockcount = 2730 PREV.br_startoff + PREV.br_blockcount - new_endoff; 2731 r[1].br_startblock = new->br_startblock + new->br_blockcount; 2732 r[1].br_state = oldext; 2733 2734 ++*idx; 2735 xfs_iext_insert(ip, *idx, 2, &r[0], state); 2736 2737 ip->i_d.di_nextents += 2; 2738 if (cur == NULL) 2739 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 2740 else { 2741 rval = XFS_ILOG_CORE; 2742 if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff, 2743 PREV.br_startblock, PREV.br_blockcount, 2744 &i))) 2745 goto done; 2746 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 2747 /* new right extent - oldext */ 2748 if ((error = xfs_bmbt_update(cur, r[1].br_startoff, 2749 r[1].br_startblock, r[1].br_blockcount, 2750 r[1].br_state))) 2751 goto done; 2752 /* new left extent - oldext */ 2753 cur->bc_rec.b = PREV; 2754 cur->bc_rec.b.br_blockcount = 2755 new->br_startoff - PREV.br_startoff; 2756 if ((error = xfs_btree_insert(cur, &i))) 2757 goto done; 2758 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 2759 /* 2760 * Reset the cursor to the position of the new extent 2761 * we are about to insert as we can't trust it after 2762 * the previous insert. 2763 */ 2764 if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, 2765 new->br_startblock, new->br_blockcount, 2766 &i))) 2767 goto done; 2768 XFS_WANT_CORRUPTED_GOTO(i == 0, done); 2769 /* new middle extent - newext */ 2770 cur->bc_rec.b.br_state = new->br_state; 2771 if ((error = xfs_btree_insert(cur, &i))) 2772 goto done; 2773 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 2774 } 2775 break; 2776 2777 case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: 2778 case BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: 2779 case BMAP_LEFT_FILLING | BMAP_RIGHT_CONTIG: 2780 case BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG: 2781 case BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: 2782 case BMAP_LEFT_CONTIG: 2783 case BMAP_RIGHT_CONTIG: 2784 /* 2785 * These cases are all impossible. 2786 */ 2787 ASSERT(0); 2788 } 2789 2790 /* convert to a btree if necessary */ 2791 if (xfs_bmap_needs_btree(ip, XFS_DATA_FORK)) { 2792 int tmp_logflags; /* partial log flag return val */ 2793 2794 ASSERT(cur == NULL); 2795 error = xfs_bmap_extents_to_btree(tp, ip, first, flist, &cur, 2796 0, &tmp_logflags, XFS_DATA_FORK); 2797 *logflagsp |= tmp_logflags; 2798 if (error) 2799 goto done; 2800 } 2801 2802 /* clear out the allocated field, done with it now in any case. */ 2803 if (cur) { 2804 cur->bc_private.b.allocated = 0; 2805 *curp = cur; 2806 } 2807 2808 xfs_bmap_check_leaf_extents(*curp, ip, XFS_DATA_FORK); 2809done: 2810 *logflagsp |= rval; 2811 return error; 2812#undef LEFT 2813#undef RIGHT 2814#undef PREV 2815} 2816 2817/* 2818 * Convert a hole to a delayed allocation. 2819 */ 2820STATIC void 2821xfs_bmap_add_extent_hole_delay( 2822 xfs_inode_t *ip, /* incore inode pointer */ 2823 xfs_extnum_t *idx, /* extent number to update/insert */ 2824 xfs_bmbt_irec_t *new) /* new data to add to file extents */ 2825{ 2826 xfs_ifork_t *ifp; /* inode fork pointer */ 2827 xfs_bmbt_irec_t left; /* left neighbor extent entry */ 2828 xfs_filblks_t newlen=0; /* new indirect size */ 2829 xfs_filblks_t oldlen=0; /* old indirect size */ 2830 xfs_bmbt_irec_t right; /* right neighbor extent entry */ 2831 int state; /* state bits, accessed thru macros */ 2832 xfs_filblks_t temp=0; /* temp for indirect calculations */ 2833 2834 ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); 2835 state = 0; 2836 ASSERT(isnullstartblock(new->br_startblock)); 2837 2838 /* 2839 * Check and set flags if this segment has a left neighbor 2840 */ 2841 if (*idx > 0) { 2842 state |= BMAP_LEFT_VALID; 2843 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx - 1), &left); 2844 2845 if (isnullstartblock(left.br_startblock)) 2846 state |= BMAP_LEFT_DELAY; 2847 } 2848 2849 /* 2850 * Check and set flags if the current (right) segment exists. 2851 * If it doesn't exist, we're converting the hole at end-of-file. 2852 */ 2853 if (*idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t)) { 2854 state |= BMAP_RIGHT_VALID; 2855 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx), &right); 2856 2857 if (isnullstartblock(right.br_startblock)) 2858 state |= BMAP_RIGHT_DELAY; 2859 } 2860 2861 /* 2862 * Set contiguity flags on the left and right neighbors. 2863 * Don't let extents get too large, even if the pieces are contiguous. 2864 */ 2865 if ((state & BMAP_LEFT_VALID) && (state & BMAP_LEFT_DELAY) && 2866 left.br_startoff + left.br_blockcount == new->br_startoff && 2867 left.br_blockcount + new->br_blockcount <= MAXEXTLEN) 2868 state |= BMAP_LEFT_CONTIG; 2869 2870 if ((state & BMAP_RIGHT_VALID) && (state & BMAP_RIGHT_DELAY) && 2871 new->br_startoff + new->br_blockcount == right.br_startoff && 2872 new->br_blockcount + right.br_blockcount <= MAXEXTLEN && 2873 (!(state & BMAP_LEFT_CONTIG) || 2874 (left.br_blockcount + new->br_blockcount + 2875 right.br_blockcount <= MAXEXTLEN))) 2876 state |= BMAP_RIGHT_CONTIG; 2877 2878 /* 2879 * Switch out based on the contiguity flags. 2880 */ 2881 switch (state & (BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG)) { 2882 case BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: 2883 /* 2884 * New allocation is contiguous with delayed allocations 2885 * on the left and on the right. 2886 * Merge all three into a single extent record. 2887 */ 2888 --*idx; 2889 temp = left.br_blockcount + new->br_blockcount + 2890 right.br_blockcount; 2891 2892 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 2893 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx), temp); 2894 oldlen = startblockval(left.br_startblock) + 2895 startblockval(new->br_startblock) + 2896 startblockval(right.br_startblock); 2897 newlen = xfs_bmap_worst_indlen(ip, temp); 2898 xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, *idx), 2899 nullstartblock((int)newlen)); 2900 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 2901 2902 xfs_iext_remove(ip, *idx + 1, 1, state); 2903 break; 2904 2905 case BMAP_LEFT_CONTIG: 2906 /* 2907 * New allocation is contiguous with a delayed allocation 2908 * on the left. 2909 * Merge the new allocation with the left neighbor. 2910 */ 2911 --*idx; 2912 temp = left.br_blockcount + new->br_blockcount; 2913 2914 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 2915 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx), temp); 2916 oldlen = startblockval(left.br_startblock) + 2917 startblockval(new->br_startblock); 2918 newlen = xfs_bmap_worst_indlen(ip, temp); 2919 xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, *idx), 2920 nullstartblock((int)newlen)); 2921 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 2922 break; 2923 2924 case BMAP_RIGHT_CONTIG: 2925 /* 2926 * New allocation is contiguous with a delayed allocation 2927 * on the right. 2928 * Merge the new allocation with the right neighbor. 2929 */ 2930 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 2931 temp = new->br_blockcount + right.br_blockcount; 2932 oldlen = startblockval(new->br_startblock) + 2933 startblockval(right.br_startblock); 2934 newlen = xfs_bmap_worst_indlen(ip, temp); 2935 xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, *idx), 2936 new->br_startoff, 2937 nullstartblock((int)newlen), temp, right.br_state); 2938 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 2939 break; 2940 2941 case 0: 2942 /* 2943 * New allocation is not contiguous with another 2944 * delayed allocation. 2945 * Insert a new entry. 2946 */ 2947 oldlen = newlen = 0; 2948 xfs_iext_insert(ip, *idx, 1, new, state); 2949 break; 2950 } 2951 if (oldlen != newlen) { 2952 ASSERT(oldlen > newlen); 2953 xfs_icsb_modify_counters(ip->i_mount, XFS_SBS_FDBLOCKS, 2954 (int64_t)(oldlen - newlen), 0); 2955 /* 2956 * Nothing to do for disk quota accounting here. 2957 */ 2958 } 2959} 2960 2961/* 2962 * Convert a hole to a real allocation. 2963 */ 2964STATIC int /* error */ 2965xfs_bmap_add_extent_hole_real( 2966 struct xfs_bmalloca *bma, 2967 int whichfork) 2968{ 2969 struct xfs_bmbt_irec *new = &bma->got; 2970 int error; /* error return value */ 2971 int i; /* temp state */ 2972 xfs_ifork_t *ifp; /* inode fork pointer */ 2973 xfs_bmbt_irec_t left; /* left neighbor extent entry */ 2974 xfs_bmbt_irec_t right; /* right neighbor extent entry */ 2975 int rval=0; /* return value (logging flags) */ 2976 int state; /* state bits, accessed thru macros */ 2977 2978 ifp = XFS_IFORK_PTR(bma->ip, whichfork); 2979 2980 ASSERT(bma->idx >= 0); 2981 ASSERT(bma->idx <= ifp->if_bytes / sizeof(struct xfs_bmbt_rec)); 2982 ASSERT(!isnullstartblock(new->br_startblock)); 2983 ASSERT(!bma->cur || 2984 !(bma->cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL)); 2985 2986 XFS_STATS_INC(xs_add_exlist); 2987 2988 state = 0; 2989 if (whichfork == XFS_ATTR_FORK) 2990 state |= BMAP_ATTRFORK; 2991 2992 /* 2993 * Check and set flags if this segment has a left neighbor. 2994 */ 2995 if (bma->idx > 0) { 2996 state |= BMAP_LEFT_VALID; 2997 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma->idx - 1), &left); 2998 if (isnullstartblock(left.br_startblock)) 2999 state |= BMAP_LEFT_DELAY; 3000 } 3001 3002 /* 3003 * Check and set flags if this segment has a current value. 3004 * Not true if we're inserting into the "hole" at eof. 3005 */ 3006 if (bma->idx < ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)) { 3007 state |= BMAP_RIGHT_VALID; 3008 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma->idx), &right); 3009 if (isnullstartblock(right.br_startblock)) 3010 state |= BMAP_RIGHT_DELAY; 3011 } 3012 3013 /* 3014 * We're inserting a real allocation between "left" and "right". 3015 * Set the contiguity flags. Don't let extents get too large. 3016 */ 3017 if ((state & BMAP_LEFT_VALID) && !(state & BMAP_LEFT_DELAY) && 3018 left.br_startoff + left.br_blockcount == new->br_startoff && 3019 left.br_startblock + left.br_blockcount == new->br_startblock && 3020 left.br_state == new->br_state && 3021 left.br_blockcount + new->br_blockcount <= MAXEXTLEN) 3022 state |= BMAP_LEFT_CONTIG; 3023 3024 if ((state & BMAP_RIGHT_VALID) && !(state & BMAP_RIGHT_DELAY) && 3025 new->br_startoff + new->br_blockcount == right.br_startoff && 3026 new->br_startblock + new->br_blockcount == right.br_startblock && 3027 new->br_state == right.br_state && 3028 new->br_blockcount + right.br_blockcount <= MAXEXTLEN && 3029 (!(state & BMAP_LEFT_CONTIG) || 3030 left.br_blockcount + new->br_blockcount + 3031 right.br_blockcount <= MAXEXTLEN)) 3032 state |= BMAP_RIGHT_CONTIG; 3033 3034 error = 0; 3035 /* 3036 * Select which case we're in here, and implement it. 3037 */ 3038 switch (state & (BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG)) { 3039 case BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: 3040 /* 3041 * New allocation is contiguous with real allocations on the 3042 * left and on the right. 3043 * Merge all three into a single extent record. 3044 */ 3045 --bma->idx; 3046 trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_); 3047 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, bma->idx), 3048 left.br_blockcount + new->br_blockcount + 3049 right.br_blockcount); 3050 trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_); 3051 3052 xfs_iext_remove(bma->ip, bma->idx + 1, 1, state); 3053 3054 XFS_IFORK_NEXT_SET(bma->ip, whichfork, 3055 XFS_IFORK_NEXTENTS(bma->ip, whichfork) - 1); 3056 if (bma->cur == NULL) { 3057 rval = XFS_ILOG_CORE | xfs_ilog_fext(whichfork); 3058 } else { 3059 rval = XFS_ILOG_CORE; 3060 error = xfs_bmbt_lookup_eq(bma->cur, right.br_startoff, 3061 right.br_startblock, right.br_blockcount, 3062 &i); 3063 if (error) 3064 goto done; 3065 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 3066 error = xfs_btree_delete(bma->cur, &i); 3067 if (error) 3068 goto done; 3069 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 3070 error = xfs_btree_decrement(bma->cur, 0, &i); 3071 if (error) 3072 goto done; 3073 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 3074 error = xfs_bmbt_update(bma->cur, left.br_startoff, 3075 left.br_startblock, 3076 left.br_blockcount + 3077 new->br_blockcount + 3078 right.br_blockcount, 3079 left.br_state); 3080 if (error) 3081 goto done; 3082 } 3083 break; 3084 3085 case BMAP_LEFT_CONTIG: 3086 /* 3087 * New allocation is contiguous with a real allocation 3088 * on the left. 3089 * Merge the new allocation with the left neighbor. 3090 */ 3091 --bma->idx; 3092 trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_); 3093 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, bma->idx), 3094 left.br_blockcount + new->br_blockcount); 3095 trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_); 3096 3097 if (bma->cur == NULL) { 3098 rval = xfs_ilog_fext(whichfork); 3099 } else { 3100 rval = 0; 3101 error = xfs_bmbt_lookup_eq(bma->cur, left.br_startoff, 3102 left.br_startblock, left.br_blockcount, 3103 &i); 3104 if (error) 3105 goto done; 3106 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 3107 error = xfs_bmbt_update(bma->cur, left.br_startoff, 3108 left.br_startblock, 3109 left.br_blockcount + 3110 new->br_blockcount, 3111 left.br_state); 3112 if (error) 3113 goto done; 3114 } 3115 break; 3116 3117 case BMAP_RIGHT_CONTIG: 3118 /* 3119 * New allocation is contiguous with a real allocation 3120 * on the right. 3121 * Merge the new allocation with the right neighbor. 3122 */ 3123 trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_); 3124 xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, bma->idx), 3125 new->br_startoff, new->br_startblock, 3126 new->br_blockcount + right.br_blockcount, 3127 right.br_state); 3128 trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_); 3129 3130 if (bma->cur == NULL) { 3131 rval = xfs_ilog_fext(whichfork); 3132 } else { 3133 rval = 0; 3134 error = xfs_bmbt_lookup_eq(bma->cur, 3135 right.br_startoff, 3136 right.br_startblock, 3137 right.br_blockcount, &i); 3138 if (error) 3139 goto done; 3140 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 3141 error = xfs_bmbt_update(bma->cur, new->br_startoff, 3142 new->br_startblock, 3143 new->br_blockcount + 3144 right.br_blockcount, 3145 right.br_state); 3146 if (error) 3147 goto done; 3148 } 3149 break; 3150 3151 case 0: 3152 /* 3153 * New allocation is not contiguous with another 3154 * real allocation. 3155 * Insert a new entry. 3156 */ 3157 xfs_iext_insert(bma->ip, bma->idx, 1, new, state); 3158 XFS_IFORK_NEXT_SET(bma->ip, whichfork, 3159 XFS_IFORK_NEXTENTS(bma->ip, whichfork) + 1); 3160 if (bma->cur == NULL) { 3161 rval = XFS_ILOG_CORE | xfs_ilog_fext(whichfork); 3162 } else { 3163 rval = XFS_ILOG_CORE; 3164 error = xfs_bmbt_lookup_eq(bma->cur, 3165 new->br_startoff, 3166 new->br_startblock, 3167 new->br_blockcount, &i); 3168 if (error) 3169 goto done; 3170 XFS_WANT_CORRUPTED_GOTO(i == 0, done); 3171 bma->cur->bc_rec.b.br_state = new->br_state; 3172 error = xfs_btree_insert(bma->cur, &i); 3173 if (error) 3174 goto done; 3175 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 3176 } 3177 break; 3178 } 3179 3180 /* convert to a btree if necessary */ 3181 if (xfs_bmap_needs_btree(bma->ip, whichfork)) { 3182 int tmp_logflags; /* partial log flag return val */ 3183 3184 ASSERT(bma->cur == NULL); 3185 error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, 3186 bma->firstblock, bma->flist, &bma->cur, 3187 0, &tmp_logflags, whichfork); 3188 bma->logflags |= tmp_logflags; 3189 if (error) 3190 goto done; 3191 } 3192 3193 /* clear out the allocated field, done with it now in any case. */ 3194 if (bma->cur) 3195 bma->cur->bc_private.b.allocated = 0; 3196 3197 xfs_bmap_check_leaf_extents(bma->cur, bma->ip, whichfork); 3198done: 3199 bma->logflags |= rval; 3200 return error; 3201} 3202 3203/* 3204 * Functions used in the extent read, allocate and remove paths 3205 */ 3206 3207/* 3208 * Adjust the size of the new extent based on di_extsize and rt extsize. 3209 */ 3210int 3211xfs_bmap_extsize_align( 3212 xfs_mount_t *mp, 3213 xfs_bmbt_irec_t *gotp, /* next extent pointer */ 3214 xfs_bmbt_irec_t *prevp, /* previous extent pointer */ 3215 xfs_extlen_t extsz, /* align to this extent size */ 3216 int rt, /* is this a realtime inode? */ 3217 int eof, /* is extent at end-of-file? */ 3218 int delay, /* creating delalloc extent? */ 3219 int convert, /* overwriting unwritten extent? */ 3220 xfs_fileoff_t *offp, /* in/out: aligned offset */ 3221 xfs_extlen_t *lenp) /* in/out: aligned length */ 3222{ 3223 xfs_fileoff_t orig_off; /* original offset */ 3224 xfs_extlen_t orig_alen; /* original length */ 3225 xfs_fileoff_t orig_end; /* original off+len */ 3226 xfs_fileoff_t nexto; /* next file offset */ 3227 xfs_fileoff_t prevo; /* previous file offset */ 3228 xfs_fileoff_t align_off; /* temp for offset */ 3229 xfs_extlen_t align_alen; /* temp for length */ 3230 xfs_extlen_t temp; /* temp for calculations */ 3231 3232 if (convert) 3233 return 0; 3234 3235 orig_off = align_off = *offp; 3236 orig_alen = align_alen = *lenp; 3237 orig_end = orig_off + orig_alen; 3238 3239 /* 3240 * If this request overlaps an existing extent, then don't 3241 * attempt to perform any additional alignment. 3242 */ 3243 if (!delay && !eof && 3244 (orig_off >= gotp->br_startoff) && 3245 (orig_end <= gotp->br_startoff + gotp->br_blockcount)) { 3246 return 0; 3247 } 3248 3249 /* 3250 * If the file offset is unaligned vs. the extent size 3251 * we need to align it. This will be possible unless 3252 * the file was previously written with a kernel that didn't 3253 * perform this alignment, or if a truncate shot us in the 3254 * foot. 3255 */ 3256 temp = do_mod(orig_off, extsz); 3257 if (temp) { 3258 align_alen += temp; 3259 align_off -= temp; 3260 } 3261 /* 3262 * Same adjustment for the end of the requested area. 3263 */ 3264 if ((temp = (align_alen % extsz))) { 3265 align_alen += extsz - temp; 3266 } 3267 /* 3268 * If the previous block overlaps with this proposed allocation 3269 * then move the start forward without adjusting the length. 3270 */ 3271 if (prevp->br_startoff != NULLFILEOFF) { 3272 if (prevp->br_startblock == HOLESTARTBLOCK) 3273 prevo = prevp->br_startoff; 3274 else 3275 prevo = prevp->br_startoff + prevp->br_blockcount; 3276 } else 3277 prevo = 0; 3278 if (align_off != orig_off && align_off < prevo) 3279 align_off = prevo; 3280 /* 3281 * If the next block overlaps with this proposed allocation 3282 * then move the start back without adjusting the length, 3283 * but not before offset 0. 3284 * This may of course make the start overlap previous block, 3285 * and if we hit the offset 0 limit then the next block 3286 * can still overlap too. 3287 */ 3288 if (!eof && gotp->br_startoff != NULLFILEOFF) { 3289 if ((delay && gotp->br_startblock == HOLESTARTBLOCK) || 3290 (!delay && gotp->br_startblock == DELAYSTARTBLOCK)) 3291 nexto = gotp->br_startoff + gotp->br_blockcount; 3292 else 3293 nexto = gotp->br_startoff; 3294 } else 3295 nexto = NULLFILEOFF; 3296 if (!eof && 3297 align_off + align_alen != orig_end && 3298 align_off + align_alen > nexto) 3299 align_off = nexto > align_alen ? nexto - align_alen : 0; 3300 /* 3301 * If we're now overlapping the next or previous extent that 3302 * means we can't fit an extsz piece in this hole. Just move 3303 * the start forward to the first valid spot and set 3304 * the length so we hit the end. 3305 */ 3306 if (align_off != orig_off && align_off < prevo) 3307 align_off = prevo; 3308 if (align_off + align_alen != orig_end && 3309 align_off + align_alen > nexto && 3310 nexto != NULLFILEOFF) { 3311 ASSERT(nexto > prevo); 3312 align_alen = nexto - align_off; 3313 } 3314 3315 /* 3316 * If realtime, and the result isn't a multiple of the realtime 3317 * extent size we need to remove blocks until it is. 3318 */ 3319 if (rt && (temp = (align_alen % mp->m_sb.sb_rextsize))) { 3320 /* 3321 * We're not covering the original request, or 3322 * we won't be able to once we fix the length. 3323 */ 3324 if (orig_off < align_off || 3325 orig_end > align_off + align_alen || 3326 align_alen - temp < orig_alen) 3327 return XFS_ERROR(EINVAL); 3328 /* 3329 * Try to fix it by moving the start up. 3330 */ 3331 if (align_off + temp <= orig_off) { 3332 align_alen -= temp; 3333 align_off += temp; 3334 } 3335 /* 3336 * Try to fix it by moving the end in. 3337 */ 3338 else if (align_off + align_alen - temp >= orig_end) 3339 align_alen -= temp; 3340 /* 3341 * Set the start to the minimum then trim the length. 3342 */ 3343 else { 3344 align_alen -= orig_off - align_off; 3345 align_off = orig_off; 3346 align_alen -= align_alen % mp->m_sb.sb_rextsize; 3347 } 3348 /* 3349 * Result doesn't cover the request, fail it. 3350 */ 3351 if (orig_off < align_off || orig_end > align_off + align_alen) 3352 return XFS_ERROR(EINVAL); 3353 } else { 3354 ASSERT(orig_off >= align_off); 3355 ASSERT(orig_end <= align_off + align_alen); 3356 } 3357 3358#ifdef DEBUG 3359 if (!eof && gotp->br_startoff != NULLFILEOFF) 3360 ASSERT(align_off + align_alen <= gotp->br_startoff); 3361 if (prevp->br_startoff != NULLFILEOFF) 3362 ASSERT(align_off >= prevp->br_startoff + prevp->br_blockcount); 3363#endif 3364 3365 *lenp = align_alen; 3366 *offp = align_off; 3367 return 0; 3368} 3369 3370#define XFS_ALLOC_GAP_UNITS 4 3371 3372void 3373xfs_bmap_adjacent( 3374 struct xfs_bmalloca *ap) /* bmap alloc argument struct */ 3375{ 3376 xfs_fsblock_t adjust; /* adjustment to block numbers */ 3377 xfs_agnumber_t fb_agno; /* ag number of ap->firstblock */ 3378 xfs_mount_t *mp; /* mount point structure */ 3379 int nullfb; /* true if ap->firstblock isn't set */ 3380 int rt; /* true if inode is realtime */ 3381 3382#define ISVALID(x,y) \ 3383 (rt ? \ 3384 (x) < mp->m_sb.sb_rblocks : \ 3385 XFS_FSB_TO_AGNO(mp, x) == XFS_FSB_TO_AGNO(mp, y) && \ 3386 XFS_FSB_TO_AGNO(mp, x) < mp->m_sb.sb_agcount && \ 3387 XFS_FSB_TO_AGBNO(mp, x) < mp->m_sb.sb_agblocks) 3388 3389 mp = ap->ip->i_mount; 3390 nullfb = *ap->firstblock == NULLFSBLOCK; 3391 rt = XFS_IS_REALTIME_INODE(ap->ip) && ap->userdata; 3392 fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, *ap->firstblock); 3393 /* 3394 * If allocating at eof, and there's a previous real block, 3395 * try to use its last block as our starting point. 3396 */ 3397 if (ap->eof && ap->prev.br_startoff != NULLFILEOFF && 3398 !isnullstartblock(ap->prev.br_startblock) && 3399 ISVALID(ap->prev.br_startblock + ap->prev.br_blockcount, 3400 ap->prev.br_startblock)) { 3401 ap->blkno = ap->prev.br_startblock + ap->prev.br_blockcount; 3402 /* 3403 * Adjust for the gap between prevp and us. 3404 */ 3405 adjust = ap->offset - 3406 (ap->prev.br_startoff + ap->prev.br_blockcount); 3407 if (adjust && 3408 ISVALID(ap->blkno + adjust, ap->prev.br_startblock)) 3409 ap->blkno += adjust; 3410 } 3411 /* 3412 * If not at eof, then compare the two neighbor blocks. 3413 * Figure out whether either one gives us a good starting point, 3414 * and pick the better one. 3415 */ 3416 else if (!ap->eof) { 3417 xfs_fsblock_t gotbno; /* right side block number */ 3418 xfs_fsblock_t gotdiff=0; /* right side difference */ 3419 xfs_fsblock_t prevbno; /* left side block number */ 3420 xfs_fsblock_t prevdiff=0; /* left side difference */ 3421 3422 /* 3423 * If there's a previous (left) block, select a requested 3424 * start block based on it. 3425 */ 3426 if (ap->prev.br_startoff != NULLFILEOFF && 3427 !isnullstartblock(ap->prev.br_startblock) && 3428 (prevbno = ap->prev.br_startblock + 3429 ap->prev.br_blockcount) && 3430 ISVALID(prevbno, ap->prev.br_startblock)) { 3431 /* 3432 * Calculate gap to end of previous block. 3433 */ 3434 adjust = prevdiff = ap->offset - 3435 (ap->prev.br_startoff + 3436 ap->prev.br_blockcount); 3437 /* 3438 * Figure the startblock based on the previous block's 3439 * end and the gap size. 3440 * Heuristic! 3441 * If the gap is large relative to the piece we're 3442 * allocating, or using it gives us an invalid block 3443 * number, then just use the end of the previous block. 3444 */ 3445 if (prevdiff <= XFS_ALLOC_GAP_UNITS * ap->length && 3446 ISVALID(prevbno + prevdiff, 3447 ap->prev.br_startblock)) 3448 prevbno += adjust; 3449 else 3450 prevdiff += adjust; 3451 /* 3452 * If the firstblock forbids it, can't use it, 3453 * must use default. 3454 */ 3455 if (!rt && !nullfb && 3456 XFS_FSB_TO_AGNO(mp, prevbno) != fb_agno) 3457 prevbno = NULLFSBLOCK; 3458 } 3459 /* 3460 * No previous block or can't follow it, just default. 3461 */ 3462 else 3463 prevbno = NULLFSBLOCK; 3464 /* 3465 * If there's a following (right) block, select a requested 3466 * start block based on it. 3467 */ 3468 if (!isnullstartblock(ap->got.br_startblock)) { 3469 /* 3470 * Calculate gap to start of next block. 3471 */ 3472 adjust = gotdiff = ap->got.br_startoff - ap->offset; 3473 /* 3474 * Figure the startblock based on the next block's 3475 * start and the gap size. 3476 */ 3477 gotbno = ap->got.br_startblock; 3478 /* 3479 * Heuristic! 3480 * If the gap is large relative to the piece we're 3481 * allocating, or using it gives us an invalid block 3482 * number, then just use the start of the next block 3483 * offset by our length. 3484 */ 3485 if (gotdiff <= XFS_ALLOC_GAP_UNITS * ap->length && 3486 ISVALID(gotbno - gotdiff, gotbno)) 3487 gotbno -= adjust; 3488 else if (ISVALID(gotbno - ap->length, gotbno)) { 3489 gotbno -= ap->length; 3490 gotdiff += adjust - ap->length; 3491 } else 3492 gotdiff += adjust; 3493 /* 3494 * If the firstblock forbids it, can't use it, 3495 * must use default. 3496 */ 3497 if (!rt && !nullfb && 3498 XFS_FSB_TO_AGNO(mp, gotbno) != fb_agno) 3499 gotbno = NULLFSBLOCK; 3500 } 3501 /* 3502 * No next block, just default. 3503 */ 3504 else 3505 gotbno = NULLFSBLOCK; 3506 /* 3507 * If both valid, pick the better one, else the only good 3508 * one, else ap->blkno is already set (to 0 or the inode block). 3509 */ 3510 if (prevbno != NULLFSBLOCK && gotbno != NULLFSBLOCK) 3511 ap->blkno = prevdiff <= gotdiff ? prevbno : gotbno; 3512 else if (prevbno != NULLFSBLOCK) 3513 ap->blkno = prevbno; 3514 else if (gotbno != NULLFSBLOCK) 3515 ap->blkno = gotbno; 3516 } 3517#undef ISVALID 3518} 3519 3520STATIC int 3521xfs_bmap_btalloc_nullfb( 3522 struct xfs_bmalloca *ap, 3523 struct xfs_alloc_arg *args, 3524 xfs_extlen_t *blen) 3525{ 3526 struct xfs_mount *mp = ap->ip->i_mount; 3527 struct xfs_perag *pag; 3528 xfs_agnumber_t ag, startag; 3529 int notinit = 0; 3530 int error; 3531 3532 if (ap->userdata && xfs_inode_is_filestream(ap->ip)) 3533 args->type = XFS_ALLOCTYPE_NEAR_BNO; 3534 else 3535 args->type = XFS_ALLOCTYPE_START_BNO; 3536 args->total = ap->total; 3537 3538 /* 3539 * Search for an allocation group with a single extent large enough 3540 * for the request. If one isn't found, then adjust the minimum 3541 * allocation size to the largest space found. 3542 */ 3543 startag = ag = XFS_FSB_TO_AGNO(mp, args->fsbno); 3544 if (startag == NULLAGNUMBER) 3545 startag = ag = 0; 3546 3547 pag = xfs_perag_get(mp, ag); 3548 while (*blen < args->maxlen) { 3549 if (!pag->pagf_init) { 3550 error = xfs_alloc_pagf_init(mp, args->tp, ag, 3551 XFS_ALLOC_FLAG_TRYLOCK); 3552 if (error) { 3553 xfs_perag_put(pag); 3554 return error; 3555 } 3556 } 3557 3558 /* 3559 * See xfs_alloc_fix_freelist... 3560 */ 3561 if (pag->pagf_init) { 3562 xfs_extlen_t longest; 3563 longest = xfs_alloc_longest_free_extent(mp, pag); 3564 if (*blen < longest) 3565 *blen = longest; 3566 } else 3567 notinit = 1; 3568 3569 if (xfs_inode_is_filestream(ap->ip)) { 3570 if (*blen >= args->maxlen) 3571 break; 3572 3573 if (ap->userdata) { 3574 /* 3575 * If startag is an invalid AG, we've 3576 * come here once before and 3577 * xfs_filestream_new_ag picked the 3578 * best currently available. 3579 * 3580 * Don't continue looping, since we 3581 * could loop forever. 3582 */ 3583 if (startag == NULLAGNUMBER) 3584 break; 3585 3586 error = xfs_filestream_new_ag(ap, &ag); 3587 xfs_perag_put(pag); 3588 if (error) 3589 return error; 3590 3591 /* loop again to set 'blen'*/ 3592 startag = NULLAGNUMBER; 3593 pag = xfs_perag_get(mp, ag); 3594 continue; 3595 } 3596 } 3597 if (++ag == mp->m_sb.sb_agcount) 3598 ag = 0; 3599 if (ag == startag) 3600 break; 3601 xfs_perag_put(pag); 3602 pag = xfs_perag_get(mp, ag); 3603 } 3604 xfs_perag_put(pag); 3605 3606 /* 3607 * Since the above loop did a BUF_TRYLOCK, it is 3608 * possible that there is space for this request. 3609 */ 3610 if (notinit || *blen < ap->minlen) 3611 args->minlen = ap->minlen; 3612 /* 3613 * If the best seen length is less than the request 3614 * length, use the best as the minimum. 3615 */ 3616 else if (*blen < args->maxlen) 3617 args->minlen = *blen; 3618 /* 3619 * Otherwise we've seen an extent as big as maxlen, 3620 * use that as the minimum. 3621 */ 3622 else 3623 args->minlen = args->maxlen; 3624 3625 /* 3626 * set the failure fallback case to look in the selected 3627 * AG as the stream may have moved. 3628 */ 3629 if (xfs_inode_is_filestream(ap->ip)) 3630 ap->blkno = args->fsbno = XFS_AGB_TO_FSB(mp, ag, 0); 3631 3632 return 0; 3633} 3634 3635STATIC int 3636xfs_bmap_btalloc( 3637 struct xfs_bmalloca *ap) /* bmap alloc argument struct */ 3638{ 3639 xfs_mount_t *mp; /* mount point structure */ 3640 xfs_alloctype_t atype = 0; /* type for allocation routines */ 3641 xfs_extlen_t align; /* minimum allocation alignment */ 3642 xfs_agnumber_t fb_agno; /* ag number of ap->firstblock */ 3643 xfs_agnumber_t ag; 3644 xfs_alloc_arg_t args; 3645 xfs_extlen_t blen; 3646 xfs_extlen_t nextminlen = 0; 3647 int nullfb; /* true if ap->firstblock isn't set */ 3648 int isaligned; 3649 int tryagain; 3650 int error; 3651 int stripe_align; 3652 3653 ASSERT(ap->length); 3654 3655 mp = ap->ip->i_mount; 3656 3657 /* stripe alignment for allocation is determined by mount parameters */ 3658 stripe_align = 0; 3659 if (mp->m_swidth && (mp->m_flags & XFS_MOUNT_SWALLOC)) 3660 stripe_align = mp->m_swidth; 3661 else if (mp->m_dalign) 3662 stripe_align = mp->m_dalign; 3663 3664 align = ap->userdata ? xfs_get_extsz_hint(ap->ip) : 0; 3665 if (unlikely(align)) { 3666 error = xfs_bmap_extsize_align(mp, &ap->got, &ap->prev, 3667 align, 0, ap->eof, 0, ap->conv, 3668 &ap->offset, &ap->length); 3669 ASSERT(!error); 3670 ASSERT(ap->length); 3671 } 3672 3673 3674 nullfb = *ap->firstblock == NULLFSBLOCK; 3675 fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, *ap->firstblock); 3676 if (nullfb) { 3677 if (ap->userdata && xfs_inode_is_filestream(ap->ip)) { 3678 ag = xfs_filestream_lookup_ag(ap->ip); 3679 ag = (ag != NULLAGNUMBER) ? ag : 0; 3680 ap->blkno = XFS_AGB_TO_FSB(mp, ag, 0); 3681 } else { 3682 ap->blkno = XFS_INO_TO_FSB(mp, ap->ip->i_ino); 3683 } 3684 } else 3685 ap->blkno = *ap->firstblock; 3686 3687 xfs_bmap_adjacent(ap); 3688 3689 /* 3690 * If allowed, use ap->blkno; otherwise must use firstblock since 3691 * it's in the right allocation group. 3692 */ 3693 if (nullfb || XFS_FSB_TO_AGNO(mp, ap->blkno) == fb_agno) 3694 ; 3695 else 3696 ap->blkno = *ap->firstblock; 3697 /* 3698 * Normal allocation, done through xfs_alloc_vextent. 3699 */ 3700 tryagain = isaligned = 0; 3701 memset(&args, 0, sizeof(args)); 3702 args.tp = ap->tp; 3703 args.mp = mp; 3704 args.fsbno = ap->blkno; 3705 3706 /* Trim the allocation back to the maximum an AG can fit. */ 3707 args.maxlen = MIN(ap->length, XFS_ALLOC_AG_MAX_USABLE(mp)); 3708 args.firstblock = *ap->firstblock; 3709 blen = 0; 3710 if (nullfb) { 3711 error = xfs_bmap_btalloc_nullfb(ap, &args, &blen); 3712 if (error) 3713 return error; 3714 } else if (ap->flist->xbf_low) { 3715 if (xfs_inode_is_filestream(ap->ip)) 3716 args.type = XFS_ALLOCTYPE_FIRST_AG; 3717 else 3718 args.type = XFS_ALLOCTYPE_START_BNO; 3719 args.total = args.minlen = ap->minlen; 3720 } else { 3721 args.type = XFS_ALLOCTYPE_NEAR_BNO; 3722 args.total = ap->total; 3723 args.minlen = ap->minlen; 3724 } 3725 /* apply extent size hints if obtained earlier */ 3726 if (unlikely(align)) { 3727 args.prod = align; 3728 if ((args.mod = (xfs_extlen_t)do_mod(ap->offset, args.prod))) 3729 args.mod = (xfs_extlen_t)(args.prod - args.mod); 3730 } else if (mp->m_sb.sb_blocksize >= PAGE_CACHE_SIZE) { 3731 args.prod = 1; 3732 args.mod = 0; 3733 } else { 3734 args.prod = PAGE_CACHE_SIZE >> mp->m_sb.sb_blocklog; 3735 if ((args.mod = (xfs_extlen_t)(do_mod(ap->offset, args.prod)))) 3736 args.mod = (xfs_extlen_t)(args.prod - args.mod); 3737 } 3738 /* 3739 * If we are not low on available data blocks, and the 3740 * underlying logical volume manager is a stripe, and 3741 * the file offset is zero then try to allocate data 3742 * blocks on stripe unit boundary. 3743 * NOTE: ap->aeof is only set if the allocation length 3744 * is >= the stripe unit and the allocation offset is 3745 * at the end of file. 3746 */ 3747 if (!ap->flist->xbf_low && ap->aeof) { 3748 if (!ap->offset) { 3749 args.alignment = stripe_align; 3750 atype = args.type; 3751 isaligned = 1; 3752 /* 3753 * Adjust for alignment 3754 */ 3755 if (blen > args.alignment && blen <= args.maxlen) 3756 args.minlen = blen - args.alignment; 3757 args.minalignslop = 0; 3758 } else { 3759 /* 3760 * First try an exact bno allocation. 3761 * If it fails then do a near or start bno 3762 * allocation with alignment turned on. 3763 */ 3764 atype = args.type; 3765 tryagain = 1; 3766 args.type = XFS_ALLOCTYPE_THIS_BNO; 3767 args.alignment = 1; 3768 /* 3769 * Compute the minlen+alignment for the 3770 * next case. Set slop so that the value 3771 * of minlen+alignment+slop doesn't go up 3772 * between the calls. 3773 */ 3774 if (blen > stripe_align && blen <= args.maxlen) 3775 nextminlen = blen - stripe_align; 3776 else 3777 nextminlen = args.minlen; 3778 if (nextminlen + stripe_align > args.minlen + 1) 3779 args.minalignslop = 3780 nextminlen + stripe_align - 3781 args.minlen - 1; 3782 else 3783 args.minalignslop = 0; 3784 } 3785 } else { 3786 args.alignment = 1; 3787 args.minalignslop = 0; 3788 } 3789 args.minleft = ap->minleft; 3790 args.wasdel = ap->wasdel; 3791 args.isfl = 0; 3792 args.userdata = ap->userdata; 3793 if ((error = xfs_alloc_vextent(&args))) 3794 return error; 3795 if (tryagain && args.fsbno == NULLFSBLOCK) { 3796 /* 3797 * Exact allocation failed. Now try with alignment 3798 * turned on. 3799 */ 3800 args.type = atype; 3801 args.fsbno = ap->blkno; 3802 args.alignment = stripe_align; 3803 args.minlen = nextminlen; 3804 args.minalignslop = 0; 3805 isaligned = 1; 3806 if ((error = xfs_alloc_vextent(&args))) 3807 return error; 3808 } 3809 if (isaligned && args.fsbno == NULLFSBLOCK) { 3810 /* 3811 * allocation failed, so turn off alignment and 3812 * try again. 3813 */ 3814 args.type = atype; 3815 args.fsbno = ap->blkno; 3816 args.alignment = 0; 3817 if ((error = xfs_alloc_vextent(&args))) 3818 return error; 3819 } 3820 if (args.fsbno == NULLFSBLOCK && nullfb && 3821 args.minlen > ap->minlen) { 3822 args.minlen = ap->minlen; 3823 args.type = XFS_ALLOCTYPE_START_BNO; 3824 args.fsbno = ap->blkno; 3825 if ((error = xfs_alloc_vextent(&args))) 3826 return error; 3827 } 3828 if (args.fsbno == NULLFSBLOCK && nullfb) { 3829 args.fsbno = 0; 3830 args.type = XFS_ALLOCTYPE_FIRST_AG; 3831 args.total = ap->minlen; 3832 args.minleft = 0; 3833 if ((error = xfs_alloc_vextent(&args))) 3834 return error; 3835 ap->flist->xbf_low = 1; 3836 } 3837 if (args.fsbno != NULLFSBLOCK) { 3838 /* 3839 * check the allocation happened at the same or higher AG than 3840 * the first block that was allocated. 3841 */ 3842 ASSERT(*ap->firstblock == NULLFSBLOCK || 3843 XFS_FSB_TO_AGNO(mp, *ap->firstblock) == 3844 XFS_FSB_TO_AGNO(mp, args.fsbno) || 3845 (ap->flist->xbf_low && 3846 XFS_FSB_TO_AGNO(mp, *ap->firstblock) < 3847 XFS_FSB_TO_AGNO(mp, args.fsbno))); 3848 3849 ap->blkno = args.fsbno; 3850 if (*ap->firstblock == NULLFSBLOCK) 3851 *ap->firstblock = args.fsbno; 3852 ASSERT(nullfb || fb_agno == args.agno || 3853 (ap->flist->xbf_low && fb_agno < args.agno)); 3854 ap->length = args.len; 3855 ap->ip->i_d.di_nblocks += args.len; 3856 xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE); 3857 if (ap->wasdel) 3858 ap->ip->i_delayed_blks -= args.len; 3859 /* 3860 * Adjust the disk quota also. This was reserved 3861 * earlier. 3862 */ 3863 xfs_trans_mod_dquot_byino(ap->tp, ap->ip, 3864 ap->wasdel ? XFS_TRANS_DQ_DELBCOUNT : 3865 XFS_TRANS_DQ_BCOUNT, 3866 (long) args.len); 3867 } else { 3868 ap->blkno = NULLFSBLOCK; 3869 ap->length = 0; 3870 } 3871 return 0; 3872} 3873 3874/* 3875 * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file. 3876 * It figures out where to ask the underlying allocator to put the new extent. 3877 */ 3878STATIC int 3879xfs_bmap_alloc( 3880 struct xfs_bmalloca *ap) /* bmap alloc argument struct */ 3881{ 3882 if (XFS_IS_REALTIME_INODE(ap->ip) && ap->userdata) 3883 return xfs_bmap_rtalloc(ap); 3884 return xfs_bmap_btalloc(ap); 3885} 3886 3887/* 3888 * Trim the returned map to the required bounds 3889 */ 3890STATIC void 3891xfs_bmapi_trim_map( 3892 struct xfs_bmbt_irec *mval, 3893 struct xfs_bmbt_irec *got, 3894 xfs_fileoff_t *bno, 3895 xfs_filblks_t len, 3896 xfs_fileoff_t obno, 3897 xfs_fileoff_t end, 3898 int n, 3899 int flags) 3900{ 3901 if ((flags & XFS_BMAPI_ENTIRE) || 3902 got->br_startoff + got->br_blockcount <= obno) { 3903 *mval = *got; 3904 if (isnullstartblock(got->br_startblock)) 3905 mval->br_startblock = DELAYSTARTBLOCK; 3906 return; 3907 } 3908 3909 if (obno > *bno) 3910 *bno = obno; 3911 ASSERT((*bno >= obno) || (n == 0)); 3912 ASSERT(*bno < end); 3913 mval->br_startoff = *bno; 3914 if (isnullstartblock(got->br_startblock)) 3915 mval->br_startblock = DELAYSTARTBLOCK; 3916 else 3917 mval->br_startblock = got->br_startblock + 3918 (*bno - got->br_startoff); 3919 /* 3920 * Return the minimum of what we got and what we asked for for 3921 * the length. We can use the len variable here because it is 3922 * modified below and we could have been there before coming 3923 * here if the first part of the allocation didn't overlap what 3924 * was asked for. 3925 */ 3926 mval->br_blockcount = XFS_FILBLKS_MIN(end - *bno, 3927 got->br_blockcount - (*bno - got->br_startoff)); 3928 mval->br_state = got->br_state; 3929 ASSERT(mval->br_blockcount <= len); 3930 return; 3931} 3932 3933/* 3934 * Update and validate the extent map to return 3935 */ 3936STATIC void 3937xfs_bmapi_update_map( 3938 struct xfs_bmbt_irec **map, 3939 xfs_fileoff_t *bno, 3940 xfs_filblks_t *len, 3941 xfs_fileoff_t obno, 3942 xfs_fileoff_t end, 3943 int *n, 3944 int flags) 3945{ 3946 xfs_bmbt_irec_t *mval = *map; 3947 3948 ASSERT((flags & XFS_BMAPI_ENTIRE) || 3949 ((mval->br_startoff + mval->br_blockcount) <= end)); 3950 ASSERT((flags & XFS_BMAPI_ENTIRE) || (mval->br_blockcount <= *len) || 3951 (mval->br_startoff < obno)); 3952 3953 *bno = mval->br_startoff + mval->br_blockcount; 3954 *len = end - *bno; 3955 if (*n > 0 && mval->br_startoff == mval[-1].br_startoff) { 3956 /* update previous map with new information */ 3957 ASSERT(mval->br_startblock == mval[-1].br_startblock); 3958 ASSERT(mval->br_blockcount > mval[-1].br_blockcount); 3959 ASSERT(mval->br_state == mval[-1].br_state); 3960 mval[-1].br_blockcount = mval->br_blockcount; 3961 mval[-1].br_state = mval->br_state; 3962 } else if (*n > 0 && mval->br_startblock != DELAYSTARTBLOCK && 3963 mval[-1].br_startblock != DELAYSTARTBLOCK && 3964 mval[-1].br_startblock != HOLESTARTBLOCK && 3965 mval->br_startblock == mval[-1].br_startblock + 3966 mval[-1].br_blockcount && 3967 ((flags & XFS_BMAPI_IGSTATE) || 3968 mval[-1].br_state == mval->br_state)) { 3969 ASSERT(mval->br_startoff == 3970 mval[-1].br_startoff + mval[-1].br_blockcount); 3971 mval[-1].br_blockcount += mval->br_blockcount; 3972 } else if (*n > 0 && 3973 mval->br_startblock == DELAYSTARTBLOCK && 3974 mval[-1].br_startblock == DELAYSTARTBLOCK && 3975 mval->br_startoff == 3976 mval[-1].br_startoff + mval[-1].br_blockcount) { 3977 mval[-1].br_blockcount += mval->br_blockcount; 3978 mval[-1].br_state = mval->br_state; 3979 } else if (!((*n == 0) && 3980 ((mval->br_startoff + mval->br_blockcount) <= 3981 obno))) { 3982 mval++; 3983 (*n)++; 3984 } 3985 *map = mval; 3986} 3987 3988/* 3989 * Map file blocks to filesystem blocks without allocation. 3990 */ 3991int 3992xfs_bmapi_read( 3993 struct xfs_inode *ip, 3994 xfs_fileoff_t bno, 3995 xfs_filblks_t len, 3996 struct xfs_bmbt_irec *mval, 3997 int *nmap, 3998 int flags) 3999{ 4000 struct xfs_mount *mp = ip->i_mount; 4001 struct xfs_ifork *ifp; 4002 struct xfs_bmbt_irec got; 4003 struct xfs_bmbt_irec prev; 4004 xfs_fileoff_t obno; 4005 xfs_fileoff_t end; 4006 xfs_extnum_t lastx; 4007 int error; 4008 int eof; 4009 int n = 0; 4010 int whichfork = (flags & XFS_BMAPI_ATTRFORK) ? 4011 XFS_ATTR_FORK : XFS_DATA_FORK; 4012 4013 ASSERT(*nmap >= 1); 4014 ASSERT(!(flags & ~(XFS_BMAPI_ATTRFORK|XFS_BMAPI_ENTIRE| 4015 XFS_BMAPI_IGSTATE))); 4016 ASSERT(xfs_isilocked(ip, XFS_ILOCK_SHARED|XFS_ILOCK_EXCL)); 4017 4018 if (unlikely(XFS_TEST_ERROR( 4019 (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && 4020 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE), 4021 mp, XFS_ERRTAG_BMAPIFORMAT, XFS_RANDOM_BMAPIFORMAT))) { 4022 XFS_ERROR_REPORT("xfs_bmapi_read", XFS_ERRLEVEL_LOW, mp); 4023 return XFS_ERROR(EFSCORRUPTED); 4024 } 4025 4026 if (XFS_FORCED_SHUTDOWN(mp)) 4027 return XFS_ERROR(EIO); 4028 4029 XFS_STATS_INC(xs_blk_mapr); 4030 4031 ifp = XFS_IFORK_PTR(ip, whichfork); 4032 4033 if (!(ifp->if_flags & XFS_IFEXTENTS)) { 4034 error = xfs_iread_extents(NULL, ip, whichfork); 4035 if (error) 4036 return error; 4037 } 4038 4039 xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, &prev); 4040 end = bno + len; 4041 obno = bno; 4042 4043 while (bno < end && n < *nmap) { 4044 /* Reading past eof, act as though there's a hole up to end. */ 4045 if (eof) 4046 got.br_startoff = end; 4047 if (got.br_startoff > bno) { 4048 /* Reading in a hole. */ 4049 mval->br_startoff = bno; 4050 mval->br_startblock = HOLESTARTBLOCK; 4051 mval->br_blockcount = 4052 XFS_FILBLKS_MIN(len, got.br_startoff - bno); 4053 mval->br_state = XFS_EXT_NORM; 4054 bno += mval->br_blockcount; 4055 len -= mval->br_blockcount; 4056 mval++; 4057 n++; 4058 continue; 4059 } 4060 4061 /* set up the extent map to return. */ 4062 xfs_bmapi_trim_map(mval, &got, &bno, len, obno, end, n, flags); 4063 xfs_bmapi_update_map(&mval, &bno, &len, obno, end, &n, flags); 4064 4065 /* If we're done, stop now. */ 4066 if (bno >= end || n >= *nmap) 4067 break; 4068 4069 /* Else go on to the next record. */ 4070 if (++lastx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t)) 4071 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx), &got); 4072 else 4073 eof = 1; 4074 } 4075 *nmap = n; 4076 return 0; 4077} 4078 4079STATIC int 4080xfs_bmapi_reserve_delalloc( 4081 struct xfs_inode *ip, 4082 xfs_fileoff_t aoff, 4083 xfs_filblks_t len, 4084 struct xfs_bmbt_irec *got, 4085 struct xfs_bmbt_irec *prev, 4086 xfs_extnum_t *lastx, 4087 int eof) 4088{ 4089 struct xfs_mount *mp = ip->i_mount; 4090 struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); 4091 xfs_extlen_t alen; 4092 xfs_extlen_t indlen; 4093 char rt = XFS_IS_REALTIME_INODE(ip); 4094 xfs_extlen_t extsz; 4095 int error; 4096 4097 alen = XFS_FILBLKS_MIN(len, MAXEXTLEN); 4098 if (!eof) 4099 alen = XFS_FILBLKS_MIN(alen, got->br_startoff - aoff); 4100 4101 /* Figure out the extent size, adjust alen */ 4102 extsz = xfs_get_extsz_hint(ip); 4103 if (extsz) { 4104 /* 4105 * Make sure we don't exceed a single extent length when we 4106 * align the extent by reducing length we are going to 4107 * allocate by the maximum amount extent size aligment may 4108 * require. 4109 */ 4110 alen = XFS_FILBLKS_MIN(len, MAXEXTLEN - (2 * extsz - 1)); 4111 error = xfs_bmap_extsize_align(mp, got, prev, extsz, rt, eof, 4112 1, 0, &aoff, &alen); 4113 ASSERT(!error); 4114 } 4115 4116 if (rt) 4117 extsz = alen / mp->m_sb.sb_rextsize; 4118 4119 /* 4120 * Make a transaction-less quota reservation for delayed allocation 4121 * blocks. This number gets adjusted later. We return if we haven't 4122 * allocated blocks already inside this loop. 4123 */ 4124 error = xfs_trans_reserve_quota_nblks(NULL, ip, (long)alen, 0, 4125 rt ? XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS); 4126 if (error) 4127 return error; 4128 4129 /* 4130 * Split changing sb for alen and indlen since they could be coming 4131 * from different places. 4132 */ 4133 indlen = (xfs_extlen_t)xfs_bmap_worst_indlen(ip, alen); 4134 ASSERT(indlen > 0); 4135 4136 if (rt) { 4137 error = xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS, 4138 -((int64_t)extsz), 0); 4139 } else { 4140 error = xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, 4141 -((int64_t)alen), 0); 4142 } 4143 4144 if (error) 4145 goto out_unreserve_quota; 4146 4147 error = xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, 4148 -((int64_t)indlen), 0); 4149 if (error) 4150 goto out_unreserve_blocks; 4151 4152 4153 ip->i_delayed_blks += alen; 4154 4155 got->br_startoff = aoff; 4156 got->br_startblock = nullstartblock(indlen); 4157 got->br_blockcount = alen; 4158 got->br_state = XFS_EXT_NORM; 4159 xfs_bmap_add_extent_hole_delay(ip, lastx, got); 4160 4161 /* 4162 * Update our extent pointer, given that xfs_bmap_add_extent_hole_delay 4163 * might have merged it into one of the neighbouring ones. 4164 */ 4165 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *lastx), got); 4166 4167 ASSERT(got->br_startoff <= aoff); 4168 ASSERT(got->br_startoff + got->br_blockcount >= aoff + alen); 4169 ASSERT(isnullstartblock(got->br_startblock)); 4170 ASSERT(got->br_state == XFS_EXT_NORM); 4171 return 0; 4172 4173out_unreserve_blocks: 4174 if (rt) 4175 xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS, extsz, 0); 4176 else 4177 xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, alen, 0); 4178out_unreserve_quota: 4179 if (XFS_IS_QUOTA_ON(mp)) 4180 xfs_trans_unreserve_quota_nblks(NULL, ip, (long)alen, 0, rt ? 4181 XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS); 4182 return error; 4183} 4184 4185/* 4186 * Map file blocks to filesystem blocks, adding delayed allocations as needed. 4187 */ 4188int 4189xfs_bmapi_delay( 4190 struct xfs_inode *ip, /* incore inode */ 4191 xfs_fileoff_t bno, /* starting file offs. mapped */ 4192 xfs_filblks_t len, /* length to map in file */ 4193 struct xfs_bmbt_irec *mval, /* output: map values */ 4194 int *nmap, /* i/o: mval size/count */ 4195 int flags) /* XFS_BMAPI_... */ 4196{ 4197 struct xfs_mount *mp = ip->i_mount; 4198 struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); 4199 struct xfs_bmbt_irec got; /* current file extent record */ 4200 struct xfs_bmbt_irec prev; /* previous file extent record */ 4201 xfs_fileoff_t obno; /* old block number (offset) */ 4202 xfs_fileoff_t end; /* end of mapped file region */ 4203 xfs_extnum_t lastx; /* last useful extent number */ 4204 int eof; /* we've hit the end of extents */ 4205 int n = 0; /* current extent index */ 4206 int error = 0; 4207 4208 ASSERT(*nmap >= 1); 4209 ASSERT(*nmap <= XFS_BMAP_MAX_NMAP); 4210 ASSERT(!(flags & ~XFS_BMAPI_ENTIRE)); 4211 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 4212 4213 if (unlikely(XFS_TEST_ERROR( 4214 (XFS_IFORK_FORMAT(ip, XFS_DATA_FORK) != XFS_DINODE_FMT_EXTENTS && 4215 XFS_IFORK_FORMAT(ip, XFS_DATA_FORK) != XFS_DINODE_FMT_BTREE), 4216 mp, XFS_ERRTAG_BMAPIFORMAT, XFS_RANDOM_BMAPIFORMAT))) { 4217 XFS_ERROR_REPORT("xfs_bmapi_delay", XFS_ERRLEVEL_LOW, mp); 4218 return XFS_ERROR(EFSCORRUPTED); 4219 } 4220 4221 if (XFS_FORCED_SHUTDOWN(mp)) 4222 return XFS_ERROR(EIO); 4223 4224 XFS_STATS_INC(xs_blk_mapw); 4225 4226 if (!(ifp->if_flags & XFS_IFEXTENTS)) { 4227 error = xfs_iread_extents(NULL, ip, XFS_DATA_FORK); 4228 if (error) 4229 return error; 4230 } 4231 4232 xfs_bmap_search_extents(ip, bno, XFS_DATA_FORK, &eof, &lastx, &got, &prev); 4233 end = bno + len; 4234 obno = bno; 4235 4236 while (bno < end && n < *nmap) { 4237 if (eof || got.br_startoff > bno) { 4238 error = xfs_bmapi_reserve_delalloc(ip, bno, len, &got, 4239 &prev, &lastx, eof); 4240 if (error) { 4241 if (n == 0) { 4242 *nmap = 0; 4243 return error; 4244 } 4245 break; 4246 } 4247 } 4248 4249 /* set up the extent map to return. */ 4250 xfs_bmapi_trim_map(mval, &got, &bno, len, obno, end, n, flags); 4251 xfs_bmapi_update_map(&mval, &bno, &len, obno, end, &n, flags); 4252 4253 /* If we're done, stop now. */ 4254 if (bno >= end || n >= *nmap) 4255 break; 4256 4257 /* Else go on to the next record. */ 4258 prev = got; 4259 if (++lastx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t)) 4260 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx), &got); 4261 else 4262 eof = 1; 4263 } 4264 4265 *nmap = n; 4266 return 0; 4267} 4268 4269 4270int 4271__xfs_bmapi_allocate( 4272 struct xfs_bmalloca *bma) 4273{ 4274 struct xfs_mount *mp = bma->ip->i_mount; 4275 int whichfork = (bma->flags & XFS_BMAPI_ATTRFORK) ? 4276 XFS_ATTR_FORK : XFS_DATA_FORK; 4277 struct xfs_ifork *ifp = XFS_IFORK_PTR(bma->ip, whichfork); 4278 int tmp_logflags = 0; 4279 int error; 4280 4281 ASSERT(bma->length > 0); 4282 4283 /* 4284 * For the wasdelay case, we could also just allocate the stuff asked 4285 * for in this bmap call but that wouldn't be as good. 4286 */ 4287 if (bma->wasdel) { 4288 bma->length = (xfs_extlen_t)bma->got.br_blockcount; 4289 bma->offset = bma->got.br_startoff; 4290 if (bma->idx != NULLEXTNUM && bma->idx) { 4291 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma->idx - 1), 4292 &bma->prev); 4293 } 4294 } else { 4295 bma->length = XFS_FILBLKS_MIN(bma->length, MAXEXTLEN); 4296 if (!bma->eof) 4297 bma->length = XFS_FILBLKS_MIN(bma->length, 4298 bma->got.br_startoff - bma->offset); 4299 } 4300 4301 /* 4302 * Indicate if this is the first user data in the file, or just any 4303 * user data. 4304 */ 4305 if (!(bma->flags & XFS_BMAPI_METADATA)) { 4306 bma->userdata = (bma->offset == 0) ? 4307 XFS_ALLOC_INITIAL_USER_DATA : XFS_ALLOC_USERDATA; 4308 } 4309 4310 bma->minlen = (bma->flags & XFS_BMAPI_CONTIG) ? bma->length : 1; 4311 4312 /* 4313 * Only want to do the alignment at the eof if it is userdata and 4314 * allocation length is larger than a stripe unit. 4315 */ 4316 if (mp->m_dalign && bma->length >= mp->m_dalign && 4317 !(bma->flags & XFS_BMAPI_METADATA) && whichfork == XFS_DATA_FORK) { 4318 error = xfs_bmap_isaeof(bma, whichfork); 4319 if (error) 4320 return error; 4321 } 4322 4323 error = xfs_bmap_alloc(bma); 4324 if (error) 4325 return error; 4326 4327 if (bma->flist->xbf_low) 4328 bma->minleft = 0; 4329 if (bma->cur) 4330 bma->cur->bc_private.b.firstblock = *bma->firstblock; 4331 if (bma->blkno == NULLFSBLOCK) 4332 return 0; 4333 if ((ifp->if_flags & XFS_IFBROOT) && !bma->cur) { 4334 bma->cur = xfs_bmbt_init_cursor(mp, bma->tp, bma->ip, whichfork); 4335 bma->cur->bc_private.b.firstblock = *bma->firstblock; 4336 bma->cur->bc_private.b.flist = bma->flist; 4337 } 4338 /* 4339 * Bump the number of extents we've allocated 4340 * in this call. 4341 */ 4342 bma->nallocs++; 4343 4344 if (bma->cur) 4345 bma->cur->bc_private.b.flags = 4346 bma->wasdel ? XFS_BTCUR_BPRV_WASDEL : 0; 4347 4348 bma->got.br_startoff = bma->offset; 4349 bma->got.br_startblock = bma->blkno; 4350 bma->got.br_blockcount = bma->length; 4351 bma->got.br_state = XFS_EXT_NORM; 4352 4353 /* 4354 * A wasdelay extent has been initialized, so shouldn't be flagged 4355 * as unwritten. 4356 */ 4357 if (!bma->wasdel && (bma->flags & XFS_BMAPI_PREALLOC) && 4358 xfs_sb_version_hasextflgbit(&mp->m_sb)) 4359 bma->got.br_state = XFS_EXT_UNWRITTEN; 4360 4361 if (bma->wasdel) 4362 error = xfs_bmap_add_extent_delay_real(bma); 4363 else 4364 error = xfs_bmap_add_extent_hole_real(bma, whichfork); 4365 4366 bma->logflags |= tmp_logflags; 4367 if (error) 4368 return error; 4369 4370 /* 4371 * Update our extent pointer, given that xfs_bmap_add_extent_delay_real 4372 * or xfs_bmap_add_extent_hole_real might have merged it into one of 4373 * the neighbouring ones. 4374 */ 4375 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma->idx), &bma->got); 4376 4377 ASSERT(bma->got.br_startoff <= bma->offset); 4378 ASSERT(bma->got.br_startoff + bma->got.br_blockcount >= 4379 bma->offset + bma->length); 4380 ASSERT(bma->got.br_state == XFS_EXT_NORM || 4381 bma->got.br_state == XFS_EXT_UNWRITTEN); 4382 return 0; 4383} 4384 4385STATIC int 4386xfs_bmapi_convert_unwritten( 4387 struct xfs_bmalloca *bma, 4388 struct xfs_bmbt_irec *mval, 4389 xfs_filblks_t len, 4390 int flags) 4391{ 4392 int whichfork = (flags & XFS_BMAPI_ATTRFORK) ? 4393 XFS_ATTR_FORK : XFS_DATA_FORK; 4394 struct xfs_ifork *ifp = XFS_IFORK_PTR(bma->ip, whichfork); 4395 int tmp_logflags = 0; 4396 int error; 4397 4398 /* check if we need to do unwritten->real conversion */ 4399 if (mval->br_state == XFS_EXT_UNWRITTEN && 4400 (flags & XFS_BMAPI_PREALLOC)) 4401 return 0; 4402 4403 /* check if we need to do real->unwritten conversion */ 4404 if (mval->br_state == XFS_EXT_NORM && 4405 (flags & (XFS_BMAPI_PREALLOC | XFS_BMAPI_CONVERT)) != 4406 (XFS_BMAPI_PREALLOC | XFS_BMAPI_CONVERT)) 4407 return 0; 4408 4409 /* 4410 * Modify (by adding) the state flag, if writing. 4411 */ 4412 ASSERT(mval->br_blockcount <= len); 4413 if ((ifp->if_flags & XFS_IFBROOT) && !bma->cur) { 4414 bma->cur = xfs_bmbt_init_cursor(bma->ip->i_mount, bma->tp, 4415 bma->ip, whichfork); 4416 bma->cur->bc_private.b.firstblock = *bma->firstblock; 4417 bma->cur->bc_private.b.flist = bma->flist; 4418 } 4419 mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN) 4420 ? XFS_EXT_NORM : XFS_EXT_UNWRITTEN; 4421 4422 error = xfs_bmap_add_extent_unwritten_real(bma->tp, bma->ip, &bma->idx, 4423 &bma->cur, mval, bma->firstblock, bma->flist, 4424 &tmp_logflags); 4425 bma->logflags |= tmp_logflags; 4426 if (error) 4427 return error; 4428 4429 /* 4430 * Update our extent pointer, given that 4431 * xfs_bmap_add_extent_unwritten_real might have merged it into one 4432 * of the neighbouring ones. 4433 */ 4434 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma->idx), &bma->got); 4435 4436 /* 4437 * We may have combined previously unwritten space with written space, 4438 * so generate another request. 4439 */ 4440 if (mval->br_blockcount < len) 4441 return EAGAIN; 4442 return 0; 4443} 4444 4445/* 4446 * Map file blocks to filesystem blocks, and allocate blocks or convert the 4447 * extent state if necessary. Details behaviour is controlled by the flags 4448 * parameter. Only allocates blocks from a single allocation group, to avoid 4449 * locking problems. 4450 * 4451 * The returned value in "firstblock" from the first call in a transaction 4452 * must be remembered and presented to subsequent calls in "firstblock". 4453 * An upper bound for the number of blocks to be allocated is supplied to 4454 * the first call in "total"; if no allocation group has that many free 4455 * blocks then the call will fail (return NULLFSBLOCK in "firstblock"). 4456 */ 4457int 4458xfs_bmapi_write( 4459 struct xfs_trans *tp, /* transaction pointer */ 4460 struct xfs_inode *ip, /* incore inode */ 4461 xfs_fileoff_t bno, /* starting file offs. mapped */ 4462 xfs_filblks_t len, /* length to map in file */ 4463 int flags, /* XFS_BMAPI_... */ 4464 xfs_fsblock_t *firstblock, /* first allocated block 4465 controls a.g. for allocs */ 4466 xfs_extlen_t total, /* total blocks needed */ 4467 struct xfs_bmbt_irec *mval, /* output: map values */ 4468 int *nmap, /* i/o: mval size/count */ 4469 struct xfs_bmap_free *flist) /* i/o: list extents to free */ 4470{ 4471 struct xfs_mount *mp = ip->i_mount; 4472 struct xfs_ifork *ifp; 4473 struct xfs_bmalloca bma = { NULL }; /* args for xfs_bmap_alloc */ 4474 xfs_fileoff_t end; /* end of mapped file region */ 4475 int eof; /* after the end of extents */ 4476 int error; /* error return */ 4477 int n; /* current extent index */ 4478 xfs_fileoff_t obno; /* old block number (offset) */ 4479 int whichfork; /* data or attr fork */ 4480 char inhole; /* current location is hole in file */ 4481 char wasdelay; /* old extent was delayed */ 4482 4483#ifdef DEBUG 4484 xfs_fileoff_t orig_bno; /* original block number value */ 4485 int orig_flags; /* original flags arg value */ 4486 xfs_filblks_t orig_len; /* original value of len arg */ 4487 struct xfs_bmbt_irec *orig_mval; /* original value of mval */ 4488 int orig_nmap; /* original value of *nmap */ 4489 4490 orig_bno = bno; 4491 orig_len = len; 4492 orig_flags = flags; 4493 orig_mval = mval; 4494 orig_nmap = *nmap; 4495#endif 4496 whichfork = (flags & XFS_BMAPI_ATTRFORK) ? 4497 XFS_ATTR_FORK : XFS_DATA_FORK; 4498 4499 ASSERT(*nmap >= 1); 4500 ASSERT(*nmap <= XFS_BMAP_MAX_NMAP); 4501 ASSERT(!(flags & XFS_BMAPI_IGSTATE)); 4502 ASSERT(tp != NULL); 4503 ASSERT(len > 0); 4504 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL); 4505 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 4506 4507 if (unlikely(XFS_TEST_ERROR( 4508 (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && 4509 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE), 4510 mp, XFS_ERRTAG_BMAPIFORMAT, XFS_RANDOM_BMAPIFORMAT))) { 4511 XFS_ERROR_REPORT("xfs_bmapi_write", XFS_ERRLEVEL_LOW, mp); 4512 return XFS_ERROR(EFSCORRUPTED); 4513 } 4514 4515 if (XFS_FORCED_SHUTDOWN(mp)) 4516 return XFS_ERROR(EIO); 4517 4518 ifp = XFS_IFORK_PTR(ip, whichfork); 4519 4520 XFS_STATS_INC(xs_blk_mapw); 4521 4522 if (*firstblock == NULLFSBLOCK) { 4523 if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE) 4524 bma.minleft = be16_to_cpu(ifp->if_broot->bb_level) + 1; 4525 else 4526 bma.minleft = 1; 4527 } else { 4528 bma.minleft = 0; 4529 } 4530 4531 if (!(ifp->if_flags & XFS_IFEXTENTS)) { 4532 error = xfs_iread_extents(tp, ip, whichfork); 4533 if (error) 4534 goto error0; 4535 } 4536 4537 xfs_bmap_search_extents(ip, bno, whichfork, &eof, &bma.idx, &bma.got, 4538 &bma.prev); 4539 n = 0; 4540 end = bno + len; 4541 obno = bno; 4542 4543 bma.tp = tp; 4544 bma.ip = ip; 4545 bma.total = total; 4546 bma.userdata = 0; 4547 bma.flist = flist; 4548 bma.firstblock = firstblock; 4549 4550 if (flags & XFS_BMAPI_STACK_SWITCH) 4551 bma.stack_switch = 1; 4552 4553 while (bno < end && n < *nmap) { 4554 inhole = eof || bma.got.br_startoff > bno; 4555 wasdelay = !inhole && isnullstartblock(bma.got.br_startblock); 4556 4557 /* 4558 * First, deal with the hole before the allocated space 4559 * that we found, if any. 4560 */ 4561 if (inhole || wasdelay) { 4562 bma.eof = eof; 4563 bma.conv = !!(flags & XFS_BMAPI_CONVERT); 4564 bma.wasdel = wasdelay; 4565 bma.offset = bno; 4566 bma.flags = flags; 4567 4568 /* 4569 * There's a 32/64 bit type mismatch between the 4570 * allocation length request (which can be 64 bits in 4571 * length) and the bma length request, which is 4572 * xfs_extlen_t and therefore 32 bits. Hence we have to 4573 * check for 32-bit overflows and handle them here. 4574 */ 4575 if (len > (xfs_filblks_t)MAXEXTLEN) 4576 bma.length = MAXEXTLEN; 4577 else 4578 bma.length = len; 4579 4580 ASSERT(len > 0); 4581 ASSERT(bma.length > 0); 4582 error = xfs_bmapi_allocate(&bma); 4583 if (error) 4584 goto error0; 4585 if (bma.blkno == NULLFSBLOCK) 4586 break; 4587 } 4588 4589 /* Deal with the allocated space we found. */ 4590 xfs_bmapi_trim_map(mval, &bma.got, &bno, len, obno, 4591 end, n, flags); 4592 4593 /* Execute unwritten extent conversion if necessary */ 4594 error = xfs_bmapi_convert_unwritten(&bma, mval, len, flags); 4595 if (error == EAGAIN) 4596 continue; 4597 if (error) 4598 goto error0; 4599 4600 /* update the extent map to return */ 4601 xfs_bmapi_update_map(&mval, &bno, &len, obno, end, &n, flags); 4602 4603 /* 4604 * If we're done, stop now. Stop when we've allocated 4605 * XFS_BMAP_MAX_NMAP extents no matter what. Otherwise 4606 * the transaction may get too big. 4607 */ 4608 if (bno >= end || n >= *nmap || bma.nallocs >= *nmap) 4609 break; 4610 4611 /* Else go on to the next record. */ 4612 bma.prev = bma.got; 4613 if (++bma.idx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t)) { 4614 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma.idx), 4615 &bma.got); 4616 } else 4617 eof = 1; 4618 } 4619 *nmap = n; 4620 4621 /* 4622 * Transform from btree to extents, give it cur. 4623 */ 4624 if (xfs_bmap_wants_extents(ip, whichfork)) { 4625 int tmp_logflags = 0; 4626 4627 ASSERT(bma.cur); 4628 error = xfs_bmap_btree_to_extents(tp, ip, bma.cur, 4629 &tmp_logflags, whichfork); 4630 bma.logflags |= tmp_logflags; 4631 if (error) 4632 goto error0; 4633 } 4634 4635 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE || 4636 XFS_IFORK_NEXTENTS(ip, whichfork) > 4637 XFS_IFORK_MAXEXT(ip, whichfork)); 4638 error = 0; 4639error0: 4640 /* 4641 * Log everything. Do this after conversion, there's no point in 4642 * logging the extent records if we've converted to btree format. 4643 */ 4644 if ((bma.logflags & xfs_ilog_fext(whichfork)) && 4645 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) 4646 bma.logflags &= ~xfs_ilog_fext(whichfork); 4647 else if ((bma.logflags & xfs_ilog_fbroot(whichfork)) && 4648 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE) 4649 bma.logflags &= ~xfs_ilog_fbroot(whichfork); 4650 /* 4651 * Log whatever the flags say, even if error. Otherwise we might miss 4652 * detecting a case where the data is changed, there's an error, 4653 * and it's not logged so we don't shutdown when we should. 4654 */ 4655 if (bma.logflags) 4656 xfs_trans_log_inode(tp, ip, bma.logflags); 4657 4658 if (bma.cur) { 4659 if (!error) { 4660 ASSERT(*firstblock == NULLFSBLOCK || 4661 XFS_FSB_TO_AGNO(mp, *firstblock) == 4662 XFS_FSB_TO_AGNO(mp, 4663 bma.cur->bc_private.b.firstblock) || 4664 (flist->xbf_low && 4665 XFS_FSB_TO_AGNO(mp, *firstblock) < 4666 XFS_FSB_TO_AGNO(mp, 4667 bma.cur->bc_private.b.firstblock))); 4668 *firstblock = bma.cur->bc_private.b.firstblock; 4669 } 4670 xfs_btree_del_cursor(bma.cur, 4671 error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); 4672 } 4673 if (!error) 4674 xfs_bmap_validate_ret(orig_bno, orig_len, orig_flags, orig_mval, 4675 orig_nmap, *nmap); 4676 return error; 4677} 4678 4679/* 4680 * Called by xfs_bmapi to update file extent records and the btree 4681 * after removing space (or undoing a delayed allocation). 4682 */ 4683STATIC int /* error */ 4684xfs_bmap_del_extent( 4685 xfs_inode_t *ip, /* incore inode pointer */ 4686 xfs_trans_t *tp, /* current transaction pointer */ 4687 xfs_extnum_t *idx, /* extent number to update/delete */ 4688 xfs_bmap_free_t *flist, /* list of extents to be freed */ 4689 xfs_btree_cur_t *cur, /* if null, not a btree */ 4690 xfs_bmbt_irec_t *del, /* data to remove from extents */ 4691 int *logflagsp, /* inode logging flags */ 4692 int whichfork) /* data or attr fork */ 4693{ 4694 xfs_filblks_t da_new; /* new delay-alloc indirect blocks */ 4695 xfs_filblks_t da_old; /* old delay-alloc indirect blocks */ 4696 xfs_fsblock_t del_endblock=0; /* first block past del */ 4697 xfs_fileoff_t del_endoff; /* first offset past del */ 4698 int delay; /* current block is delayed allocated */ 4699 int do_fx; /* free extent at end of routine */ 4700 xfs_bmbt_rec_host_t *ep; /* current extent entry pointer */ 4701 int error; /* error return value */ 4702 int flags; /* inode logging flags */ 4703 xfs_bmbt_irec_t got; /* current extent entry */ 4704 xfs_fileoff_t got_endoff; /* first offset past got */ 4705 int i; /* temp state */ 4706 xfs_ifork_t *ifp; /* inode fork pointer */ 4707 xfs_mount_t *mp; /* mount structure */ 4708 xfs_filblks_t nblks; /* quota/sb block count */ 4709 xfs_bmbt_irec_t new; /* new record to be inserted */ 4710 /* REFERENCED */ 4711 uint qfield; /* quota field to update */ 4712 xfs_filblks_t temp; /* for indirect length calculations */ 4713 xfs_filblks_t temp2; /* for indirect length calculations */ 4714 int state = 0; 4715 4716 XFS_STATS_INC(xs_del_exlist); 4717 4718 if (whichfork == XFS_ATTR_FORK) 4719 state |= BMAP_ATTRFORK; 4720 4721 mp = ip->i_mount; 4722 ifp = XFS_IFORK_PTR(ip, whichfork); 4723 ASSERT((*idx >= 0) && (*idx < ifp->if_bytes / 4724 (uint)sizeof(xfs_bmbt_rec_t))); 4725 ASSERT(del->br_blockcount > 0); 4726 ep = xfs_iext_get_ext(ifp, *idx); 4727 xfs_bmbt_get_all(ep, &got); 4728 ASSERT(got.br_startoff <= del->br_startoff); 4729 del_endoff = del->br_startoff + del->br_blockcount; 4730 got_endoff = got.br_startoff + got.br_blockcount; 4731 ASSERT(got_endoff >= del_endoff); 4732 delay = isnullstartblock(got.br_startblock); 4733 ASSERT(isnullstartblock(del->br_startblock) == delay); 4734 flags = 0; 4735 qfield = 0; 4736 error = 0; 4737 /* 4738 * If deleting a real allocation, must free up the disk space. 4739 */ 4740 if (!delay) { 4741 flags = XFS_ILOG_CORE; 4742 /* 4743 * Realtime allocation. Free it and record di_nblocks update. 4744 */ 4745 if (whichfork == XFS_DATA_FORK && XFS_IS_REALTIME_INODE(ip)) { 4746 xfs_fsblock_t bno; 4747 xfs_filblks_t len; 4748 4749 ASSERT(do_mod(del->br_blockcount, 4750 mp->m_sb.sb_rextsize) == 0); 4751 ASSERT(do_mod(del->br_startblock, 4752 mp->m_sb.sb_rextsize) == 0); 4753 bno = del->br_startblock; 4754 len = del->br_blockcount; 4755 do_div(bno, mp->m_sb.sb_rextsize); 4756 do_div(len, mp->m_sb.sb_rextsize); 4757 error = xfs_rtfree_extent(tp, bno, (xfs_extlen_t)len); 4758 if (error) 4759 goto done; 4760 do_fx = 0; 4761 nblks = len * mp->m_sb.sb_rextsize; 4762 qfield = XFS_TRANS_DQ_RTBCOUNT; 4763 } 4764 /* 4765 * Ordinary allocation. 4766 */ 4767 else { 4768 do_fx = 1; 4769 nblks = del->br_blockcount; 4770 qfield = XFS_TRANS_DQ_BCOUNT; 4771 } 4772 /* 4773 * Set up del_endblock and cur for later. 4774 */ 4775 del_endblock = del->br_startblock + del->br_blockcount; 4776 if (cur) { 4777 if ((error = xfs_bmbt_lookup_eq(cur, got.br_startoff, 4778 got.br_startblock, got.br_blockcount, 4779 &i))) 4780 goto done; 4781 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 4782 } 4783 da_old = da_new = 0; 4784 } else { 4785 da_old = startblockval(got.br_startblock); 4786 da_new = 0; 4787 nblks = 0; 4788 do_fx = 0; 4789 } 4790 /* 4791 * Set flag value to use in switch statement. 4792 * Left-contig is 2, right-contig is 1. 4793 */ 4794 switch (((got.br_startoff == del->br_startoff) << 1) | 4795 (got_endoff == del_endoff)) { 4796 case 3: 4797 /* 4798 * Matches the whole extent. Delete the entry. 4799 */ 4800 xfs_iext_remove(ip, *idx, 1, 4801 whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0); 4802 --*idx; 4803 if (delay) 4804 break; 4805 4806 XFS_IFORK_NEXT_SET(ip, whichfork, 4807 XFS_IFORK_NEXTENTS(ip, whichfork) - 1); 4808 flags |= XFS_ILOG_CORE; 4809 if (!cur) { 4810 flags |= xfs_ilog_fext(whichfork); 4811 break; 4812 } 4813 if ((error = xfs_btree_delete(cur, &i))) 4814 goto done; 4815 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 4816 break; 4817 4818 case 2: 4819 /* 4820 * Deleting the first part of the extent. 4821 */ 4822 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 4823 xfs_bmbt_set_startoff(ep, del_endoff); 4824 temp = got.br_blockcount - del->br_blockcount; 4825 xfs_bmbt_set_blockcount(ep, temp); 4826 if (delay) { 4827 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), 4828 da_old); 4829 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); 4830 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 4831 da_new = temp; 4832 break; 4833 } 4834 xfs_bmbt_set_startblock(ep, del_endblock); 4835 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 4836 if (!cur) { 4837 flags |= xfs_ilog_fext(whichfork); 4838 break; 4839 } 4840 if ((error = xfs_bmbt_update(cur, del_endoff, del_endblock, 4841 got.br_blockcount - del->br_blockcount, 4842 got.br_state))) 4843 goto done; 4844 break; 4845 4846 case 1: 4847 /* 4848 * Deleting the last part of the extent. 4849 */ 4850 temp = got.br_blockcount - del->br_blockcount; 4851 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 4852 xfs_bmbt_set_blockcount(ep, temp); 4853 if (delay) { 4854 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), 4855 da_old); 4856 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); 4857 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 4858 da_new = temp; 4859 break; 4860 } 4861 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 4862 if (!cur) { 4863 flags |= xfs_ilog_fext(whichfork); 4864 break; 4865 } 4866 if ((error = xfs_bmbt_update(cur, got.br_startoff, 4867 got.br_startblock, 4868 got.br_blockcount - del->br_blockcount, 4869 got.br_state))) 4870 goto done; 4871 break; 4872 4873 case 0: 4874 /* 4875 * Deleting the middle of the extent. 4876 */ 4877 temp = del->br_startoff - got.br_startoff; 4878 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_); 4879 xfs_bmbt_set_blockcount(ep, temp); 4880 new.br_startoff = del_endoff; 4881 temp2 = got_endoff - del_endoff; 4882 new.br_blockcount = temp2; 4883 new.br_state = got.br_state; 4884 if (!delay) { 4885 new.br_startblock = del_endblock; 4886 flags |= XFS_ILOG_CORE; 4887 if (cur) { 4888 if ((error = xfs_bmbt_update(cur, 4889 got.br_startoff, 4890 got.br_startblock, temp, 4891 got.br_state))) 4892 goto done; 4893 if ((error = xfs_btree_increment(cur, 0, &i))) 4894 goto done; 4895 cur->bc_rec.b = new; 4896 error = xfs_btree_insert(cur, &i); 4897 if (error && error != ENOSPC) 4898 goto done; 4899 /* 4900 * If get no-space back from btree insert, 4901 * it tried a split, and we have a zero 4902 * block reservation. 4903 * Fix up our state and return the error. 4904 */ 4905 if (error == ENOSPC) { 4906 /* 4907 * Reset the cursor, don't trust 4908 * it after any insert operation. 4909 */ 4910 if ((error = xfs_bmbt_lookup_eq(cur, 4911 got.br_startoff, 4912 got.br_startblock, 4913 temp, &i))) 4914 goto done; 4915 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 4916 /* 4917 * Update the btree record back 4918 * to the original value. 4919 */ 4920 if ((error = xfs_bmbt_update(cur, 4921 got.br_startoff, 4922 got.br_startblock, 4923 got.br_blockcount, 4924 got.br_state))) 4925 goto done; 4926 /* 4927 * Reset the extent record back 4928 * to the original value. 4929 */ 4930 xfs_bmbt_set_blockcount(ep, 4931 got.br_blockcount); 4932 flags = 0; 4933 error = XFS_ERROR(ENOSPC); 4934 goto done; 4935 } 4936 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 4937 } else 4938 flags |= xfs_ilog_fext(whichfork); 4939 XFS_IFORK_NEXT_SET(ip, whichfork, 4940 XFS_IFORK_NEXTENTS(ip, whichfork) + 1); 4941 } else { 4942 ASSERT(whichfork == XFS_DATA_FORK); 4943 temp = xfs_bmap_worst_indlen(ip, temp); 4944 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); 4945 temp2 = xfs_bmap_worst_indlen(ip, temp2); 4946 new.br_startblock = nullstartblock((int)temp2); 4947 da_new = temp + temp2; 4948 while (da_new > da_old) { 4949 if (temp) { 4950 temp--; 4951 da_new--; 4952 xfs_bmbt_set_startblock(ep, 4953 nullstartblock((int)temp)); 4954 } 4955 if (da_new == da_old) 4956 break; 4957 if (temp2) { 4958 temp2--; 4959 da_new--; 4960 new.br_startblock = 4961 nullstartblock((int)temp2); 4962 } 4963 } 4964 } 4965 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); 4966 xfs_iext_insert(ip, *idx + 1, 1, &new, state); 4967 ++*idx; 4968 break; 4969 } 4970 /* 4971 * If we need to, add to list of extents to delete. 4972 */ 4973 if (do_fx) 4974 xfs_bmap_add_free(del->br_startblock, del->br_blockcount, flist, 4975 mp); 4976 /* 4977 * Adjust inode # blocks in the file. 4978 */ 4979 if (nblks) 4980 ip->i_d.di_nblocks -= nblks; 4981 /* 4982 * Adjust quota data. 4983 */ 4984 if (qfield) 4985 xfs_trans_mod_dquot_byino(tp, ip, qfield, (long)-nblks); 4986 4987 /* 4988 * Account for change in delayed indirect blocks. 4989 * Nothing to do for disk quota accounting here. 4990 */ 4991 ASSERT(da_old >= da_new); 4992 if (da_old > da_new) { 4993 xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, 4994 (int64_t)(da_old - da_new), 0); 4995 } 4996done: 4997 *logflagsp = flags; 4998 return error; 4999} 5000 5001/* 5002 * Unmap (remove) blocks from a file. 5003 * If nexts is nonzero then the number of extents to remove is limited to 5004 * that value. If not all extents in the block range can be removed then 5005 * *done is set. 5006 */ 5007int /* error */ 5008xfs_bunmapi( 5009 xfs_trans_t *tp, /* transaction pointer */ 5010 struct xfs_inode *ip, /* incore inode */ 5011 xfs_fileoff_t bno, /* starting offset to unmap */ 5012 xfs_filblks_t len, /* length to unmap in file */ 5013 int flags, /* misc flags */ 5014 xfs_extnum_t nexts, /* number of extents max */ 5015 xfs_fsblock_t *firstblock, /* first allocated block 5016 controls a.g. for allocs */ 5017 xfs_bmap_free_t *flist, /* i/o: list extents to free */ 5018 int *done) /* set if not done yet */ 5019{ 5020 xfs_btree_cur_t *cur; /* bmap btree cursor */ 5021 xfs_bmbt_irec_t del; /* extent being deleted */ 5022 int eof; /* is deleting at eof */ 5023 xfs_bmbt_rec_host_t *ep; /* extent record pointer */ 5024 int error; /* error return value */ 5025 xfs_extnum_t extno; /* extent number in list */ 5026 xfs_bmbt_irec_t got; /* current extent record */ 5027 xfs_ifork_t *ifp; /* inode fork pointer */ 5028 int isrt; /* freeing in rt area */ 5029 xfs_extnum_t lastx; /* last extent index used */ 5030 int logflags; /* transaction logging flags */ 5031 xfs_extlen_t mod; /* rt extent offset */ 5032 xfs_mount_t *mp; /* mount structure */ 5033 xfs_extnum_t nextents; /* number of file extents */ 5034 xfs_bmbt_irec_t prev; /* previous extent record */ 5035 xfs_fileoff_t start; /* first file offset deleted */ 5036 int tmp_logflags; /* partial logging flags */ 5037 int wasdel; /* was a delayed alloc extent */ 5038 int whichfork; /* data or attribute fork */ 5039 xfs_fsblock_t sum; 5040 5041 trace_xfs_bunmap(ip, bno, len, flags, _RET_IP_); 5042 5043 whichfork = (flags & XFS_BMAPI_ATTRFORK) ? 5044 XFS_ATTR_FORK : XFS_DATA_FORK; 5045 ifp = XFS_IFORK_PTR(ip, whichfork); 5046 if (unlikely( 5047 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && 5048 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)) { 5049 XFS_ERROR_REPORT("xfs_bunmapi", XFS_ERRLEVEL_LOW, 5050 ip->i_mount); 5051 return XFS_ERROR(EFSCORRUPTED); 5052 } 5053 mp = ip->i_mount; 5054 if (XFS_FORCED_SHUTDOWN(mp)) 5055 return XFS_ERROR(EIO); 5056 5057 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 5058 ASSERT(len > 0); 5059 ASSERT(nexts >= 0); 5060 5061 if (!(ifp->if_flags & XFS_IFEXTENTS) && 5062 (error = xfs_iread_extents(tp, ip, whichfork))) 5063 return error; 5064 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 5065 if (nextents == 0) { 5066 *done = 1; 5067 return 0; 5068 } 5069 XFS_STATS_INC(xs_blk_unmap); 5070 isrt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip); 5071 start = bno; 5072 bno = start + len - 1; 5073 ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, 5074 &prev); 5075 5076 /* 5077 * Check to see if the given block number is past the end of the 5078 * file, back up to the last block if so... 5079 */ 5080 if (eof) { 5081 ep = xfs_iext_get_ext(ifp, --lastx); 5082 xfs_bmbt_get_all(ep, &got); 5083 bno = got.br_startoff + got.br_blockcount - 1; 5084 } 5085 logflags = 0; 5086 if (ifp->if_flags & XFS_IFBROOT) { 5087 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE); 5088 cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); 5089 cur->bc_private.b.firstblock = *firstblock; 5090 cur->bc_private.b.flist = flist; 5091 cur->bc_private.b.flags = 0; 5092 } else 5093 cur = NULL; 5094 5095 if (isrt) { 5096 /* 5097 * Synchronize by locking the bitmap inode. 5098 */ 5099 xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL); 5100 xfs_trans_ijoin(tp, mp->m_rbmip, XFS_ILOCK_EXCL); 5101 } 5102 5103 extno = 0; 5104 while (bno != (xfs_fileoff_t)-1 && bno >= start && lastx >= 0 && 5105 (nexts == 0 || extno < nexts)) { 5106 /* 5107 * Is the found extent after a hole in which bno lives? 5108 * Just back up to the previous extent, if so. 5109 */ 5110 if (got.br_startoff > bno) { 5111 if (--lastx < 0) 5112 break; 5113 ep = xfs_iext_get_ext(ifp, lastx); 5114 xfs_bmbt_get_all(ep, &got); 5115 } 5116 /* 5117 * Is the last block of this extent before the range 5118 * we're supposed to delete? If so, we're done. 5119 */ 5120 bno = XFS_FILEOFF_MIN(bno, 5121 got.br_startoff + got.br_blockcount - 1); 5122 if (bno < start) 5123 break; 5124 /* 5125 * Then deal with the (possibly delayed) allocated space 5126 * we found. 5127 */ 5128 ASSERT(ep != NULL); 5129 del = got; 5130 wasdel = isnullstartblock(del.br_startblock); 5131 if (got.br_startoff < start) { 5132 del.br_startoff = start; 5133 del.br_blockcount -= start - got.br_startoff; 5134 if (!wasdel) 5135 del.br_startblock += start - got.br_startoff; 5136 } 5137 if (del.br_startoff + del.br_blockcount > bno + 1) 5138 del.br_blockcount = bno + 1 - del.br_startoff; 5139 sum = del.br_startblock + del.br_blockcount; 5140 if (isrt && 5141 (mod = do_mod(sum, mp->m_sb.sb_rextsize))) { 5142 /* 5143 * Realtime extent not lined up at the end. 5144 * The extent could have been split into written 5145 * and unwritten pieces, or we could just be 5146 * unmapping part of it. But we can't really 5147 * get rid of part of a realtime extent. 5148 */ 5149 if (del.br_state == XFS_EXT_UNWRITTEN || 5150 !xfs_sb_version_hasextflgbit(&mp->m_sb)) { 5151 /* 5152 * This piece is unwritten, or we're not 5153 * using unwritten extents. Skip over it. 5154 */ 5155 ASSERT(bno >= mod); 5156 bno -= mod > del.br_blockcount ? 5157 del.br_blockcount : mod; 5158 if (bno < got.br_startoff) { 5159 if (--lastx >= 0) 5160 xfs_bmbt_get_all(xfs_iext_get_ext( 5161 ifp, lastx), &got); 5162 } 5163 continue; 5164 } 5165 /* 5166 * It's written, turn it unwritten. 5167 * This is better than zeroing it. 5168 */ 5169 ASSERT(del.br_state == XFS_EXT_NORM); 5170 ASSERT(xfs_trans_get_block_res(tp) > 0); 5171 /* 5172 * If this spans a realtime extent boundary, 5173 * chop it back to the start of the one we end at. 5174 */ 5175 if (del.br_blockcount > mod) { 5176 del.br_startoff += del.br_blockcount - mod; 5177 del.br_startblock += del.br_blockcount - mod; 5178 del.br_blockcount = mod; 5179 } 5180 del.br_state = XFS_EXT_UNWRITTEN; 5181 error = xfs_bmap_add_extent_unwritten_real(tp, ip, 5182 &lastx, &cur, &del, firstblock, flist, 5183 &logflags); 5184 if (error) 5185 goto error0; 5186 goto nodelete; 5187 } 5188 if (isrt && (mod = do_mod(del.br_startblock, mp->m_sb.sb_rextsize))) { 5189 /* 5190 * Realtime extent is lined up at the end but not 5191 * at the front. We'll get rid of full extents if 5192 * we can. 5193 */ 5194 mod = mp->m_sb.sb_rextsize - mod; 5195 if (del.br_blockcount > mod) { 5196 del.br_blockcount -= mod; 5197 del.br_startoff += mod; 5198 del.br_startblock += mod; 5199 } else if ((del.br_startoff == start && 5200 (del.br_state == XFS_EXT_UNWRITTEN || 5201 xfs_trans_get_block_res(tp) == 0)) || 5202 !xfs_sb_version_hasextflgbit(&mp->m_sb)) { 5203 /* 5204 * Can't make it unwritten. There isn't 5205 * a full extent here so just skip it. 5206 */ 5207 ASSERT(bno >= del.br_blockcount); 5208 bno -= del.br_blockcount; 5209 if (got.br_startoff > bno) { 5210 if (--lastx >= 0) { 5211 ep = xfs_iext_get_ext(ifp, 5212 lastx); 5213 xfs_bmbt_get_all(ep, &got); 5214 } 5215 } 5216 continue; 5217 } else if (del.br_state == XFS_EXT_UNWRITTEN) { 5218 /* 5219 * This one is already unwritten. 5220 * It must have a written left neighbor. 5221 * Unwrite the killed part of that one and 5222 * try again. 5223 */ 5224 ASSERT(lastx > 0); 5225 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, 5226 lastx - 1), &prev); 5227 ASSERT(prev.br_state == XFS_EXT_NORM); 5228 ASSERT(!isnullstartblock(prev.br_startblock)); 5229 ASSERT(del.br_startblock == 5230 prev.br_startblock + prev.br_blockcount); 5231 if (prev.br_startoff < start) { 5232 mod = start - prev.br_startoff; 5233 prev.br_blockcount -= mod; 5234 prev.br_startblock += mod; 5235 prev.br_startoff = start; 5236 } 5237 prev.br_state = XFS_EXT_UNWRITTEN; 5238 lastx--; 5239 error = xfs_bmap_add_extent_unwritten_real(tp, 5240 ip, &lastx, &cur, &prev, 5241 firstblock, flist, &logflags); 5242 if (error) 5243 goto error0; 5244 goto nodelete; 5245 } else { 5246 ASSERT(del.br_state == XFS_EXT_NORM); 5247 del.br_state = XFS_EXT_UNWRITTEN; 5248 error = xfs_bmap_add_extent_unwritten_real(tp, 5249 ip, &lastx, &cur, &del, 5250 firstblock, flist, &logflags); 5251 if (error) 5252 goto error0; 5253 goto nodelete; 5254 } 5255 } 5256 if (wasdel) { 5257 ASSERT(startblockval(del.br_startblock) > 0); 5258 /* Update realtime/data freespace, unreserve quota */ 5259 if (isrt) { 5260 xfs_filblks_t rtexts; 5261 5262 rtexts = XFS_FSB_TO_B(mp, del.br_blockcount); 5263 do_div(rtexts, mp->m_sb.sb_rextsize); 5264 xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS, 5265 (int64_t)rtexts, 0); 5266 (void)xfs_trans_reserve_quota_nblks(NULL, 5267 ip, -((long)del.br_blockcount), 0, 5268 XFS_QMOPT_RES_RTBLKS); 5269 } else { 5270 xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, 5271 (int64_t)del.br_blockcount, 0); 5272 (void)xfs_trans_reserve_quota_nblks(NULL, 5273 ip, -((long)del.br_blockcount), 0, 5274 XFS_QMOPT_RES_REGBLKS); 5275 } 5276 ip->i_delayed_blks -= del.br_blockcount; 5277 if (cur) 5278 cur->bc_private.b.flags |= 5279 XFS_BTCUR_BPRV_WASDEL; 5280 } else if (cur) 5281 cur->bc_private.b.flags &= ~XFS_BTCUR_BPRV_WASDEL; 5282 /* 5283 * If it's the case where the directory code is running 5284 * with no block reservation, and the deleted block is in 5285 * the middle of its extent, and the resulting insert 5286 * of an extent would cause transformation to btree format, 5287 * then reject it. The calling code will then swap 5288 * blocks around instead. 5289 * We have to do this now, rather than waiting for the 5290 * conversion to btree format, since the transaction 5291 * will be dirty. 5292 */ 5293 if (!wasdel && xfs_trans_get_block_res(tp) == 0 && 5294 XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS && 5295 XFS_IFORK_NEXTENTS(ip, whichfork) >= /* Note the >= */ 5296 XFS_IFORK_MAXEXT(ip, whichfork) && 5297 del.br_startoff > got.br_startoff && 5298 del.br_startoff + del.br_blockcount < 5299 got.br_startoff + got.br_blockcount) { 5300 error = XFS_ERROR(ENOSPC); 5301 goto error0; 5302 } 5303 error = xfs_bmap_del_extent(ip, tp, &lastx, flist, cur, &del, 5304 &tmp_logflags, whichfork); 5305 logflags |= tmp_logflags; 5306 if (error) 5307 goto error0; 5308 bno = del.br_startoff - 1; 5309nodelete: 5310 /* 5311 * If not done go on to the next (previous) record. 5312 */ 5313 if (bno != (xfs_fileoff_t)-1 && bno >= start) { 5314 if (lastx >= 0) { 5315 ep = xfs_iext_get_ext(ifp, lastx); 5316 if (xfs_bmbt_get_startoff(ep) > bno) { 5317 if (--lastx >= 0) 5318 ep = xfs_iext_get_ext(ifp, 5319 lastx); 5320 } 5321 xfs_bmbt_get_all(ep, &got); 5322 } 5323 extno++; 5324 } 5325 } 5326 *done = bno == (xfs_fileoff_t)-1 || bno < start || lastx < 0; 5327 5328 /* 5329 * Convert to a btree if necessary. 5330 */ 5331 if (xfs_bmap_needs_btree(ip, whichfork)) { 5332 ASSERT(cur == NULL); 5333 error = xfs_bmap_extents_to_btree(tp, ip, firstblock, flist, 5334 &cur, 0, &tmp_logflags, whichfork); 5335 logflags |= tmp_logflags; 5336 if (error) 5337 goto error0; 5338 } 5339 /* 5340 * transform from btree to extents, give it cur 5341 */ 5342 else if (xfs_bmap_wants_extents(ip, whichfork)) { 5343 ASSERT(cur != NULL); 5344 error = xfs_bmap_btree_to_extents(tp, ip, cur, &tmp_logflags, 5345 whichfork); 5346 logflags |= tmp_logflags; 5347 if (error) 5348 goto error0; 5349 } 5350 /* 5351 * transform from extents to local? 5352 */ 5353 error = 0; 5354error0: 5355 /* 5356 * Log everything. Do this after conversion, there's no point in 5357 * logging the extent records if we've converted to btree format. 5358 */ 5359 if ((logflags & xfs_ilog_fext(whichfork)) && 5360 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) 5361 logflags &= ~xfs_ilog_fext(whichfork); 5362 else if ((logflags & xfs_ilog_fbroot(whichfork)) && 5363 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE) 5364 logflags &= ~xfs_ilog_fbroot(whichfork); 5365 /* 5366 * Log inode even in the error case, if the transaction 5367 * is dirty we'll need to shut down the filesystem. 5368 */ 5369 if (logflags) 5370 xfs_trans_log_inode(tp, ip, logflags); 5371 if (cur) { 5372 if (!error) { 5373 *firstblock = cur->bc_private.b.firstblock; 5374 cur->bc_private.b.allocated = 0; 5375 } 5376 xfs_btree_del_cursor(cur, 5377 error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); 5378 } 5379 return error; 5380} 5381 5382/* 5383 * Shift extent records to the left to cover a hole. 5384 * 5385 * The maximum number of extents to be shifted in a single operation 5386 * is @num_exts, and @current_ext keeps track of the current extent 5387 * index we have shifted. @offset_shift_fsb is the length by which each 5388 * extent is shifted. If there is no hole to shift the extents 5389 * into, this will be considered invalid operation and we abort immediately. 5390 */ 5391int 5392xfs_bmap_shift_extents( 5393 struct xfs_trans *tp, 5394 struct xfs_inode *ip, 5395 int *done, 5396 xfs_fileoff_t start_fsb, 5397 xfs_fileoff_t offset_shift_fsb, 5398 xfs_extnum_t *current_ext, 5399 xfs_fsblock_t *firstblock, 5400 struct xfs_bmap_free *flist, 5401 int num_exts) 5402{ 5403 struct xfs_btree_cur *cur; 5404 struct xfs_bmbt_rec_host *gotp; 5405 struct xfs_bmbt_irec got; 5406 struct xfs_bmbt_irec left; 5407 struct xfs_mount *mp = ip->i_mount; 5408 struct xfs_ifork *ifp; 5409 xfs_extnum_t nexts = 0; 5410 xfs_fileoff_t startoff; 5411 int error = 0; 5412 int i; 5413 int whichfork = XFS_DATA_FORK; 5414 int logflags; 5415 xfs_filblks_t blockcount = 0; 5416 int total_extents; 5417 5418 if (unlikely(XFS_TEST_ERROR( 5419 (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && 5420 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE), 5421 mp, XFS_ERRTAG_BMAPIFORMAT, XFS_RANDOM_BMAPIFORMAT))) { 5422 XFS_ERROR_REPORT("xfs_bmap_shift_extents", 5423 XFS_ERRLEVEL_LOW, mp); 5424 return XFS_ERROR(EFSCORRUPTED); 5425 } 5426 5427 if (XFS_FORCED_SHUTDOWN(mp)) 5428 return XFS_ERROR(EIO); 5429 5430 ASSERT(current_ext != NULL); 5431 5432 ifp = XFS_IFORK_PTR(ip, whichfork); 5433 if (!(ifp->if_flags & XFS_IFEXTENTS)) { 5434 /* Read in all the extents */ 5435 error = xfs_iread_extents(tp, ip, whichfork); 5436 if (error) 5437 return error; 5438 } 5439 5440 /* 5441 * If *current_ext is 0, we would need to lookup the extent 5442 * from where we would start shifting and store it in gotp. 5443 */ 5444 if (!*current_ext) { 5445 gotp = xfs_iext_bno_to_ext(ifp, start_fsb, current_ext); 5446 /* 5447 * gotp can be null in 2 cases: 1) if there are no extents 5448 * or 2) start_fsb lies in a hole beyond which there are 5449 * no extents. Either way, we are done. 5450 */ 5451 if (!gotp) { 5452 *done = 1; 5453 return 0; 5454 } 5455 } 5456 5457 /* We are going to change core inode */ 5458 logflags = XFS_ILOG_CORE; 5459 if (ifp->if_flags & XFS_IFBROOT) { 5460 cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); 5461 cur->bc_private.b.firstblock = *firstblock; 5462 cur->bc_private.b.flist = flist; 5463 cur->bc_private.b.flags = 0; 5464 } else { 5465 cur = NULL; 5466 logflags |= XFS_ILOG_DEXT; 5467 } 5468 5469 /* 5470 * There may be delalloc extents in the data fork before the range we 5471 * are collapsing out, so we cannot 5472 * use the count of real extents here. Instead we have to calculate it 5473 * from the incore fork. 5474 */ 5475 total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t); 5476 while (nexts++ < num_exts && *current_ext < total_extents) { 5477 5478 gotp = xfs_iext_get_ext(ifp, *current_ext); 5479 xfs_bmbt_get_all(gotp, &got); 5480 startoff = got.br_startoff - offset_shift_fsb; 5481 5482 /* 5483 * Before shifting extent into hole, make sure that the hole 5484 * is large enough to accomodate the shift. 5485 */ 5486 if (*current_ext) { 5487 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, 5488 *current_ext - 1), &left); 5489 5490 if (startoff < left.br_startoff + left.br_blockcount) 5491 error = XFS_ERROR(EINVAL); 5492 } else if (offset_shift_fsb > got.br_startoff) { 5493 /* 5494 * When first extent is shifted, offset_shift_fsb 5495 * should be less than the stating offset of 5496 * the first extent. 5497 */ 5498 error = XFS_ERROR(EINVAL); 5499 } 5500 5501 if (error) 5502 goto del_cursor; 5503 5504 if (cur) { 5505 error = xfs_bmbt_lookup_eq(cur, got.br_startoff, 5506 got.br_startblock, 5507 got.br_blockcount, 5508 &i); 5509 if (error) 5510 goto del_cursor; 5511 XFS_WANT_CORRUPTED_GOTO(i == 1, del_cursor); 5512 } 5513 5514 /* Check if we can merge 2 adjacent extents */ 5515 if (*current_ext && 5516 left.br_startoff + left.br_blockcount == startoff && 5517 left.br_startblock + left.br_blockcount == 5518 got.br_startblock && 5519 left.br_state == got.br_state && 5520 left.br_blockcount + got.br_blockcount <= MAXEXTLEN) { 5521 blockcount = left.br_blockcount + 5522 got.br_blockcount; 5523 xfs_iext_remove(ip, *current_ext, 1, 0); 5524 if (cur) { 5525 error = xfs_btree_delete(cur, &i); 5526 if (error) 5527 goto del_cursor; 5528 XFS_WANT_CORRUPTED_GOTO(i == 1, del_cursor); 5529 } 5530 XFS_IFORK_NEXT_SET(ip, whichfork, 5531 XFS_IFORK_NEXTENTS(ip, whichfork) - 1); 5532 gotp = xfs_iext_get_ext(ifp, --*current_ext); 5533 xfs_bmbt_get_all(gotp, &got); 5534 5535 /* Make cursor point to the extent we will update */ 5536 if (cur) { 5537 error = xfs_bmbt_lookup_eq(cur, got.br_startoff, 5538 got.br_startblock, 5539 got.br_blockcount, 5540 &i); 5541 if (error) 5542 goto del_cursor; 5543 XFS_WANT_CORRUPTED_GOTO(i == 1, del_cursor); 5544 } 5545 5546 xfs_bmbt_set_blockcount(gotp, blockcount); 5547 got.br_blockcount = blockcount; 5548 } else { 5549 /* We have to update the startoff */ 5550 xfs_bmbt_set_startoff(gotp, startoff); 5551 got.br_startoff = startoff; 5552 } 5553 5554 if (cur) { 5555 error = xfs_bmbt_update(cur, got.br_startoff, 5556 got.br_startblock, 5557 got.br_blockcount, 5558 got.br_state); 5559 if (error) 5560 goto del_cursor; 5561 } 5562 5563 (*current_ext)++; 5564 total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t); 5565 } 5566 5567 /* Check if we are done */ 5568 if (*current_ext == total_extents) 5569 *done = 1; 5570 5571del_cursor: 5572 if (cur) 5573 xfs_btree_del_cursor(cur, 5574 error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); 5575 5576 xfs_trans_log_inode(tp, ip, logflags); 5577 return error; 5578}