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