xref: /csrg-svn/sys/ufs/lfs/lfs_bio.c (revision 53528)
151184Sbostic /*
251493Sbostic  * Copyright (c) 1991 Regents of the University of California.
351184Sbostic  * All rights reserved.
451184Sbostic  *
551184Sbostic  * %sccs.include.redist.c%
651184Sbostic  *
7*53528Sheideman  *	@(#)lfs_bio.c	7.9 (Berkeley) 05/14/92
851184Sbostic  */
951184Sbostic 
1051480Sbostic #include <sys/param.h>
1151480Sbostic #include <sys/proc.h>
1251480Sbostic #include <sys/buf.h>
1352081Sbostic #include <sys/vnode.h>
1451480Sbostic #include <sys/resourcevar.h>
1552081Sbostic #include <sys/mount.h>
1651184Sbostic 
1752081Sbostic #include <ufs/ufs/quota.h>
1852081Sbostic #include <ufs/ufs/inode.h>
1952081Sbostic #include <ufs/ufs/ufsmount.h>
2052081Sbostic 
2151493Sbostic #include <ufs/lfs/lfs.h>
2251493Sbostic #include <ufs/lfs/lfs_extern.h>
2351480Sbostic 
2452081Sbostic /*
2552081Sbostic  * LFS block write function.
2652081Sbostic  *
2752081Sbostic  * XXX
2852081Sbostic  * No write cost accounting is done.
2952081Sbostic  * This is almost certainly wrong for synchronous operations and NFS.
3052081Sbostic  */
3152081Sbostic int	locked_queue_count;		/* XXX Count of locked-down buffers. */
3252081Sbostic 
3351480Sbostic int
34*53528Sheideman lfs_bwrite (ap)
35*53528Sheideman 	struct vop_bwrite_args *ap;
36*53528Sheideman #define bp (ap->a_bp)
3751184Sbostic {
3852347Sbostic 	int s;
3951851Sbostic #ifdef VERBOSE
4051851Sbostic printf("lfs_bwrite\n");
4151851Sbostic #endif
4251851Sbostic 	/*
4352081Sbostic 	 * Set the delayed write flag and use reassignbuf to move the buffer
4452081Sbostic 	 * from the clean list to the dirty one.
4551851Sbostic 	 *
4652081Sbostic 	 * Set the B_LOCKED flag and unlock the buffer, causing brelse to move
4752081Sbostic 	 * the buffer onto the LOCKED free list.  This is necessary, otherwise
4852081Sbostic 	 * getnewbuf() would try to reclaim the buffers using bawrite, which
4952081Sbostic 	 * isn't going to work.
5051851Sbostic 	 */
5153143Sstaelin 	if (!(bp->b_flags & B_LOCKED)) {
5252081Sbostic 		++locked_queue_count;
5353143Sstaelin 		bp->b_flags |= B_DELWRI | B_LOCKED;
5453143Sstaelin 		bp->b_flags &= ~(B_READ | B_DONE | B_ERROR);
5553143Sstaelin 		s = splbio();
5653143Sstaelin #define	PMAP_BUG_FIX_HACK
5753143Sstaelin #ifdef PMAP_BUG_FIX_HACK
5853143Sstaelin 		if (((struct ufsmount *)
5953143Sstaelin 		    (bp->b_vp->v_mount->mnt_data))->um_lfs->lfs_ivnode !=
6053143Sstaelin 		    bp->b_vp)
6153143Sstaelin #endif
6253143Sstaelin 		reassignbuf(bp, bp->b_vp);
6353143Sstaelin 		splx(s);
6453143Sstaelin 	}
6551184Sbostic 	brelse(bp);
6651480Sbostic 	return (0);
6751184Sbostic }
68*53528Sheideman #undef bp
6952081Sbostic 
7052081Sbostic /*
7152081Sbostic  * XXX
7252081Sbostic  * This routine flushes buffers out of the B_LOCKED queue when LFS has too
7352081Sbostic  * many locked down.  Eventually the pageout daemon will simply call LFS
7452325Sbostic  * when pages need to be reclaimed.  Note, we have one static count of locked
7552325Sbostic  * buffers, so we can't have more than a single file system.  To make this
7652325Sbostic  * work for multiple file systems, put the count into the mount structure.
7752081Sbostic  */
7852081Sbostic void
7952081Sbostic lfs_flush()
8052081Sbostic {
8152081Sbostic 	register struct mount *mp;
8252081Sbostic 	struct mount *omp;
8352081Sbostic 
8452325Sbostic 	/* 1M in a 4K file system. */
8552325Sbostic 	if (locked_queue_count < 256)
8652081Sbostic 		return;
8752081Sbostic 	mp = rootfs;
8852081Sbostic 	do {
8952081Sbostic 		/*
9052081Sbostic 		 * The lock check below is to avoid races with mount
9152081Sbostic 		 * and unmount.
9252081Sbostic 		 */
9352081Sbostic 		if (mp->mnt_stat.f_type == MOUNT_LFS &&
9452081Sbostic 		    (mp->mnt_flag & (MNT_MLOCK|MNT_RDONLY|MNT_MPBUSY)) == 0 &&
9552081Sbostic 		    !vfs_busy(mp)) {
9652347Sbostic 			/*
9752347Sbostic 			 * We set the queue to 0 here because we are about to
9852347Sbostic 			 * write all the dirty buffers we have.  If more come
9952347Sbostic 			 * in while we're writing the segment, they may not
10052347Sbostic 			 * get written, so we want the count to reflect these
10152347Sbostic 			 * new writes after the segwrite completes.
10252347Sbostic 			 */
10352347Sbostic 			locked_queue_count = 0;
10452081Sbostic 			lfs_segwrite(mp, 0);
10552081Sbostic 			omp = mp;
10652081Sbostic 			mp = mp->mnt_next;
10752081Sbostic 			vfs_unbusy(omp);
10852081Sbostic 		} else
10952081Sbostic 			mp = mp->mnt_next;
11052081Sbostic 	} while (mp != rootfs);
11152081Sbostic }
112