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.9 (Berkeley) 05/14/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 #define bp (ap->a_bp) 37 { 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 #undef bp 69 70 /* 71 * XXX 72 * This routine flushes buffers out of the B_LOCKED queue when LFS has too 73 * many locked down. Eventually the pageout daemon will simply call LFS 74 * when pages need to be reclaimed. Note, we have one static count of locked 75 * buffers, so we can't have more than a single file system. To make this 76 * work for multiple file systems, put the count into the mount structure. 77 */ 78 void 79 lfs_flush() 80 { 81 register struct mount *mp; 82 struct mount *omp; 83 84 /* 1M in a 4K file system. */ 85 if (locked_queue_count < 256) 86 return; 87 mp = rootfs; 88 do { 89 /* 90 * The lock check below is to avoid races with mount 91 * and unmount. 92 */ 93 if (mp->mnt_stat.f_type == MOUNT_LFS && 94 (mp->mnt_flag & (MNT_MLOCK|MNT_RDONLY|MNT_MPBUSY)) == 0 && 95 !vfs_busy(mp)) { 96 /* 97 * We set the queue to 0 here because we are about to 98 * write all the dirty buffers we have. If more come 99 * in while we're writing the segment, they may not 100 * get written, so we want the count to reflect these 101 * new writes after the segwrite completes. 102 */ 103 locked_queue_count = 0; 104 lfs_segwrite(mp, 0); 105 omp = mp; 106 mp = mp->mnt_next; 107 vfs_unbusy(omp); 108 } else 109 mp = mp->mnt_next; 110 } while (mp != rootfs); 111 } 112