1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2014 Red Hat, Inc. 4 * All Rights Reserved. 5 */ 6 #include "xfs.h" 7 #include "xfs_fs.h" 8 #include "xfs_shared.h" 9 #include "xfs_format.h" 10 #include "xfs_log_format.h" 11 #include "xfs_trans_resv.h" 12 #include "xfs_bit.h" 13 #include "xfs_mount.h" 14 #include "xfs_defer.h" 15 #include "xfs_btree.h" 16 #include "xfs_trans.h" 17 #include "xfs_alloc.h" 18 #include "xfs_rmap.h" 19 #include "xfs_rmap_btree.h" 20 #include "xfs_trace.h" 21 #include "xfs_errortag.h" 22 #include "xfs_error.h" 23 #include "xfs_inode.h" 24 #include "xfs_ag.h" 25 26 /* 27 * Lookup the first record less than or equal to [bno, len, owner, offset] 28 * in the btree given by cur. 29 */ 30 int 31 xfs_rmap_lookup_le( 32 struct xfs_btree_cur *cur, 33 xfs_agblock_t bno, 34 xfs_extlen_t len, 35 uint64_t owner, 36 uint64_t offset, 37 unsigned int flags, 38 int *stat) 39 { 40 cur->bc_rec.r.rm_startblock = bno; 41 cur->bc_rec.r.rm_blockcount = len; 42 cur->bc_rec.r.rm_owner = owner; 43 cur->bc_rec.r.rm_offset = offset; 44 cur->bc_rec.r.rm_flags = flags; 45 return xfs_btree_lookup(cur, XFS_LOOKUP_LE, stat); 46 } 47 48 /* 49 * Lookup the record exactly matching [bno, len, owner, offset] 50 * in the btree given by cur. 51 */ 52 int 53 xfs_rmap_lookup_eq( 54 struct xfs_btree_cur *cur, 55 xfs_agblock_t bno, 56 xfs_extlen_t len, 57 uint64_t owner, 58 uint64_t offset, 59 unsigned int flags, 60 int *stat) 61 { 62 cur->bc_rec.r.rm_startblock = bno; 63 cur->bc_rec.r.rm_blockcount = len; 64 cur->bc_rec.r.rm_owner = owner; 65 cur->bc_rec.r.rm_offset = offset; 66 cur->bc_rec.r.rm_flags = flags; 67 return xfs_btree_lookup(cur, XFS_LOOKUP_EQ, stat); 68 } 69 70 /* 71 * Update the record referred to by cur to the value given 72 * by [bno, len, owner, offset]. 73 * This either works (return 0) or gets an EFSCORRUPTED error. 74 */ 75 STATIC int 76 xfs_rmap_update( 77 struct xfs_btree_cur *cur, 78 struct xfs_rmap_irec *irec) 79 { 80 union xfs_btree_rec rec; 81 int error; 82 83 trace_xfs_rmap_update(cur->bc_mp, cur->bc_ag.agno, 84 irec->rm_startblock, irec->rm_blockcount, 85 irec->rm_owner, irec->rm_offset, irec->rm_flags); 86 87 rec.rmap.rm_startblock = cpu_to_be32(irec->rm_startblock); 88 rec.rmap.rm_blockcount = cpu_to_be32(irec->rm_blockcount); 89 rec.rmap.rm_owner = cpu_to_be64(irec->rm_owner); 90 rec.rmap.rm_offset = cpu_to_be64( 91 xfs_rmap_irec_offset_pack(irec)); 92 error = xfs_btree_update(cur, &rec); 93 if (error) 94 trace_xfs_rmap_update_error(cur->bc_mp, 95 cur->bc_ag.agno, error, _RET_IP_); 96 return error; 97 } 98 99 int 100 xfs_rmap_insert( 101 struct xfs_btree_cur *rcur, 102 xfs_agblock_t agbno, 103 xfs_extlen_t len, 104 uint64_t owner, 105 uint64_t offset, 106 unsigned int flags) 107 { 108 int i; 109 int error; 110 111 trace_xfs_rmap_insert(rcur->bc_mp, rcur->bc_ag.agno, agbno, 112 len, owner, offset, flags); 113 114 error = xfs_rmap_lookup_eq(rcur, agbno, len, owner, offset, flags, &i); 115 if (error) 116 goto done; 117 if (XFS_IS_CORRUPT(rcur->bc_mp, i != 0)) { 118 error = -EFSCORRUPTED; 119 goto done; 120 } 121 122 rcur->bc_rec.r.rm_startblock = agbno; 123 rcur->bc_rec.r.rm_blockcount = len; 124 rcur->bc_rec.r.rm_owner = owner; 125 rcur->bc_rec.r.rm_offset = offset; 126 rcur->bc_rec.r.rm_flags = flags; 127 error = xfs_btree_insert(rcur, &i); 128 if (error) 129 goto done; 130 if (XFS_IS_CORRUPT(rcur->bc_mp, i != 1)) { 131 error = -EFSCORRUPTED; 132 goto done; 133 } 134 done: 135 if (error) 136 trace_xfs_rmap_insert_error(rcur->bc_mp, 137 rcur->bc_ag.agno, error, _RET_IP_); 138 return error; 139 } 140 141 STATIC int 142 xfs_rmap_delete( 143 struct xfs_btree_cur *rcur, 144 xfs_agblock_t agbno, 145 xfs_extlen_t len, 146 uint64_t owner, 147 uint64_t offset, 148 unsigned int flags) 149 { 150 int i; 151 int error; 152 153 trace_xfs_rmap_delete(rcur->bc_mp, rcur->bc_ag.agno, agbno, 154 len, owner, offset, flags); 155 156 error = xfs_rmap_lookup_eq(rcur, agbno, len, owner, offset, flags, &i); 157 if (error) 158 goto done; 159 if (XFS_IS_CORRUPT(rcur->bc_mp, i != 1)) { 160 error = -EFSCORRUPTED; 161 goto done; 162 } 163 164 error = xfs_btree_delete(rcur, &i); 165 if (error) 166 goto done; 167 if (XFS_IS_CORRUPT(rcur->bc_mp, i != 1)) { 168 error = -EFSCORRUPTED; 169 goto done; 170 } 171 done: 172 if (error) 173 trace_xfs_rmap_delete_error(rcur->bc_mp, 174 rcur->bc_ag.agno, error, _RET_IP_); 175 return error; 176 } 177 178 /* Convert an internal btree record to an rmap record. */ 179 int 180 xfs_rmap_btrec_to_irec( 181 union xfs_btree_rec *rec, 182 struct xfs_rmap_irec *irec) 183 { 184 irec->rm_startblock = be32_to_cpu(rec->rmap.rm_startblock); 185 irec->rm_blockcount = be32_to_cpu(rec->rmap.rm_blockcount); 186 irec->rm_owner = be64_to_cpu(rec->rmap.rm_owner); 187 return xfs_rmap_irec_offset_unpack(be64_to_cpu(rec->rmap.rm_offset), 188 irec); 189 } 190 191 /* 192 * Get the data from the pointed-to record. 193 */ 194 int 195 xfs_rmap_get_rec( 196 struct xfs_btree_cur *cur, 197 struct xfs_rmap_irec *irec, 198 int *stat) 199 { 200 struct xfs_mount *mp = cur->bc_mp; 201 xfs_agnumber_t agno = cur->bc_ag.agno; 202 union xfs_btree_rec *rec; 203 int error; 204 205 error = xfs_btree_get_rec(cur, &rec, stat); 206 if (error || !*stat) 207 return error; 208 209 if (xfs_rmap_btrec_to_irec(rec, irec)) 210 goto out_bad_rec; 211 212 if (irec->rm_blockcount == 0) 213 goto out_bad_rec; 214 if (irec->rm_startblock <= XFS_AGFL_BLOCK(mp)) { 215 if (irec->rm_owner != XFS_RMAP_OWN_FS) 216 goto out_bad_rec; 217 if (irec->rm_blockcount != XFS_AGFL_BLOCK(mp) + 1) 218 goto out_bad_rec; 219 } else { 220 /* check for valid extent range, including overflow */ 221 if (!xfs_verify_agbno(mp, agno, irec->rm_startblock)) 222 goto out_bad_rec; 223 if (irec->rm_startblock > 224 irec->rm_startblock + irec->rm_blockcount) 225 goto out_bad_rec; 226 if (!xfs_verify_agbno(mp, agno, 227 irec->rm_startblock + irec->rm_blockcount - 1)) 228 goto out_bad_rec; 229 } 230 231 if (!(xfs_verify_ino(mp, irec->rm_owner) || 232 (irec->rm_owner <= XFS_RMAP_OWN_FS && 233 irec->rm_owner >= XFS_RMAP_OWN_MIN))) 234 goto out_bad_rec; 235 236 return 0; 237 out_bad_rec: 238 xfs_warn(mp, 239 "Reverse Mapping BTree record corruption in AG %d detected!", 240 agno); 241 xfs_warn(mp, 242 "Owner 0x%llx, flags 0x%x, start block 0x%x block count 0x%x", 243 irec->rm_owner, irec->rm_flags, irec->rm_startblock, 244 irec->rm_blockcount); 245 return -EFSCORRUPTED; 246 } 247 248 struct xfs_find_left_neighbor_info { 249 struct xfs_rmap_irec high; 250 struct xfs_rmap_irec *irec; 251 int *stat; 252 }; 253 254 /* For each rmap given, figure out if it matches the key we want. */ 255 STATIC int 256 xfs_rmap_find_left_neighbor_helper( 257 struct xfs_btree_cur *cur, 258 struct xfs_rmap_irec *rec, 259 void *priv) 260 { 261 struct xfs_find_left_neighbor_info *info = priv; 262 263 trace_xfs_rmap_find_left_neighbor_candidate(cur->bc_mp, 264 cur->bc_ag.agno, rec->rm_startblock, 265 rec->rm_blockcount, rec->rm_owner, rec->rm_offset, 266 rec->rm_flags); 267 268 if (rec->rm_owner != info->high.rm_owner) 269 return 0; 270 if (!XFS_RMAP_NON_INODE_OWNER(rec->rm_owner) && 271 !(rec->rm_flags & XFS_RMAP_BMBT_BLOCK) && 272 rec->rm_offset + rec->rm_blockcount - 1 != info->high.rm_offset) 273 return 0; 274 275 *info->irec = *rec; 276 *info->stat = 1; 277 return -ECANCELED; 278 } 279 280 /* 281 * Find the record to the left of the given extent, being careful only to 282 * return a match with the same owner and adjacent physical and logical 283 * block ranges. 284 */ 285 int 286 xfs_rmap_find_left_neighbor( 287 struct xfs_btree_cur *cur, 288 xfs_agblock_t bno, 289 uint64_t owner, 290 uint64_t offset, 291 unsigned int flags, 292 struct xfs_rmap_irec *irec, 293 int *stat) 294 { 295 struct xfs_find_left_neighbor_info info; 296 int error; 297 298 *stat = 0; 299 if (bno == 0) 300 return 0; 301 info.high.rm_startblock = bno - 1; 302 info.high.rm_owner = owner; 303 if (!XFS_RMAP_NON_INODE_OWNER(owner) && 304 !(flags & XFS_RMAP_BMBT_BLOCK)) { 305 if (offset == 0) 306 return 0; 307 info.high.rm_offset = offset - 1; 308 } else 309 info.high.rm_offset = 0; 310 info.high.rm_flags = flags; 311 info.high.rm_blockcount = 0; 312 info.irec = irec; 313 info.stat = stat; 314 315 trace_xfs_rmap_find_left_neighbor_query(cur->bc_mp, 316 cur->bc_ag.agno, bno, 0, owner, offset, flags); 317 318 error = xfs_rmap_query_range(cur, &info.high, &info.high, 319 xfs_rmap_find_left_neighbor_helper, &info); 320 if (error == -ECANCELED) 321 error = 0; 322 if (*stat) 323 trace_xfs_rmap_find_left_neighbor_result(cur->bc_mp, 324 cur->bc_ag.agno, irec->rm_startblock, 325 irec->rm_blockcount, irec->rm_owner, 326 irec->rm_offset, irec->rm_flags); 327 return error; 328 } 329 330 /* For each rmap given, figure out if it matches the key we want. */ 331 STATIC int 332 xfs_rmap_lookup_le_range_helper( 333 struct xfs_btree_cur *cur, 334 struct xfs_rmap_irec *rec, 335 void *priv) 336 { 337 struct xfs_find_left_neighbor_info *info = priv; 338 339 trace_xfs_rmap_lookup_le_range_candidate(cur->bc_mp, 340 cur->bc_ag.agno, rec->rm_startblock, 341 rec->rm_blockcount, rec->rm_owner, rec->rm_offset, 342 rec->rm_flags); 343 344 if (rec->rm_owner != info->high.rm_owner) 345 return 0; 346 if (!XFS_RMAP_NON_INODE_OWNER(rec->rm_owner) && 347 !(rec->rm_flags & XFS_RMAP_BMBT_BLOCK) && 348 (rec->rm_offset > info->high.rm_offset || 349 rec->rm_offset + rec->rm_blockcount <= info->high.rm_offset)) 350 return 0; 351 352 *info->irec = *rec; 353 *info->stat = 1; 354 return -ECANCELED; 355 } 356 357 /* 358 * Find the record to the left of the given extent, being careful only to 359 * return a match with the same owner and overlapping physical and logical 360 * block ranges. This is the overlapping-interval version of 361 * xfs_rmap_lookup_le. 362 */ 363 int 364 xfs_rmap_lookup_le_range( 365 struct xfs_btree_cur *cur, 366 xfs_agblock_t bno, 367 uint64_t owner, 368 uint64_t offset, 369 unsigned int flags, 370 struct xfs_rmap_irec *irec, 371 int *stat) 372 { 373 struct xfs_find_left_neighbor_info info; 374 int error; 375 376 info.high.rm_startblock = bno; 377 info.high.rm_owner = owner; 378 if (!XFS_RMAP_NON_INODE_OWNER(owner) && !(flags & XFS_RMAP_BMBT_BLOCK)) 379 info.high.rm_offset = offset; 380 else 381 info.high.rm_offset = 0; 382 info.high.rm_flags = flags; 383 info.high.rm_blockcount = 0; 384 *stat = 0; 385 info.irec = irec; 386 info.stat = stat; 387 388 trace_xfs_rmap_lookup_le_range(cur->bc_mp, 389 cur->bc_ag.agno, bno, 0, owner, offset, flags); 390 error = xfs_rmap_query_range(cur, &info.high, &info.high, 391 xfs_rmap_lookup_le_range_helper, &info); 392 if (error == -ECANCELED) 393 error = 0; 394 if (*stat) 395 trace_xfs_rmap_lookup_le_range_result(cur->bc_mp, 396 cur->bc_ag.agno, irec->rm_startblock, 397 irec->rm_blockcount, irec->rm_owner, 398 irec->rm_offset, irec->rm_flags); 399 return error; 400 } 401 402 /* 403 * Perform all the relevant owner checks for a removal op. If we're doing an 404 * unknown-owner removal then we have no owner information to check. 405 */ 406 static int 407 xfs_rmap_free_check_owner( 408 struct xfs_mount *mp, 409 uint64_t ltoff, 410 struct xfs_rmap_irec *rec, 411 xfs_filblks_t len, 412 uint64_t owner, 413 uint64_t offset, 414 unsigned int flags) 415 { 416 int error = 0; 417 418 if (owner == XFS_RMAP_OWN_UNKNOWN) 419 return 0; 420 421 /* Make sure the unwritten flag matches. */ 422 if (XFS_IS_CORRUPT(mp, 423 (flags & XFS_RMAP_UNWRITTEN) != 424 (rec->rm_flags & XFS_RMAP_UNWRITTEN))) { 425 error = -EFSCORRUPTED; 426 goto out; 427 } 428 429 /* Make sure the owner matches what we expect to find in the tree. */ 430 if (XFS_IS_CORRUPT(mp, owner != rec->rm_owner)) { 431 error = -EFSCORRUPTED; 432 goto out; 433 } 434 435 /* Check the offset, if necessary. */ 436 if (XFS_RMAP_NON_INODE_OWNER(owner)) 437 goto out; 438 439 if (flags & XFS_RMAP_BMBT_BLOCK) { 440 if (XFS_IS_CORRUPT(mp, 441 !(rec->rm_flags & XFS_RMAP_BMBT_BLOCK))) { 442 error = -EFSCORRUPTED; 443 goto out; 444 } 445 } else { 446 if (XFS_IS_CORRUPT(mp, rec->rm_offset > offset)) { 447 error = -EFSCORRUPTED; 448 goto out; 449 } 450 if (XFS_IS_CORRUPT(mp, 451 offset + len > ltoff + rec->rm_blockcount)) { 452 error = -EFSCORRUPTED; 453 goto out; 454 } 455 } 456 457 out: 458 return error; 459 } 460 461 /* 462 * Find the extent in the rmap btree and remove it. 463 * 464 * The record we find should always be an exact match for the extent that we're 465 * looking for, since we insert them into the btree without modification. 466 * 467 * Special Case #1: when growing the filesystem, we "free" an extent when 468 * growing the last AG. This extent is new space and so it is not tracked as 469 * used space in the btree. The growfs code will pass in an owner of 470 * XFS_RMAP_OWN_NULL to indicate that it expected that there is no owner of this 471 * extent. We verify that - the extent lookup result in a record that does not 472 * overlap. 473 * 474 * Special Case #2: EFIs do not record the owner of the extent, so when 475 * recovering EFIs from the log we pass in XFS_RMAP_OWN_UNKNOWN to tell the rmap 476 * btree to ignore the owner (i.e. wildcard match) so we don't trigger 477 * corruption checks during log recovery. 478 */ 479 STATIC int 480 xfs_rmap_unmap( 481 struct xfs_btree_cur *cur, 482 xfs_agblock_t bno, 483 xfs_extlen_t len, 484 bool unwritten, 485 const struct xfs_owner_info *oinfo) 486 { 487 struct xfs_mount *mp = cur->bc_mp; 488 struct xfs_rmap_irec ltrec; 489 uint64_t ltoff; 490 int error = 0; 491 int i; 492 uint64_t owner; 493 uint64_t offset; 494 unsigned int flags; 495 bool ignore_off; 496 497 xfs_owner_info_unpack(oinfo, &owner, &offset, &flags); 498 ignore_off = XFS_RMAP_NON_INODE_OWNER(owner) || 499 (flags & XFS_RMAP_BMBT_BLOCK); 500 if (unwritten) 501 flags |= XFS_RMAP_UNWRITTEN; 502 trace_xfs_rmap_unmap(mp, cur->bc_ag.agno, bno, len, 503 unwritten, oinfo); 504 505 /* 506 * We should always have a left record because there's a static record 507 * for the AG headers at rm_startblock == 0 created by mkfs/growfs that 508 * will not ever be removed from the tree. 509 */ 510 error = xfs_rmap_lookup_le(cur, bno, len, owner, offset, flags, &i); 511 if (error) 512 goto out_error; 513 if (XFS_IS_CORRUPT(mp, i != 1)) { 514 error = -EFSCORRUPTED; 515 goto out_error; 516 } 517 518 error = xfs_rmap_get_rec(cur, <rec, &i); 519 if (error) 520 goto out_error; 521 if (XFS_IS_CORRUPT(mp, i != 1)) { 522 error = -EFSCORRUPTED; 523 goto out_error; 524 } 525 trace_xfs_rmap_lookup_le_range_result(cur->bc_mp, 526 cur->bc_ag.agno, ltrec.rm_startblock, 527 ltrec.rm_blockcount, ltrec.rm_owner, 528 ltrec.rm_offset, ltrec.rm_flags); 529 ltoff = ltrec.rm_offset; 530 531 /* 532 * For growfs, the incoming extent must be beyond the left record we 533 * just found as it is new space and won't be used by anyone. This is 534 * just a corruption check as we don't actually do anything with this 535 * extent. Note that we need to use >= instead of > because it might 536 * be the case that the "left" extent goes all the way to EOFS. 537 */ 538 if (owner == XFS_RMAP_OWN_NULL) { 539 if (XFS_IS_CORRUPT(mp, 540 bno < 541 ltrec.rm_startblock + ltrec.rm_blockcount)) { 542 error = -EFSCORRUPTED; 543 goto out_error; 544 } 545 goto out_done; 546 } 547 548 /* 549 * If we're doing an unknown-owner removal for EFI recovery, we expect 550 * to find the full range in the rmapbt or nothing at all. If we 551 * don't find any rmaps overlapping either end of the range, we're 552 * done. Hopefully this means that the EFI creator already queued 553 * (and finished) a RUI to remove the rmap. 554 */ 555 if (owner == XFS_RMAP_OWN_UNKNOWN && 556 ltrec.rm_startblock + ltrec.rm_blockcount <= bno) { 557 struct xfs_rmap_irec rtrec; 558 559 error = xfs_btree_increment(cur, 0, &i); 560 if (error) 561 goto out_error; 562 if (i == 0) 563 goto out_done; 564 error = xfs_rmap_get_rec(cur, &rtrec, &i); 565 if (error) 566 goto out_error; 567 if (XFS_IS_CORRUPT(mp, i != 1)) { 568 error = -EFSCORRUPTED; 569 goto out_error; 570 } 571 if (rtrec.rm_startblock >= bno + len) 572 goto out_done; 573 } 574 575 /* Make sure the extent we found covers the entire freeing range. */ 576 if (XFS_IS_CORRUPT(mp, 577 ltrec.rm_startblock > bno || 578 ltrec.rm_startblock + ltrec.rm_blockcount < 579 bno + len)) { 580 error = -EFSCORRUPTED; 581 goto out_error; 582 } 583 584 /* Check owner information. */ 585 error = xfs_rmap_free_check_owner(mp, ltoff, <rec, len, owner, 586 offset, flags); 587 if (error) 588 goto out_error; 589 590 if (ltrec.rm_startblock == bno && ltrec.rm_blockcount == len) { 591 /* exact match, simply remove the record from rmap tree */ 592 trace_xfs_rmap_delete(mp, cur->bc_ag.agno, 593 ltrec.rm_startblock, ltrec.rm_blockcount, 594 ltrec.rm_owner, ltrec.rm_offset, 595 ltrec.rm_flags); 596 error = xfs_btree_delete(cur, &i); 597 if (error) 598 goto out_error; 599 if (XFS_IS_CORRUPT(mp, i != 1)) { 600 error = -EFSCORRUPTED; 601 goto out_error; 602 } 603 } else if (ltrec.rm_startblock == bno) { 604 /* 605 * overlap left hand side of extent: move the start, trim the 606 * length and update the current record. 607 * 608 * ltbno ltlen 609 * Orig: |oooooooooooooooooooo| 610 * Freeing: |fffffffff| 611 * Result: |rrrrrrrrrr| 612 * bno len 613 */ 614 ltrec.rm_startblock += len; 615 ltrec.rm_blockcount -= len; 616 if (!ignore_off) 617 ltrec.rm_offset += len; 618 error = xfs_rmap_update(cur, <rec); 619 if (error) 620 goto out_error; 621 } else if (ltrec.rm_startblock + ltrec.rm_blockcount == bno + len) { 622 /* 623 * overlap right hand side of extent: trim the length and update 624 * the current record. 625 * 626 * ltbno ltlen 627 * Orig: |oooooooooooooooooooo| 628 * Freeing: |fffffffff| 629 * Result: |rrrrrrrrrr| 630 * bno len 631 */ 632 ltrec.rm_blockcount -= len; 633 error = xfs_rmap_update(cur, <rec); 634 if (error) 635 goto out_error; 636 } else { 637 638 /* 639 * overlap middle of extent: trim the length of the existing 640 * record to the length of the new left-extent size, increment 641 * the insertion position so we can insert a new record 642 * containing the remaining right-extent space. 643 * 644 * ltbno ltlen 645 * Orig: |oooooooooooooooooooo| 646 * Freeing: |fffffffff| 647 * Result: |rrrrr| |rrrr| 648 * bno len 649 */ 650 xfs_extlen_t orig_len = ltrec.rm_blockcount; 651 652 ltrec.rm_blockcount = bno - ltrec.rm_startblock; 653 error = xfs_rmap_update(cur, <rec); 654 if (error) 655 goto out_error; 656 657 error = xfs_btree_increment(cur, 0, &i); 658 if (error) 659 goto out_error; 660 661 cur->bc_rec.r.rm_startblock = bno + len; 662 cur->bc_rec.r.rm_blockcount = orig_len - len - 663 ltrec.rm_blockcount; 664 cur->bc_rec.r.rm_owner = ltrec.rm_owner; 665 if (ignore_off) 666 cur->bc_rec.r.rm_offset = 0; 667 else 668 cur->bc_rec.r.rm_offset = offset + len; 669 cur->bc_rec.r.rm_flags = flags; 670 trace_xfs_rmap_insert(mp, cur->bc_ag.agno, 671 cur->bc_rec.r.rm_startblock, 672 cur->bc_rec.r.rm_blockcount, 673 cur->bc_rec.r.rm_owner, 674 cur->bc_rec.r.rm_offset, 675 cur->bc_rec.r.rm_flags); 676 error = xfs_btree_insert(cur, &i); 677 if (error) 678 goto out_error; 679 } 680 681 out_done: 682 trace_xfs_rmap_unmap_done(mp, cur->bc_ag.agno, bno, len, 683 unwritten, oinfo); 684 out_error: 685 if (error) 686 trace_xfs_rmap_unmap_error(mp, cur->bc_ag.agno, 687 error, _RET_IP_); 688 return error; 689 } 690 691 /* 692 * Remove a reference to an extent in the rmap btree. 693 */ 694 int 695 xfs_rmap_free( 696 struct xfs_trans *tp, 697 struct xfs_buf *agbp, 698 xfs_agnumber_t agno, 699 xfs_agblock_t bno, 700 xfs_extlen_t len, 701 const struct xfs_owner_info *oinfo) 702 { 703 struct xfs_mount *mp = tp->t_mountp; 704 struct xfs_btree_cur *cur; 705 int error; 706 707 if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) 708 return 0; 709 710 cur = xfs_rmapbt_init_cursor(mp, tp, agbp, agno); 711 712 error = xfs_rmap_unmap(cur, bno, len, false, oinfo); 713 714 xfs_btree_del_cursor(cur, error); 715 return error; 716 } 717 718 /* 719 * A mergeable rmap must have the same owner and the same values for 720 * the unwritten, attr_fork, and bmbt flags. The startblock and 721 * offset are checked separately. 722 */ 723 static bool 724 xfs_rmap_is_mergeable( 725 struct xfs_rmap_irec *irec, 726 uint64_t owner, 727 unsigned int flags) 728 { 729 if (irec->rm_owner == XFS_RMAP_OWN_NULL) 730 return false; 731 if (irec->rm_owner != owner) 732 return false; 733 if ((flags & XFS_RMAP_UNWRITTEN) ^ 734 (irec->rm_flags & XFS_RMAP_UNWRITTEN)) 735 return false; 736 if ((flags & XFS_RMAP_ATTR_FORK) ^ 737 (irec->rm_flags & XFS_RMAP_ATTR_FORK)) 738 return false; 739 if ((flags & XFS_RMAP_BMBT_BLOCK) ^ 740 (irec->rm_flags & XFS_RMAP_BMBT_BLOCK)) 741 return false; 742 return true; 743 } 744 745 /* 746 * When we allocate a new block, the first thing we do is add a reference to 747 * the extent in the rmap btree. This takes the form of a [agbno, length, 748 * owner, offset] record. Flags are encoded in the high bits of the offset 749 * field. 750 */ 751 STATIC int 752 xfs_rmap_map( 753 struct xfs_btree_cur *cur, 754 xfs_agblock_t bno, 755 xfs_extlen_t len, 756 bool unwritten, 757 const struct xfs_owner_info *oinfo) 758 { 759 struct xfs_mount *mp = cur->bc_mp; 760 struct xfs_rmap_irec ltrec; 761 struct xfs_rmap_irec gtrec; 762 int have_gt; 763 int have_lt; 764 int error = 0; 765 int i; 766 uint64_t owner; 767 uint64_t offset; 768 unsigned int flags = 0; 769 bool ignore_off; 770 771 xfs_owner_info_unpack(oinfo, &owner, &offset, &flags); 772 ASSERT(owner != 0); 773 ignore_off = XFS_RMAP_NON_INODE_OWNER(owner) || 774 (flags & XFS_RMAP_BMBT_BLOCK); 775 if (unwritten) 776 flags |= XFS_RMAP_UNWRITTEN; 777 trace_xfs_rmap_map(mp, cur->bc_ag.agno, bno, len, 778 unwritten, oinfo); 779 ASSERT(!xfs_rmap_should_skip_owner_update(oinfo)); 780 781 /* 782 * For the initial lookup, look for an exact match or the left-adjacent 783 * record for our insertion point. This will also give us the record for 784 * start block contiguity tests. 785 */ 786 error = xfs_rmap_lookup_le(cur, bno, len, owner, offset, flags, 787 &have_lt); 788 if (error) 789 goto out_error; 790 if (have_lt) { 791 error = xfs_rmap_get_rec(cur, <rec, &have_lt); 792 if (error) 793 goto out_error; 794 if (XFS_IS_CORRUPT(mp, have_lt != 1)) { 795 error = -EFSCORRUPTED; 796 goto out_error; 797 } 798 trace_xfs_rmap_lookup_le_range_result(cur->bc_mp, 799 cur->bc_ag.agno, ltrec.rm_startblock, 800 ltrec.rm_blockcount, ltrec.rm_owner, 801 ltrec.rm_offset, ltrec.rm_flags); 802 803 if (!xfs_rmap_is_mergeable(<rec, owner, flags)) 804 have_lt = 0; 805 } 806 807 if (XFS_IS_CORRUPT(mp, 808 have_lt != 0 && 809 ltrec.rm_startblock + ltrec.rm_blockcount > bno)) { 810 error = -EFSCORRUPTED; 811 goto out_error; 812 } 813 814 /* 815 * Increment the cursor to see if we have a right-adjacent record to our 816 * insertion point. This will give us the record for end block 817 * contiguity tests. 818 */ 819 error = xfs_btree_increment(cur, 0, &have_gt); 820 if (error) 821 goto out_error; 822 if (have_gt) { 823 error = xfs_rmap_get_rec(cur, >rec, &have_gt); 824 if (error) 825 goto out_error; 826 if (XFS_IS_CORRUPT(mp, have_gt != 1)) { 827 error = -EFSCORRUPTED; 828 goto out_error; 829 } 830 if (XFS_IS_CORRUPT(mp, bno + len > gtrec.rm_startblock)) { 831 error = -EFSCORRUPTED; 832 goto out_error; 833 } 834 trace_xfs_rmap_find_right_neighbor_result(cur->bc_mp, 835 cur->bc_ag.agno, gtrec.rm_startblock, 836 gtrec.rm_blockcount, gtrec.rm_owner, 837 gtrec.rm_offset, gtrec.rm_flags); 838 if (!xfs_rmap_is_mergeable(>rec, owner, flags)) 839 have_gt = 0; 840 } 841 842 /* 843 * Note: cursor currently points one record to the right of ltrec, even 844 * if there is no record in the tree to the right. 845 */ 846 if (have_lt && 847 ltrec.rm_startblock + ltrec.rm_blockcount == bno && 848 (ignore_off || ltrec.rm_offset + ltrec.rm_blockcount == offset)) { 849 /* 850 * left edge contiguous, merge into left record. 851 * 852 * ltbno ltlen 853 * orig: |ooooooooo| 854 * adding: |aaaaaaaaa| 855 * result: |rrrrrrrrrrrrrrrrrrr| 856 * bno len 857 */ 858 ltrec.rm_blockcount += len; 859 if (have_gt && 860 bno + len == gtrec.rm_startblock && 861 (ignore_off || offset + len == gtrec.rm_offset) && 862 (unsigned long)ltrec.rm_blockcount + len + 863 gtrec.rm_blockcount <= XFS_RMAP_LEN_MAX) { 864 /* 865 * right edge also contiguous, delete right record 866 * and merge into left record. 867 * 868 * ltbno ltlen gtbno gtlen 869 * orig: |ooooooooo| |ooooooooo| 870 * adding: |aaaaaaaaa| 871 * result: |rrrrrrrrrrrrrrrrrrrrrrrrrrrrr| 872 */ 873 ltrec.rm_blockcount += gtrec.rm_blockcount; 874 trace_xfs_rmap_delete(mp, cur->bc_ag.agno, 875 gtrec.rm_startblock, 876 gtrec.rm_blockcount, 877 gtrec.rm_owner, 878 gtrec.rm_offset, 879 gtrec.rm_flags); 880 error = xfs_btree_delete(cur, &i); 881 if (error) 882 goto out_error; 883 if (XFS_IS_CORRUPT(mp, i != 1)) { 884 error = -EFSCORRUPTED; 885 goto out_error; 886 } 887 } 888 889 /* point the cursor back to the left record and update */ 890 error = xfs_btree_decrement(cur, 0, &have_gt); 891 if (error) 892 goto out_error; 893 error = xfs_rmap_update(cur, <rec); 894 if (error) 895 goto out_error; 896 } else if (have_gt && 897 bno + len == gtrec.rm_startblock && 898 (ignore_off || offset + len == gtrec.rm_offset)) { 899 /* 900 * right edge contiguous, merge into right record. 901 * 902 * gtbno gtlen 903 * Orig: |ooooooooo| 904 * adding: |aaaaaaaaa| 905 * Result: |rrrrrrrrrrrrrrrrrrr| 906 * bno len 907 */ 908 gtrec.rm_startblock = bno; 909 gtrec.rm_blockcount += len; 910 if (!ignore_off) 911 gtrec.rm_offset = offset; 912 error = xfs_rmap_update(cur, >rec); 913 if (error) 914 goto out_error; 915 } else { 916 /* 917 * no contiguous edge with identical owner, insert 918 * new record at current cursor position. 919 */ 920 cur->bc_rec.r.rm_startblock = bno; 921 cur->bc_rec.r.rm_blockcount = len; 922 cur->bc_rec.r.rm_owner = owner; 923 cur->bc_rec.r.rm_offset = offset; 924 cur->bc_rec.r.rm_flags = flags; 925 trace_xfs_rmap_insert(mp, cur->bc_ag.agno, bno, len, 926 owner, offset, flags); 927 error = xfs_btree_insert(cur, &i); 928 if (error) 929 goto out_error; 930 if (XFS_IS_CORRUPT(mp, i != 1)) { 931 error = -EFSCORRUPTED; 932 goto out_error; 933 } 934 } 935 936 trace_xfs_rmap_map_done(mp, cur->bc_ag.agno, bno, len, 937 unwritten, oinfo); 938 out_error: 939 if (error) 940 trace_xfs_rmap_map_error(mp, cur->bc_ag.agno, 941 error, _RET_IP_); 942 return error; 943 } 944 945 /* 946 * Add a reference to an extent in the rmap btree. 947 */ 948 int 949 xfs_rmap_alloc( 950 struct xfs_trans *tp, 951 struct xfs_buf *agbp, 952 xfs_agnumber_t agno, 953 xfs_agblock_t bno, 954 xfs_extlen_t len, 955 const struct xfs_owner_info *oinfo) 956 { 957 struct xfs_mount *mp = tp->t_mountp; 958 struct xfs_btree_cur *cur; 959 int error; 960 961 if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) 962 return 0; 963 964 cur = xfs_rmapbt_init_cursor(mp, tp, agbp, agno); 965 error = xfs_rmap_map(cur, bno, len, false, oinfo); 966 967 xfs_btree_del_cursor(cur, error); 968 return error; 969 } 970 971 #define RMAP_LEFT_CONTIG (1 << 0) 972 #define RMAP_RIGHT_CONTIG (1 << 1) 973 #define RMAP_LEFT_FILLING (1 << 2) 974 #define RMAP_RIGHT_FILLING (1 << 3) 975 #define RMAP_LEFT_VALID (1 << 6) 976 #define RMAP_RIGHT_VALID (1 << 7) 977 978 #define LEFT r[0] 979 #define RIGHT r[1] 980 #define PREV r[2] 981 #define NEW r[3] 982 983 /* 984 * Convert an unwritten extent to a real extent or vice versa. 985 * Does not handle overlapping extents. 986 */ 987 STATIC int 988 xfs_rmap_convert( 989 struct xfs_btree_cur *cur, 990 xfs_agblock_t bno, 991 xfs_extlen_t len, 992 bool unwritten, 993 const struct xfs_owner_info *oinfo) 994 { 995 struct xfs_mount *mp = cur->bc_mp; 996 struct xfs_rmap_irec r[4]; /* neighbor extent entries */ 997 /* left is 0, right is 1, */ 998 /* prev is 2, new is 3 */ 999 uint64_t owner; 1000 uint64_t offset; 1001 uint64_t new_endoff; 1002 unsigned int oldext; 1003 unsigned int newext; 1004 unsigned int flags = 0; 1005 int i; 1006 int state = 0; 1007 int error; 1008 1009 xfs_owner_info_unpack(oinfo, &owner, &offset, &flags); 1010 ASSERT(!(XFS_RMAP_NON_INODE_OWNER(owner) || 1011 (flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK)))); 1012 oldext = unwritten ? XFS_RMAP_UNWRITTEN : 0; 1013 new_endoff = offset + len; 1014 trace_xfs_rmap_convert(mp, cur->bc_ag.agno, bno, len, 1015 unwritten, oinfo); 1016 1017 /* 1018 * For the initial lookup, look for an exact match or the left-adjacent 1019 * record for our insertion point. This will also give us the record for 1020 * start block contiguity tests. 1021 */ 1022 error = xfs_rmap_lookup_le(cur, bno, len, owner, offset, oldext, &i); 1023 if (error) 1024 goto done; 1025 if (XFS_IS_CORRUPT(mp, i != 1)) { 1026 error = -EFSCORRUPTED; 1027 goto done; 1028 } 1029 1030 error = xfs_rmap_get_rec(cur, &PREV, &i); 1031 if (error) 1032 goto done; 1033 if (XFS_IS_CORRUPT(mp, i != 1)) { 1034 error = -EFSCORRUPTED; 1035 goto done; 1036 } 1037 trace_xfs_rmap_lookup_le_range_result(cur->bc_mp, 1038 cur->bc_ag.agno, PREV.rm_startblock, 1039 PREV.rm_blockcount, PREV.rm_owner, 1040 PREV.rm_offset, PREV.rm_flags); 1041 1042 ASSERT(PREV.rm_offset <= offset); 1043 ASSERT(PREV.rm_offset + PREV.rm_blockcount >= new_endoff); 1044 ASSERT((PREV.rm_flags & XFS_RMAP_UNWRITTEN) == oldext); 1045 newext = ~oldext & XFS_RMAP_UNWRITTEN; 1046 1047 /* 1048 * Set flags determining what part of the previous oldext allocation 1049 * extent is being replaced by a newext allocation. 1050 */ 1051 if (PREV.rm_offset == offset) 1052 state |= RMAP_LEFT_FILLING; 1053 if (PREV.rm_offset + PREV.rm_blockcount == new_endoff) 1054 state |= RMAP_RIGHT_FILLING; 1055 1056 /* 1057 * Decrement the cursor to see if we have a left-adjacent record to our 1058 * insertion point. This will give us the record for end block 1059 * contiguity tests. 1060 */ 1061 error = xfs_btree_decrement(cur, 0, &i); 1062 if (error) 1063 goto done; 1064 if (i) { 1065 state |= RMAP_LEFT_VALID; 1066 error = xfs_rmap_get_rec(cur, &LEFT, &i); 1067 if (error) 1068 goto done; 1069 if (XFS_IS_CORRUPT(mp, i != 1)) { 1070 error = -EFSCORRUPTED; 1071 goto done; 1072 } 1073 if (XFS_IS_CORRUPT(mp, 1074 LEFT.rm_startblock + LEFT.rm_blockcount > 1075 bno)) { 1076 error = -EFSCORRUPTED; 1077 goto done; 1078 } 1079 trace_xfs_rmap_find_left_neighbor_result(cur->bc_mp, 1080 cur->bc_ag.agno, LEFT.rm_startblock, 1081 LEFT.rm_blockcount, LEFT.rm_owner, 1082 LEFT.rm_offset, LEFT.rm_flags); 1083 if (LEFT.rm_startblock + LEFT.rm_blockcount == bno && 1084 LEFT.rm_offset + LEFT.rm_blockcount == offset && 1085 xfs_rmap_is_mergeable(&LEFT, owner, newext)) 1086 state |= RMAP_LEFT_CONTIG; 1087 } 1088 1089 /* 1090 * Increment the cursor to see if we have a right-adjacent record to our 1091 * insertion point. This will give us the record for end block 1092 * contiguity tests. 1093 */ 1094 error = xfs_btree_increment(cur, 0, &i); 1095 if (error) 1096 goto done; 1097 if (XFS_IS_CORRUPT(mp, i != 1)) { 1098 error = -EFSCORRUPTED; 1099 goto done; 1100 } 1101 error = xfs_btree_increment(cur, 0, &i); 1102 if (error) 1103 goto done; 1104 if (i) { 1105 state |= RMAP_RIGHT_VALID; 1106 error = xfs_rmap_get_rec(cur, &RIGHT, &i); 1107 if (error) 1108 goto done; 1109 if (XFS_IS_CORRUPT(mp, i != 1)) { 1110 error = -EFSCORRUPTED; 1111 goto done; 1112 } 1113 if (XFS_IS_CORRUPT(mp, bno + len > RIGHT.rm_startblock)) { 1114 error = -EFSCORRUPTED; 1115 goto done; 1116 } 1117 trace_xfs_rmap_find_right_neighbor_result(cur->bc_mp, 1118 cur->bc_ag.agno, RIGHT.rm_startblock, 1119 RIGHT.rm_blockcount, RIGHT.rm_owner, 1120 RIGHT.rm_offset, RIGHT.rm_flags); 1121 if (bno + len == RIGHT.rm_startblock && 1122 offset + len == RIGHT.rm_offset && 1123 xfs_rmap_is_mergeable(&RIGHT, owner, newext)) 1124 state |= RMAP_RIGHT_CONTIG; 1125 } 1126 1127 /* check that left + prev + right is not too long */ 1128 if ((state & (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG | 1129 RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG)) == 1130 (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG | 1131 RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG) && 1132 (unsigned long)LEFT.rm_blockcount + len + 1133 RIGHT.rm_blockcount > XFS_RMAP_LEN_MAX) 1134 state &= ~RMAP_RIGHT_CONTIG; 1135 1136 trace_xfs_rmap_convert_state(mp, cur->bc_ag.agno, state, 1137 _RET_IP_); 1138 1139 /* reset the cursor back to PREV */ 1140 error = xfs_rmap_lookup_le(cur, bno, len, owner, offset, oldext, &i); 1141 if (error) 1142 goto done; 1143 if (XFS_IS_CORRUPT(mp, i != 1)) { 1144 error = -EFSCORRUPTED; 1145 goto done; 1146 } 1147 1148 /* 1149 * Switch out based on the FILLING and CONTIG state bits. 1150 */ 1151 switch (state & (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG | 1152 RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG)) { 1153 case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG | 1154 RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG: 1155 /* 1156 * Setting all of a previous oldext extent to newext. 1157 * The left and right neighbors are both contiguous with new. 1158 */ 1159 error = xfs_btree_increment(cur, 0, &i); 1160 if (error) 1161 goto done; 1162 if (XFS_IS_CORRUPT(mp, i != 1)) { 1163 error = -EFSCORRUPTED; 1164 goto done; 1165 } 1166 trace_xfs_rmap_delete(mp, cur->bc_ag.agno, 1167 RIGHT.rm_startblock, RIGHT.rm_blockcount, 1168 RIGHT.rm_owner, RIGHT.rm_offset, 1169 RIGHT.rm_flags); 1170 error = xfs_btree_delete(cur, &i); 1171 if (error) 1172 goto done; 1173 if (XFS_IS_CORRUPT(mp, i != 1)) { 1174 error = -EFSCORRUPTED; 1175 goto done; 1176 } 1177 error = xfs_btree_decrement(cur, 0, &i); 1178 if (error) 1179 goto done; 1180 if (XFS_IS_CORRUPT(mp, i != 1)) { 1181 error = -EFSCORRUPTED; 1182 goto done; 1183 } 1184 trace_xfs_rmap_delete(mp, cur->bc_ag.agno, 1185 PREV.rm_startblock, PREV.rm_blockcount, 1186 PREV.rm_owner, PREV.rm_offset, 1187 PREV.rm_flags); 1188 error = xfs_btree_delete(cur, &i); 1189 if (error) 1190 goto done; 1191 if (XFS_IS_CORRUPT(mp, i != 1)) { 1192 error = -EFSCORRUPTED; 1193 goto done; 1194 } 1195 error = xfs_btree_decrement(cur, 0, &i); 1196 if (error) 1197 goto done; 1198 if (XFS_IS_CORRUPT(mp, i != 1)) { 1199 error = -EFSCORRUPTED; 1200 goto done; 1201 } 1202 NEW = LEFT; 1203 NEW.rm_blockcount += PREV.rm_blockcount + RIGHT.rm_blockcount; 1204 error = xfs_rmap_update(cur, &NEW); 1205 if (error) 1206 goto done; 1207 break; 1208 1209 case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG: 1210 /* 1211 * Setting all of a previous oldext extent to newext. 1212 * The left neighbor is contiguous, the right is not. 1213 */ 1214 trace_xfs_rmap_delete(mp, cur->bc_ag.agno, 1215 PREV.rm_startblock, PREV.rm_blockcount, 1216 PREV.rm_owner, PREV.rm_offset, 1217 PREV.rm_flags); 1218 error = xfs_btree_delete(cur, &i); 1219 if (error) 1220 goto done; 1221 if (XFS_IS_CORRUPT(mp, i != 1)) { 1222 error = -EFSCORRUPTED; 1223 goto done; 1224 } 1225 error = xfs_btree_decrement(cur, 0, &i); 1226 if (error) 1227 goto done; 1228 if (XFS_IS_CORRUPT(mp, i != 1)) { 1229 error = -EFSCORRUPTED; 1230 goto done; 1231 } 1232 NEW = LEFT; 1233 NEW.rm_blockcount += PREV.rm_blockcount; 1234 error = xfs_rmap_update(cur, &NEW); 1235 if (error) 1236 goto done; 1237 break; 1238 1239 case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG: 1240 /* 1241 * Setting all of a previous oldext extent to newext. 1242 * The right neighbor is contiguous, the left is not. 1243 */ 1244 error = xfs_btree_increment(cur, 0, &i); 1245 if (error) 1246 goto done; 1247 if (XFS_IS_CORRUPT(mp, i != 1)) { 1248 error = -EFSCORRUPTED; 1249 goto done; 1250 } 1251 trace_xfs_rmap_delete(mp, cur->bc_ag.agno, 1252 RIGHT.rm_startblock, RIGHT.rm_blockcount, 1253 RIGHT.rm_owner, RIGHT.rm_offset, 1254 RIGHT.rm_flags); 1255 error = xfs_btree_delete(cur, &i); 1256 if (error) 1257 goto done; 1258 if (XFS_IS_CORRUPT(mp, i != 1)) { 1259 error = -EFSCORRUPTED; 1260 goto done; 1261 } 1262 error = xfs_btree_decrement(cur, 0, &i); 1263 if (error) 1264 goto done; 1265 if (XFS_IS_CORRUPT(mp, i != 1)) { 1266 error = -EFSCORRUPTED; 1267 goto done; 1268 } 1269 NEW = PREV; 1270 NEW.rm_blockcount = len + RIGHT.rm_blockcount; 1271 NEW.rm_flags = newext; 1272 error = xfs_rmap_update(cur, &NEW); 1273 if (error) 1274 goto done; 1275 break; 1276 1277 case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING: 1278 /* 1279 * Setting all of a previous oldext extent to newext. 1280 * Neither the left nor right neighbors are contiguous with 1281 * the new one. 1282 */ 1283 NEW = PREV; 1284 NEW.rm_flags = newext; 1285 error = xfs_rmap_update(cur, &NEW); 1286 if (error) 1287 goto done; 1288 break; 1289 1290 case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG: 1291 /* 1292 * Setting the first part of a previous oldext extent to newext. 1293 * The left neighbor is contiguous. 1294 */ 1295 NEW = PREV; 1296 NEW.rm_offset += len; 1297 NEW.rm_startblock += len; 1298 NEW.rm_blockcount -= len; 1299 error = xfs_rmap_update(cur, &NEW); 1300 if (error) 1301 goto done; 1302 error = xfs_btree_decrement(cur, 0, &i); 1303 if (error) 1304 goto done; 1305 NEW = LEFT; 1306 NEW.rm_blockcount += len; 1307 error = xfs_rmap_update(cur, &NEW); 1308 if (error) 1309 goto done; 1310 break; 1311 1312 case RMAP_LEFT_FILLING: 1313 /* 1314 * Setting the first part of a previous oldext extent to newext. 1315 * The left neighbor is not contiguous. 1316 */ 1317 NEW = PREV; 1318 NEW.rm_startblock += len; 1319 NEW.rm_offset += len; 1320 NEW.rm_blockcount -= len; 1321 error = xfs_rmap_update(cur, &NEW); 1322 if (error) 1323 goto done; 1324 NEW.rm_startblock = bno; 1325 NEW.rm_owner = owner; 1326 NEW.rm_offset = offset; 1327 NEW.rm_blockcount = len; 1328 NEW.rm_flags = newext; 1329 cur->bc_rec.r = NEW; 1330 trace_xfs_rmap_insert(mp, cur->bc_ag.agno, bno, 1331 len, owner, offset, newext); 1332 error = xfs_btree_insert(cur, &i); 1333 if (error) 1334 goto done; 1335 if (XFS_IS_CORRUPT(mp, i != 1)) { 1336 error = -EFSCORRUPTED; 1337 goto done; 1338 } 1339 break; 1340 1341 case RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG: 1342 /* 1343 * Setting the last part of a previous oldext extent to newext. 1344 * The right neighbor is contiguous with the new allocation. 1345 */ 1346 NEW = PREV; 1347 NEW.rm_blockcount -= len; 1348 error = xfs_rmap_update(cur, &NEW); 1349 if (error) 1350 goto done; 1351 error = xfs_btree_increment(cur, 0, &i); 1352 if (error) 1353 goto done; 1354 NEW = RIGHT; 1355 NEW.rm_offset = offset; 1356 NEW.rm_startblock = bno; 1357 NEW.rm_blockcount += len; 1358 error = xfs_rmap_update(cur, &NEW); 1359 if (error) 1360 goto done; 1361 break; 1362 1363 case RMAP_RIGHT_FILLING: 1364 /* 1365 * Setting the last part of a previous oldext extent to newext. 1366 * The right neighbor is not contiguous. 1367 */ 1368 NEW = PREV; 1369 NEW.rm_blockcount -= len; 1370 error = xfs_rmap_update(cur, &NEW); 1371 if (error) 1372 goto done; 1373 error = xfs_rmap_lookup_eq(cur, bno, len, owner, offset, 1374 oldext, &i); 1375 if (error) 1376 goto done; 1377 if (XFS_IS_CORRUPT(mp, i != 0)) { 1378 error = -EFSCORRUPTED; 1379 goto done; 1380 } 1381 NEW.rm_startblock = bno; 1382 NEW.rm_owner = owner; 1383 NEW.rm_offset = offset; 1384 NEW.rm_blockcount = len; 1385 NEW.rm_flags = newext; 1386 cur->bc_rec.r = NEW; 1387 trace_xfs_rmap_insert(mp, cur->bc_ag.agno, bno, 1388 len, owner, offset, newext); 1389 error = xfs_btree_insert(cur, &i); 1390 if (error) 1391 goto done; 1392 if (XFS_IS_CORRUPT(mp, i != 1)) { 1393 error = -EFSCORRUPTED; 1394 goto done; 1395 } 1396 break; 1397 1398 case 0: 1399 /* 1400 * Setting the middle part of a previous oldext extent to 1401 * newext. Contiguity is impossible here. 1402 * One extent becomes three extents. 1403 */ 1404 /* new right extent - oldext */ 1405 NEW.rm_startblock = bno + len; 1406 NEW.rm_owner = owner; 1407 NEW.rm_offset = new_endoff; 1408 NEW.rm_blockcount = PREV.rm_offset + PREV.rm_blockcount - 1409 new_endoff; 1410 NEW.rm_flags = PREV.rm_flags; 1411 error = xfs_rmap_update(cur, &NEW); 1412 if (error) 1413 goto done; 1414 /* new left extent - oldext */ 1415 NEW = PREV; 1416 NEW.rm_blockcount = offset - PREV.rm_offset; 1417 cur->bc_rec.r = NEW; 1418 trace_xfs_rmap_insert(mp, cur->bc_ag.agno, 1419 NEW.rm_startblock, NEW.rm_blockcount, 1420 NEW.rm_owner, NEW.rm_offset, 1421 NEW.rm_flags); 1422 error = xfs_btree_insert(cur, &i); 1423 if (error) 1424 goto done; 1425 if (XFS_IS_CORRUPT(mp, i != 1)) { 1426 error = -EFSCORRUPTED; 1427 goto done; 1428 } 1429 /* 1430 * Reset the cursor to the position of the new extent 1431 * we are about to insert as we can't trust it after 1432 * the previous insert. 1433 */ 1434 error = xfs_rmap_lookup_eq(cur, bno, len, owner, offset, 1435 oldext, &i); 1436 if (error) 1437 goto done; 1438 if (XFS_IS_CORRUPT(mp, i != 0)) { 1439 error = -EFSCORRUPTED; 1440 goto done; 1441 } 1442 /* new middle extent - newext */ 1443 cur->bc_rec.r.rm_flags &= ~XFS_RMAP_UNWRITTEN; 1444 cur->bc_rec.r.rm_flags |= newext; 1445 trace_xfs_rmap_insert(mp, cur->bc_ag.agno, bno, len, 1446 owner, offset, newext); 1447 error = xfs_btree_insert(cur, &i); 1448 if (error) 1449 goto done; 1450 if (XFS_IS_CORRUPT(mp, i != 1)) { 1451 error = -EFSCORRUPTED; 1452 goto done; 1453 } 1454 break; 1455 1456 case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG: 1457 case RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG: 1458 case RMAP_LEFT_FILLING | RMAP_RIGHT_CONTIG: 1459 case RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG: 1460 case RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG: 1461 case RMAP_LEFT_CONTIG: 1462 case RMAP_RIGHT_CONTIG: 1463 /* 1464 * These cases are all impossible. 1465 */ 1466 ASSERT(0); 1467 } 1468 1469 trace_xfs_rmap_convert_done(mp, cur->bc_ag.agno, bno, len, 1470 unwritten, oinfo); 1471 done: 1472 if (error) 1473 trace_xfs_rmap_convert_error(cur->bc_mp, 1474 cur->bc_ag.agno, error, _RET_IP_); 1475 return error; 1476 } 1477 1478 /* 1479 * Convert an unwritten extent to a real extent or vice versa. If there is no 1480 * possibility of overlapping extents, delegate to the simpler convert 1481 * function. 1482 */ 1483 STATIC int 1484 xfs_rmap_convert_shared( 1485 struct xfs_btree_cur *cur, 1486 xfs_agblock_t bno, 1487 xfs_extlen_t len, 1488 bool unwritten, 1489 const struct xfs_owner_info *oinfo) 1490 { 1491 struct xfs_mount *mp = cur->bc_mp; 1492 struct xfs_rmap_irec r[4]; /* neighbor extent entries */ 1493 /* left is 0, right is 1, */ 1494 /* prev is 2, new is 3 */ 1495 uint64_t owner; 1496 uint64_t offset; 1497 uint64_t new_endoff; 1498 unsigned int oldext; 1499 unsigned int newext; 1500 unsigned int flags = 0; 1501 int i; 1502 int state = 0; 1503 int error; 1504 1505 xfs_owner_info_unpack(oinfo, &owner, &offset, &flags); 1506 ASSERT(!(XFS_RMAP_NON_INODE_OWNER(owner) || 1507 (flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK)))); 1508 oldext = unwritten ? XFS_RMAP_UNWRITTEN : 0; 1509 new_endoff = offset + len; 1510 trace_xfs_rmap_convert(mp, cur->bc_ag.agno, bno, len, 1511 unwritten, oinfo); 1512 1513 /* 1514 * For the initial lookup, look for and exact match or the left-adjacent 1515 * record for our insertion point. This will also give us the record for 1516 * start block contiguity tests. 1517 */ 1518 error = xfs_rmap_lookup_le_range(cur, bno, owner, offset, oldext, 1519 &PREV, &i); 1520 if (error) 1521 goto done; 1522 if (XFS_IS_CORRUPT(mp, i != 1)) { 1523 error = -EFSCORRUPTED; 1524 goto done; 1525 } 1526 1527 ASSERT(PREV.rm_offset <= offset); 1528 ASSERT(PREV.rm_offset + PREV.rm_blockcount >= new_endoff); 1529 ASSERT((PREV.rm_flags & XFS_RMAP_UNWRITTEN) == oldext); 1530 newext = ~oldext & XFS_RMAP_UNWRITTEN; 1531 1532 /* 1533 * Set flags determining what part of the previous oldext allocation 1534 * extent is being replaced by a newext allocation. 1535 */ 1536 if (PREV.rm_offset == offset) 1537 state |= RMAP_LEFT_FILLING; 1538 if (PREV.rm_offset + PREV.rm_blockcount == new_endoff) 1539 state |= RMAP_RIGHT_FILLING; 1540 1541 /* Is there a left record that abuts our range? */ 1542 error = xfs_rmap_find_left_neighbor(cur, bno, owner, offset, newext, 1543 &LEFT, &i); 1544 if (error) 1545 goto done; 1546 if (i) { 1547 state |= RMAP_LEFT_VALID; 1548 if (XFS_IS_CORRUPT(mp, 1549 LEFT.rm_startblock + LEFT.rm_blockcount > 1550 bno)) { 1551 error = -EFSCORRUPTED; 1552 goto done; 1553 } 1554 if (xfs_rmap_is_mergeable(&LEFT, owner, newext)) 1555 state |= RMAP_LEFT_CONTIG; 1556 } 1557 1558 /* Is there a right record that abuts our range? */ 1559 error = xfs_rmap_lookup_eq(cur, bno + len, len, owner, offset + len, 1560 newext, &i); 1561 if (error) 1562 goto done; 1563 if (i) { 1564 state |= RMAP_RIGHT_VALID; 1565 error = xfs_rmap_get_rec(cur, &RIGHT, &i); 1566 if (error) 1567 goto done; 1568 if (XFS_IS_CORRUPT(mp, i != 1)) { 1569 error = -EFSCORRUPTED; 1570 goto done; 1571 } 1572 if (XFS_IS_CORRUPT(mp, bno + len > RIGHT.rm_startblock)) { 1573 error = -EFSCORRUPTED; 1574 goto done; 1575 } 1576 trace_xfs_rmap_find_right_neighbor_result(cur->bc_mp, 1577 cur->bc_ag.agno, RIGHT.rm_startblock, 1578 RIGHT.rm_blockcount, RIGHT.rm_owner, 1579 RIGHT.rm_offset, RIGHT.rm_flags); 1580 if (xfs_rmap_is_mergeable(&RIGHT, owner, newext)) 1581 state |= RMAP_RIGHT_CONTIG; 1582 } 1583 1584 /* check that left + prev + right is not too long */ 1585 if ((state & (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG | 1586 RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG)) == 1587 (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG | 1588 RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG) && 1589 (unsigned long)LEFT.rm_blockcount + len + 1590 RIGHT.rm_blockcount > XFS_RMAP_LEN_MAX) 1591 state &= ~RMAP_RIGHT_CONTIG; 1592 1593 trace_xfs_rmap_convert_state(mp, cur->bc_ag.agno, state, 1594 _RET_IP_); 1595 /* 1596 * Switch out based on the FILLING and CONTIG state bits. 1597 */ 1598 switch (state & (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG | 1599 RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG)) { 1600 case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG | 1601 RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG: 1602 /* 1603 * Setting all of a previous oldext extent to newext. 1604 * The left and right neighbors are both contiguous with new. 1605 */ 1606 error = xfs_rmap_delete(cur, RIGHT.rm_startblock, 1607 RIGHT.rm_blockcount, RIGHT.rm_owner, 1608 RIGHT.rm_offset, RIGHT.rm_flags); 1609 if (error) 1610 goto done; 1611 error = xfs_rmap_delete(cur, PREV.rm_startblock, 1612 PREV.rm_blockcount, PREV.rm_owner, 1613 PREV.rm_offset, PREV.rm_flags); 1614 if (error) 1615 goto done; 1616 NEW = LEFT; 1617 error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock, 1618 NEW.rm_blockcount, NEW.rm_owner, 1619 NEW.rm_offset, NEW.rm_flags, &i); 1620 if (error) 1621 goto done; 1622 if (XFS_IS_CORRUPT(mp, i != 1)) { 1623 error = -EFSCORRUPTED; 1624 goto done; 1625 } 1626 NEW.rm_blockcount += PREV.rm_blockcount + RIGHT.rm_blockcount; 1627 error = xfs_rmap_update(cur, &NEW); 1628 if (error) 1629 goto done; 1630 break; 1631 1632 case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG: 1633 /* 1634 * Setting all of a previous oldext extent to newext. 1635 * The left neighbor is contiguous, the right is not. 1636 */ 1637 error = xfs_rmap_delete(cur, PREV.rm_startblock, 1638 PREV.rm_blockcount, PREV.rm_owner, 1639 PREV.rm_offset, PREV.rm_flags); 1640 if (error) 1641 goto done; 1642 NEW = LEFT; 1643 error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock, 1644 NEW.rm_blockcount, NEW.rm_owner, 1645 NEW.rm_offset, NEW.rm_flags, &i); 1646 if (error) 1647 goto done; 1648 if (XFS_IS_CORRUPT(mp, i != 1)) { 1649 error = -EFSCORRUPTED; 1650 goto done; 1651 } 1652 NEW.rm_blockcount += PREV.rm_blockcount; 1653 error = xfs_rmap_update(cur, &NEW); 1654 if (error) 1655 goto done; 1656 break; 1657 1658 case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG: 1659 /* 1660 * Setting all of a previous oldext extent to newext. 1661 * The right neighbor is contiguous, the left is not. 1662 */ 1663 error = xfs_rmap_delete(cur, RIGHT.rm_startblock, 1664 RIGHT.rm_blockcount, RIGHT.rm_owner, 1665 RIGHT.rm_offset, RIGHT.rm_flags); 1666 if (error) 1667 goto done; 1668 NEW = PREV; 1669 error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock, 1670 NEW.rm_blockcount, NEW.rm_owner, 1671 NEW.rm_offset, NEW.rm_flags, &i); 1672 if (error) 1673 goto done; 1674 if (XFS_IS_CORRUPT(mp, i != 1)) { 1675 error = -EFSCORRUPTED; 1676 goto done; 1677 } 1678 NEW.rm_blockcount += RIGHT.rm_blockcount; 1679 NEW.rm_flags = RIGHT.rm_flags; 1680 error = xfs_rmap_update(cur, &NEW); 1681 if (error) 1682 goto done; 1683 break; 1684 1685 case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING: 1686 /* 1687 * Setting all of a previous oldext extent to newext. 1688 * Neither the left nor right neighbors are contiguous with 1689 * the new one. 1690 */ 1691 NEW = PREV; 1692 error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock, 1693 NEW.rm_blockcount, NEW.rm_owner, 1694 NEW.rm_offset, NEW.rm_flags, &i); 1695 if (error) 1696 goto done; 1697 if (XFS_IS_CORRUPT(mp, i != 1)) { 1698 error = -EFSCORRUPTED; 1699 goto done; 1700 } 1701 NEW.rm_flags = newext; 1702 error = xfs_rmap_update(cur, &NEW); 1703 if (error) 1704 goto done; 1705 break; 1706 1707 case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG: 1708 /* 1709 * Setting the first part of a previous oldext extent to newext. 1710 * The left neighbor is contiguous. 1711 */ 1712 NEW = PREV; 1713 error = xfs_rmap_delete(cur, NEW.rm_startblock, 1714 NEW.rm_blockcount, NEW.rm_owner, 1715 NEW.rm_offset, NEW.rm_flags); 1716 if (error) 1717 goto done; 1718 NEW.rm_offset += len; 1719 NEW.rm_startblock += len; 1720 NEW.rm_blockcount -= len; 1721 error = xfs_rmap_insert(cur, NEW.rm_startblock, 1722 NEW.rm_blockcount, NEW.rm_owner, 1723 NEW.rm_offset, NEW.rm_flags); 1724 if (error) 1725 goto done; 1726 NEW = LEFT; 1727 error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock, 1728 NEW.rm_blockcount, NEW.rm_owner, 1729 NEW.rm_offset, NEW.rm_flags, &i); 1730 if (error) 1731 goto done; 1732 if (XFS_IS_CORRUPT(mp, i != 1)) { 1733 error = -EFSCORRUPTED; 1734 goto done; 1735 } 1736 NEW.rm_blockcount += len; 1737 error = xfs_rmap_update(cur, &NEW); 1738 if (error) 1739 goto done; 1740 break; 1741 1742 case RMAP_LEFT_FILLING: 1743 /* 1744 * Setting the first part of a previous oldext extent to newext. 1745 * The left neighbor is not contiguous. 1746 */ 1747 NEW = PREV; 1748 error = xfs_rmap_delete(cur, NEW.rm_startblock, 1749 NEW.rm_blockcount, NEW.rm_owner, 1750 NEW.rm_offset, NEW.rm_flags); 1751 if (error) 1752 goto done; 1753 NEW.rm_offset += len; 1754 NEW.rm_startblock += len; 1755 NEW.rm_blockcount -= len; 1756 error = xfs_rmap_insert(cur, NEW.rm_startblock, 1757 NEW.rm_blockcount, NEW.rm_owner, 1758 NEW.rm_offset, NEW.rm_flags); 1759 if (error) 1760 goto done; 1761 error = xfs_rmap_insert(cur, bno, len, owner, offset, newext); 1762 if (error) 1763 goto done; 1764 break; 1765 1766 case RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG: 1767 /* 1768 * Setting the last part of a previous oldext extent to newext. 1769 * The right neighbor is contiguous with the new allocation. 1770 */ 1771 NEW = PREV; 1772 error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock, 1773 NEW.rm_blockcount, NEW.rm_owner, 1774 NEW.rm_offset, NEW.rm_flags, &i); 1775 if (error) 1776 goto done; 1777 if (XFS_IS_CORRUPT(mp, i != 1)) { 1778 error = -EFSCORRUPTED; 1779 goto done; 1780 } 1781 NEW.rm_blockcount = offset - NEW.rm_offset; 1782 error = xfs_rmap_update(cur, &NEW); 1783 if (error) 1784 goto done; 1785 NEW = RIGHT; 1786 error = xfs_rmap_delete(cur, NEW.rm_startblock, 1787 NEW.rm_blockcount, NEW.rm_owner, 1788 NEW.rm_offset, NEW.rm_flags); 1789 if (error) 1790 goto done; 1791 NEW.rm_offset = offset; 1792 NEW.rm_startblock = bno; 1793 NEW.rm_blockcount += len; 1794 error = xfs_rmap_insert(cur, NEW.rm_startblock, 1795 NEW.rm_blockcount, NEW.rm_owner, 1796 NEW.rm_offset, NEW.rm_flags); 1797 if (error) 1798 goto done; 1799 break; 1800 1801 case RMAP_RIGHT_FILLING: 1802 /* 1803 * Setting the last part of a previous oldext extent to newext. 1804 * The right neighbor is not contiguous. 1805 */ 1806 NEW = PREV; 1807 error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock, 1808 NEW.rm_blockcount, NEW.rm_owner, 1809 NEW.rm_offset, NEW.rm_flags, &i); 1810 if (error) 1811 goto done; 1812 if (XFS_IS_CORRUPT(mp, i != 1)) { 1813 error = -EFSCORRUPTED; 1814 goto done; 1815 } 1816 NEW.rm_blockcount -= len; 1817 error = xfs_rmap_update(cur, &NEW); 1818 if (error) 1819 goto done; 1820 error = xfs_rmap_insert(cur, bno, len, owner, offset, newext); 1821 if (error) 1822 goto done; 1823 break; 1824 1825 case 0: 1826 /* 1827 * Setting the middle part of a previous oldext extent to 1828 * newext. Contiguity is impossible here. 1829 * One extent becomes three extents. 1830 */ 1831 /* new right extent - oldext */ 1832 NEW.rm_startblock = bno + len; 1833 NEW.rm_owner = owner; 1834 NEW.rm_offset = new_endoff; 1835 NEW.rm_blockcount = PREV.rm_offset + PREV.rm_blockcount - 1836 new_endoff; 1837 NEW.rm_flags = PREV.rm_flags; 1838 error = xfs_rmap_insert(cur, NEW.rm_startblock, 1839 NEW.rm_blockcount, NEW.rm_owner, NEW.rm_offset, 1840 NEW.rm_flags); 1841 if (error) 1842 goto done; 1843 /* new left extent - oldext */ 1844 NEW = PREV; 1845 error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock, 1846 NEW.rm_blockcount, NEW.rm_owner, 1847 NEW.rm_offset, NEW.rm_flags, &i); 1848 if (error) 1849 goto done; 1850 if (XFS_IS_CORRUPT(mp, i != 1)) { 1851 error = -EFSCORRUPTED; 1852 goto done; 1853 } 1854 NEW.rm_blockcount = offset - NEW.rm_offset; 1855 error = xfs_rmap_update(cur, &NEW); 1856 if (error) 1857 goto done; 1858 /* new middle extent - newext */ 1859 NEW.rm_startblock = bno; 1860 NEW.rm_blockcount = len; 1861 NEW.rm_owner = owner; 1862 NEW.rm_offset = offset; 1863 NEW.rm_flags = newext; 1864 error = xfs_rmap_insert(cur, NEW.rm_startblock, 1865 NEW.rm_blockcount, NEW.rm_owner, NEW.rm_offset, 1866 NEW.rm_flags); 1867 if (error) 1868 goto done; 1869 break; 1870 1871 case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG: 1872 case RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG: 1873 case RMAP_LEFT_FILLING | RMAP_RIGHT_CONTIG: 1874 case RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG: 1875 case RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG: 1876 case RMAP_LEFT_CONTIG: 1877 case RMAP_RIGHT_CONTIG: 1878 /* 1879 * These cases are all impossible. 1880 */ 1881 ASSERT(0); 1882 } 1883 1884 trace_xfs_rmap_convert_done(mp, cur->bc_ag.agno, bno, len, 1885 unwritten, oinfo); 1886 done: 1887 if (error) 1888 trace_xfs_rmap_convert_error(cur->bc_mp, 1889 cur->bc_ag.agno, error, _RET_IP_); 1890 return error; 1891 } 1892 1893 #undef NEW 1894 #undef LEFT 1895 #undef RIGHT 1896 #undef PREV 1897 1898 /* 1899 * Find an extent in the rmap btree and unmap it. For rmap extent types that 1900 * can overlap (data fork rmaps on reflink filesystems) we must be careful 1901 * that the prev/next records in the btree might belong to another owner. 1902 * Therefore we must use delete+insert to alter any of the key fields. 1903 * 1904 * For every other situation there can only be one owner for a given extent, 1905 * so we can call the regular _free function. 1906 */ 1907 STATIC int 1908 xfs_rmap_unmap_shared( 1909 struct xfs_btree_cur *cur, 1910 xfs_agblock_t bno, 1911 xfs_extlen_t len, 1912 bool unwritten, 1913 const struct xfs_owner_info *oinfo) 1914 { 1915 struct xfs_mount *mp = cur->bc_mp; 1916 struct xfs_rmap_irec ltrec; 1917 uint64_t ltoff; 1918 int error = 0; 1919 int i; 1920 uint64_t owner; 1921 uint64_t offset; 1922 unsigned int flags; 1923 1924 xfs_owner_info_unpack(oinfo, &owner, &offset, &flags); 1925 if (unwritten) 1926 flags |= XFS_RMAP_UNWRITTEN; 1927 trace_xfs_rmap_unmap(mp, cur->bc_ag.agno, bno, len, 1928 unwritten, oinfo); 1929 1930 /* 1931 * We should always have a left record because there's a static record 1932 * for the AG headers at rm_startblock == 0 created by mkfs/growfs that 1933 * will not ever be removed from the tree. 1934 */ 1935 error = xfs_rmap_lookup_le_range(cur, bno, owner, offset, flags, 1936 <rec, &i); 1937 if (error) 1938 goto out_error; 1939 if (XFS_IS_CORRUPT(mp, i != 1)) { 1940 error = -EFSCORRUPTED; 1941 goto out_error; 1942 } 1943 ltoff = ltrec.rm_offset; 1944 1945 /* Make sure the extent we found covers the entire freeing range. */ 1946 if (XFS_IS_CORRUPT(mp, 1947 ltrec.rm_startblock > bno || 1948 ltrec.rm_startblock + ltrec.rm_blockcount < 1949 bno + len)) { 1950 error = -EFSCORRUPTED; 1951 goto out_error; 1952 } 1953 1954 /* Make sure the owner matches what we expect to find in the tree. */ 1955 if (XFS_IS_CORRUPT(mp, owner != ltrec.rm_owner)) { 1956 error = -EFSCORRUPTED; 1957 goto out_error; 1958 } 1959 1960 /* Make sure the unwritten flag matches. */ 1961 if (XFS_IS_CORRUPT(mp, 1962 (flags & XFS_RMAP_UNWRITTEN) != 1963 (ltrec.rm_flags & XFS_RMAP_UNWRITTEN))) { 1964 error = -EFSCORRUPTED; 1965 goto out_error; 1966 } 1967 1968 /* Check the offset. */ 1969 if (XFS_IS_CORRUPT(mp, ltrec.rm_offset > offset)) { 1970 error = -EFSCORRUPTED; 1971 goto out_error; 1972 } 1973 if (XFS_IS_CORRUPT(mp, offset > ltoff + ltrec.rm_blockcount)) { 1974 error = -EFSCORRUPTED; 1975 goto out_error; 1976 } 1977 1978 if (ltrec.rm_startblock == bno && ltrec.rm_blockcount == len) { 1979 /* Exact match, simply remove the record from rmap tree. */ 1980 error = xfs_rmap_delete(cur, ltrec.rm_startblock, 1981 ltrec.rm_blockcount, ltrec.rm_owner, 1982 ltrec.rm_offset, ltrec.rm_flags); 1983 if (error) 1984 goto out_error; 1985 } else if (ltrec.rm_startblock == bno) { 1986 /* 1987 * Overlap left hand side of extent: move the start, trim the 1988 * length and update the current record. 1989 * 1990 * ltbno ltlen 1991 * Orig: |oooooooooooooooooooo| 1992 * Freeing: |fffffffff| 1993 * Result: |rrrrrrrrrr| 1994 * bno len 1995 */ 1996 1997 /* Delete prev rmap. */ 1998 error = xfs_rmap_delete(cur, ltrec.rm_startblock, 1999 ltrec.rm_blockcount, ltrec.rm_owner, 2000 ltrec.rm_offset, ltrec.rm_flags); 2001 if (error) 2002 goto out_error; 2003 2004 /* Add an rmap at the new offset. */ 2005 ltrec.rm_startblock += len; 2006 ltrec.rm_blockcount -= len; 2007 ltrec.rm_offset += len; 2008 error = xfs_rmap_insert(cur, ltrec.rm_startblock, 2009 ltrec.rm_blockcount, ltrec.rm_owner, 2010 ltrec.rm_offset, ltrec.rm_flags); 2011 if (error) 2012 goto out_error; 2013 } else if (ltrec.rm_startblock + ltrec.rm_blockcount == bno + len) { 2014 /* 2015 * Overlap right hand side of extent: trim the length and 2016 * update the current record. 2017 * 2018 * ltbno ltlen 2019 * Orig: |oooooooooooooooooooo| 2020 * Freeing: |fffffffff| 2021 * Result: |rrrrrrrrrr| 2022 * bno len 2023 */ 2024 error = xfs_rmap_lookup_eq(cur, ltrec.rm_startblock, 2025 ltrec.rm_blockcount, ltrec.rm_owner, 2026 ltrec.rm_offset, ltrec.rm_flags, &i); 2027 if (error) 2028 goto out_error; 2029 if (XFS_IS_CORRUPT(mp, i != 1)) { 2030 error = -EFSCORRUPTED; 2031 goto out_error; 2032 } 2033 ltrec.rm_blockcount -= len; 2034 error = xfs_rmap_update(cur, <rec); 2035 if (error) 2036 goto out_error; 2037 } else { 2038 /* 2039 * Overlap middle of extent: trim the length of the existing 2040 * record to the length of the new left-extent size, increment 2041 * the insertion position so we can insert a new record 2042 * containing the remaining right-extent space. 2043 * 2044 * ltbno ltlen 2045 * Orig: |oooooooooooooooooooo| 2046 * Freeing: |fffffffff| 2047 * Result: |rrrrr| |rrrr| 2048 * bno len 2049 */ 2050 xfs_extlen_t orig_len = ltrec.rm_blockcount; 2051 2052 /* Shrink the left side of the rmap */ 2053 error = xfs_rmap_lookup_eq(cur, ltrec.rm_startblock, 2054 ltrec.rm_blockcount, ltrec.rm_owner, 2055 ltrec.rm_offset, ltrec.rm_flags, &i); 2056 if (error) 2057 goto out_error; 2058 if (XFS_IS_CORRUPT(mp, i != 1)) { 2059 error = -EFSCORRUPTED; 2060 goto out_error; 2061 } 2062 ltrec.rm_blockcount = bno - ltrec.rm_startblock; 2063 error = xfs_rmap_update(cur, <rec); 2064 if (error) 2065 goto out_error; 2066 2067 /* Add an rmap at the new offset */ 2068 error = xfs_rmap_insert(cur, bno + len, 2069 orig_len - len - ltrec.rm_blockcount, 2070 ltrec.rm_owner, offset + len, 2071 ltrec.rm_flags); 2072 if (error) 2073 goto out_error; 2074 } 2075 2076 trace_xfs_rmap_unmap_done(mp, cur->bc_ag.agno, bno, len, 2077 unwritten, oinfo); 2078 out_error: 2079 if (error) 2080 trace_xfs_rmap_unmap_error(cur->bc_mp, 2081 cur->bc_ag.agno, error, _RET_IP_); 2082 return error; 2083 } 2084 2085 /* 2086 * Find an extent in the rmap btree and map it. For rmap extent types that 2087 * can overlap (data fork rmaps on reflink filesystems) we must be careful 2088 * that the prev/next records in the btree might belong to another owner. 2089 * Therefore we must use delete+insert to alter any of the key fields. 2090 * 2091 * For every other situation there can only be one owner for a given extent, 2092 * so we can call the regular _alloc function. 2093 */ 2094 STATIC int 2095 xfs_rmap_map_shared( 2096 struct xfs_btree_cur *cur, 2097 xfs_agblock_t bno, 2098 xfs_extlen_t len, 2099 bool unwritten, 2100 const struct xfs_owner_info *oinfo) 2101 { 2102 struct xfs_mount *mp = cur->bc_mp; 2103 struct xfs_rmap_irec ltrec; 2104 struct xfs_rmap_irec gtrec; 2105 int have_gt; 2106 int have_lt; 2107 int error = 0; 2108 int i; 2109 uint64_t owner; 2110 uint64_t offset; 2111 unsigned int flags = 0; 2112 2113 xfs_owner_info_unpack(oinfo, &owner, &offset, &flags); 2114 if (unwritten) 2115 flags |= XFS_RMAP_UNWRITTEN; 2116 trace_xfs_rmap_map(mp, cur->bc_ag.agno, bno, len, 2117 unwritten, oinfo); 2118 2119 /* Is there a left record that abuts our range? */ 2120 error = xfs_rmap_find_left_neighbor(cur, bno, owner, offset, flags, 2121 <rec, &have_lt); 2122 if (error) 2123 goto out_error; 2124 if (have_lt && 2125 !xfs_rmap_is_mergeable(<rec, owner, flags)) 2126 have_lt = 0; 2127 2128 /* Is there a right record that abuts our range? */ 2129 error = xfs_rmap_lookup_eq(cur, bno + len, len, owner, offset + len, 2130 flags, &have_gt); 2131 if (error) 2132 goto out_error; 2133 if (have_gt) { 2134 error = xfs_rmap_get_rec(cur, >rec, &have_gt); 2135 if (error) 2136 goto out_error; 2137 if (XFS_IS_CORRUPT(mp, have_gt != 1)) { 2138 error = -EFSCORRUPTED; 2139 goto out_error; 2140 } 2141 trace_xfs_rmap_find_right_neighbor_result(cur->bc_mp, 2142 cur->bc_ag.agno, gtrec.rm_startblock, 2143 gtrec.rm_blockcount, gtrec.rm_owner, 2144 gtrec.rm_offset, gtrec.rm_flags); 2145 2146 if (!xfs_rmap_is_mergeable(>rec, owner, flags)) 2147 have_gt = 0; 2148 } 2149 2150 if (have_lt && 2151 ltrec.rm_startblock + ltrec.rm_blockcount == bno && 2152 ltrec.rm_offset + ltrec.rm_blockcount == offset) { 2153 /* 2154 * Left edge contiguous, merge into left record. 2155 * 2156 * ltbno ltlen 2157 * orig: |ooooooooo| 2158 * adding: |aaaaaaaaa| 2159 * result: |rrrrrrrrrrrrrrrrrrr| 2160 * bno len 2161 */ 2162 ltrec.rm_blockcount += len; 2163 if (have_gt && 2164 bno + len == gtrec.rm_startblock && 2165 offset + len == gtrec.rm_offset) { 2166 /* 2167 * Right edge also contiguous, delete right record 2168 * and merge into left record. 2169 * 2170 * ltbno ltlen gtbno gtlen 2171 * orig: |ooooooooo| |ooooooooo| 2172 * adding: |aaaaaaaaa| 2173 * result: |rrrrrrrrrrrrrrrrrrrrrrrrrrrrr| 2174 */ 2175 ltrec.rm_blockcount += gtrec.rm_blockcount; 2176 error = xfs_rmap_delete(cur, gtrec.rm_startblock, 2177 gtrec.rm_blockcount, gtrec.rm_owner, 2178 gtrec.rm_offset, gtrec.rm_flags); 2179 if (error) 2180 goto out_error; 2181 } 2182 2183 /* Point the cursor back to the left record and update. */ 2184 error = xfs_rmap_lookup_eq(cur, ltrec.rm_startblock, 2185 ltrec.rm_blockcount, ltrec.rm_owner, 2186 ltrec.rm_offset, ltrec.rm_flags, &i); 2187 if (error) 2188 goto out_error; 2189 if (XFS_IS_CORRUPT(mp, i != 1)) { 2190 error = -EFSCORRUPTED; 2191 goto out_error; 2192 } 2193 2194 error = xfs_rmap_update(cur, <rec); 2195 if (error) 2196 goto out_error; 2197 } else if (have_gt && 2198 bno + len == gtrec.rm_startblock && 2199 offset + len == gtrec.rm_offset) { 2200 /* 2201 * Right edge contiguous, merge into right record. 2202 * 2203 * gtbno gtlen 2204 * Orig: |ooooooooo| 2205 * adding: |aaaaaaaaa| 2206 * Result: |rrrrrrrrrrrrrrrrrrr| 2207 * bno len 2208 */ 2209 /* Delete the old record. */ 2210 error = xfs_rmap_delete(cur, gtrec.rm_startblock, 2211 gtrec.rm_blockcount, gtrec.rm_owner, 2212 gtrec.rm_offset, gtrec.rm_flags); 2213 if (error) 2214 goto out_error; 2215 2216 /* Move the start and re-add it. */ 2217 gtrec.rm_startblock = bno; 2218 gtrec.rm_blockcount += len; 2219 gtrec.rm_offset = offset; 2220 error = xfs_rmap_insert(cur, gtrec.rm_startblock, 2221 gtrec.rm_blockcount, gtrec.rm_owner, 2222 gtrec.rm_offset, gtrec.rm_flags); 2223 if (error) 2224 goto out_error; 2225 } else { 2226 /* 2227 * No contiguous edge with identical owner, insert 2228 * new record at current cursor position. 2229 */ 2230 error = xfs_rmap_insert(cur, bno, len, owner, offset, flags); 2231 if (error) 2232 goto out_error; 2233 } 2234 2235 trace_xfs_rmap_map_done(mp, cur->bc_ag.agno, bno, len, 2236 unwritten, oinfo); 2237 out_error: 2238 if (error) 2239 trace_xfs_rmap_map_error(cur->bc_mp, 2240 cur->bc_ag.agno, error, _RET_IP_); 2241 return error; 2242 } 2243 2244 /* Insert a raw rmap into the rmapbt. */ 2245 int 2246 xfs_rmap_map_raw( 2247 struct xfs_btree_cur *cur, 2248 struct xfs_rmap_irec *rmap) 2249 { 2250 struct xfs_owner_info oinfo; 2251 2252 oinfo.oi_owner = rmap->rm_owner; 2253 oinfo.oi_offset = rmap->rm_offset; 2254 oinfo.oi_flags = 0; 2255 if (rmap->rm_flags & XFS_RMAP_ATTR_FORK) 2256 oinfo.oi_flags |= XFS_OWNER_INFO_ATTR_FORK; 2257 if (rmap->rm_flags & XFS_RMAP_BMBT_BLOCK) 2258 oinfo.oi_flags |= XFS_OWNER_INFO_BMBT_BLOCK; 2259 2260 if (rmap->rm_flags || XFS_RMAP_NON_INODE_OWNER(rmap->rm_owner)) 2261 return xfs_rmap_map(cur, rmap->rm_startblock, 2262 rmap->rm_blockcount, 2263 rmap->rm_flags & XFS_RMAP_UNWRITTEN, 2264 &oinfo); 2265 2266 return xfs_rmap_map_shared(cur, rmap->rm_startblock, 2267 rmap->rm_blockcount, 2268 rmap->rm_flags & XFS_RMAP_UNWRITTEN, 2269 &oinfo); 2270 } 2271 2272 struct xfs_rmap_query_range_info { 2273 xfs_rmap_query_range_fn fn; 2274 void *priv; 2275 }; 2276 2277 /* Format btree record and pass to our callback. */ 2278 STATIC int 2279 xfs_rmap_query_range_helper( 2280 struct xfs_btree_cur *cur, 2281 union xfs_btree_rec *rec, 2282 void *priv) 2283 { 2284 struct xfs_rmap_query_range_info *query = priv; 2285 struct xfs_rmap_irec irec; 2286 int error; 2287 2288 error = xfs_rmap_btrec_to_irec(rec, &irec); 2289 if (error) 2290 return error; 2291 return query->fn(cur, &irec, query->priv); 2292 } 2293 2294 /* Find all rmaps between two keys. */ 2295 int 2296 xfs_rmap_query_range( 2297 struct xfs_btree_cur *cur, 2298 struct xfs_rmap_irec *low_rec, 2299 struct xfs_rmap_irec *high_rec, 2300 xfs_rmap_query_range_fn fn, 2301 void *priv) 2302 { 2303 union xfs_btree_irec low_brec; 2304 union xfs_btree_irec high_brec; 2305 struct xfs_rmap_query_range_info query; 2306 2307 low_brec.r = *low_rec; 2308 high_brec.r = *high_rec; 2309 query.priv = priv; 2310 query.fn = fn; 2311 return xfs_btree_query_range(cur, &low_brec, &high_brec, 2312 xfs_rmap_query_range_helper, &query); 2313 } 2314 2315 /* Find all rmaps. */ 2316 int 2317 xfs_rmap_query_all( 2318 struct xfs_btree_cur *cur, 2319 xfs_rmap_query_range_fn fn, 2320 void *priv) 2321 { 2322 struct xfs_rmap_query_range_info query; 2323 2324 query.priv = priv; 2325 query.fn = fn; 2326 return xfs_btree_query_all(cur, xfs_rmap_query_range_helper, &query); 2327 } 2328 2329 /* Clean up after calling xfs_rmap_finish_one. */ 2330 void 2331 xfs_rmap_finish_one_cleanup( 2332 struct xfs_trans *tp, 2333 struct xfs_btree_cur *rcur, 2334 int error) 2335 { 2336 struct xfs_buf *agbp; 2337 2338 if (rcur == NULL) 2339 return; 2340 agbp = rcur->bc_ag.agbp; 2341 xfs_btree_del_cursor(rcur, error); 2342 if (error) 2343 xfs_trans_brelse(tp, agbp); 2344 } 2345 2346 /* 2347 * Process one of the deferred rmap operations. We pass back the 2348 * btree cursor to maintain our lock on the rmapbt between calls. 2349 * This saves time and eliminates a buffer deadlock between the 2350 * superblock and the AGF because we'll always grab them in the same 2351 * order. 2352 */ 2353 int 2354 xfs_rmap_finish_one( 2355 struct xfs_trans *tp, 2356 enum xfs_rmap_intent_type type, 2357 uint64_t owner, 2358 int whichfork, 2359 xfs_fileoff_t startoff, 2360 xfs_fsblock_t startblock, 2361 xfs_filblks_t blockcount, 2362 xfs_exntst_t state, 2363 struct xfs_btree_cur **pcur) 2364 { 2365 struct xfs_mount *mp = tp->t_mountp; 2366 struct xfs_btree_cur *rcur; 2367 struct xfs_buf *agbp = NULL; 2368 int error = 0; 2369 xfs_agnumber_t agno; 2370 struct xfs_owner_info oinfo; 2371 xfs_agblock_t bno; 2372 bool unwritten; 2373 2374 agno = XFS_FSB_TO_AGNO(mp, startblock); 2375 ASSERT(agno != NULLAGNUMBER); 2376 bno = XFS_FSB_TO_AGBNO(mp, startblock); 2377 2378 trace_xfs_rmap_deferred(mp, agno, type, bno, owner, whichfork, 2379 startoff, blockcount, state); 2380 2381 if (XFS_TEST_ERROR(false, mp, 2382 XFS_ERRTAG_RMAP_FINISH_ONE)) 2383 return -EIO; 2384 2385 /* 2386 * If we haven't gotten a cursor or the cursor AG doesn't match 2387 * the startblock, get one now. 2388 */ 2389 rcur = *pcur; 2390 if (rcur != NULL && rcur->bc_ag.agno != agno) { 2391 xfs_rmap_finish_one_cleanup(tp, rcur, 0); 2392 rcur = NULL; 2393 *pcur = NULL; 2394 } 2395 if (rcur == NULL) { 2396 /* 2397 * Refresh the freelist before we start changing the 2398 * rmapbt, because a shape change could cause us to 2399 * allocate blocks. 2400 */ 2401 error = xfs_free_extent_fix_freelist(tp, agno, &agbp); 2402 if (error) 2403 return error; 2404 if (XFS_IS_CORRUPT(tp->t_mountp, !agbp)) 2405 return -EFSCORRUPTED; 2406 2407 rcur = xfs_rmapbt_init_cursor(mp, tp, agbp, agno); 2408 } 2409 *pcur = rcur; 2410 2411 xfs_rmap_ino_owner(&oinfo, owner, whichfork, startoff); 2412 unwritten = state == XFS_EXT_UNWRITTEN; 2413 bno = XFS_FSB_TO_AGBNO(rcur->bc_mp, startblock); 2414 2415 switch (type) { 2416 case XFS_RMAP_ALLOC: 2417 case XFS_RMAP_MAP: 2418 error = xfs_rmap_map(rcur, bno, blockcount, unwritten, &oinfo); 2419 break; 2420 case XFS_RMAP_MAP_SHARED: 2421 error = xfs_rmap_map_shared(rcur, bno, blockcount, unwritten, 2422 &oinfo); 2423 break; 2424 case XFS_RMAP_FREE: 2425 case XFS_RMAP_UNMAP: 2426 error = xfs_rmap_unmap(rcur, bno, blockcount, unwritten, 2427 &oinfo); 2428 break; 2429 case XFS_RMAP_UNMAP_SHARED: 2430 error = xfs_rmap_unmap_shared(rcur, bno, blockcount, unwritten, 2431 &oinfo); 2432 break; 2433 case XFS_RMAP_CONVERT: 2434 error = xfs_rmap_convert(rcur, bno, blockcount, !unwritten, 2435 &oinfo); 2436 break; 2437 case XFS_RMAP_CONVERT_SHARED: 2438 error = xfs_rmap_convert_shared(rcur, bno, blockcount, 2439 !unwritten, &oinfo); 2440 break; 2441 default: 2442 ASSERT(0); 2443 error = -EFSCORRUPTED; 2444 } 2445 return error; 2446 } 2447 2448 /* 2449 * Don't defer an rmap if we aren't an rmap filesystem. 2450 */ 2451 static bool 2452 xfs_rmap_update_is_needed( 2453 struct xfs_mount *mp, 2454 int whichfork) 2455 { 2456 return xfs_sb_version_hasrmapbt(&mp->m_sb) && whichfork != XFS_COW_FORK; 2457 } 2458 2459 /* 2460 * Record a rmap intent; the list is kept sorted first by AG and then by 2461 * increasing age. 2462 */ 2463 static void 2464 __xfs_rmap_add( 2465 struct xfs_trans *tp, 2466 enum xfs_rmap_intent_type type, 2467 uint64_t owner, 2468 int whichfork, 2469 struct xfs_bmbt_irec *bmap) 2470 { 2471 struct xfs_rmap_intent *ri; 2472 2473 trace_xfs_rmap_defer(tp->t_mountp, 2474 XFS_FSB_TO_AGNO(tp->t_mountp, bmap->br_startblock), 2475 type, 2476 XFS_FSB_TO_AGBNO(tp->t_mountp, bmap->br_startblock), 2477 owner, whichfork, 2478 bmap->br_startoff, 2479 bmap->br_blockcount, 2480 bmap->br_state); 2481 2482 ri = kmem_alloc(sizeof(struct xfs_rmap_intent), KM_NOFS); 2483 INIT_LIST_HEAD(&ri->ri_list); 2484 ri->ri_type = type; 2485 ri->ri_owner = owner; 2486 ri->ri_whichfork = whichfork; 2487 ri->ri_bmap = *bmap; 2488 2489 xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_RMAP, &ri->ri_list); 2490 } 2491 2492 /* Map an extent into a file. */ 2493 void 2494 xfs_rmap_map_extent( 2495 struct xfs_trans *tp, 2496 struct xfs_inode *ip, 2497 int whichfork, 2498 struct xfs_bmbt_irec *PREV) 2499 { 2500 enum xfs_rmap_intent_type type = XFS_RMAP_MAP; 2501 2502 if (!xfs_rmap_update_is_needed(tp->t_mountp, whichfork)) 2503 return; 2504 2505 if (whichfork != XFS_ATTR_FORK && xfs_is_reflink_inode(ip)) 2506 type = XFS_RMAP_MAP_SHARED; 2507 2508 __xfs_rmap_add(tp, type, ip->i_ino, whichfork, PREV); 2509 } 2510 2511 /* Unmap an extent out of a file. */ 2512 void 2513 xfs_rmap_unmap_extent( 2514 struct xfs_trans *tp, 2515 struct xfs_inode *ip, 2516 int whichfork, 2517 struct xfs_bmbt_irec *PREV) 2518 { 2519 enum xfs_rmap_intent_type type = XFS_RMAP_UNMAP; 2520 2521 if (!xfs_rmap_update_is_needed(tp->t_mountp, whichfork)) 2522 return; 2523 2524 if (whichfork != XFS_ATTR_FORK && xfs_is_reflink_inode(ip)) 2525 type = XFS_RMAP_UNMAP_SHARED; 2526 2527 __xfs_rmap_add(tp, type, ip->i_ino, whichfork, PREV); 2528 } 2529 2530 /* 2531 * Convert a data fork extent from unwritten to real or vice versa. 2532 * 2533 * Note that tp can be NULL here as no transaction is used for COW fork 2534 * unwritten conversion. 2535 */ 2536 void 2537 xfs_rmap_convert_extent( 2538 struct xfs_mount *mp, 2539 struct xfs_trans *tp, 2540 struct xfs_inode *ip, 2541 int whichfork, 2542 struct xfs_bmbt_irec *PREV) 2543 { 2544 enum xfs_rmap_intent_type type = XFS_RMAP_CONVERT; 2545 2546 if (!xfs_rmap_update_is_needed(mp, whichfork)) 2547 return; 2548 2549 if (whichfork != XFS_ATTR_FORK && xfs_is_reflink_inode(ip)) 2550 type = XFS_RMAP_CONVERT_SHARED; 2551 2552 __xfs_rmap_add(tp, type, ip->i_ino, whichfork, PREV); 2553 } 2554 2555 /* Schedule the creation of an rmap for non-file data. */ 2556 void 2557 xfs_rmap_alloc_extent( 2558 struct xfs_trans *tp, 2559 xfs_agnumber_t agno, 2560 xfs_agblock_t bno, 2561 xfs_extlen_t len, 2562 uint64_t owner) 2563 { 2564 struct xfs_bmbt_irec bmap; 2565 2566 if (!xfs_rmap_update_is_needed(tp->t_mountp, XFS_DATA_FORK)) 2567 return; 2568 2569 bmap.br_startblock = XFS_AGB_TO_FSB(tp->t_mountp, agno, bno); 2570 bmap.br_blockcount = len; 2571 bmap.br_startoff = 0; 2572 bmap.br_state = XFS_EXT_NORM; 2573 2574 __xfs_rmap_add(tp, XFS_RMAP_ALLOC, owner, XFS_DATA_FORK, &bmap); 2575 } 2576 2577 /* Schedule the deletion of an rmap for non-file data. */ 2578 void 2579 xfs_rmap_free_extent( 2580 struct xfs_trans *tp, 2581 xfs_agnumber_t agno, 2582 xfs_agblock_t bno, 2583 xfs_extlen_t len, 2584 uint64_t owner) 2585 { 2586 struct xfs_bmbt_irec bmap; 2587 2588 if (!xfs_rmap_update_is_needed(tp->t_mountp, XFS_DATA_FORK)) 2589 return; 2590 2591 bmap.br_startblock = XFS_AGB_TO_FSB(tp->t_mountp, agno, bno); 2592 bmap.br_blockcount = len; 2593 bmap.br_startoff = 0; 2594 bmap.br_state = XFS_EXT_NORM; 2595 2596 __xfs_rmap_add(tp, XFS_RMAP_FREE, owner, XFS_DATA_FORK, &bmap); 2597 } 2598 2599 /* Compare rmap records. Returns -1 if a < b, 1 if a > b, and 0 if equal. */ 2600 int 2601 xfs_rmap_compare( 2602 const struct xfs_rmap_irec *a, 2603 const struct xfs_rmap_irec *b) 2604 { 2605 __u64 oa; 2606 __u64 ob; 2607 2608 oa = xfs_rmap_irec_offset_pack(a); 2609 ob = xfs_rmap_irec_offset_pack(b); 2610 2611 if (a->rm_startblock < b->rm_startblock) 2612 return -1; 2613 else if (a->rm_startblock > b->rm_startblock) 2614 return 1; 2615 else if (a->rm_owner < b->rm_owner) 2616 return -1; 2617 else if (a->rm_owner > b->rm_owner) 2618 return 1; 2619 else if (oa < ob) 2620 return -1; 2621 else if (oa > ob) 2622 return 1; 2623 else 2624 return 0; 2625 } 2626 2627 /* Is there a record covering a given extent? */ 2628 int 2629 xfs_rmap_has_record( 2630 struct xfs_btree_cur *cur, 2631 xfs_agblock_t bno, 2632 xfs_extlen_t len, 2633 bool *exists) 2634 { 2635 union xfs_btree_irec low; 2636 union xfs_btree_irec high; 2637 2638 memset(&low, 0, sizeof(low)); 2639 low.r.rm_startblock = bno; 2640 memset(&high, 0xFF, sizeof(high)); 2641 high.r.rm_startblock = bno + len - 1; 2642 2643 return xfs_btree_has_record(cur, &low, &high, exists); 2644 } 2645 2646 /* 2647 * Is there a record for this owner completely covering a given physical 2648 * extent? If so, *has_rmap will be set to true. If there is no record 2649 * or the record only covers part of the range, we set *has_rmap to false. 2650 * This function doesn't perform range lookups or offset checks, so it is 2651 * not suitable for checking data fork blocks. 2652 */ 2653 int 2654 xfs_rmap_record_exists( 2655 struct xfs_btree_cur *cur, 2656 xfs_agblock_t bno, 2657 xfs_extlen_t len, 2658 const struct xfs_owner_info *oinfo, 2659 bool *has_rmap) 2660 { 2661 uint64_t owner; 2662 uint64_t offset; 2663 unsigned int flags; 2664 int has_record; 2665 struct xfs_rmap_irec irec; 2666 int error; 2667 2668 xfs_owner_info_unpack(oinfo, &owner, &offset, &flags); 2669 ASSERT(XFS_RMAP_NON_INODE_OWNER(owner) || 2670 (flags & XFS_RMAP_BMBT_BLOCK)); 2671 2672 error = xfs_rmap_lookup_le(cur, bno, len, owner, offset, flags, 2673 &has_record); 2674 if (error) 2675 return error; 2676 if (!has_record) { 2677 *has_rmap = false; 2678 return 0; 2679 } 2680 2681 error = xfs_rmap_get_rec(cur, &irec, &has_record); 2682 if (error) 2683 return error; 2684 if (!has_record) { 2685 *has_rmap = false; 2686 return 0; 2687 } 2688 2689 *has_rmap = (irec.rm_owner == owner && irec.rm_startblock <= bno && 2690 irec.rm_startblock + irec.rm_blockcount >= bno + len); 2691 return 0; 2692 } 2693 2694 struct xfs_rmap_key_state { 2695 uint64_t owner; 2696 uint64_t offset; 2697 unsigned int flags; 2698 }; 2699 2700 /* For each rmap given, figure out if it doesn't match the key we want. */ 2701 STATIC int 2702 xfs_rmap_has_other_keys_helper( 2703 struct xfs_btree_cur *cur, 2704 struct xfs_rmap_irec *rec, 2705 void *priv) 2706 { 2707 struct xfs_rmap_key_state *rks = priv; 2708 2709 if (rks->owner == rec->rm_owner && rks->offset == rec->rm_offset && 2710 ((rks->flags & rec->rm_flags) & XFS_RMAP_KEY_FLAGS) == rks->flags) 2711 return 0; 2712 return -ECANCELED; 2713 } 2714 2715 /* 2716 * Given an extent and some owner info, can we find records overlapping 2717 * the extent whose owner info does not match the given owner? 2718 */ 2719 int 2720 xfs_rmap_has_other_keys( 2721 struct xfs_btree_cur *cur, 2722 xfs_agblock_t bno, 2723 xfs_extlen_t len, 2724 const struct xfs_owner_info *oinfo, 2725 bool *has_rmap) 2726 { 2727 struct xfs_rmap_irec low = {0}; 2728 struct xfs_rmap_irec high; 2729 struct xfs_rmap_key_state rks; 2730 int error; 2731 2732 xfs_owner_info_unpack(oinfo, &rks.owner, &rks.offset, &rks.flags); 2733 *has_rmap = false; 2734 2735 low.rm_startblock = bno; 2736 memset(&high, 0xFF, sizeof(high)); 2737 high.rm_startblock = bno + len - 1; 2738 2739 error = xfs_rmap_query_range(cur, &low, &high, 2740 xfs_rmap_has_other_keys_helper, &rks); 2741 if (error == -ECANCELED) { 2742 *has_rmap = true; 2743 return 0; 2744 } 2745 2746 return error; 2747 } 2748 2749 const struct xfs_owner_info XFS_RMAP_OINFO_SKIP_UPDATE = { 2750 .oi_owner = XFS_RMAP_OWN_NULL, 2751 }; 2752 const struct xfs_owner_info XFS_RMAP_OINFO_ANY_OWNER = { 2753 .oi_owner = XFS_RMAP_OWN_UNKNOWN, 2754 }; 2755 const struct xfs_owner_info XFS_RMAP_OINFO_FS = { 2756 .oi_owner = XFS_RMAP_OWN_FS, 2757 }; 2758 const struct xfs_owner_info XFS_RMAP_OINFO_LOG = { 2759 .oi_owner = XFS_RMAP_OWN_LOG, 2760 }; 2761 const struct xfs_owner_info XFS_RMAP_OINFO_AG = { 2762 .oi_owner = XFS_RMAP_OWN_AG, 2763 }; 2764 const struct xfs_owner_info XFS_RMAP_OINFO_INOBT = { 2765 .oi_owner = XFS_RMAP_OWN_INOBT, 2766 }; 2767 const struct xfs_owner_info XFS_RMAP_OINFO_INODES = { 2768 .oi_owner = XFS_RMAP_OWN_INODES, 2769 }; 2770 const struct xfs_owner_info XFS_RMAP_OINFO_REFC = { 2771 .oi_owner = XFS_RMAP_OWN_REFC, 2772 }; 2773 const struct xfs_owner_info XFS_RMAP_OINFO_COW = { 2774 .oi_owner = XFS_RMAP_OWN_COW, 2775 }; 2776