Module Name: src
Committed By: tls
Date: Sun Aug 10 06:56:06 UTC 2014
Modified Files:
src/sys/miscfs/deadfs [tls-earlyentropy]: dead_vnops.c
src/sys/miscfs/fdesc [tls-earlyentropy]: fdesc.h fdesc_vfsops.c
fdesc_vnops.c
src/sys/miscfs/fifofs [tls-earlyentropy]: fifo_vnops.c
src/sys/miscfs/genfs [tls-earlyentropy]: layer.h layer_extern.h
layer_subr.c layer_vfsops.c layer_vnops.c
src/sys/miscfs/kernfs [tls-earlyentropy]: files.kernfs kernfs.h
kernfs_vfsops.c kernfs_vnops.c
src/sys/miscfs/nullfs [tls-earlyentropy]: null_vfsops.c
src/sys/miscfs/overlay [tls-earlyentropy]: overlay_vfsops.c
src/sys/miscfs/procfs [tls-earlyentropy]: procfs.h procfs_linux.c
procfs_subr.c procfs_vfsops.c procfs_vnops.c
src/sys/miscfs/specfs [tls-earlyentropy]: spec_vnops.c specdev.h
src/sys/miscfs/umapfs [tls-earlyentropy]: umap_vfsops.c
Removed Files:
src/sys/miscfs/kernfs [tls-earlyentropy]: kernfs_subr.c
Log Message:
Rebase.
To generate a diff of this commit:
cvs rdiff -u -r1.56 -r1.56.2.1 src/sys/miscfs/deadfs/dead_vnops.c
cvs rdiff -u -r1.21 -r1.21.26.1 src/sys/miscfs/fdesc/fdesc.h
cvs rdiff -u -r1.88 -r1.88.2.1 src/sys/miscfs/fdesc/fdesc_vfsops.c
cvs rdiff -u -r1.119 -r1.119.2.1 src/sys/miscfs/fdesc/fdesc_vnops.c
cvs rdiff -u -r1.74 -r1.74.2.1 src/sys/miscfs/fifofs/fifo_vnops.c
cvs rdiff -u -r1.14 -r1.14.32.1 src/sys/miscfs/genfs/layer.h
cvs rdiff -u -r1.35 -r1.35.2.1 src/sys/miscfs/genfs/layer_extern.h \
src/sys/miscfs/genfs/layer_subr.c
cvs rdiff -u -r1.43 -r1.43.2.1 src/sys/miscfs/genfs/layer_vfsops.c
cvs rdiff -u -r1.57 -r1.57.2.1 src/sys/miscfs/genfs/layer_vnops.c
cvs rdiff -u -r1.4 -r1.4.34.1 src/sys/miscfs/kernfs/files.kernfs
cvs rdiff -u -r1.37 -r1.37.12.1 src/sys/miscfs/kernfs/kernfs.h
cvs rdiff -u -r1.26 -r0 src/sys/miscfs/kernfs/kernfs_subr.c
cvs rdiff -u -r1.93 -r1.93.2.1 src/sys/miscfs/kernfs/kernfs_vfsops.c
cvs rdiff -u -r1.150 -r1.150.2.1 src/sys/miscfs/kernfs/kernfs_vnops.c
cvs rdiff -u -r1.87 -r1.87.2.1 src/sys/miscfs/nullfs/null_vfsops.c
cvs rdiff -u -r1.60 -r1.60.2.1 src/sys/miscfs/overlay/overlay_vfsops.c
cvs rdiff -u -r1.69 -r1.69.2.1 src/sys/miscfs/procfs/procfs.h
cvs rdiff -u -r1.67 -r1.67.2.1 src/sys/miscfs/procfs/procfs_linux.c
cvs rdiff -u -r1.104 -r1.104.2.1 src/sys/miscfs/procfs/procfs_subr.c
cvs rdiff -u -r1.90 -r1.90.2.1 src/sys/miscfs/procfs/procfs_vfsops.c
cvs rdiff -u -r1.189 -r1.189.2.1 src/sys/miscfs/procfs/procfs_vnops.c
cvs rdiff -u -r1.143 -r1.143.2.1 src/sys/miscfs/specfs/spec_vnops.c
cvs rdiff -u -r1.42 -r1.42.2.1 src/sys/miscfs/specfs/specdev.h
cvs rdiff -u -r1.91 -r1.91.2.1 src/sys/miscfs/umapfs/umap_vfsops.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/miscfs/deadfs/dead_vnops.c
diff -u src/sys/miscfs/deadfs/dead_vnops.c:1.56 src/sys/miscfs/deadfs/dead_vnops.c:1.56.2.1
--- src/sys/miscfs/deadfs/dead_vnops.c:1.56 Thu Feb 27 16:51:38 2014
+++ src/sys/miscfs/deadfs/dead_vnops.c Sun Aug 10 06:56:05 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: dead_vnops.c,v 1.56 2014/02/27 16:51:38 hannken Exp $ */
+/* $NetBSD: dead_vnops.c,v 1.56.2.1 2014/08/10 06:56:05 tls Exp $ */
/*
* Copyright (c) 1989, 1993
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: dead_vnops.c,v 1.56 2014/02/27 16:51:38 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: dead_vnops.c,v 1.56.2.1 2014/08/10 06:56:05 tls Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -87,6 +87,8 @@ const struct vnodeopv_entry_desc dead_vn
{ &vop_close_desc, dead_close }, /* close */
{ &vop_read_desc, dead_read }, /* read */
{ &vop_write_desc, dead_write }, /* write */
+ { &vop_fallocate_desc, genfs_eopnotsupp }, /* fallocate */
+ { &vop_fdiscard_desc, genfs_eopnotsupp }, /* fdiscard */
{ &vop_fcntl_desc, dead_fcntl }, /* fcntl */
{ &vop_ioctl_desc, dead_ioctl }, /* ioctl */
{ &vop_poll_desc, dead_poll }, /* poll */
Index: src/sys/miscfs/fdesc/fdesc.h
diff -u src/sys/miscfs/fdesc/fdesc.h:1.21 src/sys/miscfs/fdesc/fdesc.h:1.21.26.1
--- src/sys/miscfs/fdesc/fdesc.h:1.21 Tue Sep 27 01:22:12 2011
+++ src/sys/miscfs/fdesc/fdesc.h Sun Aug 10 06:56:05 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: fdesc.h,v 1.21 2011/09/27 01:22:12 christos Exp $ */
+/* $NetBSD: fdesc.h,v 1.21.26.1 2014/08/10 06:56:05 tls Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -56,11 +56,10 @@ typedef enum {
} fdntype;
struct fdescnode {
- LIST_ENTRY(fdescnode) fd_hash; /* Hash list */
struct vnode *fd_vnode; /* Back ptr to vnode */
fdntype fd_type; /* Type of this node */
unsigned fd_fd; /* Fd to be dup'ed */
- char *fd_link; /* Link to fd/n */
+ const char *fd_link; /* Link to fd/n */
int fd_ix; /* filesystem index */
};
Index: src/sys/miscfs/fdesc/fdesc_vfsops.c
diff -u src/sys/miscfs/fdesc/fdesc_vfsops.c:1.88 src/sys/miscfs/fdesc/fdesc_vfsops.c:1.88.2.1
--- src/sys/miscfs/fdesc/fdesc_vfsops.c:1.88 Sun Mar 23 15:21:16 2014
+++ src/sys/miscfs/fdesc/fdesc_vfsops.c Sun Aug 10 06:56:05 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: fdesc_vfsops.c,v 1.88 2014/03/23 15:21:16 hannken Exp $ */
+/* $NetBSD: fdesc_vfsops.c,v 1.88.2.1 2014/08/10 06:56:05 tls Exp $ */
/*
* Copyright (c) 1992, 1993, 1995
@@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fdesc_vfsops.c,v 1.88 2014/03/23 15:21:16 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fdesc_vfsops.c,v 1.88.2.1 2014/08/10 06:56:05 tls Exp $");
#if defined(_KERNEL_OPT)
#include "opt_compat_netbsd.h"
@@ -78,7 +78,7 @@ int
fdesc_mount(struct mount *mp, const char *path, void *data, size_t *data_len)
{
struct lwp *l = curlwp;
- int error = 0;
+ int error = 0, ix;
struct vnode *rvp;
if (mp->mnt_flag & MNT_GETARGS) {
@@ -91,12 +91,11 @@ fdesc_mount(struct mount *mp, const char
if (mp->mnt_flag & MNT_UPDATE)
return (EOPNOTSUPP);
- error = fdesc_allocvp(Froot, FD_ROOT, mp, &rvp);
+ ix = FD_ROOT;
+ error = vcache_get(mp, &ix, sizeof(ix), &rvp);
if (error)
- return (error);
+ return error;
- rvp->v_type = VDIR;
- rvp->v_vflag |= VV_ROOT;
mp->mnt_stat.f_namemax = FDESC_MAXNAMLEN;
mp->mnt_flag |= MNT_LOCAL;
mp->mnt_data = rvp;
@@ -104,7 +103,6 @@ fdesc_mount(struct mount *mp, const char
error = set_statvfs_info(path, UIO_USERSPACE, "fdesc", UIO_SYSSPACE,
mp->mnt_op->vfs_name, mp, l);
- VOP_UNLOCK(rvp);
return error;
}
@@ -174,6 +172,66 @@ fdesc_vget(struct mount *mp, ino_t ino,
return (EOPNOTSUPP);
}
+int
+fdesc_loadvnode(struct mount *mp, struct vnode *vp,
+ const void *key, size_t key_len, const void **new_key)
+{
+ int ix;
+ struct fdescnode *fd;
+
+ KASSERT(key_len == sizeof(ix));
+ memcpy(&ix, key, key_len);
+
+ fd = kmem_alloc(sizeof(struct fdescnode), KM_SLEEP);
+ fd->fd_fd = -1;
+ fd->fd_link = NULL;
+ fd->fd_ix = ix;
+ fd->fd_vnode = vp;
+ vp->v_tag = VT_FDESC;
+ vp->v_op = fdesc_vnodeop_p;
+ vp->v_data = fd;
+ switch (ix) {
+ case FD_ROOT:
+ fd->fd_type = Froot;
+ vp->v_type = VDIR;
+ vp->v_vflag |= VV_ROOT;
+ break;
+ case FD_DEVFD:
+ fd->fd_type = Fdevfd;
+ vp->v_type = VDIR;
+ break;
+ case FD_CTTY:
+ fd->fd_type = Fctty;
+ vp->v_type = VNON;
+ break;
+ case FD_STDIN:
+ fd->fd_type = Flink;
+ fd->fd_link = "fd/0";
+ vp->v_type = VLNK;
+ break;
+ case FD_STDOUT:
+ fd->fd_type = Flink;
+ fd->fd_link = "fd/1";
+ vp->v_type = VLNK;
+ break;
+ case FD_STDERR:
+ fd->fd_type = Flink;
+ fd->fd_link = "fd/2";
+ vp->v_type = VLNK;
+ break;
+ default:
+ KASSERT(ix >= FD_DESC);
+ fd->fd_type = Fdesc;
+ fd->fd_fd = ix - FD_DESC;
+ vp->v_type = VNON;
+ break;
+ }
+ uvm_vnp_setsize(vp, 0);
+ *new_key = &fd->fd_ix;
+
+ return 0;
+}
+
extern const struct vnodeopv_desc fdesc_vnodeop_opv_desc;
const struct vnodeopv_desc * const fdesc_vnodeopv_descs[] = {
@@ -192,6 +250,7 @@ struct vfsops fdesc_vfsops = {
.vfs_statvfs = genfs_statvfs,
.vfs_sync = fdesc_sync,
.vfs_vget = fdesc_vget,
+ .vfs_loadvnode = fdesc_loadvnode,
.vfs_fhtovp = (void *)eopnotsupp,
.vfs_vptofh = (void *)eopnotsupp,
.vfs_init = fdesc_init,
Index: src/sys/miscfs/fdesc/fdesc_vnops.c
diff -u src/sys/miscfs/fdesc/fdesc_vnops.c:1.119 src/sys/miscfs/fdesc/fdesc_vnops.c:1.119.2.1
--- src/sys/miscfs/fdesc/fdesc_vnops.c:1.119 Thu Mar 20 18:04:05 2014
+++ src/sys/miscfs/fdesc/fdesc_vnops.c Sun Aug 10 06:56:05 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: fdesc_vnops.c,v 1.119 2014/03/20 18:04:05 christos Exp $ */
+/* $NetBSD: fdesc_vnops.c,v 1.119.2.1 2014/08/10 06:56:05 tls Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fdesc_vnops.c,v 1.119 2014/03/20 18:04:05 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fdesc_vnops.c,v 1.119.2.1 2014/08/10 06:56:05 tls Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -69,21 +69,12 @@ __KERNEL_RCSID(0, "$NetBSD: fdesc_vnops.
#define cttyvp(p) ((p)->p_lflag & PL_CONTROLT ? (p)->p_session->s_ttyvp : NULL)
-static kmutex_t fdcache_lock;
-
dev_t devctty;
#if (FD_STDIN != FD_STDOUT-1) || (FD_STDOUT != FD_STDERR-1)
FD_STDIN, FD_STDOUT, FD_STDERR must be a sequence n, n+1, n+2
#endif
-#define NFDCACHE 4
-
-#define FD_NHASH(ix) \
- (&fdhashtbl[(ix) & fdhash])
-LIST_HEAD(fdhashhead, fdescnode) *fdhashtbl;
-u_long fdhash;
-
int fdesc_lookup(void *);
#define fdesc_create genfs_eopnotsupp
#define fdesc_mknod genfs_eopnotsupp
@@ -139,6 +130,8 @@ const struct vnodeopv_entry_desc fdesc_v
{ &vop_setattr_desc, fdesc_setattr }, /* setattr */
{ &vop_read_desc, fdesc_read }, /* read */
{ &vop_write_desc, fdesc_write }, /* write */
+ { &vop_fallocate_desc, genfs_eopnotsupp }, /* fallocate */
+ { &vop_fdiscard_desc, genfs_eopnotsupp }, /* fdiscard */
{ &vop_ioctl_desc, fdesc_ioctl }, /* ioctl */
{ &vop_fcntl_desc, fdesc_fcntl }, /* fcntl */
{ &vop_poll_desc, fdesc_poll }, /* poll */
@@ -185,76 +178,11 @@ fdesc_init(void)
/* locate the major number */
cttymajor = devsw_name2chr("ctty", NULL, 0);
devctty = makedev(cttymajor, 0);
- mutex_init(&fdcache_lock, MUTEX_DEFAULT, IPL_NONE);
- fdhashtbl = hashinit(NFDCACHE, HASH_LIST, true, &fdhash);
}
-/*
- * Free hash table.
- */
void
fdesc_done(void)
{
- hashdone(fdhashtbl, HASH_LIST, fdhash);
- mutex_destroy(&fdcache_lock);
-}
-
-/*
- * Return a locked vnode of the correct type.
- */
-int
-fdesc_allocvp(fdntype ftype, int ix, struct mount *mp, struct vnode **vpp)
-{
- struct fdhashhead *fc;
- struct fdescnode *fd;
- int error = 0;
-
- fc = FD_NHASH(ix);
-loop:
- mutex_enter(&fdcache_lock);
- LIST_FOREACH(fd, fc, fd_hash) {
- if (fd->fd_ix == ix && fd->fd_vnode->v_mount == mp) {
- mutex_enter(fd->fd_vnode->v_interlock);
- mutex_exit(&fdcache_lock);
- if (vget(fd->fd_vnode, LK_EXCLUSIVE))
- goto loop;
- *vpp = fd->fd_vnode;
- return 0;
- }
- }
- mutex_exit(&fdcache_lock);
-
- error = getnewvnode(VT_FDESC, mp, fdesc_vnodeop_p, NULL, vpp);
- if (error)
- return error;
-
- mutex_enter(&fdcache_lock);
- LIST_FOREACH(fd, fc, fd_hash) {
- if (fd->fd_ix == ix && fd->fd_vnode->v_mount == mp) {
- /*
- * Another thread beat us, push back freshly
- * allocated vnode and retry.
- */
- mutex_exit(&fdcache_lock);
- ungetnewvnode(*vpp);
- goto loop;
- }
- }
-
- fd = malloc(sizeof(struct fdescnode), M_TEMP, M_WAITOK);
- (*vpp)->v_data = fd;
- fd->fd_vnode = *vpp;
- fd->fd_type = ftype;
- fd->fd_fd = -1;
- fd->fd_link = 0;
- fd->fd_ix = ix;
- uvm_vnp_setsize(*vpp, 0);
- error = VOP_LOCK(*vpp, LK_EXCLUSIVE);
- KASSERT(error == 0);
- LIST_INSERT_HEAD(fc, fd, fd_hash);
- mutex_exit(&fdcache_lock);
-
- return 0;
}
/*
@@ -276,9 +204,7 @@ fdesc_lookup(void *v)
const char *pname = cnp->cn_nameptr;
struct proc *p = l->l_proc;
unsigned fd = 0;
- int error;
- struct vnode *fvp;
- const char *ln;
+ int error, ix = -1;
fdtab_t *dt;
dt = curlwp->l_fd->fd_dt;
@@ -299,11 +225,7 @@ fdesc_lookup(void *v)
case Froot:
if (cnp->cn_namelen == 2 && memcmp(pname, "fd", 2) == 0) {
- error = fdesc_allocvp(Fdevfd, FD_DEVFD, dvp->v_mount, &fvp);
- if (error)
- goto bad;
- *vpp = fvp;
- fvp->v_type = VDIR;
+ ix = FD_DEVFD;
goto good;
}
@@ -313,58 +235,35 @@ fdesc_lookup(void *v)
error = ENXIO;
goto bad;
}
- error = fdesc_allocvp(Fctty, FD_CTTY, dvp->v_mount, &fvp);
- if (error)
- goto bad;
- *vpp = fvp;
- fvp->v_type = VCHR;
+ ix = FD_CTTY;
goto good;
}
- ln = 0;
switch (cnp->cn_namelen) {
case 5:
if (memcmp(pname, "stdin", 5) == 0) {
- ln = "fd/0";
- fd = FD_STDIN;
+ ix = FD_STDIN;
+ goto good;
}
break;
case 6:
if (memcmp(pname, "stdout", 6) == 0) {
- ln = "fd/1";
- fd = FD_STDOUT;
- } else
- if (memcmp(pname, "stderr", 6) == 0) {
- ln = "fd/2";
- fd = FD_STDERR;
+ ix = FD_STDOUT;
+ goto good;
+ } else if (memcmp(pname, "stderr", 6) == 0) {
+ ix = FD_STDERR;
+ goto good;
}
break;
}
- if (ln) {
- error = fdesc_allocvp(Flink, fd, dvp->v_mount, &fvp);
- if (error)
- goto bad;
- /* XXXUNCONST */
- VTOFDESC(fvp)->fd_link = __UNCONST(ln);
- *vpp = fvp;
- fvp->v_type = VLNK;
- goto good;
- } else {
- error = ENOENT;
- goto bad;
- }
-
- /* FALL THROUGH */
+ error = ENOENT;
+ goto bad;
case Fdevfd:
if (cnp->cn_namelen == 2 && memcmp(pname, "..", 2) == 0) {
- VOP_UNLOCK(dvp);
- error = fdesc_root(dvp->v_mount, vpp);
- vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
- if (error)
- goto bad;
- return (error);
+ ix = FD_ROOT;
+ goto good;
}
fd = 0;
@@ -385,21 +284,18 @@ fdesc_lookup(void *v)
goto bad;
}
- error = fdesc_allocvp(Fdesc, FD_DESC+fd, dvp->v_mount, &fvp);
- if (error)
- goto bad;
- VTOFDESC(fvp)->fd_fd = fd;
- *vpp = fvp;
+ ix = FD_DESC + fd;
goto good;
}
bad:
*vpp = NULL;
- return (error);
+ return error;
good:
- VOP_UNLOCK(*vpp);
- return (0);
+ KASSERT(ix != -1);
+ error = vcache_get(dvp->v_mount, &ix, sizeof(ix), vpp);
+ return error;
}
int
@@ -793,8 +689,8 @@ fdesc_readlink(void *v)
return (EPERM);
if (VTOFDESC(vp)->fd_type == Flink) {
- char *ln = VTOFDESC(vp)->fd_link;
- error = uiomove(ln, strlen(ln), ap->a_uio);
+ const char *ln = VTOFDESC(vp)->fd_link;
+ error = uiomove(__UNCONST(ln), strlen(ln), ap->a_uio);
} else {
error = EOPNOTSUPP;
}
@@ -942,13 +838,15 @@ fdesc_inactive(void *v)
struct vnode *a_vp;
} */ *ap = v;
struct vnode *vp = ap->a_vp;
+ struct fdescnode *fd = VTOFDESC(vp);
/*
* Clear out the v_type field to avoid
- * nasty things happening in vgone().
+ * nasty things happening on reclaim.
*/
+ if (fd->fd_type == Fctty || fd->fd_type == Fdesc)
+ vp->v_type = VNON;
VOP_UNLOCK(vp);
- vp->v_type = VNON;
return (0);
}
@@ -961,11 +859,9 @@ fdesc_reclaim(void *v)
struct vnode *vp = ap->a_vp;
struct fdescnode *fd = VTOFDESC(vp);
- mutex_enter(&fdcache_lock);
- LIST_REMOVE(fd, fd_hash);
- free(vp->v_data, M_TEMP);
- vp->v_data = 0;
- mutex_exit(&fdcache_lock);
+ vp->v_data = NULL;
+ vcache_remove(vp->v_mount, &fd->fd_ix, sizeof(fd->fd_ix));
+ kmem_free(fd, sizeof(struct fdescnode));
return (0);
}
Index: src/sys/miscfs/fifofs/fifo_vnops.c
diff -u src/sys/miscfs/fifofs/fifo_vnops.c:1.74 src/sys/miscfs/fifofs/fifo_vnops.c:1.74.2.1
--- src/sys/miscfs/fifofs/fifo_vnops.c:1.74 Fri Feb 7 15:29:22 2014
+++ src/sys/miscfs/fifofs/fifo_vnops.c Sun Aug 10 06:56:05 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: fifo_vnops.c,v 1.74 2014/02/07 15:29:22 hannken Exp $ */
+/* $NetBSD: fifo_vnops.c,v 1.74.2.1 2014/08/10 06:56:05 tls Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -58,7 +58,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fifo_vnops.c,v 1.74 2014/02/07 15:29:22 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fifo_vnops.c,v 1.74.2.1 2014/08/10 06:56:05 tls Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -116,7 +116,6 @@ fifo_lookup(void *v)
* Open called to set up a new instance of a fifo or
* to find an active instance of a fifo.
*/
-/* ARGSUSED */
static int
fifo_open(void *v)
{
@@ -132,14 +131,13 @@ fifo_open(void *v)
int error;
vp = ap->a_vp;
+ KASSERT(VOP_ISLOCKED(vp));
if ((fip = vp->v_fifoinfo) == NULL) {
fip = kmem_alloc(sizeof(*fip), KM_SLEEP);
- vp->v_fifoinfo = fip;
error = socreate(AF_LOCAL, &rso, SOCK_STREAM, 0, l, NULL);
if (error != 0) {
kmem_free(fip, sizeof(*fip));
- vp->v_fifoinfo = NULL;
return (error);
}
fip->fi_readsock = rso;
@@ -147,17 +145,15 @@ fifo_open(void *v)
if (error != 0) {
(void)soclose(rso);
kmem_free(fip, sizeof(*fip));
- vp->v_fifoinfo = NULL;
return (error);
}
fip->fi_writesock = wso;
solock(wso);
- if ((error = unp_connect2(wso, rso, PRU_CONNECT2)) != 0) {
+ if ((error = unp_connect2(wso, rso)) != 0) {
sounlock(wso);
(void)soclose(wso);
(void)soclose(rso);
kmem_free(fip, sizeof(*fip));
- vp->v_fifoinfo = NULL;
return (error);
}
fip->fi_readers = 0;
@@ -166,6 +162,7 @@ fifo_open(void *v)
rso->so_state |= SS_CANTSENDMORE;
cv_init(&fip->fi_rcv, "fiford");
cv_init(&fip->fi_wcv, "fifowr");
+ vp->v_fifoinfo = fip;
} else {
wso = fip->fi_writesock;
rso = fip->fi_readsock;
@@ -636,6 +633,8 @@ const struct vnodeopv_entry_desc fifo_vn
{ &vop_setattr_desc, genfs_ebadf }, /* setattr */
{ &vop_read_desc, fifo_read }, /* read */
{ &vop_write_desc, fifo_write }, /* write */
+ { &vop_fallocate_desc, genfs_eopnotsupp }, /* fallocate */
+ { &vop_fdiscard_desc, genfs_eopnotsupp }, /* fdiscard */
{ &vop_ioctl_desc, fifo_ioctl }, /* ioctl */
{ &vop_poll_desc, fifo_poll }, /* poll */
{ &vop_kqfilter_desc, fifo_kqfilter }, /* kqfilter */
Index: src/sys/miscfs/genfs/layer.h
diff -u src/sys/miscfs/genfs/layer.h:1.14 src/sys/miscfs/genfs/layer.h:1.14.32.1
--- src/sys/miscfs/genfs/layer.h:1.14 Sun Jun 6 08:01:31 2010
+++ src/sys/miscfs/genfs/layer.h Sun Aug 10 06:56:05 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: layer.h,v 1.14 2010/06/06 08:01:31 hannken Exp $ */
+/* $NetBSD: layer.h,v 1.14.32.1 2014/08/10 06:56:05 tls Exp $ */
/*
* Copyright (c) 1999 National Aeronautics & Space Administration
@@ -78,27 +78,16 @@ struct layer_args {
#ifdef _KERNEL
-struct layer_node;
-
-LIST_HEAD(layer_node_hashhead, layer_node);
-
struct layer_mount {
struct mount *layerm_vfs;
struct vnode *layerm_rootvp; /* Ref to root layer_node */
u_int layerm_flags; /* mount point layer flags */
u_int layerm_size; /* size of fs's struct node */
- enum vtype layerm_tag; /* vtag of our vnodes */
+ enum vtagtype layerm_tag; /* vtag of our vnodes */
int /* bypass routine for this mount */
(*layerm_bypass)(void *);
- int (*layerm_alloc) /* alloc a new layer node */
- (struct mount *, struct vnode *,
- struct vnode **);
int (**layerm_vnodeop_p) /* ops for our nodes */
(void *);
- struct layer_node_hashhead /* head of hash list for layer_nodes */
- *layerm_node_hashtbl;
- u_long layerm_node_hash; /* hash mask for hash chain */
- kmutex_t layerm_hashlock; /* interlock for hash chain. */
};
#define LAYERFS_MFLAGS 0x00000fff /* reserved layer mount flags */
@@ -108,7 +97,6 @@ struct layer_mount {
* A cache of vnode references
*/
struct layer_node {
- LIST_ENTRY(layer_node) layer_hash; /* Hash list */
struct vnode *layer_lowervp; /* VREFed once */
struct vnode *layer_vnode; /* Back pointer */
unsigned int layer_flags; /* locking, etc. */
Index: src/sys/miscfs/genfs/layer_extern.h
diff -u src/sys/miscfs/genfs/layer_extern.h:1.35 src/sys/miscfs/genfs/layer_extern.h:1.35.2.1
--- src/sys/miscfs/genfs/layer_extern.h:1.35 Thu Feb 27 16:51:38 2014
+++ src/sys/miscfs/genfs/layer_extern.h Sun Aug 10 06:56:05 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: layer_extern.h,v 1.35 2014/02/27 16:51:38 hannken Exp $ */
+/* $NetBSD: layer_extern.h,v 1.35.2.1 2014/08/10 06:56:05 tls Exp $ */
/*
* Copyright (c) 1999 National Aeronautics & Space Administration
@@ -76,14 +76,7 @@
/* Routines to manage nodes. */
void layerfs_init(void);
void layerfs_done(void);
-int layer_node_alloc(struct mount *, struct vnode *, struct vnode **);
int layer_node_create(struct mount *, struct vnode *, struct vnode **);
-struct vnode *layer_node_find(struct mount *, struct vnode *);
-
-#define LOG2_SIZEVNODE 7 /* log2(sizeof struct vnode) */
-#define LAYER_NHASH(lmp, vp) \
- (&((lmp)->layerm_node_hashtbl[(((u_long)vp)>>LOG2_SIZEVNODE) & \
- (lmp)->layerm_node_hash]))
/* VFS routines */
int layerfs_start(struct mount *, int);
@@ -91,6 +84,8 @@ int layerfs_root(struct mount *, struct
int layerfs_quotactl(struct mount *, struct quotactl_args *);
int layerfs_statvfs(struct mount *, struct statvfs *);
int layerfs_sync(struct mount *, int, struct kauth_cred *);
+int layerfs_loadvnode(struct mount *, struct vnode *,
+ const void *, size_t, const void **);
int layerfs_vget(struct mount *, ino_t, struct vnode **);
int layerfs_fhtovp(struct mount *, struct fid *, struct vnode **);
int layerfs_vptofh(struct vnode *, struct fid *, size_t *);
Index: src/sys/miscfs/genfs/layer_subr.c
diff -u src/sys/miscfs/genfs/layer_subr.c:1.35 src/sys/miscfs/genfs/layer_subr.c:1.35.2.1
--- src/sys/miscfs/genfs/layer_subr.c:1.35 Mon Feb 10 11:23:14 2014
+++ src/sys/miscfs/genfs/layer_subr.c Sun Aug 10 06:56:05 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: layer_subr.c,v 1.35 2014/02/10 11:23:14 hannken Exp $ */
+/* $NetBSD: layer_subr.c,v 1.35.2.1 2014/08/10 06:56:05 tls Exp $ */
/*
* Copyright (c) 1999 National Aeronautics & Space Administration
@@ -69,7 +69,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: layer_subr.c,v 1.35 2014/02/10 11:23:14 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: layer_subr.c,v 1.35.2.1 2014/08/10 06:56:05 tls Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -81,7 +81,6 @@ __KERNEL_RCSID(0, "$NetBSD: layer_subr.c
#include <sys/kmem.h>
#include <sys/malloc.h>
-#include <miscfs/specfs/specdev.h>
#include <miscfs/genfs/layer.h>
#include <miscfs/genfs/layer_extern.h>
@@ -110,156 +109,18 @@ layerfs_done(void)
}
/*
- * layer_node_find: find and return alias for lower vnode or NULL.
- *
- * => Return alias vnode referenced. if already exists.
- * => The layermp's hashlock must be held on entry, we will unlock on success.
- */
-struct vnode *
-layer_node_find(struct mount *mp, struct vnode *lowervp)
-{
- struct layer_mount *lmp = MOUNTTOLAYERMOUNT(mp);
- struct layer_node_hashhead *hd;
- struct layer_node *a;
- struct vnode *vp;
- int error;
-
- /*
- * Find hash bucket and search the (two-way) linked list looking
- * for a layerfs node structure which is referencing the lower vnode.
- * If found, the increment the layer_node reference count, but NOT
- * the lower vnode's reference counter.
- */
- KASSERT(mutex_owned(&lmp->layerm_hashlock));
- hd = LAYER_NHASH(lmp, lowervp);
-loop:
- LIST_FOREACH(a, hd, layer_hash) {
- if (a->layer_lowervp != lowervp) {
- continue;
- }
- vp = LAYERTOV(a);
- if (vp->v_mount != mp) {
- continue;
- }
- mutex_enter(vp->v_interlock);
- mutex_exit(&lmp->layerm_hashlock);
- error = vget(vp, 0);
- if (error) {
- mutex_enter(&lmp->layerm_hashlock);
- goto loop;
- }
- return vp;
- }
- return NULL;
-}
-
-/*
- * layer_node_alloc: make a new layerfs vnode.
- *
- * => vp is the alias vnode, lowervp is the lower vnode.
- * => We will hold a reference to lowervp.
- */
-int
-layer_node_alloc(struct mount *mp, struct vnode *lowervp, struct vnode **vpp)
-{
- struct layer_mount *lmp = MOUNTTOLAYERMOUNT(mp);
- struct layer_node_hashhead *hd;
- struct layer_node *xp;
- struct vnode *vp, *nvp;
- int error;
-
- /* Get a new vnode and share its interlock with underlying vnode. */
- error = getnewvnode(lmp->layerm_tag, mp, lmp->layerm_vnodeop_p,
- lowervp->v_interlock, &vp);
- if (error) {
- return error;
- }
- vp->v_type = lowervp->v_type;
- mutex_enter(vp->v_interlock);
- vp->v_iflag |= VI_LAYER;
- mutex_exit(vp->v_interlock);
-
- xp = kmem_alloc(lmp->layerm_size, KM_SLEEP);
- if (xp == NULL) {
- ungetnewvnode(vp);
- return ENOMEM;
- }
- if (vp->v_type == VBLK || vp->v_type == VCHR) {
- spec_node_init(vp, lowervp->v_rdev);
- }
-
- /*
- * Before inserting the node into the hash, check if other thread
- * did not race with us. If so - return that node, destroy ours.
- */
- mutex_enter(&lmp->layerm_hashlock);
- if ((nvp = layer_node_find(mp, lowervp)) != NULL) {
- ungetnewvnode(vp);
- kmem_free(xp, lmp->layerm_size);
- *vpp = nvp;
- return 0;
- }
-
- vp->v_data = xp;
- vp->v_vflag = (vp->v_vflag & ~VV_MPSAFE) |
- (lowervp->v_vflag & VV_MPSAFE);
- xp->layer_vnode = vp;
- xp->layer_lowervp = lowervp;
- xp->layer_flags = 0;
-
- /*
- * Insert the new node into the hash.
- * Add a reference to the lower node.
- */
- vref(lowervp);
- hd = LAYER_NHASH(lmp, lowervp);
- LIST_INSERT_HEAD(hd, xp, layer_hash);
- uvm_vnp_setsize(vp, 0);
- mutex_exit(&lmp->layerm_hashlock);
-
- *vpp = vp;
- return 0;
-}
-
-/*
* layer_node_create: try to find an existing layerfs vnode refering to it,
* otherwise make a new vnode which contains a reference to the lower vnode.
- *
- * => Caller should lock the lower node.
*/
int
layer_node_create(struct mount *mp, struct vnode *lowervp, struct vnode **nvpp)
{
+ int error;
struct vnode *aliasvp;
- struct layer_mount *lmp = MOUNTTOLAYERMOUNT(mp);
- mutex_enter(&lmp->layerm_hashlock);
- aliasvp = layer_node_find(mp, lowervp);
- if (aliasvp != NULL) {
- /*
- * Note: layer_node_find() has taken another reference to
- * the alias vnode and moved the lock holding to aliasvp.
- */
-#ifdef LAYERFS_DIAGNOSTIC
- if (layerfs_debug)
- vprint("layer_node_create: exists", aliasvp);
-#endif
- } else {
- int error;
-
- mutex_exit(&lmp->layerm_hashlock);
- /*
- * Get a new vnode. Make it to reference the layer_node.
- * Note: aliasvp will be return with the reference held.
- */
- error = (lmp->layerm_alloc)(mp, lowervp, &aliasvp);
- if (error)
- return error;
-#ifdef LAYERFS_DIAGNOSTIC
- if (layerfs_debug)
- printf("layer_node_create: create new alias vnode\n");
-#endif
- }
+ error = vcache_get(mp, &lowervp, sizeof(lowervp), &aliasvp);
+ if (error)
+ return error;
/*
* Now that we acquired a reference on the upper vnode, release one
Index: src/sys/miscfs/genfs/layer_vfsops.c
diff -u src/sys/miscfs/genfs/layer_vfsops.c:1.43 src/sys/miscfs/genfs/layer_vfsops.c:1.43.2.1
--- src/sys/miscfs/genfs/layer_vfsops.c:1.43 Tue Feb 25 18:30:11 2014
+++ src/sys/miscfs/genfs/layer_vfsops.c Sun Aug 10 06:56:05 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: layer_vfsops.c,v 1.43 2014/02/25 18:30:11 pooka Exp $ */
+/* $NetBSD: layer_vfsops.c,v 1.43.2.1 2014/08/10 06:56:05 tls Exp $ */
/*
* Copyright (c) 1999 National Aeronautics & Space Administration
@@ -74,7 +74,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: layer_vfsops.c,v 1.43 2014/02/25 18:30:11 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: layer_vfsops.c,v 1.43.2.1 2014/08/10 06:56:05 tls Exp $");
#include <sys/param.h>
#include <sys/sysctl.h>
@@ -86,6 +86,7 @@ __KERNEL_RCSID(0, "$NetBSD: layer_vfsops
#include <sys/kauth.h>
#include <sys/module.h>
+#include <miscfs/specfs/specdev.h>
#include <miscfs/genfs/layer.h>
#include <miscfs/genfs/layer_extern.h>
@@ -204,6 +205,43 @@ layerfs_sync(struct mount *mp, int waitf
}
int
+layerfs_loadvnode(struct mount *mp, struct vnode *vp,
+ const void *key, size_t key_len, const void **new_key)
+{
+ struct layer_mount *lmp = MOUNTTOLAYERMOUNT(mp);
+ struct vnode *lowervp;
+ struct layer_node *xp;
+
+ KASSERT(key_len == sizeof(struct vnode *));
+ memcpy(&lowervp, key, key_len);
+
+ xp = kmem_alloc(lmp->layerm_size, KM_SLEEP);
+ if (xp == NULL)
+ return ENOMEM;
+
+ /* Share the interlock with the lower node. */
+ mutex_obj_hold(lowervp->v_interlock);
+ uvm_obj_setlock(&vp->v_uobj, lowervp->v_interlock);
+ vp->v_iflag |= VI_LAYER | VI_LOCKSHARE;
+
+ vp->v_tag = lmp->layerm_tag;
+ vp->v_type = lowervp->v_type;
+ vp->v_op = lmp->layerm_vnodeop_p;
+ if (vp->v_type == VBLK || vp->v_type == VCHR)
+ spec_node_init(vp, lowervp->v_rdev);
+ vp->v_data = xp;
+ xp->layer_vnode = vp;
+ xp->layer_lowervp = lowervp;
+ xp->layer_flags = 0;
+ uvm_vnp_setsize(vp, 0);
+
+ /* Add a reference to the lower node. */
+ vref(lowervp);
+ *new_key = &xp->layer_lowervp;
+ return 0;
+}
+
+int
layerfs_vget(struct mount *mp, ino_t ino, struct vnode **vpp)
{
struct vnode *vp;
Index: src/sys/miscfs/genfs/layer_vnops.c
diff -u src/sys/miscfs/genfs/layer_vnops.c:1.57 src/sys/miscfs/genfs/layer_vnops.c:1.57.2.1
--- src/sys/miscfs/genfs/layer_vnops.c:1.57 Mon Mar 24 13:42:40 2014
+++ src/sys/miscfs/genfs/layer_vnops.c Sun Aug 10 06:56:05 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: layer_vnops.c,v 1.57 2014/03/24 13:42:40 hannken Exp $ */
+/* $NetBSD: layer_vnops.c,v 1.57.2.1 2014/08/10 06:56:05 tls Exp $ */
/*
* Copyright (c) 1999 National Aeronautics & Space Administration
@@ -170,7 +170,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: layer_vnops.c,v 1.57 2014/03/24 13:42:40 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: layer_vnops.c,v 1.57.2.1 2014/08/10 06:56:05 tls Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -694,11 +694,9 @@ layer_reclaim(void *v)
*/
lmp->layerm_rootvp = NULL;
}
+ vcache_remove(vp->v_mount, &lowervp, sizeof(lowervp));
/* After this assignment, this node will not be re-used. */
xp->layer_lowervp = NULL;
- mutex_enter(&lmp->layerm_hashlock);
- LIST_REMOVE(xp, layer_hash);
- mutex_exit(&lmp->layerm_hashlock);
kmem_free(vp->v_data, lmp->layerm_size);
vp->v_data = NULL;
vrele(lowervp);
Index: src/sys/miscfs/kernfs/files.kernfs
diff -u src/sys/miscfs/kernfs/files.kernfs:1.4 src/sys/miscfs/kernfs/files.kernfs:1.4.34.1
--- src/sys/miscfs/kernfs/files.kernfs:1.4 Wed Mar 3 01:26:01 2010
+++ src/sys/miscfs/kernfs/files.kernfs Sun Aug 10 06:56:05 2014
@@ -1,7 +1,6 @@
-# $NetBSD: files.kernfs,v 1.4 2010/03/03 01:26:01 pooka Exp $
+# $NetBSD: files.kernfs,v 1.4.34.1 2014/08/10 06:56:05 tls Exp $
deffs KERNFS
-file miscfs/kernfs/kernfs_subr.c kernfs
file miscfs/kernfs/kernfs_vfsops.c kernfs
file miscfs/kernfs/kernfs_vnops.c kernfs
Index: src/sys/miscfs/kernfs/kernfs.h
diff -u src/sys/miscfs/kernfs/kernfs.h:1.37 src/sys/miscfs/kernfs/kernfs.h:1.37.12.1
--- src/sys/miscfs/kernfs/kernfs.h:1.37 Thu Mar 22 20:34:38 2012
+++ src/sys/miscfs/kernfs/kernfs.h Sun Aug 10 06:56:05 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: kernfs.h,v 1.37 2012/03/22 20:34:38 drochner Exp $ */
+/* $NetBSD: kernfs.h,v 1.37.12.1 2014/08/10 06:56:05 tls Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -39,6 +39,7 @@
#ifdef _KERNEL
#include <sys/queue.h>
#include <sys/tree.h>
+#include <sys/mutex.h>
/*
* The different types of node in a kernfs filesystem
@@ -91,9 +92,8 @@ struct kernfs_node {
kfstype kfs_type; /* type of kernfs node */
mode_t kfs_mode; /* mode bits for stat() */
long kfs_fileno; /* unique file id */
- u_int32_t kfs_value; /* SA id or SP id (KFSint) */
const struct kern_target *kfs_kt;
- void *kfs_v; /* pointer to secasvar/secpolicy/mbuf */
+ void *kfs_v; /* dynamic node private data */
long kfs_cookie; /* fileno cookie */
};
@@ -123,22 +123,10 @@ extern const int static_nkern_targets;
extern int (**kernfs_vnodeop_p)(void *);
extern struct vfsops kernfs_vfsops;
extern dev_t rrootdev;
-
-struct secasvar;
-struct secpolicy;
+extern kmutex_t kfs_lock;
int kernfs_root(struct mount *, struct vnode **);
-void kernfs_hashinit(void);
-void kernfs_hashreinit(void);
-void kernfs_hashdone(void);
-int kernfs_freevp(struct vnode *);
-int kernfs_allocvp(struct mount *, struct vnode **, kfstype,
- const struct kern_target *, u_int32_t);
-
-void kernfs_revoke_sa(struct secasvar *);
-void kernfs_revoke_sp(struct secpolicy *);
-
/*
* Data types for the kernfs file operations.
*/
Index: src/sys/miscfs/kernfs/kernfs_vfsops.c
diff -u src/sys/miscfs/kernfs/kernfs_vfsops.c:1.93 src/sys/miscfs/kernfs/kernfs_vfsops.c:1.93.2.1
--- src/sys/miscfs/kernfs/kernfs_vfsops.c:1.93 Sun Mar 23 15:21:16 2014
+++ src/sys/miscfs/kernfs/kernfs_vfsops.c Sun Aug 10 06:56:05 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: kernfs_vfsops.c,v 1.93 2014/03/23 15:21:16 hannken Exp $ */
+/* $NetBSD: kernfs_vfsops.c,v 1.93.2.1 2014/08/10 06:56:05 tls Exp $ */
/*
* Copyright (c) 1992, 1993, 1995
@@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kernfs_vfsops.c,v 1.93 2014/03/23 15:21:16 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kernfs_vfsops.c,v 1.93.2.1 2014/08/10 06:56:05 tls Exp $");
#ifdef _KERNEL_OPT
#include "opt_compat_netbsd.h"
@@ -68,6 +68,7 @@ MODULE(MODULE_CLASS_VFS, kernfs, NULL);
MALLOC_JUSTDEFINE(M_KERNFSMNT, "kernfs mount", "kernfs mount structures");
dev_t rrootdev = NODEV;
+kmutex_t kfs_lock;
VFS_PROTOS(kernfs);
@@ -80,20 +81,20 @@ kernfs_init(void)
{
malloc_type_attach(M_KERNFSMNT);
- kernfs_hashinit();
+ mutex_init(&kfs_lock, MUTEX_DEFAULT, IPL_NONE);
}
void
kernfs_reinit(void)
{
- kernfs_hashreinit();
+
}
void
kernfs_done(void)
{
- kernfs_hashdone();
+ mutex_destroy(&kfs_lock);
malloc_type_detach(M_KERNFSMNT);
}
@@ -190,9 +191,20 @@ kernfs_unmount(struct mount *mp, int mnt
int
kernfs_root(struct mount *mp, struct vnode **vpp)
{
+ const struct kern_target *root_target = &kern_targets[0];
+ int error;
/* setup "." */
- return (kernfs_allocvp(mp, vpp, KFSkern, &kern_targets[0], 0));
+ error = vcache_get(mp, &root_target, sizeof(root_target), vpp);
+ if (error)
+ return error;
+ error = vn_lock(*vpp, LK_EXCLUSIVE);
+ if (error) {
+ vrele(*vpp);
+ *vpp = NULL;
+ return error;
+ }
+ return 0;
}
/*ARGSUSED*/
@@ -216,6 +228,70 @@ kernfs_vget(struct mount *mp, ino_t ino,
return (EOPNOTSUPP);
}
+int
+kernfs_loadvnode(struct mount *mp, struct vnode *vp,
+ const void *key, size_t key_len, const void **new_key)
+{
+ const struct kern_target *kt;
+ struct kernfs_node *kfs, *kfsp;
+ long *cookie;
+
+ KASSERT(key_len == sizeof(kt));
+ memcpy(&kt, key, key_len);
+
+ kfs = kmem_zalloc(sizeof(struct kernfs_node), KM_SLEEP);
+ cookie = &(VFSTOKERNFS(mp)->fileno_cookie);
+ mutex_enter(&kfs_lock);
+again:
+ TAILQ_FOREACH(kfsp, &VFSTOKERNFS(mp)->nodelist, kfs_list) {
+ if (kfsp->kfs_cookie == *cookie) {
+ (*cookie) ++;
+ goto again;
+ }
+ if (TAILQ_NEXT(kfsp, kfs_list)) {
+ if (kfsp->kfs_cookie < *cookie &&
+ *cookie < TAILQ_NEXT(kfsp, kfs_list)->kfs_cookie)
+ break;
+ if (kfsp->kfs_cookie + 1 <
+ TAILQ_NEXT(kfsp, kfs_list)->kfs_cookie) {
+ *cookie = kfsp->kfs_cookie + 1;
+ break;
+ }
+ }
+ }
+
+ kfs->kfs_cookie = *cookie;
+
+ if (kfsp)
+ TAILQ_INSERT_AFTER(&VFSTOKERNFS(mp)->nodelist, kfsp, kfs,
+ kfs_list);
+ else
+ TAILQ_INSERT_TAIL(&VFSTOKERNFS(mp)->nodelist, kfs, kfs_list);
+
+ kfs->kfs_type = kt->kt_tag;
+ kfs->kfs_vnode = vp;
+ kfs->kfs_fileno = KERNFS_FILENO(kt, kt->kt_tag, kfs->kfs_cookie);
+ kfs->kfs_kt = kt;
+ kfs->kfs_mode = kt->kt_mode;
+ vp->v_tag = VT_KERNFS;
+ vp->v_op = kernfs_vnodeop_p;
+ vp->v_data = kfs;
+ vp->v_type = kt->kt_vtype;
+ mutex_exit(&kfs_lock);
+
+ if (kt->kt_tag == KFSkern)
+ vp->v_vflag = VV_ROOT;
+
+ if (kt->kt_tag == KFSdevice) {
+ spec_node_init(vp, *(dev_t *)kt->kt_data);
+ }
+
+ uvm_vnp_setsize(vp, 0);
+
+ *new_key = &kfs->kfs_kt;
+ return 0;
+}
+
extern const struct vnodeopv_desc kernfs_vnodeop_opv_desc;
const struct vnodeopv_desc * const kernfs_vnodeopv_descs[] = {
@@ -234,6 +310,7 @@ struct vfsops kernfs_vfsops = {
.vfs_statvfs = genfs_statvfs,
.vfs_sync = kernfs_sync,
.vfs_vget = kernfs_vget,
+ .vfs_loadvnode = kernfs_loadvnode,
.vfs_fhtovp = (void *)eopnotsupp,
.vfs_vptofh = (void *)eopnotsupp,
.vfs_init = kernfs_init,
Index: src/sys/miscfs/kernfs/kernfs_vnops.c
diff -u src/sys/miscfs/kernfs/kernfs_vnops.c:1.150 src/sys/miscfs/kernfs/kernfs_vnops.c:1.150.2.1
--- src/sys/miscfs/kernfs/kernfs_vnops.c:1.150 Fri Feb 7 15:29:22 2014
+++ src/sys/miscfs/kernfs/kernfs_vnops.c Sun Aug 10 06:56:05 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: kernfs_vnops.c,v 1.150 2014/02/07 15:29:22 hannken Exp $ */
+/* $NetBSD: kernfs_vnops.c,v 1.150.2.1 2014/08/10 06:56:05 tls Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kernfs_vnops.c,v 1.150 2014/02/07 15:29:22 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kernfs_vnops.c,v 1.150.2.1 2014/08/10 06:56:05 tls Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -59,6 +59,7 @@ __KERNEL_RCSID(0, "$NetBSD: kernfs_vnops
#include <miscfs/genfs/genfs.h>
#include <miscfs/kernfs/kernfs.h>
+#include <miscfs/specfs/specdev.h>
#include <uvm/uvm_extern.h>
@@ -190,6 +191,8 @@ const struct vnodeopv_entry_desc kernfs_
{ &vop_setattr_desc, kernfs_setattr }, /* setattr */
{ &vop_read_desc, kernfs_read }, /* read */
{ &vop_write_desc, kernfs_write }, /* write */
+ { &vop_fallocate_desc, genfs_eopnotsupp }, /* fallocate */
+ { &vop_fdiscard_desc, genfs_eopnotsupp }, /* fdiscard */
{ &vop_fcntl_desc, kernfs_fcntl }, /* fcntl */
{ &vop_ioctl_desc, kernfs_ioctl }, /* ioctl */
{ &vop_poll_desc, kernfs_poll }, /* poll */
@@ -519,11 +522,8 @@ kernfs_lookup(void *v)
break;
found:
- error = kernfs_allocvp(dvp->v_mount, vpp, kt->kt_tag, kt, 0);
- if (error)
- return error;
- VOP_UNLOCK(*vpp);
- return 0;
+ error = vcache_get(dvp->v_mount, &kt, sizeof(kt), vpp);
+ return error;
case KFSsubdir:
ks = (struct kernfs_subdir *)kfs->kfs_kt->kt_data;
@@ -653,6 +653,11 @@ kernfs_getattr(void *v)
vap->va_bytes = vap->va_size = DEV_BSIZE;
break;
+ case KFSdevice:
+ vap->va_nlink = 1;
+ vap->va_rdev = ap->a_vp->v_rdev;
+ break;
+
case KFSroot:
vap->va_nlink = 1;
vap->va_bytes = vap->va_size = DEV_BSIZE;
@@ -670,7 +675,6 @@ kernfs_getattr(void *v)
case KFSstring:
case KFShostname:
case KFSavenrun:
- case KFSdevice:
case KFSmsgbuf:
vap->va_nlink = 1;
total = 0;
@@ -823,28 +827,17 @@ kernfs_ioctl(void *v)
static int
kernfs_setdirentfileno_kt(struct dirent *d, const struct kern_target *kt,
- u_int32_t value, struct vop_readdir_args *ap)
+ struct vop_readdir_args *ap)
{
struct kernfs_node *kfs;
struct vnode *vp;
int error;
- if ((error = kernfs_allocvp(ap->a_vp->v_mount, &vp, kt->kt_tag, kt,
- value)) != 0)
+ if ((error = vcache_get(ap->a_vp->v_mount, &kt, sizeof(kt), &vp)) != 0)
return error;
- if (kt->kt_tag == KFSdevice) {
- struct vattr va;
-
- error = VOP_GETATTR(vp, &va, ap->a_cred);
- if (error != 0) {
- return error;
- }
- d->d_fileno = va.va_fileid;
- } else {
- kfs = VTOKERN(vp);
- d->d_fileno = kfs->kfs_fileno;
- }
- vput(vp);
+ kfs = VTOKERN(vp);
+ d->d_fileno = kfs->kfs_fileno;
+ vrele(vp);
return 0;
}
@@ -868,7 +861,7 @@ kernfs_setdirentfileno(struct dirent *d,
break;
}
if (ikt != thisdir_kfs->kfs_kt) {
- if ((error = kernfs_setdirentfileno_kt(d, ikt, 0, ap)) != 0)
+ if ((error = kernfs_setdirentfileno_kt(d, ikt, ap)) != 0)
return error;
} else
d->d_fileno = thisdir_kfs->kfs_fileno;
@@ -1085,8 +1078,17 @@ kernfs_reclaim(void *v)
struct vop_reclaim_args /* {
struct vnode *a_vp;
} */ *ap = v;
+ struct vnode *vp = ap->a_vp;
+ struct kernfs_node *kfs = VTOKERN(vp);
- return (kernfs_freevp(ap->a_vp));
+ vp->v_data = NULL;
+ vcache_remove(vp->v_mount, &kfs->kfs_kt, sizeof(kfs->kfs_kt));
+ mutex_enter(&kfs_lock);
+ TAILQ_REMOVE(&VFSTOKERNFS(vp->v_mount)->nodelist, kfs, kfs_list);
+ mutex_exit(&kfs_lock);
+ kmem_free(kfs, sizeof(struct kernfs_node));
+
+ return 0;
}
/*
Index: src/sys/miscfs/nullfs/null_vfsops.c
diff -u src/sys/miscfs/nullfs/null_vfsops.c:1.87 src/sys/miscfs/nullfs/null_vfsops.c:1.87.2.1
--- src/sys/miscfs/nullfs/null_vfsops.c:1.87 Sun Mar 23 15:21:16 2014
+++ src/sys/miscfs/nullfs/null_vfsops.c Sun Aug 10 06:56:05 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: null_vfsops.c,v 1.87 2014/03/23 15:21:16 hannken Exp $ */
+/* $NetBSD: null_vfsops.c,v 1.87.2.1 2014/08/10 06:56:05 tls Exp $ */
/*
* Copyright (c) 1999 National Aeronautics & Space Administration
@@ -76,7 +76,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: null_vfsops.c,v 1.87 2014/03/23 15:21:16 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: null_vfsops.c,v 1.87.2.1 2014/08/10 06:56:05 tls Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -107,6 +107,8 @@ nullfs_mount(struct mount *mp, const cha
struct nameidata nd;
int error;
+ if (args == NULL)
+ return EINVAL;
if (*data_len < sizeof(*args))
return EINVAL;
@@ -152,19 +154,13 @@ nullfs_mount(struct mount *mp, const cha
nmp->nullm_size = sizeof(struct null_node);
nmp->nullm_tag = VT_NULL;
nmp->nullm_bypass = layer_bypass;
- nmp->nullm_alloc = layer_node_alloc; /* the default alloc is fine */
nmp->nullm_vnodeop_p = null_vnodeop_p;
- mutex_init(&nmp->nullm_hashlock, MUTEX_DEFAULT, IPL_NONE);
- nmp->nullm_node_hashtbl = hashinit(desiredvnodes, HASH_LIST, true,
- &nmp->nullm_node_hash);
/* Setup a null node for root vnode. */
VOP_UNLOCK(lowerrootvp);
error = layer_node_create(mp, lowerrootvp, &vp);
if (error) {
vrele(lowerrootvp);
- hashdone(nmp->nullm_node_hashtbl, HASH_LIST,
- nmp->nullm_node_hash);
kmem_free(nmp, sizeof(struct null_mount));
return error;
}
@@ -203,8 +199,6 @@ nullfs_unmount(struct mount *mp, int mnt
vgone(null_rootvp);
/* Finally, destroy the mount point structures. */
- hashdone(nmp->nullm_node_hashtbl, HASH_LIST, nmp->nullm_node_hash);
- mutex_destroy(&nmp->nullm_hashlock);
kmem_free(mp->mnt_data, sizeof(struct null_mount));
mp->mnt_data = NULL;
return 0;
@@ -227,6 +221,7 @@ struct vfsops nullfs_vfsops = {
.vfs_quotactl = layerfs_quotactl,
.vfs_statvfs = layerfs_statvfs,
.vfs_sync = layerfs_sync,
+ .vfs_loadvnode = layerfs_loadvnode,
.vfs_vget = layerfs_vget,
.vfs_fhtovp = layerfs_fhtovp,
.vfs_vptofh = layerfs_vptofh,
Index: src/sys/miscfs/overlay/overlay_vfsops.c
diff -u src/sys/miscfs/overlay/overlay_vfsops.c:1.60 src/sys/miscfs/overlay/overlay_vfsops.c:1.60.2.1
--- src/sys/miscfs/overlay/overlay_vfsops.c:1.60 Sun Mar 23 15:21:16 2014
+++ src/sys/miscfs/overlay/overlay_vfsops.c Sun Aug 10 06:56:05 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: overlay_vfsops.c,v 1.60 2014/03/23 15:21:16 hannken Exp $ */
+/* $NetBSD: overlay_vfsops.c,v 1.60.2.1 2014/08/10 06:56:05 tls Exp $ */
/*
* Copyright (c) 1999, 2000 National Aeronautics & Space Administration
@@ -74,7 +74,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: overlay_vfsops.c,v 1.60 2014/03/23 15:21:16 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: overlay_vfsops.c,v 1.60.2.1 2014/08/10 06:56:05 tls Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -114,6 +114,8 @@ ov_mount(struct mount *mp, const char *p
printf("ov_mount(mp = %p)\n", mp);
#endif
+ if (args == NULL)
+ return EINVAL;
if (*data_len < sizeof *args)
return EINVAL;
@@ -161,11 +163,7 @@ ov_mount(struct mount *mp, const char *p
nmp->ovm_size = sizeof (struct overlay_node);
nmp->ovm_tag = VT_OVERLAY;
nmp->ovm_bypass = layer_bypass;
- nmp->ovm_alloc = layer_node_alloc; /* the default alloc is fine */
nmp->ovm_vnodeop_p = overlay_vnodeop_p;
- mutex_init(&nmp->ovm_hashlock, MUTEX_DEFAULT, IPL_NONE);
- nmp->ovm_node_hashtbl = hashinit(NOVERLAYNODECACHE, HASH_LIST, true,
- &nmp->ovm_node_hash);
/*
* Fix up overlay node for root vnode
@@ -177,7 +175,6 @@ ov_mount(struct mount *mp, const char *p
*/
if (error) {
vrele(lowerrootvp);
- hashdone(nmp->ovm_node_hashtbl, HASH_LIST, nmp->ovm_node_hash);
kmem_free(nmp, sizeof(struct overlay_mount));
return error;
}
@@ -234,8 +231,6 @@ ov_unmount(struct mount *mp, int mntflag
* Finally, throw away the overlay_mount structure
*/
omp = mp->mnt_data;
- mutex_destroy(&omp->ovm_hashlock);
- hashdone(omp->ovm_node_hashtbl, HASH_LIST, omp->ovm_node_hash);
kmem_free(omp, sizeof(struct overlay_mount));
mp->mnt_data = NULL;
return 0;
@@ -258,6 +253,7 @@ struct vfsops overlay_vfsops = {
.vfs_quotactl = layerfs_quotactl,
.vfs_statvfs = layerfs_statvfs,
.vfs_sync = layerfs_sync,
+ .vfs_loadvnode = layerfs_loadvnode,
.vfs_vget = layerfs_vget,
.vfs_fhtovp = layerfs_fhtovp,
.vfs_vptofh = layerfs_vptofh,
Index: src/sys/miscfs/procfs/procfs.h
diff -u src/sys/miscfs/procfs/procfs.h:1.69 src/sys/miscfs/procfs/procfs.h:1.69.2.1
--- src/sys/miscfs/procfs/procfs.h:1.69 Sat Apr 5 18:42:32 2014
+++ src/sys/miscfs/procfs/procfs.h Sun Aug 10 06:56:05 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: procfs.h,v 1.69 2014/04/05 18:42:32 christos Exp $ */
+/* $NetBSD: procfs.h,v 1.69.2.1 2014/08/10 06:56:05 tls Exp $ */
/*
* Copyright (c) 1993
@@ -118,12 +118,17 @@ typedef enum {
/*
* control data for the proc file system.
*/
+struct pfskey {
+ pfstype pk_type; /* type of procfs node */
+ pid_t pk_pid; /* associated process */
+ int pk_fd; /* associated fd if not -1 */
+};
struct pfsnode {
- LIST_ENTRY(pfsnode) pfs_hash; /* hash chain */
struct vnode *pfs_vnode; /* vnode associated with this pfsnode */
- pfstype pfs_type; /* type of procfs node */
- pid_t pfs_pid; /* associated process */
- int pfs_fd; /* associated fd if not -1 */
+ struct pfskey pfs_key;
+#define pfs_type pfs_key.pk_type
+#define pfs_pid pfs_key.pk_pid
+#define pfs_fd pfs_key.pk_fd
mode_t pfs_mode; /* mode bits for stat() */
u_long pfs_flags; /* open flags */
u_long pfs_fileno; /* unique file id */
@@ -187,9 +192,7 @@ const vfs_namemap_t *vfs_findname(const
int procfs_proc_lock(int, struct proc **, int);
void procfs_proc_unlock(struct proc *);
-int procfs_freevp(struct vnode *);
-int procfs_allocvp(struct mount *, struct vnode **, pid_t, pfstype, int,
- struct proc *);
+int procfs_allocvp(struct mount *, struct vnode **, pid_t, pfstype, int);
int procfs_donote(struct lwp *, struct proc *, struct pfsnode *,
struct uio *);
int procfs_doregs(struct lwp *, struct lwp *, struct pfsnode *,
@@ -232,9 +235,6 @@ int procfs_doversion(struct lwp *, struc
struct uio *);
void procfs_revoke_vnodes(struct proc *, void *);
-void procfs_hashinit(void);
-void procfs_hashreinit(void);
-void procfs_hashdone(void);
int procfs_getfp(struct pfsnode *, struct proc *, struct file **);
/* functions to check whether or not files should be displayed */
Index: src/sys/miscfs/procfs/procfs_linux.c
diff -u src/sys/miscfs/procfs/procfs_linux.c:1.67 src/sys/miscfs/procfs/procfs_linux.c:1.67.2.1
--- src/sys/miscfs/procfs/procfs_linux.c:1.67 Sat Apr 5 18:42:32 2014
+++ src/sys/miscfs/procfs/procfs_linux.c Sun Aug 10 06:56:05 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: procfs_linux.c,v 1.67 2014/04/05 18:42:32 christos Exp $ */
+/* $NetBSD: procfs_linux.c,v 1.67.2.1 2014/08/10 06:56:05 tls Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: procfs_linux.c,v 1.67 2014/04/05 18:42:32 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: procfs_linux.c,v 1.67.2.1 2014/08/10 06:56:05 tls Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -400,7 +400,7 @@ out:
return error;
}
-#define USEC_2_TICKS(x) ((x) / 10000)
+#define UTIME2TICKS(s,u) (((uint64_t)(s) * 1000000 + (u)) / 10000)
/*
* Linux compatible /proc/<pid>/stat. Only active when the -o linux
@@ -413,12 +413,11 @@ procfs_do_pid_stat(struct lwp *curl, str
char *bf;
struct proc *p = l->l_proc;
int len;
- struct tty *tty = p->p_session->s_ttyp;
- struct rusage *ru = &p->p_stats->p_ru;
struct rusage *cru = &p->p_stats->p_cru;
unsigned long stext = 0, etext = 0, sstack = 0;
struct timeval rt;
struct vmspace *vm;
+ struct kinfo_proc2 ki;
int error = 0;
bf = malloc(LBFSZ, M_TEMP, M_WAITOK);
@@ -432,65 +431,67 @@ procfs_do_pid_stat(struct lwp *curl, str
mutex_enter(proc_lock);
mutex_enter(p->p_lock);
+ fill_kproc2(p, &ki, false);
calcru(p, NULL, NULL, NULL, &rt);
len = snprintf(bf, LBFSZ,
- "%d (%s) %c %d %d %d %lld %d "
+ "%d (%s) %c %d %d %d %u %d "
"%u "
- "%lu %lu %lu %lu %lu %lu %lu %lu "
- "%d %d %d "
- "%lld %lld %lu %lu %" PRIu64 " "
+ "%"PRIu64" %lu %"PRIu64" %lu %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64" "
+ "%d %d %"PRIu64" "
+ "%lld %"PRIu64" %"PRId64" %lu %"PRIu64" "
"%lu %lu %lu "
"%u %u "
"%u %u %u %u "
- "%lu %lu %lu %d %d\n",
+ "%"PRIu64" %"PRIu64" %"PRIu64" %d %"PRIu64"\n",
- p->p_pid,
- p->p_comm,
- "0IR3SZD"[(p->p_stat > 6) ? 0 : (int)p->p_stat],
- (p->p_pptr != NULL) ? p->p_pptr->p_pid : 0,
+ ki.p_pid, /* 1 pid */
+ ki.p_comm, /* 2 tcomm */
+ "0RRSTZXR8"[(ki.p_stat > 8) ? 0 : (int)ki.p_stat], /* 3 state */
+ ki.p_ppid, /* 4 ppid */
+ ki.p__pgid, /* 5 pgrp */
+ ki.p_sid, /* 6 sid */
+ (ki.p_tdev != (uint32_t)NODEV) ? ki.p_tdev : 0, /* 7 tty_nr */
+ ki.p_tpgid, /* 8 tty_pgrp */
- p->p_pgid,
- p->p_session->s_sid,
- (unsigned long long)(tty ? tty->t_dev : 0),
- (tty && tty->t_pgrp) ? tty->t_pgrp->pg_id : 0,
+ ki.p_flag, /* 9 flags */
- p->p_flag,
-
- ru->ru_minflt,
+ ki.p_uru_minflt, /* 10 min_flt */
cru->ru_minflt,
- ru->ru_majflt,
+ ki.p_uru_majflt, /* 12 maj_flt */
cru->ru_majflt,
- (long)USEC_2_TICKS(ru->ru_utime.tv_usec),
- (long)USEC_2_TICKS(ru->ru_stime.tv_usec),
- (long)USEC_2_TICKS(cru->ru_utime.tv_usec),
- (long)USEC_2_TICKS(cru->ru_stime.tv_usec),
-
- l->l_priority, /* XXX: priority */
- p->p_nice - 20,
- 0,
+ UTIME2TICKS(ki.p_uutime_sec, ki.p_uutime_usec), /* 14 utime */
+ UTIME2TICKS(ki.p_ustime_sec, ki.p_ustime_usec), /* 15 stime */
+ UTIME2TICKS(cru->ru_utime.tv_sec, cru->ru_utime.tv_usec), /* 16 cutime */
+ UTIME2TICKS(cru->ru_stime.tv_sec, cru->ru_stime.tv_usec), /* 17 cstime */
+
+ ki.p_priority, /* XXX: 18 priority */
+ ki.p_nice - NZERO, /* 19 nice */
+ ki.p_nlwps, /* 20 num_threads */
(long long)rt.tv_sec,
- (long long)p->p_stats->p_start.tv_sec,
- (unsigned long)(vm->vm_tsize + vm->vm_dsize + vm->vm_ssize), /* size */
- (unsigned long)(vm->vm_rssize), /* resident */
- p->p_rlimit[RLIMIT_RSS].rlim_cur,
-
- stext, /* start code */
- etext, /* end code */
- sstack, /* mm start stack */
- 0, /* XXX: pc */
- 0, /* XXX: sp */
- p->p_sigpend.sp_set.__bits[0], /* XXX: pending */
- 0, /* XXX: held */
- p->p_sigctx.ps_sigignore.__bits[0], /* ignored */
- p->p_sigctx.ps_sigcatch.__bits[0], /* caught */
-
- (unsigned long)(intptr_t)l->l_wchan,
- ru->ru_nvcsw,
- ru->ru_nivcsw,
- p->p_exitsig,
- 0); /* XXX: processor */
+ UTIME2TICKS(ki.p_ustart_sec, ki.p_ustart_usec), /* 22 start_time */
+ ki.p_vm_msize, /* 23 vsize */
+ PGTOKB(ki.p_vm_rssize), /* 24 rss */
+ p->p_rlimit[RLIMIT_RSS].rlim_cur, /* 25 rsslim */
+
+ stext, /* 26 start_code */
+ etext, /* 27 end_code */
+ sstack, /* 28 start_stack */
+
+ 0, /* XXX: 29 esp */
+ 0, /* XXX: 30 eip */
+
+ ki.p_siglist.__bits[0], /* XXX: 31 pending */
+ 0, /* XXX: 32 blocked */
+ ki.p_sigignore.__bits[0], /* 33 sigign */
+ ki.p_sigcatch.__bits[0], /* 34 sigcatch */
+
+ ki.p_wchan, /* 35 wchan */
+ ki.p_uru_nvcsw,
+ ki.p_uru_nivcsw,
+ ki.p_exitsig, /* 38 exit_signal */
+ ki.p_cpuid); /* 39 task_cpu */
mutex_exit(p->p_lock);
mutex_exit(proc_lock);
Index: src/sys/miscfs/procfs/procfs_subr.c
diff -u src/sys/miscfs/procfs/procfs_subr.c:1.104 src/sys/miscfs/procfs/procfs_subr.c:1.104.2.1
--- src/sys/miscfs/procfs/procfs_subr.c:1.104 Fri Feb 7 15:29:22 2014
+++ src/sys/miscfs/procfs/procfs_subr.c Sun Aug 10 06:56:05 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: procfs_subr.c,v 1.104 2014/02/07 15:29:22 hannken Exp $ */
+/* $NetBSD: procfs_subr.c,v 1.104.2.1 2014/08/10 06:56:05 tls Exp $ */
/*-
* Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -102,7 +102,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: procfs_subr.c,v 1.104 2014/02/07 15:29:22 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: procfs_subr.c,v 1.104.2.1 2014/08/10 06:56:05 tls Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -118,224 +118,22 @@ __KERNEL_RCSID(0, "$NetBSD: procfs_subr.
#include <miscfs/procfs/procfs.h>
-void procfs_hashins(struct pfsnode *);
-void procfs_hashrem(struct pfsnode *);
-struct vnode *procfs_hashget(pid_t, pfstype, int, struct mount *);
-
-LIST_HEAD(pfs_hashhead, pfsnode) *pfs_hashtbl;
-u_long pfs_ihash; /* size of hash table - 1 */
-#define PFSPIDHASH(pid) ((pid) & pfs_ihash)
-
-kmutex_t pfs_hashlock;
-kmutex_t pfs_ihash_lock;
-
-#define ISSET(t, f) ((t) & (f))
-
/*
- * allocate a pfsnode/vnode pair. the vnode is
- * referenced, and locked.
- *
- * the pid, pfs_type, and mount point uniquely
- * identify a pfsnode. the mount point is needed
- * because someone might mount this filesystem
- * twice.
- *
- * all pfsnodes are maintained on a singly-linked
- * list. new nodes are only allocated when they cannot
- * be found on this list. entries on the list are
- * removed when the vfs reclaim entry is called.
- *
- * a single lock is kept for the entire list. this is
- * needed because the getnewvnode() function can block
- * waiting for a vnode to become free, in which case there
- * may be more than one process trying to get the same
- * vnode. this lock is only taken if we are going to
- * call getnewvnode, since the kernel itself is single-threaded.
- *
- * if an entry is found on the list, then call vget() to
- * take a reference. this is done because there may be
- * zero references to it and so it needs to removed from
- * the vnode free list.
+ * Allocate a pfsnode/vnode pair. The vnode is referenced.
+ * The pid, type, and file descriptor uniquely identify a pfsnode.
*/
int
procfs_allocvp(struct mount *mp, struct vnode **vpp, pid_t pid,
- pfstype pfs_type, int fd, struct proc *p)
+ pfstype type, int fd)
{
- struct pfsnode *pfs;
- struct vnode *vp;
- int error;
-
- *vpp = procfs_hashget(pid, pfs_type, fd, mp);
- if (*vpp != NULL)
- return (0);
+ struct pfskey key;
- error = getnewvnode(VT_PROCFS, mp, procfs_vnodeop_p, NULL, &vp);
- if (error) {
- *vpp = NULL;
- return (error);
- }
- pfs = malloc(sizeof(struct pfsnode), M_TEMP, M_WAITOK);
+ memset(&key, 0, sizeof(key));
+ key.pk_type = type;
+ key.pk_pid = pid;
+ key.pk_fd = fd;
- mutex_enter(&pfs_hashlock);
- if ((*vpp = procfs_hashget(pid, pfs_type, fd, mp)) != NULL) {
- mutex_exit(&pfs_hashlock);
- ungetnewvnode(vp);
- free(pfs, M_TEMP);
- return 0;
- }
-
- vp->v_data = pfs;
- pfs->pfs_pid = pid;
- pfs->pfs_type = pfs_type;
- pfs->pfs_vnode = vp;
- pfs->pfs_flags = 0;
- pfs->pfs_fileno = PROCFS_FILENO(pid, pfs_type, fd);
- pfs->pfs_fd = fd;
-
- switch (pfs_type) {
- case PFSroot: /* /proc = dr-xr-xr-x */
- vp->v_vflag |= VV_ROOT;
- /*FALLTHROUGH*/
- case PFSproc: /* /proc/N = dr-xr-xr-x */
- pfs->pfs_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
- vp->v_type = VDIR;
- break;
-
- case PFStask: /* /proc/N/task = dr-xr-xr-x */
- if (fd == -1) {
- pfs->pfs_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|
- S_IROTH|S_IXOTH;
- vp->v_type = VDIR;
- break;
- }
- /*FALLTHROUGH*/
- case PFScurproc: /* /proc/curproc = lr-xr-xr-x */
- case PFSself: /* /proc/self = lr-xr-xr-x */
- case PFScwd: /* /proc/N/cwd = lr-xr-xr-x */
- case PFSchroot: /* /proc/N/chroot = lr-xr-xr-x */
- case PFSexe: /* /proc/N/exe = lr-xr-xr-x */
- pfs->pfs_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
- vp->v_type = VLNK;
- break;
-
- case PFSfd:
- if (fd == -1) { /* /proc/N/fd = dr-x------ */
- pfs->pfs_mode = S_IRUSR|S_IXUSR;
- vp->v_type = VDIR;
- } else { /* /proc/N/fd/M = [ps-]rw------- */
- file_t *fp;
- vnode_t *vxp;
-
- if ((fp = fd_getfile2(p, pfs->pfs_fd)) == NULL) {
- error = EBADF;
- goto bad;
- }
-
- pfs->pfs_mode = S_IRUSR|S_IWUSR;
- switch (fp->f_type) {
- case DTYPE_VNODE:
- vxp = fp->f_data;
-
- /*
- * We make symlinks for directories
- * to avoid cycles.
- */
- if (vxp->v_type == VDIR)
- goto symlink;
- vp->v_type = vxp->v_type;
- break;
- case DTYPE_PIPE:
- vp->v_type = VFIFO;
- break;
- case DTYPE_SOCKET:
- vp->v_type = VSOCK;
- break;
- case DTYPE_KQUEUE:
- case DTYPE_MISC:
- case DTYPE_SEM:
- symlink:
- pfs->pfs_mode = S_IRUSR|S_IXUSR|S_IRGRP|
- S_IXGRP|S_IROTH|S_IXOTH;
- vp->v_type = VLNK;
- break;
- default:
- error = EOPNOTSUPP;
- closef(fp);
- goto bad;
- }
- closef(fp);
- }
- break;
-
- case PFSfile: /* /proc/N/file = -rw------- */
- case PFSmem: /* /proc/N/mem = -rw------- */
- case PFSregs: /* /proc/N/regs = -rw------- */
- case PFSfpregs: /* /proc/N/fpregs = -rw------- */
- pfs->pfs_mode = S_IRUSR|S_IWUSR;
- vp->v_type = VREG;
- break;
-
- case PFSctl: /* /proc/N/ctl = --w------ */
- case PFSnote: /* /proc/N/note = --w------ */
- case PFSnotepg: /* /proc/N/notepg = --w------ */
- pfs->pfs_mode = S_IWUSR;
- vp->v_type = VREG;
- break;
-
- case PFSmap: /* /proc/N/map = -r--r--r-- */
- case PFSmaps: /* /proc/N/maps = -r--r--r-- */
- case PFSstatus: /* /proc/N/status = -r--r--r-- */
- case PFSstat: /* /proc/N/stat = -r--r--r-- */
- case PFScmdline: /* /proc/N/cmdline = -r--r--r-- */
- case PFSemul: /* /proc/N/emul = -r--r--r-- */
- case PFSmeminfo: /* /proc/meminfo = -r--r--r-- */
- case PFScpustat: /* /proc/stat = -r--r--r-- */
- case PFSdevices: /* /proc/devices = -r--r--r-- */
- case PFScpuinfo: /* /proc/cpuinfo = -r--r--r-- */
- case PFSuptime: /* /proc/uptime = -r--r--r-- */
- case PFSmounts: /* /proc/mounts = -r--r--r-- */
- case PFSloadavg: /* /proc/loadavg = -r--r--r-- */
- case PFSstatm: /* /proc/N/statm = -r--r--r-- */
- case PFSversion: /* /proc/version = -r--r--r-- */
- pfs->pfs_mode = S_IRUSR|S_IRGRP|S_IROTH;
- vp->v_type = VREG;
- break;
-
-#ifdef __HAVE_PROCFS_MACHDEP
- PROCFS_MACHDEP_NODETYPE_CASES
- procfs_machdep_allocvp(vp);
- break;
-#endif
-
- default:
- panic("procfs_allocvp");
- }
-
- procfs_hashins(pfs);
- uvm_vnp_setsize(vp, 0);
- mutex_exit(&pfs_hashlock);
-
- *vpp = vp;
- return (0);
-
- bad:
- mutex_exit(&pfs_hashlock);
- free(pfs, M_TEMP);
- vp->v_data = NULL;
- ungetnewvnode(vp);
- return (error);
-}
-
-int
-procfs_freevp(struct vnode *vp)
-{
- struct pfsnode *pfs = VTOPFS(vp);
-
- procfs_hashrem(pfs);
-
- free(vp->v_data, M_TEMP);
- vp->v_data = NULL;
- return (0);
+ return vcache_get(mp, &key, sizeof(key), vpp);
}
int
@@ -550,132 +348,34 @@ vfs_findname(const vfs_namemap_t *nm, co
return (0);
}
-/*
- * Initialize pfsnode hash table.
- */
-void
-procfs_hashinit(void)
-{
- mutex_init(&pfs_hashlock, MUTEX_DEFAULT, IPL_NONE);
- mutex_init(&pfs_ihash_lock, MUTEX_DEFAULT, IPL_NONE);
- pfs_hashtbl = hashinit(desiredvnodes / 4, HASH_LIST, true, &pfs_ihash);
-}
-
-void
-procfs_hashreinit(void)
-{
- struct pfsnode *pp;
- struct pfs_hashhead *oldhash, *hash;
- u_long i, oldmask, mask, val;
-
- hash = hashinit(desiredvnodes / 4, HASH_LIST, true, &mask);
-
- mutex_enter(&pfs_ihash_lock);
- oldhash = pfs_hashtbl;
- oldmask = pfs_ihash;
- pfs_hashtbl = hash;
- pfs_ihash = mask;
- for (i = 0; i <= oldmask; i++) {
- while ((pp = LIST_FIRST(&oldhash[i])) != NULL) {
- LIST_REMOVE(pp, pfs_hash);
- val = PFSPIDHASH(pp->pfs_pid);
- LIST_INSERT_HEAD(&hash[val], pp, pfs_hash);
- }
- }
- mutex_exit(&pfs_ihash_lock);
- hashdone(oldhash, HASH_LIST, oldmask);
-}
-
-/*
- * Free pfsnode hash table.
- */
-void
-procfs_hashdone(void)
-{
- hashdone(pfs_hashtbl, HASH_LIST, pfs_ihash);
- mutex_destroy(&pfs_hashlock);
- mutex_destroy(&pfs_ihash_lock);
-}
-
-struct vnode *
-procfs_hashget(pid_t pid, pfstype type, int fd, struct mount *mp)
+static bool
+procfs_revoke_selector(void *arg, struct vnode *vp)
{
- struct pfs_hashhead *ppp;
- struct pfsnode *pp;
- struct vnode *vp;
-
-loop:
- mutex_enter(&pfs_ihash_lock);
- ppp = &pfs_hashtbl[PFSPIDHASH(pid)];
- LIST_FOREACH(pp, ppp, pfs_hash) {
- vp = PFSTOV(pp);
- if (pid == pp->pfs_pid && pp->pfs_type == type &&
- pp->pfs_fd == fd && vp->v_mount == mp) {
- mutex_enter(vp->v_interlock);
- mutex_exit(&pfs_ihash_lock);
- if (vget(vp, 0))
- goto loop;
- return (vp);
- }
- }
- mutex_exit(&pfs_ihash_lock);
- return (NULL);
-}
-
-/*
- * Insert the pfsnode into the hash table and lock it.
- */
-void
-procfs_hashins(struct pfsnode *pp)
-{
- struct pfs_hashhead *ppp;
+ struct proc *p = arg;
+ struct pfsnode *pfs = VTOPFS(vp);
- mutex_enter(&pfs_ihash_lock);
- ppp = &pfs_hashtbl[PFSPIDHASH(pp->pfs_pid)];
- LIST_INSERT_HEAD(ppp, pp, pfs_hash);
- mutex_exit(&pfs_ihash_lock);
-}
-
-/*
- * Remove the pfsnode from the hash table.
- */
-void
-procfs_hashrem(struct pfsnode *pp)
-{
- mutex_enter(&pfs_ihash_lock);
- LIST_REMOVE(pp, pfs_hash);
- mutex_exit(&pfs_ihash_lock);
+ return (pfs != NULL && pfs->pfs_pid == p->p_pid);
}
void
procfs_revoke_vnodes(struct proc *p, void *arg)
{
- struct pfsnode *pfs, *pnext;
struct vnode *vp;
+ struct vnode_iterator *marker;
struct mount *mp = (struct mount *)arg;
- struct pfs_hashhead *ppp;
if (!(p->p_flag & PK_SUGID))
return;
- mutex_enter(&pfs_ihash_lock);
- ppp = &pfs_hashtbl[PFSPIDHASH(p->p_pid)];
- for (pfs = LIST_FIRST(ppp); pfs; pfs = pnext) {
- vp = PFSTOV(pfs);
- pnext = LIST_NEXT(pfs, pfs_hash);
- if (pfs->pfs_pid != p->p_pid || vp->v_mount != mp)
- continue;
- mutex_enter(vp->v_interlock);
- mutex_exit(&pfs_ihash_lock);
- if (vget(vp, 0) != 0) {
- mutex_enter(&pfs_ihash_lock);
- continue;
- }
+ vfs_vnode_iterator_init(mp, &marker);
+
+ while ((vp = vfs_vnode_iterator_next(marker,
+ procfs_revoke_selector, p)) != NULL) {
VOP_REVOKE(vp, REVOKEALL);
vrele(vp);
- mutex_enter(&pfs_ihash_lock);
}
- mutex_exit(&pfs_ihash_lock);
+
+ vfs_vnode_iterator_destroy(marker);
}
int
Index: src/sys/miscfs/procfs/procfs_vfsops.c
diff -u src/sys/miscfs/procfs/procfs_vfsops.c:1.90 src/sys/miscfs/procfs/procfs_vfsops.c:1.90.2.1
--- src/sys/miscfs/procfs/procfs_vfsops.c:1.90 Sun Mar 23 15:21:16 2014
+++ src/sys/miscfs/procfs/procfs_vfsops.c Sun Aug 10 06:56:05 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: procfs_vfsops.c,v 1.90 2014/03/23 15:21:16 hannken Exp $ */
+/* $NetBSD: procfs_vfsops.c,v 1.90.2.1 2014/08/10 06:56:05 tls Exp $ */
/*
* Copyright (c) 1993
@@ -76,7 +76,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: procfs_vfsops.c,v 1.90 2014/03/23 15:21:16 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: procfs_vfsops.c,v 1.90.2.1 2014/08/10 06:56:05 tls Exp $");
#if defined(_KERNEL_OPT)
#include "opt_compat_netbsd.h"
@@ -95,6 +95,8 @@ __KERNEL_RCSID(0, "$NetBSD: procfs_vfsop
#include <sys/signalvar.h>
#include <sys/vnode.h>
#include <sys/malloc.h>
+#include <sys/file.h>
+#include <sys/filedesc.h>
#include <sys/kauth.h>
#include <sys/module.h>
@@ -130,6 +132,9 @@ procfs_mount(
struct procfs_args *args = data;
int error;
+ if (args == NULL)
+ return EINVAL;
+
if (UIO_MX & (UIO_MX-1)) {
log(LOG_ERR, "procfs: invalid directory entry size");
return (EINVAL);
@@ -201,7 +206,7 @@ procfs_root(struct mount *mp, struct vno
{
int error;
- error = procfs_allocvp(mp, vpp, 0, PFSroot, -1, NULL);
+ error = procfs_allocvp(mp, vpp, 0, PFSroot, -1);
if (error == 0) {
error = vn_lock(*vpp, LK_EXCLUSIVE);
if (error != 0) {
@@ -260,22 +265,187 @@ procfs_vget(struct mount *mp, ino_t ino,
return (EOPNOTSUPP);
}
+int
+procfs_loadvnode(struct mount *mp, struct vnode *vp,
+ const void *key, size_t key_len, const void **new_key)
+{
+ int error;
+ struct pfskey pfskey;
+ struct pfsnode *pfs;
+
+ KASSERT(key_len == sizeof(pfskey));
+ memcpy(&pfskey, key, key_len);
+
+ pfs = kmem_alloc(sizeof(*pfs), KM_SLEEP);
+ pfs->pfs_pid = pfskey.pk_pid;
+ pfs->pfs_type = pfskey.pk_type;
+ pfs->pfs_fd = pfskey.pk_fd;
+ pfs->pfs_vnode = vp;
+ pfs->pfs_flags = 0;
+ pfs->pfs_fileno =
+ PROCFS_FILENO(pfs->pfs_pid, pfs->pfs_type, pfs->pfs_fd);
+ vp->v_tag = VT_PROCFS;
+ vp->v_op = procfs_vnodeop_p;
+ vp->v_data = pfs;
+
+ switch (pfs->pfs_type) {
+ case PFSroot: /* /proc = dr-xr-xr-x */
+ vp->v_vflag |= VV_ROOT;
+ /*FALLTHROUGH*/
+ case PFSproc: /* /proc/N = dr-xr-xr-x */
+ pfs->pfs_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
+ vp->v_type = VDIR;
+ break;
+
+ case PFStask: /* /proc/N/task = dr-xr-xr-x */
+ if (pfs->pfs_fd == -1) {
+ pfs->pfs_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|
+ S_IROTH|S_IXOTH;
+ vp->v_type = VDIR;
+ break;
+ }
+ /*FALLTHROUGH*/
+ case PFScurproc: /* /proc/curproc = lr-xr-xr-x */
+ case PFSself: /* /proc/self = lr-xr-xr-x */
+ case PFScwd: /* /proc/N/cwd = lr-xr-xr-x */
+ case PFSchroot: /* /proc/N/chroot = lr-xr-xr-x */
+ case PFSexe: /* /proc/N/exe = lr-xr-xr-x */
+ pfs->pfs_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
+ vp->v_type = VLNK;
+ break;
+
+ case PFSfd:
+ if (pfs->pfs_fd == -1) { /* /proc/N/fd = dr-x------ */
+ pfs->pfs_mode = S_IRUSR|S_IXUSR;
+ vp->v_type = VDIR;
+ } else { /* /proc/N/fd/M = [ps-]rw------- */
+ file_t *fp;
+ vnode_t *vxp;
+ struct proc *p;
+
+ mutex_enter(proc_lock);
+ p = proc_find(pfs->pfs_pid);
+ mutex_exit(proc_lock);
+ if (p == NULL) {
+ error = ENOENT;
+ goto bad;
+ }
+ KASSERT(rw_read_held(&p->p_reflock));
+ if ((fp = fd_getfile2(p, pfs->pfs_fd)) == NULL) {
+ error = EBADF;
+ goto bad;
+ }
+
+ pfs->pfs_mode = S_IRUSR|S_IWUSR;
+ switch (fp->f_type) {
+ case DTYPE_VNODE:
+ vxp = fp->f_data;
+
+ /*
+ * We make symlinks for directories
+ * to avoid cycles.
+ */
+ if (vxp->v_type == VDIR)
+ goto symlink;
+ vp->v_type = vxp->v_type;
+ break;
+ case DTYPE_PIPE:
+ vp->v_type = VFIFO;
+ break;
+ case DTYPE_SOCKET:
+ vp->v_type = VSOCK;
+ break;
+ case DTYPE_KQUEUE:
+ case DTYPE_MISC:
+ case DTYPE_SEM:
+ symlink:
+ pfs->pfs_mode = S_IRUSR|S_IXUSR|S_IRGRP|
+ S_IXGRP|S_IROTH|S_IXOTH;
+ vp->v_type = VLNK;
+ break;
+ default:
+ error = EOPNOTSUPP;
+ closef(fp);
+ goto bad;
+ }
+ closef(fp);
+ }
+ break;
+
+ case PFSfile: /* /proc/N/file = -rw------- */
+ case PFSmem: /* /proc/N/mem = -rw------- */
+ case PFSregs: /* /proc/N/regs = -rw------- */
+ case PFSfpregs: /* /proc/N/fpregs = -rw------- */
+ pfs->pfs_mode = S_IRUSR|S_IWUSR;
+ vp->v_type = VREG;
+ break;
+
+ case PFSctl: /* /proc/N/ctl = --w------ */
+ case PFSnote: /* /proc/N/note = --w------ */
+ case PFSnotepg: /* /proc/N/notepg = --w------ */
+ pfs->pfs_mode = S_IWUSR;
+ vp->v_type = VREG;
+ break;
+
+ case PFSmap: /* /proc/N/map = -r--r--r-- */
+ case PFSmaps: /* /proc/N/maps = -r--r--r-- */
+ case PFSstatus: /* /proc/N/status = -r--r--r-- */
+ case PFSstat: /* /proc/N/stat = -r--r--r-- */
+ case PFScmdline: /* /proc/N/cmdline = -r--r--r-- */
+ case PFSemul: /* /proc/N/emul = -r--r--r-- */
+ case PFSmeminfo: /* /proc/meminfo = -r--r--r-- */
+ case PFScpustat: /* /proc/stat = -r--r--r-- */
+ case PFSdevices: /* /proc/devices = -r--r--r-- */
+ case PFScpuinfo: /* /proc/cpuinfo = -r--r--r-- */
+ case PFSuptime: /* /proc/uptime = -r--r--r-- */
+ case PFSmounts: /* /proc/mounts = -r--r--r-- */
+ case PFSloadavg: /* /proc/loadavg = -r--r--r-- */
+ case PFSstatm: /* /proc/N/statm = -r--r--r-- */
+ case PFSversion: /* /proc/version = -r--r--r-- */
+ pfs->pfs_mode = S_IRUSR|S_IRGRP|S_IROTH;
+ vp->v_type = VREG;
+ break;
+
+#ifdef __HAVE_PROCFS_MACHDEP
+ PROCFS_MACHDEP_NODETYPE_CASES
+ procfs_machdep_allocvp(vp);
+ break;
+#endif
+
+ default:
+ panic("procfs_allocvp");
+ }
+
+ uvm_vnp_setsize(vp, 0);
+ *new_key = &pfs->pfs_key;
+
+ return 0;
+
+bad:
+ vp->v_tag =VT_NON;
+ vp->v_type = VNON;
+ vp->v_op = NULL;
+ vp->v_data = NULL;
+ kmem_free(pfs, sizeof(*pfs));
+ return error;
+}
+
void
procfs_init(void)
{
- procfs_hashinit();
+
}
void
procfs_reinit(void)
{
- procfs_hashreinit();
+
}
void
procfs_done(void)
{
- procfs_hashdone();
+
}
extern const struct vnodeopv_desc procfs_vnodeop_opv_desc;
@@ -296,6 +466,7 @@ struct vfsops procfs_vfsops = {
.vfs_statvfs = procfs_statvfs,
.vfs_sync = procfs_sync,
.vfs_vget = procfs_vget,
+ .vfs_loadvnode = procfs_loadvnode,
.vfs_fhtovp = (void *)eopnotsupp,
.vfs_vptofh = (void *)eopnotsupp,
.vfs_init = procfs_init,
Index: src/sys/miscfs/procfs/procfs_vnops.c
diff -u src/sys/miscfs/procfs/procfs_vnops.c:1.189 src/sys/miscfs/procfs/procfs_vnops.c:1.189.2.1
--- src/sys/miscfs/procfs/procfs_vnops.c:1.189 Fri Feb 7 15:29:22 2014
+++ src/sys/miscfs/procfs/procfs_vnops.c Sun Aug 10 06:56:05 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: procfs_vnops.c,v 1.189 2014/02/07 15:29:22 hannken Exp $ */
+/* $NetBSD: procfs_vnops.c,v 1.189.2.1 2014/08/10 06:56:05 tls Exp $ */
/*-
* Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -105,7 +105,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: procfs_vnops.c,v 1.189 2014/02/07 15:29:22 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: procfs_vnops.c,v 1.189.2.1 2014/08/10 06:56:05 tls Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -259,6 +259,8 @@ const struct vnodeopv_entry_desc procfs_
{ &vop_setattr_desc, procfs_setattr }, /* setattr */
{ &vop_read_desc, procfs_read }, /* read */
{ &vop_write_desc, procfs_write }, /* write */
+ { &vop_fallocate_desc, genfs_eopnotsupp }, /* fallocate */
+ { &vop_fdiscard_desc, genfs_eopnotsupp }, /* fdiscard */
{ &vop_fcntl_desc, procfs_fcntl }, /* fcntl */
{ &vop_ioctl_desc, procfs_ioctl }, /* ioctl */
{ &vop_poll_desc, procfs_poll }, /* poll */
@@ -439,8 +441,18 @@ procfs_reclaim(void *v)
struct vop_reclaim_args /* {
struct vnode *a_vp;
} */ *ap = v;
+ struct vnode *vp = ap->a_vp;
+ struct pfsnode *pfs = VTOPFS(vp);
- return (procfs_freevp(ap->a_vp));
+ /*
+ * To interlock with procfs_revoke_vnodes().
+ */
+ mutex_enter(vp->v_interlock);
+ vp->v_data = NULL;
+ mutex_exit(vp->v_interlock);
+ vcache_remove(vp->v_mount, &pfs->pfs_key, sizeof(pfs->pfs_key));
+ kmem_free(pfs, sizeof(*pfs));
+ return 0;
}
/*
@@ -1035,7 +1047,7 @@ procfs_lookup(void *v)
if (i != nproc_root_targets) {
error = procfs_allocvp(dvp->v_mount, vpp, 0,
- pt->pt_pfstype, -1, NULL);
+ pt->pt_pfstype, -1);
return (error);
}
@@ -1055,14 +1067,14 @@ procfs_lookup(void *v)
if (procfs_proc_lock(pid, &p, ESRCH) != 0)
break;
- error = procfs_allocvp(dvp->v_mount, vpp, vnpid, type, -1, p);
+ error = procfs_allocvp(dvp->v_mount, vpp, vnpid, type, -1);
procfs_proc_unlock(p);
return (error);
case PFSproc:
if (cnp->cn_flags & ISDOTDOT) {
error = procfs_allocvp(dvp->v_mount, vpp, 0, PFSroot,
- -1, NULL);
+ -1);
return (error);
}
@@ -1110,7 +1122,7 @@ procfs_lookup(void *v)
}
error = procfs_allocvp(dvp->v_mount, vpp, pfs->pfs_pid,
- pt->pt_pfstype, -1, p);
+ pt->pt_pfstype, -1);
procfs_proc_unlock(p);
return (error);
@@ -1123,7 +1135,7 @@ procfs_lookup(void *v)
if (cnp->cn_flags & ISDOTDOT) {
error = procfs_allocvp(dvp->v_mount, vpp, pfs->pfs_pid,
- PFSproc, -1, p);
+ PFSproc, -1);
procfs_proc_unlock(p);
return (error);
}
@@ -1147,7 +1159,7 @@ procfs_lookup(void *v)
closef(fp);
error = procfs_allocvp(dvp->v_mount, vpp, pfs->pfs_pid,
- PFSfd, fd, p);
+ PFSfd, fd);
procfs_proc_unlock(p);
return error;
}
@@ -1159,7 +1171,7 @@ procfs_lookup(void *v)
if (cnp->cn_flags & ISDOTDOT) {
error = procfs_allocvp(dvp->v_mount, vpp, pfs->pfs_pid,
- PFSproc, -1, p);
+ PFSproc, -1);
procfs_proc_unlock(p);
return (error);
}
@@ -1170,7 +1182,7 @@ procfs_lookup(void *v)
return ENOENT;
}
error = procfs_allocvp(dvp->v_mount, vpp, pfs->pfs_pid,
- PFStask, 0, p);
+ PFStask, 0);
procfs_proc_unlock(p);
return error;
}
Index: src/sys/miscfs/specfs/spec_vnops.c
diff -u src/sys/miscfs/specfs/spec_vnops.c:1.143 src/sys/miscfs/specfs/spec_vnops.c:1.143.2.1
--- src/sys/miscfs/specfs/spec_vnops.c:1.143 Mon Mar 24 13:42:40 2014
+++ src/sys/miscfs/specfs/spec_vnops.c Sun Aug 10 06:56:05 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: spec_vnops.c,v 1.143 2014/03/24 13:42:40 hannken Exp $ */
+/* $NetBSD: spec_vnops.c,v 1.143.2.1 2014/08/10 06:56:05 tls Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -58,7 +58,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: spec_vnops.c,v 1.143 2014/03/24 13:42:40 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: spec_vnops.c,v 1.143.2.1 2014/08/10 06:56:05 tls Exp $");
#include <sys/param.h>
#include <sys/proc.h>
@@ -123,6 +123,8 @@ const struct vnodeopv_entry_desc spec_vn
{ &vop_setattr_desc, spec_setattr }, /* setattr */
{ &vop_read_desc, spec_read }, /* read */
{ &vop_write_desc, spec_write }, /* write */
+ { &vop_fallocate_desc, spec_fallocate }, /* fallocate */
+ { &vop_fdiscard_desc, spec_fdiscard }, /* fdiscard */
{ &vop_fcntl_desc, spec_fcntl }, /* fcntl */
{ &vop_ioctl_desc, spec_ioctl }, /* ioctl */
{ &vop_poll_desc, spec_poll }, /* poll */
@@ -838,6 +840,46 @@ spec_write(void *v)
}
/*
+ * fdiscard, which on disk devices becomes TRIM.
+ */
+int
+spec_fdiscard(void *v)
+{
+ struct vop_fdiscard_args /* {
+ struct vnode *a_vp;
+ off_t a_pos;
+ off_t a_len;
+ } */ *ap = v;
+ struct vnode *vp;
+ dev_t dev;
+
+ vp = ap->a_vp;
+ dev = NODEV;
+
+ mutex_enter(vp->v_interlock);
+ if (vdead_check(vp, VDEAD_NOWAIT) == 0 && vp->v_specnode != NULL) {
+ dev = vp->v_rdev;
+ }
+ mutex_exit(vp->v_interlock);
+
+ if (dev == NODEV) {
+ return ENXIO;
+ }
+
+ switch (vp->v_type) {
+ case VCHR:
+ // this is not stored for character devices
+ //KASSERT(vp == vp->v_specnode->sn_dev->sd_cdevvp);
+ return cdev_discard(dev, ap->a_pos, ap->a_len);
+ case VBLK:
+ KASSERT(vp == vp->v_specnode->sn_dev->sd_bdevvp);
+ return bdev_discard(dev, ap->a_pos, ap->a_len);
+ default:
+ panic("spec_fdiscard: not a device\n");
+ }
+}
+
+/*
* Device ioctl operation.
*/
/* ARGSUSED */
Index: src/sys/miscfs/specfs/specdev.h
diff -u src/sys/miscfs/specfs/specdev.h:1.42 src/sys/miscfs/specfs/specdev.h:1.42.2.1
--- src/sys/miscfs/specfs/specdev.h:1.42 Mon Sep 30 18:58:00 2013
+++ src/sys/miscfs/specfs/specdev.h Sun Aug 10 06:56:05 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: specdev.h,v 1.42 2013/09/30 18:58:00 hannken Exp $ */
+/* $NetBSD: specdev.h,v 1.42.2.1 2014/08/10 06:56:05 tls Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -119,6 +119,8 @@ int spec_close(void *);
#define spec_setattr genfs_ebadf
int spec_read(void *);
int spec_write(void *);
+#define spec_fallocate genfs_eopnotsupp
+int spec_fdiscard(void *);
#define spec_fcntl genfs_fcntl
int spec_ioctl(void *);
int spec_poll(void *);
Index: src/sys/miscfs/umapfs/umap_vfsops.c
diff -u src/sys/miscfs/umapfs/umap_vfsops.c:1.91 src/sys/miscfs/umapfs/umap_vfsops.c:1.91.2.1
--- src/sys/miscfs/umapfs/umap_vfsops.c:1.91 Sun Mar 23 15:21:16 2014
+++ src/sys/miscfs/umapfs/umap_vfsops.c Sun Aug 10 06:56:05 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: umap_vfsops.c,v 1.91 2014/03/23 15:21:16 hannken Exp $ */
+/* $NetBSD: umap_vfsops.c,v 1.91.2.1 2014/08/10 06:56:05 tls Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: umap_vfsops.c,v 1.91 2014/03/23 15:21:16 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: umap_vfsops.c,v 1.91.2.1 2014/08/10 06:56:05 tls Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -81,6 +81,8 @@ umapfs_mount(struct mount *mp, const cha
int i;
#endif
+ if (args == NULL)
+ return EINVAL;
if (*data_len < sizeof *args)
return EINVAL;
@@ -195,12 +197,7 @@ umapfs_mount(struct mount *mp, const cha
amp->umapm_size = sizeof(struct umap_node);
amp->umapm_tag = VT_UMAP;
amp->umapm_bypass = umap_bypass;
- amp->umapm_alloc = layer_node_alloc; /* the default alloc is fine */
amp->umapm_vnodeop_p = umap_vnodeop_p;
- mutex_init(&->umapm_hashlock, MUTEX_DEFAULT, IPL_NONE);
- amp->umapm_node_hashtbl = hashinit(NUMAPNODECACHE, HASH_LIST, true,
- &->umapm_node_hash);
-
/*
* fix up umap node for root vnode.
@@ -212,8 +209,6 @@ umapfs_mount(struct mount *mp, const cha
*/
if (error) {
vrele(lowerrootvp);
- hashdone(amp->umapm_node_hashtbl, HASH_LIST,
- amp->umapm_node_hash);
kmem_free(amp, sizeof(struct umap_mount));
return error;
}
@@ -269,8 +264,6 @@ umapfs_unmount(struct mount *mp, int mnt
/*
* Finally, throw away the umap_mount structure
*/
- mutex_destroy(&->umapm_hashlock);
- hashdone(amp->umapm_node_hashtbl, HASH_LIST, amp->umapm_node_hash);
kmem_free(amp, sizeof(struct umap_mount));
mp->mnt_data = NULL;
return 0;
@@ -293,6 +286,7 @@ struct vfsops umapfs_vfsops = {
.vfs_quotactl = layerfs_quotactl,
.vfs_statvfs = layerfs_statvfs,
.vfs_sync = layerfs_sync,
+ .vfs_loadvnode = layerfs_loadvnode,
.vfs_vget = layerfs_vget,
.vfs_fhtovp = layerfs_fhtovp,
.vfs_vptofh = layerfs_vptofh,