Make it possible for the file server to specify the root vnode type

and other information instead of always using VDIR.  To make this
possible without races, require all root node information already
in puffs_mount() and nuke puffs_start2() and the associated start
operation completely.

requested/inspired by Tobias Nygren
This commit is contained in:
pooka 2007-05-17 13:59:22 +00:00
parent cb7e3eae7c
commit 339652951e
5 changed files with 50 additions and 79 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: puffs_msgif.h,v 1.29 2007/05/07 17:14:54 pooka Exp $ */
/* $NetBSD: puffs_msgif.h,v 1.30 2007/05/17 13:59:22 pooka Exp $ */
/*
* Copyright (c) 2005, 2006 Antti Kantee. All Rights Reserved.
@ -86,7 +86,7 @@ enum {
#define PUFFS_VN_MAX PUFFS_VN_SETEXTATTR
#define PUFFSDEVELVERS 0x80000000
#define PUFFSVERSION 9
#define PUFFSVERSION 10
#define PUFFSNAMESIZE 32
struct puffs_kargs {
unsigned int pa_vers;
@ -99,6 +99,13 @@ struct puffs_kargs {
size_t pa_fhsize;
int pa_fhflags;
void *pa_root_cookie;
enum vtype pa_root_vtype;
voff_t pa_root_vsize;
dev_t pa_root_rdev;
struct statvfs pa_svfsb;
char pa_name[PUFFSNAMESIZE+1]; /* name for puffs type */
uint8_t pa_vnopmask[PUFFS_VN_MAX];
};
@ -284,15 +291,14 @@ struct puffs_flush {
/*
* Available ioctl operations
*/
#define PUFFSSTARTOP _IOWR('p', 1, struct puffs_startreq)
#define PUFFSGETOP _IOWR('p', 2, struct puffs_reqh_get)
#define PUFFSPUTOP _IOWR('p', 3, struct puffs_reqh_put)
#define PUFFSSIZEOP _IOWR('p', 4, struct puffs_sizeop)
#define PUFFSFLUSHOP _IOW ('p', 5, struct puffs_flush)
#define PUFFSGETOP _IOWR('p', 1, struct puffs_reqh_get)
#define PUFFSPUTOP _IOWR('p', 2, struct puffs_reqh_put)
#define PUFFSSIZEOP _IOWR('p', 3, struct puffs_sizeop)
#define PUFFSFLUSHOP _IOW ('p', 4, struct puffs_flush)
#if 0
#define PUFFSFLUSHMULTIOP _IOW ('p', 6, struct puffs_flushmulti)
#define PUFFSFLUSHMULTIOP _IOW ('p', 5, struct puffs_flushmulti)
#endif
#define PUFFSSUSPENDOP _IO ('p', 7)
#define PUFFSSUSPENDOP _IO ('p', 6)
/*
@ -357,13 +363,6 @@ struct puffs_kcn {
* modified only by specific routines.
*/
struct puffs_startreq {
struct puffs_req psr_pr;
void *psr_cookie; /* IN: root node cookie */
struct statvfs psr_sb; /* IN: statvfs buffer */
};
/*
* aux structures for vfs operations.
*/

View File

@ -1,4 +1,4 @@
/* $NetBSD: puffs_subr.c,v 1.29 2007/05/08 21:39:03 pooka Exp $ */
/* $NetBSD: puffs_subr.c,v 1.30 2007/05/17 13:59:22 pooka Exp $ */
/*
* Copyright (c) 2005, 2006 Antti Kantee. All Rights Reserved.
@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: puffs_subr.c,v 1.29 2007/05/08 21:39:03 pooka Exp $");
__KERNEL_RCSID(0, "$NetBSD: puffs_subr.c,v 1.30 2007/05/17 13:59:22 pooka Exp $");
#include <sys/param.h>
#include <sys/conf.h>
@ -226,7 +226,7 @@ puffs_newnode(struct mount *mp, struct vnode *dvp, struct vnode **vpp,
* not the caller.
*/
mutex_enter(&pmp->pmp_lock);
if (cookie == pmp->pmp_rootcookie
if (cookie == pmp->pmp_root_cookie
|| puffs_cookie2pnode(pmp, cookie) != NULL) {
mutex_exit(&pmp->pmp_lock);
error = EEXIST;
@ -318,7 +318,7 @@ puffs_pnode2vnode(struct puffs_mount *pmp, void *cookie, int lock)
* puffs_root() to get all the right things set. Lock must
* be set, since VFS_ROOT() always locks the returned vnode.
*/
if (cookie == pmp->pmp_rootcookie) {
if (cookie == pmp->pmp_root_cookie) {
if (!lock)
return NULL;
if (VFS_ROOT(pmp->pmp_mp, &vp))

View File

@ -1,4 +1,4 @@
/* $NetBSD: puffs_sys.h,v 1.34 2007/05/07 17:14:54 pooka Exp $ */
/* $NetBSD: puffs_sys.h,v 1.35 2007/05/17 13:59:22 pooka Exp $ */
/*
* Copyright (c) 2005, 2006 Antti Kantee. All Rights Reserved.
@ -137,8 +137,13 @@ struct puffs_mount {
int pmp_npnodehash;
struct mount *pmp_mp;
struct vnode *pmp_root;
void *pmp_rootcookie;
void *pmp_root_cookie;
enum vtype pmp_root_vtype;
vsize_t pmp_root_vsize;
dev_t pmp_root_rdev;
struct selinfo *pmp_sel; /* in puffs_instance */
unsigned int pmp_refcount;
@ -195,8 +200,6 @@ void puffs_msgif_destroy(void);
void *puffs_park_alloc(int);
void puffs_park_release(void *, int);
int puffs_start2(struct puffs_mount *, struct puffs_startreq *);
int puffs_vfstouser(struct puffs_mount *, int, void *, size_t);
void puffs_suspendtouser(struct puffs_mount *, int);
int puffs_vntouser(struct puffs_mount *, int, void *, size_t, size_t,

View File

@ -1,4 +1,4 @@
/* $NetBSD: puffs_transport.c,v 1.17 2007/05/01 12:18:40 pooka Exp $ */
/* $NetBSD: puffs_transport.c,v 1.18 2007/05/17 13:59:22 pooka Exp $ */
/*
* Copyright (c) 2006 Antti Kantee. All Rights Reserved.
@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: puffs_transport.c,v 1.17 2007/05/01 12:18:40 pooka Exp $");
__KERNEL_RCSID(0, "$NetBSD: puffs_transport.c,v 1.18 2007/05/17 13:59:22 pooka Exp $");
#include <sys/param.h>
#include <sys/conf.h>
@ -474,10 +474,6 @@ puffs_fop_ioctl(struct file *fp, u_long cmd, void *data, struct lwp *l)
break;
#endif
case PUFFSSTARTOP:
rv = puffs_start2(pmp, data);
break;
case PUFFSFLUSHOP:
rv = puffs_flush(pmp, data);
break;

View File

@ -1,4 +1,4 @@
/* $NetBSD: puffs_vfsops.c,v 1.41 2007/05/01 12:18:40 pooka Exp $ */
/* $NetBSD: puffs_vfsops.c,v 1.42 2007/05/17 13:59:22 pooka Exp $ */
/*
* Copyright (c) 2005, 2006 Antti Kantee. All Rights Reserved.
@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: puffs_vfsops.c,v 1.41 2007/05/01 12:18:40 pooka Exp $");
__KERNEL_RCSID(0, "$NetBSD: puffs_vfsops.c,v 1.42 2007/05/17 13:59:22 pooka Exp $");
#include <sys/param.h>
#include <sys/mount.h>
@ -170,6 +170,14 @@ puffs_mount(struct mount *mp, const char *path, void *data,
goto out;
mp->mnt_stat.f_iosize = DEV_BSIZE;
/*
* We can't handle the VFS_STATVFS() mount_domount() does
* after VFS_MOUNT() because we'd deadlock, so handle it
* here already.
*/
copy_statvfs_info(&args->pa_svfsb, mp);
(void)memcpy(&mp->mnt_stat, &args->pa_svfsb, sizeof(mp->mnt_stat));
MALLOC(pmp, struct puffs_mount *, sizeof(struct puffs_mount),
M_PUFFS, M_WAITOK | M_ZERO);
@ -202,6 +210,12 @@ puffs_mount(struct mount *mp, const char *path, void *data,
goto out;
}
/* XXX: check parameters */
pmp->pmp_root_cookie = args->pa_root_cookie;
pmp->pmp_root_vtype = args->pa_root_vtype;
pmp->pmp_root_vsize = args->pa_root_vsize;
pmp->pmp_root_rdev = args->pa_root_rdev;
mutex_init(&pmp->pmp_lock, MUTEX_DEFAULT, IPL_NONE);
cv_init(&pmp->pmp_req_waiter_cv, "puffsget");
cv_init(&pmp->pmp_refcount_cv, "puffsref");
@ -224,56 +238,14 @@ puffs_mount(struct mount *mp, const char *path, void *data,
return error;
}
/*
* This is called from the first "Hello, I'm alive" ioctl
* from userspace.
*/
int
puffs_start2(struct puffs_mount *pmp, struct puffs_startreq *sreq)
{
struct puffs_node *pn;
struct mount *mp;
mp = PMPTOMP(pmp);
mutex_enter(&pmp->pmp_lock);
/*
* if someone has issued a VFS_ROOT() already, fill in the
* vnode cookie.
*/
pn = NULL;
if (pmp->pmp_root) {
pn = VPTOPP(pmp->pmp_root);
pn->pn_cookie = sreq->psr_cookie;
}
/* We're good to fly */
pmp->pmp_rootcookie = sreq->psr_cookie;
pmp->pmp_status = PUFFSTAT_RUNNING;
mutex_exit(&pmp->pmp_lock);
/* do the VFS_STATVFS() we missed out on in sys_mount() */
copy_statvfs_info(&sreq->psr_sb, mp);
(void)memcpy(&mp->mnt_stat, &sreq->psr_sb, sizeof(mp->mnt_stat));
mp->mnt_stat.f_iosize = DEV_BSIZE;
DPRINTF(("puffs_start2: root vp %p, cur root pnode %p, cookie %p\n",
pmp->pmp_root, pn, sreq->psr_cookie));
return 0;
}
int
puffs_start(struct mount *mp, int flags, struct lwp *l)
{
struct puffs_mount *pmp = MPTOPUFFSMP(mp);
KASSERT(pmp->pmp_status == PUFFSTAT_MOUNTING);
pmp->pmp_status = PUFFSTAT_RUNNING;
/*
* This cannot travel to userspace, as this is called from
* the kernel context of the process doing mount(2). But
* it's probably a safe bet that the process doing mount(2)
* realizes it needs to start the filesystem also...
*/
return 0;
}
@ -400,7 +372,8 @@ puffs_root(struct mount *mp, struct vnode **vpp)
* So, didn't have the magic root vnode available.
* No matter, grab another an stuff it with the cookie.
*/
if (puffs_getvnode(mp, pmp->pmp_rootcookie, VDIR, 0, 0, &vp))
if (puffs_getvnode(mp, pmp->pmp_root_cookie, pmp->pmp_root_vtype,
pmp->pmp_root_vsize, pmp->pmp_root_rdev, &vp))
panic("sloppy programming");
mutex_enter(&pmp->pmp_lock);