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*69810Smargo * @(#)lfs_bio.c 8.10 (Berkeley) 06/10/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
lfs_bwrite(ap)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);
76*69810Smargo wakeup(&fs->lfs_nextseg);
7756865Smargo if (error = tsleep(&fs->lfs_avail, PCATCH | PUSER,
7856865Smargo "cleaner", NULL)) {
7956865Smargo brelse(bp);
8056865Smargo return (error);
8156865Smargo }
8255935Sbostic }
8355935Sbostic ip = VTOI((bp)->b_vp);
8464608Sbostic if (!(ip->i_flag & IN_MODIFIED))
8555935Sbostic ++fs->lfs_uinodes;
8664608Sbostic ip->i_flag |= IN_CHANGE | IN_MODIFIED | IN_UPDATE;
8769287Smckusick fs->lfs_avail -= db;
8852081Sbostic ++locked_queue_count;
8953867Sheideman bp->b_flags |= B_DELWRI | B_LOCKED;
9055935Sbostic bp->b_flags &= ~(B_READ | B_ERROR);
9153143Sstaelin s = splbio();
9253867Sheideman reassignbuf(bp, bp->b_vp);
9353143Sstaelin splx(s);
9453143Sstaelin }
9553867Sheideman brelse(bp);
9651480Sbostic return (0);
9751184Sbostic }
9852081Sbostic
9952081Sbostic /*
10052081Sbostic * XXX
10152081Sbostic * This routine flushes buffers out of the B_LOCKED queue when LFS has too
10252081Sbostic * many locked down. Eventually the pageout daemon will simply call LFS
10352325Sbostic * when pages need to be reclaimed. Note, we have one static count of locked
10452325Sbostic * buffers, so we can't have more than a single file system. To make this
10552325Sbostic * work for multiple file systems, put the count into the mount structure.
10652081Sbostic */
10752081Sbostic void
lfs_flush()10852081Sbostic lfs_flush()
10952081Sbostic {
11069582Smckusick register struct mount *mp, *nmp;
11169582Smckusick struct proc *p = curproc; /* XXX */
11252081Sbostic
11357066Smargo #ifdef DOSTATS
11457066Smargo ++lfs_stats.write_exceeded;
11557066Smargo #endif
11655935Sbostic if (lfs_writing)
11752081Sbostic return;
11855935Sbostic lfs_writing = 1;
11969582Smckusick simple_lock(&mountlist_slock);
12069582Smckusick for (mp = mountlist.cqh_first; mp != (void *)&mountlist; mp = nmp) {
12169582Smckusick if (vfs_busy(mp, LK_NOWAIT, &mountlist_slock, p)) {
12269582Smckusick nmp = mp->mnt_list.cqe_next;
12369582Smckusick continue;
12469582Smckusick }
12568675Smckusick if (mp->mnt_stat.f_type == lfs_mount_type &&
12669582Smckusick (mp->mnt_flag & MNT_RDONLY) == 0 &&
12755935Sbostic !((((struct ufsmount *)mp->mnt_data))->ufsmount_u.lfs)->lfs_dirops ) {
12852347Sbostic /*
12952347Sbostic * We set the queue to 0 here because we are about to
13052347Sbostic * write all the dirty buffers we have. If more come
13152347Sbostic * in while we're writing the segment, they may not
13252347Sbostic * get written, so we want the count to reflect these
13352347Sbostic * new writes after the segwrite completes.
13452347Sbostic */
13557066Smargo #ifdef DOSTATS
13657066Smargo ++lfs_stats.flush_invoked;
13757066Smargo #endif
13852081Sbostic lfs_segwrite(mp, 0);
13955935Sbostic }
14069582Smckusick simple_lock(&mountlist_slock);
14169582Smckusick nmp = mp->mnt_list.cqe_next;
14269582Smckusick vfs_unbusy(mp, p);
14365238Smckusick }
14469582Smckusick simple_unlock(&mountlist_slock);
14555935Sbostic lfs_writing = 0;
14652081Sbostic }
14755935Sbostic
14855935Sbostic int
lfs_check(vp,blkno)14955935Sbostic lfs_check(vp, blkno)
15055935Sbostic struct vnode *vp;
15168550Smckusick ufs_daddr_t blkno;
15255935Sbostic {
15355935Sbostic extern int lfs_allclean_wakeup;
15455935Sbostic int error;
15555935Sbostic
15656865Smargo error = 0;
15755935Sbostic if (incore(vp, blkno))
15855935Sbostic return (0);
15955935Sbostic if (locked_queue_count > WRITE_THRESHHOLD)
16055935Sbostic lfs_flush();
16156865Smargo
16256865Smargo /* If out of buffers, wait on writer */
16357066Smargo while (locked_queue_count > WAIT_THRESHHOLD) {
16457066Smargo #ifdef DOSTATS
16557066Smargo ++lfs_stats.wait_exceeded;
16657066Smargo #endif
16756865Smargo error = tsleep(&locked_queue_count, PCATCH | PUSER, "buffers",
16856865Smargo hz * LFS_BUFWAIT);
16957066Smargo }
17056865Smargo
17155935Sbostic return (error);
17255935Sbostic }
173