Annotation of kernel/bsd/miscfs/umapfs/umap_vfsops.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
        !             7:  * Reserved.  This file contains Original Code and/or Modifications of
        !             8:  * Original Code as defined in and that are subject to the Apple Public
        !             9:  * Source License Version 1.1 (the "License").  You may not use this file
        !            10:  * except in compliance with the License.  Please obtain a copy of the
        !            11:  * License at http://www.apple.com/publicsource and read it before using
        !            12:  * this file.
        !            13:  * 
        !            14:  * The Original Code and all software distributed under the License are
        !            15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            19:  * License for the specific language governing rights and limitations
        !            20:  * under the License.
        !            21:  * 
        !            22:  * @APPLE_LICENSE_HEADER_END@
        !            23:  */
        !            24: 
        !            25: /*     $NetBSD: umap_vfsops.c,v 1.7 1995/03/09 12:05:59 mycroft Exp $  */
        !            26: 
        !            27: /*
        !            28:  * Copyright (c) 1992, 1993
        !            29:  *     The Regents of the University of California.  All rights reserved.
        !            30:  *
        !            31:  * This code is derived from software donated to Berkeley by
        !            32:  * the UCLA Ficus project.
        !            33:  *
        !            34:  * Redistribution and use in source and binary forms, with or without
        !            35:  * modification, are permitted provided that the following conditions
        !            36:  * are met:
        !            37:  * 1. Redistributions of source code must retain the above copyright
        !            38:  *    notice, this list of conditions and the following disclaimer.
        !            39:  * 2. Redistributions in binary form must reproduce the above copyright
        !            40:  *    notice, this list of conditions and the following disclaimer in the
        !            41:  *    documentation and/or other materials provided with the distribution.
        !            42:  * 3. All advertising materials mentioning features or use of this software
        !            43:  *    must display the following acknowledgement:
        !            44:  *     This product includes software developed by the University of
        !            45:  *     California, Berkeley and its contributors.
        !            46:  * 4. Neither the name of the University nor the names of its contributors
        !            47:  *    may be used to endorse or promote products derived from this software
        !            48:  *    without specific prior written permission.
        !            49:  *
        !            50:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            51:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            52:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            53:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            54:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            55:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            56:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            57:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            58:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            59:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            60:  * SUCH DAMAGE.
        !            61:  *
        !            62:  *     from: @(#)null_vfsops.c       1.5 (Berkeley) 7/10/92
        !            63:  *     @(#)umap_vfsops.c       8.3 (Berkeley) 1/21/94
        !            64:  */
        !            65: 
        !            66: /*
        !            67:  * Umap Layer
        !            68:  * (See mount_umap(8) for a description of this layer.)
        !            69:  */
        !            70: 
        !            71: #include <sys/param.h>
        !            72: #include <sys/systm.h>
        !            73: #include <sys/time.h>
        !            74: #include <sys/types.h>
        !            75: #include <sys/vnode.h>
        !            76: #include <sys/mount.h>
        !            77: #include <sys/namei.h>
        !            78: #include <sys/malloc.h>
        !            79: #include <miscfs/umapfs/umap.h>
        !            80: 
        !            81: /*
        !            82:  * Mount umap layer
        !            83:  */
        !            84: int
        !            85: umapfs_mount(mp, path, data, ndp, p)
        !            86:        struct mount *mp;
        !            87:        char *path;
        !            88:        caddr_t data;
        !            89:        struct nameidata *ndp;
        !            90:        struct proc *p;
        !            91: {
        !            92:        struct umap_args args;
        !            93:        struct vnode *lowerrootvp, *vp;
        !            94:        struct vnode *umapm_rootvp;
        !            95:        struct umap_mount *amp;
        !            96:        size_t size;
        !            97:        int error;
        !            98: 
        !            99: #ifdef UMAPFS_DIAGNOSTIC
        !           100:        printf("umapfs_mount(mp = %x)\n", mp);
        !           101: #endif
        !           102: 
        !           103:        /*
        !           104:         * Update is a no-op
        !           105:         */
        !           106:        if (mp->mnt_flag & MNT_UPDATE) {
        !           107:                return (EOPNOTSUPP);
        !           108:                /* return (VFS_MOUNT(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, path, data, ndp, p));*/
        !           109:        }
        !           110: 
        !           111:        /*
        !           112:         * Get argument
        !           113:         */
        !           114:        if (error = copyin(data, (caddr_t)&args, sizeof(struct umap_args)))
        !           115:                return (error);
        !           116: 
        !           117:        /*
        !           118:         * Find lower node
        !           119:         */
        !           120:        NDINIT(ndp, LOOKUP, FOLLOW|WANTPARENT|LOCKLEAF,
        !           121:                UIO_USERSPACE, args.target, p);
        !           122:        if (error = namei(ndp))
        !           123:                return (error);
        !           124: 
        !           125:        /*
        !           126:         * Sanity check on lower vnode
        !           127:         */
        !           128:        lowerrootvp = ndp->ni_vp;
        !           129: #ifdef UMAPFS_DIAGNOSTIC
        !           130:        printf("vp = %x, check for VDIR...\n", lowerrootvp);
        !           131: #endif
        !           132:        vrele(ndp->ni_dvp);
        !           133:        ndp->ni_dvp = 0;
        !           134: 
        !           135:        if (lowerrootvp->v_type != VDIR) {
        !           136:                vput(lowerrootvp);
        !           137:                return (EINVAL);
        !           138:        }
        !           139: 
        !           140: #ifdef UMAPFS_DIAGNOSTIC
        !           141:        printf("mp = %x\n", mp);
        !           142: #endif
        !           143: 
        !           144: //     amp = (struct umap_mount *) malloc(sizeof(struct umap_mount),
        !           145: //                             M_UFSMNT, M_WAITOK);    /* XXX */
        !           146:        MALLOC(amp, struct umap_mount *, sizeof(struct umap_mount),
        !           147:                                M_UFSMNT, M_WAITOK);
        !           148: 
        !           149:        /*
        !           150:         * Save reference to underlying FS
        !           151:         */
        !           152:        amp->umapm_vfs = lowerrootvp->v_mount;
        !           153: 
        !           154:        /* 
        !           155:         * Now copy in the number of entries and maps for umap mapping.
        !           156:         */
        !           157:        amp->info_nentries = args.nentries;
        !           158:        amp->info_gnentries = args.gnentries;
        !           159:        error = copyin(args.mapdata, (caddr_t)amp->info_mapdata, 
        !           160:            2*sizeof(u_long)*args.nentries);
        !           161:        if (error)
        !           162:                return (error);
        !           163: 
        !           164: #ifdef UMAP_DIAGNOSTIC
        !           165:        printf("umap_mount:nentries %d\n",args.nentries);
        !           166:        for (i = 0; i < args.nentries; i++)
        !           167:                printf("   %d maps to %d\n", amp->info_mapdata[i][0],
        !           168:                    amp->info_mapdata[i][1]);
        !           169: #endif
        !           170: 
        !           171:        error = copyin(args.gmapdata, (caddr_t)amp->info_gmapdata, 
        !           172:            2*sizeof(u_long)*args.nentries);
        !           173:        if (error)
        !           174:                return (error);
        !           175: 
        !           176: #ifdef UMAP_DIAGNOSTIC
        !           177:        printf("umap_mount:gnentries %d\n",args.gnentries);
        !           178:        for (i = 0; i < args.gnentries; i++)
        !           179:                printf("        group %d maps to %d\n", 
        !           180:                    amp->info_gmapdata[i][0],
        !           181:                    amp->info_gmapdata[i][1]);
        !           182: #endif
        !           183: 
        !           184: 
        !           185:        /*
        !           186:         * Save reference.  Each mount also holds
        !           187:         * a reference on the root vnode.
        !           188:         */
        !           189:        error = umap_node_create(mp, lowerrootvp, &vp);
        !           190:        /*
        !           191:         * Unlock the node (either the lower or the alias)
        !           192:         */
        !           193:        VOP_UNLOCK(vp);
        !           194:        /*
        !           195:         * Make sure the node alias worked
        !           196:         */
        !           197:        if (error) {
        !           198:                vrele(lowerrootvp);
        !           199:                free(amp, M_UFSMNT);    /* XXX */
        !           200:                return (error);
        !           201:        }
        !           202: 
        !           203:        /*
        !           204:         * Keep a held reference to the root vnode.
        !           205:         * It is vrele'd in umapfs_unmount.
        !           206:         */
        !           207:        umapm_rootvp = vp;
        !           208:        umapm_rootvp->v_flag |= VROOT;
        !           209:        amp->umapm_rootvp = umapm_rootvp;
        !           210:        if (UMAPVPTOLOWERVP(umapm_rootvp)->v_mount->mnt_flag & MNT_LOCAL)
        !           211:                mp->mnt_flag |= MNT_LOCAL;
        !           212:        mp->mnt_data = (qaddr_t) amp;
        !           213:        getnewfsid(mp, makefstype(MOUNT_LOFS));
        !           214: 
        !           215:        (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
        !           216:        bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
        !           217:        (void) copyinstr(args.target, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, 
        !           218:            &size);
        !           219:        bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
        !           220: #ifdef UMAPFS_DIAGNOSTIC
        !           221:        printf("umapfs_mount: lower %s, alias at %s\n",
        !           222:                mp->mnt_stat.f_mntfromname, mp->mnt_stat.f_mntonname);
        !           223: #endif
        !           224:        return (0);
        !           225: }
        !           226: 
        !           227: /*
        !           228:  * VFS start.  Nothing needed here - the start routine
        !           229:  * on the underlying filesystem will have been called
        !           230:  * when that filesystem was mounted.
        !           231:  */
        !           232: int
        !           233: umapfs_start(mp, flags, p)
        !           234:        struct mount *mp;
        !           235:        int flags;
        !           236:        struct proc *p;
        !           237: {
        !           238: 
        !           239:        return (0);
        !           240:        /* return (VFS_START(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, flags, p)); */
        !           241: }
        !           242: 
        !           243: /*
        !           244:  * Free reference to umap layer
        !           245:  */
        !           246: int
        !           247: umapfs_unmount(mp, mntflags, p)
        !           248:        struct mount *mp;
        !           249:        int mntflags;
        !           250:        struct proc *p;
        !           251: {
        !           252:        struct vnode *umapm_rootvp = MOUNTTOUMAPMOUNT(mp)->umapm_rootvp;
        !           253:        int error;
        !           254:        int flags = 0;
        !           255:        extern int doforce;
        !           256: 
        !           257: #ifdef UMAPFS_DIAGNOSTIC
        !           258:        printf("umapfs_unmount(mp = %x)\n", mp);
        !           259: #endif
        !           260: 
        !           261:        if (mntflags & MNT_FORCE) {
        !           262:                /* lofs can never be rootfs so don't check for it */
        !           263:                if (!doforce)
        !           264:                        return (EINVAL);
        !           265:                flags |= FORCECLOSE;
        !           266:        }
        !           267: 
        !           268:        /*
        !           269:         * Clear out buffer cache.  I don't think we
        !           270:         * ever get anything cached at this level at the
        !           271:         * moment, but who knows...
        !           272:         */
        !           273: #ifdef notyet
        !           274:        mntflushbuf(mp, 0); 
        !           275:        if (mntinvalbuf(mp, 1))
        !           276:                return (EBUSY);
        !           277: #endif
        !           278:        if (umapm_rootvp->v_usecount > 1)
        !           279:                return (EBUSY);
        !           280:        if (error = vflush(mp, umapm_rootvp, flags))
        !           281:                return (error);
        !           282: 
        !           283: #ifdef UMAPFS_DIAGNOSTIC
        !           284:        vprint("alias root of lower", umapm_rootvp);
        !           285: #endif  
        !           286:        /*
        !           287:         * Release reference on underlying root vnode
        !           288:         */
        !           289:        vrele(umapm_rootvp);
        !           290:        /*
        !           291:         * And blow it away for future re-use
        !           292:         */
        !           293:        vgone(umapm_rootvp);
        !           294:        /*
        !           295:         * Finally, throw away the umap_mount structure
        !           296:         */
        !           297:        free(mp->mnt_data, M_UFSMNT);   /* XXX */
        !           298:        mp->mnt_data = 0;
        !           299:        return (0);
        !           300: }
        !           301: 
        !           302: int
        !           303: umapfs_root(mp, vpp)
        !           304:        struct mount *mp;
        !           305:        struct vnode **vpp;
        !           306: {
        !           307:        struct vnode *vp;
        !           308: 
        !           309: #ifdef UMAPFS_DIAGNOSTIC
        !           310:        printf("umapfs_root(mp = %x, vp = %x->%x)\n", mp,
        !           311:                        MOUNTTOUMAPMOUNT(mp)->umapm_rootvp,
        !           312:                        UMAPVPTOLOWERVP(MOUNTTOUMAPMOUNT(mp)->umapm_rootvp)
        !           313:                        );
        !           314: #endif
        !           315: 
        !           316:        /*
        !           317:         * Return locked reference to root.
        !           318:         */
        !           319:        vp = MOUNTTOUMAPMOUNT(mp)->umapm_rootvp;
        !           320:        VREF(vp);
        !           321:        VOP_LOCK(vp);
        !           322:        *vpp = vp;
        !           323:        return (0);
        !           324: }
        !           325: 
        !           326: int
        !           327: umapfs_quotactl(mp, cmd, uid, arg, p)
        !           328:        struct mount *mp;
        !           329:        int cmd;
        !           330:        uid_t uid;
        !           331:        caddr_t arg;
        !           332:        struct proc *p;
        !           333: {
        !           334: 
        !           335:        return (VFS_QUOTACTL(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, cmd, uid, arg, p));
        !           336: }
        !           337: 
        !           338: int
        !           339: umapfs_statfs(mp, sbp, p)
        !           340:        struct mount *mp;
        !           341:        struct statfs *sbp;
        !           342:        struct proc *p;
        !           343: {
        !           344:        int error;
        !           345:        struct statfs mstat;
        !           346: 
        !           347: #ifdef UMAPFS_DIAGNOSTIC
        !           348:        printf("umapfs_statfs(mp = %x, vp = %x->%x)\n", mp,
        !           349:                        MOUNTTOUMAPMOUNT(mp)->umapm_rootvp,
        !           350:                        UMAPVPTOLOWERVP(MOUNTTOUMAPMOUNT(mp)->umapm_rootvp)
        !           351:                        );
        !           352: #endif
        !           353: 
        !           354:        bzero(&mstat, sizeof(mstat));
        !           355: 
        !           356:        error = VFS_STATFS(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, &mstat, p);
        !           357:        if (error)
        !           358:                return (error);
        !           359: 
        !           360:        /* now copy across the "interesting" information and fake the rest */
        !           361:        sbp->f_type = mstat.f_type;
        !           362:        sbp->f_flags = mstat.f_flags;
        !           363:        sbp->f_bsize = mstat.f_bsize;
        !           364:        sbp->f_iosize = mstat.f_iosize;
        !           365:        sbp->f_blocks = mstat.f_blocks;
        !           366:        sbp->f_bfree = mstat.f_bfree;
        !           367:        sbp->f_bavail = mstat.f_bavail;
        !           368:        sbp->f_files = mstat.f_files;
        !           369:        sbp->f_ffree = mstat.f_ffree;
        !           370:        if (sbp != &mp->mnt_stat) {
        !           371:                bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid));
        !           372:                bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
        !           373:                bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
        !           374:        }
        !           375:        strncpy(sbp->f_fstypename, mp->mnt_op->vfs_name, MFSNAMELEN);
        !           376:        sbp->f_fstypename[MFSNAMELEN] = '\0';
        !           377:        return (0);
        !           378: }
        !           379: 
        !           380: int
        !           381: umapfs_sync(mp, waitfor, cred, p)
        !           382:        struct mount *mp;
        !           383:        int waitfor;
        !           384:        struct ucred *cred;
        !           385:        struct proc *p;
        !           386: {
        !           387: 
        !           388:        /*
        !           389:         * XXX - Assumes no data cached at umap layer.
        !           390:         */
        !           391:        return (0);
        !           392: }
        !           393: 
        !           394: int
        !           395: umapfs_vget(mp, ino, vpp)
        !           396:        struct mount *mp;
        !           397:        ino_t ino;
        !           398:        struct vnode **vpp;
        !           399: {
        !           400:        
        !           401:        return (VFS_VGET(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, ino, vpp));
        !           402: }
        !           403: 
        !           404: int
        !           405: umapfs_fhtovp(mp, fidp, nam, vpp, exflagsp, credanonp)
        !           406:        struct mount *mp;
        !           407:        struct fid *fidp;
        !           408:        struct mbuf *nam;
        !           409:        struct vnode **vpp;
        !           410:        int *exflagsp;
        !           411:        struct ucred**credanonp;
        !           412: {
        !           413: 
        !           414:        return (EOPNOTSUPP);
        !           415: }
        !           416: 
        !           417: int
        !           418: umapfs_vptofh(vp, fhp)
        !           419:        struct vnode *vp;
        !           420:        struct fid *fhp;
        !           421: {
        !           422: 
        !           423:        return (EOPNOTSUPP);
        !           424: }
        !           425: 
        !           426: int umapfs_init __P((void));
        !           427: 
        !           428: struct vfsops umap_vfsops = {
        !           429:        MOUNT_UMAP,
        !           430:        umapfs_mount,
        !           431:        umapfs_start,
        !           432:        umapfs_unmount,
        !           433:        umapfs_root,
        !           434:        umapfs_quotactl,
        !           435:        umapfs_statfs,
        !           436:        umapfs_sync,
        !           437:        umapfs_vget,
        !           438:        umapfs_fhtovp,
        !           439:        umapfs_vptofh,
        !           440:        umapfs_init,
        !           441: };

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.