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