summaryrefslogtreecommitdiffstats
path: root/sys/ufs/ffs
diff options
context:
space:
mode:
authordyson <dyson@FreeBSD.org>1998-01-06 05:26:17 +0000
committerdyson <dyson@FreeBSD.org>1998-01-06 05:26:17 +0000
commitcb2800cd94015c1a5a07a78ac1299961c8cbfee8 (patch)
tree458fd90f400f25f9120e71fd368963d5190181bb /sys/ufs/ffs
parent082257799eb016d17f2ea10684dc8c250c8dce19 (diff)
downloadFreeBSD-src-cb2800cd94015c1a5a07a78ac1299961c8cbfee8.zip
FreeBSD-src-cb2800cd94015c1a5a07a78ac1299961c8cbfee8.tar.gz
Make our v_usecount vnode reference count work identically to the
original BSD code. The association between the vnode and the vm_object no longer includes reference counts. The major difference is that vm_object's are no longer freed gratuitiously from the vnode, and so once an object is created for the vnode, it will last as long as the vnode does. When a vnode object reference count is incremented, then the underlying vnode reference count is incremented also. The two "objects" are now more intimately related, and so the interactions are now much less complex. When vnodes are now normally placed onto the free queue with an object still attached. The rundown of the object happens at vnode rundown time, and happens with exactly the same filesystem semantics of the original VFS code. There is absolutely no need for vnode_pager_uncache and other travesties like that anymore. A side-effect of these changes is that SMP locking should be much simpler, the I/O copyin/copyout optimizations work, NFS should be more ponderable, and further work on layered filesystems should be less frustrating, because of the totally coherent management of the vnode objects and vnodes. Please be careful with your system while running this code, but I would greatly appreciate feedback as soon a reasonably possible.
Diffstat (limited to 'sys/ufs/ffs')
-rw-r--r--sys/ufs/ffs/ffs_balloc.c6
-rw-r--r--sys/ufs/ffs/ffs_inode.c9
-rw-r--r--sys/ufs/ffs/ffs_vfsops.c43
-rw-r--r--sys/ufs/ffs/ffs_vnops.c39
4 files changed, 77 insertions, 20 deletions
diff --git a/sys/ufs/ffs/ffs_balloc.c b/sys/ufs/ffs/ffs_balloc.c
index d66d48f..c4edbd3 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.8 (Berkeley) 6/16/95
- * $Id: ffs_balloc.c,v 1.15 1997/08/02 14:33:18 bde Exp $
+ * $Id: ffs_balloc.c,v 1.16 1997/12/05 19:55:49 bde Exp $
*/
#include <sys/param.h>
@@ -237,6 +237,8 @@ ffs_balloc(ip, lbn, size, cred, bpp, flags)
if (flags & B_SYNC) {
bwrite(bp);
} else {
+ if (bp->b_bufsize == fs->fs_bsize)
+ bp->b_flags |= B_CLUSTEROK;
bdwrite(bp);
}
}
@@ -265,6 +267,8 @@ ffs_balloc(ip, lbn, size, cred, bpp, flags)
if (flags & B_SYNC) {
bwrite(bp);
} else {
+ if (bp->b_bufsize == fs->fs_bsize)
+ bp->b_flags |= B_CLUSTEROK;
bdwrite(bp);
}
*bpp = nbp;
diff --git a/sys/ufs/ffs/ffs_inode.c b/sys/ufs/ffs/ffs_inode.c
index 92bb2a7..77f72d3 100644
--- a/sys/ufs/ffs/ffs_inode.c
+++ b/sys/ufs/ffs/ffs_inode.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)ffs_inode.c 8.13 (Berkeley) 4/21/95
- * $Id: ffs_inode.c,v 1.28 1997/10/16 10:49:28 phk Exp $
+ * $Id: ffs_inode.c,v 1.29 1997/10/16 20:32:34 phk Exp $
*/
#include "opt_quota.h"
@@ -134,7 +134,8 @@ ffs_update(vp, access, modify, waitfor)
if (waitfor && (vp->v_mount->mnt_flag & MNT_ASYNC) == 0)
return (bwrite(bp));
else {
- bp->b_flags |= B_CLUSTEROK;
+ if (bp->b_bufsize == fs->fs_bsize)
+ bp->b_flags |= B_CLUSTEROK;
bdwrite(bp);
return (0);
}
@@ -214,6 +215,8 @@ ffs_truncate(vp, length, flags, cred, p)
return (error);
oip->i_size = length;
vnode_pager_setsize(ovp, length);
+ if (bp->b_bufsize == fs->fs_bsize)
+ bp->b_flags |= B_CLUSTEROK;
if (aflags & B_SYNC)
bwrite(bp);
else if (ovp->v_mount->mnt_flag & MNT_ASYNC)
@@ -245,6 +248,8 @@ ffs_truncate(vp, length, flags, cred, p)
size = blksize(fs, oip, lbn);
bzero((char *)bp->b_data + offset, (u_int)(size - offset));
allocbuf(bp, size);
+ if (bp->b_bufsize == fs->fs_bsize)
+ bp->b_flags |= B_CLUSTEROK;
if (aflags & B_SYNC)
bwrite(bp);
else if (ovp->v_mount->mnt_flag & MNT_ASYNC)
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index 16f77c6..e78bceb 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.31 (Berkeley) 5/20/95
- * $Id: ffs_vfsops.c,v 1.62 1997/11/12 05:42:25 julian Exp $
+ * $Id: ffs_vfsops.c,v 1.63 1997/12/29 00:24:28 dyson Exp $
*/
#include "opt_quota.h"
@@ -63,6 +63,7 @@
#include <vm/vm_prot.h>
#include <vm/vm_page.h>
#include <vm/vm_extern.h>
+#include <vm/vm_object.h>
static MALLOC_DEFINE(M_FFSNODE, "FFS node", "FFS vnode private part");
@@ -364,6 +365,7 @@ ffs_reload(mp, cred, p)
struct buf *bp;
struct fs *fs, *newfs;
struct partinfo dpart;
+ dev_t dev;
int i, blks, size, error;
int32_t *lp;
@@ -375,6 +377,18 @@ ffs_reload(mp, cred, p)
devvp = VFSTOUFS(mp)->um_devvp;
if (vinvalbuf(devvp, 0, cred, p, 0, 0))
panic("ffs_reload: dirty1");
+
+ dev = devvp->v_rdev;
+ /*
+ * Only VMIO the backing device if the backing device is a real
+ * block device. This excludes the original MFS implementation.
+ * Note that it is optional that the backing device be VMIOed. This
+ * increases the opportunity for metadata caching.
+ */
+ if ((devvp->v_type == VBLK) && (major(dev) < nblkdev)) {
+ vfs_object_create(devvp, p, p->p_ucred, 0);
+ }
+
/*
* Step 2: re-read superblock from disk.
*/
@@ -509,17 +523,31 @@ ffs_mountfs(devvp, mp, p, malloctype)
if (error)
return (error);
ncount = vcount(devvp);
+/*
if (devvp->v_object)
ncount -= 1;
+*/
if (ncount > 1 && devvp != rootvp)
return (EBUSY);
if (error = vinvalbuf(devvp, V_SAVE, cred, p, 0, 0))
return (error);
+ /*
+ * Only VMIO the backing device if the backing device is a real
+ * block device. This excludes the original MFS implementation.
+ * Note that it is optional that the backing device be VMIOed. This
+ * increases the opportunity for metadata caching.
+ */
+ if ((devvp->v_type == VBLK) && (major(dev) < nblkdev)) {
+ vfs_object_create(devvp, p, p->p_ucred, 0);
+ }
+
+
ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, p);
if (error)
return (error);
+
if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, cred, p) != 0)
size = DEV_BSIZE;
else
@@ -641,15 +669,6 @@ ffs_mountfs(devvp, mp, p, malloctype)
fs->fs_clean = 0;
(void) ffs_sbupdate(ump, MNT_WAIT);
}
- /*
- * Only VMIO the backing device if the backing device is a real
- * block device. This excludes the original MFS implementation.
- * Note that it is optional that the backing device be VMIOed. This
- * increases the opportunity for metadata caching.
- */
- if ((devvp->v_type == VBLK) && (major(devvp->v_rdev) < nblkdev)) {
- vfs_object_create(devvp, p, p->p_ucred, 0);
- }
return (0);
out:
if (bp)
@@ -727,6 +746,10 @@ ffs_unmount(mp, mntflags, p)
}
ump->um_devvp->v_specflags &= ~SI_MOUNTEDON;
+ vinvalbuf(ump->um_devvp, V_SAVE, NOCRED, p, 0, 0);
+ if (ump->um_devvp->v_object)
+ vm_object_terminate(ump->um_devvp->v_object);
+
error = VOP_CLOSE(ump->um_devvp, fs->fs_ronly ? FREAD : FREAD|FWRITE,
NOCRED, p);
diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c
index 341b811..d3b68b7 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.15 (Berkeley) 5/14/95
- * $Id: ffs_vnops.c,v 1.36 1997/10/16 20:32:35 phk Exp $
+ * $Id: ffs_vnops.c,v 1.37 1997/10/27 13:33:45 bde Exp $
*/
#include <sys/param.h>
@@ -124,6 +124,16 @@ ffs_fsync(ap)
struct buf *nbp;
int pass;
int s;
+ daddr_t lbn;
+
+
+ if (vp->v_type == VBLK) {
+ lbn = INT_MAX;
+ } else {
+ struct inode *ip;
+ ip = VTOI(vp);
+ lbn = lblkno(ip->i_fs, (ip->i_size + ip->i_fs->fs_bsize - 1));
+ }
pass = 0;
/*
@@ -133,24 +143,40 @@ 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) || (pass == 0 && (bp->b_blkno < 0)))
+ if ((bp->b_flags & B_BUSY) || (pass == 0 && (bp->b_lblkno < 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)) ||
+ ((vp->v_type != VREG) && (vp->v_type != VBLK))) {
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.
*/
- if (bp->b_vp == vp || ap->a_waitfor == MNT_NOWAIT)
- (void) bawrite(bp);
- else
+ if ((bp->b_vp == vp) && (ap->a_waitfor == MNT_NOWAIT)) {
+ if (bp->b_flags & B_CLUSTEROK) {
+ bdwrite(bp);
+ (void) vfs_bio_awrite(bp);
+ } else {
+ (void) bawrite(bp);
+ }
+ } else {
(void) bwrite(bp);
+ }
+
+ } else if ((vp->v_type == VREG) && (bp->b_lblkno >= lbn)) {
+
+ bremfree(bp);
+ bp->b_flags |= B_BUSY | B_INVAL | B_NOCACHE;
+ brelse(bp);
+ splx(s);
+
} else {
vfs_bio_awrite(bp);
splx(s);
@@ -182,4 +208,3 @@ loop:
gettime(&tv);
return (UFS_UPDATE(ap->a_vp, &tv, &tv, ap->a_waitfor == MNT_WAIT));
}
-
OpenPOWER on IntegriCloud