1 /* $NetBSD: lfs_kclean.c,v 1.6 2026/09/23 17:47:52 perseant Exp $ */ 2 3 /*- 4 * Copyright (c) 2025 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Konrad E. Schroder <perseant (at) hhhh.org>. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include <sys/cdefs.h> 33 __KERNEL_RCSID(0, "$NetBSD: lfs_kclean.c,v 1.6 2026/09/23 17:47:52 perseant Exp $"); 34 35 #include <sys/param.h> 36 #include <sys/systm.h> 37 #include <sys/namei.h> 38 #include <sys/proc.h> 39 #include <sys/kernel.h> 40 #include <sys/vnode.h> 41 #include <sys/conf.h> 42 #include <sys/kauth.h> 43 #include <sys/buf.h> 44 #include <sys/kthread.h> 45 46 #include <ufs/lfs/ulfs_inode.h> 47 #include <ufs/lfs/ulfsmount.h> 48 #include <ufs/lfs/ulfs_extern.h> 49 50 #include <ufs/lfs/lfs.h> 51 #include <ufs/lfs/lfs_accessors.h> 52 #include <ufs/lfs/lfs_kernel.h> 53 #include <ufs/lfs/lfs_extern.h> 54 55 static int ino_func_setclean(struct lfs_inofuncarg *); 56 static int finfo_func_rewrite(struct lfs_finfofuncarg *); 57 static int finfo_func_setclean(struct lfs_finfofuncarg *); 58 static int rewrite_block(struct lfs *, struct vnode *, daddr_t, daddr_t, 59 size_t, int *); 60 61 static int ino_func_rewrite(struct lfs_inofuncarg *); 62 static int ino_func_setclean(struct lfs_inofuncarg *); 63 static int ino_func_checkempty(struct lfs_inofuncarg *); 64 65 static int clean(struct lfs *); 66 static long segselect_cb_rosenblum(struct lfs *, int, SEGUSE *, long); 67 static long segselect_greedy(struct lfs *, int, SEGUSE *); 68 static long segselect_cb_time(struct lfs *, int, SEGUSE *); 69 #if 0 70 static long segselect_cb_serial(struct lfs *, int, SEGUSE *); 71 #endif 72 static int check_clean_list(struct lfs *, ino_t); 73 74 struct lwp * lfs_cleaner_daemon = NULL; 75 extern kcondvar_t lfs_allclean_wakeup; 76 static int lfs_ncleaners = 0; 77 78 static int 79 ino_func_setclean(struct lfs_inofuncarg *lifa) 80 { 81 struct lfs *fs; 82 daddr_t offset; 83 struct vnode *devvp, *vp; 84 union lfs_dinode *dip; 85 struct buf *dbp, *ibp; 86 int error; 87 IFILE *ifp; 88 unsigned i, num; 89 daddr_t true_addr; 90 ino_t ino; 91 92 fs = lifa->fs; 93 offset = lifa->offset; 94 devvp = VTOI(fs->lfs_ivnode)->i_devvp; 95 96 /* Read inode block */ 97 error = bread(devvp, LFS_FSBTODB(fs, offset), lfs_sb_getibsize(fs), 98 0, &dbp); 99 if (error) { 100 DLOG((DLOG_RF, "ino_func_setclean: bread returned %d\n", 101 error)); 102 return error; 103 } 104 memcpy(lifa->buf, dbp->b_data, dbp->b_bcount); 105 brelse(dbp, BC_AGE); 106 107 /* Check each inode against ifile entry */ 108 num = LFS_INOPB(fs); 109 for (i = num; i-- > 0; ) { 110 dip = DINO_IN_BLOCK(fs, lifa->buf, i); 111 ino = lfs_dino_getinumber(fs, dip); 112 if (ino == LFS_IFILE_INUM) { 113 /* Check address against superblock */ 114 true_addr = lfs_sb_getidaddr(fs); 115 } else { 116 /* Not ifile. Check address against ifile. */ 117 LFS_IENTRY(ifp, fs, ino, ibp); 118 true_addr = lfs_if_getdaddr(fs, ifp); 119 LFS_RELEASEIENTRY(ifp, fs, ino, ibp); 120 } 121 if (offset != true_addr) 122 continue; 123 124 LFS_ASSERT_MAXINO(fs, ino); 125 126 /* XXX We can use fastvget here! */ 127 128 /* 129 * An inode we need to relocate. 130 * Get it if we can. 131 */ 132 if (ino == LFS_IFILE_INUM) 133 vp = fs->lfs_ivnode; 134 else 135 error = VFS_VGET(fs->lfs_ivnode->v_mount, ino, 136 LK_EXCLUSIVE | LK_NOWAIT, &vp); 137 if (error) 138 continue; 139 140 KASSERT(VTOI(vp)->i_gen == lfs_dino_getgen(fs, dip)); 141 lfs_setclean(fs, vp); 142 if (vp != fs->lfs_ivnode) { 143 VOP_UNLOCK(vp); 144 vrele(vp); 145 } 146 } 147 148 return error; 149 } 150 151 static int 152 ino_func_rewrite(struct lfs_inofuncarg *lifa) 153 { 154 struct lfs *fs; 155 daddr_t offset; 156 struct vnode *devvp, *vp; 157 union lfs_dinode *dip; 158 struct buf *dbp, *ibp; 159 int error; 160 IFILE *ifp; 161 unsigned i, num; 162 daddr_t true_addr; 163 ino_t ino; 164 165 fs = lifa->fs; 166 offset = lifa->offset; 167 devvp = VTOI(fs->lfs_ivnode)->i_devvp; 168 169 /* Read inode block */ 170 error = bread(devvp, LFS_FSBTODB(fs, offset), lfs_sb_getibsize(fs), 171 0, &dbp); 172 if (error) { 173 DLOG((DLOG_RF, "ino_func_rewrite: bread returned %d\n", 174 error)); 175 return error; 176 } 177 memcpy(lifa->buf, dbp->b_data, dbp->b_bcount); 178 brelse(dbp, BC_AGE); 179 180 /* Check each inode against ifile entry */ 181 num = LFS_INOPB(fs); 182 for (i = num; i-- > 0; ) { 183 dip = DINO_IN_BLOCK(fs, lifa->buf, i); 184 ino = lfs_dino_getinumber(fs, dip); 185 if (ino == LFS_IFILE_INUM) { 186 /* Check address against superblock */ 187 true_addr = lfs_sb_getidaddr(fs); 188 } else { 189 /* Not ifile. Check address against ifile. */ 190 LFS_IENTRY(ifp, fs, ino, ibp); 191 true_addr = lfs_if_getdaddr(fs, ifp); 192 LFS_RELEASEIENTRY(ifp, fs, ino, ibp); 193 } 194 if (offset != true_addr) 195 continue; 196 197 if (ino == LFS_IFILE_INUM) 198 continue; 199 200 LFS_ASSERT_MAXINO(fs, ino); 201 202 /* XXX We can use fastvget here! */ 203 204 /* 205 * An inode we need to relocate. 206 * Get it if we can. 207 */ 208 error = check_clean_list(fs, ino); 209 if (error) 210 continue; 211 error = VFS_VGET(fs->lfs_ivnode->v_mount, ino, 212 LK_EXCLUSIVE | LK_NOWAIT, &vp); 213 if (error) 214 continue; 215 216 KASSERT(VTOI(vp)->i_gen == lfs_dino_getgen(fs, dip)); 217 218 if (!(VTOI(vp)->i_state & IN_CLEANING)) { 219 lfs_setclean(fs, vp); 220 lfs_writeinode(fs, fs->lfs_sp, VTOI(vp)); 221 } 222 223 VOP_UNLOCK(vp); 224 vrele(vp); 225 226 } 227 228 return error; 229 } 230 231 static int 232 rewrite_block(struct lfs *fs, struct vnode *vp, daddr_t lbn, daddr_t offset, size_t size, int *have_finfop) 233 { 234 daddr_t daddr; 235 int error; 236 struct buf *bp; 237 struct inode *ip; 238 239 KASSERT(have_finfop != NULL); 240 241 /* Look up current location of this block. */ 242 error = VOP_BMAP(vp, lbn, NULL, &daddr, NULL); 243 if (error) 244 return error; 245 246 /* Skip any block that is not here. */ 247 if (offset != 0 && LFS_DBTOFSB(fs, daddr) != offset) 248 return ESTALE; 249 250 /* 251 * It is (was recently) here. Read the block. 252 */ 253 //size = lfs_blksize(fs, VTOI(vp), lbn); 254 error = bread(vp, lbn, size, 0, &bp); 255 if (error) 256 return error; 257 258 if (vp == fs->lfs_ivnode) { 259 VOP_BWRITE(vp, bp); 260 } else { 261 /* Get ready to write. */ 262 if (!*have_finfop) { 263 ip = VTOI(vp); 264 lfs_acquire_finfo(fs, ip->i_number, ip->i_gen); 265 fs->lfs_sp->vp = vp; 266 *have_finfop = 1; 267 } 268 269 KASSERT(bp->b_vp == vp); 270 /* bp->b_cflags |= BC_INVAL; */ /* brelse will kill the buffer */ 271 error = lfs_bwrite_ext(bp, BW_CLEAN); 272 if (error) 273 return error; 274 KASSERT(bp->b_vp == vp); 275 mutex_enter(&bufcache_lock); 276 while (lfs_gatherblock(fs->lfs_sp, bp, &bufcache_lock)) { 277 KASSERT(bp->b_vp != NULL); 278 } 279 mutex_exit(&bufcache_lock); 280 281 KASSERT(bp->b_flags & B_GATHERED); 282 KASSERT(fs->lfs_sp->cbpp[-1] == bp); 283 } 284 return 0; 285 } 286 287 static int 288 check_clean_list(struct lfs *fs, ino_t ino) 289 { 290 struct inode *ip; 291 292 /* 293 * Look for the inode on the clean list. 294 * If it is not there, we can't lock it without risking a deadlock. 295 */ 296 TAILQ_FOREACH(ip, &fs->lfs_cleanhd, i_lfs_clean) { 297 if (ip->i_number == ino) { 298 return 0; 299 } 300 } 301 return EWOULDBLOCK; 302 } 303 304 static int 305 finfo_func_rewrite(struct lfs_finfofuncarg *lffa) 306 { 307 struct lfs *fs; 308 FINFO *fip; 309 daddr_t *offsetp; 310 int j, have_finfo, error; 311 size_t size, bytes; 312 ino_t ino; 313 uint32_t gen; 314 struct vnode *vp; 315 daddr_t lbn; 316 int *fragsp; 317 318 fs = lffa->fs; 319 fip = lffa->finfop; 320 offsetp = lffa->offsetp; 321 fragsp = (int *)lffa->arg; 322 323 /* Get the inode and check its version. */ 324 ino = lfs_fi_getino(fs, fip); 325 gen = lfs_fi_getversion(fs, fip); 326 error = 0; 327 if (ino == LFS_IFILE_INUM) 328 vp = fs->lfs_ivnode; 329 else { 330 LFS_ASSERT_MAXINO(fs, ino); 331 error = check_clean_list(fs, ino); 332 if (error) 333 vp = NULL; 334 else 335 error = VFS_VGET(fs->lfs_ivnode->v_mount, ino, 336 LK_EXCLUSIVE|LK_NOWAIT, &vp); 337 } 338 339 /* 340 * If we can't, or if version is wrong, or it has dirop blocks on it, 341 * we can't relocate its blocks; but we still have to count 342 * blocks through the partial segment to return the right offset. 343 * XXX actually we can move DIROP vnodes' *old* data, as long 344 * XXX as we are sure that we are moving *only* the old data---? 345 */ 346 if (error || VTOI(vp)->i_gen != gen || (vp->v_uflag & VU_DIROP)) { 347 if (error == 0) 348 error = ESTALE; 349 350 if (vp != NULL && vp != fs->lfs_ivnode) { 351 VOP_UNLOCK(vp); 352 vrele(vp); 353 } 354 vp = NULL; 355 bytes = ((lfs_fi_getnblocks(fs, fip) - 1) << lfs_sb_getbshift(fs)) 356 + lfs_fi_getlastlength(fs, fip); 357 *offsetp += lfs_btofsb(fs, bytes); 358 359 return error; 360 } 361 362 /* 363 * We have the vnode and its version is correct. 364 * Take a cleaning reference; and loop through the blocks 365 * and rewrite them. 366 */ 367 lfs_setclean(fs, vp); 368 size = lfs_sb_getbsize(fs); 369 have_finfo = 0; 370 for (j = 0; j < lfs_fi_getnblocks(fs, fip); ++j) { 371 if (j == lfs_fi_getnblocks(fs, fip) - 1) 372 size = lfs_fi_getlastlength(fs, fip); 373 /* 374 * An error of ESTALE indicates that there was nothing 375 * to rewrite; this is not a problem. Any other error 376 * causes us to skip the rest of this FINFO. 377 */ 378 if (vp != NULL && error == 0) { 379 lbn = lfs_fi_getblock(fs, fip, j); 380 error = rewrite_block(fs, vp, lbn, *offsetp, 381 size, &have_finfo); 382 if (error == ESTALE) 383 error = 0; 384 if (fragsp != NULL && error == 0) 385 *fragsp += lfs_btofsb(fs, size); 386 } 387 *offsetp += lfs_btofsb(fs, size); 388 } 389 390 /* 391 * If we acquired finfo, release it and write the blocks. 392 */ 393 if (have_finfo) { 394 lfs_updatemeta(fs->lfs_sp); 395 fs->lfs_sp->vp = NULL; 396 lfs_release_finfo(fs); 397 lfs_writeinode(fs, fs->lfs_sp, VTOI(vp)); 398 } 399 400 /* Release vnode */ 401 if (vp != fs->lfs_ivnode) { 402 VOP_UNLOCK(vp); 403 vrele(vp); 404 } 405 406 return error; 407 } 408 409 static int 410 finfo_func_setclean(struct lfs_finfofuncarg *lffa) 411 { 412 struct lfs *fs; 413 FINFO *fip; 414 daddr_t *offsetp; 415 int error; 416 size_t bytes; 417 ino_t ino; 418 uint32_t gen; 419 struct vnode *vp; 420 421 fs = lffa->fs; 422 fip = lffa->finfop; 423 offsetp = lffa->offsetp; 424 425 /* Get the inode and check its version. */ 426 ino = lfs_fi_getino(fs, fip); 427 gen = lfs_fi_getversion(fs, fip); 428 error = 0; 429 if (ino == LFS_IFILE_INUM) 430 vp = fs->lfs_ivnode; 431 else { 432 LFS_ASSERT_MAXINO(fs, ino); 433 error = VFS_VGET(fs->lfs_ivnode->v_mount, ino, 434 LK_EXCLUSIVE|LK_NOWAIT, &vp); 435 } 436 437 /* If we have it and its version is right, take a cleaning reference */ 438 if (error == 0 && VTOI(vp)->i_gen == gen) 439 lfs_setclean(fs, vp); 440 441 if (vp == fs->lfs_ivnode) 442 vp = NULL; 443 else if (vp != NULL) { 444 VOP_UNLOCK(vp); 445 vrele(vp); 446 vp = NULL; 447 } 448 449 /* Skip to the next block */ 450 bytes = ((lfs_fi_getnblocks(fs, fip) - 1) << lfs_sb_getbshift(fs)) 451 + lfs_fi_getlastlength(fs, fip); 452 *offsetp += lfs_btofsb(fs, bytes); 453 454 return error; 455 } 456 457 /* 458 * Use the partial-segment parser to rewrite (clean) a segment. 459 */ 460 int 461 lfs_rewrite_segment(struct lfs *fs, int sn, int *fragsp, kauth_cred_t cred, struct lwp *l) 462 { 463 daddr_t ooffset, offset, endpseg; 464 465 ASSERT_SEGLOCK(fs); 466 467 offset = lfs_sntod(fs, sn); 468 lfs_skip_superblock(fs, &offset); 469 endpseg = lfs_sntod(fs, sn + 1); 470 471 while (offset > 0 && offset != endpseg) { 472 /* First check summary validity (XXX unnecessary?) */ 473 ooffset = offset; 474 lfs_parse_pseg(fs, &offset, 0, cred, NULL, l, 475 NULL, NULL, CKSEG_CKSUM, NULL); 476 if (offset == ooffset) 477 break; 478 479 /* 480 * Valid, proceed. 481 * 482 * First write the file blocks, marking their 483 * inodes IN_CLEANING. 484 */ 485 offset = ooffset; 486 lfs_parse_pseg(fs, &offset, 0, cred, NULL, l, 487 NULL, finfo_func_rewrite, 488 CKSEG_NONE, fragsp); 489 490 /* 491 * Now go back and pick up any inodes that 492 * were not already marked IN_CLEANING, and 493 * write them as well. 494 */ 495 offset = ooffset; 496 lfs_parse_pseg(fs, &offset, 0, cred, NULL, l, 497 ino_func_rewrite, NULL, 498 CKSEG_NONE, fragsp); 499 } 500 return 0; 501 } 502 503 /* 504 * Rewrite the contents of one or more segments, in preparation for 505 * marking them clean. 506 */ 507 int 508 lfs_rewrite_segments(struct lfs *fs, int *snn, int len, int *directp, int *offsetp, struct lwp *l) 509 { 510 kauth_cred_t cred; 511 int i, error; 512 struct buf *bp; 513 SEGUSE *sup; 514 daddr_t offset, endpseg; 515 516 ASSERT_NO_SEGLOCK(fs); 517 518 cred = l ? l->l_cred : NOCRED; 519 520 /* Prevent new dirops and acquire the cleaner lock. */ 521 lfs_writer_enter(fs, "rewritesegs"); 522 if ((error = lfs_cleanerlock(fs)) != 0) { 523 lfs_writer_leave(fs); 524 return error; 525 } 526 527 /* 528 * Pre-reference vnodes now that we have cleaner lock 529 * but before we take the segment lock. We don't want to 530 * mix cleaning blocks with flushed vnodes. 531 */ 532 for (i = 0; i < len; i++) { 533 error = 0; 534 /* Refuse to clean segments that are ACTIVE */ 535 LFS_SEGENTRY(sup, fs, snn[i], bp); 536 if (sup->su_flags & SEGUSE_ACTIVE 537 || !(sup->su_flags & SEGUSE_DIRTY)) 538 error = EINVAL; 539 540 LFS_RELEASESEGENTRY(sup, fs, snn[i], bp); 541 if (error) 542 break; 543 544 offset = lfs_sntod(fs, snn[i]); 545 lfs_skip_superblock(fs, &offset); 546 endpseg = lfs_sntod(fs, snn[i] + 1); 547 548 while (offset > 0 && offset != endpseg) { 549 lfs_parse_pseg(fs, &offset, 0, cred, NULL, l, 550 ino_func_setclean, finfo_func_setclean, 551 CKSEG_NONE, NULL); 552 } 553 } 554 555 /* 556 * Actually rewrite the contents of the segment. 557 */ 558 lfs_seglock(fs, SEGM_CLEAN); 559 560 for (i = 0; i < len; i++) { 561 error = 0; 562 /* Refuse to clean segments that are ACTIVE */ 563 LFS_SEGENTRY(sup, fs, snn[i], bp); 564 if (sup->su_flags & SEGUSE_ACTIVE 565 || !(sup->su_flags & SEGUSE_DIRTY)) 566 error = EINVAL; 567 568 LFS_RELEASESEGENTRY(sup, fs, snn[i], bp); 569 if (error) 570 break; 571 572 error = lfs_rewrite_segment(fs, snn[i], directp, cred, l); 573 if (error) 574 break; 575 } 576 while (lfs_writeseg(fs, fs->lfs_sp)) 577 ; 578 579 *offsetp = lfs_btofsb(fs, fs->lfs_sp->bytes_written); 580 lfs_segunlock(fs); 581 lfs_cleanerunlock(fs); 582 lfs_writer_leave(fs); 583 584 return error; 585 } 586 587 static int 588 ino_func_checkempty(struct lfs_inofuncarg *lifa) 589 { 590 struct lfs *fs; 591 daddr_t offset; 592 struct vnode *devvp; 593 union lfs_dinode *dip; 594 struct buf *dbp, *ibp; 595 int error; 596 IFILE *ifp; 597 unsigned i, num; 598 daddr_t true_addr; 599 ino_t ino; 600 601 fs = lifa->fs; 602 offset = lifa->offset; 603 devvp = VTOI(fs->lfs_ivnode)->i_devvp; 604 605 /* Read inode block */ 606 error = bread(devvp, LFS_FSBTODB(fs, offset), lfs_sb_getibsize(fs), 607 0, &dbp); 608 if (error) { 609 DLOG((DLOG_RF, "ino_func_checkempty: bread returned %d\n", 610 error)); 611 return error; 612 } 613 614 /* Check each inode against ifile entry */ 615 num = LFS_INOPB(fs); 616 for (i = num; i-- > 0; ) { 617 dip = DINO_IN_BLOCK(fs, dbp->b_data, i); 618 ino = lfs_dino_getinumber(fs, dip); 619 if (ino == 0) { 620 /* The last inode block is zero-padded. Ignore this. */ 621 continue; 622 } else if (ino == LFS_IFILE_INUM) { 623 /* Check address against superblock */ 624 true_addr = lfs_sb_getidaddr(fs); 625 } else if (ino >= LFS_MAXINO(fs)) { 626 /* 627 * An inode greater than we have must be from a 628 * previous allocation that was not rolled forward. 629 * For our purposes, it does not exist. 630 */ 631 continue; 632 } else { 633 /* Not ifile. Check address against ifile. */ 634 LFS_IENTRY(ifp, fs, ino, ibp); 635 true_addr = lfs_if_getdaddr(fs, ifp); 636 LFS_RELEASEIENTRY(ifp, fs, ino, ibp); 637 } 638 if (offset == true_addr) { 639 error = EEXIST; 640 break; 641 } 642 } 643 brelse(dbp, BC_AGE); 644 645 return error; 646 } 647 648 static int 649 finfo_func_checkempty(struct lfs_finfofuncarg *lffa) 650 { 651 struct lfs *fs; 652 FINFO *fip; 653 daddr_t *offsetp; 654 int j, error; 655 size_t size, bytes; 656 ino_t ino; 657 uint32_t gen; 658 struct vnode *vp; 659 daddr_t lbn, daddr; 660 661 fs = lffa->fs; 662 fip = lffa->finfop; 663 offsetp = lffa->offsetp; 664 665 /* Get the inode and check its version. */ 666 ino = lfs_fi_getino(fs, fip); 667 gen = lfs_fi_getversion(fs, fip); 668 669 if (lfs_fi_getnblocks(fs, fip) <= 0 || ino < LFS_IFILE_INUM) 670 return EINVAL; 671 672 /* We can safely ignore this; see comment in ino_func_checkempty. */ 673 if (ino >= LFS_MAXINO(fs)) 674 return 0; 675 676 error = VFS_VGET(fs->lfs_ivnode->v_mount, ino, LK_EXCLUSIVE|LK_NOWAIT, &vp); 677 678 /* 679 * If we can't, or if version is wrong, this FINFO does not refer 680 * to a live file. Skip over it and continue. 681 */ 682 if (error || VTOI(vp)->i_gen != gen) { 683 if (error == 0) 684 error = ESTALE; 685 686 if (vp != NULL) { 687 VOP_UNLOCK(vp); 688 vrele(vp); 689 vp = NULL; 690 } 691 bytes = ((lfs_fi_getnblocks(fs, fip) - 1) 692 << lfs_sb_getbshift(fs)) 693 + lfs_fi_getlastlength(fs, fip); 694 *offsetp += lfs_btofsb(fs, bytes); 695 696 return error; 697 } 698 699 /* 700 * We have the vnode and its version is correct. 701 * Loop through the blocks and check their currency. 702 */ 703 size = lfs_sb_getbsize(fs); 704 for (j = 0; j < lfs_fi_getnblocks(fs, fip); ++j) { 705 if (j == lfs_fi_getnblocks(fs, fip) - 1) 706 size = lfs_fi_getlastlength(fs, fip); 707 if (vp != NULL) { 708 lbn = lfs_fi_getblock(fs, fip, j); 709 710 /* Look up current location of this block. */ 711 error = VOP_BMAP(vp, lbn, NULL, &daddr, NULL); 712 if (error) 713 break; 714 715 /* If it is here, the segment is not empty. */ 716 if (LFS_DBTOFSB(fs, daddr) == *offsetp) { 717 error = EEXIST; 718 break; 719 } 720 } 721 *offsetp += lfs_btofsb(fs, size); 722 } 723 724 /* Release vnode */ 725 VOP_UNLOCK(vp); 726 vrele(vp); 727 728 return error; 729 } 730 731 int 732 lfs_checkempty(struct lfs *fs, int sn, kauth_cred_t cred, struct lwp *l) 733 { 734 daddr_t offset, ooffset, endpseg; 735 int error; 736 737 ASSERT_SEGLOCK(fs); 738 739 offset = ooffset = lfs_sntod(fs, sn); 740 lfs_skip_superblock(fs, &offset); 741 endpseg = lfs_sntod(fs, sn + 1); 742 743 while (offset >= ooffset && offset < endpseg) { 744 error = lfs_parse_pseg(fs, &offset, 0, cred, NULL, l, 745 ino_func_checkempty, 746 finfo_func_checkempty, 747 CKSEG_NONE, NULL); 748 if (error) 749 return error; 750 } 751 return 0; 752 } 753 754 static long 755 segselect_greedy(struct lfs *fs, int sn, SEGUSE *sup) 756 { 757 return lfs_sb_getssize(fs) - sup->su_nbytes; 758 } 759 760 __inline static long 761 segselect_cb_rosenblum(struct lfs *fs, int sn, SEGUSE *sup, long age) 762 { 763 long benefit, cost; 764 765 benefit = (int64_t)lfs_sb_getssize(fs) - sup->su_nbytes - 766 (sup->su_nsums + 1) * lfs_sb_getfsize(fs); 767 if (sup->su_flags & SEGUSE_SUPERBLOCK) 768 benefit -= LFS_SBPAD; 769 if (lfs_sb_getbsize(fs) > lfs_sb_getfsize(fs)) /* fragmentation */ 770 benefit -= (lfs_sb_getbsize(fs) / 2); 771 if (benefit <= 0) { 772 return 0; 773 } 774 775 cost = lfs_sb_getssize(fs) + sup->su_nbytes; 776 return (256 * benefit * age) / cost; 777 } 778 779 static long 780 segselect_cb_time(struct lfs *fs, int sn, SEGUSE *sup) 781 { 782 long age; 783 784 age = time_second - sup->su_lastmod; 785 if (age < 0) 786 age = 0; 787 return segselect_cb_rosenblum(fs, sn, sup, age); 788 } 789 790 #if 0 791 /* 792 * Same as the time comparator, but fetch the serial number from the 793 * segment header to compare. 794 * 795 * This is ugly. Whether serial number or wall time is better is a 796 * worthy question, but if we want to use serial number to compute 797 * age, we should record the serial number in su_lastmod instead of 798 * the time. 799 */ 800 static long 801 segselect_cb_serial(struct lfs *fs, int sn, SEGUSE *sup) 802 { 803 struct buf *bp; 804 uint32_t magic; 805 uint64_t age, serial; 806 daddr_t addr; 807 808 addr = lfs_segtod(fs, sn); 809 lfs_skip_superblock(fs, &addr); 810 bread(fs->lfs_devvp, LFS_FSBTODB(fs, addr), 811 lfs_sb_getsumsize(fs), 0, &bp); 812 magic = lfs_ss_getmagic(fs, ((SEGSUM *)bp->b_data)); 813 serial = lfs_ss_getserial(fs, ((SEGSUM *)bp->b_data)); 814 brelse(bp, 0); 815 816 if (magic != SS_MAGIC) 817 return 0; 818 819 age = lfs_sb_getserial(fs) - serial; 820 return segselect_cb_rosenblum(fs, sn, sup, age); 821 } 822 #endif 823 824 void 825 lfs_cleanerd(void *arg) 826 { 827 mount_iterator_t *iter; 828 struct mount *mp; 829 struct lfs *fs; 830 struct vfsops *vfs = NULL; 831 int lfsc; 832 int cleaned_something = 0; 833 834 /* Take an extra reference to the LFS vfsops. */ 835 vfs = vfs_getopsbyname(MOUNT_LFS); 836 837 mutex_enter(&lfs_lock); 838 for (;;) { 839 KASSERT(mutex_owned(&lfs_lock)); 840 if (cleaned_something == 0) 841 cv_timedwait(&lfs_allclean_wakeup, &lfs_lock, hz/10 + 1); 842 KASSERT(mutex_owned(&lfs_lock)); 843 cleaned_something = 0; 844 845 KASSERT(mutex_owned(&lfs_lock)); 846 mutex_exit(&lfs_lock); 847 848 /* 849 * Look through the list of LFSs to see if any of them 850 * need cleaning. 851 */ 852 mountlist_iterator_init(&iter); 853 lfsc = 0; 854 while ((mp = mountlist_iterator_next(iter)) != NULL) { 855 KASSERT(!mutex_owned(&lfs_lock)); 856 if (strncmp(mp->mnt_stat.f_fstypename, MOUNT_LFS, 857 sizeof(mp->mnt_stat.f_fstypename)) == 0) { 858 fs = VFSTOULFS(mp)->um_lfs; 859 860 mutex_enter(&lfs_lock); 861 if (fs->lfs_clean_selector == NULL) { 862 /* Notify cleanctl */ 863 if (fs->lfs_autoclean_status) { 864 fs->lfs_autoclean_status = 865 LFS_AUTOCLEAN_STATUS_OFF; 866 cv_broadcast(&fs->lfs_cleanquitcv); 867 } 868 } else 869 ++lfsc; 870 mutex_exit(&lfs_lock); 871 cleaned_something += clean(fs); 872 } 873 } 874 if (lfsc == 0) { 875 mutex_enter(&lfs_lock); 876 lfs_cleaner_daemon = NULL; 877 mutex_exit(&lfs_lock); 878 mountlist_iterator_destroy(iter); 879 break; 880 } 881 mountlist_iterator_destroy(iter); 882 883 mutex_enter(&lfs_lock); 884 } 885 KASSERT(!mutex_owned(&lfs_lock)); 886 887 /* Give up our extra reference so the module can be unloaded. */ 888 mutex_enter(&vfs_list_lock); 889 if (vfs != NULL) 890 vfs->vfs_refcount--; 891 mutex_exit(&vfs_list_lock); 892 893 /* Done! */ 894 kthread_exit(0); 895 } 896 897 /* 898 * Look at the file system to see whether it needs cleaning, and if it does, 899 * clean a segment. 900 */ 901 static int 902 clean(struct lfs *fs) 903 { 904 struct buf *bp; 905 SEGUSE *sup; 906 int sn, maxsn, nclean, nready, nempty, nerror, nzero, again, target; 907 long prio, maxprio, maxeprio, thresh; 908 long (*func)(struct lfs *, int, SEGUSE *); 909 uint32_t __debugused segflags = 0; 910 daddr_t oldsn, bfree, avail; 911 int direct, offset; 912 913 mutex_enter(&lfs_lock); 914 func = fs->lfs_clean_selector; 915 mutex_exit(&lfs_lock); 916 if (func == NULL) 917 return 1; /* Run again so we get cleaned up immediately */ 918 919 thresh = fs->lfs_autoclean.thresh; 920 if (fs->lfs_flags & LFS_MUSTCLEAN) 921 thresh = 0; 922 else if (thresh < 0) { 923 /* 924 * Compute a priority threshold based on availability ratio. 925 * XXX These numbers only makes sense for the greedy cleaner. 926 * What is an appropriate threshold for the cost-benefit 927 * cleaner? 928 */ 929 bfree = lfs_sb_getbfree(fs) 930 + lfs_segtod(fs, 1) * lfs_sb_getminfree(fs); 931 avail = lfs_sb_getavail(fs) - fs->lfs_ravail - fs->lfs_favail; 932 if (avail > bfree) 933 return 0; 934 thresh = lfs_sb_getssize(fs) * (bfree - avail) 935 / (lfs_sb_getsize(fs) - avail); 936 if (thresh > lfs_sb_getsumsize(fs) + 5 * lfs_sb_getbsize(fs)) 937 thresh = lfs_sb_getsumsize(fs) + 5 * lfs_sb_getbsize(fs); 938 if (thresh > lfs_sb_getssize(fs) - lfs_sb_getbsize(fs)) 939 return 0; 940 } 941 942 target = fs->lfs_autoclean.target; 943 if (target <= 0) { 944 /* Default to half a segment target */ 945 target = lfs_segtod(fs, 1) / 2; 946 } 947 948 oldsn = lfs_dtosn(fs, lfs_sb_getoffset(fs)); 949 950 again = 0; 951 maxprio = maxeprio = -1; 952 nzero = nclean = nready = nempty = nerror = 0; 953 for (sn = 0; sn < lfs_sb_getnseg(fs); sn++) { 954 955 prio = 0; 956 LFS_SEGENTRY(sup, fs, sn, bp); 957 if (sup->su_flags & SEGUSE_ACTIVE) 958 prio = 0; 959 else if (!(sup->su_flags & SEGUSE_DIRTY)) 960 ++nclean; 961 else if (sup->su_flags & SEGUSE_READY) 962 ++nready; 963 else if (sup->su_flags & SEGUSE_EMPTY) 964 ++nempty; 965 else if (sup->su_nbytes == 0) 966 ++nzero; 967 else 968 prio = (*func)(fs, sn, sup); 969 970 if (sup->su_flags & SEGUSE_ERROR) { 971 if (prio > maxeprio) 972 maxeprio = prio; 973 prio = 0; 974 ++nerror; 975 } 976 977 if (prio > maxprio) { 978 maxprio = prio; 979 maxsn = sn; 980 segflags = sup->su_flags; 981 } 982 LFS_RELEASESEGENTRY(sup, fs, sn, bp); 983 } 984 DLOG((DLOG_CLEAN, "%s clean=%d/%d zero=%d empty=%d ready=%d maxsn=%d maxprio=%ld/%ld segflags=0x%lx\n", 985 (maxprio > thresh ? "YES" : "NO "), 986 nclean, (int)lfs_sb_getnseg(fs), nzero, nempty, nready, 987 maxsn, maxprio, (unsigned long)thresh, 988 (unsigned long)segflags)); 989 990 /* 991 * If we are trying to clean the segment we cleaned last, 992 * cleaning did not work. Mark this segment SEGUSE_ERROR 993 * and try again. 994 */ 995 if (maxprio > 0 && fs->lfs_lastcleaned == maxsn) { 996 LFS_SEGENTRY(sup, fs, maxsn, bp); 997 sup->su_flags |= SEGUSE_ERROR; 998 LFS_WRITESEGENTRY(sup, fs, sn, bp); 999 return 1; 1000 } 1001 1002 /* 1003 * If there were nothing but error segments, clear error. 1004 * We will wait to try again. 1005 */ 1006 if (maxprio == 0 && maxeprio > 0) { 1007 DLOG((DLOG_CLEAN, "clear error on %d segments, try again\n", 1008 nerror)); 1009 lfs_seguse_clrflag_all(fs, SEGUSE_ERROR); 1010 } 1011 1012 /* Rewrite the highest-priority segment */ 1013 if (maxprio > thresh) { 1014 direct = offset = 0; 1015 (void)lfs_rewrite_segments(fs, &maxsn, 1, 1016 &direct, &offset, curlwp); 1017 DLOG((DLOG_CLEAN, " direct=%d offset=%d\n", direct, offset)); 1018 again += direct; 1019 fs->lfs_clean_accum += offset; 1020 1021 /* Don't clean this again immediately */ 1022 fs->lfs_lastcleaned = maxsn; 1023 } 1024 1025 /* 1026 * If we are in dire straits but we have segments already 1027 * empty, force a double checkpoint to reclaim them. 1028 */ 1029 if (fs->lfs_flags & LFS_MUSTCLEAN) { 1030 if (nready + nempty > 0) { 1031 DLOG((DLOG_CLEAN, "force checkpoint with nready=%d nempty=%d nzero=%d\n", 1032 nready, nempty, nzero)); 1033 lfs_segwrite(fs->lfs_ivnode->v_mount, 1034 SEGM_CKP | SEGM_FORCE_CKP | SEGM_SYNC); 1035 lfs_segwrite(fs->lfs_ivnode->v_mount, 1036 SEGM_CKP | SEGM_FORCE_CKP | SEGM_SYNC); 1037 ++again; 1038 } 1039 } else if (fs->lfs_clean_accum > target) { 1040 DLOG((DLOG_CLEAN, "checkpoint to flush\n")); 1041 lfs_segwrite(fs->lfs_ivnode->v_mount, SEGM_CKP); 1042 fs->lfs_clean_accum = 0; 1043 } else if (lfs_dtosn(fs, lfs_sb_getoffset(fs)) != oldsn 1044 || nempty + nready > LFS_MAX_ACTIVE) { /* XXX arbitrary */ 1045 DLOG((DLOG_CLEAN, "write to promote empty segments\n")); 1046 lfs_segwrite(fs->lfs_ivnode->v_mount, SEGM_CKP); 1047 fs->lfs_clean_accum = 0; 1048 } 1049 1050 return again; 1051 } 1052 1053 /* 1054 * Rewrite a file in its entirety. 1055 * 1056 * Generally this would be done to coalesce a file that is scattered 1057 * around the disk; but if the "scramble" flag is set, instead rewrite 1058 * only the even-numbered blocks, which provides the opposite effect 1059 * for testing purposes. 1060 * 1061 * It is the caller's responsibility to check the bounds of the inode 1062 * numbers. 1063 */ 1064 int 1065 lfs_rewrite_file(struct lfs *fs, ino_t *inoa, int len, bool scramble, 1066 int *directp, int *offsetp) 1067 { 1068 daddr_t hiblk, lbn; 1069 struct vnode *vp; 1070 struct inode *ip; 1071 struct buf *bp; 1072 int i, error; 1073 1074 KASSERT(directp != NULL); 1075 KASSERT(offsetp != NULL); 1076 1077 *directp = 0; 1078 if ((error = lfs_cleanerlock(fs)) != 0) 1079 return error; 1080 lfs_seglock(fs, 0); 1081 for (i = 0; i < len; ++i) { 1082 error = VFS_VGET(fs->lfs_ivnode->v_mount, inoa[i], 1083 LK_EXCLUSIVE | LK_NOWAIT, &vp); 1084 if (error) 1085 goto out; 1086 1087 ip = VTOI(vp); 1088 if ((vp->v_uflag & VU_DIROP) || (ip->i_flags & IN_ADIROP)) { 1089 VOP_UNLOCK(vp); 1090 vrele(vp); 1091 error = EAGAIN; 1092 goto out; 1093 } 1094 1095 /* Highest block in this inode */ 1096 hiblk = lfs_lblkno(fs, ip->i_size + lfs_sb_getbsize(fs) - 1) - 1; 1097 1098 for (lbn = 0; lbn <= hiblk; ++lbn) { 1099 if (scramble && (lbn & 0x01)) 1100 continue; 1101 1102 if (lfs_needsflush(fs)) { 1103 lfs_segwrite(fs->lfs_ivnode->v_mount, 0); 1104 } 1105 1106 error = bread(vp, lbn, lfs_blksize(fs, ip, lbn), 0, &bp); 1107 if (error) 1108 break; 1109 1110 /* bp->b_cflags |= BC_INVAL; */ 1111 lfs_bwrite_ext(bp, 0); 1112 *directp += lfs_btofsb(fs, bp->b_bcount); 1113 } 1114 1115 /* Done with this vnode */ 1116 VOP_UNLOCK(vp); 1117 vrele(vp); 1118 if (error) 1119 break; 1120 } 1121 out: 1122 lfs_segwrite(fs->lfs_ivnode->v_mount, 0); 1123 *offsetp += lfs_btofsb(fs, fs->lfs_sp->bytes_written); 1124 lfs_segunlock(fs); 1125 lfs_cleanerunlock(fs); 1126 1127 return error; 1128 } 1129 1130 int 1131 lfs_cleanctl(struct lfs *fs, struct lfs_autoclean_params *params) 1132 { 1133 long (*cleanfunc)(struct lfs *, int, SEGUSE *); 1134 1135 fs->lfs_autoclean = *params; 1136 1137 cleanfunc = NULL; 1138 switch (fs->lfs_autoclean.mode) { 1139 case LFS_CLEANMODE_NONE: 1140 cleanfunc = NULL; 1141 break; 1142 1143 case LFS_CLEANMODE_GREEDY: 1144 cleanfunc = segselect_greedy; 1145 break; 1146 1147 case LFS_CLEANMODE_CB: 1148 cleanfunc = segselect_cb_time; 1149 break; 1150 1151 default: 1152 return EINVAL; 1153 } 1154 1155 mutex_enter(&lfs_lock); 1156 while (cleanfunc == NULL && 1157 fs->lfs_autoclean_status != LFS_AUTOCLEAN_STATUS_OFF) { 1158 cv_wait(&fs->lfs_cleanquitcv, &lfs_lock); 1159 } 1160 if (fs->lfs_clean_selector == NULL && cleanfunc != NULL) 1161 if (++lfs_ncleaners == 1) { 1162 if (lfs_cleaner_daemon == NULL && 1163 kthread_create(PRI_BIO, 0, NULL, 1164 lfs_cleanerd, NULL, 1165 &lfs_cleaner_daemon, 1166 "lfs_cleaner") != 0) 1167 panic("fork lfs_cleaner"); 1168 } 1169 if (fs->lfs_clean_selector != NULL && cleanfunc == NULL) { 1170 if (--lfs_ncleaners == 0) { 1171 #if 0 1172 kthread_join(lfs_cleaner_daemon); 1173 lfs_cleaner_daemon = NULL; 1174 #endif /* 0 */ 1175 } 1176 } 1177 fs->lfs_clean_selector = cleanfunc; 1178 mutex_exit(&lfs_lock); 1179 1180 return 0; 1181 } 1182