[BACK]Return to puffs_vfsops.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / fs / puffs

Annotation of src/sys/fs/puffs/puffs_vfsops.c, Revision 1.25

1.25    ! pooka       1: /*     $NetBSD: puffs_vfsops.c,v 1.24 2007/01/23 18:27:50 pooka Exp $  */
1.1       pooka       2:
                      3: /*
                      4:  * Copyright (c) 2005, 2006  Antti Kantee.  All Rights Reserved.
                      5:  *
                      6:  * Development of this software was supported by the
                      7:  * Google Summer of Code program and the Ulla Tuominen Foundation.
                      8:  * The Google SoC project was mentored by Bill Studenmund.
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  * 3. The name of the company nor the name of the author may be used to
                     19:  *    endorse or promote products derived from this software without specific
                     20:  *    prior written permission.
                     21:  *
                     22:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
                     23:  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     24:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
                     25:  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
                     26:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     27:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
                     28:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     29:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     30:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     31:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     32:  * SUCH DAMAGE.
                     33:  */
                     34:
                     35: #include <sys/cdefs.h>
1.25    ! pooka      36: __KERNEL_RCSID(0, "$NetBSD: puffs_vfsops.c,v 1.24 2007/01/23 18:27:50 pooka Exp $");
1.1       pooka      37:
                     38: #include <sys/param.h>
                     39: #include <sys/mount.h>
                     40: #include <sys/malloc.h>
                     41: #include <sys/extattr.h>
                     42: #include <sys/queue.h>
                     43: #include <sys/vnode.h>
                     44: #include <sys/dirent.h>
                     45: #include <sys/kauth.h>
                     46:
                     47: #include <lib/libkern/libkern.h>
                     48:
                     49: #include <fs/puffs/puffs_msgif.h>
                     50: #include <fs/puffs/puffs_sys.h>
                     51:
                     52: VFS_PROTOS(puffs);
                     53:
                     54: MALLOC_DEFINE(M_PUFFS, "puffs", "pass-to-userspace file system structures");
                     55:
1.22      pooka      56: #ifndef PUFFS_PNODEBUCKETS
                     57: #define PUFFS_PNODEBUCKETS 256
                     58: #endif
                     59: #ifndef PUFFS_MAXPNODEBUCKETS
                     60: #define PUFFS_MAXPNODEBUCKETS 65536
                     61: #endif
                     62: int puffs_pnodebuckets = PUFFS_PNODEBUCKETS;
                     63:
1.1       pooka      64: int
                     65: puffs_mount(struct mount *mp, const char *path, void *data,
                     66:            struct nameidata *ndp, struct lwp *l)
                     67: {
1.22      pooka      68:        struct puffs_mount *pmp = NULL;
1.17      pooka      69:        struct puffs_args *args;
                     70:        char namebuf[PUFFSNAMESIZE+sizeof(PUFFS_NAMEPREFIX)+1]; /* spooky */
1.22      pooka      71:        int error = 0, i;
1.1       pooka      72:
                     73:        if (mp->mnt_flag & MNT_GETARGS) {
                     74:                pmp = MPTOPUFFSMP(mp);
                     75:                return copyout(&pmp->pmp_args, data, sizeof(struct puffs_args));
                     76:        }
                     77:
                     78:        /* update is not supported currently */
                     79:        if (mp->mnt_flag & MNT_UPDATE)
                     80:                return EOPNOTSUPP;
                     81:
                     82:        /*
                     83:         * We need the file system name
                     84:         */
                     85:        if (!data)
                     86:                return EINVAL;
                     87:
1.17      pooka      88:        MALLOC(args, struct puffs_args *, sizeof(struct puffs_args),
                     89:            M_PUFFS, M_WAITOK);
                     90:
                     91:        error = copyin(data, args, sizeof(struct puffs_args));
1.1       pooka      92:        if (error)
1.17      pooka      93:                goto out;
                     94:
                     95:        /* devel phase */
                     96:        if (args->pa_vers != (PUFFSVERSION | PUFFSDEVELVERS)) {
                     97:                printf("puffs_mount: development version mismatch\n");
                     98:                error = EINVAL;
                     99:                goto out;
                    100:        }
1.1       pooka     101:
1.8       pooka     102:        /* nuke spy bits */
1.17      pooka     103:        args->pa_flags &= PUFFS_KFLAG_MASK;
1.8       pooka     104:
1.1       pooka     105:        /* build real name */
1.17      pooka     106:        (void)strlcpy(namebuf, PUFFS_NAMEPREFIX, sizeof(namebuf));
                    107:        (void)strlcat(namebuf, args->pa_name, sizeof(namebuf));
1.1       pooka     108:
                    109:        /* inform user server if it got the max request size it wanted */
1.17      pooka     110:        if (args->pa_maxreqlen == 0 || args->pa_maxreqlen > PUFFS_REQ_MAXSIZE)
                    111:                args->pa_maxreqlen = PUFFS_REQ_MAXSIZE;
                    112:        else if (args->pa_maxreqlen < PUFFS_REQSTRUCT_MAX)
                    113:                args->pa_maxreqlen = PUFFS_REQSTRUCT_MAX;
                    114:        (void)strlcpy(args->pa_name, namebuf, sizeof(args->pa_name));
1.1       pooka     115:
1.17      pooka     116:        error = copyout(args, data, sizeof(struct puffs_args));
1.1       pooka     117:        if (error)
1.17      pooka     118:                goto out;
1.1       pooka     119:
                    120:        error = set_statvfs_info(path, UIO_USERSPACE, namebuf,
                    121:            UIO_SYSSPACE, mp, l);
                    122:        if (error)
1.17      pooka     123:                goto out;
1.10      pooka     124:        mp->mnt_stat.f_iosize = DEV_BSIZE;
1.1       pooka     125:
                    126:        MALLOC(pmp, struct puffs_mount *, sizeof(struct puffs_mount),
                    127:            M_PUFFS, M_WAITOK | M_ZERO);
                    128:
1.6       pooka     129:        mp->mnt_fs_bshift = DEV_BSHIFT;
                    130:        mp->mnt_dev_bshift = DEV_BSHIFT;
                    131:        mp->mnt_flag &= ~MNT_LOCAL; /* we don't really know, so ... */
1.1       pooka     132:        mp->mnt_data = pmp;
1.6       pooka     133:
1.1       pooka     134:        pmp->pmp_status = PUFFSTAT_MOUNTING;
                    135:        pmp->pmp_nextreq = 0;
                    136:        pmp->pmp_mp = mp;
1.17      pooka     137:        pmp->pmp_req_maxsize = args->pa_maxreqlen;
                    138:        pmp->pmp_args = *args;
1.1       pooka     139:
1.22      pooka     140:        /* puffs_node hash buckets */
                    141:        pmp->pmp_npnodehash = puffs_pnodebuckets;
                    142:        if (pmp->pmp_npnodehash < 1)
                    143:                pmp->pmp_npnodehash = 1;
                    144:        if (pmp->pmp_npnodehash > PUFFS_MAXPNODEBUCKETS)
                    145:                pmp->pmp_npnodehash = PUFFS_MAXPNODEBUCKETS;
                    146:        pmp->pmp_pnodehash = malloc
                    147:            (sizeof(struct puffs_pnode_hashlist *) * pmp->pmp_npnodehash,
                    148:            M_PUFFS, M_WAITOK);
                    149:        for (i = 0; i < pmp->pmp_npnodehash; i++)
                    150:                LIST_INIT(&pmp->pmp_pnodehash[i]);
                    151:
1.1       pooka     152:        /*
                    153:         * Inform the fileops processing code that we have a mountpoint.
                    154:         * If it doesn't know about anyone with our pid/fd having the
                    155:         * device open, punt
                    156:         */
1.17      pooka     157:        if (puffs_setpmp(l->l_proc->p_pid, args->pa_fd, pmp)) {
                    158:                error = ENOENT;
                    159:                goto out;
1.1       pooka     160:        }
                    161:
                    162:        simple_lock_init(&pmp->pmp_lock);
                    163:        TAILQ_INIT(&pmp->pmp_req_touser);
                    164:        TAILQ_INIT(&pmp->pmp_req_replywait);
                    165:        TAILQ_INIT(&pmp->pmp_req_sizepark);
                    166:
                    167:        DPRINTF(("puffs_mount: mount point at %p, puffs specific at %p\n",
                    168:            mp, MPTOPUFFSMP(mp)));
                    169:
                    170:        vfs_getnewfsid(mp);
                    171:
1.17      pooka     172:  out:
1.22      pooka     173:        if (error && pmp && pmp->pmp_pnodehash)
                    174:                free(pmp->pmp_pnodehash, M_PUFFS);
                    175:        if (error && pmp)
                    176:                FREE(pmp, M_PUFFS);
1.17      pooka     177:        FREE(args, M_PUFFS);
                    178:        return error;
1.1       pooka     179: }
                    180:
                    181: /*
                    182:  * This is called from the first "Hello, I'm alive" ioctl
                    183:  * from userspace.
                    184:  */
                    185: int
1.7       pooka     186: puffs_start2(struct puffs_mount *pmp, struct puffs_startreq *sreq)
1.1       pooka     187: {
                    188:        struct puffs_node *pn;
                    189:        struct mount *mp;
                    190:
                    191:        mp = PMPTOMP(pmp);
                    192:
                    193:        simple_lock(&pmp->pmp_lock);
                    194:
                    195:        /*
                    196:         * if someone has issued a VFS_ROOT() already, fill in the
                    197:         * vnode cookie.
                    198:         */
1.2       pooka     199:        pn = NULL;
1.1       pooka     200:        if (pmp->pmp_root) {
                    201:                pn = VPTOPP(pmp->pmp_root);
                    202:                pn->pn_cookie = sreq->psr_cookie;
                    203:        }
                    204:
                    205:        /* We're good to fly */
                    206:        pmp->pmp_rootcookie = sreq->psr_cookie;
                    207:        pmp->pmp_status = PUFFSTAT_RUNNING;
1.9       pooka     208:        simple_unlock(&pmp->pmp_lock);
1.1       pooka     209:
1.9       pooka     210:        /* do the VFS_STATVFS() we missed out on in sys_mount() */
                    211:        copy_statvfs_info(&sreq->psr_sb, mp);
                    212:        (void)memcpy(&mp->mnt_stat, &sreq->psr_sb, sizeof(mp->mnt_stat));
1.11      pooka     213:        mp->mnt_stat.f_iosize = DEV_BSIZE;
1.1       pooka     214:
1.2       pooka     215:        DPRINTF(("puffs_start2: root vp %p, cur root pnode %p, cookie %p\n",
1.1       pooka     216:            pmp->pmp_root, pn, sreq->psr_cookie));
                    217:
                    218:        return 0;
                    219: }
                    220:
                    221: int
                    222: puffs_start(struct mount *mp, int flags, struct lwp *l)
                    223: {
                    224:
                    225:        /*
                    226:         * This cannot travel to userspace, as this is called from
                    227:         * the kernel context of the process doing mount(2).  But
                    228:         * it's probably a safe bet that the process doing mount(2)
                    229:         * realizes it needs to start the filesystem also...
                    230:         */
                    231:        return 0;
                    232: }
                    233:
                    234: int
                    235: puffs_unmount(struct mount *mp, int mntflags, struct lwp *l)
                    236: {
                    237:        struct puffs_mount *pmp;
                    238:        int error, force;
                    239:
                    240:        PUFFS_VFSREQ(unmount);
                    241:
                    242:        error = 0;
                    243:        force = mntflags & MNT_FORCE;
                    244:        pmp = MPTOPUFFSMP(mp);
                    245:
                    246:        DPRINTF(("puffs_unmount: detach filesystem from vfs, current "
                    247:            "status 0x%x\n", pmp->pmp_status));
                    248:
                    249:        /*
                    250:         * flush all the vnodes.  VOP_RECLAIM() takes care that the
                    251:         * root vnode does not get flushed until unmount.  The
                    252:         * userspace root node cookie is stored in the mount
                    253:         * structure, so we can always re-instantiate a root vnode,
                    254:         * should userspace unmount decide it doesn't want to
                    255:         * cooperate.
                    256:         */
                    257:        error = vflush(mp, NULLVP, force ? FORCECLOSE : 0);
                    258:        if (error)
                    259:                goto out;
                    260:
                    261:        /*
                    262:         * If we are not DYING, we should ask userspace's opinion
                    263:         * about the situation
                    264:         */
1.16      pooka     265:        simple_lock(&pmp->pmp_lock);
1.1       pooka     266:        if (pmp->pmp_status != PUFFSTAT_DYING) {
1.16      pooka     267:                pmp->pmp_unmounting = 1;
                    268:                simple_unlock(&pmp->pmp_lock);
                    269:
1.1       pooka     270:                unmount_arg.pvfsr_flags = mntflags;
                    271:                unmount_arg.pvfsr_pid = puffs_lwp2pid(l);
1.16      pooka     272:
1.1       pooka     273:                error = puffs_vfstouser(pmp, PUFFS_VFS_UNMOUNT,
                    274:                     &unmount_arg, sizeof(unmount_arg));
1.16      pooka     275:                DPRINTF(("puffs_unmount: error %d force %d\n", error, force));
                    276:
                    277:                simple_lock(&pmp->pmp_lock);
                    278:                pmp->pmp_unmounting = 0;
                    279:                wakeup(&pmp->pmp_unmounting);
1.1       pooka     280:        }
                    281:
                    282:        /*
                    283:         * if userspace cooperated or we really need to die,
                    284:         * screw what userland thinks and just die.
                    285:         */
                    286:        if (error == 0 || force) {
                    287:                pmp->pmp_status = PUFFSTAT_DYING;
                    288:                puffs_nukebypmp(pmp);
1.16      pooka     289:                simple_unlock(&pmp->pmp_lock);
1.22      pooka     290:                free(pmp->pmp_pnodehash, M_PUFFS);
1.1       pooka     291:                FREE(pmp, M_PUFFS);
                    292:                error = 0;
1.16      pooka     293:        } else {
                    294:                simple_unlock(&pmp->pmp_lock);
1.1       pooka     295:        }
                    296:
                    297:  out:
1.2       pooka     298:        DPRINTF(("puffs_unmount: return %d\n", error));
1.1       pooka     299:        return error;
                    300: }
                    301:
                    302: /*
                    303:  * This doesn't need to travel to userspace
                    304:  */
                    305: int
                    306: puffs_root(struct mount *mp, struct vnode **vpp)
                    307: {
                    308:        struct puffs_mount *pmp;
                    309:        struct puffs_node *pn;
                    310:        struct vnode *vp;
                    311:
                    312:        pmp = MPTOPUFFSMP(mp);
                    313:
                    314:        /*
                    315:         * pmp_lock must be held if vref()'ing or vrele()'ing the
1.20      pooka     316:         * root vnode.  the latter is controlled by puffs_inactive().
1.1       pooka     317:         */
                    318:        simple_lock(&pmp->pmp_lock);
                    319:        vp = pmp->pmp_root;
                    320:        if (vp) {
1.25    ! pooka     321:                simple_lock(&vp->v_interlock);
        !           322:                simple_unlock(&pmp->pmp_lock);
1.1       pooka     323:                pn = VPTOPP(vp);
1.25    ! pooka     324:                if (vget(vp, LK_EXCLUSIVE | LK_RETRY | LK_INTERLOCK))
1.20      pooka     325:                        goto grabnew;
1.1       pooka     326:                *vpp = vp;
                    327:                return 0;
1.25    ! pooka     328:        } else
        !           329:                simple_unlock(&pmp->pmp_lock);
        !           330:
        !           331:        /* XXX: this is wrong, so FIXME */
1.1       pooka     332:  grabnew:
                    333:
                    334:        /*
                    335:         * So, didn't have the magic root vnode available.
                    336:         * No matter, grab another an stuff it with the cookie.
                    337:         */
1.6       pooka     338:        if (puffs_getvnode(mp, pmp->pmp_rootcookie, VDIR, 0, 0, &vp))
1.1       pooka     339:                panic("sloppy programming");
                    340:
                    341:        simple_lock(&pmp->pmp_lock);
                    342:        /*
                    343:         * check if by mysterious force someone else created a root
                    344:         * vnode while we were executing.
                    345:         */
                    346:        if (pmp->pmp_root) {
                    347:                vref(pmp->pmp_root);
                    348:                simple_unlock(&pmp->pmp_lock);
                    349:                puffs_putvnode(vp);
                    350:                vn_lock(pmp->pmp_root, LK_EXCLUSIVE | LK_RETRY);
                    351:                *vpp = pmp->pmp_root;
                    352:                return 0;
                    353:        }
                    354:
                    355:        /* store cache */
                    356:        vp->v_flag = VROOT;
                    357:        pmp->pmp_root = vp;
                    358:        simple_unlock(&pmp->pmp_lock);
                    359:
                    360:        vn_lock(pmp->pmp_root, LK_EXCLUSIVE | LK_RETRY);
                    361:
                    362:        *vpp = vp;
                    363:        return 0;
                    364: }
                    365:
                    366: int
                    367: puffs_quotactl(struct mount *mp, int cmd, uid_t uid, void *arg, struct lwp *l)
                    368: {
                    369:
                    370:        return EOPNOTSUPP;
                    371: }
                    372:
                    373: int
                    374: puffs_statvfs(struct mount *mp, struct statvfs *sbp, struct lwp *l)
                    375: {
                    376:        struct puffs_vfsreq_statvfs *statvfs_arg; /* too big for stack */
                    377:        struct puffs_mount *pmp;
                    378:        int error = 0;
                    379:
                    380:        pmp = MPTOPUFFSMP(mp);
                    381:
                    382:        /*
                    383:         * If we are mounting, it means that the userspace counterpart
                    384:         * is calling mount(2), but mount(2) also calls statvfs.  So
                    385:         * requesting statvfs from userspace would mean a deadlock.
                    386:         * Compensate.
                    387:         */
                    388:        if (pmp->pmp_status == PUFFSTAT_MOUNTING)
                    389:                return EINPROGRESS;
                    390:
                    391:        /* too big for stack */
                    392:        MALLOC(statvfs_arg, struct puffs_vfsreq_statvfs *,
                    393:            sizeof(struct puffs_vfsreq_statvfs), M_PUFFS, M_WAITOK | M_ZERO);
                    394:        statvfs_arg->pvfsr_pid = puffs_lwp2pid(l);
                    395:
                    396:        error = puffs_vfstouser(pmp, PUFFS_VFS_STATVFS,
                    397:            statvfs_arg, sizeof(*statvfs_arg));
1.11      pooka     398:        statvfs_arg->pvfsr_sb.f_iosize = DEV_BSIZE;
1.10      pooka     399:
1.1       pooka     400:        /*
                    401:         * Try to produce a sensible result even in the event
                    402:         * of userspace error.
                    403:         *
                    404:         * XXX: cache the copy in non-error case
                    405:         */
                    406:        if (!error) {
                    407:                copy_statvfs_info(&statvfs_arg->pvfsr_sb, mp);
                    408:                (void)memcpy(sbp, &statvfs_arg->pvfsr_sb,
                    409:                    sizeof(struct statvfs));
                    410:        } else {
                    411:                copy_statvfs_info(sbp, mp);
                    412:        }
                    413:
                    414:        FREE(statvfs_arg, M_PUFFS);
1.14      pooka     415:        return error;
1.1       pooka     416: }
                    417:
                    418: int
                    419: puffs_sync(struct mount *mp, int waitfor, struct kauth_cred *cred,
                    420:        struct lwp *l)
                    421: {
1.18      pooka     422:        struct vnode *vp, *nvp;
                    423:        int error, rv;
1.21      pooka     424:        int ppflags;
1.1       pooka     425:
                    426:        PUFFS_VFSREQ(sync);
                    427:
1.18      pooka     428:        error = 0;
1.21      pooka     429:        ppflags = PGO_CLEANIT | PGO_ALLPAGES;
                    430:        if (waitfor == MNT_WAIT)
                    431:                ppflags |= PGO_SYNCIO;
1.18      pooka     432:
                    433:        /*
1.24      pooka     434:         * Sync all cached data from regular vnodes (which are not
                    435:         * currently locked, see below).  After this we call VFS_SYNC
                    436:         * for the fs server, which should handle data and metadata for
                    437:         * all the nodes it knows to exist.
1.18      pooka     438:         */
                    439:        simple_lock(&mntvnode_slock);
                    440:  loop:
                    441:        for (vp = TAILQ_FIRST(&mp->mnt_vnodelist); vp; vp = nvp) {
                    442:                /* check if we're on the right list */
                    443:                if (vp->v_mount != mp)
                    444:                        goto loop;
                    445:
                    446:                simple_lock(&vp->v_interlock);
                    447:                nvp = TAILQ_NEXT(vp, v_mntvnodes);
                    448:
1.19      pooka     449:                if (vp->v_type != VREG || UVM_OBJ_IS_CLEAN(&vp->v_uobj)) {
1.18      pooka     450:                        simple_unlock(&vp->v_interlock);
                    451:                        continue;
                    452:                }
                    453:
                    454:                simple_unlock(&mntvnode_slock);
1.21      pooka     455:
                    456:                /*
                    457:                 * Here we try to get a reference to the vnode and to
                    458:                 * lock it.  This is mostly cargo-culted, but I will
                    459:                 * offer an explanation to why I believe this might
                    460:                 * actually do the right thing.
                    461:                 *
                    462:                 * If the vnode is a goner, we quite obviously don't need
                    463:                 * to sync it.
                    464:                 *
                    465:                 * If the vnode was busy, we don't need to sync it because
                    466:                 * this is never called with MNT_WAIT except from
                    467:                 * dounmount(), when we are wait-flushing all the dirty
                    468:                 * vnodes through other routes in any case.  So there,
                    469:                 * sync() doesn't actually sync.  Happy now?
                    470:                 */
1.18      pooka     471:                rv = vget(vp, LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK);
                    472:                if (rv) {
                    473:                        simple_lock(&mntvnode_slock);
                    474:                        if (rv == ENOENT)
                    475:                                goto loop;
                    476:                        continue;
                    477:                }
                    478:
1.21      pooka     479:                simple_lock(&vp->v_interlock);
                    480:                rv = VOP_PUTPAGES(vp, 0, 0, ppflags);
                    481:                if (rv)
1.18      pooka     482:                        error = rv;
                    483:                vput(vp);
                    484:                simple_lock(&mntvnode_slock);
                    485:        }
                    486:        simple_unlock(&mntvnode_slock);
                    487:
                    488:        /* sync fs */
1.1       pooka     489:        sync_arg.pvfsr_waitfor = waitfor;
                    490:        puffs_credcvt(&sync_arg.pvfsr_cred, cred);
                    491:        sync_arg.pvfsr_pid = puffs_lwp2pid(l);
                    492:
1.18      pooka     493:        rv = puffs_vfstouser(MPTOPUFFSMP(mp), PUFFS_VFS_SYNC,
1.1       pooka     494:            &sync_arg, sizeof(sync_arg));
1.18      pooka     495:        if (rv)
                    496:                error = rv;
1.1       pooka     497:
                    498:        return error;
                    499: }
                    500:
                    501: int
                    502: puffs_vget(struct mount *mp, ino_t ino, struct vnode **vpp)
                    503: {
                    504:
                    505:        return EOPNOTSUPP;
                    506: }
                    507:
                    508: #if 0
                    509: /*ARGSUSED*/
                    510: int
                    511: puffs_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp)
                    512: {
                    513:
                    514:        return EOPNOTSUPP;
                    515: }
                    516:
                    517: /*ARGSUSED*/
                    518: int
                    519: puffs_vptofh(struct vnode *vp, struct fid *fhp)
                    520: {
                    521:
                    522:        return EOPNOTSUPP;
                    523: }
                    524: #endif
                    525:
                    526: void
                    527: puffs_init()
                    528: {
                    529:
1.5       pooka     530: #ifdef _LKM
                    531:        malloc_type_attach(M_PUFFS);
                    532:        pool_init(&puffs_pnpool, sizeof(struct puffs_node), 0, 0, 0,
                    533:            "puffspnpl", &pool_allocator_nointr);
                    534: #endif
                    535:
1.1       pooka     536:        return;
                    537: }
                    538:
                    539: void
                    540: puffs_done()
                    541: {
                    542:
1.5       pooka     543: #ifdef _LKM
                    544:        pool_destroy(&puffs_pnpool);
                    545:        malloc_type_detach(M_PUFFS);
                    546: #endif
                    547:
1.1       pooka     548:        return;
                    549: }
                    550:
                    551: int
                    552: puffs_snapshot(struct mount *mp, struct vnode *vp, struct timespec *ts)
                    553: {
                    554:
                    555:        return EOPNOTSUPP;
                    556: }
                    557:
                    558: const struct vnodeopv_desc * const puffs_vnodeopv_descs[] = {
                    559:        &puffs_vnodeop_opv_desc,
1.3       pooka     560:        &puffs_specop_opv_desc,
1.4       pooka     561:        &puffs_fifoop_opv_desc,
1.12      pooka     562:        &puffs_msgop_opv_desc,
1.1       pooka     563:        NULL,
                    564: };
                    565:
                    566: struct vfsops puffs_vfsops = {
                    567:        MOUNT_PUFFS,
                    568:        puffs_mount,            /* mount        */
                    569:        puffs_start,            /* start        */
                    570:        puffs_unmount,          /* unmount      */
                    571:        puffs_root,             /* root         */
                    572:        puffs_quotactl,         /* quotactl     */
                    573:        puffs_statvfs,          /* statvfs      */
                    574:        puffs_sync,             /* sync         */
                    575:        puffs_vget,             /* vget         */
1.15      chs       576:        (void *)eopnotsupp,     /* fhtovp       */
                    577:        (void *)eopnotsupp,     /* vptofh       */
1.1       pooka     578:        puffs_init,             /* init         */
                    579:        NULL,                   /* reinit       */
                    580:        puffs_done,             /* done         */
                    581:        NULL,                   /* mountroot    */
                    582:        puffs_snapshot,         /* snapshot     */
                    583:        vfs_stdextattrctl,      /* extattrctl   */
1.23      hannken   584:        vfs_stdsuspendctl,      /* suspendctl   */
1.1       pooka     585:        puffs_vnodeopv_descs,   /* vnodeops     */
                    586:        0,                      /* refcount     */
                    587:        { NULL, NULL }
                    588: };
                    589: VFS_ATTACH(puffs_vfsops);

CVSweb <webmaster@jp.NetBSD.org>