diff options
author | dg <dg@FreeBSD.org> | 1995-04-09 06:03:56 +0000 |
---|---|---|
committer | dg <dg@FreeBSD.org> | 1995-04-09 06:03:56 +0000 |
commit | b804a532828494b010ef0df5ed1bdef80932bc75 (patch) | |
tree | d7255955eb6b243461a28e283cd09739dbf8dbe7 /sys/ufs/ffs | |
parent | 78a655a0460b2e110a8aee7d5ee8ae5d27258f2f (diff) | |
download | FreeBSD-src-b804a532828494b010ef0df5ed1bdef80932bc75.zip FreeBSD-src-b804a532828494b010ef0df5ed1bdef80932bc75.tar.gz |
Changes from John Dyson and myself:
Fixed remaining known bugs in the buffer IO and VM system.
vfs_bio.c:
Fixed some race conditions and locking bugs. Improved performance
by removing some (now) unnecessary code and fixing some broken
logic.
Fixed process accounting of # of FS outputs.
Properly handle NFS interrupts (B_EINTR).
(various)
Replaced calls to clrbuf() with calls to an optimized routine
called vfs_bio_clrbuf().
(various FS sync)
Sync out modified vnode_pager backed pages.
ffs_vnops.c:
Do two passes: Sync out file data first, then indirect blocks.
vm_fault.c:
Fixed deadly embrace caused by acquiring locks in the wrong order.
vnode_pager.c:
Changed to use buffer I/O system for writing out modified pages. This
should fix the problem with the modification date previous not getting
updated. Also dramatically simplifies the code. Note that this is
going to change in the future and be implemented via VOP_PUTPAGES().
vm_object.c:
Fixed a pile of bugs related to cleaning (vnode) objects. The performance
of vm_object_page_clean() is terrible when dealing with huge objects,
but this will change when we implement a binary tree to keep the object
pages sorted.
vm_pageout.c:
Fixed broken clustering of pageouts. Fixed race conditions and other
lockup style bugs in the scanning of pages. Improved performance.
Diffstat (limited to 'sys/ufs/ffs')
-rw-r--r-- | sys/ufs/ffs/ffs_balloc.c | 10 | ||||
-rw-r--r-- | sys/ufs/ffs/ffs_vfsops.c | 15 | ||||
-rw-r--r-- | sys/ufs/ffs/ffs_vnops.c | 37 |
3 files changed, 47 insertions, 15 deletions
diff --git a/sys/ufs/ffs/ffs_balloc.c b/sys/ufs/ffs/ffs_balloc.c index b9994a1..8621869 100644 --- a/sys/ufs/ffs/ffs_balloc.c +++ b/sys/ufs/ffs/ffs_balloc.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)ffs_balloc.c 8.4 (Berkeley) 9/23/93 - * $Id: ffs_balloc.c,v 1.5 1995/03/03 22:13:16 davidg Exp $ + * $Id: ffs_balloc.c,v 1.6 1995/03/19 14:29:13 davidg Exp $ */ #include <sys/param.h> @@ -150,7 +150,7 @@ ffs_balloc(ip, bn, size, cred, bpp, flags) bp = getblk(vp, bn, nsize, 0, 0); bp->b_blkno = fsbtodb(fs, newb); if (flags & B_CLRBUF) - clrbuf(bp); + vfs_bio_clrbuf(bp); } ip->i_db[bn] = dbtofsb(fs, bp->b_blkno); ip->i_flag |= IN_CHANGE | IN_UPDATE; @@ -182,7 +182,7 @@ ffs_balloc(ip, bn, size, cred, bpp, flags) nb = newb; bp = getblk(vp, indirs[1].in_lbn, fs->fs_bsize, 0, 0); bp->b_blkno = fsbtodb(fs, newb); - clrbuf(bp); + vfs_bio_clrbuf(bp); /* * Write synchronously so that indirect blocks * never point at garbage. @@ -225,7 +225,7 @@ ffs_balloc(ip, bn, size, cred, bpp, flags) nb = newb; nbp = getblk(vp, indirs[i].in_lbn, fs->fs_bsize, 0, 0); nbp->b_blkno = fsbtodb(fs, nb); - clrbuf(nbp); + vfs_bio_clrbuf(nbp); /* * Write synchronously so that indirect blocks * never point at garbage. @@ -262,7 +262,7 @@ ffs_balloc(ip, bn, size, cred, bpp, flags) nbp = getblk(vp, lbn, fs->fs_bsize, 0, 0); nbp->b_blkno = fsbtodb(fs, nb); if (flags & B_CLRBUF) - clrbuf(nbp); + vfs_bio_clrbuf(nbp); bap[indirs[i].in_off] = nb; /* * If required, write synchronously, otherwise use diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c index 6776049..fce754b 100644 --- a/sys/ufs/ffs/ffs_vfsops.c +++ b/sys/ufs/ffs/ffs_vfsops.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)ffs_vfsops.c 8.8 (Berkeley) 4/18/94 - * $Id: ffs_vfsops.c,v 1.14 1995/03/18 18:03:29 davidg Exp $ + * $Id: ffs_vfsops.c,v 1.15 1995/03/28 07:57:47 bde Exp $ */ #include <sys/param.h> @@ -60,6 +60,10 @@ #include <ufs/ffs/fs.h> #include <ufs/ffs/ffs_extern.h> +#include <vm/vm.h> +#include <vm/vm_page.h> +#include <vm/vm_object.h> + int ffs_sbupdate __P((struct ufsmount *, int)); int ffs_reload __P((struct mount *,struct ucred *,struct proc *)); int ffs_oldfscompat __P((struct fs *)); @@ -662,6 +666,15 @@ loop: if (VOP_ISLOCKED(vp)) continue; ip = VTOI(vp); + if (vp->v_vmdata && + (((vm_object_t) vp->v_vmdata)->flags & OBJ_WRITEABLE)) { + if (vget(vp, 1)) + goto loop; + _vm_object_page_clean( (vm_object_t) vp->v_vmdata, + 0, 0, 0); + vput(vp); + } + if (((vp->v_type == VCHR) || ((ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0)) && vp->v_dirtyblkhd.lh_first == NULL) diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c index be78eaf..ef08ebd 100644 --- a/sys/ufs/ffs/ffs_vnops.c +++ b/sys/ufs/ffs/ffs_vnops.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)ffs_vnops.c 8.7 (Berkeley) 2/3/94 - * $Id: ffs_vnops.c,v 1.7 1994/10/10 01:04:40 phk Exp $ + * $Id: ffs_vnops.c,v 1.8 1995/01/09 16:05:19 davidg Exp $ */ #include <sys/param.h> @@ -50,6 +50,8 @@ #include <sys/lockf.h> #include <vm/vm.h> +#include <vm/vm_page.h> +#include <vm/vm_object.h> #include <miscfs/specfs/specdev.h> #include <miscfs/fifofs/fifo.h> @@ -248,29 +250,39 @@ ffs_fsync(ap) register struct buf *bp; struct timeval tv; struct buf *nbp; + int pass; int s; /* + * If the vnode has an object, then flush all of the dirty pages + * into the buffer cache. + */ + + if (vp->v_vmdata) + _vm_object_page_clean((vm_object_t)vp->v_vmdata, 0, 0, 0); + + pass = 0; + /* * Flush all dirty buffers associated with a vnode. */ loop: s = splbio(); for (bp = vp->v_dirtyblkhd.lh_first; bp; bp = nbp) { nbp = bp->b_vnbufs.le_next; - if ((bp->b_flags & B_BUSY)) + if ((bp->b_flags & B_BUSY) || (pass == 0 && (bp->b_blkno < 0))) continue; if ((bp->b_flags & B_DELWRI) == 0) panic("ffs_fsync: not dirty"); - if (bp->b_vp != vp && ap->a_waitfor != MNT_NOWAIT) { + if (bp->b_vp != vp || ap->a_waitfor != MNT_NOWAIT) { bremfree(bp); bp->b_flags |= B_BUSY; splx(s); - /* - * Wait for I/O associated with indirect blocks to complete, - * since there is no way to quickly wait for them below. - */ + /* + * Wait for I/O associated with indirect blocks to complete, + * since there is no way to quickly wait for them below. + */ if (bp->b_vp == vp || ap->a_waitfor == MNT_NOWAIT) (void) bawrite(bp); else @@ -281,12 +293,20 @@ loop: } goto loop; } - + splx(s); + + if (pass == 0) { + pass = 1; + goto loop; + } + if (ap->a_waitfor == MNT_WAIT) { + s = splbio(); while (vp->v_numoutput) { vp->v_flag |= VBWAIT; (void) tsleep((caddr_t)&vp->v_numoutput, PRIBIO + 1, "ffsfsn", 0); } + splx(s); #ifdef DIAGNOSTIC if (vp->v_dirtyblkhd.lh_first) { vprint("ffs_fsync: dirty", vp); @@ -294,7 +314,6 @@ loop: } #endif } - splx(s); tv = time; return (VOP_UPDATE(ap->a_vp, &tv, &tv, ap->a_waitfor == MNT_WAIT)); |