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