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