summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2000-10-09 14:18:07 +0000
committerphk <phk@FreeBSD.org>2000-10-09 14:18:07 +0000
commit25e67656df365dc742ef9b23471d781550fda24e (patch)
tree1d6bf0225b0494ec5a62bf8525a63fec403b7e65
parentbee0dc7d0d90adee364a7e41c5adeaedecd050f5 (diff)
downloadFreeBSD-src-25e67656df365dc742ef9b23471d781550fda24e.zip
FreeBSD-src-25e67656df365dc742ef9b23471d781550fda24e.tar.gz
Don't hold an extra reference to vnodes. Devfs vnodes are sufficiently
cheap to setup that it doesn't really matter that we recycle device vnodes at kleenex speed. Implement first cut try at killing cloned devices when they are not needed anymore. For now only the bpf driver is involved in this experiment. Cloned devices can set the SI_CHEAPCLONE flag which allows us to destroy_dev() it when the vcount() drops to zero and the vnode is reclaimed. For now it's a requirement that the driver doesn't keep persistent state from close to (re)open. Some whitespace changes.
-rw-r--r--sys/fs/devfs/devfs_devs.c16
-rw-r--r--sys/fs/devfs/devfs_vfsops.c6
-rw-r--r--sys/fs/devfs/devfs_vnops.c30
3 files changed, 28 insertions, 24 deletions
diff --git a/sys/fs/devfs/devfs_devs.c b/sys/fs/devfs/devfs_devs.c
index 49854a0..1d5d32b 100644
--- a/sys/fs/devfs/devfs_devs.c
+++ b/sys/fs/devfs/devfs_devs.c
@@ -153,10 +153,10 @@ devfs_attemptoverflow(int insist)
bzero(ot, nb);
nb = sizeof (int) * n;
MALLOC(or, int *, nb, M_DEVFS, insist ? M_WAITOK : M_NOWAIT);
- if (or == NULL)
+ if (or == NULL)
goto bail;
bzero(or, nb);
- if (!atomic_cmpset_ptr(&devfs_overflow, NULL, ot))
+ if (!atomic_cmpset_ptr(&devfs_overflow, NULL, ot))
goto bail;
devfs_refoverflow = or;
devfs_noverflow = n;
@@ -249,10 +249,8 @@ devfs_delete(struct devfs_dirent *dd, struct devfs_dirent *de)
FREE(de->de_symlink, M_DEVFS);
de->de_symlink = NULL;
}
- if (de->de_vnode) {
+ if (de->de_vnode)
de->de_vnode->v_data = NULL;
- vdrop(de->de_vnode);
- }
TAILQ_REMOVE(&dd->de_dlist, de, de_list);
FREE(de, M_DEVFS);
}
@@ -281,7 +279,7 @@ devfs_populate(struct devfs_mount *dm)
struct devfs_dirent *de, **dep;
char *q, *s;
- if (dm->dm_generation == devfs_generation)
+ if (dm->dm_generation == devfs_generation)
return (0);
lockmgr(&dm->dm_lock, LK_UPGRADE, 0, curproc);
if (devfs_noverflow && dm->dm_overflow == NULL) {
@@ -304,10 +302,8 @@ devfs_populate(struct devfs_mount *dm)
dd = de->de_dir;
*dep = NULL;
TAILQ_REMOVE(&dd->de_dlist, de, de_list);
- if (de->de_vnode) {
+ if (de->de_vnode)
de->de_vnode->v_data = NULL;
- vdrop(de->de_vnode);
- }
FREE(de, M_DEVFS);
devfs_dropref(i);
continue;
@@ -323,7 +319,7 @@ devfs_populate(struct devfs_mount *dm)
for (;;) {
for (q = s; *q != '/' && *q != '\0'; q++)
continue;
- if (*q != '/')
+ if (*q != '/')
break;
de = devfs_find(dd, s, q - s);
if (de == NULL) {
diff --git a/sys/fs/devfs/devfs_vfsops.c b/sys/fs/devfs/devfs_vfsops.c
index 00951ae..0c5d1bb 100644
--- a/sys/fs/devfs/devfs_vfsops.c
+++ b/sys/fs/devfs/devfs_vfsops.c
@@ -133,12 +133,14 @@ devfs_unmount(mp, mntflags, p)
fmp = VFSTODEVFS(mp);
if (mntflags & MNT_FORCE)
flags |= FORCECLOSE;
- if (rootvp->v_usecount > 1)
+ if (rootvp->v_usecount > 2) {
+ vrele(rootvp);
return (EBUSY);
- devfs_purge(fmp->dm_rootdir);
+ }
error = vflush(mp, rootvp, flags);
if (error)
return (error);
+ devfs_purge(fmp->dm_rootdir);
vput(rootvp);
vrele(rootvp);
vgone(rootvp);
diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c
index cb8caff..e3c717e 100644
--- a/sys/fs/devfs/devfs_vnops.c
+++ b/sys/fs/devfs/devfs_vnops.c
@@ -106,7 +106,6 @@ loop:
}
vp->v_data = de;
de->de_vnode = vp;
- vhold(vp);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
*vpp = vp;
return (0);
@@ -148,7 +147,7 @@ devfs_getattr(ap)
dev_t dev;
de = vp->v_data;
- if (vp->v_type == VDIR)
+ if (vp->v_type == VDIR)
de = de->de_dir;
bzero((caddr_t) vap, sizeof(*vap));
vattr_null(vap);
@@ -245,7 +244,7 @@ devfs_lookupx(ap)
vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, p);
return (error);
}
- if ((flags & LOCKPARENT) && (flags & ISLASTCN))
+ if ((flags & LOCKPARENT) && (flags & ISLASTCN))
error = vn_lock(dvp, LK_EXCLUSIVE, p);
if (error)
vput(*vpp);
@@ -296,13 +295,13 @@ devfs_lookupx(ap)
printf("Finished specname: %d \"%s\"\n", i, specname + i);
#endif
cdev = NODEV;
- EVENTHANDLER_INVOKE(dev_clone, specname + i,
+ EVENTHANDLER_INVOKE(dev_clone, specname + i,
strlen(specname + i), &cdev);
#if 0
printf("cloned %s -> %p %s\n", specname + i, cdev,
cdev == NODEV ? "NODEV" : cdev->si_name);
#endif
- if (cdev == NODEV)
+ if (cdev == NODEV)
goto notfound;
devfs_populate(dmp);
@@ -431,7 +430,7 @@ devfs_readdir(ap)
dd = TAILQ_FIRST(&de->de_dlist);
off = 0;
while (dd != NULL) {
- if (dd->de_dirent->d_type == DT_DIR)
+ if (dd->de_dirent->d_type == DT_DIR)
de = dd->de_dir;
else
de = dd;
@@ -476,14 +475,24 @@ devfs_reclaim(ap)
{
struct vnode *vp = ap->a_vp;
struct devfs_dirent *de;
+ int i;
de = vp->v_data;
+ if (de != NULL)
+ de->de_vnode = NULL;
if (de != NULL && de->de_flags & DE_ORPHAN) {
- if (de->de_symlink)
+ if (de->de_symlink)
FREE(de->de_symlink, M_DEVFS);
- FREE(de, M_DEVFS);
+ FREE(de, M_DEVFS);
}
vp->v_data = NULL;
+ if (vp->v_rdev != NODEV && vp->v_rdev != NULL) {
+ i = vcount(vp);
+ if ((vp->v_rdev->si_flags & SI_CHEAPCLONE) && i == 0) {
+ destroy_dev(vp->v_rdev);
+ printf("Reclaim <%s> %d %d Killed\n", vp->v_rdev->si_name, vp->v_rdev->si_flags, i);
+ }
+ }
return (0);
}
@@ -508,7 +517,6 @@ devfs_remove(ap)
if (dep != NULL)
*dep = DE_DELETED;
de->de_flags |= DE_ORPHAN;
- vdrop(de->de_vnode);
lockmgr(&dmp->dm_lock, LK_RELEASE, 0, curproc);
return (0);
}
@@ -529,8 +537,6 @@ devfs_revoke(ap)
struct devfs_dirent *de;
de = vp->v_data;
- if (!(de->de_flags & DE_ORPHAN))
- vdrop(de->de_vnode);
de->de_vnode = NULL;
vop_revoke(ap);
return (0);
@@ -565,7 +571,7 @@ devfs_setattr(ap)
}
de = ap->a_vp->v_data;
- if (ap->a_vp->v_type == VDIR)
+ if (ap->a_vp->v_type == VDIR)
de = de->de_dir;
error = c = 0;
OpenPOWER on IntegriCloud