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.4 (Berkeley) 12/31/91 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(bp) 35 register BUF *bp; 36 { 37 #ifdef VERBOSE 38 printf("lfs_bwrite\n"); 39 #endif 40 /* 41 * Set the delayed write flag and use reassignbuf to move the buffer 42 * from the clean list to the dirty one. 43 * 44 * Set the B_LOCKED flag and unlock the buffer, causing brelse to move 45 * the buffer onto the LOCKED free list. This is necessary, otherwise 46 * getnewbuf() would try to reclaim the buffers using bawrite, which 47 * isn't going to work. 48 */ 49 if (!(bp->b_flags & B_LOCKED)) 50 ++locked_queue_count; 51 bp->b_flags |= B_DELWRI | B_LOCKED; 52 bp->b_flags &= ~(B_READ | B_DONE | B_ERROR); 53 reassignbuf(bp, bp->b_vp); 54 brelse(bp); 55 return (0); 56 } 57 58 /* 59 * XXX 60 * This routine flushes buffers out of the B_LOCKED queue when LFS has too 61 * many locked down. Eventually the pageout daemon will simply call LFS 62 * when pages need to be reclaimed. 63 */ 64 void 65 lfs_flush() 66 { 67 register struct mount *mp; 68 struct mount *omp; 69 70 /* 800K in a 4K file system. */ 71 if (locked_queue_count < 200) 72 return; 73 mp = rootfs; 74 do { 75 /* 76 * The lock check below is to avoid races with mount 77 * and unmount. 78 */ 79 if (mp->mnt_stat.f_type == MOUNT_LFS && 80 (mp->mnt_flag & (MNT_MLOCK|MNT_RDONLY|MNT_MPBUSY)) == 0 && 81 !vfs_busy(mp)) { 82 lfs_segwrite(mp, 0); 83 omp = mp; 84 mp = mp->mnt_next; 85 vfs_unbusy(omp); 86 } else 87 mp = mp->mnt_next; 88 } while (mp != rootfs); 89 /* Not exact, but it doesn't matter. */ 90 locked_queue_count = 0; 91 } 92