[BACK]Return to p2k.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / libp2k

Annotation of src/lib/libp2k/p2k.c, Revision 1.14

1.14    ! pooka       1: /*     $NetBSD: p2k.c,v 1.13 2009/05/03 20:26:42 pooka Exp $   */
1.1       pooka       2:
                      3: /*
                      4:  * Copyright (c) 2007 Antti Kantee.  All Rights Reserved.
                      5:  *
                      6:  * Development of this software was supported by Google Summer of Code.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  *
                     17:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
                     18:  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     19:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
                     20:  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
                     21:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     22:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
                     23:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     24:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     25:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     26:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     27:  * SUCH DAMAGE.
                     28:  */
                     29:
                     30: /*
                     31:  * puffs 2k, i.e. puffs 2 kernel.  Converts the puffs protocol to
                     32:  * the kernel vfs protocol and vice versa.
                     33:  *
                     34:  * A word about reference counting: puffs in the kernel is the king of
                     35:  * reference counting.  We must maintain a vnode alive and kicking
                     36:  * until the kernel tells us to reclaim it.  Therefore we make sure
                     37:  * we never accidentally lose a vnode.  Before calling operations which
                     38:  * decrease the refcount we always bump the refcount up to compensate.
                     39:  * Come inactive, if the file system thinks that the vnode should be
                     40:  * put out of its misery, it will set the recycle flag.  We use this
                     41:  * to tell the kernel to reclaim the vnode.  Only in reclaim do we
                     42:  * really nuke the last reference.
                     43:  */
                     44:
1.4       pooka      45: #include <sys/cdefs.h>
1.1       pooka      46: #include <sys/mount.h>
                     47: #include <sys/param.h>
                     48: #include <sys/vnode.h>
                     49: #include <sys/lock.h>
                     50: #include <sys/namei.h>
                     51: #include <sys/dirent.h>
                     52:
                     53: #include <assert.h>
                     54: #include <errno.h>
                     55: #include <puffs.h>
                     56: #include <stdlib.h>
1.10      pooka      57: #include <stdio.h>
1.1       pooka      58:
                     59: #include <rump/rump.h>
                     60: #include <rump/p2k.h>
                     61: #include <rump/ukfs.h>
                     62:
                     63: PUFFSOP_PROTOS(p2k)
                     64:
                     65: static kauth_cred_t
                     66: cred_create(const struct puffs_cred *pcr)
                     67: {
                     68:        gid_t groups[NGROUPS];
                     69:        uid_t uid;
                     70:        gid_t gid;
                     71:        short ngroups = 0;
                     72:
                     73:        if (puffs_cred_getuid(pcr, &uid) == -1)
                     74:                uid = 0;
                     75:        if (puffs_cred_getgid(pcr, &gid) == -1)
                     76:                gid = 0;
                     77:        puffs_cred_getgroups(pcr, groups, &ngroups);
                     78:
                     79:        /* LINTED: ngroups is ok */
                     80:        return rump_cred_create(uid, gid, ngroups, groups);
                     81: }
                     82:
                     83: static __inline void
                     84: cred_destroy(kauth_cred_t cred)
                     85: {
                     86:
1.12      pooka      87:        rump_cred_put(cred);
1.1       pooka      88: }
                     89:
                     90: static struct componentname *
                     91: makecn(const struct puffs_cn *pcn)
                     92: {
                     93:        kauth_cred_t cred;
                     94:
                     95:        cred = cred_create(pcn->pcn_cred);
                     96:        /* LINTED: prehistoric types in first two args */
                     97:        return rump_makecn(pcn->pcn_nameiop, pcn->pcn_flags, pcn->pcn_name,
                     98:            pcn->pcn_namelen, cred, curlwp);
                     99: }
                    100:
                    101: static __inline void
                    102: freecn(struct componentname *cnp, int flags)
                    103: {
                    104:
                    105:        rump_freecn(cnp, flags | RUMPCN_FREECRED);
                    106: }
                    107:
                    108: static void
                    109: makelwp(struct puffs_usermount *pu)
                    110: {
                    111:        pid_t pid;
                    112:        lwpid_t lid;
                    113:
                    114:        puffs_cc_getcaller(puffs_cc_getcc(pu), &pid, &lid);
                    115:        rump_setup_curlwp(pid, lid, 1);
                    116: }
                    117:
                    118: /*ARGSUSED*/
                    119: static void
                    120: clearlwp(struct puffs_usermount *pu)
                    121: {
                    122:
1.4       pooka     123:        /*
                    124:         * XXX: because of the vnode reference counting lossage, we
                    125:         * can't clear the curlwp if we unmounted succesfully.
                    126:         * Therefore, don't do it to avoid a diagnostic panic.
                    127:         * So this currently leaks a process structure in that case,
                    128:         * but since p2k is rarely used multiple times in a single
                    129:         * process, it's more like a feature than a bug (yea, I'm
                    130:         * good at lying to myself).
                    131:         */
                    132:        if (__predict_false(puffs_getstate(pu) != PUFFS_STATE_UNMOUNTED))
                    133:                rump_clear_curlwp();
1.1       pooka     134: }
                    135:
1.11      pooka     136: /*ARGSUSED*/
1.10      pooka     137: static void
                    138: p2k_errcatcher(struct puffs_usermount *pu, uint8_t type, int error,
                    139:        const char *str, puffs_cookie_t cook)
                    140: {
                    141:
                    142:        fprintf(stderr, "type %d, error %d, cookie %p (%s)\n",
                    143:            type, error, cook, str);
                    144:
                    145:        /*
                    146:         * Trap all EINVAL responses to lookup.  It most likely means
                    147:         * that we supplied VNON/VBAD as the type.  The real kernel
                    148:         * doesn't panic from this either, but just handles it.
                    149:         */
                    150:        if (type != PUFFS_VN_LOOKUP && error == EINVAL)
                    151:                abort();
                    152: }
                    153:
1.1       pooka     154: int
                    155: p2k_run_fs(const char *vfsname, const char *devpath, const char *mountpath,
                    156:        int mntflags, void *arg, size_t alen, uint32_t puffs_flags)
                    157: {
                    158:        char typebuf[PUFFS_TYPELEN];
                    159:        struct puffs_ops *pops;
1.7       pooka     160:        struct puffs_usermount *pu = NULL;
1.1       pooka     161:        struct puffs_node *pn_root;
                    162:        struct vnode *rvp;
1.7       pooka     163:        struct ukfs *ukfs = NULL;
1.1       pooka     164:        extern int puffs_fakecc;
1.7       pooka     165:        int rv = -1, sverrno;
1.6       pooka     166:        bool dodaemon;
1.1       pooka     167:
                    168:        PUFFSOP_INIT(pops);
                    169:
                    170:        PUFFSOP_SET(pops, p2k, fs, statvfs);
                    171:        PUFFSOP_SET(pops, p2k, fs, unmount);
                    172:        PUFFSOP_SET(pops, p2k, fs, sync);
                    173:        PUFFSOP_SET(pops, p2k, fs, fhtonode);
                    174:        PUFFSOP_SET(pops, p2k, fs, nodetofh);
                    175:
                    176:        PUFFSOP_SET(pops, p2k, node, lookup);
                    177:        PUFFSOP_SET(pops, p2k, node, create);
                    178:        PUFFSOP_SET(pops, p2k, node, mknod);
                    179:        PUFFSOP_SET(pops, p2k, node, open);
                    180:        PUFFSOP_SET(pops, p2k, node, close);
                    181:        PUFFSOP_SET(pops, p2k, node, access);
                    182:        PUFFSOP_SET(pops, p2k, node, getattr);
                    183:        PUFFSOP_SET(pops, p2k, node, setattr);
                    184: #if 0
                    185:        PUFFSOP_SET(pops, p2k, node, poll);
                    186: #endif
                    187:        PUFFSOP_SET(pops, p2k, node, mmap);
                    188:        PUFFSOP_SET(pops, p2k, node, fsync);
                    189:        PUFFSOP_SET(pops, p2k, node, seek);
                    190:        PUFFSOP_SET(pops, p2k, node, remove);
                    191:        PUFFSOP_SET(pops, p2k, node, link);
                    192:        PUFFSOP_SET(pops, p2k, node, rename);
                    193:        PUFFSOP_SET(pops, p2k, node, mkdir);
                    194:        PUFFSOP_SET(pops, p2k, node, rmdir);
                    195:        PUFFSOP_SET(pops, p2k, node, symlink);
                    196:        PUFFSOP_SET(pops, p2k, node, readdir);
                    197:        PUFFSOP_SET(pops, p2k, node, readlink);
                    198:        PUFFSOP_SET(pops, p2k, node, read);
                    199:        PUFFSOP_SET(pops, p2k, node, write);
                    200:
                    201:        PUFFSOP_SET(pops, p2k, node, inactive);
                    202:        PUFFSOP_SET(pops, p2k, node, reclaim);
                    203:
1.6       pooka     204:        dodaemon = true;
                    205:        if (getenv("P2K_DEBUG") != NULL) {
                    206:                puffs_flags |= PUFFS_FLAG_OPDUMP;
                    207:                dodaemon = false;
                    208:        }
1.8       pooka     209:        if (getenv("P2K_NODETACH") != NULL) {
                    210:                dodaemon = false;
                    211:        }
1.13      pooka     212:        if (getenv("P2K_NOCACHE_PAGE") != NULL) {
                    213:                puffs_flags |= PUFFS_KFLAG_NOCACHE_PAGE;
                    214:        }
                    215:        if (getenv("P2K_NOCACHE_NAME") != NULL) {
                    216:                puffs_flags |= PUFFS_KFLAG_NOCACHE_NAME;
                    217:        }
                    218:        if (getenv("P2K_NOCACHE") != NULL) {
                    219:                puffs_flags |= PUFFS_KFLAG_NOCACHE;
                    220:        }
1.6       pooka     221:
1.1       pooka     222:        strcpy(typebuf, "p2k|");
                    223:        if (strcmp(vfsname, "puffs") == 0) { /* XXX */
                    224:                struct puffs_kargs *args = arg;
                    225:                strlcat(typebuf, args->pa_typename, sizeof(typebuf));
1.6       pooka     226:                dodaemon = false;
1.1       pooka     227:        } else {
                    228:                strlcat(typebuf, vfsname, sizeof(typebuf));
                    229:        }
                    230:
1.7       pooka     231:        pu = puffs_init(pops, devpath, typebuf, NULL, puffs_flags);
1.1       pooka     232:        if (pu == NULL)
                    233:                goto out;
                    234:
1.7       pooka     235:        if (dodaemon)
                    236:                puffs_daemon(pu, 1, 1);
                    237:
                    238:        if (ukfs_init() == -1)
                    239:                return -1;
                    240:        ukfs = ukfs_mount(vfsname, devpath, mountpath, mntflags, arg, alen);
                    241:        if (ukfs == NULL)
                    242:                goto out;
                    243:
1.1       pooka     244:        rvp = ukfs_getrvp(ukfs);
                    245:        pn_root = puffs_pn_new(pu, rvp);
                    246:        puffs_setroot(pu, pn_root);
                    247:        puffs_setfhsize(pu, 0, PUFFS_FHFLAG_PASSTHROUGH);
                    248:        puffs_setstacksize(pu, PUFFS_STACKSIZE_MIN);
                    249:        puffs_fakecc = 1;
                    250:
                    251:        puffs_set_prepost(pu, makelwp, clearlwp);
1.10      pooka     252:        puffs_set_errnotify(pu, p2k_errcatcher);
1.1       pooka     253:
1.7       pooka     254:        puffs_setspecific(pu, ukfs_getmp(ukfs));
1.1       pooka     255:        if ((rv = puffs_mount(pu, mountpath, mntflags, rvp))== -1)
                    256:                goto out;
                    257:        rv = puffs_mainloop(pu);
1.7       pooka     258:        puffs_exit(pu, 1);
                    259:        pu = NULL;
1.1       pooka     260:
                    261:  out:
                    262:        sverrno = errno;
1.7       pooka     263:        if (ukfs)
                    264:                ukfs_release(ukfs, UKFS_RELFLAG_NOUNMOUNT);
                    265:        if (pu)
                    266:                puffs_cancel(pu, sverrno);
1.1       pooka     267:        if (rv) {
                    268:                errno = sverrno;
                    269:                rv = -1;
                    270:        }
                    271:
                    272:        return rv;
                    273: }
                    274:
                    275: /* XXX: vn_lock() */
                    276: #define VLE(a) RUMP_VOP_LOCK(a, LK_EXCLUSIVE)
                    277: #define VLS(a) RUMP_VOP_LOCK(a, LK_SHARED)
                    278: #define VUL(a) RUMP_VOP_UNLOCK(a, 0);
                    279: #define AUL(a) assert(RUMP_VOP_ISLOCKED(a) == 0)
                    280:
                    281: int
                    282: p2k_fs_statvfs(struct puffs_usermount *pu, struct statvfs *sbp)
                    283: {
                    284:        struct mount *mp = puffs_getspecific(pu);
                    285:
                    286:        return rump_vfs_statvfs(mp, sbp);
                    287: }
                    288:
                    289: int
                    290: p2k_fs_unmount(struct puffs_usermount *pu, int flags)
                    291: {
                    292:        struct mount *mp = puffs_getspecific(pu);
                    293:        struct puffs_node *pn_root = puffs_getroot(pu);
                    294:        struct vnode *rvp = pn_root->pn_data, *rvp2;
                    295:        int rv;
                    296:
                    297:        /*
                    298:         * We recycle the root node already here (god knows how
                    299:         * many references it has due to lookup).  This is good
                    300:         * because VFS_UNMOUNT would do it anyway.  But it is
                    301:         * very bad if VFS_UNMOUNT fails for a reason or another
                    302:         * (puffs guards against busy fs, but there might be other
                    303:         * reasons).
                    304:         *
                    305:         * Theoretically we're going south, sinking fast & dying
                    306:         * out here because the old vnode will be freed and we are
                    307:         * unlikely to get a vnode at the same address.  But try
                    308:         * anyway.
                    309:         *
                    310:         * XXX: reallyfixmesomeday.  either introduce VFS_ROOT to
                    311:         * puffs (blah) or check the cookie in every routine
                    312:         * against the root cookie, which might change (blah2).
                    313:         */
                    314:        rump_vp_recycle_nokidding(rvp);
                    315:        rv = rump_vfs_unmount(mp, flags);
                    316:        if (rv) {
                    317:                int rv2;
                    318:
                    319:                rv2 = rump_vfs_root(mp, &rvp2, 0);
                    320:                assert(rv2 == 0 && rvp == rvp2);
                    321:        }
                    322:        return rv;
                    323: }
                    324:
                    325: int
                    326: p2k_fs_sync(struct puffs_usermount *pu, int waitfor,
                    327:        const struct puffs_cred *pcr)
                    328: {
                    329:        struct mount *mp = puffs_getspecific(pu);
                    330:        kauth_cred_t cred;
                    331:        int rv;
                    332:
                    333:        cred = cred_create(pcr);
                    334:        rv = rump_vfs_sync(mp, waitfor, (kauth_cred_t)cred);
                    335:        cred_destroy(cred);
                    336:
                    337:        return rv;
                    338: }
                    339:
                    340: /*ARGSUSED*/
                    341: int
                    342: p2k_fs_fhtonode(struct puffs_usermount *pu, void *fid, size_t fidsize,
                    343:        struct puffs_newinfo *pni)
                    344: {
                    345:        struct mount *mp = puffs_getspecific(pu);
                    346:        struct vnode *vp;
                    347:        enum vtype vtype;
                    348:        voff_t vsize;
1.14    ! pooka     349:        uint64_t rdev; /* XXX: uint64_t because of stack overwrite in compat */
1.1       pooka     350:        int rv;
                    351:
                    352:        rv = rump_vfs_fhtovp(mp, fid, &vp);
                    353:        if (rv)
                    354:                return rv;
                    355:
                    356:        puffs_newinfo_setcookie(pni, vp);
1.14    ! pooka     357:        rump_getvninfo(vp, &vtype, &vsize, (void *)&rdev);
1.1       pooka     358:        puffs_newinfo_setvtype(pni, vtype);
                    359:        puffs_newinfo_setsize(pni, vsize);
                    360:        puffs_newinfo_setrdev(pni, rdev);
                    361:
                    362:        return 0;
                    363: }
                    364:
                    365: /*ARGSUSED*/
                    366: int
1.3       pooka     367: p2k_fs_nodetofh(struct puffs_usermount *pu, puffs_cookie_t cookie, void *fid,
1.1       pooka     368:        size_t *fidsize)
                    369: {
                    370:        struct vnode *vp = cookie;
                    371:
                    372:        return rump_vfs_vptofh(vp, fid, fidsize);
                    373: }
                    374:
                    375: /*ARGSUSED*/
                    376: int
1.3       pooka     377: p2k_node_lookup(struct puffs_usermount *pu, puffs_cookie_t opc,
1.1       pooka     378:        struct puffs_newinfo *pni, const struct puffs_cn *pcn)
                    379: {
                    380:        struct componentname *cn;
                    381:        struct vnode *vp;
                    382:        enum vtype vtype;
                    383:        voff_t vsize;
1.14    ! pooka     384:        uint64_t rdev; /* XXX: uint64_t because of stack overwrite in compat */
1.1       pooka     385:        int rv;
                    386:
                    387:        cn = makecn(pcn);
                    388:        VLE(opc);
                    389:        rv = RUMP_VOP_LOOKUP(opc, &vp, cn);
                    390:        VUL(opc);
                    391:        freecn(cn, RUMPCN_ISLOOKUP);
                    392:        if (rv) {
                    393:                if (rv == EJUSTRETURN)
                    394:                        rv = ENOENT;
                    395:                return rv;
                    396:        }
                    397:        VUL(vp);
                    398:
                    399:        puffs_newinfo_setcookie(pni, vp);
1.14    ! pooka     400:        rump_getvninfo(vp, &vtype, &vsize, (void *)&rdev);
1.1       pooka     401:        puffs_newinfo_setvtype(pni, vtype);
                    402:        puffs_newinfo_setsize(pni, vsize);
                    403:        puffs_newinfo_setrdev(pni, rdev);
                    404:
                    405:        return 0;
                    406: }
                    407:
1.14    ! pooka     408: #define VERS_TIMECHANGE 599000700
        !           409: static int
        !           410: needcompat(void)
        !           411: {
        !           412:
        !           413:        return __NetBSD_Version__ < VERS_TIMECHANGE
        !           414:            && rump_getversion() >= VERS_TIMECHANGE;
        !           415: }
        !           416:
        !           417: #define DOCOMPAT(va, va_compat)                                                \
        !           418: do {                                                                   \
        !           419:        if (needcompat()) {                                             \
        !           420:                va_compat = rump_vattr_init();                          \
        !           421:                rump_vattr50_to_vattr(va, va_compat);                   \
        !           422:        } else {                                                        \
        !           423:                va_compat = __UNCONST(va);                              \
        !           424:        }                                                               \
        !           425: } while (/*CONSTCOND*/0)
        !           426:
        !           427: #define UNDOCOMPAT(va_compat)                                          \
        !           428: do {                                                                   \
        !           429:        if (needcompat())                                               \
        !           430:                rump_vattr_free(va_compat);                             \
        !           431: } while (/*CONSTCOND*/0)
        !           432:
1.1       pooka     433: /*ARGSUSED*/
                    434: int
1.3       pooka     435: p2k_node_create(struct puffs_usermount *pu, puffs_cookie_t opc,
1.1       pooka     436:        struct puffs_newinfo *pni, const struct puffs_cn *pcn,
                    437:        const struct vattr *vap)
                    438: {
                    439:        struct componentname *cn;
1.14    ! pooka     440:        struct vattr *va_x;
1.1       pooka     441:        struct vnode *vp;
                    442:        int rv;
                    443:
1.14    ! pooka     444:        DOCOMPAT(vap, va_x);
        !           445:
1.1       pooka     446:        cn = makecn(pcn);
                    447:        VLE(opc);
                    448:        rump_vp_incref(opc);
1.14    ! pooka     449:        rv = RUMP_VOP_CREATE(opc, &vp, cn, va_x);
1.1       pooka     450:        AUL(opc);
                    451:        freecn(cn, 0);
                    452:        if (rv == 0) {
                    453:                VUL(vp);
                    454:                puffs_newinfo_setcookie(pni, vp);
                    455:        }
                    456:
1.14    ! pooka     457:        UNDOCOMPAT(va_x);
        !           458:
1.1       pooka     459:        return rv;
                    460: }
                    461:
                    462: /*ARGSUSED*/
                    463: int
1.3       pooka     464: p2k_node_mknod(struct puffs_usermount *pu, puffs_cookie_t opc,
                    465:        struct puffs_newinfo *pni, const struct puffs_cn *pcn,
                    466:        const struct vattr *vap)
1.1       pooka     467: {
                    468:        struct componentname *cn;
1.14    ! pooka     469:        struct vattr *va_x;
1.1       pooka     470:        struct vnode *vp;
                    471:        int rv;
                    472:
1.14    ! pooka     473:        DOCOMPAT(vap, va_x);
        !           474:
1.1       pooka     475:        cn = makecn(pcn);
                    476:        VLE(opc);
                    477:        rump_vp_incref(opc);
1.14    ! pooka     478:        rv = RUMP_VOP_MKNOD(opc, &vp, cn, va_x);
1.1       pooka     479:        AUL(opc);
                    480:        freecn(cn, 0);
                    481:        if (rv == 0) {
                    482:                VUL(vp);
                    483:                puffs_newinfo_setcookie(pni, vp);
                    484:        }
                    485:
1.14    ! pooka     486:        UNDOCOMPAT(va_x);
        !           487:
1.1       pooka     488:        return rv;
                    489: }
                    490:
                    491: /*ARGSUSED*/
                    492: int
1.3       pooka     493: p2k_node_open(struct puffs_usermount *pu, puffs_cookie_t opc, int mode,
1.1       pooka     494:        const struct puffs_cred *pcr)
                    495: {
                    496:        kauth_cred_t cred;
                    497:        int rv;
                    498:
                    499:        cred = cred_create(pcr);
                    500:        VLE(opc);
                    501:        rv = RUMP_VOP_OPEN(opc, mode, cred);
                    502:        VUL(opc);
                    503:        cred_destroy(cred);
                    504:
                    505:        return rv;
                    506: }
                    507:
                    508: /*ARGSUSED*/
                    509: int
1.3       pooka     510: p2k_node_close(struct puffs_usermount *pu, puffs_cookie_t opc, int flags,
1.1       pooka     511:        const struct puffs_cred *pcr)
                    512: {
                    513:        kauth_cred_t cred;
                    514:
                    515:        cred = cred_create(pcr);
                    516:        VLE(opc);
                    517:        RUMP_VOP_CLOSE(opc, flags, cred);
                    518:        VUL(opc);
                    519:        cred_destroy(cred);
                    520:
                    521:        return 0;
                    522: }
                    523:
                    524: /*ARGSUSED*/
                    525: int
1.3       pooka     526: p2k_node_access(struct puffs_usermount *pu, puffs_cookie_t opc, int mode,
1.1       pooka     527:        const struct puffs_cred *pcr)
                    528: {
                    529:        kauth_cred_t cred;
                    530:        int rv;
                    531:
                    532:        cred = cred_create(pcr);
                    533:        VLE(opc);
                    534:        rv = RUMP_VOP_ACCESS(opc, mode, cred);
                    535:        VUL(opc);
                    536:        cred_destroy(cred);
                    537:
                    538:        return rv;
                    539: }
                    540:
                    541: /*ARGSUSED*/
                    542: int
1.3       pooka     543: p2k_node_getattr(struct puffs_usermount *pu, puffs_cookie_t opc,
                    544:        struct vattr *vap, const struct puffs_cred *pcr)
1.1       pooka     545: {
                    546:        kauth_cred_t cred;
1.14    ! pooka     547:        struct vattr *va_x;
1.1       pooka     548:        int rv;
                    549:
1.14    ! pooka     550:        if (needcompat()) {
        !           551:                va_x = rump_vattr_init();
        !           552:        } else {
        !           553:                va_x = vap;
        !           554:        }
        !           555:
1.1       pooka     556:        cred = cred_create(pcr);
                    557:        VLE(opc);
1.14    ! pooka     558:        rv = RUMP_VOP_GETATTR(opc, va_x, cred);
1.1       pooka     559:        VUL(opc);
                    560:        cred_destroy(cred);
                    561:
1.14    ! pooka     562:        if (needcompat()) {
        !           563:                rump_vattr_to_vattr50(va_x, vap);
        !           564:                rump_vattr_free(va_x);
        !           565:        }
        !           566:
1.1       pooka     567:        return rv;
                    568: }
                    569:
                    570: /*ARGSUSED*/
                    571: int
1.3       pooka     572: p2k_node_setattr(struct puffs_usermount *pu, puffs_cookie_t opc,
                    573:        const struct vattr *vap, const struct puffs_cred *pcr)
1.1       pooka     574: {
                    575:        kauth_cred_t cred;
1.14    ! pooka     576:        struct vattr *va_x;
1.1       pooka     577:        int rv;
                    578:
1.14    ! pooka     579:        DOCOMPAT(vap, va_x);
        !           580:
1.1       pooka     581:        cred = cred_create(pcr);
                    582:        VLE(opc);
1.14    ! pooka     583:        rv = RUMP_VOP_SETATTR(opc, va_x, cred);
1.1       pooka     584:        VUL(opc);
                    585:        cred_destroy(cred);
                    586:
1.14    ! pooka     587:        UNDOCOMPAT(va_x);
        !           588:
1.1       pooka     589:        return rv;
                    590: }
                    591:
                    592: /*ARGSUSED*/
                    593: int
1.3       pooka     594: p2k_node_fsync(struct puffs_usermount *pu, puffs_cookie_t opc,
1.1       pooka     595:        const struct puffs_cred *pcr, int flags, off_t offlo, off_t offhi)
                    596: {
                    597:        kauth_cred_t cred;
                    598:        int rv;
                    599:
                    600:        cred = cred_create(pcr);
                    601:        VLE(opc);
                    602:        rv = RUMP_VOP_FSYNC(opc, cred, flags, offlo, offhi);
                    603:        VUL(opc);
                    604:        cred_destroy(cred);
                    605:
                    606:        return rv;
                    607: }
                    608:
                    609: /*ARGSUSED*/
                    610: int
1.3       pooka     611: p2k_node_mmap(struct puffs_usermount *pu, puffs_cookie_t opc, vm_prot_t flags,
1.1       pooka     612:        const struct puffs_cred *pcr)
                    613: {
                    614:        kauth_cred_t cred;
                    615:        int rv;
                    616:
                    617:        cred = cred_create(pcr);
                    618:        rv = RUMP_VOP_MMAP(opc, flags, cred);
                    619:        cred_destroy(cred);
                    620:
                    621:        return rv;
                    622: }
                    623:
                    624: /*ARGSUSED*/
                    625: int
1.3       pooka     626: p2k_node_seek(struct puffs_usermount *pu, puffs_cookie_t opc,
                    627:        off_t oldoff, off_t newoff, const struct puffs_cred *pcr)
1.1       pooka     628: {
                    629:        kauth_cred_t cred;
                    630:        int rv;
                    631:
                    632:        cred = cred_create(pcr);
                    633:        VLE(opc);
                    634:        rv = RUMP_VOP_SEEK(opc, oldoff, newoff, cred);
                    635:        VUL(opc);
                    636:        cred_destroy(cred);
                    637:
                    638:        return rv;
                    639: }
                    640:
                    641: /*ARGSUSED*/
                    642: int
1.3       pooka     643: p2k_node_remove(struct puffs_usermount *pu, puffs_cookie_t opc,
                    644:        puffs_cookie_t targ, const struct puffs_cn *pcn)
1.1       pooka     645: {
                    646:        struct componentname *cn;
                    647:        int rv;
                    648:
                    649:        cn = makecn(pcn);
                    650:        VLE(opc);
                    651:        rump_vp_incref(opc);
                    652:        VLE(targ);
                    653:        rump_vp_incref(targ);
                    654:        rv = RUMP_VOP_REMOVE(opc, targ, cn);
                    655:        AUL(opc);
                    656:        AUL(targ);
                    657:        freecn(cn, 0);
                    658:
                    659:        return rv;
                    660: }
                    661:
                    662: /*ARGSUSED*/
                    663: int
1.3       pooka     664: p2k_node_link(struct puffs_usermount *pu, puffs_cookie_t opc,
                    665:        puffs_cookie_t targ, const struct puffs_cn *pcn)
1.1       pooka     666: {
                    667:        struct componentname *cn;
                    668:        int rv;
                    669:
                    670:        cn = makecn(pcn);
                    671:        VLE(opc);
                    672:        rump_vp_incref(opc);
                    673:        rv = RUMP_VOP_LINK(opc, targ, cn);
                    674:        freecn(cn, 0);
                    675:
                    676:        return rv;
                    677: }
                    678:
                    679: /*ARGSUSED*/
                    680: int
1.3       pooka     681: p2k_node_rename(struct puffs_usermount *pu,
                    682:        puffs_cookie_t src_dir, puffs_cookie_t src,
                    683:        const struct puffs_cn *pcn_src,
                    684:        puffs_cookie_t targ_dir, puffs_cookie_t targ,
1.1       pooka     685:        const struct puffs_cn *pcn_targ)
                    686: {
                    687:        struct componentname *cn_src, *cn_targ;
                    688:        int rv;
                    689:
                    690:        cn_src = makecn(pcn_src);
                    691:        cn_targ = makecn(pcn_targ);
                    692:        rump_vp_incref(src_dir);
                    693:        rump_vp_incref(src);
                    694:        VLE(targ_dir);
                    695:        rump_vp_incref(targ_dir);
                    696:        if (targ) {
                    697:                VLE(targ);
                    698:                rump_vp_incref(targ);
                    699:        }
                    700:        rv = RUMP_VOP_RENAME(src_dir, src, cn_src, targ_dir, targ, cn_targ);
                    701:        AUL(targ_dir);
                    702:        if (targ)
                    703:                AUL(targ);
                    704:        freecn(cn_src, 0);
                    705:        freecn(cn_targ, 0);
                    706:
                    707:        return rv;
                    708: }
                    709:
                    710: /*ARGSUSED*/
                    711: int
1.3       pooka     712: p2k_node_mkdir(struct puffs_usermount *pu, puffs_cookie_t opc,
                    713:        struct puffs_newinfo *pni, const struct puffs_cn *pcn,
                    714:        const struct vattr *vap)
1.1       pooka     715: {
                    716:        struct componentname *cn;
1.14    ! pooka     717:        struct vattr *va_x;
1.1       pooka     718:        struct vnode *vp;
                    719:        int rv;
                    720:
1.14    ! pooka     721:        DOCOMPAT(vap, va_x);
        !           722:
1.1       pooka     723:        cn = makecn(pcn);
                    724:        VLE(opc);
                    725:        rump_vp_incref(opc);
1.14    ! pooka     726:        rv = RUMP_VOP_MKDIR(opc, &vp, cn, va_x);
1.1       pooka     727:        AUL(opc);
                    728:        freecn(cn, 0);
                    729:        if (rv == 0) {
                    730:                VUL(vp);
                    731:                puffs_newinfo_setcookie(pni, vp);
                    732:        }
                    733:
1.14    ! pooka     734:        UNDOCOMPAT(va_x);
        !           735:
1.1       pooka     736:        return rv;
                    737: }
                    738:
                    739: /*ARGSUSED*/
                    740: int
1.3       pooka     741: p2k_node_rmdir(struct puffs_usermount *pu, puffs_cookie_t opc,
                    742:        puffs_cookie_t targ, const struct puffs_cn *pcn)
1.1       pooka     743: {
                    744:        struct componentname *cn;
                    745:        int rv;
                    746:
                    747:        cn = makecn(pcn);
                    748:        VLE(opc);
                    749:        rump_vp_incref(opc);
                    750:        VLE(targ);
                    751:        rump_vp_incref(targ);
                    752:        rv = RUMP_VOP_RMDIR(opc, targ, cn);
                    753:        AUL(targ);
                    754:        AUL(opc);
                    755:        freecn(cn, 0);
                    756:
                    757:        return rv;
                    758: }
                    759:
                    760: /*ARGSUSED*/
                    761: int
1.3       pooka     762: p2k_node_symlink(struct puffs_usermount *pu, puffs_cookie_t opc,
1.1       pooka     763:        struct puffs_newinfo *pni, const struct puffs_cn *pcn_src,
                    764:        const struct vattr *vap, const char *link_target)
                    765: {
                    766:        struct componentname *cn;
1.14    ! pooka     767:        struct vattr *va_x;
1.1       pooka     768:        struct vnode *vp;
                    769:        int rv;
                    770:
1.14    ! pooka     771:        DOCOMPAT(vap, va_x);
        !           772:
1.1       pooka     773:        cn = makecn(pcn_src);
                    774:        VLE(opc);
                    775:        rump_vp_incref(opc);
1.14    ! pooka     776:        rv = RUMP_VOP_SYMLINK(opc, &vp, cn, va_x, __UNCONST(link_target));
1.1       pooka     777:        AUL(opc);
                    778:        freecn(cn, 0);
                    779:        if (rv == 0) {
                    780:                VUL(vp);
                    781:                puffs_newinfo_setcookie(pni, vp);
                    782:        }
                    783:
1.14    ! pooka     784:        UNDOCOMPAT(va_x);
        !           785:
1.1       pooka     786:        return rv;
                    787: }
                    788:
                    789: /*ARGSUSED*/
                    790: int
1.3       pooka     791: p2k_node_readdir(struct puffs_usermount *pu, puffs_cookie_t opc,
                    792:        struct dirent *dent, off_t *readoff, size_t *reslen,
                    793:        const struct puffs_cred *pcr, int *eofflag,
                    794:        off_t *cookies, size_t *ncookies)
1.1       pooka     795: {
                    796:        kauth_cred_t cred;
                    797:        struct uio *uio;
                    798:        off_t *vop_cookies;
                    799:        int vop_ncookies;
                    800:        int rv;
                    801:
                    802:        cred = cred_create(pcr);
                    803:        uio = rump_uio_setup(dent, *reslen, *readoff, RUMPUIO_READ);
                    804:        VLS(opc);
                    805:        if (cookies) {
                    806:                rv = RUMP_VOP_READDIR(opc, uio, cred, eofflag,
                    807:                    &vop_cookies, &vop_ncookies);
                    808:                memcpy(cookies, vop_cookies, vop_ncookies * sizeof(*cookies));
                    809:                *ncookies = vop_ncookies;
                    810:                free(vop_cookies);
                    811:        } else {
                    812:                rv = RUMP_VOP_READDIR(opc, uio, cred, eofflag, NULL, NULL);
                    813:        }
                    814:        VUL(opc);
                    815:        if (rv == 0) {
                    816:                *reslen = rump_uio_getresid(uio);
                    817:                *readoff = rump_uio_getoff(uio);
                    818:        }
                    819:        rump_uio_free(uio);
                    820:        cred_destroy(cred);
                    821:
                    822:        return rv;
                    823: }
                    824:
                    825: /*ARGSUSED*/
                    826: int
1.3       pooka     827: p2k_node_readlink(struct puffs_usermount *pu, puffs_cookie_t opc,
1.1       pooka     828:        const struct puffs_cred *pcr, char *linkname, size_t *linklen)
                    829: {
                    830:        kauth_cred_t cred;
                    831:        struct uio *uio;
                    832:        int rv;
                    833:
                    834:        cred = cred_create(pcr);
                    835:        uio = rump_uio_setup(linkname, *linklen, 0, RUMPUIO_READ);
                    836:        VLE(opc);
                    837:        rv = RUMP_VOP_READLINK(opc, uio, cred);
                    838:        VUL(opc);
                    839:        *linklen -= rump_uio_free(uio);
                    840:        cred_destroy(cred);
                    841:
                    842:        return rv;
                    843: }
                    844:
                    845: /*ARGSUSED*/
                    846: int
1.3       pooka     847: p2k_node_read(struct puffs_usermount *pu, puffs_cookie_t opc,
1.1       pooka     848:        uint8_t *buf, off_t offset, size_t *resid,
                    849:        const struct puffs_cred *pcr, int ioflag)
                    850: {
                    851:        kauth_cred_t cred;
                    852:        struct uio *uio;
                    853:        int rv;
                    854:
                    855:        cred = cred_create(pcr);
                    856:        uio = rump_uio_setup(buf, *resid, offset, RUMPUIO_READ);
                    857:        VLS(opc);
                    858:        rv = RUMP_VOP_READ(opc, uio, ioflag, cred);
                    859:        VUL(opc);
                    860:        *resid = rump_uio_free(uio);
                    861:        cred_destroy(cred);
                    862:
                    863:        return rv;
                    864: }
                    865:
                    866: /*ARGSUSED*/
                    867: int
1.3       pooka     868: p2k_node_write(struct puffs_usermount *pu, puffs_cookie_t opc,
1.1       pooka     869:        uint8_t *buf, off_t offset, size_t *resid,
                    870:        const struct puffs_cred *pcr, int ioflag)
                    871: {
                    872:        kauth_cred_t cred;
                    873:        struct uio *uio;
                    874:        int rv;
                    875:
                    876:        cred = cred_create(pcr);
                    877:        uio = rump_uio_setup(buf, *resid, offset, RUMPUIO_WRITE);
                    878:        VLE(opc);
                    879:        rv = RUMP_VOP_WRITE(opc, uio, ioflag, cred);
                    880:        VUL(opc);
                    881:        *resid = rump_uio_free(uio);
                    882:        cred_destroy(cred);
                    883:
                    884:        return rv;
                    885: }
                    886:
                    887: int
1.3       pooka     888: p2k_node_inactive(struct puffs_usermount *pu, puffs_cookie_t opc)
1.1       pooka     889: {
                    890:        struct vnode *vp = opc;
                    891:        bool recycle;
                    892:        int rv;
                    893:
                    894:        rump_vp_interlock(vp);
                    895:        (void) RUMP_VOP_PUTPAGES(vp, 0, 0, PGO_ALLPAGES);
                    896:        VLE(vp);
                    897:        rv = RUMP_VOP_INACTIVE(vp, &recycle);
                    898:        if (recycle)
                    899:                puffs_setback(puffs_cc_getcc(pu), PUFFS_SETBACK_NOREF_N1);
                    900:
                    901:        return rv;
                    902: }
                    903:
                    904: /*ARGSUSED*/
                    905: int
1.3       pooka     906: p2k_node_reclaim(struct puffs_usermount *pu, puffs_croissant_t opc)
1.1       pooka     907: {
                    908:
                    909:        rump_vp_recycle_nokidding(opc);
                    910:        return 0;
                    911: }

CVSweb <webmaster@jp.NetBSD.org>