1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (c) 2021-2024 Oracle. All Rights Reserved. 4 * Author: Darrick J. Wong <djwong@kernel.org> 5 */ 6 #include "xfs_platform.h" 7 #include "xfs_fs.h" 8 #include "xfs_shared.h" 9 #include "xfs_format.h" 10 #include "xfs_trans_resv.h" 11 #include "xfs_mount.h" 12 #include "xfs_log_format.h" 13 #include "xfs_trans.h" 14 #include "xfs_inode.h" 15 #include "xfs_ialloc.h" 16 #include "xfs_quota.h" 17 #include "xfs_bmap.h" 18 #include "xfs_bmap_btree.h" 19 #include "xfs_trans_space.h" 20 #include "xfs_dir2.h" 21 #include "xfs_exchrange.h" 22 #include "xfs_exchmaps.h" 23 #include "xfs_defer.h" 24 #include "xfs_symlink_remote.h" 25 #include "xfs_metafile.h" 26 #include "scrub/scrub.h" 27 #include "scrub/common.h" 28 #include "scrub/repair.h" 29 #include "scrub/trace.h" 30 #include "scrub/tempfile.h" 31 #include "scrub/tempexch.h" 32 #include "scrub/xfile.h" 33 34 /* 35 * Create a temporary file for reconstructing metadata, with the intention of 36 * atomically exchanging the temporary file's contents with the file that's 37 * being repaired. 38 */ 39 int 40 xrep_tempfile_create( 41 struct xfs_scrub *sc, 42 uint16_t mode) 43 { 44 struct xfs_icreate_args args = { 45 .pip = sc->mp->m_rootip, 46 .mode = mode, 47 .flags = XFS_ICREATE_TMPFILE | XFS_ICREATE_UNLINKABLE, 48 }; 49 struct xfs_mount *mp = sc->mp; 50 struct xfs_trans *tp = NULL; 51 struct xfs_dquot *udqp; 52 struct xfs_dquot *gdqp; 53 struct xfs_dquot *pdqp; 54 struct xfs_trans_res *tres; 55 struct xfs_inode *dp = mp->m_rootip; 56 xfs_ino_t ino; 57 unsigned int resblks; 58 bool is_dir = S_ISDIR(mode); 59 int error; 60 61 if (xfs_is_shutdown(mp)) 62 return -EIO; 63 if (xfs_is_readonly(mp)) 64 return -EROFS; 65 66 ASSERT(sc->tp == NULL); 67 ASSERT(sc->tempip == NULL); 68 69 /* 70 * Make sure that we have allocated dquot(s) on disk. The temporary 71 * inode should be completely root owned so that we don't fail due to 72 * quota limits. 73 */ 74 error = xfs_icreate_dqalloc(&args, &udqp, &gdqp, &pdqp); 75 if (error) 76 return error; 77 78 if (is_dir) { 79 resblks = xfs_mkdir_space_res(mp, 0); 80 tres = &M_RES(mp)->tr_mkdir; 81 } else { 82 resblks = XFS_IALLOC_SPACE_RES(mp); 83 tres = &M_RES(mp)->tr_create_tmpfile; 84 } 85 86 error = xfs_trans_alloc_icreate(mp, tres, udqp, gdqp, pdqp, resblks, 87 &tp); 88 if (error) 89 goto out_release_dquots; 90 91 /* Allocate inode, set up directory. */ 92 error = xfs_dialloc(&tp, &args, &ino); 93 if (error) 94 goto out_trans_cancel; 95 error = xfs_icreate(tp, ino, &args, &sc->tempip); 96 if (error) 97 goto out_trans_cancel; 98 99 /* We don't touch file data, so drop the realtime flags. */ 100 sc->tempip->i_diflags &= ~(XFS_DIFLAG_REALTIME | XFS_DIFLAG_RTINHERIT); 101 xfs_trans_log_inode(tp, sc->tempip, XFS_ILOG_CORE); 102 103 /* 104 * Mark our temporary file as private so that LSMs and the ACL code 105 * don't try to add their own metadata or reason about these files. 106 * The file should never be exposed to userspace. 107 */ 108 VFS_I(sc->tempip)->i_flags |= S_PRIVATE; 109 VFS_I(sc->tempip)->i_opflags &= ~IOP_XATTR; 110 111 if (is_dir) { 112 error = xfs_dir_init(tp, sc->tempip, dp); 113 if (error) 114 goto out_trans_cancel; 115 } else if (S_ISLNK(VFS_I(sc->tempip)->i_mode)) { 116 /* 117 * Initialize the temporary symlink with a meaningless target 118 * that won't trip the verifiers. Repair must rewrite the 119 * target with meaningful content before swapping with the file 120 * being repaired. A single-byte target will not write a 121 * remote target block, so the owner is irrelevant. 122 */ 123 error = xfs_symlink_write_target(tp, sc->tempip, 124 I_INO(sc->tempip), ".", 1, 0, 0); 125 if (error) 126 goto out_trans_cancel; 127 } 128 129 /* 130 * Attach the dquot(s) to the inodes and modify them incore. 131 * These ids of the inode couldn't have changed since the new 132 * inode has been locked ever since it was created. 133 */ 134 xfs_qm_vop_create_dqattach(tp, sc->tempip, udqp, gdqp, pdqp); 135 136 /* 137 * Put our temp file on the unlinked list so it's purged automatically. 138 * All file-based metadata being reconstructed using this file must be 139 * atomically exchanged with the original file because the contents 140 * here will be purged when the inode is dropped or log recovery cleans 141 * out the unlinked list. 142 */ 143 error = xfs_iunlink(tp, sc->tempip); 144 if (error) 145 goto out_trans_cancel; 146 147 error = xfs_trans_commit(tp); 148 if (error) 149 goto out_release_inode; 150 151 trace_xrep_tempfile_create(sc); 152 153 xfs_qm_dqrele(udqp); 154 xfs_qm_dqrele(gdqp); 155 xfs_qm_dqrele(pdqp); 156 157 /* Finish setting up the incore / vfs context. */ 158 xfs_iunlock(sc->tempip, XFS_ILOCK_EXCL); 159 xfs_setup_iops(sc->tempip); 160 xfs_finish_inode_setup(sc->tempip); 161 162 sc->temp_ilock_flags = 0; 163 return error; 164 165 out_trans_cancel: 166 xfs_trans_cancel(tp); 167 out_release_inode: 168 /* 169 * Wait until after the current transaction is aborted to finish the 170 * setup of the inode and release the inode. This prevents recursive 171 * transactions and deadlocks from xfs_inactive. 172 */ 173 if (sc->tempip) { 174 xfs_iunlock(sc->tempip, XFS_ILOCK_EXCL); 175 xfs_finish_inode_setup(sc->tempip); 176 xchk_irele(sc, sc->tempip); 177 sc->tempip = NULL; 178 } 179 out_release_dquots: 180 xfs_qm_dqrele(udqp); 181 xfs_qm_dqrele(gdqp); 182 xfs_qm_dqrele(pdqp); 183 184 return error; 185 } 186 187 /* 188 * Move sc->tempip from the regular directory tree to the metadata directory 189 * tree if sc->ip is part of the metadata directory tree and tempip has an 190 * eligible file mode. 191 * 192 * Temporary files have to be created before we even know which inode we're 193 * going to scrub, so we assume that they will be part of the regular directory 194 * tree. If it turns out that we're actually scrubbing a file from the 195 * metadata directory tree, we have to subtract the temp file from the root 196 * dquots and detach the dquots prior to setting the METADATA iflag. However, 197 * the scrub setup functions grab sc->ip and create sc->tempip before we 198 * actually get around to checking if the file mode is the right type for the 199 * scrubber. 200 */ 201 int 202 xrep_tempfile_adjust_directory_tree( 203 struct xfs_scrub *sc) 204 { 205 int error; 206 207 if (!sc->tempip) 208 return 0; 209 210 ASSERT(sc->tp == NULL); 211 ASSERT(!xfs_is_metadir_inode(sc->tempip)); 212 213 if (!sc->ip || !xfs_is_metadir_inode(sc->ip)) 214 return 0; 215 if (!S_ISDIR(VFS_I(sc->tempip)->i_mode) && 216 !S_ISREG(VFS_I(sc->tempip)->i_mode)) 217 return 0; 218 219 xfs_ilock(sc->tempip, XFS_IOLOCK_EXCL); 220 sc->temp_ilock_flags |= XFS_IOLOCK_EXCL; 221 222 error = xchk_trans_alloc(sc, 0); 223 if (error) 224 goto out_iolock; 225 226 xrep_tempfile_ilock(sc); 227 xfs_trans_ijoin(sc->tp, sc->tempip, 0); 228 229 /* Metadir files are not accounted in quota, so drop icount */ 230 xfs_trans_mod_dquot_byino(sc->tp, sc->tempip, XFS_TRANS_DQ_ICOUNT, -1L); 231 xfs_metafile_set_iflag(sc->tp, sc->tempip, XFS_METAFILE_UNKNOWN); 232 233 error = xrep_trans_commit(sc); 234 if (error) 235 goto out_ilock; 236 237 xfs_iflags_set(sc->tempip, XFS_IRECOVERY); 238 xfs_qm_dqdetach(sc->tempip); 239 out_ilock: 240 xrep_tempfile_iunlock(sc); 241 out_iolock: 242 xrep_tempfile_iounlock(sc); 243 return error; 244 } 245 246 /* 247 * Remove this temporary file from the metadata directory tree so that it can 248 * be inactivated the normal way. 249 */ 250 STATIC int 251 xrep_tempfile_remove_metadir( 252 struct xfs_scrub *sc) 253 { 254 int error; 255 256 if (!sc->tempip || !xfs_is_metadir_inode(sc->tempip)) 257 return 0; 258 259 ASSERT(sc->tp == NULL); 260 261 xfs_iflags_clear(sc->tempip, XFS_IRECOVERY); 262 263 xfs_ilock(sc->tempip, XFS_IOLOCK_EXCL); 264 sc->temp_ilock_flags |= XFS_IOLOCK_EXCL; 265 266 error = xchk_trans_alloc(sc, 0); 267 if (error) 268 goto out_iolock; 269 270 xrep_tempfile_ilock(sc); 271 xfs_trans_ijoin(sc->tp, sc->tempip, 0); 272 273 xfs_metafile_clear_iflag(sc->tp, sc->tempip); 274 275 /* Non-metadir files are accounted in quota, so bump bcount/icount */ 276 error = xfs_qm_dqattach_locked(sc->tempip, false); 277 if (error) 278 goto out_cancel; 279 280 xfs_trans_mod_dquot_byino(sc->tp, sc->tempip, XFS_TRANS_DQ_ICOUNT, 1L); 281 xfs_trans_mod_dquot_byino(sc->tp, sc->tempip, XFS_TRANS_DQ_BCOUNT, 282 sc->tempip->i_nblocks); 283 error = xrep_trans_commit(sc); 284 goto out_ilock; 285 286 out_cancel: 287 xchk_trans_cancel(sc); 288 out_ilock: 289 xrep_tempfile_iunlock(sc); 290 out_iolock: 291 xrep_tempfile_iounlock(sc); 292 return error; 293 } 294 295 /* Take IOLOCK_EXCL on the temporary file, maybe. */ 296 bool 297 xrep_tempfile_iolock_nowait( 298 struct xfs_scrub *sc) 299 { 300 if (xfs_ilock_nowait(sc->tempip, XFS_IOLOCK_EXCL)) { 301 sc->temp_ilock_flags |= XFS_IOLOCK_EXCL; 302 return true; 303 } 304 305 return false; 306 } 307 308 /* 309 * Take the temporary file's IOLOCK while holding a different inode's IOLOCK. 310 * In theory nobody else should hold the tempfile's IOLOCK, but we use trylock 311 * to avoid deadlocks and lockdep complaints. 312 */ 313 int 314 xrep_tempfile_iolock_polled( 315 struct xfs_scrub *sc) 316 { 317 int error = 0; 318 319 while (!xrep_tempfile_iolock_nowait(sc)) { 320 if (xchk_should_terminate(sc, &error)) 321 return error; 322 delay(1); 323 } 324 325 return 0; 326 } 327 328 /* Release IOLOCK_EXCL on the temporary file. */ 329 void 330 xrep_tempfile_iounlock( 331 struct xfs_scrub *sc) 332 { 333 xfs_iunlock(sc->tempip, XFS_IOLOCK_EXCL); 334 sc->temp_ilock_flags &= ~XFS_IOLOCK_EXCL; 335 } 336 337 /* Prepare the temporary file for metadata updates by grabbing ILOCK_EXCL. */ 338 void 339 xrep_tempfile_ilock( 340 struct xfs_scrub *sc) 341 { 342 sc->temp_ilock_flags |= XFS_ILOCK_EXCL; 343 xfs_ilock(sc->tempip, XFS_ILOCK_EXCL); 344 } 345 346 /* Try to grab ILOCK_EXCL on the temporary file. */ 347 bool 348 xrep_tempfile_ilock_nowait( 349 struct xfs_scrub *sc) 350 { 351 if (xfs_ilock_nowait(sc->tempip, XFS_ILOCK_EXCL)) { 352 sc->temp_ilock_flags |= XFS_ILOCK_EXCL; 353 return true; 354 } 355 356 return false; 357 } 358 359 /* Unlock ILOCK_EXCL on the temporary file after an update. */ 360 void 361 xrep_tempfile_iunlock( 362 struct xfs_scrub *sc) 363 { 364 xfs_iunlock(sc->tempip, XFS_ILOCK_EXCL); 365 sc->temp_ilock_flags &= ~XFS_ILOCK_EXCL; 366 } 367 368 /* 369 * Begin the process of making changes to both the file being scrubbed and 370 * the temporary file by taking ILOCK_EXCL on both. 371 */ 372 void 373 xrep_tempfile_ilock_both( 374 struct xfs_scrub *sc) 375 { 376 xfs_lock_two_inodes(sc->ip, XFS_ILOCK_EXCL, sc->tempip, XFS_ILOCK_EXCL); 377 sc->ilock_flags |= XFS_ILOCK_EXCL; 378 sc->temp_ilock_flags |= XFS_ILOCK_EXCL; 379 } 380 381 /* Unlock ILOCK_EXCL on both files. */ 382 void 383 xrep_tempfile_iunlock_both( 384 struct xfs_scrub *sc) 385 { 386 xrep_tempfile_iunlock(sc); 387 xchk_iunlock(sc, XFS_ILOCK_EXCL); 388 } 389 390 /* Release the temporary file. */ 391 void 392 xrep_tempfile_rele( 393 struct xfs_scrub *sc) 394 { 395 if (!sc->tempip) 396 return; 397 398 if (sc->temp_ilock_flags) { 399 xfs_iunlock(sc->tempip, sc->temp_ilock_flags); 400 sc->temp_ilock_flags = 0; 401 } 402 403 xrep_tempfile_remove_metadir(sc); 404 xchk_irele(sc, sc->tempip); 405 sc->tempip = NULL; 406 } 407 408 /* 409 * Make sure that the given range of the data fork of the temporary file is 410 * mapped to written blocks. The caller must ensure that both inodes are 411 * joined to the transaction. 412 */ 413 int 414 xrep_tempfile_prealloc( 415 struct xfs_scrub *sc, 416 xfs_fileoff_t off, 417 xfs_filblks_t len) 418 { 419 struct xfs_bmbt_irec map; 420 xfs_fileoff_t end = off + len; 421 int error; 422 423 ASSERT(sc->tempip != NULL); 424 ASSERT(!XFS_NOT_DQATTACHED(sc->mp, sc->tempip)); 425 426 for (; off < end; off = map.br_startoff + map.br_blockcount) { 427 int nmaps = 1; 428 429 /* 430 * If we have a real extent mapping this block then we're 431 * in ok shape. 432 */ 433 error = xfs_bmapi_read(sc->tempip, off, end - off, &map, &nmaps, 434 XFS_DATA_FORK); 435 if (error) 436 return error; 437 if (nmaps == 0) { 438 ASSERT(nmaps != 0); 439 return -EFSCORRUPTED; 440 } 441 442 if (xfs_bmap_is_written_extent(&map)) 443 continue; 444 445 /* 446 * If we find a delalloc reservation then something is very 447 * very wrong. Bail out. 448 */ 449 if (map.br_startblock == DELAYSTARTBLOCK) 450 return -EFSCORRUPTED; 451 452 /* 453 * Make sure this block has a real zeroed extent allocated to 454 * it. 455 */ 456 nmaps = 1; 457 error = xfs_bmapi_write(sc->tp, sc->tempip, off, end - off, 458 XFS_BMAPI_CONVERT | XFS_BMAPI_ZERO, 0, &map, 459 &nmaps); 460 if (error) 461 return error; 462 if (nmaps != 1) 463 return -EFSCORRUPTED; 464 465 trace_xrep_tempfile_prealloc(sc, XFS_DATA_FORK, &map); 466 467 /* Commit new extent and all deferred work. */ 468 error = xfs_defer_finish(&sc->tp); 469 if (error) 470 return error; 471 } 472 473 return 0; 474 } 475 476 /* 477 * Write data to each block of a file. The given range of the tempfile's data 478 * fork must already be populated with written extents. 479 */ 480 int 481 xrep_tempfile_copyin( 482 struct xfs_scrub *sc, 483 xfs_fileoff_t off, 484 xfs_filblks_t len, 485 xrep_tempfile_copyin_fn prep_fn, 486 void *data) 487 { 488 LIST_HEAD(buffers_list); 489 struct xfs_mount *mp = sc->mp; 490 struct xfs_buf *bp; 491 xfs_fileoff_t flush_mask; 492 xfs_fileoff_t end = off + len; 493 loff_t pos = XFS_FSB_TO_B(mp, off); 494 int error = 0; 495 496 ASSERT(S_ISREG(VFS_I(sc->tempip)->i_mode)); 497 498 /* Flush buffers to disk every 512K */ 499 flush_mask = XFS_B_TO_FSBT(mp, (1U << 19)) - 1; 500 501 for (; off < end; off++, pos += mp->m_sb.sb_blocksize) { 502 struct xfs_bmbt_irec map; 503 int nmaps = 1; 504 505 /* Read block mapping for this file block. */ 506 error = xfs_bmapi_read(sc->tempip, off, 1, &map, &nmaps, 0); 507 if (error) 508 goto out_err; 509 if (nmaps == 0 || !xfs_bmap_is_written_extent(&map)) { 510 error = -EFSCORRUPTED; 511 goto out_err; 512 } 513 514 /* Get the metadata buffer for this offset in the file. */ 515 error = xfs_trans_get_buf(sc->tp, mp->m_ddev_targp, 516 XFS_FSB_TO_DADDR(mp, map.br_startblock), 517 mp->m_bsize, 0, &bp); 518 if (error) 519 goto out_err; 520 521 trace_xrep_tempfile_copyin(sc, XFS_DATA_FORK, &map); 522 523 /* Read in a block's worth of data from the xfile. */ 524 error = prep_fn(sc, bp, data); 525 if (error) { 526 xfs_trans_brelse(sc->tp, bp); 527 goto out_err; 528 } 529 530 /* Queue buffer, and flush if we have too much dirty data. */ 531 xfs_buf_delwri_queue_here(bp, &buffers_list); 532 xfs_trans_brelse(sc->tp, bp); 533 534 if (!(off & flush_mask)) { 535 error = xfs_buf_delwri_submit(&buffers_list); 536 if (error) 537 goto out_err; 538 } 539 } 540 541 /* 542 * Write the new blocks to disk. If the ordered list isn't empty after 543 * that, then something went wrong and we have to fail. This should 544 * never happen, but we'll check anyway. 545 */ 546 error = xfs_buf_delwri_submit(&buffers_list); 547 if (error) 548 goto out_err; 549 550 if (!list_empty(&buffers_list)) { 551 ASSERT(list_empty(&buffers_list)); 552 error = -EIO; 553 goto out_err; 554 } 555 556 return 0; 557 558 out_err: 559 xfs_buf_delwri_cancel(&buffers_list); 560 return error; 561 } 562 563 /* 564 * Set the temporary file's size. Caller must join the tempfile to the scrub 565 * transaction and is responsible for adjusting block mappings as needed. 566 */ 567 int 568 xrep_tempfile_set_isize( 569 struct xfs_scrub *sc, 570 unsigned long long isize) 571 { 572 if (sc->tempip->i_disk_size == isize) 573 return 0; 574 575 sc->tempip->i_disk_size = isize; 576 i_size_write(VFS_I(sc->tempip), isize); 577 return xrep_tempfile_roll_trans(sc); 578 } 579 580 /* 581 * Roll a repair transaction involving the temporary file. Caller must join 582 * both the temporary file and the file being scrubbed to the transaction. 583 * This function return with both inodes joined to a new scrub transaction, 584 * or the usual negative errno. 585 */ 586 int 587 xrep_tempfile_roll_trans( 588 struct xfs_scrub *sc) 589 { 590 int error; 591 592 xfs_trans_log_inode(sc->tp, sc->tempip, XFS_ILOG_CORE); 593 error = xrep_roll_trans(sc); 594 if (error) 595 return error; 596 597 xfs_trans_ijoin(sc->tp, sc->tempip, 0); 598 return 0; 599 } 600 601 /* 602 * Fill out the mapping exchange request in preparation for atomically 603 * committing the contents of a metadata file that we've rebuilt in the temp 604 * file. 605 */ 606 STATIC int 607 xrep_tempexch_prep_request( 608 struct xfs_scrub *sc, 609 int whichfork, 610 xfs_fileoff_t off, 611 xfs_filblks_t len, 612 struct xrep_tempexch *tx) 613 { 614 struct xfs_exchmaps_req *req = &tx->req; 615 616 memset(tx, 0, sizeof(struct xrep_tempexch)); 617 618 /* COW forks don't exist on disk. */ 619 if (whichfork == XFS_COW_FORK) { 620 ASSERT(0); 621 return -EINVAL; 622 } 623 624 /* Both files should have the relevant forks. */ 625 if (!xfs_ifork_ptr(sc->ip, whichfork) || 626 !xfs_ifork_ptr(sc->tempip, whichfork)) { 627 ASSERT(xfs_ifork_ptr(sc->ip, whichfork) != NULL); 628 ASSERT(xfs_ifork_ptr(sc->tempip, whichfork) != NULL); 629 return -EINVAL; 630 } 631 632 /* Exchange all mappings in both forks. */ 633 req->ip1 = sc->tempip; 634 req->ip2 = sc->ip; 635 req->startoff1 = off; 636 req->startoff2 = off; 637 switch (whichfork) { 638 case XFS_ATTR_FORK: 639 req->flags |= XFS_EXCHMAPS_ATTR_FORK; 640 break; 641 case XFS_DATA_FORK: 642 /* Exchange sizes when exchanging all data fork mappings. */ 643 if (off == 0 && len == XFS_MAX_FILEOFF) 644 req->flags |= XFS_EXCHMAPS_SET_SIZES; 645 break; 646 } 647 req->blockcount = len; 648 649 return 0; 650 } 651 652 /* 653 * Fill out the mapping exchange resource estimation structures in preparation 654 * for exchanging the contents of a metadata file that we've rebuilt in the 655 * temp file. Caller must hold IOLOCK_EXCL but not ILOCK_EXCL on both files. 656 */ 657 STATIC int 658 xrep_tempexch_estimate( 659 struct xfs_scrub *sc, 660 struct xrep_tempexch *tx) 661 { 662 struct xfs_exchmaps_req *req = &tx->req; 663 struct xfs_ifork *ifp; 664 struct xfs_ifork *tifp; 665 int whichfork = xfs_exchmaps_reqfork(req); 666 int state = 0; 667 668 /* 669 * The exchmaps code only knows how to exchange file fork space 670 * mappings. Any fork data in local format must be promoted to a 671 * single block before the exchange can take place. 672 */ 673 ifp = xfs_ifork_ptr(sc->ip, whichfork); 674 if (ifp->if_format == XFS_DINODE_FMT_LOCAL) 675 state |= 1; 676 677 tifp = xfs_ifork_ptr(sc->tempip, whichfork); 678 if (tifp->if_format == XFS_DINODE_FMT_LOCAL) 679 state |= 2; 680 681 switch (state) { 682 case 0: 683 /* Both files have mapped extents; use the regular estimate. */ 684 return xfs_exchrange_estimate(req); 685 case 1: 686 /* 687 * The file being repaired is in local format, but the temp 688 * file has mapped extents. To perform the exchange, the file 689 * being repaired must have its shorform data converted to an 690 * ondisk block so that the forks will be in extents format. 691 * We need one resblk for the conversion; the number of 692 * exchanges is (worst case) the temporary file's extent count 693 * plus the block we converted. 694 */ 695 req->ip1_bcount = sc->tempip->i_nblocks; 696 req->ip2_bcount = 1; 697 req->nr_exchanges = 1 + tifp->if_nextents; 698 req->resblks = 1; 699 break; 700 case 2: 701 /* 702 * The temporary file is in local format, but the file being 703 * repaired has mapped extents. To perform the exchange, the 704 * temp file must have its shortform data converted to an 705 * ondisk block, and the fork changed to extents format. We 706 * need one resblk for the conversion; the number of exchanges 707 * is (worst case) the extent count of the file being repaired 708 * plus the block we converted. 709 */ 710 req->ip1_bcount = 1; 711 req->ip2_bcount = sc->ip->i_nblocks; 712 req->nr_exchanges = 1 + ifp->if_nextents; 713 req->resblks = 1; 714 break; 715 case 3: 716 /* 717 * Both forks are in local format. To perform the exchange, 718 * both files must have their shortform data converted to 719 * fsblocks, and both forks must be converted to extents 720 * format. We need two resblks for the two conversions, and 721 * the number of exchanges is 1 since there's only one block at 722 * fileoff 0. Presumably, the caller could not exchange the 723 * two inode fork areas directly. 724 */ 725 req->ip1_bcount = 1; 726 req->ip2_bcount = 1; 727 req->nr_exchanges = 1; 728 req->resblks = 2; 729 break; 730 } 731 732 return xfs_exchmaps_estimate_overhead(req); 733 } 734 735 /* 736 * Obtain a quota reservation to make sure we don't hit EDQUOT. We can skip 737 * this if quota enforcement is disabled or if both inodes' dquots are the 738 * same. The qretry structure must be initialized to zeroes before the first 739 * call to this function. 740 */ 741 STATIC int 742 xrep_tempexch_reserve_quota( 743 struct xfs_scrub *sc, 744 const struct xrep_tempexch *tx) 745 { 746 struct xfs_trans *tp = sc->tp; 747 const struct xfs_exchmaps_req *req = &tx->req; 748 int64_t ddelta, rdelta; 749 int error; 750 751 /* 752 * Don't bother with a quota reservation if we're not enforcing them 753 * or the two inodes have the same dquots. 754 */ 755 if (!XFS_IS_QUOTA_ON(tp->t_mountp) || req->ip1 == req->ip2 || 756 xfs_is_metadir_inode(req->ip1) || 757 (req->ip1->i_udquot == req->ip2->i_udquot && 758 req->ip1->i_gdquot == req->ip2->i_gdquot && 759 req->ip1->i_pdquot == req->ip2->i_pdquot)) 760 return 0; 761 762 /* 763 * Quota reservation for each file comes from two sources. First, we 764 * need to account for any net gain in mapped blocks during the 765 * exchange. Second, we need reservation for the gross gain in mapped 766 * blocks so that we don't trip over any quota block reservation 767 * assertions. We must reserve the gross gain because the quota code 768 * subtracts from bcount the number of blocks that we unmap; it does 769 * not add that quantity back to the quota block reservation. 770 */ 771 ddelta = max_t(int64_t, 0, req->ip2_bcount - req->ip1_bcount); 772 rdelta = max_t(int64_t, 0, req->ip2_rtbcount - req->ip1_rtbcount); 773 error = xfs_trans_reserve_quota_nblks(tp, req->ip1, 774 ddelta + req->ip1_bcount, rdelta + req->ip1_rtbcount, 775 true); 776 if (error) 777 return error; 778 779 ddelta = max_t(int64_t, 0, req->ip1_bcount - req->ip2_bcount); 780 rdelta = max_t(int64_t, 0, req->ip1_rtbcount - req->ip2_rtbcount); 781 return xfs_trans_reserve_quota_nblks(tp, req->ip2, 782 ddelta + req->ip2_bcount, rdelta + req->ip2_rtbcount, 783 true); 784 } 785 786 /* 787 * Prepare an existing transaction for an atomic file contents exchange. 788 * 789 * This function fills out the mapping exchange request and resource estimation 790 * structures in preparation for exchanging the contents of a metadata file 791 * that has been rebuilt in the temp file. Next, it reserves space and quota 792 * for the transaction. 793 * 794 * The caller must hold ILOCK_EXCL of the scrub target file and the temporary 795 * file. The caller must join both inodes to the transaction with no unlock 796 * flags, and is responsible for dropping both ILOCKs when appropriate. Only 797 * use this when those ILOCKs cannot be dropped. 798 */ 799 int 800 xrep_tempexch_trans_reserve( 801 struct xfs_scrub *sc, 802 int whichfork, 803 xfs_fileoff_t off, 804 xfs_filblks_t len, 805 struct xrep_tempexch *tx) 806 { 807 int error; 808 809 ASSERT(sc->tp != NULL); 810 xfs_assert_ilocked(sc->ip, XFS_ILOCK_EXCL); 811 xfs_assert_ilocked(sc->tempip, XFS_ILOCK_EXCL); 812 813 error = xrep_tempexch_prep_request(sc, whichfork, off, len, tx); 814 if (error) 815 return error; 816 817 error = xfs_exchmaps_estimate(&tx->req); 818 if (error) 819 return error; 820 821 error = xfs_trans_reserve_more(sc->tp, tx->req.resblks, 0); 822 if (error) 823 return error; 824 825 return xrep_tempexch_reserve_quota(sc, tx); 826 } 827 828 /* 829 * Create a new transaction for a file contents exchange. 830 * 831 * This function fills out the mapping excahange request and resource 832 * estimation structures in preparation for exchanging the contents of a 833 * metadata file that has been rebuilt in the temp file. Next, it reserves 834 * space, takes ILOCK_EXCL of both inodes, joins them to the transaction and 835 * reserves quota for the transaction. 836 * 837 * The caller is responsible for dropping both ILOCKs when appropriate. 838 */ 839 int 840 xrep_tempexch_trans_alloc( 841 struct xfs_scrub *sc, 842 int whichfork, 843 struct xrep_tempexch *tx) 844 { 845 unsigned int flags = 0; 846 int error; 847 848 ASSERT(sc->tp == NULL); 849 ASSERT(xfs_has_exchange_range(sc->mp)); 850 851 error = xrep_tempexch_prep_request(sc, whichfork, 0, XFS_MAX_FILEOFF, 852 tx); 853 if (error) 854 return error; 855 856 error = xrep_tempexch_estimate(sc, tx); 857 if (error) 858 return error; 859 860 if (xfs_has_lazysbcount(sc->mp)) 861 flags |= XFS_TRANS_RES_FDBLKS; 862 863 error = xfs_trans_alloc(sc->mp, &M_RES(sc->mp)->tr_itruncate, 864 tx->req.resblks, 0, flags, &sc->tp); 865 if (error) 866 return error; 867 868 sc->temp_ilock_flags |= XFS_ILOCK_EXCL; 869 sc->ilock_flags |= XFS_ILOCK_EXCL; 870 xfs_exchrange_ilock(sc->tp, sc->ip, sc->tempip); 871 872 return xrep_tempexch_reserve_quota(sc, tx); 873 } 874 875 /* 876 * Exchange file mappings (and hence file contents) between the file being 877 * repaired and the temporary file. Returns with both inodes locked and joined 878 * to a clean scrub transaction. 879 */ 880 int 881 xrep_tempexch_contents( 882 struct xfs_scrub *sc, 883 struct xrep_tempexch *tx) 884 { 885 int error; 886 887 ASSERT(xfs_has_exchange_range(sc->mp)); 888 889 xfs_exchange_mappings(sc->tp, &tx->req); 890 error = xfs_defer_finish(&sc->tp); 891 if (error) 892 return error; 893 894 /* 895 * If we exchanged the ondisk sizes of two metadata files, we must 896 * exchanged the incore sizes as well. 897 */ 898 if (tx->req.flags & XFS_EXCHMAPS_SET_SIZES) { 899 loff_t temp; 900 901 temp = i_size_read(VFS_I(sc->ip)); 902 i_size_write(VFS_I(sc->ip), i_size_read(VFS_I(sc->tempip))); 903 i_size_write(VFS_I(sc->tempip), temp); 904 } 905 906 return 0; 907 } 908 909 /* 910 * Write local format data from one of the temporary file's forks into the same 911 * fork of file being repaired, and exchange the file sizes, if appropriate. 912 * Caller must ensure that the file being repaired has enough fork space to 913 * hold all the bytes. 914 */ 915 void 916 xrep_tempfile_copyout_local( 917 struct xfs_scrub *sc, 918 int whichfork) 919 { 920 struct xfs_ifork *temp_ifp; 921 struct xfs_ifork *ifp; 922 unsigned int ilog_flags = XFS_ILOG_CORE; 923 924 temp_ifp = xfs_ifork_ptr(sc->tempip, whichfork); 925 ifp = xfs_ifork_ptr(sc->ip, whichfork); 926 927 ASSERT(temp_ifp != NULL); 928 ASSERT(ifp != NULL); 929 ASSERT(temp_ifp->if_format == XFS_DINODE_FMT_LOCAL); 930 ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL); 931 932 switch (whichfork) { 933 case XFS_DATA_FORK: 934 ASSERT(sc->tempip->i_disk_size <= 935 xfs_inode_data_fork_size(sc->ip)); 936 break; 937 case XFS_ATTR_FORK: 938 ASSERT(sc->tempip->i_forkoff >= sc->ip->i_forkoff); 939 break; 940 default: 941 ASSERT(0); 942 return; 943 } 944 945 /* Recreate @sc->ip's incore fork (ifp) with data from temp_ifp. */ 946 xfs_idestroy_fork(ifp); 947 xfs_init_local_fork(sc->ip, whichfork, temp_ifp->if_data, 948 temp_ifp->if_bytes); 949 950 if (whichfork == XFS_DATA_FORK) { 951 i_size_write(VFS_I(sc->ip), i_size_read(VFS_I(sc->tempip))); 952 sc->ip->i_disk_size = sc->tempip->i_disk_size; 953 } 954 955 ilog_flags |= xfs_ilog_fdata(whichfork); 956 xfs_trans_log_inode(sc->tp, sc->ip, ilog_flags); 957 } 958 959 /* Decide if a given XFS inode is a temporary file for a repair. */ 960 bool 961 xrep_is_tempfile( 962 const struct xfs_inode *ip) 963 { 964 const struct inode *inode = &ip->i_vnode; 965 struct xfs_mount *mp = ip->i_mount; 966 967 /* 968 * Files in the metadata directory tree also have S_PRIVATE set and 969 * IOP_XATTR unset, so we must distinguish them separately. We (ab)use 970 * the IRECOVERY flag to mark temporary metadir inodes knowing that the 971 * end of log recovery clears IRECOVERY, so the only ones that can 972 * exist during online repair are the ones we create. 973 */ 974 if (xfs_has_metadir(mp) && (ip->i_diflags2 & XFS_DIFLAG2_METADATA)) 975 return __xfs_iflags_test(ip, XFS_IRECOVERY); 976 977 if (IS_PRIVATE(inode) && !(inode->i_opflags & IOP_XATTR)) 978 return true; 979 980 return false; 981 } 982