[BACK]Return to genfs_vnops.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / miscfs / genfs

Annotation of src/sys/miscfs/genfs/genfs_vnops.c, Revision 1.164.6.2

1.164.6.1  mjf         1: /*     $NetBSD$        */
1.164     ad          2:
                      3: /*-
                      4:  * Copyright (c) 2008 The NetBSD Foundation, Inc.
                      5:  * All rights reserved.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
                     15:  *
                     16:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     17:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     18:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     19:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     20:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     21:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     22:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     23:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     24:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     25:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     26:  * POSSIBILITY OF SUCH DAMAGE.
                     27:  */
1.6       fvdl       28:
                     29: /*
                     30:  * Copyright (c) 1982, 1986, 1989, 1993
                     31:  *     The Regents of the University of California.  All rights reserved.
                     32:  *
                     33:  * Redistribution and use in source and binary forms, with or without
                     34:  * modification, are permitted provided that the following conditions
                     35:  * are met:
                     36:  * 1. Redistributions of source code must retain the above copyright
                     37:  *    notice, this list of conditions and the following disclaimer.
                     38:  * 2. Redistributions in binary form must reproduce the above copyright
                     39:  *    notice, this list of conditions and the following disclaimer in the
                     40:  *    documentation and/or other materials provided with the distribution.
1.81      agc        41:  * 3. Neither the name of the University nor the names of its contributors
1.6       fvdl       42:  *    may be used to endorse or promote products derived from this software
                     43:  *    without specific prior written permission.
                     44:  *
                     45:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     46:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     47:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     48:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     49:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     50:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     51:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     52:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     53:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     54:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     55:  * SUCH DAMAGE.
                     56:  *
                     57:  */
1.40      lukem      58:
                     59: #include <sys/cdefs.h>
1.164.6.1  mjf        60: __KERNEL_RCSID(0, "$NetBSD$");
1.8       thorpej    61:
1.1       mycroft    62: #include <sys/param.h>
                     63: #include <sys/systm.h>
1.6       fvdl       64: #include <sys/proc.h>
1.1       mycroft    65: #include <sys/kernel.h>
                     66: #include <sys/mount.h>
                     67: #include <sys/namei.h>
                     68: #include <sys/vnode.h>
1.13      wrstuden   69: #include <sys/fcntl.h>
1.135     yamt       70: #include <sys/kmem.h>
1.3       mycroft    71: #include <sys/poll.h>
1.37      chs        72: #include <sys/mman.h>
1.66      jdolecek   73: #include <sys/file.h>
1.125     elad       74: #include <sys/kauth.h>
1.1       mycroft    75:
                     76: #include <miscfs/genfs/genfs.h>
1.37      chs        77: #include <miscfs/genfs/genfs_node.h>
1.6       fvdl       78: #include <miscfs/specfs/specdev.h>
1.1       mycroft    79:
1.21      chs        80: #include <uvm/uvm.h>
                     81: #include <uvm/uvm_pager.h>
                     82:
1.70      christos   83: static void filt_genfsdetach(struct knote *);
                     84: static int filt_genfsread(struct knote *, long);
                     85: static int filt_genfsvnode(struct knote *, long);
                     86:
1.1       mycroft    87: int
1.53      enami      88: genfs_poll(void *v)
1.1       mycroft    89: {
1.3       mycroft    90:        struct vop_poll_args /* {
1.1       mycroft    91:                struct vnode *a_vp;
1.3       mycroft    92:                int a_events;
1.116     christos   93:                struct lwp *a_l;
1.1       mycroft    94:        } */ *ap = v;
                     95:
1.3       mycroft    96:        return (ap->a_events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM));
1.1       mycroft    97: }
                     98:
                     99: int
1.53      enami     100: genfs_seek(void *v)
1.4       kleink    101: {
                    102:        struct vop_seek_args /* {
                    103:                struct vnode *a_vp;
                    104:                off_t a_oldoff;
                    105:                off_t a_newoff;
1.125     elad      106:                kauth_cred_t cred;
1.4       kleink    107:        } */ *ap = v;
                    108:
                    109:        if (ap->a_newoff < 0)
                    110:                return (EINVAL);
                    111:
                    112:        return (0);
                    113: }
                    114:
                    115: int
1.53      enami     116: genfs_abortop(void *v)
1.1       mycroft   117: {
                    118:        struct vop_abortop_args /* {
                    119:                struct vnode *a_dvp;
                    120:                struct componentname *a_cnp;
                    121:        } */ *ap = v;
1.53      enami     122:
1.1       mycroft   123:        if ((ap->a_cnp->cn_flags & (HASBUF | SAVESTART)) == HASBUF)
1.19      thorpej   124:                PNBUF_PUT(ap->a_cnp->cn_pnbuf);
1.1       mycroft   125:        return (0);
1.13      wrstuden  126: }
                    127:
                    128: int
1.53      enami     129: genfs_fcntl(void *v)
1.13      wrstuden  130: {
                    131:        struct vop_fcntl_args /* {
                    132:                struct vnode *a_vp;
                    133:                u_int a_command;
1.150     christos  134:                void *a_data;
1.13      wrstuden  135:                int a_fflag;
1.125     elad      136:                kauth_cred_t a_cred;
1.116     christos  137:                struct lwp *a_l;
1.13      wrstuden  138:        } */ *ap = v;
                    139:
                    140:        if (ap->a_command == F_SETFL)
                    141:                return (0);
                    142:        else
                    143:                return (EOPNOTSUPP);
1.1       mycroft   144: }
                    145:
                    146: /*ARGSUSED*/
                    147: int
1.138     christos  148: genfs_badop(void *v)
1.1       mycroft   149: {
                    150:
                    151:        panic("genfs: bad op");
                    152: }
                    153:
                    154: /*ARGSUSED*/
                    155: int
1.138     christos  156: genfs_nullop(void *v)
1.1       mycroft   157: {
                    158:
                    159:        return (0);
1.10      kleink    160: }
                    161:
                    162: /*ARGSUSED*/
                    163: int
1.138     christos  164: genfs_einval(void *v)
1.10      kleink    165: {
                    166:
                    167:        return (EINVAL);
1.1       mycroft   168: }
                    169:
1.12      wrstuden  170: /*
1.74      jdolecek  171:  * Called when an fs doesn't support a particular vop.
                    172:  * This takes care to vrele, vput, or vunlock passed in vnodes.
1.12      wrstuden  173:  */
                    174: int
1.75      jdolecek  175: genfs_eopnotsupp(void *v)
1.12      wrstuden  176: {
                    177:        struct vop_generic_args /*
                    178:                struct vnodeop_desc *a_desc;
1.53      enami     179:                / * other random data follows, presumably * /
1.12      wrstuden  180:        } */ *ap = v;
                    181:        struct vnodeop_desc *desc = ap->a_desc;
1.74      jdolecek  182:        struct vnode *vp, *vp_last = NULL;
1.12      wrstuden  183:        int flags, i, j, offset;
                    184:
                    185:        flags = desc->vdesc_flags;
                    186:        for (i = 0; i < VDESC_MAX_VPS; flags >>=1, i++) {
                    187:                if ((offset = desc->vdesc_vp_offsets[i]) == VDESC_NO_OFFSET)
                    188:                        break;  /* stop at end of list */
                    189:                if ((j = flags & VDESC_VP0_WILLPUT)) {
1.53      enami     190:                        vp = *VOPARG_OFFSETTO(struct vnode **, offset, ap);
1.74      jdolecek  191:
                    192:                        /* Skip if NULL */
                    193:                        if (!vp)
                    194:                                continue;
                    195:
1.12      wrstuden  196:                        switch (j) {
                    197:                        case VDESC_VP0_WILLPUT:
1.74      jdolecek  198:                                /* Check for dvp == vp cases */
                    199:                                if (vp == vp_last)
                    200:                                        vrele(vp);
                    201:                                else {
                    202:                                        vput(vp);
                    203:                                        vp_last = vp;
                    204:                                }
1.12      wrstuden  205:                                break;
                    206:                        case VDESC_VP0_WILLUNLOCK:
                    207:                                VOP_UNLOCK(vp, 0);
                    208:                                break;
                    209:                        case VDESC_VP0_WILLRELE:
                    210:                                vrele(vp);
                    211:                                break;
                    212:                        }
                    213:                }
                    214:        }
                    215:
                    216:        return (EOPNOTSUPP);
                    217: }
                    218:
1.1       mycroft   219: /*ARGSUSED*/
                    220: int
1.138     christos  221: genfs_ebadf(void *v)
1.1       mycroft   222: {
                    223:
                    224:        return (EBADF);
1.9       matthias  225: }
                    226:
                    227: /* ARGSUSED */
                    228: int
1.138     christos  229: genfs_enoioctl(void *v)
1.9       matthias  230: {
                    231:
1.51      atatat    232:        return (EPASSTHROUGH);
1.6       fvdl      233: }
                    234:
                    235:
                    236: /*
1.15      fvdl      237:  * Eliminate all activity associated with the requested vnode
1.6       fvdl      238:  * and with all vnodes aliased to the requested vnode.
                    239:  */
                    240: int
1.53      enami     241: genfs_revoke(void *v)
1.6       fvdl      242: {
                    243:        struct vop_revoke_args /* {
                    244:                struct vnode *a_vp;
                    245:                int a_flags;
                    246:        } */ *ap = v;
                    247:
                    248: #ifdef DIAGNOSTIC
                    249:        if ((ap->a_flags & REVOKEALL) == 0)
                    250:                panic("genfs_revoke: not revokeall");
                    251: #endif
1.161     ad        252:        vrevoke(ap->a_vp);
1.6       fvdl      253:        return (0);
                    254: }
                    255:
                    256: /*
1.12      wrstuden  257:  * Lock the node.
1.6       fvdl      258:  */
                    259: int
1.53      enami     260: genfs_lock(void *v)
1.6       fvdl      261: {
                    262:        struct vop_lock_args /* {
                    263:                struct vnode *a_vp;
                    264:                int a_flags;
                    265:        } */ *ap = v;
                    266:        struct vnode *vp = ap->a_vp;
1.163     ad        267:        int flags = ap->a_flags;
1.6       fvdl      268:
1.163     ad        269:        if ((flags & LK_INTERLOCK) != 0) {
                    270:                flags &= ~LK_INTERLOCK;
                    271:                mutex_exit(&vp->v_interlock);
                    272:        }
                    273:
                    274:        return (vlockmgr(vp->v_vnlock, flags));
1.6       fvdl      275: }
                    276:
                    277: /*
1.12      wrstuden  278:  * Unlock the node.
1.6       fvdl      279:  */
                    280: int
1.53      enami     281: genfs_unlock(void *v)
1.6       fvdl      282: {
                    283:        struct vop_unlock_args /* {
                    284:                struct vnode *a_vp;
                    285:                int a_flags;
                    286:        } */ *ap = v;
                    287:        struct vnode *vp = ap->a_vp;
                    288:
1.163     ad        289:        KASSERT(ap->a_flags == 0);
                    290:
                    291:        return (vlockmgr(vp->v_vnlock, LK_RELEASE));
1.6       fvdl      292: }
                    293:
                    294: /*
1.12      wrstuden  295:  * Return whether or not the node is locked.
1.6       fvdl      296:  */
                    297: int
1.53      enami     298: genfs_islocked(void *v)
1.6       fvdl      299: {
                    300:        struct vop_islocked_args /* {
                    301:                struct vnode *a_vp;
                    302:        } */ *ap = v;
                    303:        struct vnode *vp = ap->a_vp;
                    304:
1.163     ad        305:        return (vlockstatus(vp->v_vnlock));
1.12      wrstuden  306: }
                    307:
                    308: /*
                    309:  * Stubs to use when there is no locking to be done on the underlying object.
                    310:  */
                    311: int
1.53      enami     312: genfs_nolock(void *v)
1.12      wrstuden  313: {
                    314:        struct vop_lock_args /* {
                    315:                struct vnode *a_vp;
                    316:                int a_flags;
1.116     christos  317:                struct lwp *a_l;
1.12      wrstuden  318:        } */ *ap = v;
                    319:
                    320:        /*
                    321:         * Since we are not using the lock manager, we must clear
                    322:         * the interlock here.
                    323:         */
                    324:        if (ap->a_flags & LK_INTERLOCK)
1.160     ad        325:                mutex_exit(&ap->a_vp->v_interlock);
1.12      wrstuden  326:        return (0);
                    327: }
                    328:
                    329: int
1.138     christos  330: genfs_nounlock(void *v)
1.12      wrstuden  331: {
1.53      enami     332:
1.12      wrstuden  333:        return (0);
                    334: }
                    335:
                    336: int
1.138     christos  337: genfs_noislocked(void *v)
1.12      wrstuden  338: {
1.53      enami     339:
1.12      wrstuden  340:        return (0);
1.8       thorpej   341: }
                    342:
1.34      chs       343: int
1.138     christos  344: genfs_mmap(void *v)
1.34      chs       345: {
1.53      enami     346:
                    347:        return (0);
1.21      chs       348: }
                    349:
1.37      chs       350: void
1.98      yamt      351: genfs_node_init(struct vnode *vp, const struct genfs_ops *ops)
1.37      chs       352: {
                    353:        struct genfs_node *gp = VTOG(vp);
                    354:
1.146     ad        355:        rw_init(&gp->g_glock);
1.37      chs       356:        gp->g_op = ops;
                    357: }
                    358:
                    359: void
1.147     ad        360: genfs_node_destroy(struct vnode *vp)
                    361: {
                    362:        struct genfs_node *gp = VTOG(vp);
                    363:
                    364:        rw_destroy(&gp->g_glock);
                    365: }
                    366:
                    367: void
1.138     christos  368: genfs_size(struct vnode *vp, off_t size, off_t *eobp, int flags)
1.21      chs       369: {
                    370:        int bsize;
                    371:
1.37      chs       372:        bsize = 1 << vp->v_mount->mnt_fs_bshift;
                    373:        *eobp = (size + bsize - 1) & ~(bsize - 1);
1.43      chs       374: }
                    375:
1.66      jdolecek  376: static void
                    377: filt_genfsdetach(struct knote *kn)
                    378: {
                    379:        struct vnode *vp = (struct vnode *)kn->kn_hook;
                    380:
1.164     ad        381:        mutex_enter(&vp->v_interlock);
1.66      jdolecek  382:        SLIST_REMOVE(&vp->v_klist, kn, knote, kn_selnext);
1.164     ad        383:        mutex_exit(&vp->v_interlock);
1.66      jdolecek  384: }
                    385:
                    386: static int
                    387: filt_genfsread(struct knote *kn, long hint)
                    388: {
                    389:        struct vnode *vp = (struct vnode *)kn->kn_hook;
1.164     ad        390:        int rv;
1.66      jdolecek  391:
                    392:        /*
                    393:         * filesystem is gone, so set the EOF flag and schedule
                    394:         * the knote for deletion.
                    395:         */
1.164     ad        396:        switch (hint) {
                    397:        case NOTE_REVOKE:
                    398:                KASSERT(mutex_owned(&vp->v_interlock));
1.66      jdolecek  399:                kn->kn_flags |= (EV_EOF | EV_ONESHOT);
                    400:                return (1);
1.164     ad        401:        case 0:
                    402:                mutex_enter(&vp->v_interlock);
1.164.6.1  mjf       403:                kn->kn_data = vp->v_size - ((file_t *)kn->kn_obj)->f_offset;
1.164     ad        404:                rv = (kn->kn_data != 0);
                    405:                mutex_exit(&vp->v_interlock);
                    406:                return rv;
                    407:        default:
                    408:                KASSERT(mutex_owned(&vp->v_interlock));
1.164.6.1  mjf       409:                kn->kn_data = vp->v_size - ((file_t *)kn->kn_obj)->f_offset;
1.164     ad        410:                return (kn->kn_data != 0);
1.66      jdolecek  411:        }
                    412: }
                    413:
                    414: static int
                    415: filt_genfsvnode(struct knote *kn, long hint)
                    416: {
1.164     ad        417:        struct vnode *vp = (struct vnode *)kn->kn_hook;
                    418:        int fflags;
1.66      jdolecek  419:
1.164     ad        420:        switch (hint) {
                    421:        case NOTE_REVOKE:
                    422:                KASSERT(mutex_owned(&vp->v_interlock));
1.66      jdolecek  423:                kn->kn_flags |= EV_EOF;
1.164     ad        424:                if ((kn->kn_sfflags & hint) != 0)
                    425:                        kn->kn_fflags |= hint;
1.66      jdolecek  426:                return (1);
1.164     ad        427:        case 0:
                    428:                mutex_enter(&vp->v_interlock);
                    429:                fflags = kn->kn_fflags;
                    430:                mutex_exit(&vp->v_interlock);
                    431:                break;
                    432:        default:
                    433:                KASSERT(mutex_owned(&vp->v_interlock));
                    434:                if ((kn->kn_sfflags & hint) != 0)
                    435:                        kn->kn_fflags |= hint;
                    436:                fflags = kn->kn_fflags;
                    437:                break;
1.66      jdolecek  438:        }
1.164     ad        439:
1.164.6.1  mjf       440:        return (fflags != 0);
1.66      jdolecek  441: }
                    442:
1.96      perry     443: static const struct filterops genfsread_filtops =
1.66      jdolecek  444:        { 1, NULL, filt_genfsdetach, filt_genfsread };
1.96      perry     445: static const struct filterops genfsvnode_filtops =
1.66      jdolecek  446:        { 1, NULL, filt_genfsdetach, filt_genfsvnode };
                    447:
                    448: int
                    449: genfs_kqfilter(void *v)
                    450: {
                    451:        struct vop_kqfilter_args /* {
                    452:                struct vnode    *a_vp;
                    453:                struct knote    *a_kn;
                    454:        } */ *ap = v;
                    455:        struct vnode *vp;
                    456:        struct knote *kn;
                    457:
                    458:        vp = ap->a_vp;
                    459:        kn = ap->a_kn;
                    460:        switch (kn->kn_filter) {
                    461:        case EVFILT_READ:
                    462:                kn->kn_fop = &genfsread_filtops;
                    463:                break;
                    464:        case EVFILT_VNODE:
                    465:                kn->kn_fop = &genfsvnode_filtops;
                    466:                break;
                    467:        default:
1.159     pooka     468:                return (EINVAL);
1.66      jdolecek  469:        }
                    470:
                    471:        kn->kn_hook = vp;
                    472:
1.164     ad        473:        mutex_enter(&vp->v_interlock);
1.66      jdolecek  474:        SLIST_INSERT_HEAD(&vp->v_klist, kn, kn_selnext);
1.164     ad        475:        mutex_exit(&vp->v_interlock);
1.66      jdolecek  476:
                    477:        return (0);
1.1       mycroft   478: }
1.136     yamt      479:
                    480: void
                    481: genfs_node_wrlock(struct vnode *vp)
                    482: {
                    483:        struct genfs_node *gp = VTOG(vp);
                    484:
1.146     ad        485:        rw_enter(&gp->g_glock, RW_WRITER);
1.136     yamt      486: }
                    487:
                    488: void
                    489: genfs_node_rdlock(struct vnode *vp)
                    490: {
                    491:        struct genfs_node *gp = VTOG(vp);
                    492:
1.146     ad        493:        rw_enter(&gp->g_glock, RW_READER);
1.136     yamt      494: }
                    495:
                    496: void
                    497: genfs_node_unlock(struct vnode *vp)
                    498: {
                    499:        struct genfs_node *gp = VTOG(vp);
                    500:
1.146     ad        501:        rw_exit(&gp->g_glock);
1.136     yamt      502: }

CVSweb <webmaster@jp.NetBSD.org>