xref: /original-bsd/sys/ufs/lfs/lfs_bio.c (revision 68d9582f)
1 /*
2  * Copyright (c) 1991 Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  *
7  *	@(#)lfs_bio.c	7.11 (Berkeley) 06/04/92
8  */
9 
10 #include <sys/param.h>
11 #include <sys/proc.h>
12 #include <sys/buf.h>
13 #include <sys/vnode.h>
14 #include <sys/resourcevar.h>
15 #include <sys/mount.h>
16 
17 #include <ufs/ufs/quota.h>
18 #include <ufs/ufs/inode.h>
19 #include <ufs/ufs/ufsmount.h>
20 
21 #include <ufs/lfs/lfs.h>
22 #include <ufs/lfs/lfs_extern.h>
23 
24 /*
25  * LFS block write function.
26  *
27  * XXX
28  * No write cost accounting is done.
29  * This is almost certainly wrong for synchronous operations and NFS.
30  */
31 int	locked_queue_count;		/* XXX Count of locked-down buffers. */
32 
33 int
34 lfs_bwrite (ap)
35 	struct vop_bwrite_args *ap;
36 {
37 	register struct buf *bp = ap->a_bp;
38 	int s;
39 #ifdef VERBOSE
40 printf("lfs_bwrite\n");
41 #endif
42 	/*
43 	 * Set the delayed write flag and use reassignbuf to move the buffer
44 	 * from the clean list to the dirty one.
45 	 *
46 	 * Set the B_LOCKED flag and unlock the buffer, causing brelse to move
47 	 * the buffer onto the LOCKED free list.  This is necessary, otherwise
48 	 * getnewbuf() would try to reclaim the buffers using bawrite, which
49 	 * isn't going to work.
50 	 */
51 	if (!(bp->b_flags & B_LOCKED)) {
52 		++locked_queue_count;
53 		bp->b_flags |= B_DELWRI | B_LOCKED;
54 		bp->b_flags &= ~(B_READ | B_DONE | B_ERROR);
55 		s = splbio();
56 #define	PMAP_BUG_FIX_HACK
57 #ifdef PMAP_BUG_FIX_HACK
58 		if (((struct ufsmount *)
59 		    (bp->b_vp->v_mount->mnt_data))->um_lfs->lfs_ivnode !=
60 		    bp->b_vp)
61 #endif
62 		reassignbuf(bp, bp->b_vp);
63 		splx(s);
64 	}
65 	brelse(bp);
66 	return (0);
67 }
68 
69 /*
70  * XXX
71  * This routine flushes buffers out of the B_LOCKED queue when LFS has too
72  * many locked down.  Eventually the pageout daemon will simply call LFS
73  * when pages need to be reclaimed.  Note, we have one static count of locked
74  * buffers, so we can't have more than a single file system.  To make this
75  * work for multiple file systems, put the count into the mount structure.
76  */
77 void
78 lfs_flush()
79 {
80 	register struct mount *mp;
81 	struct mount *omp;
82 
83 	/* 1M in a 4K file system. */
84 	if (locked_queue_count < 256)
85 		return;
86 	mp = rootfs;
87 	do {
88 		/*
89 		 * The lock check below is to avoid races with mount
90 		 * and unmount.
91 		 */
92 		if (mp->mnt_stat.f_type == MOUNT_LFS &&
93 		    (mp->mnt_flag & (MNT_MLOCK|MNT_RDONLY|MNT_MPBUSY)) == 0 &&
94 		    !vfs_busy(mp)) {
95 			/*
96 			 * We set the queue to 0 here because we are about to
97 			 * write all the dirty buffers we have.  If more come
98 			 * in while we're writing the segment, they may not
99 			 * get written, so we want the count to reflect these
100 			 * new writes after the segwrite completes.
101 			 */
102 			locked_queue_count = 0;
103 			lfs_segwrite(mp, 0);
104 			omp = mp;
105 			mp = mp->mnt_next;
106 			vfs_unbusy(omp);
107 		} else
108 			mp = mp->mnt_next;
109 	} while (mp != rootfs);
110 }
111