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

Annotation of src/sys/miscfs/fdesc/fdesc_vnops.c, Revision 1.82.6.1

1.82.6.1! yamt        1: /*     $NetBSD: fdesc_vnops.c,v 1.82 2004/11/30 04:25:44 christos Exp $        */
1.15      cgd         2:
1.1       cgd         3: /*
1.14      mycroft     4:  * Copyright (c) 1992, 1993
                      5:  *     The Regents of the University of California.  All rights reserved.
1.1       cgd         6:  *
1.8       cgd         7:  * This code is derived from software donated to Berkeley by
1.1       cgd         8:  * Jan-Simon Pendry.
                      9:  *
1.2       cgd        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.
1.78      agc        18:  * 3. Neither the name of the University nor the names of its contributors
1.2       cgd        19:  *    may be used to endorse or promote products derived from this software
                     20:  *    without specific prior written permission.
1.1       cgd        21:  *
1.2       cgd        22:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     23:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     24:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     25:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS 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
                     28:  * OR 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.
1.1       cgd        33:  *
1.44      fvdl       34:  *     @(#)fdesc_vnops.c       8.17 (Berkeley) 5/22/95
1.22      mycroft    35:  *
                     36:  * #Id: fdesc_vnops.c,v 1.12 1993/04/06 16:17:17 jsp Exp #
1.1       cgd        37:  */
                     38:
                     39: /*
                     40:  * /dev/fd Filesystem
                     41:  */
1.65      lukem      42:
                     43: #include <sys/cdefs.h>
1.82.6.1! yamt       44: __KERNEL_RCSID(0, "$NetBSD: fdesc_vnops.c,v 1.82 2004/11/30 04:25:44 christos Exp $");
1.1       cgd        45:
1.8       cgd        46: #include <sys/param.h>
                     47: #include <sys/systm.h>
                     48: #include <sys/time.h>
                     49: #include <sys/proc.h>
                     50: #include <sys/kernel.h>        /* boottime */
                     51: #include <sys/resourcevar.h>
1.30      christos   52: #include <sys/socketvar.h>
1.8       cgd        53: #include <sys/filedesc.h>
                     54: #include <sys/vnode.h>
1.14      mycroft    55: #include <sys/malloc.h>
1.32      mrg        56: #include <sys/conf.h>
1.8       cgd        57: #include <sys/file.h>
                     58: #include <sys/stat.h>
                     59: #include <sys/mount.h>
                     60: #include <sys/namei.h>
                     61: #include <sys/buf.h>
1.14      mycroft    62: #include <sys/dirent.h>
1.30      christos   63: #include <sys/tty.h>
1.34      mycroft    64:
1.8       cgd        65: #include <miscfs/fdesc/fdesc.h>
1.34      mycroft    66: #include <miscfs/genfs/genfs.h>
1.8       cgd        67:
1.14      mycroft    68: #define cttyvp(p) ((p)->p_flag & P_CONTROLT ? (p)->p_session->s_ttyvp : NULL)
1.8       cgd        69:
                     70: #define FDL_WANT       0x01
                     71: #define FDL_LOCKED     0x02
1.14      mycroft    72: static int fdcache_lock;
                     73:
                     74: dev_t devctty;
1.8       cgd        75:
                     76: #if (FD_STDIN != FD_STDOUT-1) || (FD_STDOUT != FD_STDERR-1)
                     77: FD_STDIN, FD_STDOUT, FD_STDERR must be a sequence n, n+1, n+2
                     78: #endif
                     79:
1.16      mycroft    80: #define        NFDCACHE 4
1.14      mycroft    81:
1.17      mycroft    82: #define FD_NHASH(ix) \
                     83:        (&fdhashtbl[(ix) & fdhash])
                     84: LIST_HEAD(fdhashhead, fdescnode) *fdhashtbl;
                     85: u_long fdhash;
1.14      mycroft    86:
1.30      christos   87: int    fdesc_lookup    __P((void *));
1.74      jdolecek   88: #define        fdesc_create    genfs_eopnotsupp
                     89: #define        fdesc_mknod     genfs_eopnotsupp
1.30      christos   90: int    fdesc_open      __P((void *));
1.34      mycroft    91: #define        fdesc_close     genfs_nullop
                     92: #define        fdesc_access    genfs_nullop
1.30      christos   93: int    fdesc_getattr   __P((void *));
                     94: int    fdesc_setattr   __P((void *));
                     95: int    fdesc_read      __P((void *));
                     96: int    fdesc_write     __P((void *));
                     97: int    fdesc_ioctl     __P((void *));
1.35      mycroft    98: int    fdesc_poll      __P((void *));
1.71      jdolecek   99: int    fdesc_kqfilter  __P((void *));
1.34      mycroft   100: #define        fdesc_mmap      genfs_eopnotsupp
1.50      wrstuden  101: #define        fdesc_fcntl     genfs_fcntl
1.34      mycroft   102: #define        fdesc_fsync     genfs_nullop
1.40      fvdl      103: #define        fdesc_seek      genfs_seek
1.74      jdolecek  104: #define        fdesc_remove    genfs_eopnotsupp
1.31      mycroft   105: int    fdesc_link      __P((void *));
1.74      jdolecek  106: #define        fdesc_rename    genfs_eopnotsupp
                    107: #define        fdesc_mkdir     genfs_eopnotsupp
                    108: #define        fdesc_rmdir     genfs_eopnotsupp
1.30      christos  109: int    fdesc_symlink   __P((void *));
                    110: int    fdesc_readdir   __P((void *));
                    111: int    fdesc_readlink  __P((void *));
1.34      mycroft   112: #define        fdesc_abortop   genfs_abortop
1.30      christos  113: int    fdesc_inactive  __P((void *));
                    114: int    fdesc_reclaim   __P((void *));
1.48      wrstuden  115: #define        fdesc_lock      genfs_lock
                    116: #define        fdesc_unlock    genfs_unlock
1.34      mycroft   117: #define        fdesc_bmap      genfs_badop
                    118: #define        fdesc_strategy  genfs_badop
1.30      christos  119: int    fdesc_print     __P((void *));
1.31      mycroft   120: int    fdesc_pathconf  __P((void *));
1.48      wrstuden  121: #define        fdesc_islocked  genfs_islocked
1.47      kleink    122: #define        fdesc_advlock   genfs_einval
1.34      mycroft   123: #define        fdesc_blkatoff  genfs_eopnotsupp
                    124: #define        fdesc_valloc    genfs_eopnotsupp
                    125: #define        fdesc_vfree     genfs_nullop
                    126: #define        fdesc_truncate  genfs_eopnotsupp
                    127: #define        fdesc_update    genfs_nullop
                    128: #define        fdesc_bwrite    genfs_eopnotsupp
1.44      fvdl      129: #define fdesc_revoke   genfs_revoke
1.67      chs       130: #define fdesc_putpages genfs_null_putpages
1.30      christos  131:
1.77      fvdl      132: static int fdesc_attr __P((int, struct vattr *, struct ucred *, struct proc *));
1.30      christos  133:
                    134: int (**fdesc_vnodeop_p) __P((void *));
1.58      jdolecek  135: const struct vnodeopv_entry_desc fdesc_vnodeop_entries[] = {
1.30      christos  136:        { &vop_default_desc, vn_default_error },
1.34      mycroft   137:        { &vop_lookup_desc, fdesc_lookup },             /* lookup */
                    138:        { &vop_create_desc, fdesc_create },             /* create */
                    139:        { &vop_mknod_desc, fdesc_mknod },               /* mknod */
                    140:        { &vop_open_desc, fdesc_open },                 /* open */
                    141:        { &vop_close_desc, fdesc_close },               /* close */
                    142:        { &vop_access_desc, fdesc_access },             /* access */
                    143:        { &vop_getattr_desc, fdesc_getattr },           /* getattr */
                    144:        { &vop_setattr_desc, fdesc_setattr },           /* setattr */
                    145:        { &vop_read_desc, fdesc_read },                 /* read */
                    146:        { &vop_write_desc, fdesc_write },               /* write */
                    147:        { &vop_ioctl_desc, fdesc_ioctl },               /* ioctl */
1.50      wrstuden  148:        { &vop_fcntl_desc, fdesc_fcntl },               /* fcntl */
1.35      mycroft   149:        { &vop_poll_desc, fdesc_poll },                 /* poll */
1.71      jdolecek  150:        { &vop_kqfilter_desc, fdesc_kqfilter },         /* kqfilter */
1.44      fvdl      151:        { &vop_revoke_desc, fdesc_revoke },             /* revoke */
1.34      mycroft   152:        { &vop_mmap_desc, fdesc_mmap },                 /* mmap */
                    153:        { &vop_fsync_desc, fdesc_fsync },               /* fsync */
                    154:        { &vop_seek_desc, fdesc_seek },                 /* seek */
                    155:        { &vop_remove_desc, fdesc_remove },             /* remove */
                    156:        { &vop_link_desc, fdesc_link },                 /* link */
                    157:        { &vop_rename_desc, fdesc_rename },             /* rename */
                    158:        { &vop_mkdir_desc, fdesc_mkdir },               /* mkdir */
                    159:        { &vop_rmdir_desc, fdesc_rmdir },               /* rmdir */
                    160:        { &vop_symlink_desc, fdesc_symlink },           /* symlink */
                    161:        { &vop_readdir_desc, fdesc_readdir },           /* readdir */
                    162:        { &vop_readlink_desc, fdesc_readlink },         /* readlink */
                    163:        { &vop_abortop_desc, fdesc_abortop },           /* abortop */
                    164:        { &vop_inactive_desc, fdesc_inactive },         /* inactive */
                    165:        { &vop_reclaim_desc, fdesc_reclaim },           /* reclaim */
                    166:        { &vop_lock_desc, fdesc_lock },                 /* lock */
                    167:        { &vop_unlock_desc, fdesc_unlock },             /* unlock */
                    168:        { &vop_bmap_desc, fdesc_bmap },                 /* bmap */
                    169:        { &vop_strategy_desc, fdesc_strategy },         /* strategy */
                    170:        { &vop_print_desc, fdesc_print },               /* print */
                    171:        { &vop_islocked_desc, fdesc_islocked },         /* islocked */
                    172:        { &vop_pathconf_desc, fdesc_pathconf },         /* pathconf */
                    173:        { &vop_advlock_desc, fdesc_advlock },           /* advlock */
                    174:        { &vop_blkatoff_desc, fdesc_blkatoff },         /* blkatoff */
                    175:        { &vop_valloc_desc, fdesc_valloc },             /* valloc */
                    176:        { &vop_vfree_desc, fdesc_vfree },               /* vfree */
                    177:        { &vop_truncate_desc, fdesc_truncate },         /* truncate */
                    178:        { &vop_update_desc, fdesc_update },             /* update */
                    179:        { &vop_bwrite_desc, fdesc_bwrite },             /* bwrite */
1.67      chs       180:        { &vop_putpages_desc, fdesc_putpages },         /* putpages */
                    181:        { NULL, NULL }
1.30      christos  182: };
                    183:
1.58      jdolecek  184: const struct vnodeopv_desc fdesc_vnodeop_opv_desc =
1.30      christos  185:        { &fdesc_vnodeop_p, fdesc_vnodeop_entries };
                    186:
1.70      gehenna   187: extern const struct cdevsw ctty_cdevsw;
                    188:
1.14      mycroft   189: /*
                    190:  * Initialise cache headers
                    191:  */
1.30      christos  192: void
1.14      mycroft   193: fdesc_init()
                    194: {
1.32      mrg       195:        int cttymajor;
1.14      mycroft   196:
1.32      mrg       197:        /* locate the major number */
1.70      gehenna   198:        cttymajor = cdevsw_lookup_major(&ctty_cdevsw);
1.32      mrg       199:        devctty = makedev(cttymajor, 0);
1.57      ad        200:        fdhashtbl = hashinit(NFDCACHE, HASH_LIST, M_CACHE, M_NOWAIT, &fdhash);
1.54      jdolecek  201: }
                    202:
                    203: /*
                    204:  * Free hash table.
                    205:  */
                    206: void
                    207: fdesc_done()
                    208: {
                    209:        hashdone(fdhashtbl, M_CACHE);
1.14      mycroft   210: }
                    211:
1.48      wrstuden  212: /*
                    213:  * Return a locked vnode of the correct type.
                    214:  */
1.14      mycroft   215: int
1.8       cgd       216: fdesc_allocvp(ftype, ix, mp, vpp)
                    217:        fdntype ftype;
                    218:        int ix;
                    219:        struct mount *mp;
                    220:        struct vnode **vpp;
                    221: {
1.17      mycroft   222:        struct fdhashhead *fc;
1.14      mycroft   223:        struct fdescnode *fd;
1.8       cgd       224:        int error = 0;
                    225:
1.17      mycroft   226:        fc = FD_NHASH(ix);
1.8       cgd       227: loop:
1.17      mycroft   228:        for (fd = fc->lh_first; fd != 0; fd = fd->fd_hash.le_next) {
1.14      mycroft   229:                if (fd->fd_ix == ix && fd->fd_vnode->v_mount == mp) {
1.76      thorpej   230:                        if (vget(fd->fd_vnode, LK_EXCLUSIVE))
1.8       cgd       231:                                goto loop;
1.14      mycroft   232:                        *vpp = fd->fd_vnode;
1.8       cgd       233:                        return (error);
                    234:                }
                    235:        }
                    236:
                    237:        /*
                    238:         * otherwise lock the array while we call getnewvnode
                    239:         * since that can block.
1.82.6.1! yamt      240:         */
1.14      mycroft   241:        if (fdcache_lock & FDL_LOCKED) {
                    242:                fdcache_lock |= FDL_WANT;
1.55      thorpej   243:                (void) tsleep(&fdcache_lock, PINOD, "fdcache", 0);
1.8       cgd       244:                goto loop;
                    245:        }
1.14      mycroft   246:        fdcache_lock |= FDL_LOCKED;
1.1       cgd       247:
1.14      mycroft   248:        error = getnewvnode(VT_FDESC, mp, fdesc_vnodeop_p, vpp);
1.8       cgd       249:        if (error)
                    250:                goto out;
1.14      mycroft   251:        MALLOC(fd, void *, sizeof(struct fdescnode), M_TEMP, M_WAITOK);
                    252:        (*vpp)->v_data = fd;
                    253:        fd->fd_vnode = *vpp;
                    254:        fd->fd_type = ftype;
                    255:        fd->fd_fd = -1;
                    256:        fd->fd_link = 0;
                    257:        fd->fd_ix = ix;
1.48      wrstuden  258:        VOP_LOCK(*vpp, LK_EXCLUSIVE);
1.17      mycroft   259:        LIST_INSERT_HEAD(fc, fd, fd_hash);
1.8       cgd       260:
                    261: out:;
1.14      mycroft   262:        fdcache_lock &= ~FDL_LOCKED;
1.8       cgd       263:
1.14      mycroft   264:        if (fdcache_lock & FDL_WANT) {
                    265:                fdcache_lock &= ~FDL_WANT;
1.81      jrf       266:                wakeup(&fdcache_lock);
1.8       cgd       267:        }
                    268:
                    269:        return (error);
                    270: }
1.1       cgd       271:
                    272: /*
                    273:  * vp is the current namei directory
                    274:  * ndp is the name to locate in that directory...
                    275:  */
1.14      mycroft   276: int
1.30      christos  277: fdesc_lookup(v)
                    278:        void *v;
                    279: {
1.14      mycroft   280:        struct vop_lookup_args /* {
                    281:                struct vnode * a_dvp;
                    282:                struct vnode ** a_vpp;
                    283:                struct componentname * a_cnp;
1.30      christos  284:        } */ *ap = v;
1.14      mycroft   285:        struct vnode **vpp = ap->a_vpp;
                    286:        struct vnode *dvp = ap->a_dvp;
1.44      fvdl      287:        struct componentname *cnp = ap->a_cnp;
1.77      fvdl      288:        struct proc *p = cnp->cn_proc;
1.44      fvdl      289:        const char *pname = cnp->cn_nameptr;
1.77      fvdl      290:        int nfiles = p->p_fd->fd_nfiles;
1.30      christos  291:        unsigned fd = 0;
1.1       cgd       292:        int error;
                    293:        struct vnode *fvp;
1.8       cgd       294:        char *ln;
1.1       cgd       295:
1.44      fvdl      296:        if (cnp->cn_namelen == 1 && *pname == '.') {
1.14      mycroft   297:                *vpp = dvp;
1.44      fvdl      298:                VREF(dvp);
1.1       cgd       299:                return (0);
                    300:        }
                    301:
1.8       cgd       302:        switch (VTOFDESC(dvp)->fd_type) {
                    303:        default:
                    304:        case Flink:
                    305:        case Fdesc:
                    306:        case Fctty:
                    307:                error = ENOTDIR;
                    308:                goto bad;
                    309:
                    310:        case Froot:
1.46      perry     311:                if (cnp->cn_namelen == 2 && memcmp(pname, "fd", 2) == 0) {
1.8       cgd       312:                        error = fdesc_allocvp(Fdevfd, FD_DEVFD, dvp->v_mount, &fvp);
                    313:                        if (error)
                    314:                                goto bad;
1.14      mycroft   315:                        *vpp = fvp;
1.8       cgd       316:                        fvp->v_type = VDIR;
1.48      wrstuden  317:                        goto good;
1.8       cgd       318:                }
                    319:
1.46      perry     320:                if (cnp->cn_namelen == 3 && memcmp(pname, "tty", 3) == 0) {
1.8       cgd       321:                        struct vnode *ttyvp = cttyvp(p);
                    322:                        if (ttyvp == NULL) {
                    323:                                error = ENXIO;
                    324:                                goto bad;
                    325:                        }
                    326:                        error = fdesc_allocvp(Fctty, FD_CTTY, dvp->v_mount, &fvp);
                    327:                        if (error)
                    328:                                goto bad;
1.14      mycroft   329:                        *vpp = fvp;
1.32      mrg       330:                        fvp->v_type = VCHR;
1.48      wrstuden  331:                        goto good;
1.8       cgd       332:                }
                    333:
                    334:                ln = 0;
1.44      fvdl      335:                switch (cnp->cn_namelen) {
1.8       cgd       336:                case 5:
1.46      perry     337:                        if (memcmp(pname, "stdin", 5) == 0) {
1.8       cgd       338:                                ln = "fd/0";
                    339:                                fd = FD_STDIN;
                    340:                        }
1.1       cgd       341:                        break;
1.8       cgd       342:                case 6:
1.46      perry     343:                        if (memcmp(pname, "stdout", 6) == 0) {
1.8       cgd       344:                                ln = "fd/1";
                    345:                                fd = FD_STDOUT;
                    346:                        } else
1.46      perry     347:                        if (memcmp(pname, "stderr", 6) == 0) {
1.8       cgd       348:                                ln = "fd/2";
                    349:                                fd = FD_STDERR;
                    350:                        }
                    351:                        break;
                    352:                }
                    353:
                    354:                if (ln) {
                    355:                        error = fdesc_allocvp(Flink, fd, dvp->v_mount, &fvp);
                    356:                        if (error)
                    357:                                goto bad;
                    358:                        VTOFDESC(fvp)->fd_link = ln;
1.14      mycroft   359:                        *vpp = fvp;
1.8       cgd       360:                        fvp->v_type = VLNK;
1.48      wrstuden  361:                        goto good;
1.8       cgd       362:                } else {
                    363:                        error = ENOENT;
                    364:                        goto bad;
                    365:                }
                    366:
1.14      mycroft   367:                /* FALL THROUGH */
1.8       cgd       368:
                    369:        case Fdevfd:
1.46      perry     370:                if (cnp->cn_namelen == 2 && memcmp(pname, "..", 2) == 0) {
1.48      wrstuden  371:                        VOP_UNLOCK(dvp, 0);
                    372:                        cnp->cn_flags |= PDIRUNLOCK;
1.76      thorpej   373:                        error = fdesc_root(dvp->v_mount, vpp);
1.44      fvdl      374:                        if (error)
                    375:                                goto bad;
1.48      wrstuden  376:                        /*
                    377:                         * If we're at the last component and need the
                    378:                         * parent locked, undo the unlock above.
                    379:                         */
                    380:                        if (((~cnp->cn_flags & (ISLASTCN | LOCKPARENT)) == 0) &&
                    381:                                   ((error = vn_lock(dvp, LK_EXCLUSIVE)) == 0))
                    382:                                cnp->cn_flags &= ~PDIRUNLOCK;
                    383:                        return (error);
1.8       cgd       384:                }
                    385:
                    386:                fd = 0;
                    387:                while (*pname >= '0' && *pname <= '9') {
                    388:                        fd = 10 * fd + *pname++ - '0';
                    389:                        if (fd >= nfiles)
                    390:                                break;
                    391:                }
1.1       cgd       392:
1.8       cgd       393:                if (*pname != '\0') {
                    394:                        error = ENOENT;
                    395:                        goto bad;
                    396:                }
1.1       cgd       397:
1.63      thorpej   398:                if (fd >= nfiles || p->p_fd->fd_ofiles[fd] == NULL ||
                    399:                    FILE_IS_USABLE(p->p_fd->fd_ofiles[fd]) == 0) {
1.8       cgd       400:                        error = EBADF;
                    401:                        goto bad;
                    402:                }
1.1       cgd       403:
1.8       cgd       404:                error = fdesc_allocvp(Fdesc, FD_DESC+fd, dvp->v_mount, &fvp);
                    405:                if (error)
                    406:                        goto bad;
                    407:                VTOFDESC(fvp)->fd_fd = fd;
1.14      mycroft   408:                *vpp = fvp;
1.48      wrstuden  409:                goto good;
1.8       cgd       410:        }
1.1       cgd       411:
                    412: bad:;
1.14      mycroft   413:        *vpp = NULL;
1.1       cgd       414:        return (error);
1.48      wrstuden  415:
                    416: good:;
                    417:        /*
                    418:         * As "." was special cased above, we now unlock the parent if we're
                    419:         * suppoed to. We're only supposed to not unlock if this is the
                    420:         * last component, and the caller requested LOCKPARENT. So if either
                    421:         * condition is false, unlock.
                    422:         */
                    423:        if (((~cnp->cn_flags) & (ISLASTCN | LOCKPARENT)) != 0) {
                    424:                VOP_UNLOCK(dvp, 0);
                    425:                cnp->cn_flags |= PDIRUNLOCK;
                    426:        }
                    427:        return (0);
1.1       cgd       428: }
                    429:
1.14      mycroft   430: int
1.30      christos  431: fdesc_open(v)
                    432:        void *v;
                    433: {
1.14      mycroft   434:        struct vop_open_args /* {
                    435:                struct vnode *a_vp;
                    436:                int  a_mode;
                    437:                struct ucred *a_cred;
1.77      fvdl      438:                struct proc *a_p;
1.30      christos  439:        } */ *ap = v;
1.14      mycroft   440:        struct vnode *vp = ap->a_vp;
1.8       cgd       441:
                    442:        switch (VTOFDESC(vp)->fd_type) {
                    443:        case Fdesc:
1.23      mycroft   444:                /*
1.79      jdolecek  445:                 * XXX Kludge: set dupfd to contain the value of the
1.82.6.1! yamt      446:                 * the file descriptor being sought for duplication. The error
1.23      mycroft   447:                 * return ensures that the vnode for this device will be
                    448:                 * released by vn_open. Open will detect this special error and
                    449:                 * take the actions in dupfdopen.  Other callers of vn_open or
                    450:                 * VOP_OPEN will simply report the error.
                    451:                 */
1.79      jdolecek  452:                curlwp->l_dupfd = VTOFDESC(vp)->fd_fd;  /* XXX */
1.82      christos  453:                return EDUPFD;
1.1       cgd       454:
1.8       cgd       455:        case Fctty:
1.77      fvdl      456:                return ((*ctty_cdevsw.d_open)(devctty, ap->a_mode, 0, ap->a_p));
1.30      christos  457:        case Froot:
                    458:        case Fdevfd:
                    459:        case Flink:
                    460:                break;
1.8       cgd       461:        }
1.1       cgd       462:
1.21      mycroft   463:        return (0);
1.1       cgd       464: }
                    465:
                    466: static int
1.77      fvdl      467: fdesc_attr(fd, vap, cred, p)
1.1       cgd       468:        int fd;
                    469:        struct vattr *vap;
                    470:        struct ucred *cred;
1.77      fvdl      471:        struct proc *p;
1.1       cgd       472: {
                    473:        struct filedesc *fdp = p->p_fd;
                    474:        struct file *fp;
1.8       cgd       475:        struct stat stb;
1.1       cgd       476:        int error;
                    477:
1.63      thorpej   478:        if ((fp = fd_getfile(fdp, fd)) == NULL)
1.1       cgd       479:                return (EBADF);
                    480:
                    481:        switch (fp->f_type) {
                    482:        case DTYPE_VNODE:
1.73      pk        483:                simple_unlock(&fp->f_slock);
1.77      fvdl      484:                error = VOP_GETATTR((struct vnode *) fp->f_data, vap, cred, p);
1.8       cgd       485:                if (error == 0 && vap->va_type == VDIR) {
                    486:                        /*
1.22      mycroft   487:                         * directories can cause loops in the namespace,
                    488:                         * so turn off the 'x' bits to avoid trouble.
1.8       cgd       489:                         */
1.41      mycroft   490:                        vap->va_mode &= ~(S_IXUSR|S_IXGRP|S_IXOTH);
1.8       cgd       491:                }
1.1       cgd       492:                break;
                    493:
1.69      jdolecek  494:        default:
1.61      jdolecek  495:                FILE_USE(fp);
1.69      jdolecek  496:                memset(&stb, 0, sizeof(stb));
1.77      fvdl      497:                error = (*fp->f_ops->fo_stat)(fp, &stb, p);
                    498:                FILE_UNUSE(fp, p);
1.69      jdolecek  499:                if (error)
                    500:                        break;
                    501:
                    502:                vattr_null(vap);
                    503:                switch(fp->f_type) {
                    504:                case DTYPE_SOCKET:
                    505:                        vap->va_type = VSOCK;
                    506:                        break;
                    507:                case DTYPE_PIPE:
                    508:                        vap->va_type = VFIFO;
                    509:                        break;
                    510:                default:
                    511:                        /* use VNON perhaps? */
                    512:                        vap->va_type = VBAD;
                    513:                        break;
1.8       cgd       514:                }
1.69      jdolecek  515:                vap->va_mode = stb.st_mode;
                    516:                vap->va_nlink = stb.st_nlink;
                    517:                vap->va_uid = stb.st_uid;
                    518:                vap->va_gid = stb.st_gid;
                    519:                vap->va_fsid = stb.st_dev;
                    520:                vap->va_fileid = stb.st_ino;
                    521:                vap->va_size = stb.st_size;
                    522:                vap->va_blocksize = stb.st_blksize;
                    523:                vap->va_atime = stb.st_atimespec;
                    524:                vap->va_mtime = stb.st_mtimespec;
                    525:                vap->va_ctime = stb.st_ctimespec;
                    526:                vap->va_gen = stb.st_gen;
                    527:                vap->va_flags = stb.st_flags;
                    528:                vap->va_rdev = stb.st_rdev;
                    529:                vap->va_bytes = stb.st_blocks * stb.st_blksize;
1.1       cgd       530:                break;
                    531:        }
                    532:
                    533:        return (error);
                    534: }
                    535:
1.14      mycroft   536: int
1.30      christos  537: fdesc_getattr(v)
                    538:        void *v;
                    539: {
1.14      mycroft   540:        struct vop_getattr_args /* {
                    541:                struct vnode *a_vp;
                    542:                struct vattr *a_vap;
                    543:                struct ucred *a_cred;
1.77      fvdl      544:                struct proc *a_p;
1.30      christos  545:        } */ *ap = v;
1.14      mycroft   546:        struct vnode *vp = ap->a_vp;
                    547:        struct vattr *vap = ap->a_vap;
1.1       cgd       548:        unsigned fd;
1.8       cgd       549:        int error = 0;
1.1       cgd       550:
1.8       cgd       551:        switch (VTOFDESC(vp)->fd_type) {
                    552:        case Froot:
                    553:        case Fdevfd:
                    554:        case Flink:
                    555:        case Fctty:
1.33      mrg       556:                VATTR_NULL(vap);
1.8       cgd       557:                vap->va_fileid = VTOFDESC(vp)->fd_ix;
                    558:
1.30      christos  559: #define R_ALL (S_IRUSR|S_IRGRP|S_IROTH)
                    560: #define W_ALL (S_IWUSR|S_IWGRP|S_IWOTH)
                    561: #define X_ALL (S_IXUSR|S_IXGRP|S_IXOTH)
                    562:
1.8       cgd       563:                switch (VTOFDESC(vp)->fd_type) {
                    564:                case Flink:
1.30      christos  565:                        vap->va_mode = R_ALL|X_ALL;
1.8       cgd       566:                        vap->va_type = VLNK;
1.32      mrg       567:                        vap->va_rdev = 0;
1.8       cgd       568:                        vap->va_nlink = 1;
                    569:                        vap->va_size = strlen(VTOFDESC(vp)->fd_link);
                    570:                        break;
                    571:
                    572:                case Fctty:
1.30      christos  573:                        vap->va_mode = R_ALL|W_ALL;
1.32      mrg       574:                        vap->va_type = VCHR;
                    575:                        vap->va_rdev = devctty;
1.8       cgd       576:                        vap->va_nlink = 1;
                    577:                        vap->va_size = 0;
                    578:                        break;
                    579:
                    580:                default:
1.30      christos  581:                        vap->va_mode = R_ALL|X_ALL;
1.8       cgd       582:                        vap->va_type = VDIR;
1.32      mrg       583:                        vap->va_rdev = 0;
1.8       cgd       584:                        vap->va_nlink = 2;
                    585:                        vap->va_size = DEV_BSIZE;
                    586:                        break;
                    587:                }
1.1       cgd       588:                vap->va_uid = 0;
                    589:                vap->va_gid = 0;
1.80      christos  590:                vap->va_fsid = vp->v_mount->mnt_stat.f_fsidx.__fsid_val[0];
1.1       cgd       591:                vap->va_blocksize = DEV_BSIZE;
1.28      jtc       592:                vap->va_atime.tv_sec = boottime.tv_sec;
                    593:                vap->va_atime.tv_nsec = 0;
1.1       cgd       594:                vap->va_mtime = vap->va_atime;
1.14      mycroft   595:                vap->va_ctime = vap->va_mtime;
1.1       cgd       596:                vap->va_gen = 0;
                    597:                vap->va_flags = 0;
                    598:                vap->va_bytes = 0;
1.8       cgd       599:                break;
                    600:
                    601:        case Fdesc:
                    602:                fd = VTOFDESC(vp)->fd_fd;
1.77      fvdl      603:                error = fdesc_attr(fd, vap, ap->a_cred, ap->a_p);
1.8       cgd       604:                break;
                    605:
                    606:        default:
                    607:                panic("fdesc_getattr");
1.82.6.1! yamt      608:                break;
1.1       cgd       609:        }
                    610:
                    611:        if (error == 0)
                    612:                vp->v_type = vap->va_type;
1.8       cgd       613:
1.1       cgd       614:        return (error);
                    615: }
                    616:
1.14      mycroft   617: int
1.30      christos  618: fdesc_setattr(v)
                    619:        void *v;
                    620: {
1.14      mycroft   621:        struct vop_setattr_args /* {
                    622:                struct vnode *a_vp;
                    623:                struct vattr *a_vap;
                    624:                struct ucred *a_cred;
1.77      fvdl      625:                struct proc *a_p;
1.30      christos  626:        } */ *ap = v;
1.77      fvdl      627:        struct filedesc *fdp = ap->a_p->p_fd;
1.73      pk        628:        struct file *fp;
1.1       cgd       629:        unsigned fd;
                    630:
                    631:        /*
                    632:         * Can't mess with the root vnode
                    633:         */
1.14      mycroft   634:        switch (VTOFDESC(ap->a_vp)->fd_type) {
1.8       cgd       635:        case Fdesc:
                    636:                break;
                    637:
                    638:        case Fctty:
                    639:                return (0);
                    640:
                    641:        default:
1.1       cgd       642:                return (EACCES);
1.8       cgd       643:        }
1.1       cgd       644:
1.14      mycroft   645:        fd = VTOFDESC(ap->a_vp)->fd_fd;
1.73      pk        646:        if ((fp = fd_getfile(fdp, fd)) == NULL)
1.1       cgd       647:                return (EBADF);
                    648:
                    649:        /*
1.68      jmc       650:         * XXX: Can't reasonably set the attr's on any types currently.
                    651:         *      On vnode's this will cause truncation and socket/pipes make
                    652:         *      no sense.
1.1       cgd       653:         */
1.73      pk        654:        simple_unlock(&fp->f_slock);
1.69      jdolecek  655:        return (0);
1.1       cgd       656: }
                    657:
1.25      mycroft   658: #define UIO_MX 32
1.8       cgd       659:
1.25      mycroft   660: struct fdesc_target {
                    661:        ino_t ft_fileno;
                    662:        u_char ft_type;
                    663:        u_char ft_namlen;
                    664:        char *ft_name;
                    665: } fdesc_targets[] = {
                    666: /* NOTE: The name must be less than UIO_MX-16 chars in length */
                    667: #define N(s) sizeof(s)-1, s
                    668:        { FD_DEVFD,  DT_DIR,     N("fd")     },
1.27      mycroft   669:        { FD_STDIN,  DT_LNK,     N("stdin")  },
                    670:        { FD_STDOUT, DT_LNK,     N("stdout") },
                    671:        { FD_STDERR, DT_LNK,     N("stderr") },
1.25      mycroft   672:        { FD_CTTY,   DT_UNKNOWN, N("tty")    },
                    673: #undef N
1.8       cgd       674: };
1.25      mycroft   675: static int nfdesc_targets = sizeof(fdesc_targets) / sizeof(fdesc_targets[0]);
1.8       cgd       676:
1.14      mycroft   677: int
1.30      christos  678: fdesc_readdir(v)
                    679:        void *v;
                    680: {
1.14      mycroft   681:        struct vop_readdir_args /* {
                    682:                struct vnode *a_vp;
                    683:                struct uio *a_uio;
                    684:                struct ucred *a_cred;
1.22      mycroft   685:                int *a_eofflag;
1.44      fvdl      686:                off_t **a_cookies;
                    687:                int *a_ncookies;
1.30      christos  688:        } */ *ap = v;
1.14      mycroft   689:        struct uio *uio = ap->a_uio;
1.25      mycroft   690:        struct dirent d;
1.1       cgd       691:        struct filedesc *fdp;
1.53      sommerfe  692:        off_t i;
1.1       cgd       693:        int error;
1.44      fvdl      694:        off_t *cookies = NULL;
                    695:        int ncookies = 0;
1.11      ws        696:
1.14      mycroft   697:        switch (VTOFDESC(ap->a_vp)->fd_type) {
1.8       cgd       698:        case Fctty:
                    699:                return (0);
                    700:
                    701:        case Fdesc:
                    702:                return (ENOTDIR);
1.30      christos  703:
                    704:        default:
                    705:                break;
1.8       cgd       706:        }
1.1       cgd       707:
1.77      fvdl      708:        fdp = uio->uio_procp->p_fd;
1.8       cgd       709:
1.25      mycroft   710:        if (uio->uio_resid < UIO_MX)
                    711:                return (EINVAL);
1.26      mycroft   712:        if (uio->uio_offset < 0)
1.25      mycroft   713:                return (EINVAL);
                    714:
                    715:        error = 0;
1.26      mycroft   716:        i = uio->uio_offset;
1.81      jrf       717:        memset(&d, 0, UIO_MX);
1.25      mycroft   718:        d.d_reclen = UIO_MX;
1.44      fvdl      719:        if (ap->a_ncookies)
                    720:                ncookies = (uio->uio_resid / UIO_MX);
1.25      mycroft   721:
1.14      mycroft   722:        if (VTOFDESC(ap->a_vp)->fd_type == Froot) {
1.25      mycroft   723:                struct fdesc_target *ft;
1.51      christos  724:
                    725:                if (i >= nfdesc_targets)
1.52      sommerfe  726:                        return 0;
1.3       cgd       727:
1.44      fvdl      728:                if (ap->a_ncookies) {
                    729:                        ncookies = min(ncookies, (nfdesc_targets - i));
1.56      thorpej   730:                        cookies = malloc(ncookies * sizeof(off_t),
1.44      fvdl      731:                            M_TEMP, M_WAITOK);
                    732:                        *ap->a_cookies = cookies;
                    733:                        *ap->a_ncookies = ncookies;
                    734:                }
                    735:
1.25      mycroft   736:                for (ft = &fdesc_targets[i];
                    737:                     uio->uio_resid >= UIO_MX && i < nfdesc_targets; ft++, i++) {
                    738:                        switch (ft->ft_fileno) {
1.8       cgd       739:                        case FD_CTTY:
1.77      fvdl      740:                                if (cttyvp(uio->uio_procp) == NULL)
1.8       cgd       741:                                        continue;
                    742:                                break;
                    743:
                    744:                        case FD_STDIN:
                    745:                        case FD_STDOUT:
                    746:                        case FD_STDERR:
1.25      mycroft   747:                                if ((ft->ft_fileno - FD_STDIN) >= fdp->fd_nfiles)
1.8       cgd       748:                                        continue;
1.63      thorpej   749:                                if (fdp->fd_ofiles[ft->ft_fileno - FD_STDIN] == NULL
                    750:                                    || FILE_IS_USABLE(fdp->fd_ofiles[ft->ft_fileno - FD_STDIN]) == 0)
1.8       cgd       751:                                        continue;
                    752:                                break;
                    753:                        }
1.25      mycroft   754:
                    755:                        d.d_fileno = ft->ft_fileno;
                    756:                        d.d_namlen = ft->ft_namlen;
1.46      perry     757:                        memcpy(d.d_name, ft->ft_name, ft->ft_namlen + 1);
1.25      mycroft   758:                        d.d_type = ft->ft_type;
                    759:
1.81      jrf       760:                        if ((error = uiomove(&d, UIO_MX, uio)) != 0)
1.8       cgd       761:                                break;
1.44      fvdl      762:                        if (cookies)
1.26      mycroft   763:                                *cookies++ = i + 1;
1.3       cgd       764:                }
1.25      mycroft   765:        } else {
1.44      fvdl      766:                if (ap->a_ncookies) {
                    767:                        ncookies = min(ncookies, (fdp->fd_nfiles + 2));
1.56      thorpej   768:                        cookies = malloc(ncookies * sizeof(off_t),
                    769:                            M_TEMP, M_WAITOK);
1.44      fvdl      770:                        *ap->a_cookies = cookies;
                    771:                        *ap->a_ncookies = ncookies;
                    772:                }
1.25      mycroft   773:                for (; i - 2 < fdp->fd_nfiles && uio->uio_resid >= UIO_MX;
                    774:                     i++) {
                    775:                        switch (i) {
                    776:                        case 0:
                    777:                        case 1:
                    778:                                d.d_fileno = FD_ROOT;           /* XXX */
                    779:                                d.d_namlen = i + 1;
1.46      perry     780:                                memcpy(d.d_name, "..", d.d_namlen);
1.25      mycroft   781:                                d.d_name[i + 1] = '\0';
                    782:                                d.d_type = DT_DIR;
                    783:                                break;
1.82.6.1! yamt      784:
1.25      mycroft   785:                        default:
1.63      thorpej   786:                                if (fdp->fd_ofiles[i - 2] == NULL ||
                    787:                                    FILE_IS_USABLE(fdp->fd_ofiles[i - 2]) == 0)
1.25      mycroft   788:                                        continue;
                    789:                                d.d_fileno = i - 2 + FD_STDIN;
1.53      sommerfe  790:                                d.d_namlen = sprintf(d.d_name, "%d", (int) i - 2);
1.25      mycroft   791:                                d.d_type = DT_UNKNOWN;
                    792:                                break;
                    793:                        }
1.8       cgd       794:
1.81      jrf       795:                        if ((error = uiomove(&d, UIO_MX, uio)) != 0)
1.1       cgd       796:                                break;
1.44      fvdl      797:                        if (cookies)
1.26      mycroft   798:                                *cookies++ = i + 1;
1.1       cgd       799:                }
1.8       cgd       800:        }
                    801:
1.44      fvdl      802:        if (ap->a_ncookies && error) {
1.56      thorpej   803:                free(*ap->a_cookies, M_TEMP);
1.44      fvdl      804:                *ap->a_ncookies = 0;
                    805:                *ap->a_cookies = NULL;
                    806:        }
                    807:
1.26      mycroft   808:        uio->uio_offset = i;
1.8       cgd       809:        return (error);
                    810: }
                    811:
1.14      mycroft   812: int
1.30      christos  813: fdesc_readlink(v)
                    814:        void *v;
                    815: {
1.14      mycroft   816:        struct vop_readlink_args /* {
                    817:                struct vnode *a_vp;
                    818:                struct uio *a_uio;
                    819:                struct ucred *a_cred;
1.30      christos  820:        } */ *ap = v;
1.14      mycroft   821:        struct vnode *vp = ap->a_vp;
1.8       cgd       822:        int error;
                    823:
1.14      mycroft   824:        if (vp->v_type != VLNK)
                    825:                return (EPERM);
                    826:
1.8       cgd       827:        if (VTOFDESC(vp)->fd_type == Flink) {
                    828:                char *ln = VTOFDESC(vp)->fd_link;
1.14      mycroft   829:                error = uiomove(ln, strlen(ln), ap->a_uio);
1.8       cgd       830:        } else {
                    831:                error = EOPNOTSUPP;
                    832:        }
                    833:
                    834:        return (error);
                    835: }
                    836:
1.14      mycroft   837: int
1.30      christos  838: fdesc_read(v)
                    839:        void *v;
                    840: {
1.14      mycroft   841:        struct vop_read_args /* {
                    842:                struct vnode *a_vp;
                    843:                struct uio *a_uio;
                    844:                int  a_ioflag;
                    845:                struct ucred *a_cred;
1.30      christos  846:        } */ *ap = v;
1.8       cgd       847:        int error = EOPNOTSUPP;
1.49      thorpej   848:        struct vnode *vp = ap->a_vp;
1.8       cgd       849:
1.49      thorpej   850:        switch (VTOFDESC(vp)->fd_type) {
1.8       cgd       851:        case Fctty:
1.49      thorpej   852:                VOP_UNLOCK(vp, 0);
1.70      gehenna   853:                error = (*ctty_cdevsw.d_read)(devctty, ap->a_uio, ap->a_ioflag);
1.49      thorpej   854:                vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
1.8       cgd       855:                break;
                    856:
                    857:        default:
                    858:                error = EOPNOTSUPP;
                    859:                break;
                    860:        }
1.82.6.1! yamt      861:
1.8       cgd       862:        return (error);
                    863: }
                    864:
1.14      mycroft   865: int
1.30      christos  866: fdesc_write(v)
                    867:        void *v;
                    868: {
1.14      mycroft   869:        struct vop_write_args /* {
                    870:                struct vnode *a_vp;
                    871:                struct uio *a_uio;
                    872:                int  a_ioflag;
                    873:                struct ucred *a_cred;
1.30      christos  874:        } */ *ap = v;
1.8       cgd       875:        int error = EOPNOTSUPP;
1.49      thorpej   876:        struct vnode *vp = ap->a_vp;
1.8       cgd       877:
1.49      thorpej   878:        switch (VTOFDESC(vp)->fd_type) {
1.8       cgd       879:        case Fctty:
1.49      thorpej   880:                VOP_UNLOCK(vp, 0);
1.70      gehenna   881:                error = (*ctty_cdevsw.d_write)(devctty, ap->a_uio,
                    882:                                               ap->a_ioflag);
1.49      thorpej   883:                vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
1.8       cgd       884:                break;
                    885:
                    886:        default:
                    887:                error = EOPNOTSUPP;
                    888:                break;
                    889:        }
1.82.6.1! yamt      890:
1.8       cgd       891:        return (error);
                    892: }
                    893:
1.14      mycroft   894: int
1.30      christos  895: fdesc_ioctl(v)
                    896:        void *v;
                    897: {
1.14      mycroft   898:        struct vop_ioctl_args /* {
                    899:                struct vnode *a_vp;
1.19      cgd       900:                u_long a_command;
1.81      jrf       901:                void *a_data;
1.14      mycroft   902:                int  a_fflag;
                    903:                struct ucred *a_cred;
1.77      fvdl      904:                struct proc *a_p;
1.30      christos  905:        } */ *ap = v;
1.8       cgd       906:        int error = EOPNOTSUPP;
                    907:
1.14      mycroft   908:        switch (VTOFDESC(ap->a_vp)->fd_type) {
1.8       cgd       909:        case Fctty:
1.70      gehenna   910:                error = (*ctty_cdevsw.d_ioctl)(devctty, ap->a_command,
                    911:                                               ap->a_data, ap->a_fflag,
1.77      fvdl      912:                                               ap->a_p);
1.8       cgd       913:                break;
                    914:
                    915:        default:
                    916:                error = EOPNOTSUPP;
                    917:                break;
1.1       cgd       918:        }
1.82.6.1! yamt      919:
1.8       cgd       920:        return (error);
                    921: }
                    922:
1.14      mycroft   923: int
1.35      mycroft   924: fdesc_poll(v)
1.30      christos  925:        void *v;
                    926: {
1.35      mycroft   927:        struct vop_poll_args /* {
1.14      mycroft   928:                struct vnode *a_vp;
1.35      mycroft   929:                int a_events;
1.77      fvdl      930:                struct proc *a_p;
1.30      christos  931:        } */ *ap = v;
1.35      mycroft   932:        int revents;
1.8       cgd       933:
1.14      mycroft   934:        switch (VTOFDESC(ap->a_vp)->fd_type) {
1.8       cgd       935:        case Fctty:
1.77      fvdl      936:                revents = (*ctty_cdevsw.d_poll)(devctty, ap->a_events, ap->a_p);
1.8       cgd       937:                break;
1.1       cgd       938:
1.8       cgd       939:        default:
1.35      mycroft   940:                revents = genfs_poll(v);
1.8       cgd       941:                break;
                    942:        }
1.34      mycroft   943:
1.35      mycroft   944:        return (revents);
1.71      jdolecek  945: }
                    946:
                    947: int
                    948: fdesc_kqfilter(v)
                    949:        void *v;
                    950: {
                    951:        struct vop_kqfilter_args /* {
                    952:                struct vnode *a_vp;
                    953:                struct knote *a_kn;
                    954:        } */ *ap = v;
                    955:        int error;
                    956:        struct proc *p;
                    957:        struct file *fp;
                    958:
                    959:        switch (VTOFDESC(ap->a_vp)->fd_type) {
                    960:        case Fctty:
                    961:                error = (*ctty_cdevsw.d_kqfilter)(devctty, ap->a_kn);
                    962:                break;
                    963:
                    964:        case Fdesc:
                    965:                /* just invoke kqfilter for the underlying descriptor */
1.77      fvdl      966:                p = curproc;    /* XXX hopefully ok to use curproc here */
1.71      jdolecek  967:                if ((fp = fd_getfile(p->p_fd, VTOFDESC(ap->a_vp)->fd_fd)) == NULL)
                    968:                        return (1);
1.82.6.1! yamt      969:
1.71      jdolecek  970:                FILE_USE(fp);
                    971:                error = (*fp->f_ops->fo_kqfilter)(fp, ap->a_kn);
1.77      fvdl      972:                FILE_UNUSE(fp, p);
1.71      jdolecek  973:                break;
                    974:
                    975:        default:
                    976:                return (genfs_kqfilter(v));
                    977:        }
                    978:
                    979:        return (error);
1.1       cgd       980: }
                    981:
1.14      mycroft   982: int
1.30      christos  983: fdesc_inactive(v)
                    984:        void *v;
                    985: {
1.14      mycroft   986:        struct vop_inactive_args /* {
                    987:                struct vnode *a_vp;
1.77      fvdl      988:                struct proc *a_p;
1.30      christos  989:        } */ *ap = v;
1.14      mycroft   990:        struct vnode *vp = ap->a_vp;
                    991:
1.1       cgd       992:        /*
                    993:         * Clear out the v_type field to avoid
                    994:         * nasty things happening in vgone().
                    995:         */
1.44      fvdl      996:        VOP_UNLOCK(vp, 0);
1.1       cgd       997:        vp->v_type = VNON;
                    998:        return (0);
                    999: }
                   1000:
1.14      mycroft  1001: int
1.30      christos 1002: fdesc_reclaim(v)
                   1003:        void *v;
                   1004: {
1.14      mycroft  1005:        struct vop_reclaim_args /* {
                   1006:                struct vnode *a_vp;
1.30      christos 1007:        } */ *ap = v;
1.14      mycroft  1008:        struct vnode *vp = ap->a_vp;
1.17      mycroft  1009:        struct fdescnode *fd = VTOFDESC(vp);
1.14      mycroft  1010:
1.17      mycroft  1011:        LIST_REMOVE(fd, fd_hash);
1.14      mycroft  1012:        FREE(vp->v_data, M_TEMP);
                   1013:        vp->v_data = 0;
                   1014:
                   1015:        return (0);
                   1016: }
                   1017:
                   1018: /*
                   1019:  * Return POSIX pathconf information applicable to special devices.
                   1020:  */
1.30      christos 1021: int
                   1022: fdesc_pathconf(v)
                   1023:        void *v;
                   1024: {
1.14      mycroft  1025:        struct vop_pathconf_args /* {
                   1026:                struct vnode *a_vp;
                   1027:                int a_name;
1.18      cgd      1028:                register_t *a_retval;
1.30      christos 1029:        } */ *ap = v;
1.8       cgd      1030:
1.14      mycroft  1031:        switch (ap->a_name) {
                   1032:        case _PC_LINK_MAX:
                   1033:                *ap->a_retval = LINK_MAX;
                   1034:                return (0);
                   1035:        case _PC_MAX_CANON:
                   1036:                *ap->a_retval = MAX_CANON;
                   1037:                return (0);
                   1038:        case _PC_MAX_INPUT:
                   1039:                *ap->a_retval = MAX_INPUT;
                   1040:                return (0);
                   1041:        case _PC_PIPE_BUF:
                   1042:                *ap->a_retval = PIPE_BUF;
                   1043:                return (0);
                   1044:        case _PC_CHOWN_RESTRICTED:
                   1045:                *ap->a_retval = 1;
                   1046:                return (0);
                   1047:        case _PC_VDISABLE:
                   1048:                *ap->a_retval = _POSIX_VDISABLE;
1.45      kleink   1049:                return (0);
                   1050:        case _PC_SYNC_IO:
                   1051:                *ap->a_retval = 1;
1.14      mycroft  1052:                return (0);
                   1053:        default:
                   1054:                return (EINVAL);
1.8       cgd      1055:        }
1.14      mycroft  1056:        /* NOTREACHED */
1.8       cgd      1057: }
                   1058:
1.1       cgd      1059: /*
                   1060:  * Print out the contents of a /dev/fd vnode.
                   1061:  */
                   1062: /* ARGSUSED */
1.14      mycroft  1063: int
1.30      christos 1064: fdesc_print(v)
                   1065:        void *v;
1.1       cgd      1066: {
1.37      christos 1067:        printf("tag VT_NON, fdesc vnode\n");
1.14      mycroft  1068:        return (0);
                   1069: }
                   1070:
                   1071: int
1.82.6.1! yamt     1072: fdesc_link(v)
1.30      christos 1073:        void *v;
                   1074: {
1.29      mycroft  1075:        struct vop_link_args /* {
                   1076:                struct vnode *a_dvp;
1.82.6.1! yamt     1077:                struct vnode *a_vp;
1.29      mycroft  1078:                struct componentname *a_cnp;
1.30      christos 1079:        } */ *ap = v;
1.82.6.1! yamt     1080:
1.29      mycroft  1081:        VOP_ABORTOP(ap->a_dvp, ap->a_cnp);
                   1082:        vput(ap->a_dvp);
                   1083:        return (EROFS);
                   1084: }
                   1085:
                   1086: int
1.30      christos 1087: fdesc_symlink(v)
                   1088:        void *v;
                   1089: {
1.29      mycroft  1090:        struct vop_symlink_args /* {
                   1091:                struct vnode *a_dvp;
                   1092:                struct vnode **a_vpp;
                   1093:                struct componentname *a_cnp;
                   1094:                struct vattr *a_vap;
                   1095:                char *a_target;
1.30      christos 1096:        } */ *ap = v;
1.82.6.1! yamt     1097:
1.29      mycroft  1098:        VOP_ABORTOP(ap->a_dvp, ap->a_cnp);
                   1099:        vput(ap->a_dvp);
                   1100:        return (EROFS);
1.1       cgd      1101: }

CVSweb <webmaster@jp.NetBSD.org>