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