Home | History | Annotate | Line # | Download | only in lfs
      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