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