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