Annotation of kernel/bsd/miscfs/umapfs/umap_vfsops.c, revision 1.1.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.