151184Sbostic /* 251493Sbostic * Copyright (c) 1991 Regents of the University of California. 351184Sbostic * All rights reserved. 451184Sbostic * 551184Sbostic * %sccs.include.redist.c% 651184Sbostic * 7*53867Sheideman * @(#)lfs_bio.c 7.11 (Berkeley) 06/04/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 3453528Sheideman lfs_bwrite (ap) 3553528Sheideman struct vop_bwrite_args *ap; 3651184Sbostic { 37*53867Sheideman register struct buf *bp = ap->a_bp; 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 */ 51*53867Sheideman if (!(bp->b_flags & B_LOCKED)) { 5252081Sbostic ++locked_queue_count; 53*53867Sheideman bp->b_flags |= B_DELWRI | B_LOCKED; 54*53867Sheideman 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 *) 59*53867Sheideman (bp->b_vp->v_mount->mnt_data))->um_lfs->lfs_ivnode != 60*53867Sheideman bp->b_vp) 6153143Sstaelin #endif 62*53867Sheideman reassignbuf(bp, bp->b_vp); 6353143Sstaelin splx(s); 6453143Sstaelin } 65*53867Sheideman brelse(bp); 6651480Sbostic return (0); 6751184Sbostic } 6852081Sbostic 6952081Sbostic /* 7052081Sbostic * XXX 7152081Sbostic * This routine flushes buffers out of the B_LOCKED queue when LFS has too 7252081Sbostic * many locked down. Eventually the pageout daemon will simply call LFS 7352325Sbostic * when pages need to be reclaimed. Note, we have one static count of locked 7452325Sbostic * buffers, so we can't have more than a single file system. To make this 7552325Sbostic * work for multiple file systems, put the count into the mount structure. 7652081Sbostic */ 7752081Sbostic void 7852081Sbostic lfs_flush() 7952081Sbostic { 8052081Sbostic register struct mount *mp; 8152081Sbostic struct mount *omp; 8252081Sbostic 8352325Sbostic /* 1M in a 4K file system. */ 8452325Sbostic if (locked_queue_count < 256) 8552081Sbostic return; 8652081Sbostic mp = rootfs; 8752081Sbostic do { 8852081Sbostic /* 8952081Sbostic * The lock check below is to avoid races with mount 9052081Sbostic * and unmount. 9152081Sbostic */ 9252081Sbostic if (mp->mnt_stat.f_type == MOUNT_LFS && 9352081Sbostic (mp->mnt_flag & (MNT_MLOCK|MNT_RDONLY|MNT_MPBUSY)) == 0 && 9452081Sbostic !vfs_busy(mp)) { 9552347Sbostic /* 9652347Sbostic * We set the queue to 0 here because we are about to 9752347Sbostic * write all the dirty buffers we have. If more come 9852347Sbostic * in while we're writing the segment, they may not 9952347Sbostic * get written, so we want the count to reflect these 10052347Sbostic * new writes after the segwrite completes. 10152347Sbostic */ 10252347Sbostic locked_queue_count = 0; 10352081Sbostic lfs_segwrite(mp, 0); 10452081Sbostic omp = mp; 10552081Sbostic mp = mp->mnt_next; 10652081Sbostic vfs_unbusy(omp); 10752081Sbostic } else 10852081Sbostic mp = mp->mnt_next; 10952081Sbostic } while (mp != rootfs); 11052081Sbostic } 111