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