Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/rump Add directory support to etfs: host directories and...
details: https://anonhg.NetBSD.org/src/rev/1b73166f9453
branches: trunk
changeset: 754299:1b73166f9453
user: pooka <pooka%NetBSD.org@localhost>
date: Mon Apr 26 23:40:22 2010 +0000
description:
Add directory support to etfs: host directories and their contents
will be mapped to rumpfs based on the given key. The directory
can be mapped either for a single level or recursively down the
entire subtree.
diffstat:
sys/rump/include/rump/rump.h | 10 +-
sys/rump/librump/rumpvfs/rumpfs.c | 174 ++++++++++++++++++++++++++++++-------
2 files changed, 149 insertions(+), 35 deletions(-)
diffs (truncated from 332 to 300 lines):
diff -r 9882334fbbf6 -r 1b73166f9453 sys/rump/include/rump/rump.h
--- a/sys/rump/include/rump/rump.h Mon Apr 26 23:18:51 2010 +0000
+++ b/sys/rump/include/rump/rump.h Mon Apr 26 23:40:22 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: rump.h,v 1.40 2010/04/24 01:47:34 dholland Exp $ */
+/* $NetBSD: rump.h,v 1.41 2010/04/26 23:40:22 pooka Exp $ */
/*
* Copyright (c) 2007 Antti Kantee. All Rights Reserved.
@@ -76,7 +76,13 @@
#define RUMPCN_FREECRED 0x02
#define RUMPCN_FORCEFREE 0x04
#define RUMP_ETFS_SIZE_ENDOFF ((uint64_t)-1)
-enum rump_etfs_type { RUMP_ETFS_REG, RUMP_ETFS_BLK, RUMP_ETFS_CHR };
+enum rump_etfs_type {
+ RUMP_ETFS_REG,
+ RUMP_ETFS_BLK,
+ RUMP_ETFS_CHR,
+ RUMP_ETFS_DIR, /* only the registered directory */
+ RUMP_ETFS_DIR_SUBDIRS /* dir + subdirectories (recursive) */
+};
/*
* Something like rump capabilities would be nicer, but let's
diff -r 9882334fbbf6 -r 1b73166f9453 sys/rump/librump/rumpvfs/rumpfs.c
--- a/sys/rump/librump/rumpvfs/rumpfs.c Mon Apr 26 23:18:51 2010 +0000
+++ b/sys/rump/librump/rumpvfs/rumpfs.c Mon Apr 26 23:40:22 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: rumpfs.c,v 1.40 2010/04/21 07:35:12 pooka Exp $ */
+/* $NetBSD: rumpfs.c,v 1.41 2010/04/26 23:40:22 pooka Exp $ */
/*
* Copyright (c) 2009 Antti Kantee. All Rights Reserved.
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rumpfs.c,v 1.40 2010/04/21 07:35:12 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rumpfs.c,v 1.41 2010/04/26 23:40:22 pooka Exp $");
#include <sys/param.h>
#include <sys/atomic.h>
@@ -123,22 +123,29 @@
struct rumpfs_node {
struct vattr rn_va;
struct vnode *rn_vp;
+ char *rn_hostpath;
+ int rn_flags;
union {
- struct {
- char *hostpath; /* VREG */
+ struct { /* VREG */
int readfd;
int writefd;
uint64_t offset;
} reg;
- LIST_HEAD(, rumpfs_dent) dir; /* VDIR */
+ struct { /* VDIR */
+ LIST_HEAD(, rumpfs_dent) dents;
+ int flags;
+ } dir;
} rn_u;
};
-#define rn_hostpath rn_u.reg.hostpath
#define rn_readfd rn_u.reg.readfd
#define rn_writefd rn_u.reg.writefd
#define rn_offset rn_u.reg.offset
-#define rn_dir rn_u.dir
+#define rn_dir rn_u.dir.dents
+
+#define RUMPNODE_CANRECLAIM 0x01
+#define RUMPNODE_DIR_ET 0x02
+#define RUMPNODE_DIR_ETSUBS 0x04
struct rumpfs_mount {
struct vnode *rfsmp_rvp;
@@ -157,6 +164,7 @@
struct etfs {
char et_key[MAXPATHLEN];
size_t et_keylen;
+ bool et_prefixkey;
LIST_ENTRY(etfs) et_entries;
@@ -180,6 +188,12 @@
case RUMP_ETFS_CHR:
vt = VCHR;
break;
+ case RUMP_ETFS_DIR:
+ vt = VDIR;
+ break;
+ case RUMP_ETFS_DIR_SUBDIRS:
+ vt = VDIR;
+ break;
default:
panic("invalid et type: %d", et);
}
@@ -187,32 +201,63 @@
return vt;
}
+static enum vtype
+hft_to_vtype(int hft)
+{
+ enum vtype vt;
+
+ switch (hft) {
+ case RUMPUSER_FT_OTHER:
+ vt = VNON;
+ break;
+ case RUMPUSER_FT_DIR:
+ vt = VDIR;
+ break;
+ case RUMPUSER_FT_REG:
+ vt = VREG;
+ break;
+ case RUMPUSER_FT_BLK:
+ vt = VBLK;
+ break;
+ case RUMPUSER_FT_CHR:
+ vt = VCHR;
+ break;
+ default:
+ vt = VNON;
+ break;
+ }
+
+ return vt;
+}
+
static bool
-etfs_find(const char *key, struct rumpfs_node **rnp)
+etfs_find(const char *key, struct etfs **etp, bool forceprefix)
{
struct etfs *et;
size_t keylen = strlen(key);
- bool rv = false;
KASSERT(mutex_owned(&etfs_lock));
LIST_FOREACH(et, &etfs_list, et_entries) {
- if (keylen == et->et_keylen && strcmp(key, et->et_key) == 0) {
- *rnp = et->et_rn;
- rv = true;
- break;
+ if ((keylen == et->et_keylen || et->et_prefixkey || forceprefix)
+ && strncmp(key, et->et_key, et->et_keylen) == 0) {
+ if (etp)
+ *etp = et;
+ return true;
}
}
- return rv;
+ return false;
}
+#define REGDIR(ftype) \
+ ((ftype) == RUMP_ETFS_DIR || (ftype) == RUMP_ETFS_DIR_SUBDIRS)
static int
doregister(const char *key, const char *hostpath,
enum rump_etfs_type ftype, uint64_t begin, uint64_t size)
{
struct etfs *et;
- struct rumpfs_node *rn_dummy, *rn;
+ struct rumpfs_node *rn;
uint64_t fsize;
dev_t rdev = NODEV;
devminor_t dmin;
@@ -221,13 +266,23 @@
if (rumpuser_getfileinfo(hostpath, &fsize, &hft, &error))
return error;
- /* check that we give sensible arguments */
- if (begin > fsize)
- return EINVAL;
- if (size == RUMP_ETFS_SIZE_ENDOFF)
- size = fsize - begin;
- if (begin + size > fsize)
- return EINVAL;
+ /* etfs directory requires a directory on the host */
+ if (REGDIR(ftype)) {
+ if (hft != RUMPUSER_FT_DIR)
+ return ENOTDIR;
+ if (begin != 0)
+ return EISDIR;
+ if (size != RUMP_ETFS_SIZE_ENDOFF)
+ return EISDIR;
+ size = fsize;
+ } else {
+ if (begin > fsize)
+ return EINVAL;
+ if (size == RUMP_ETFS_SIZE_ENDOFF)
+ size = fsize - begin;
+ if (begin + size > fsize)
+ return EINVAL;
+ }
if (ftype == RUMP_ETFS_BLK || ftype == RUMP_ETFS_CHR) {
error = rumpblk_register(hostpath, &dmin, begin, size);
@@ -241,7 +296,8 @@
strcpy(et->et_key, key);
et->et_keylen = strlen(et->et_key);
et->et_rn = rn = makeprivate(ettype_to_vtype(ftype), rdev, size);
- if (ftype == RUMP_ETFS_REG) {
+
+ if (ftype == RUMP_ETFS_REG || REGDIR(ftype)) {
size_t len = strlen(hostpath)+1;
rn->rn_hostpath = malloc(len, M_TEMP, M_WAITOK | M_ZERO);
@@ -249,8 +305,18 @@
rn->rn_offset = begin;
}
+ if (REGDIR(ftype)) {
+ rn->rn_flags |= RUMPNODE_DIR_ET;
+ et->et_prefixkey = true;
+ } else {
+ et->et_prefixkey = false;
+ }
+
+ if (ftype == RUMP_ETFS_DIR_SUBDIRS)
+ rn->rn_flags |= RUMPNODE_DIR_ETSUBS;
+
mutex_enter(&etfs_lock);
- if (etfs_find(key, &rn_dummy)) {
+ if (etfs_find(key, NULL, REGDIR(ftype))) {
mutex_exit(&etfs_lock);
kmem_free(et, sizeof(*et));
/* XXX: rumpblk_deregister(hostpath); */
@@ -261,6 +327,7 @@
return 0;
}
+#undef REGDIR
int
rump_etfs_register(const char *key, const char *hostpath,
@@ -427,6 +494,7 @@
struct vnode *vp;
struct rumpfs_node *rnd = dvp->v_data, *rn;
struct rumpfs_dent *rd = NULL;
+ struct etfs *et;
int rv;
/* we handle only some "non-special" cases */
@@ -443,20 +511,55 @@
goto out;
}
- /* check if we are returning a faked block device */
+ /* check for etfs */
if (dvp == rootvnode && cnp->cn_nameiop == LOOKUP) {
+ bool found;
mutex_enter(&etfs_lock);
- if (etfs_find(cnp->cn_pnbuf, &rn)) {
- mutex_exit(&etfs_lock);
- cnp->cn_consume = strlen(cnp->cn_nameptr
- + cnp->cn_namelen);
- cnp->cn_flags &= ~REQUIREDIR;
+ found = etfs_find(cnp->cn_pnbuf, &et, false);
+ mutex_exit(&etfs_lock);
+
+ if (found) {
+ rn = et->et_rn;
+ cnp->cn_consume += et->et_keylen - cnp->cn_namelen;
+ if (rn->rn_va.va_type != VDIR)
+ cnp->cn_flags &= ~REQUIREDIR;
goto getvnode;
}
- mutex_exit(&etfs_lock);
}
- if (!rd) {
+ if (rnd->rn_flags & RUMPNODE_DIR_ET) {
+ uint64_t fsize;
+ char *newpath;
+ size_t newpathlen;
+ int hft, error;
+
+ newpathlen = strlen(rnd->rn_hostpath) + 1 + cnp->cn_namelen + 1;
+ newpath = malloc(newpathlen, M_TEMP, M_WAITOK);
+
+ strlcpy(newpath, rnd->rn_hostpath, newpathlen);
+ strlcat(newpath, "/", newpathlen);
+ strlcat(newpath, cnp->cn_nameptr, newpathlen);
+
+ if (rumpuser_getfileinfo(newpath, &fsize, &hft, &error)) {
+ free(newpath, M_TEMP);
+ return error;
+ }
+
+ /* allow only dirs and regular files */
+ if (hft != RUMPUSER_FT_REG && hft != RUMPUSER_FT_DIR) {
+ free(newpath, M_TEMP);
+ return ENOENT;
+ }
+
+ rn = makeprivate(hft_to_vtype(hft), NODEV, fsize);
Home |
Main Index |
Thread Index |
Old Index