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

Annotation of src/sys/miscfs/kernfs/kernfs_vfsops.c, Revision 1.95

1.95    ! hannken     1: /*     $NetBSD: kernfs_vfsops.c,v 1.94 2014/07/17 08:21:34 hannken Exp $       */
1.18      cgd         2:
1.1       cgd         3: /*
1.32      fvdl        4:  * Copyright (c) 1992, 1993, 1995
1.15      mycroft     5:  *     The Regents of the University of California.  All rights reserved.
1.1       cgd         6:  *
1.11      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.53      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.32      fvdl       34:  *     @(#)kernfs_vfsops.c     8.10 (Berkeley) 5/14/95
1.1       cgd        35:  */
                     36:
                     37: /*
                     38:  * Kernel params Filesystem
                     39:  */
1.42      lukem      40:
                     41: #include <sys/cdefs.h>
1.95    ! hannken    42: __KERNEL_RCSID(0, "$NetBSD: kernfs_vfsops.c,v 1.94 2014/07/17 08:21:34 hannken Exp $");
1.33      jonathan   43:
1.54      itojun     44: #ifdef _KERNEL_OPT
1.33      jonathan   45: #include "opt_compat_netbsd.h"
                     46: #endif
1.1       cgd        47:
1.9       mycroft    48: #include <sys/param.h>
                     49: #include <sys/systm.h>
1.57      atatat     50: #include <sys/sysctl.h>
1.15      mycroft    51: #include <sys/conf.h>
1.9       mycroft    52: #include <sys/proc.h>
                     53: #include <sys/vnode.h>
                     54: #include <sys/mount.h>
                     55: #include <sys/namei.h>
1.60      christos   56: #include <sys/dirent.h>
1.9       mycroft    57: #include <sys/malloc.h>
1.54      itojun     58: #include <sys/syslog.h>
1.71      elad       59: #include <sys/kauth.h>
1.85      rumble     60: #include <sys/module.h>
1.15      mycroft    61:
1.83      dholland   62: #include <miscfs/genfs/genfs.h>
1.15      mycroft    63: #include <miscfs/specfs/specdev.h>
1.9       mycroft    64: #include <miscfs/kernfs/kernfs.h>
1.1       cgd        65:
1.85      rumble     66: MODULE(MODULE_CLASS_VFS, kernfs, NULL);
                     67:
1.77      pooka      68: MALLOC_JUSTDEFINE(M_KERNFSMNT, "kernfs mount", "kernfs mount structures");
1.47      thorpej    69:
1.15      mycroft    70: dev_t rrootdev = NODEV;
1.95    ! hannken    71: kmutex_t kfs_lock;
1.15      mycroft    72:
1.81      pooka      73: VFS_PROTOS(kernfs);
                     74:
1.68      xtraeme    75: void   kernfs_get_rrootdev(void);
1.25      christos   76:
1.86      rumble     77: static struct sysctllog *kernfs_sysctl_log;
                     78:
1.25      christos   79: void
1.89      cegger     80: kernfs_init(void)
1.1       cgd        81: {
1.77      pooka      82:
1.49      christos   83:        malloc_type_attach(M_KERNFSMNT);
1.95    ! hannken    84:        mutex_init(&kfs_lock, MUTEX_DEFAULT, IPL_NONE);
1.54      itojun     85: }
                     86:
                     87: void
1.89      cegger     88: kernfs_reinit(void)
1.54      itojun     89: {
1.95    ! hannken    90:
1.10      cgd        91: }
                     92:
1.11      cgd        93: void
1.89      cegger     94: kernfs_done(void)
1.36      jdolecek   95: {
1.77      pooka      96:
1.95    ! hannken    97:        mutex_destroy(&kfs_lock);
1.49      christos   98:        malloc_type_detach(M_KERNFSMNT);
1.36      jdolecek   99: }
                    100:
                    101: void
1.89      cegger    102: kernfs_get_rrootdev(void)
1.10      cgd       103: {
1.16      mycroft   104:        static int tried = 0;
1.10      cgd       105:
1.16      mycroft   106:        if (tried) {
1.15      mycroft   107:                /* Already did it once. */
                    108:                return;
                    109:        }
1.16      mycroft   110:        tried = 1;
                    111:
                    112:        if (rootdev == NODEV)
                    113:                return;
1.45      gehenna   114:        rrootdev = devsw_blk2chr(rootdev);
1.54      itojun    115:        if (rrootdev != NODEV)
1.45      gehenna   116:                return;
1.16      mycroft   117:        rrootdev = NODEV;
1.28      christos  118:        printf("kernfs_get_rrootdev: no raw root device\n");
1.1       cgd       119: }
                    120:
                    121: /*
1.15      mycroft   122:  * Mount the Kernel params filesystem
1.1       cgd       123:  */
1.25      christos  124: int
1.82      pooka     125: kernfs_mount(struct mount *mp, const char *path, void *data, size_t *data_len)
1.1       cgd       126: {
1.82      pooka     127:        struct lwp *l = curlwp;
1.1       cgd       128:        int error = 0;
                    129:        struct kernfs_mount *fmp;
                    130:
1.54      itojun    131:        if (UIO_MX & (UIO_MX - 1)) {
                    132:                log(LOG_ERR, "kernfs: invalid directory entry size");
                    133:                return (EINVAL);
                    134:        }
1.1       cgd       135:
1.78      dsl       136:        if (mp->mnt_flag & MNT_GETARGS) {
                    137:                *data_len = 0;
1.46      christos  138:                return 0;
1.78      dsl       139:        }
1.1       cgd       140:        /*
                    141:         * Update is a no-op
                    142:         */
                    143:        if (mp->mnt_flag & MNT_UPDATE)
                    144:                return (EOPNOTSUPP);
                    145:
1.87      cegger    146:        fmp = malloc(sizeof(struct kernfs_mount), M_KERNFSMNT, M_WAITOK|M_ZERO);
1.54      itojun    147:        TAILQ_INIT(&fmp->nodelist);
                    148:
1.91      christos  149:        mp->mnt_stat.f_namemax = KERNFS_MAXNAMLEN;
1.65      jdolecek  150:        mp->mnt_flag |= MNT_LOCAL;
1.54      itojun    151:        mp->mnt_data = fmp;
1.37      assar     152:        vfs_getnewfsid(mp);
1.1       cgd       153:
1.64      tron      154:        if ((error = set_statvfs_info(path, UIO_USERSPACE, "kernfs",
1.79      pooka     155:            UIO_SYSSPACE, mp->mnt_op->vfs_name, mp, l)) != 0) {
1.64      tron      156:                free(fmp, M_KERNFSMNT);
                    157:                return error;
                    158:        }
1.10      cgd       159:
1.15      mycroft   160:        kernfs_get_rrootdev();
1.64      tron      161:        return 0;
1.1       cgd       162: }
                    163:
1.25      christos  164: int
1.82      pooka     165: kernfs_start(struct mount *mp, int flags)
1.1       cgd       166: {
1.15      mycroft   167:
1.1       cgd       168:        return (0);
                    169: }
                    170:
1.25      christos  171: int
1.82      pooka     172: kernfs_unmount(struct mount *mp, int mntflags)
1.1       cgd       173: {
                    174:        int error;
                    175:        int flags = 0;
                    176:
1.54      itojun    177:        if (mntflags & MNT_FORCE)
1.1       cgd       178:                flags |= FORCECLOSE;
                    179:
1.54      itojun    180:        if ((error = vflush(mp, 0, flags)) != 0)
1.1       cgd       181:                return (error);
                    182:
                    183:        /*
                    184:         * Finally, throw away the kernfs_mount structure
                    185:         */
1.47      thorpej   186:        free(mp->mnt_data, M_KERNFSMNT);
1.64      tron      187:        mp->mnt_data = NULL;
1.15      mycroft   188:        return (0);
1.1       cgd       189: }
                    190:
1.25      christos  191: int
1.88      dsl       192: kernfs_root(struct mount *mp, struct vnode **vpp)
1.1       cgd       193: {
1.95    ! hannken   194:        const struct kern_target *root_target = &kern_targets[0];
        !           195:        int error;
1.1       cgd       196:
1.54      itojun    197:        /* setup "." */
1.95    ! hannken   198:        error = vcache_get(mp, &root_target, sizeof(root_target), vpp);
        !           199:        if (error)
        !           200:                return error;
        !           201:        error = vn_lock(*vpp, LK_EXCLUSIVE);
        !           202:        if (error) {
        !           203:                vrele(*vpp);
        !           204:                *vpp = NULL;
        !           205:                return error;
        !           206:        }
        !           207:        return 0;
1.1       cgd       208: }
                    209:
1.25      christos  210: /*ARGSUSED*/
                    211: int
1.74      christos  212: kernfs_sync(struct mount *mp, int waitfor,
1.82      pooka     213:     kauth_cred_t uc)
1.1       cgd       214: {
1.15      mycroft   215:
1.1       cgd       216:        return (0);
                    217: }
                    218:
1.15      mycroft   219: /*
                    220:  * Kernfs flat namespace lookup.
                    221:  * Currently unsupported.
                    222:  */
1.25      christos  223: int
1.74      christos  224: kernfs_vget(struct mount *mp, ino_t ino,
                    225:     struct vnode **vpp)
1.15      mycroft   226: {
                    227:
                    228:        return (EOPNOTSUPP);
                    229: }
                    230:
1.95    ! hannken   231: int
        !           232: kernfs_loadvnode(struct mount *mp, struct vnode *vp,
        !           233:     const void *key, size_t key_len, const void **new_key)
        !           234: {
        !           235:        const struct kern_target *kt;
        !           236:        struct kernfs_node *kfs, *kfsp;
        !           237:        long *cookie;
        !           238:
        !           239:        KASSERT(key_len == sizeof(kt));
        !           240:        memcpy(&kt, key, key_len);
        !           241:
        !           242:        kfs = kmem_zalloc(sizeof(struct kernfs_node), KM_SLEEP);
        !           243:        cookie = &(VFSTOKERNFS(mp)->fileno_cookie);
        !           244:        mutex_enter(&kfs_lock);
        !           245: again:
        !           246:        TAILQ_FOREACH(kfsp, &VFSTOKERNFS(mp)->nodelist, kfs_list) {
        !           247:                if (kfsp->kfs_cookie == *cookie) {
        !           248:                        (*cookie) ++;
        !           249:                        goto again;
        !           250:                }
        !           251:                if (TAILQ_NEXT(kfsp, kfs_list)) {
        !           252:                        if (kfsp->kfs_cookie < *cookie &&
        !           253:                            *cookie < TAILQ_NEXT(kfsp, kfs_list)->kfs_cookie)
        !           254:                                break;
        !           255:                        if (kfsp->kfs_cookie + 1 <
        !           256:                            TAILQ_NEXT(kfsp, kfs_list)->kfs_cookie) {
        !           257:                                *cookie = kfsp->kfs_cookie + 1;
        !           258:                                break;
        !           259:                        }
        !           260:                }
        !           261:        }
        !           262:
        !           263:        kfs->kfs_cookie = *cookie;
        !           264:
        !           265:        if (kfsp)
        !           266:                TAILQ_INSERT_AFTER(&VFSTOKERNFS(mp)->nodelist, kfsp, kfs,
        !           267:                    kfs_list);
        !           268:        else
        !           269:                TAILQ_INSERT_TAIL(&VFSTOKERNFS(mp)->nodelist, kfs, kfs_list);
        !           270:
        !           271:        kfs->kfs_type = kt->kt_tag;
        !           272:        kfs->kfs_vnode = vp;
        !           273:        kfs->kfs_fileno = KERNFS_FILENO(kt, kt->kt_tag, kfs->kfs_cookie);
        !           274:        kfs->kfs_kt = kt;
        !           275:        kfs->kfs_mode = kt->kt_mode;
        !           276:        vp->v_tag = VT_KERNFS;
        !           277:        vp->v_op = kernfs_vnodeop_p;
        !           278:        vp->v_data = kfs;
        !           279:        vp->v_type = kt->kt_vtype;
        !           280:        mutex_exit(&kfs_lock);
        !           281:
        !           282:        if (kt->kt_tag == KFSkern)
        !           283:                vp->v_vflag = VV_ROOT;
        !           284:
        !           285:        if (kt->kt_tag == KFSdevice) {
        !           286:                spec_node_init(vp, *(dev_t *)kt->kt_data);
        !           287:        }
        !           288:
        !           289:        uvm_vnp_setsize(vp, 0);
        !           290:
        !           291:        *new_key = &kfs->kfs_kt;
        !           292:        return 0;
        !           293: }
        !           294:
1.38      jdolecek  295: extern const struct vnodeopv_desc kernfs_vnodeop_opv_desc;
1.31      thorpej   296:
1.38      jdolecek  297: const struct vnodeopv_desc * const kernfs_vnodeopv_descs[] = {
1.31      thorpej   298:        &kernfs_vnodeop_opv_desc,
                    299:        NULL,
                    300: };
                    301:
1.1       cgd       302: struct vfsops kernfs_vfsops = {
1.93      hannken   303:        .vfs_name = MOUNT_KERNFS,
                    304:        .vfs_min_mount_data = 0,
                    305:        .vfs_mount = kernfs_mount,
                    306:        .vfs_start = kernfs_start,
                    307:        .vfs_unmount = kernfs_unmount,
                    308:        .vfs_root = kernfs_root,
                    309:        .vfs_quotactl = (void *)eopnotsupp,
                    310:        .vfs_statvfs = genfs_statvfs,
                    311:        .vfs_sync = kernfs_sync,
                    312:        .vfs_vget = kernfs_vget,
1.95    ! hannken   313:        .vfs_loadvnode = kernfs_loadvnode,
1.93      hannken   314:        .vfs_fhtovp = (void *)eopnotsupp,
                    315:        .vfs_vptofh = (void *)eopnotsupp,
                    316:        .vfs_init = kernfs_init,
                    317:        .vfs_reinit = kernfs_reinit,
                    318:        .vfs_done = kernfs_done,
                    319:        .vfs_snapshot = (void *)eopnotsupp,
                    320:        .vfs_extattrctl = vfs_stdextattrctl,
                    321:        .vfs_suspendctl = (void *)eopnotsupp,
                    322:        .vfs_renamelock_enter = genfs_renamelock_enter,
                    323:        .vfs_renamelock_exit = genfs_renamelock_exit,
                    324:        .vfs_fsync = (void *)eopnotsupp,
                    325:        .vfs_opv_descs = kernfs_vnodeopv_descs
1.1       cgd       326: };
1.85      rumble    327:
                    328: static int
                    329: kernfs_modcmd(modcmd_t cmd, void *arg)
                    330: {
1.86      rumble    331:        int error;
1.85      rumble    332:
                    333:        switch (cmd) {
                    334:        case MODULE_CMD_INIT:
1.86      rumble    335:                error = vfs_attach(&kernfs_vfsops);
                    336:                if (error != 0)
                    337:                        break;
                    338:                sysctl_createv(&kernfs_sysctl_log, 0, NULL, NULL,
                    339:                               CTLFLAG_PERMANENT,
                    340:                               CTLTYPE_NODE, "kernfs",
                    341:                               SYSCTL_DESCR("/kern file system"),
                    342:                               NULL, 0, NULL, 0,
                    343:                               CTL_VFS, 11, CTL_EOL);
                    344:                /*
                    345:                 * XXX the "11" above could be dynamic, thereby eliminating one
                    346:                 * more instance of the "number to vfs" mapping problem, but
                    347:                 * "11" is the order as taken from sys/mount.h
                    348:                 */
                    349:                break;
1.85      rumble    350:        case MODULE_CMD_FINI:
1.86      rumble    351:                error = vfs_detach(&kernfs_vfsops);
                    352:                if (error != 0)
                    353:                        break;
                    354:                sysctl_teardown(&kernfs_sysctl_log);
                    355:                break;
1.85      rumble    356:        default:
1.86      rumble    357:                error = ENOTTY;
                    358:                break;
1.85      rumble    359:        }
1.86      rumble    360:
                    361:        return (error);
1.85      rumble    362: }

CVSweb <webmaster@jp.NetBSD.org>