151184Sbostic /* 263375Sbostic * Copyright (c) 1991, 1993 363375Sbostic * The Regents of the University of California. All rights reserved. 451184Sbostic * 551184Sbostic * %sccs.include.redist.c% 651184Sbostic * 7*69582Smckusick * @(#)lfs_bio.c 8.9 (Berkeley) 05/20/95 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> 1656865Smargo #include <sys/kernel.h> 1751184Sbostic 1852081Sbostic #include <ufs/ufs/quota.h> 1952081Sbostic #include <ufs/ufs/inode.h> 2052081Sbostic #include <ufs/ufs/ufsmount.h> 2152081Sbostic 2251493Sbostic #include <ufs/lfs/lfs.h> 2351493Sbostic #include <ufs/lfs/lfs_extern.h> 2451480Sbostic 2552081Sbostic /* 2652081Sbostic * LFS block write function. 2752081Sbostic * 2852081Sbostic * XXX 2952081Sbostic * No write cost accounting is done. 3052081Sbostic * This is almost certainly wrong for synchronous operations and NFS. 3152081Sbostic */ 3256052Sbostic int lfs_allclean_wakeup; /* Cleaner wakeup address. */ 3352081Sbostic int locked_queue_count; /* XXX Count of locked-down buffers. */ 3455935Sbostic int lfs_writing; /* Set if already kicked off a writer 3555935Sbostic because of buffer space */ 3657066Smargo /* 3755935Sbostic #define WRITE_THRESHHOLD ((nbuf >> 2) - 10) 3855935Sbostic #define WAIT_THRESHHOLD ((nbuf >> 1) - 10) 3957066Smargo */ 4057066Smargo #define WAIT_THRESHHOLD (nbuf - (nbuf >> 2) - 10) 4157066Smargo #define WRITE_THRESHHOLD ((nbuf >> 1) - 10) 4256865Smargo #define LFS_BUFWAIT 2 4352081Sbostic 4451480Sbostic int 4554621Smckusick lfs_bwrite(ap) 4654621Smckusick struct vop_bwrite_args /* { 4754621Smckusick struct buf *a_bp; 4854621Smckusick } */ *ap; 4951184Sbostic { 5053867Sheideman register struct buf *bp = ap->a_bp; 5155935Sbostic struct lfs *fs; 5255935Sbostic struct inode *ip; 5369287Smckusick int db, error, s; 5455807Sbostic 5551851Sbostic /* 5652081Sbostic * Set the delayed write flag and use reassignbuf to move the buffer 5752081Sbostic * from the clean list to the dirty one. 5851851Sbostic * 5952081Sbostic * Set the B_LOCKED flag and unlock the buffer, causing brelse to move 6052081Sbostic * the buffer onto the LOCKED free list. This is necessary, otherwise 6152081Sbostic * getnewbuf() would try to reclaim the buffers using bawrite, which 6252081Sbostic * isn't going to work. 6356155Smargo * 6456155Smargo * XXX we don't let meta-data writes run out of space because they can 6556155Smargo * come from the segment writer. We need to make sure that there is 6656155Smargo * enough space reserved so that there's room to write meta-data 6756155Smargo * blocks. 6851851Sbostic */ 6953867Sheideman if (!(bp->b_flags & B_LOCKED)) { 7055935Sbostic fs = VFSTOUFS(bp->b_vp->v_mount)->um_lfs; 7169287Smckusick db = fragstodb(fs, numfrags(fs, bp->b_bcount)); 7269287Smckusick while (!LFS_FITS(fs, db) && !IS_IFILE(bp) && 7356155Smargo bp->b_lblkno > 0) { 7456865Smargo /* Out of space, need cleaner to run */ 7556052Sbostic wakeup(&lfs_allclean_wakeup); 7656865Smargo if (error = tsleep(&fs->lfs_avail, PCATCH | PUSER, 7756865Smargo "cleaner", NULL)) { 7856865Smargo brelse(bp); 7956865Smargo return (error); 8056865Smargo } 8155935Sbostic } 8255935Sbostic ip = VTOI((bp)->b_vp); 8364608Sbostic if (!(ip->i_flag & IN_MODIFIED)) 8455935Sbostic ++fs->lfs_uinodes; 8564608Sbostic ip->i_flag |= IN_CHANGE | IN_MODIFIED | IN_UPDATE; 8669287Smckusick fs->lfs_avail -= db; 8752081Sbostic ++locked_queue_count; 8853867Sheideman bp->b_flags |= B_DELWRI | B_LOCKED; 8955935Sbostic bp->b_flags &= ~(B_READ | B_ERROR); 9053143Sstaelin s = splbio(); 9153867Sheideman reassignbuf(bp, bp->b_vp); 9253143Sstaelin splx(s); 9353143Sstaelin } 9453867Sheideman brelse(bp); 9551480Sbostic return (0); 9651184Sbostic } 9752081Sbostic 9852081Sbostic /* 9952081Sbostic * XXX 10052081Sbostic * This routine flushes buffers out of the B_LOCKED queue when LFS has too 10152081Sbostic * many locked down. Eventually the pageout daemon will simply call LFS 10252325Sbostic * when pages need to be reclaimed. Note, we have one static count of locked 10352325Sbostic * buffers, so we can't have more than a single file system. To make this 10452325Sbostic * work for multiple file systems, put the count into the mount structure. 10552081Sbostic */ 10652081Sbostic void 10752081Sbostic lfs_flush() 10852081Sbostic { 109*69582Smckusick register struct mount *mp, *nmp; 110*69582Smckusick struct proc *p = curproc; /* XXX */ 11152081Sbostic 11257066Smargo #ifdef DOSTATS 11357066Smargo ++lfs_stats.write_exceeded; 11457066Smargo #endif 11555935Sbostic if (lfs_writing) 11652081Sbostic return; 11755935Sbostic lfs_writing = 1; 118*69582Smckusick simple_lock(&mountlist_slock); 119*69582Smckusick for (mp = mountlist.cqh_first; mp != (void *)&mountlist; mp = nmp) { 120*69582Smckusick if (vfs_busy(mp, LK_NOWAIT, &mountlist_slock, p)) { 121*69582Smckusick nmp = mp->mnt_list.cqe_next; 122*69582Smckusick continue; 123*69582Smckusick } 12468675Smckusick if (mp->mnt_stat.f_type == lfs_mount_type && 125*69582Smckusick (mp->mnt_flag & MNT_RDONLY) == 0 && 12655935Sbostic !((((struct ufsmount *)mp->mnt_data))->ufsmount_u.lfs)->lfs_dirops ) { 12752347Sbostic /* 12852347Sbostic * We set the queue to 0 here because we are about to 12952347Sbostic * write all the dirty buffers we have. If more come 13052347Sbostic * in while we're writing the segment, they may not 13152347Sbostic * get written, so we want the count to reflect these 13252347Sbostic * new writes after the segwrite completes. 13352347Sbostic */ 13457066Smargo #ifdef DOSTATS 13557066Smargo ++lfs_stats.flush_invoked; 13657066Smargo #endif 13752081Sbostic lfs_segwrite(mp, 0); 13855935Sbostic } 139*69582Smckusick simple_lock(&mountlist_slock); 140*69582Smckusick nmp = mp->mnt_list.cqe_next; 141*69582Smckusick vfs_unbusy(mp, p); 14265238Smckusick } 143*69582Smckusick simple_unlock(&mountlist_slock); 14455935Sbostic lfs_writing = 0; 14552081Sbostic } 14655935Sbostic 14755935Sbostic int 14855935Sbostic lfs_check(vp, blkno) 14955935Sbostic struct vnode *vp; 15068550Smckusick ufs_daddr_t blkno; 15155935Sbostic { 15255935Sbostic extern int lfs_allclean_wakeup; 15355935Sbostic int error; 15455935Sbostic 15556865Smargo error = 0; 15655935Sbostic if (incore(vp, blkno)) 15755935Sbostic return (0); 15855935Sbostic if (locked_queue_count > WRITE_THRESHHOLD) 15955935Sbostic lfs_flush(); 16056865Smargo 16156865Smargo /* If out of buffers, wait on writer */ 16257066Smargo while (locked_queue_count > WAIT_THRESHHOLD) { 16357066Smargo #ifdef DOSTATS 16457066Smargo ++lfs_stats.wait_exceeded; 16557066Smargo #endif 16656865Smargo error = tsleep(&locked_queue_count, PCATCH | PUSER, "buffers", 16756865Smargo hz * LFS_BUFWAIT); 16857066Smargo } 16956865Smargo 17055935Sbostic return (error); 17155935Sbostic } 172