Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/rump/librump/rumpvfs support read/write & ubc



details:   https://anonhg.NetBSD.org/src/rev/40d88b770968
branches:  trunk
changeset: 758629:40d88b770968
user:      pooka <pooka%NetBSD.org@localhost>
date:      Thu Nov 11 17:26:01 2010 +0000

description:
support read/write & ubc

diffstat:

 sys/rump/librump/rumpvfs/rumpfs.c |  236 +++++++++++++++++++++++++++++++------
 1 files changed, 196 insertions(+), 40 deletions(-)

diffs (truncated from 404 to 300 lines):

diff -r 1dda1883186c -r 40d88b770968 sys/rump/librump/rumpvfs/rumpfs.c
--- a/sys/rump/librump/rumpvfs/rumpfs.c Thu Nov 11 16:08:31 2010 +0000
+++ b/sys/rump/librump/rumpvfs/rumpfs.c Thu Nov 11 17:26:01 2010 +0000
@@ -1,7 +1,7 @@
-/*     $NetBSD: rumpfs.c,v 1.70 2010/11/11 16:08:31 pooka Exp $        */
+/*     $NetBSD: rumpfs.c,v 1.71 2010/11/11 17:26:01 pooka Exp $        */
 
 /*
- * Copyright (c) 2009  Antti Kantee.  All Rights Reserved.
+ * Copyright (c) 2009, 2010 Antti Kantee.  All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,10 +26,11 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rumpfs.c,v 1.70 2010/11/11 16:08:31 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rumpfs.c,v 1.71 2010/11/11 17:26:01 pooka Exp $");
 
 #include <sys/param.h>
 #include <sys/atomic.h>
+#include <sys/buf.h>
 #include <sys/dirent.h>
 #include <sys/errno.h>
 #include <sys/filedesc.h>
@@ -52,6 +53,8 @@
 #include <miscfs/genfs/genfs.h>
 #include <miscfs/genfs/genfs_node.h>
 
+#include <uvm/uvm_extern.h>
+
 #include <rump/rumpuser.h>
 
 #include "rump_private.h"
@@ -75,6 +78,8 @@
 static int rump_vop_readlink(void *);
 static int rump_vop_whiteout(void *);
 static int rump_vop_pathconf(void *);
+static int rump_vop_bmap(void *);
+static int rump_vop_strategy(void *);
 
 int (**fifo_vnodeop_p)(void *);
 const struct vnodeopv_entry_desc fifo_vnodeop_entries[] = {
@@ -114,6 +119,8 @@
        { &vop_remove_desc, genfs_eopnotsupp },
        { &vop_link_desc, genfs_eopnotsupp },
        { &vop_pathconf_desc, rump_vop_pathconf },
+       { &vop_bmap_desc, rump_vop_bmap },
+       { &vop_strategy_desc, rump_vop_strategy },
        { NULL, NULL }
 };
 const struct vnodeopv_desc rump_vnodeop_opv_desc =
@@ -165,6 +172,10 @@
                        int writefd;
                        uint64_t offset;
                } reg;
+               struct {
+                       void *data;
+                       size_t dlen;
+               } reg_noet;
                struct {                /* VDIR */
                        LIST_HEAD(, rumpfs_dent) dents;
                        struct rumpfs_node *parent;
@@ -179,6 +190,8 @@
 #define rn_readfd      rn_u.reg.readfd
 #define rn_writefd     rn_u.reg.writefd
 #define rn_offset      rn_u.reg.offset
+#define rn_data                rn_u.reg_noet.data
+#define rn_dlen                rn_u.reg_noet.dlen
 #define rn_dir         rn_u.dir.dents
 #define rn_parent      rn_u.dir.parent
 #define rn_linktarg    rn_u.link.target
@@ -193,7 +206,7 @@
        struct vnode *rfsmp_rvp;
 };
 
-static struct rumpfs_node *makeprivate(enum vtype, dev_t, off_t);
+static struct rumpfs_node *makeprivate(enum vtype, dev_t, off_t, bool);
 
 /*
  * Extra Terrestrial stuff.  We map a given key (pathname) to a file on
@@ -340,7 +353,7 @@
        et = kmem_alloc(sizeof(*et), KM_SLEEP);
        strcpy(et->et_key, key);
        et->et_keylen = strlen(et->et_key);
-       et->et_rn = rn = makeprivate(ettype_to_vtype(ftype), rdev, size);
+       et->et_rn = rn = makeprivate(ettype_to_vtype(ftype), rdev, size, true);
        et->et_removing = false;
        et->et_blkmin = dmin;
 
@@ -462,7 +475,7 @@
 static kmutex_t reclock;
 
 static struct rumpfs_node *
-makeprivate(enum vtype vt, dev_t rdev, off_t size)
+makeprivate(enum vtype vt, dev_t rdev, off_t size, bool et)
 {
        struct rumpfs_node *rn;
        struct vattr *va;
@@ -475,8 +488,10 @@
                LIST_INIT(&rn->rn_dir);
                break;
        case VREG:
-               rn->rn_readfd = -1;
-               rn->rn_writefd = -1;
+               if (et) {
+                       rn->rn_readfd = -1;
+                       rn->rn_writefd = -1;
+               }
                break;
        default:
                break;
@@ -668,10 +683,11 @@
                        return ENOENT;
                }
 
-               rn = makeprivate(hft_to_vtype(hft), NODEV, fsize);
+               rn = makeprivate(hft_to_vtype(hft), NODEV, fsize, true);
                rn->rn_flags |= RUMPNODE_CANRECLAIM;
                if (rnd->rn_flags & RUMPNODE_DIR_ETSUBS) {
                        rn->rn_flags |= RUMPNODE_DIR_ET | RUMPNODE_DIR_ETSUBS;
+                       rn->rn_flags |= RUMPNODE_ET_PHONE_HOST;
                }
                rn->rn_hostpath = newpath;
 
@@ -754,7 +770,7 @@
        struct rumpfs_node *rnd = dvp->v_data, *rn;
        int rv = 0;
 
-       rn = makeprivate(VDIR, NODEV, DEV_BSIZE);
+       rn = makeprivate(VDIR, NODEV, DEV_BSIZE, false);
        rn->rn_parent = rnd;
        rv = makevnode(dvp->v_mount, rn, vpp);
        if (rv)
@@ -815,7 +831,7 @@
        struct rumpfs_node *rnd = dvp->v_data, *rn;
        int rv;
 
-       rn = makeprivate(va->va_type, va->va_rdev, DEV_BSIZE);
+       rn = makeprivate(va->va_type, va->va_rdev, DEV_BSIZE, false);
        rv = makevnode(dvp->v_mount, rn, vpp);
        if (rv)
                goto out;
@@ -846,7 +862,7 @@
        int rv;
 
        newsize = va->va_type == VSOCK ? DEV_BSIZE : 0;
-       rn = makeprivate(va->va_type, NODEV, newsize);
+       rn = makeprivate(va->va_type, NODEV, newsize, false);
        rv = makevnode(dvp->v_mount, rn, vpp);
        if (rv)
                goto out;
@@ -879,7 +895,7 @@
 
        linklen = strlen(target);
        KASSERT(linklen < MAXPATHLEN);
-       rn = makeprivate(VLNK, NODEV, linklen);
+       rn = makeprivate(VLNK, NODEV, linklen, false);
        rv = makevnode(dvp->v_mount, rn, vpp);
        if (rv)
                goto out;
@@ -1045,6 +1061,28 @@
 }
 
 static int
+etread(struct rumpfs_node *rn, struct uio *uio)
+{
+       uint8_t *buf;
+       size_t bufsize;
+       ssize_t n;
+       int error = 0;
+
+       bufsize = uio->uio_resid;
+       buf = kmem_alloc(bufsize, KM_SLEEP);
+       if ((n = rumpuser_pread(rn->rn_readfd, buf, bufsize,
+           uio->uio_offset + rn->rn_offset, &error)) == -1)
+               goto out;
+       KASSERT(n <= bufsize);
+       error = uiomove(buf, n, uio);
+
+ out:
+       kmem_free(buf, bufsize);
+       return error;
+
+}
+
+static int
 rump_vop_read(void *v)
 {
        struct vop_read_args /* {
@@ -1056,21 +1094,48 @@
        struct vnode *vp = ap->a_vp;
        struct rumpfs_node *rn = vp->v_data;
        struct uio *uio = ap->a_uio;
+       const int advice = IO_ADV_DECODE(ap->a_ioflag);
+       off_t chunk;
+       int error;
+
+       /* et op? */
+       if (rn->rn_flags & RUMPNODE_ET_PHONE_HOST)
+               return etread(rn, uio);
+
+       /* otherwise, it's off to ubc with us */
+       while (uio->uio_resid > 0) {
+               chunk = MIN(uio->uio_resid, (off_t)rn->rn_dlen-uio->uio_offset);
+               if (chunk == 0)
+                       break;
+               error = ubc_uiomove(&vp->v_uobj, uio, chunk, advice,
+                   UBC_READ | UBC_PARTIALOK | UBC_WANT_UNMAP(vp)?UBC_UNMAP:0);
+               if (error)
+                       break;
+       }
+
+       return error;
+}
+
+static int
+etwrite(struct rumpfs_node *rn, struct uio *uio)
+{
        uint8_t *buf;
        size_t bufsize;
        ssize_t n;
        int error = 0;
 
-       if (rn->rn_readfd == -1)
-               return EOPNOTSUPP;
-
        bufsize = uio->uio_resid;
        buf = kmem_alloc(bufsize, KM_SLEEP);
-       if ((n = rumpuser_pread(rn->rn_readfd, buf, bufsize,
-           uio->uio_offset + rn->rn_offset, &error)) == -1)
+       error = uiomove(buf, bufsize, uio);
+       if (error)
                goto out;
-       KASSERT(n <= bufsize);
-       error = uiomove(buf, n, uio);
+       KASSERT(uio->uio_resid == 0);
+       n = rumpuser_pwrite(rn->rn_writefd, buf, bufsize,
+           (uio->uio_offset-bufsize) + rn->rn_offset, &error);
+       if (n >= 0) {
+               KASSERT(n <= bufsize);
+               uio->uio_resid = bufsize - n;
+       }
 
  out:
        kmem_free(buf, bufsize);
@@ -1089,30 +1154,120 @@
        struct vnode *vp = ap->a_vp;
        struct rumpfs_node *rn = vp->v_data;
        struct uio *uio = ap->a_uio;
-       uint8_t *buf;
-       size_t bufsize;
-       ssize_t n;
-       int error = 0;
+       const int advice = IO_ADV_DECODE(ap->a_ioflag);
+       void *olddata;
+       size_t oldlen, newlen;
+       off_t chunk;
+       int error;
+       bool allocd = false;
+
+       /* consult et? */
+       if (rn->rn_flags & RUMPNODE_ET_PHONE_HOST)
+               return etwrite(rn, uio);
 
-       if (rn->rn_writefd == -1)
-               return EOPNOTSUPP;
+       /*
+        * Otherwise, it's a case of ubcmove.
+        */
+
+       /*
+        * First, make sure we have enough storage.
+        *
+        * No, you don't need to tell me it's not very efficient.
+        * No, it doesn't really support sparse files, just fakes it.
+        */
+       newlen = uio->uio_offset + uio->uio_resid;
+       if (rn->rn_dlen < newlen) {
+               oldlen = rn->rn_dlen;
+               olddata = rn->rn_data;
 
-       bufsize = uio->uio_resid;
-       buf = kmem_alloc(bufsize, KM_SLEEP);
-       error = uiomove(buf, bufsize, uio);
-       if (error)
-               goto out;
-       KASSERT(uio->uio_resid == 0);
-       n = rumpuser_pwrite(rn->rn_writefd, buf, bufsize,
-           (uio->uio_offset-bufsize) + rn->rn_offset, &error);
-       if (n >= 0) {
-               KASSERT(n <= bufsize);
-               uio->uio_resid = bufsize - n;
+               rn->rn_data = rump_hypermalloc(newlen, 0, true, "rumpfs");
+               rn->rn_dlen = newlen;
+               memset(rn->rn_data, 0, newlen);
+               memcpy(rn->rn_data, olddata, oldlen);
+               allocd = true;
+               uvm_vnp_setsize(vp, newlen);



Home | Main Index | Thread Index | Old Index