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

Annotation of src/sys/fs/puffs/puffs_subr.c, Revision 1.45

1.45    ! pooka       1: /*     $NetBSD: puffs_subr.c,v 1.44 2007/08/01 14:20:45 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:  *
                     19:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
                     20:  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     21:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
                     22:  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
                     23:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     24:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
                     25:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     26:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     27:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     28:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     29:  * SUCH DAMAGE.
                     30:  */
                     31:
                     32: #include <sys/cdefs.h>
1.45    ! pooka      33: __KERNEL_RCSID(0, "$NetBSD: puffs_subr.c,v 1.44 2007/08/01 14:20:45 pooka Exp $");
1.1       pooka      34:
                     35: #include <sys/param.h>
                     36: #include <sys/conf.h>
1.16      pooka      37: #include <sys/hash.h>
1.31      pooka      38: #include <sys/kauth.h>
1.1       pooka      39: #include <sys/malloc.h>
                     40: #include <sys/mount.h>
1.31      pooka      41: #include <sys/namei.h>
                     42: #include <sys/poll.h>
1.1       pooka      43: #include <sys/socketvar.h>
                     44: #include <sys/vnode.h>
1.40      ad         45: #include <sys/proc.h>
1.1       pooka      46:
                     47: #include <fs/puffs/puffs_msgif.h>
                     48: #include <fs/puffs/puffs_sys.h>
                     49:
1.7       pooka      50: #include <miscfs/genfs/genfs_node.h>
1.4       pooka      51: #include <miscfs/specfs/specdev.h>
                     52:
1.26      pooka      53: struct pool puffs_pnpool;
1.1       pooka      54:
1.19      pooka      55: #ifdef PUFFSDEBUG
1.10      pooka      56: int puffsdebug;
                     57: #endif
                     58:
1.16      pooka      59: static __inline struct puffs_node_hashlist
                     60:        *puffs_cookie2hashlist(struct puffs_mount *, void *);
                     61: static struct puffs_node *puffs_cookie2pnode(struct puffs_mount *, void *);
1.7       pooka      62:
                     63: static void puffs_gop_size(struct vnode *, off_t, off_t *, int);
                     64: static void puffs_gop_markupdate(struct vnode *, int);
                     65:
                     66: static const struct genfs_ops puffs_genfsops = {
                     67:        .gop_size = puffs_gop_size,
                     68:        .gop_write = genfs_gop_write,
                     69:        .gop_markupdate = puffs_gop_markupdate,
                     70: #if 0
                     71:        .gop_alloc, should ask userspace
                     72: #endif
                     73: };
                     74:
1.1       pooka      75: /*
                     76:  * Grab a vnode, intialize all the puffs-dependant stuff.
                     77:  */
                     78: int
1.4       pooka      79: puffs_getvnode(struct mount *mp, void *cookie, enum vtype type,
1.7       pooka      80:        voff_t vsize, dev_t rdev, struct vnode **vpp)
1.1       pooka      81: {
                     82:        struct puffs_mount *pmp;
1.4       pooka      83:        struct vnode *vp, *nvp;
1.1       pooka      84:        struct puffs_node *pnode;
1.16      pooka      85:        struct puffs_node_hashlist *plist;
1.1       pooka      86:        int error;
                     87:
1.39      pooka      88:        if (type <= VNON || type >= VBAD)
                     89:                return EINVAL;
1.45    ! pooka      90:        if (vsize == VSIZENOTSET)
        !            91:                return EINVAL;
1.39      pooka      92:
1.1       pooka      93:        pmp = MPTOPUFFSMP(mp);
                     94:
1.2       pooka      95:        /*
                     96:         * XXX: there is a deadlock condition between vfs_busy() and
                     97:         * vnode locks.  For an unmounting file system the mountpoint
                     98:         * is frozen, but in unmount(FORCE) vflush() wants to access all
                     99:         * of the vnodes.  If we are here waiting for the mountpoint
                    100:         * lock while holding on to a vnode lock, well, we ain't
                    101:         * just pining for the fjords anymore.  If we release the
                    102:         * vnode lock, we will be in the situation "mount point
                    103:         * is dying" and panic() will ensue in insmntque.  So as a
                    104:         * temporary workaround, get a vnode without putting it on
                    105:         * the mount point list, check if mount point is still alive
                    106:         * and kicking and only then add the vnode to the list.
                    107:         */
                    108:        error = getnewvnode(VT_PUFFS, NULL, puffs_vnodeop_p, &vp);
                    109:        if (error)
1.1       pooka     110:                return error;
1.2       pooka     111:        vp->v_vnlock = NULL;
1.4       pooka     112:        vp->v_type = type;
1.2       pooka     113:
                    114:        /*
                    115:         * Check what mount point isn't going away.  This will work
                    116:         * until we decide to remove biglock or make the kernel
                    117:         * preemptive.  But hopefully the real problem will be fixed
                    118:         * by then.
                    119:         *
                    120:         * XXX: yes, should call vfs_busy(), but thar be rabbits with
                    121:         * vicious streaks a mile wide ...
                    122:         */
                    123:        if (mp->mnt_iflag & IMNT_UNMOUNT) {
                    124:                DPRINTF(("puffs_getvnode: mp %p unmount, unable to create "
                    125:                    "vnode for cookie %p\n", mp, cookie));
                    126:                ungetnewvnode(vp);
                    127:                return ENXIO;
1.1       pooka     128:        }
                    129:
1.2       pooka     130:        /* So it's not dead yet.. good.. inform new vnode of its master */
                    131:        simple_lock(&mntvnode_slock);
1.16      pooka     132:        TAILQ_INSERT_TAIL(&mp->mnt_vnodelist, vp, v_mntvnodes);
1.2       pooka     133:        simple_unlock(&mntvnode_slock);
                    134:        vp->v_mount = mp;
                    135:
1.4       pooka     136:        /*
                    137:         * clerical tasks & footwork
                    138:         */
                    139:
1.29      pooka     140:        /* default size */
                    141:        uvm_vnp_setsize(vp, 0);
                    142:
1.4       pooka     143:        /* dances based on vnode type. almost ufs_vinit(), but not quite */
                    144:        switch (type) {
                    145:        case VCHR:
                    146:        case VBLK:
                    147:                /*
                    148:                 * replace vnode operation vector with the specops vector.
                    149:                 * our user server has very little control over the node
                    150:                 * if it decides its a character or block special file
                    151:                 */
                    152:                vp->v_op = puffs_specop_p;
                    153:
                    154:                /* do the standard checkalias-dance */
                    155:                if ((nvp = checkalias(vp, rdev, mp)) != NULL) {
                    156:                        /*
1.6       pooka     157:                         * found: release & unallocate aliased
1.4       pooka     158:                         * old (well, actually, new) node
                    159:                         */
                    160:                        vp->v_op = spec_vnodeop_p;
                    161:                        vp->v_flag &= ~VLOCKSWORK;
                    162:                        vrele(vp);
                    163:                        vgone(vp); /* cya */
                    164:
                    165:                        /* init "new" vnode */
                    166:                        vp = nvp;
                    167:                        vp->v_vnlock = NULL;
                    168:                        vp->v_mount = mp;
                    169:                }
                    170:                break;
1.7       pooka     171:
1.5       pooka     172:        case VFIFO:
                    173:                vp->v_op = puffs_fifoop_p;
                    174:                break;
1.7       pooka     175:
                    176:        case VREG:
                    177:                uvm_vnp_setsize(vp, vsize);
                    178:                break;
                    179:
1.5       pooka     180:        case VDIR:
                    181:        case VLNK:
                    182:        case VSOCK:
                    183:                break;
1.4       pooka     184:        default:
1.5       pooka     185: #ifdef DIAGNOSTIC
                    186:                panic("puffs_getvnode: invalid vtype %d", type);
                    187: #endif
1.4       pooka     188:                break;
                    189:        }
                    190:
1.2       pooka     191:        pnode = pool_get(&puffs_pnpool, PR_WAITOK);
1.41      pooka     192:        memset(pnode, 0, sizeof(struct puffs_node));
                    193:
1.1       pooka     194:        pnode->pn_cookie = cookie;
1.31      pooka     195:        pnode->pn_refcount = 1;
                    196:
                    197:        mutex_init(&pnode->pn_mtx, MUTEX_DEFAULT, IPL_NONE);
                    198:        SLIST_INIT(&pnode->pn_sel.sel_klist);
                    199:
1.16      pooka     200:        plist = puffs_cookie2hashlist(pmp, cookie);
                    201:        LIST_INSERT_HEAD(plist, pnode, pn_hashent);
1.1       pooka     202:        vp->v_data = pnode;
1.4       pooka     203:        vp->v_type = type;
1.1       pooka     204:        pnode->pn_vp = vp;
1.42      pooka     205:        pnode->pn_serversize = vsize;
1.1       pooka     206:
1.7       pooka     207:        genfs_node_init(vp, &puffs_genfsops);
1.1       pooka     208:        *vpp = vp;
                    209:
                    210:        DPRINTF(("new vnode at %p, pnode %p, cookie %p\n", vp,
                    211:            pnode, pnode->pn_cookie));
                    212:
                    213:        return 0;
                    214: }
                    215:
                    216: /* new node creating for creative vop ops (create, symlink, mkdir, mknod) */
                    217: int
                    218: puffs_newnode(struct mount *mp, struct vnode *dvp, struct vnode **vpp,
1.4       pooka     219:        void *cookie, struct componentname *cnp, enum vtype type, dev_t rdev)
1.1       pooka     220: {
1.13      pooka     221:        struct puffs_mount *pmp = MPTOPUFFSMP(mp);
1.1       pooka     222:        struct vnode *vp;
                    223:        int error;
                    224:
                    225:        /* userspace probably has this as a NULL op */
                    226:        if (cookie == NULL) {
                    227:                error = EOPNOTSUPP;
1.3       pooka     228:                return error;
1.1       pooka     229:        }
                    230:
1.15      pooka     231:        /*
                    232:         * Check for previous node with the same designation.
1.20      pooka     233:         * Explicitly check the root node cookie, since it might be
                    234:         * reclaimed from the kernel when this check is made.
1.15      pooka     235:         *
                    236:         * XXX: technically this error check should punish the fs,
                    237:         * not the caller.
                    238:         */
1.26      pooka     239:        mutex_enter(&pmp->pmp_lock);
1.30      pooka     240:        if (cookie == pmp->pmp_root_cookie
1.20      pooka     241:            || puffs_cookie2pnode(pmp, cookie) != NULL) {
1.26      pooka     242:                mutex_exit(&pmp->pmp_lock);
1.15      pooka     243:                error = EEXIST;
                    244:                return error;
                    245:        }
1.26      pooka     246:        mutex_exit(&pmp->pmp_lock);
1.15      pooka     247:
1.7       pooka     248:        error = puffs_getvnode(dvp->v_mount, cookie, type, 0, rdev, &vp);
1.1       pooka     249:        if (error)
1.3       pooka     250:                return error;
1.1       pooka     251:
                    252:        vp->v_type = type;
                    253:        vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
                    254:        *vpp = vp;
                    255:
1.35      pooka     256:        if ((cnp->cn_flags & MAKEENTRY) && PUFFS_USE_NAMECACHE(pmp))
1.13      pooka     257:                cache_enter(dvp, vp, cnp);
                    258:
1.3       pooka     259:        return 0;
1.1       pooka     260: }
                    261:
1.31      pooka     262: /*
                    263:  * Release pnode structure which dealing with references to the
                    264:  * puffs_node instead of the vnode.  Can't use vref()/vrele() on
                    265:  * the vnode there, since that causes the lovely VOP_INACTIVE(),
                    266:  * which in turn causes the lovely deadlock when called by the one
                    267:  * who is supposed to handle it.
                    268:  */
                    269: void
                    270: puffs_releasenode(struct puffs_node *pn)
                    271: {
                    272:
                    273:        mutex_enter(&pn->pn_mtx);
                    274:        if (--pn->pn_refcount == 0) {
                    275:                mutex_exit(&pn->pn_mtx);
                    276:                mutex_destroy(&pn->pn_mtx);
                    277:                pool_put(&puffs_pnpool, pn);
                    278:        } else {
                    279:                mutex_exit(&pn->pn_mtx);
                    280:        }
                    281: }
                    282:
                    283: /*
                    284:  * Add reference to node.
                    285:  *  mutex held on entry and return
                    286:  */
                    287: void
                    288: puffs_referencenode(struct puffs_node *pn)
                    289: {
                    290:
                    291:        KASSERT(mutex_owned(&pn->pn_mtx));
                    292:        pn->pn_refcount++;
                    293: }
                    294:
1.1       pooka     295: void
                    296: puffs_putvnode(struct vnode *vp)
                    297: {
                    298:        struct puffs_mount *pmp;
                    299:        struct puffs_node *pnode;
                    300:
                    301:        pmp = VPTOPUFFSMP(vp);
                    302:        pnode = VPTOPP(vp);
                    303:
                    304: #ifdef DIAGNOSTIC
                    305:        if (vp->v_tag != VT_PUFFS)
                    306:                panic("puffs_putvnode: %p not a puffs vnode", vp);
                    307: #endif
                    308:
1.16      pooka     309:        LIST_REMOVE(pnode, pn_hashent);
1.21      ad        310:        genfs_node_destroy(vp);
1.31      pooka     311:        puffs_releasenode(pnode);
1.1       pooka     312:        vp->v_data = NULL;
                    313:
                    314:        return;
                    315: }
                    316:
1.16      pooka     317: static __inline struct puffs_node_hashlist *
                    318: puffs_cookie2hashlist(struct puffs_mount *pmp, void *cookie)
                    319: {
                    320:        uint32_t hash;
                    321:
                    322:        hash = hash32_buf(&cookie, sizeof(void *), HASH32_BUF_INIT);
                    323:        return &pmp->pmp_pnodehash[hash % pmp->pmp_npnodehash];
                    324: }
                    325:
1.1       pooka     326: /*
1.15      pooka     327:  * Translate cookie to puffs_node.  Caller must hold mountpoint
                    328:  * lock and it will be held upon return.
                    329:  */
1.16      pooka     330: static struct puffs_node *
1.15      pooka     331: puffs_cookie2pnode(struct puffs_mount *pmp, void *cookie)
                    332: {
1.16      pooka     333:        struct puffs_node_hashlist *plist;
1.15      pooka     334:        struct puffs_node *pnode;
                    335:
1.16      pooka     336:        plist = puffs_cookie2hashlist(pmp, cookie);
                    337:        LIST_FOREACH(pnode, plist, pn_hashent) {
1.15      pooka     338:                if (pnode->pn_cookie == cookie)
                    339:                        break;
                    340:        }
                    341:
                    342:        return pnode;
                    343: }
                    344:
                    345: /*
1.33      pooka     346:  * Make sure root vnode exists and reference it.  Does NOT lock.
                    347:  */
1.34      pooka     348: static int
1.33      pooka     349: puffs_makeroot(struct puffs_mount *pmp)
                    350: {
                    351:        struct vnode *vp;
                    352:        int rv;
                    353:
                    354:        /*
                    355:         * pmp_lock must be held if vref()'ing or vrele()'ing the
                    356:         * root vnode.  the latter is controlled by puffs_inactive().
                    357:         *
                    358:         * pmp_root is set here and cleared in puffs_reclaim().
                    359:         */
                    360:  retry:
                    361:        mutex_enter(&pmp->pmp_lock);
                    362:        vp = pmp->pmp_root;
                    363:        if (vp) {
                    364:                simple_lock(&vp->v_interlock);
                    365:                mutex_exit(&pmp->pmp_lock);
                    366:                if (vget(vp, LK_INTERLOCK) == 0)
                    367:                        return 0;
                    368:        } else
                    369:                mutex_exit(&pmp->pmp_lock);
                    370:
                    371:        /*
                    372:         * So, didn't have the magic root vnode available.
                    373:         * No matter, grab another an stuff it with the cookie.
                    374:         */
                    375:        if ((rv = puffs_getvnode(pmp->pmp_mp, pmp->pmp_root_cookie,
                    376:            pmp->pmp_root_vtype, pmp->pmp_root_vsize, pmp->pmp_root_rdev, &vp)))
                    377:                return rv;
                    378:
                    379:        /*
                    380:         * Someone magically managed to race us into puffs_getvnode?
                    381:         * Put our previous new vnode back and retry.
                    382:         */
                    383:        mutex_enter(&pmp->pmp_lock);
                    384:        if (pmp->pmp_root) {
                    385:                mutex_exit(&pmp->pmp_lock);
                    386:                puffs_putvnode(vp);
                    387:                goto retry;
                    388:        }
                    389:
                    390:        /* store cache */
                    391:        vp->v_flag = VROOT;
                    392:        pmp->pmp_root = vp;
                    393:        mutex_exit(&pmp->pmp_lock);
                    394:
                    395:        return 0;
                    396: }
                    397:
                    398: /*
1.1       pooka     399:  * Locate the in-kernel vnode based on the cookie received given
1.20      pooka     400:  * from userspace.  Returns a vnode, if found, NULL otherwise.
                    401:  * The parameter "lock" control whether to lock the possible or
                    402:  * not.  Locking always might cause us to lock against ourselves
                    403:  * in situations where we want the vnode but don't care for the
                    404:  * vnode lock, e.g. file server issued putpages.
1.1       pooka     405:  */
1.34      pooka     406: int
                    407: puffs_pnode2vnode(struct puffs_mount *pmp, void *cookie, int lock,
                    408:        struct vnode **vpp)
1.1       pooka     409: {
                    410:        struct puffs_node *pnode;
                    411:        struct vnode *vp;
1.34      pooka     412:        int vgetflags, rv;
1.1       pooka     413:
1.20      pooka     414:        /*
1.33      pooka     415:         * Handle root in a special manner, since we want to make sure
                    416:         * pmp_root is properly set.
1.20      pooka     417:         */
1.30      pooka     418:        if (cookie == pmp->pmp_root_cookie) {
1.34      pooka     419:                if ((rv = puffs_makeroot(pmp)))
                    420:                        return rv;
1.33      pooka     421:                if (lock)
                    422:                        vn_lock(pmp->pmp_root, LK_EXCLUSIVE | LK_RETRY);
1.20      pooka     423:
1.34      pooka     424:                *vpp = pmp->pmp_root;
                    425:                return 0;
1.20      pooka     426:        }
                    427:
1.26      pooka     428:        mutex_enter(&pmp->pmp_lock);
1.15      pooka     429:        pnode = puffs_cookie2pnode(pmp, cookie);
1.14      pooka     430:
1.15      pooka     431:        if (pnode == NULL) {
1.26      pooka     432:                mutex_exit(&pmp->pmp_lock);
1.34      pooka     433:                return ENOENT;
1.15      pooka     434:        }
1.34      pooka     435:
1.1       pooka     436:        vp = pnode->pn_vp;
1.17      pooka     437:        simple_lock(&vp->v_interlock);
1.26      pooka     438:        mutex_exit(&pmp->pmp_lock);
1.1       pooka     439:
1.34      pooka     440:        vgetflags = LK_INTERLOCK;
                    441:        if (lock)
                    442:                vgetflags |= LK_EXCLUSIVE | LK_RETRY;
                    443:        if ((rv = vget(vp, vgetflags)))
                    444:                return rv;
1.14      pooka     445:
1.34      pooka     446:        *vpp = vp;
                    447:        return 0;
1.1       pooka     448: }
                    449:
                    450: void
1.36      pooka     451: puffs_makecn(struct puffs_kcn *pkcn, struct puffs_kcred *pkcr,
1.38      pooka     452:        struct puffs_kcid *pkcid, const struct componentname *cn, int full)
1.1       pooka     453: {
                    454:
1.12      pooka     455:        pkcn->pkcn_nameiop = cn->cn_nameiop;
                    456:        pkcn->pkcn_flags = cn->cn_flags;
1.37      pooka     457:        puffs_cidcvt(pkcid, cn->cn_lwp);
1.1       pooka     458:
1.38      pooka     459:        if (full) {
                    460:                (void)strcpy(pkcn->pkcn_name, cn->cn_nameptr);
                    461:        } else {
                    462:                (void)memcpy(pkcn->pkcn_name, cn->cn_nameptr, cn->cn_namelen);
                    463:                pkcn->pkcn_name[cn->cn_namelen] = '\0';
                    464:        }
1.12      pooka     465:        pkcn->pkcn_namelen = cn->cn_namelen;
1.38      pooka     466:        pkcn->pkcn_consume = 0;
1.36      pooka     467:
                    468:        puffs_credcvt(pkcr, cn->cn_cred);
1.1       pooka     469: }
                    470:
                    471: /*
1.36      pooka     472:  * Convert given credentials to struct puffs_kcred for userspace.
1.1       pooka     473:  */
                    474: void
1.36      pooka     475: puffs_credcvt(struct puffs_kcred *pkcr, const kauth_cred_t cred)
1.1       pooka     476: {
                    477:
1.36      pooka     478:        memset(pkcr, 0, sizeof(struct puffs_kcred));
1.1       pooka     479:
                    480:        if (cred == NOCRED || cred == FSCRED) {
1.36      pooka     481:                pkcr->pkcr_type = PUFFCRED_TYPE_INTERNAL;
1.1       pooka     482:                if (cred == NOCRED)
1.36      pooka     483:                        pkcr->pkcr_internal = PUFFCRED_CRED_NOCRED;
1.1       pooka     484:                if (cred == FSCRED)
1.36      pooka     485:                        pkcr->pkcr_internal = PUFFCRED_CRED_FSCRED;
1.1       pooka     486:        } else {
1.36      pooka     487:                pkcr->pkcr_type = PUFFCRED_TYPE_UUC;
                    488:                kauth_cred_to_uucred(&pkcr->pkcr_uuc, cred);
1.1       pooka     489:        }
                    490: }
                    491:
1.37      pooka     492: void
                    493: puffs_cidcvt(struct puffs_kcid *pkcid, const struct lwp *l)
1.1       pooka     494: {
                    495:
1.37      pooka     496:        if (l) {
                    497:                pkcid->pkcid_type = PUFFCID_TYPE_REAL;
                    498:                pkcid->pkcid_pid = l->l_proc->p_pid;
                    499:                pkcid->pkcid_lwpid = l->l_lid;
                    500:        } else {
                    501:                pkcid->pkcid_type = PUFFCID_TYPE_FAKE;
                    502:                pkcid->pkcid_pid = 0;
                    503:                pkcid->pkcid_lwpid = 0;
                    504:        }
1.1       pooka     505: }
1.7       pooka     506:
                    507: static void
1.8       christos  508: puffs_gop_size(struct vnode *vp, off_t size, off_t *eobp,
                    509:        int flags)
1.7       pooka     510: {
                    511:
                    512:        *eobp = size;
                    513: }
                    514:
                    515: static void
                    516: puffs_gop_markupdate(struct vnode *vp, int flags)
                    517: {
                    518:        int uflags = 0;
                    519:
                    520:        if (flags & GOP_UPDATE_ACCESSED)
                    521:                uflags |= PUFFS_UPDATEATIME;
                    522:        if (flags & GOP_UPDATE_MODIFIED)
                    523:                uflags |= PUFFS_UPDATEMTIME;
                    524:
                    525:        puffs_updatenode(vp, uflags);
                    526: }
                    527:
                    528: void
                    529: puffs_updatenode(struct vnode *vp, int flags)
                    530: {
1.25      pooka     531:        struct puffs_node *pn;
1.7       pooka     532:        struct timespec ts;
                    533:
                    534:        if (flags == 0)
                    535:                return;
                    536:
1.25      pooka     537:        pn = VPTOPP(vp);
1.7       pooka     538:        nanotime(&ts);
                    539:
1.25      pooka     540:        if (flags & PUFFS_UPDATEATIME) {
                    541:                pn->pn_mc_atime = ts;
                    542:                pn->pn_stat |= PNODE_METACACHE_ATIME;
                    543:        }
                    544:        if (flags & PUFFS_UPDATECTIME) {
                    545:                pn->pn_mc_ctime = ts;
                    546:                pn->pn_stat |= PNODE_METACACHE_CTIME;
                    547:        }
                    548:        if (flags & PUFFS_UPDATEMTIME) {
                    549:                pn->pn_mc_mtime = ts;
                    550:                pn->pn_stat |= PNODE_METACACHE_MTIME;
                    551:        }
                    552:        if (flags & PUFFS_UPDATESIZE) {
                    553:                pn->pn_mc_size = vp->v_size;
                    554:                pn->pn_stat |= PNODE_METACACHE_SIZE;
                    555:        }
1.7       pooka     556: }
1.9       pooka     557:
                    558: void
                    559: puffs_updatevpsize(struct vnode *vp)
                    560: {
                    561:        struct vattr va;
                    562:
                    563:        if (VOP_GETATTR(vp, &va, FSCRED, NULL))
                    564:                return;
                    565:
                    566:        if (va.va_size != VNOVAL)
                    567:                vp->v_size = va.va_size;
                    568: }
1.27      pooka     569:
                    570: void
                    571: puffs_parkdone_asyncbioread(struct puffs_req *preq, void *arg)
                    572: {
                    573:        struct puffs_vnreq_read *read_argp = (void *)preq;
                    574:        struct buf *bp = arg;
                    575:        size_t moved;
                    576:
                    577:        bp->b_error = preq->preq_rv;
                    578:        if (bp->b_error == 0) {
                    579:                moved = bp->b_bcount - read_argp->pvnr_resid;
                    580:                bp->b_resid = read_argp->pvnr_resid;
                    581:
                    582:                memcpy(bp->b_data, read_argp->pvnr_data, moved);
                    583:        }
                    584:
                    585:        biodone(bp);
                    586:        free(preq, M_PUFFS);
                    587: }
1.28      pooka     588:
1.44      pooka     589: /* XXX: userspace can leak kernel resources */
1.28      pooka     590: void
1.31      pooka     591: puffs_parkdone_poll(struct puffs_req *preq, void *arg)
                    592: {
                    593:        struct puffs_vnreq_poll *poll_argp = (void *)preq;
                    594:        struct puffs_node *pn = arg;
                    595:        int revents;
                    596:
                    597:        if (preq->preq_rv == 0)
                    598:                revents = poll_argp->pvnr_events;
                    599:        else
                    600:                revents = POLLERR;
                    601:
                    602:        mutex_enter(&pn->pn_mtx);
                    603:        pn->pn_revents |= revents;
                    604:        mutex_exit(&pn->pn_mtx);
                    605:
                    606:        selnotify(&pn->pn_sel, 0);
                    607:        free(preq, M_PUFFS);
                    608:
                    609:        puffs_releasenode(pn);
                    610: }
                    611:
                    612: void
1.28      pooka     613: puffs_mp_reference(struct puffs_mount *pmp)
                    614: {
                    615:
                    616:        KASSERT(mutex_owned(&pmp->pmp_lock));
                    617:        pmp->pmp_refcount++;
                    618: }
                    619:
                    620: void
                    621: puffs_mp_release(struct puffs_mount *pmp)
                    622: {
                    623:
                    624:        KASSERT(mutex_owned(&pmp->pmp_lock));
                    625:        if (--pmp->pmp_refcount == 0)
                    626:                cv_broadcast(&pmp->pmp_refcount_cv);
                    627: }

CVSweb <webmaster@jp.NetBSD.org>