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

Annotation of src/sys/miscfs/kernfs/kernfs_vnops.c, Revision 1.100

1.100   ! cl          1: /*     $NetBSD: kernfs_vnops.c,v 1.99 2004/04/29 16:10:55 jrf Exp $    */
1.27      cgd         2:
1.1       cgd         3: /*
1.23      mycroft     4:  * Copyright (c) 1992, 1993
                      5:  *     The Regents of the University of California.  All rights reserved.
1.1       cgd         6:  *
1.17      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.89      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.57      fvdl       34:  *     @(#)kernfs_vnops.c      8.15 (Berkeley) 5/21/95
1.1       cgd        35:  */
                     36:
                     37: /*
1.23      mycroft    38:  * Kernel parameter filesystem (/kern)
1.1       cgd        39:  */
1.77      lukem      40:
                     41: #include <sys/cdefs.h>
1.100   ! cl         42: __KERNEL_RCSID(0, "$NetBSD: kernfs_vnops.c,v 1.99 2004/04/29 16:10:55 jrf Exp $");
1.90      itojun     43:
                     44: #ifdef _KERNEL_OPT
                     45: #include "opt_ipsec.h"
                     46: #endif
1.55      mrg        47:
1.14      mycroft    48: #include <sys/param.h>
                     49: #include <sys/systm.h>
                     50: #include <sys/kernel.h>
1.23      mycroft    51: #include <sys/vmmeter.h>
1.14      mycroft    52: #include <sys/time.h>
                     53: #include <sys/proc.h>
1.23      mycroft    54: #include <sys/vnode.h>
                     55: #include <sys/malloc.h>
1.14      mycroft    56: #include <sys/file.h>
                     57: #include <sys/stat.h>
                     58: #include <sys/mount.h>
                     59: #include <sys/namei.h>
                     60: #include <sys/buf.h>
1.23      mycroft    61: #include <sys/dirent.h>
1.28      mycroft    62: #include <sys/msgbuf.h>
1.44      mycroft    63:
                     64: #include <miscfs/genfs/genfs.h>
1.17      cgd        65: #include <miscfs/kernfs/kernfs.h>
1.63      mrg        66:
1.90      itojun     67: #ifdef IPSEC
                     68: #include <sys/mbuf.h>
                     69: #include <net/route.h>
                     70: #include <netinet/in.h>
                     71: #include <netinet6/ipsec.h>
                     72: #include <netkey/key.h>
                     73: #endif
                     74:
1.54      mrg        75: #include <uvm/uvm_extern.h>
                     76:
1.17      cgd        77: #define KSTRING        256             /* Largest I/O available via this filesystem */
                     78: #define        UIO_MX 32
1.1       cgd        79:
1.23      mycroft    80: #define        READ_MODE       (S_IRUSR|S_IRGRP|S_IROTH)
                     81: #define        WRITE_MODE      (S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH)
                     82: #define DIR_MODE       (S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)
1.90      itojun     83: #define UDIR_MODE      (S_IRUSR|S_IXUSR)
1.23      mycroft    84:
1.90      itojun     85: #define N(s) sizeof(s)-1, s
1.75      jdolecek   86: const struct kern_target kern_targets[] = {
1.1       cgd        87: /* NOTE: The name must be less than UIO_MX-16 chars in length */
1.23      mycroft    88:      /*        name            data          tag           type  ro/rw */
1.98      darcy      89:      { DT_DIR, N("."),         0,            KFSkern,        VDIR, DIR_MODE   },
                     90:      { DT_DIR, N(".."),        0,            KFSroot,        VDIR, DIR_MODE   },
                     91:      { DT_REG, N("boottime"),  &boottime.tv_sec, KFSint,     VREG, READ_MODE  },
1.69      thorpej    92:                        /* XXX cast away const */
                     93:      { DT_REG, N("copyright"), (void *)copyright,
1.98      darcy      94:                                             KFSstring,      VREG, READ_MODE  },
                     95:      { DT_REG, N("hostname"),  0,            KFShostname,    VREG, WRITE_MODE },
                     96:      { DT_REG, N("hz"),        &hz,          KFSint,         VREG, READ_MODE  },
1.90      itojun     97: #ifdef IPSEC
1.98      darcy      98:      { DT_DIR, N("ipsecsa"),   0,           KFSipsecsadir,  VDIR, UDIR_MODE  },
                     99:      { DT_DIR, N("ipsecsp"),   0,           KFSipsecspdir,  VDIR, UDIR_MODE  },
1.90      itojun    100: #endif
1.98      darcy     101:      { DT_REG, N("loadavg"),   0,            KFSavenrun,     VREG, READ_MODE  },
                    102:      { DT_REG, N("msgbuf"),    0,           KFSmsgbuf,      VREG, READ_MODE  },
                    103:      { DT_REG, N("pagesize"),  &uvmexp.pagesize, KFSint,     VREG, READ_MODE  },
                    104:      { DT_REG, N("physmem"),   &physmem,     KFSint,         VREG, READ_MODE  },
1.17      cgd       105: #if 0
1.98      darcy     106:      { DT_DIR, N("root"),      0,            KFSnull,        VDIR, DIR_MODE   },
1.17      cgd       107: #endif
1.98      darcy     108:      { DT_BLK, N("rootdev"),   &rootdev,     KFSdevice,      VBLK, READ_MODE  },
                    109:      { DT_CHR, N("rrootdev"),  &rrootdev,    KFSdevice,      VCHR, READ_MODE  },
                    110:      { DT_REG, N("time"),      0,            KFStime,        VREG, READ_MODE  },
1.69      thorpej   111:                        /* XXX cast away const */
                    112:      { DT_REG, N("version"),   (void *)version,
1.98      darcy     113:                                             KFSstring,      VREG, READ_MODE  },
1.90      itojun    114: };
                    115: #ifdef IPSEC
                    116: const struct kern_target ipsecsa_targets[] = {
                    117: /* NOTE: The name must be less than UIO_MX-16 chars in length */
                    118:      /*        name            data          tag           type  ro/rw */
1.98      darcy     119:      { DT_DIR, N("."),         0,            KFSipsecsadir,  VDIR, DIR_MODE   },
                    120:      { DT_DIR, N(".."),        0,            KFSkern,        VDIR, DIR_MODE   },
1.90      itojun    121: };
                    122: const struct kern_target ipsecsp_targets[] = {
                    123: /* NOTE: The name must be less than UIO_MX-16 chars in length */
                    124:      /*        name            data          tag           type  ro/rw */
1.98      darcy     125:      { DT_DIR, N("."),         0,            KFSipsecspdir,  VDIR, DIR_MODE   },
                    126:      { DT_DIR, N(".."),        0,            KFSkern,        VDIR, DIR_MODE   },
1.90      itojun    127: };
                    128: #endif
1.23      mycroft   129: #undef N
1.90      itojun    130: int nkern_targets = sizeof(kern_targets) / sizeof(kern_targets[0]);
                    131: #ifdef IPSEC
                    132: int nipsecsa_targets = sizeof(ipsecsa_targets) / sizeof(ipsecsa_targets[0]);
                    133: int nipsecsp_targets = sizeof(ipsecsp_targets) / sizeof(ipsecsp_targets[0]);
                    134: #endif
                    135:
1.1       cgd       136:
1.41      christos  137: int    kernfs_lookup   __P((void *));
1.85      jdolecek  138: #define        kernfs_create   genfs_eopnotsupp
                    139: #define        kernfs_mknod    genfs_eopnotsupp
1.90      itojun    140: int    kernfs_open     __P((void *));
                    141: int    kernfs_close    __P((void *));
1.41      christos  142: int    kernfs_access   __P((void *));
                    143: int    kernfs_getattr  __P((void *));
                    144: int    kernfs_setattr  __P((void *));
                    145: int    kernfs_read     __P((void *));
                    146: int    kernfs_write    __P((void *));
1.65      wrstuden  147: #define        kernfs_fcntl    genfs_fcntl
1.61      matthias  148: #define        kernfs_ioctl    genfs_enoioctl
1.45      mycroft   149: #define        kernfs_poll     genfs_poll
1.57      fvdl      150: #define kernfs_revoke  genfs_revoke
1.44      mycroft   151: #define        kernfs_fsync    genfs_nullop
                    152: #define        kernfs_seek     genfs_nullop
1.85      jdolecek  153: #define        kernfs_remove   genfs_eopnotsupp
1.41      christos  154: int    kernfs_link     __P((void *));
1.85      jdolecek  155: #define        kernfs_rename   genfs_eopnotsupp
                    156: #define        kernfs_mkdir    genfs_eopnotsupp
                    157: #define        kernfs_rmdir    genfs_eopnotsupp
1.41      christos  158: int    kernfs_symlink  __P((void *));
                    159: int    kernfs_readdir  __P((void *));
1.44      mycroft   160: #define        kernfs_readlink genfs_eopnotsupp
                    161: #define        kernfs_abortop  genfs_abortop
1.41      christos  162: int    kernfs_inactive __P((void *));
                    163: int    kernfs_reclaim  __P((void *));
1.64      wrstuden  164: #define        kernfs_lock     genfs_lock
                    165: #define        kernfs_unlock   genfs_unlock
1.44      mycroft   166: #define        kernfs_bmap     genfs_badop
                    167: #define        kernfs_strategy genfs_badop
1.41      christos  168: int    kernfs_print    __P((void *));
1.64      wrstuden  169: #define        kernfs_islocked genfs_islocked
1.41      christos  170: int    kernfs_pathconf __P((void *));
1.62      kleink    171: #define        kernfs_advlock  genfs_einval
1.44      mycroft   172: #define        kernfs_blkatoff genfs_eopnotsupp
                    173: #define        kernfs_valloc   genfs_eopnotsupp
                    174: #define        kernfs_vfree    genfs_nullop
                    175: #define        kernfs_truncate genfs_eopnotsupp
                    176: #define        kernfs_update   genfs_nullop
                    177: #define        kernfs_bwrite   genfs_eopnotsupp
1.79      chs       178: #define        kernfs_putpages genfs_putpages
1.41      christos  179:
1.90      itojun    180: static int     kernfs_xread __P((struct kernfs_node *, int, char **, size_t, size_t *));
                    181: static int     kernfs_xwrite __P((const struct kernfs_node *, char *, size_t));
1.41      christos  182:
                    183: int (**kernfs_vnodeop_p) __P((void *));
1.71      jdolecek  184: const struct vnodeopv_entry_desc kernfs_vnodeop_entries[] = {
1.41      christos  185:        { &vop_default_desc, vn_default_error },
1.44      mycroft   186:        { &vop_lookup_desc, kernfs_lookup },            /* lookup */
                    187:        { &vop_create_desc, kernfs_create },            /* create */
                    188:        { &vop_mknod_desc, kernfs_mknod },              /* mknod */
                    189:        { &vop_open_desc, kernfs_open },                /* open */
                    190:        { &vop_close_desc, kernfs_close },              /* close */
                    191:        { &vop_access_desc, kernfs_access },            /* access */
                    192:        { &vop_getattr_desc, kernfs_getattr },          /* getattr */
                    193:        { &vop_setattr_desc, kernfs_setattr },          /* setattr */
                    194:        { &vop_read_desc, kernfs_read },                /* read */
                    195:        { &vop_write_desc, kernfs_write },              /* write */
1.65      wrstuden  196:        { &vop_fcntl_desc, kernfs_fcntl },              /* fcntl */
1.44      mycroft   197:        { &vop_ioctl_desc, kernfs_ioctl },              /* ioctl */
1.45      mycroft   198:        { &vop_poll_desc, kernfs_poll },                /* poll */
1.57      fvdl      199:        { &vop_revoke_desc, kernfs_revoke },            /* revoke */
1.44      mycroft   200:        { &vop_fsync_desc, kernfs_fsync },              /* fsync */
                    201:        { &vop_seek_desc, kernfs_seek },                /* seek */
                    202:        { &vop_remove_desc, kernfs_remove },            /* remove */
                    203:        { &vop_link_desc, kernfs_link },                /* link */
                    204:        { &vop_rename_desc, kernfs_rename },            /* rename */
                    205:        { &vop_mkdir_desc, kernfs_mkdir },              /* mkdir */
                    206:        { &vop_rmdir_desc, kernfs_rmdir },              /* rmdir */
                    207:        { &vop_symlink_desc, kernfs_symlink },          /* symlink */
                    208:        { &vop_readdir_desc, kernfs_readdir },          /* readdir */
                    209:        { &vop_readlink_desc, kernfs_readlink },        /* readlink */
                    210:        { &vop_abortop_desc, kernfs_abortop },          /* abortop */
                    211:        { &vop_inactive_desc, kernfs_inactive },        /* inactive */
                    212:        { &vop_reclaim_desc, kernfs_reclaim },          /* reclaim */
                    213:        { &vop_lock_desc, kernfs_lock },                /* lock */
                    214:        { &vop_unlock_desc, kernfs_unlock },            /* unlock */
                    215:        { &vop_bmap_desc, kernfs_bmap },                /* bmap */
                    216:        { &vop_strategy_desc, kernfs_strategy },        /* strategy */
                    217:        { &vop_print_desc, kernfs_print },              /* print */
                    218:        { &vop_islocked_desc, kernfs_islocked },        /* islocked */
                    219:        { &vop_pathconf_desc, kernfs_pathconf },        /* pathconf */
                    220:        { &vop_advlock_desc, kernfs_advlock },          /* advlock */
                    221:        { &vop_blkatoff_desc, kernfs_blkatoff },        /* blkatoff */
                    222:        { &vop_valloc_desc, kernfs_valloc },            /* valloc */
                    223:        { &vop_vfree_desc, kernfs_vfree },              /* vfree */
                    224:        { &vop_truncate_desc, kernfs_truncate },        /* truncate */
                    225:        { &vop_update_desc, kernfs_update },            /* update */
                    226:        { &vop_bwrite_desc, kernfs_bwrite },            /* bwrite */
1.79      chs       227:        { &vop_putpages_desc, kernfs_putpages },        /* putpages */
1.76      chs       228:        { NULL, NULL }
1.41      christos  229: };
1.71      jdolecek  230: const struct vnodeopv_desc kernfs_vnodeop_opv_desc =
1.41      christos  231:        { &kernfs_vnodeop_p, kernfs_vnodeop_entries };
                    232:
1.82      jdolecek  233: static int
1.90      itojun    234: kernfs_xread(kfs, off, bufp, len, wrlen)
                    235:        struct kernfs_node *kfs;
1.28      mycroft   236:        int off;
                    237:        char **bufp;
1.82      jdolecek  238:        size_t len;
                    239:        size_t *wrlen;
1.1       cgd       240: {
1.90      itojun    241:        const struct kern_target *kt;
                    242: #ifdef IPSEC
                    243:        struct mbuf *m;
                    244: #endif
                    245:
                    246:        kt = kfs->kfs_kt;
1.1       cgd       247:
1.90      itojun    248:        switch (kfs->kfs_type) {
1.98      darcy     249:        case KFStime: {
1.1       cgd       250:                struct timeval tv;
1.28      mycroft   251:
1.1       cgd       252:                microtime(&tv);
1.90      itojun    253:                snprintf(*bufp, len, "%ld %ld\n", tv.tv_sec, tv.tv_usec);
1.1       cgd       254:                break;
                    255:        }
                    256:
1.98      darcy     257:        case KFSint: {
1.1       cgd       258:                int *ip = kt->kt_data;
1.28      mycroft   259:
1.90      itojun    260:                snprintf(*bufp, len, "%d\n", *ip);
1.1       cgd       261:                break;
                    262:        }
                    263:
1.98      darcy     264:        case KFSstring: {
1.1       cgd       265:                char *cp = kt->kt_data;
                    266:
1.28      mycroft   267:                *bufp = cp;
                    268:                break;
                    269:        }
1.1       cgd       270:
1.98      darcy     271:        case KFSmsgbuf: {
1.28      mycroft   272:                long n;
                    273:
1.52      leo       274:                /*
                    275:                 * deal with cases where the message buffer has
                    276:                 * become corrupted.
                    277:                 */
                    278:                if (!msgbufenabled || msgbufp->msg_magic != MSG_MAGIC) {
                    279:                        msgbufenabled = 0;
                    280:                        return (ENXIO);
                    281:                }
                    282:
                    283:                /*
                    284:                 * Note that reads of /kern/msgbuf won't necessarily yield
                    285:                 * consistent results, if the message buffer is modified
                    286:                 * while the read is in progress.  The worst that can happen
                    287:                 * is that incorrect data will be read.  There's no way
                    288:                 * that this can crash the system unless the values in the
                    289:                 * message buffer header are corrupted, but that'll cause
                    290:                 * the system to die anyway.
                    291:                 */
1.82      jdolecek  292:                if (off >= msgbufp->msg_bufs) {
                    293:                        *wrlen = 0;
1.28      mycroft   294:                        return (0);
1.82      jdolecek  295:                }
1.28      mycroft   296:                n = msgbufp->msg_bufx + off;
1.52      leo       297:                if (n >= msgbufp->msg_bufs)
                    298:                        n -= msgbufp->msg_bufs;
                    299:                len = min(msgbufp->msg_bufs - n, msgbufp->msg_bufs - off);
1.28      mycroft   300:                *bufp = msgbufp->msg_bufc + n;
1.82      jdolecek  301:                *wrlen = len;
                    302:                return (0);
1.1       cgd       303:        }
                    304:
1.98      darcy     305:        case KFShostname: {
1.1       cgd       306:                char *cp = hostname;
                    307:                int xlen = hostnamelen;
                    308:
1.90      itojun    309:                if (xlen >= (len - 2))
1.1       cgd       310:                        return (EINVAL);
                    311:
1.60      perry     312:                memcpy(*bufp, cp, xlen);
1.28      mycroft   313:                (*bufp)[xlen] = '\n';
                    314:                (*bufp)[xlen+1] = '\0';
1.90      itojun    315:                len = strlen(*bufp);
1.1       cgd       316:                break;
                    317:        }
                    318:
1.98      darcy     319:        case KFSavenrun:
1.31      mycroft   320:                averunnable.fscale = FSCALE;
1.90      itojun    321:                snprintf(*bufp, len, "%d %d %d %ld\n",
1.23      mycroft   322:                    averunnable.ldavg[0], averunnable.ldavg[1],
                    323:                    averunnable.ldavg[2], averunnable.fscale);
1.1       cgd       324:                break;
                    325:
1.90      itojun    326: #ifdef IPSEC
1.98      darcy     327:        case KFSipsecsa:
1.90      itojun    328:                /*
                    329:                 * Note that SA configuration could be changed during the
                    330:                 * read operation, resulting in garbled output.
                    331:                 */
                    332:                m = key_setdumpsa_spi(htonl(kfs->kfs_value));
                    333:                if (!m)
                    334:                        return (ENOBUFS);
                    335:                if (off >= m->m_pkthdr.len) {
                    336:                        *wrlen = 0;
                    337:                        m_freem(m);
                    338:                        return (0);
                    339:                }
                    340:                if (len > m->m_pkthdr.len - off)
                    341:                        len = m->m_pkthdr.len - off;
                    342:                m_copydata(m, off, len, *bufp);
                    343:                *wrlen = len;
                    344:                m_freem(m);
                    345:                return (0);
                    346:
1.98      darcy     347:        case KFSipsecsp:
1.90      itojun    348:                /*
                    349:                 * Note that SP configuration could be changed during the
                    350:                 * read operation, resulting in garbled output.
                    351:                 */
                    352:                if (!kfs->kfs_v) {
                    353:                        struct secpolicy *sp;
                    354:
                    355:                        sp = key_getspbyid(kfs->kfs_value);
                    356:                        if (sp)
                    357:                                kfs->kfs_v = sp;
                    358:                        else
                    359:                                return (ENOENT);
                    360:                }
                    361:                m = key_setdumpsp((struct secpolicy *)kfs->kfs_v,
                    362:                    SADB_X_SPDGET, 0, 0);
                    363:                if (!m)
                    364:                        return (ENOBUFS);
                    365:                if (off >= m->m_pkthdr.len) {
                    366:                        *wrlen = 0;
                    367:                        m_freem(m);
                    368:                        return (0);
                    369:                }
                    370:                if (len > m->m_pkthdr.len - off)
                    371:                        len = m->m_pkthdr.len - off;
                    372:                m_copydata(m, off, len, *bufp);
                    373:                *wrlen = len;
                    374:                m_freem(m);
                    375:                return (0);
                    376: #endif
                    377:
1.1       cgd       378:        default:
1.82      jdolecek  379:                *wrlen = 0;
1.28      mycroft   380:                return (0);
1.1       cgd       381:        }
                    382:
1.28      mycroft   383:        len = strlen(*bufp);
                    384:        if (len <= off)
1.82      jdolecek  385:                *wrlen = 0;
                    386:        else {
                    387:                *bufp += off;
                    388:                *wrlen = len - off;
                    389:        }
                    390:        return (0);
1.1       cgd       391: }
                    392:
1.82      jdolecek  393: static int
1.90      itojun    394: kernfs_xwrite(kfs, buf, len)
                    395:        const struct kernfs_node *kfs;
1.1       cgd       396:        char *buf;
1.82      jdolecek  397:        size_t len;
1.1       cgd       398: {
1.23      mycroft   399:
1.90      itojun    400:        switch (kfs->kfs_type) {
1.98      darcy     401:        case KFShostname:
1.1       cgd       402:                if (buf[len-1] == '\n')
                    403:                        --len;
1.60      perry     404:                memcpy(hostname, buf, len);
1.17      cgd       405:                hostname[len] = '\0';
1.82      jdolecek  406:                hostnamelen = (size_t) len;
1.1       cgd       407:                return (0);
                    408:
                    409:        default:
                    410:                return (EIO);
                    411:        }
                    412: }
                    413:
1.17      cgd       414:
                    415: /*
1.1       cgd       416:  * vp is the current namei directory
                    417:  * ndp is the name to locate in that directory...
                    418:  */
1.41      christos  419: int
                    420: kernfs_lookup(v)
                    421:        void *v;
                    422: {
1.23      mycroft   423:        struct vop_lookup_args /* {
                    424:                struct vnode * a_dvp;
                    425:                struct vnode ** a_vpp;
                    426:                struct componentname * a_cnp;
1.41      christos  427:        } */ *ap = v;
1.23      mycroft   428:        struct componentname *cnp = ap->a_cnp;
                    429:        struct vnode **vpp = ap->a_vpp;
                    430:        struct vnode *dvp = ap->a_dvp;
1.48      cgd       431:        const char *pname = cnp->cn_nameptr;
1.90      itojun    432:        const struct kernfs_node *kfs;
1.75      jdolecek  433:        const struct kern_target *kt;
1.64      wrstuden  434:        int error, i, wantpunlock;
1.90      itojun    435: #ifdef IPSEC
                    436:        char *ep;
                    437:        u_int32_t id;
1.1       cgd       438: #endif
1.23      mycroft   439:
1.35      mycroft   440:        *vpp = NULLVP;
1.64      wrstuden  441:        cnp->cn_flags &= ~PDIRUNLOCK;
1.35      mycroft   442:
                    443:        if (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)
                    444:                return (EROFS);
                    445:
1.23      mycroft   446:        if (cnp->cn_namelen == 1 && *pname == '.') {
                    447:                *vpp = dvp;
1.1       cgd       448:                VREF(dvp);
                    449:                return (0);
                    450:        }
1.13      cgd       451:
1.90      itojun    452:        wantpunlock = (~cnp->cn_flags & (LOCKPARENT | ISLASTCN));
                    453:        kfs = VTOKERN(dvp);
                    454:        switch (kfs->kfs_type) {
1.98      darcy     455:        case KFSkern:
1.90      itojun    456:                /*
                    457:                 * Shouldn't get here with .. in the root node.
                    458:                 */
                    459:                if (cnp->cn_flags & ISDOTDOT)
                    460:                        return (EIO);
1.64      wrstuden  461:
1.90      itojun    462:                for (i = 0; i < nkern_targets; i++) {
                    463:                        kt = &kern_targets[i];
                    464:                        if (cnp->cn_namelen == kt->kt_namlen &&
                    465:                            memcmp(kt->kt_name, pname, cnp->cn_namelen) == 0)
                    466:                                goto found;
                    467:                }
                    468:                break;
1.25      mycroft   469:
1.90      itojun    470:        found:
                    471:                error = kernfs_allocvp(dvp->v_mount, vpp, kt->kt_tag, kt, 0);
                    472:                if ((error == 0) && wantpunlock) {
                    473:                        VOP_UNLOCK(dvp, 0);
                    474:                        cnp->cn_flags |= PDIRUNLOCK;
                    475:                }
                    476:                return (error);
1.64      wrstuden  477:
1.90      itojun    478: #ifdef IPSEC
1.98      darcy     479:        case KFSipsecsadir:
1.100   ! cl        480:                if (cnp->cn_flags & ISDOTDOT) {
        !           481:                        kt = &kern_targets[0];
        !           482:                        goto found;
        !           483:                }
        !           484:
        !           485:                for (i = 2; i < nipsecsa_targets; i++) {
1.90      itojun    486:                        kt = &ipsecsa_targets[i];
                    487:                        if (cnp->cn_namelen == kt->kt_namlen &&
1.100   ! cl        488:                            memcmp(kt->kt_name, pname, cnp->cn_namelen) == 0)
        !           489:                                goto found;
1.90      itojun    490:                }
1.1       cgd       491:
1.90      itojun    492:                ep = NULL;
                    493:                id = strtoul(pname, &ep, 10);
                    494:                if (!ep || *ep || ep == pname)
                    495:                        break;
1.1       cgd       496:
1.98      darcy     497:                error = kernfs_allocvp(dvp->v_mount, vpp, KFSipsecsa, NULL, id);
1.90      itojun    498:                if ((error == 0) && wantpunlock) {
                    499:                        VOP_UNLOCK(dvp, 0);
                    500:                        cnp->cn_flags |= PDIRUNLOCK;
                    501:                }
                    502:                return (error);
1.23      mycroft   503:
1.98      darcy     504:        case KFSipsecspdir:
1.100   ! cl        505:                if (cnp->cn_flags & ISDOTDOT) {
        !           506:                        kt = &kern_targets[0];
        !           507:                        goto found;
        !           508:                }
        !           509:
        !           510:                for (i = 2; i < nipsecsp_targets; i++) {
1.90      itojun    511:                        kt = &ipsecsp_targets[i];
                    512:                        if (cnp->cn_namelen == kt->kt_namlen &&
1.100   ! cl        513:                            memcmp(kt->kt_name, pname, cnp->cn_namelen) == 0)
        !           514:                                goto found;
1.57      fvdl      515:                }
1.90      itojun    516:
                    517:                ep = NULL;
                    518:                id = strtoul(pname, &ep, 10);
                    519:                if (!ep || *ep || ep == pname)
                    520:                        break;
                    521:
1.98      darcy     522:                error = kernfs_allocvp(dvp->v_mount, vpp, KFSipsecsp, NULL, id);
1.90      itojun    523:                if ((error == 0) && wantpunlock) {
1.64      wrstuden  524:                        VOP_UNLOCK(dvp, 0);
                    525:                        cnp->cn_flags |= PDIRUNLOCK;
                    526:                }
1.90      itojun    527:                return (error);
                    528: #endif
                    529:
                    530:        default:
                    531:                return (ENOTDIR);
                    532:        }
                    533:
                    534:        return (cnp->cn_nameiop == LOOKUP ? ENOENT : EROFS);
                    535: }
                    536:
                    537: int
                    538: kernfs_open(v)
                    539:        void *v;
                    540: {
                    541:        struct vop_open_args /* {
                    542:                struct vnode *a_vp;
                    543:                int a_mode;
                    544:                struct ucred *a_cred;
                    545:                struct proc *a_p;
                    546:        } */ *ap = v;
                    547:        struct kernfs_node *kfs = VTOKERN(ap->a_vp);
                    548: #ifdef IPSEC
                    549:        struct mbuf *m;
                    550:        struct secpolicy *sp;
                    551: #endif
                    552:
                    553:        switch (kfs->kfs_type) {
                    554: #ifdef IPSEC
1.98      darcy     555:        case KFSipsecsa:
1.90      itojun    556:                m = key_setdumpsa_spi(htonl(kfs->kfs_value));
                    557:                if (m) {
                    558:                        m_freem(m);
                    559:                        return (0);
                    560:                } else
                    561:                        return (ENOENT);
                    562:
1.98      darcy     563:        case KFSipsecsp:
1.90      itojun    564:                sp = key_getspbyid(kfs->kfs_value);
                    565:                if (sp) {
                    566:                        kfs->kfs_v = sp;
                    567:                        return (0);
                    568:                } else
                    569:                        return (ENOENT);
                    570: #endif
                    571:
                    572:        default:
1.23      mycroft   573:                return (0);
                    574:        }
1.90      itojun    575: }
1.1       cgd       576:
1.90      itojun    577: int
                    578: kernfs_close(v)
                    579:        void *v;
                    580: {
                    581:        struct vop_close_args /* {
                    582:                struct vnode *a_vp;
                    583:                int a_fflag;
                    584:                struct ucred *a_cred;
                    585:                struct proc *a_p;
                    586:        } */ *ap = v;
                    587:        struct kernfs_node *kfs = VTOKERN(ap->a_vp);
                    588:
                    589:        switch (kfs->kfs_type) {
                    590: #ifdef IPSEC
1.98      darcy     591:        case KFSipsecsp:
1.90      itojun    592:                key_freesp((struct secpolicy *)kfs->kfs_v);
                    593:                break;
1.1       cgd       594: #endif
1.90      itojun    595:
                    596:        default:
                    597:                break;
1.57      fvdl      598:        }
1.23      mycroft   599:
1.1       cgd       600:        return (0);
                    601: }
                    602:
1.28      mycroft   603: int
1.41      christos  604: kernfs_access(v)
                    605:        void *v;
                    606: {
1.23      mycroft   607:        struct vop_access_args /* {
                    608:                struct vnode *a_vp;
1.34      mycroft   609:                int a_mode;
1.23      mycroft   610:                struct ucred *a_cred;
                    611:                struct proc *a_p;
1.41      christos  612:        } */ *ap = v;
1.90      itojun    613:        struct vattr va;
                    614:        int error;
1.17      cgd       615:
1.90      itojun    616:        if ((error = VOP_GETATTR(ap->a_vp, &va, ap->a_cred, ap->a_p)) != 0)
                    617:                return (error);
1.49      mycroft   618:
1.90      itojun    619:        return (vaccess(va.va_type, va.va_mode, va.va_uid, va.va_gid,
                    620:            ap->a_mode, ap->a_cred));
1.23      mycroft   621: }
                    622:
1.41      christos  623: int
                    624: kernfs_getattr(v)
                    625:        void *v;
                    626: {
1.23      mycroft   627:        struct vop_getattr_args /* {
                    628:                struct vnode *a_vp;
                    629:                struct vattr *a_vap;
                    630:                struct ucred *a_cred;
                    631:                struct proc *a_p;
1.41      christos  632:        } */ *ap = v;
1.90      itojun    633:        struct kernfs_node *kfs = VTOKERN(ap->a_vp);
1.23      mycroft   634:        struct vattr *vap = ap->a_vap;
1.1       cgd       635:        int error = 0;
1.28      mycroft   636:        char strbuf[KSTRING], *buf;
1.90      itojun    637:        size_t nread, total;
1.1       cgd       638:
1.90      itojun    639:        VATTR_NULL(vap);
                    640:        vap->va_type = ap->a_vp->v_type;
1.17      cgd       641:        vap->va_uid = 0;
                    642:        vap->va_gid = 0;
1.90      itojun    643:        vap->va_mode = kfs->kfs_mode;
                    644:        vap->va_fileid = kfs->kfs_fileno;
                    645:        vap->va_flags = 0;
1.23      mycroft   646:        vap->va_size = 0;
1.1       cgd       647:        vap->va_blocksize = DEV_BSIZE;
1.81      lukem     648:        /*
1.92      dan       649:         * Make all times be current TOD, except for the "boottime" node.
1.93      simonb    650:         * Avoid microtime(9), it's slow.
1.83      simonb    651:         * We don't guard the read from time(9) with splclock(9) since we
                    652:         * don't actually need to be THAT sure the access is atomic.
1.81      lukem     653:         */
1.96      itojun    654:        if (kfs->kfs_kt && kfs->kfs_kt->kt_namlen == 8 &&
1.92      dan       655:            !memcmp(kfs->kfs_kt->kt_name, "boottime", 8)) {
                    656:                TIMEVAL_TO_TIMESPEC(&boottime, &vap->va_ctime);
                    657:        } else {
                    658:                TIMEVAL_TO_TIMESPEC(&time, &vap->va_ctime);
                    659:        }
1.81      lukem     660:        vap->va_atime = vap->va_mtime = vap->va_ctime;
1.1       cgd       661:        vap->va_gen = 0;
                    662:        vap->va_flags = 0;
                    663:        vap->va_rdev = 0;
                    664:        vap->va_bytes = 0;
                    665:
1.90      itojun    666:        switch (kfs->kfs_type) {
1.98      darcy     667:        case KFSkern:
1.95      dan       668: #ifdef IPSEC
                    669:                vap->va_nlink = 4; /* 2 extra subdirs */
                    670: #else
                    671:                vap->va_nlink = 2;
                    672: #endif
1.90      itojun    673:                vap->va_bytes = vap->va_size = DEV_BSIZE;
                    674:                break;
                    675:
1.98      darcy     676:        case KFSroot:
1.90      itojun    677:                vap->va_nlink = 1;
                    678:                vap->va_bytes = vap->va_size = DEV_BSIZE;
                    679:                break;
                    680:
1.98      darcy     681:        case KFSnull:
                    682:        case KFStime:
                    683:        case KFSint:
                    684:        case KFSstring:
                    685:        case KFShostname:
                    686:        case KFSavenrun:
                    687:        case KFSdevice:
                    688:        case KFSmsgbuf:
1.90      itojun    689: #ifdef IPSEC
1.98      darcy     690:        case KFSipsecsa:
                    691:        case KFSipsecsp:
1.1       cgd       692: #endif
                    693:                vap->va_nlink = 1;
1.84      jdolecek  694:                total = 0;
                    695:                do {
                    696:                        buf = strbuf;
1.90      itojun    697:                        error = kernfs_xread(kfs, total, &buf,
                    698:                            sizeof(strbuf), &nread);
1.84      jdolecek  699:                        total += nread;
                    700:                } while (error == 0 && nread != 0);
1.90      itojun    701:                vap->va_bytes = vap->va_size = total;
                    702:                break;
                    703:
                    704: #ifdef IPSEC
1.98      darcy     705:        case KFSipsecsadir:
                    706:        case KFSipsecspdir:
1.90      itojun    707:                vap->va_nlink = 2;
                    708:                vap->va_bytes = vap->va_size = DEV_BSIZE;
                    709:                break;
                    710: #endif
                    711:
                    712:        default:
                    713:                error = EINVAL;
                    714:                break;
1.1       cgd       715:        }
                    716:
                    717:        return (error);
                    718: }
                    719:
1.41      christos  720: /*ARGSUSED*/
                    721: int
                    722: kernfs_setattr(v)
                    723:        void *v;
1.1       cgd       724: {
1.90      itojun    725:
1.1       cgd       726:        /*
1.17      cgd       727:         * Silently ignore attribute changes.
                    728:         * This allows for open with truncate to have no
                    729:         * effect until some data is written.  I want to
                    730:         * do it this way because all writes are atomic.
1.1       cgd       731:         */
1.17      cgd       732:        return (0);
1.1       cgd       733: }
                    734:
1.28      mycroft   735: int
1.41      christos  736: kernfs_read(v)
                    737:        void *v;
                    738: {
1.23      mycroft   739:        struct vop_read_args /* {
                    740:                struct vnode *a_vp;
                    741:                struct uio *a_uio;
                    742:                int  a_ioflag;
                    743:                struct ucred *a_cred;
1.41      christos  744:        } */ *ap = v;
1.23      mycroft   745:        struct uio *uio = ap->a_uio;
1.90      itojun    746:        struct kernfs_node *kfs = VTOKERN(ap->a_vp);
1.28      mycroft   747:        char strbuf[KSTRING], *buf;
1.82      jdolecek  748:        off_t off;
                    749:        size_t len;
1.28      mycroft   750:        int error;
1.23      mycroft   751:
1.90      itojun    752:        if (ap->a_vp->v_type == VDIR)
1.23      mycroft   753:                return (EOPNOTSUPP);
                    754:
1.28      mycroft   755:        off = uio->uio_offset;
1.82      jdolecek  756:        buf = strbuf;
1.90      itojun    757:        if ((error = kernfs_xread(kfs, off, &buf, sizeof(strbuf), &len)) == 0)
1.82      jdolecek  758:                error = uiomove(buf, len, uio);
                    759:        return (error);
1.1       cgd       760: }
                    761:
1.28      mycroft   762: int
1.41      christos  763: kernfs_write(v)
                    764:        void *v;
                    765: {
1.23      mycroft   766:        struct vop_write_args /* {
                    767:                struct vnode *a_vp;
                    768:                struct uio *a_uio;
                    769:                int  a_ioflag;
                    770:                struct ucred *a_cred;
1.41      christos  771:        } */ *ap = v;
1.90      itojun    772:        struct kernfs_node *kfs = VTOKERN(ap->a_vp);
1.23      mycroft   773:        struct uio *uio = ap->a_uio;
                    774:        int error, xlen;
1.1       cgd       775:        char strbuf[KSTRING];
1.23      mycroft   776:
1.1       cgd       777:        if (uio->uio_offset != 0)
                    778:                return (EINVAL);
                    779:
                    780:        xlen = min(uio->uio_resid, KSTRING-1);
1.41      christos  781:        if ((error = uiomove(strbuf, xlen, uio)) != 0)
1.1       cgd       782:                return (error);
                    783:
                    784:        if (uio->uio_resid != 0)
                    785:                return (EIO);
                    786:
                    787:        strbuf[xlen] = '\0';
1.17      cgd       788:        xlen = strlen(strbuf);
1.90      itojun    789:        return (kernfs_xwrite(kfs, strbuf, xlen));
1.1       cgd       790: }
                    791:
1.41      christos  792: int
                    793: kernfs_readdir(v)
                    794:        void *v;
                    795: {
1.23      mycroft   796:        struct vop_readdir_args /* {
                    797:                struct vnode *a_vp;
                    798:                struct uio *a_uio;
                    799:                struct ucred *a_cred;
1.26      mycroft   800:                int *a_eofflag;
1.57      fvdl      801:                off_t **a_cookies;
                    802:                int a_*ncookies;
1.41      christos  803:        } */ *ap = v;
1.23      mycroft   804:        struct uio *uio = ap->a_uio;
1.37      mycroft   805:        struct dirent d;
1.90      itojun    806:        struct kernfs_node *kfs = VTOKERN(ap->a_vp);
1.75      jdolecek  807:        const struct kern_target *kt;
1.67      sommerfe  808:        off_t i;
1.1       cgd       809:        int error;
1.57      fvdl      810:        off_t *cookies = NULL;
1.90      itojun    811:        int ncookies = 0, n;
                    812: #ifdef IPSEC
                    813:        struct secasvar *sav, *sav2;
                    814:        struct secpolicy *sp;
                    815: #endif
1.23      mycroft   816:
1.37      mycroft   817:        if (uio->uio_resid < UIO_MX)
                    818:                return (EINVAL);
1.38      mycroft   819:        if (uio->uio_offset < 0)
1.37      mycroft   820:                return (EINVAL);
1.26      mycroft   821:
1.1       cgd       822:        error = 0;
1.38      mycroft   823:        i = uio->uio_offset;
1.90      itojun    824:        memset(&d, 0, sizeof(d));
                    825:        d.d_reclen = UIO_MX;
                    826:        ncookies = uio->uio_resid / UIO_MX;
                    827:
                    828:        switch (kfs->kfs_type) {
1.98      darcy     829:        case KFSkern:
1.90      itojun    830:                if (i >= nkern_targets)
                    831:                        return (0);
1.66      sommerfe  832:
1.90      itojun    833:                if (ap->a_ncookies) {
                    834:                        ncookies = min(ncookies, (nkern_targets - i));
                    835:                        cookies = malloc(ncookies * sizeof(off_t), M_TEMP,
                    836:                            M_WAITOK);
                    837:                        *ap->a_cookies = cookies;
                    838:                }
                    839:
                    840:                n = 0;
                    841:                for (; i < nkern_targets && uio->uio_resid >= UIO_MX; i++) {
                    842:                        kt = &kern_targets[i];
1.98      darcy     843:                        if (kt->kt_tag == KFSdevice) {
1.94      itojun    844:                                dev_t *dp = kt->kt_data;
                    845:                                struct vnode *fvp;
                    846:
                    847:                                if (*dp == NODEV ||
                    848:                                    !vfinddev(*dp, kt->kt_vtype, &fvp))
                    849:                                        continue;
                    850:                        }
1.90      itojun    851:                        d.d_namlen = kt->kt_namlen;
                    852:                        if (i < 2)
                    853:                                d.d_fileno = KERNFS_FILENO(&kern_targets[0],
                    854:                                    kern_targets[0].kt_tag, 0);
                    855:                        else
                    856:                                d.d_fileno = KERNFS_FILENO(kt, kt->kt_tag, 0);
                    857:                        memcpy(d.d_name, kt->kt_name, kt->kt_namlen + 1);
                    858:                        d.d_type = kt->kt_type;
1.99      jrf       859:                        if ((error = uiomove(&d, UIO_MX, uio)) != 0)
1.90      itojun    860:                                break;
                    861:                        if (cookies)
                    862:                                *cookies++ = i + 1;
                    863:                        n++;
                    864:                }
                    865:                ncookies = n;
                    866:                break;
                    867:
1.98      darcy     868:        case KFSroot:
1.90      itojun    869:                if (i >= 2)
                    870:                        return 0;
                    871:
                    872:                if (ap->a_ncookies) {
                    873:                        ncookies = min(ncookies, (2 - i));
                    874:                        cookies = malloc(ncookies * sizeof(off_t), M_TEMP,
                    875:                            M_WAITOK);
                    876:                        *ap->a_cookies = cookies;
                    877:                }
                    878:
                    879:                n = 0;
                    880:                for (; i < 2 && uio->uio_resid >= UIO_MX; i++) {
                    881:                        kt = &kern_targets[i];
                    882:                        d.d_namlen = kt->kt_namlen;
                    883:                        d.d_fileno = KERNFS_FILENO(kt, kt->kt_tag, 0);
                    884:                        memcpy(d.d_name, kt->kt_name, kt->kt_namlen + 1);
                    885:                        d.d_type = kt->kt_type;
1.99      jrf       886:                        if ((error = uiomove(&d, UIO_MX, uio)) != 0)
1.90      itojun    887:                                break;
                    888:                        if (cookies)
                    889:                                *cookies++ = i + 1;
                    890:                        n++;
                    891:                }
                    892:                ncookies = n;
                    893:                break;
                    894:
                    895: #ifdef IPSEC
1.98      darcy     896:        case KFSipsecsadir:
1.90      itojun    897:                /* count SA in the system */
                    898:                n = 0;
                    899:                TAILQ_FOREACH(sav, &satailq, tailq) {
                    900:                        for (sav2 = TAILQ_FIRST(&satailq);
                    901:                            sav2 != sav;
                    902:                            sav2 = TAILQ_NEXT(sav2, tailq)) {
                    903:                                if (sav->spi == sav2->spi) {
                    904:                                        /* multiple SA with same SPI */
                    905:                                        break;
                    906:                                }
                    907:                        }
                    908:                        if (sav == sav2 || sav->spi != sav2->spi)
                    909:                                n++;
                    910:                }
1.37      mycroft   911:
1.90      itojun    912:                if (i >= nipsecsa_targets + n)
                    913:                        return (0);
1.57      fvdl      914:
1.90      itojun    915:                if (ap->a_ncookies) {
                    916:                        ncookies = min(ncookies, (n - i));
                    917:                        cookies = malloc(ncookies * sizeof(off_t), M_TEMP,
                    918:                            M_WAITOK);
                    919:                        *ap->a_cookies = cookies;
                    920:                }
1.26      mycroft   921:
1.90      itojun    922:                n = 0;
                    923:                for (; i < nipsecsa_targets && uio->uio_resid >= UIO_MX; i++) {
                    924:                        kt = &ipsecsa_targets[i];
                    925:                        d.d_namlen = kt->kt_namlen;
                    926:                        d.d_fileno = KERNFS_FILENO(kt, kt->kt_tag, 0);
                    927:                        memcpy(d.d_name, kt->kt_name, kt->kt_namlen + 1);
                    928:                        d.d_type = kt->kt_type;
1.99      jrf       929:                        if ((error = uiomove(&d, UIO_MX, uio)) != 0)
1.90      itojun    930:                                break;
                    931:                        if (cookies)
                    932:                                *cookies++ = i + 1;
                    933:                        n++;
                    934:                }
                    935:                if (error) {
                    936:                        ncookies = n;
                    937:                        break;
                    938:                }
1.26      mycroft   939:
1.90      itojun    940:                TAILQ_FOREACH(sav, &satailq, tailq) {
                    941:                        for (sav2 = TAILQ_FIRST(&satailq);
                    942:                            sav2 != sav;
                    943:                            sav2 = TAILQ_NEXT(sav2, tailq)) {
                    944:                                if (sav->spi == sav2->spi) {
                    945:                                        /* multiple SA with same SPI */
                    946:                                        break;
                    947:                                }
                    948:                        }
                    949:                        if (sav != sav2 && sav->spi == sav2->spi)
1.23      mycroft   950:                                continue;
1.90      itojun    951:                        if (uio->uio_resid < UIO_MX)
                    952:                                break;
                    953:                        d.d_fileno = KERNFS_FILENO(kfs->kfs_kt, kfs->kfs_type,
                    954:                            kfs->kfs_cookie);
                    955:                        d.d_namlen = snprintf(d.d_name, sizeof(d.d_name),
                    956:                            "%u", ntohl(sav->spi));
                    957:                        d.d_type = DT_REG;
1.99      jrf       958:                        if ((error = uiomove(&d, UIO_MX, uio)) != 0)
1.90      itojun    959:                                break;
                    960:                        if (cookies)
                    961:                                *cookies++ = i + 1;
                    962:                        n++;
                    963:                        i++;
1.23      mycroft   964:                }
1.90      itojun    965:                ncookies = n;
                    966:                break;
                    967:
1.98      darcy     968:        case KFSipsecspdir:
1.90      itojun    969:                /* count SP in the system */
                    970:                n = 0;
                    971:                TAILQ_FOREACH(sp, &sptailq, tailq)
                    972:                        n++;
1.26      mycroft   973:
1.90      itojun    974:                if (i >= 2 + n)
                    975:                        return (0);
                    976:
                    977:                if (ap->a_ncookies) {
                    978:                        ncookies = min(ncookies, (n - i));
                    979:                        cookies = malloc(ncookies * sizeof(off_t), M_TEMP,
                    980:                            M_WAITOK);
                    981:                        *ap->a_cookies = cookies;
                    982:                }
1.26      mycroft   983:
1.90      itojun    984:                n = 0;
                    985:                for (; i < nipsecsp_targets && uio->uio_resid >= UIO_MX; i++) {
                    986:                        kt = &ipsecsp_targets[i];
                    987:                        d.d_namlen = kt->kt_namlen;
                    988:                        d.d_fileno = KERNFS_FILENO(kt, kt->kt_tag, 0);
                    989:                        memcpy(d.d_name, kt->kt_name, kt->kt_namlen + 1);
                    990:                        d.d_type = kt->kt_type;
1.99      jrf       991:                        if ((error = uiomove(&d, UIO_MX, uio)) != 0)
1.90      itojun    992:                                break;
                    993:                        if (cookies)
                    994:                                *cookies++ = i + 1;
                    995:                        n++;
                    996:                }
                    997:                if (error) {
                    998:                        ncookies = n;
1.1       cgd       999:                        break;
1.57      fvdl     1000:                }
1.90      itojun   1001:
                   1002:                TAILQ_FOREACH(sp, &sptailq, tailq) {
                   1003:                        if (uio->uio_resid < UIO_MX)
                   1004:                                break;
                   1005:                        d.d_fileno = KERNFS_FILENO(kfs->kfs_kt, kfs->kfs_type,
                   1006:                            kfs->kfs_cookie);
                   1007:                        d.d_namlen = snprintf(d.d_name, sizeof(d.d_name),
                   1008:                            "%u", sp->id);
                   1009:                        d.d_type = DT_REG;
1.99      jrf      1010:                        if ((error = uiomove(&d, UIO_MX, uio)) != 0)
1.90      itojun   1011:                                break;
                   1012:                        if (cookies)
                   1013:                                *cookies++ = i + 1;
                   1014:                        n++;
                   1015:                        i++;
                   1016:                }
                   1017:                ncookies = n;
                   1018:                break;
                   1019: #endif
                   1020:
                   1021:        default:
                   1022:                error = ENOTDIR;
                   1023:                break;
1.57      fvdl     1024:        }
                   1025:
                   1026:        if (ap->a_ncookies) {
                   1027:                if (error) {
1.90      itojun   1028:                        if (cookies)
                   1029:                                free(*ap->a_cookies, M_TEMP);
1.57      fvdl     1030:                        *ap->a_ncookies = 0;
                   1031:                        *ap->a_cookies = NULL;
                   1032:                } else
                   1033:                        *ap->a_ncookies = ncookies;
1.1       cgd      1034:        }
                   1035:
1.38      mycroft  1036:        uio->uio_offset = i;
1.1       cgd      1037:        return (error);
                   1038: }
                   1039:
1.41      christos 1040: int
                   1041: kernfs_inactive(v)
                   1042:        void *v;
                   1043: {
1.23      mycroft  1044:        struct vop_inactive_args /* {
                   1045:                struct vnode *a_vp;
1.57      fvdl     1046:                struct proc *a_p;
1.41      christos 1047:        } */ *ap = v;
1.23      mycroft  1048:        struct vnode *vp = ap->a_vp;
1.90      itojun   1049:        const struct kernfs_node *kfs = VTOKERN(ap->a_vp);
                   1050: #ifdef IPSEC
                   1051:        struct mbuf *m;
                   1052:        struct secpolicy *sp;
                   1053: #endif
1.23      mycroft  1054:
1.90      itojun   1055:        VOP_UNLOCK(vp, 0);
                   1056:        switch (kfs->kfs_type) {
                   1057: #ifdef IPSEC
1.98      darcy    1058:        case KFSipsecsa:
1.90      itojun   1059:                m = key_setdumpsa_spi(htonl(kfs->kfs_value));
                   1060:                if (m)
                   1061:                        m_freem(m);
1.91      itojun   1062:                else
1.90      itojun   1063:                        vgone(vp);
                   1064:                break;
1.98      darcy    1065:        case KFSipsecsp:
1.90      itojun   1066:                sp = key_getspbyid(kfs->kfs_value);
                   1067:                if (sp)
                   1068:                        key_freesp(sp);
                   1069:                else {
                   1070:                        /* should never happen as we hold a refcnt */
                   1071:                        vgone(vp);
                   1072:                }
                   1073:                break;
1.23      mycroft  1074: #endif
1.90      itojun   1075:        default:
                   1076:                break;
                   1077:        }
1.23      mycroft  1078:        return (0);
                   1079: }
                   1080:
1.41      christos 1081: int
                   1082: kernfs_reclaim(v)
                   1083:        void *v;
                   1084: {
1.23      mycroft  1085:        struct vop_reclaim_args /* {
                   1086:                struct vnode *a_vp;
1.41      christos 1087:        } */ *ap = v;
1.23      mycroft  1088:
1.90      itojun   1089:        return (kernfs_freevp(ap->a_vp));
1.1       cgd      1090: }
                   1091:
                   1092: /*
1.23      mycroft  1093:  * Return POSIX pathconf information applicable to special devices.
                   1094:  */
1.41      christos 1095: int
                   1096: kernfs_pathconf(v)
                   1097:        void *v;
                   1098: {
1.23      mycroft  1099:        struct vop_pathconf_args /* {
                   1100:                struct vnode *a_vp;
                   1101:                int a_name;
1.29      cgd      1102:                register_t *a_retval;
1.41      christos 1103:        } */ *ap = v;
1.23      mycroft  1104:
                   1105:        switch (ap->a_name) {
                   1106:        case _PC_LINK_MAX:
                   1107:                *ap->a_retval = LINK_MAX;
                   1108:                return (0);
                   1109:        case _PC_MAX_CANON:
                   1110:                *ap->a_retval = MAX_CANON;
                   1111:                return (0);
                   1112:        case _PC_MAX_INPUT:
                   1113:                *ap->a_retval = MAX_INPUT;
                   1114:                return (0);
                   1115:        case _PC_PIPE_BUF:
                   1116:                *ap->a_retval = PIPE_BUF;
                   1117:                return (0);
                   1118:        case _PC_CHOWN_RESTRICTED:
                   1119:                *ap->a_retval = 1;
                   1120:                return (0);
                   1121:        case _PC_VDISABLE:
                   1122:                *ap->a_retval = _POSIX_VDISABLE;
1.59      kleink   1123:                return (0);
                   1124:        case _PC_SYNC_IO:
                   1125:                *ap->a_retval = 1;
1.23      mycroft  1126:                return (0);
                   1127:        default:
                   1128:                return (EINVAL);
                   1129:        }
                   1130:        /* NOTREACHED */
                   1131: }
                   1132:
                   1133: /*
                   1134:  * Print out the contents of a /dev/fd vnode.
1.1       cgd      1135:  */
                   1136: /* ARGSUSED */
1.41      christos 1137: int
                   1138: kernfs_print(v)
                   1139:        void *v;
1.23      mycroft  1140: {
                   1141:
1.47      christos 1142:        printf("tag VT_KERNFS, kernfs vnode\n");
1.23      mycroft  1143:        return (0);
                   1144: }
                   1145:
1.40      mycroft  1146: int
1.41      christos 1147: kernfs_link(v)
                   1148:        void *v;
                   1149: {
1.40      mycroft  1150:        struct vop_link_args /* {
                   1151:                struct vnode *a_dvp;
                   1152:                struct vnode *a_vp;
                   1153:                struct componentname *a_cnp;
1.41      christos 1154:        } */ *ap = v;
1.40      mycroft  1155:
                   1156:        VOP_ABORTOP(ap->a_dvp, ap->a_cnp);
                   1157:        vput(ap->a_dvp);
                   1158:        return (EROFS);
                   1159: }
                   1160:
                   1161: int
1.41      christos 1162: kernfs_symlink(v)
                   1163:        void *v;
                   1164: {
1.40      mycroft  1165:        struct vop_symlink_args /* {
                   1166:                struct vnode *a_dvp;
                   1167:                struct vnode **a_vpp;
                   1168:                struct componentname *a_cnp;
                   1169:                struct vattr *a_vap;
                   1170:                char *a_target;
1.41      christos 1171:        } */ *ap = v;
1.40      mycroft  1172:
                   1173:        VOP_ABORTOP(ap->a_dvp, ap->a_cnp);
                   1174:        vput(ap->a_dvp);
                   1175:        return (EROFS);
1.1       cgd      1176: }

CVSweb <webmaster@jp.NetBSD.org>