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