Annotation of XNU/bsd/ufs/mfs/mfs_vfsops.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
                     23: /*
                     24:  * Copyright (c) 1989, 1990, 1993, 1994
                     25:  *     The Regents of the University of California.  All rights reserved.
                     26:  *
                     27:  * Redistribution and use in source and binary forms, with or without
                     28:  * modification, are permitted provided that the following conditions
                     29:  * are met:
                     30:  * 1. Redistributions of source code must retain the above copyright
                     31:  *    notice, this list of conditions and the following disclaimer.
                     32:  * 2. Redistributions in binary form must reproduce the above copyright
                     33:  *    notice, this list of conditions and the following disclaimer in the
                     34:  *    documentation and/or other materials provided with the distribution.
                     35:  * 3. All advertising materials mentioning features or use of this software
                     36:  *    must display the following acknowledgement:
                     37:  *     This product includes software developed by the University of
                     38:  *     California, Berkeley and its contributors.
                     39:  * 4. Neither the name of the University nor the names of its contributors
                     40:  *    may be used to endorse or promote products derived from this software
                     41:  *    without specific prior written permission.
                     42:  *
                     43:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     44:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     45:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     46:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     47:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     48:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     49:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     50:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     51:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     52:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     53:  * SUCH DAMAGE.
                     54:  *
                     55:  *     @(#)mfs_vfsops.c        8.4 (Berkeley) 4/16/94
                     56:  */
                     57: 
                     58: #include <sys/param.h>
                     59: #include <sys/systm.h>
                     60: #include <sys/time.h>
                     61: #include <sys/kernel.h>
                     62: #include <sys/proc.h>
                     63: #include <sys/buf.h>
                     64: #include <sys/mount.h>
                     65: #include <sys/signalvar.h>
                     66: #include <sys/vnode.h>
                     67: #include <sys/malloc.h>
                     68: 
                     69: #include <ufs/ufs/quota.h>
                     70: #include <ufs/ufs/inode.h>
                     71: #include <ufs/ufs/ufsmount.h>
                     72: #include <ufs/ufs/ufs_extern.h>
                     73: 
                     74: #include <ufs/ffs/fs.h>
                     75: #include <ufs/ffs/ffs_extern.h>
                     76: 
                     77: #include <ufs/mfs/mfsnode.h>
                     78: #include <ufs/mfs/mfs_extern.h>
                     79: 
                     80: caddr_t        mfs_rootbase;   /* address of mini-root in kernel virtual memory */
                     81: u_long mfs_rootsize;   /* size of mini-root in bytes */
                     82: 
                     83: static int mfs_minor;  /* used for building internal dev_t */
                     84: 
                     85: extern int (**mfs_vnodeop_p)();
                     86: 
                     87: /*
                     88:  * mfs vfs operations.
                     89:  */
                     90: struct vfsops mfs_vfsops = {
                     91:        MOUNT_MFS,
                     92:        mfs_mount,
                     93:        mfs_start,
                     94:        ffs_unmount,
                     95:        ufs_root,
                     96:        ufs_quotactl,
                     97:        mfs_statfs,
                     98:        ffs_sync,
                     99:        ffs_vget,
                    100:        ffs_fhtovp,
                    101:        ffs_vptofh,
                    102:        mfs_init,
                    103: };
                    104: 
                    105: /*
                    106:  * Called by main() when mfs is going to be mounted as root.
                    107:  *
                    108:  * Name is updated by mount(8) after booting.
                    109:  */
                    110: #define ROOTNAME       "mfs_root"
                    111: 
                    112: mfs_mountroot()
                    113: {
                    114:        extern struct vnode *rootvp;
                    115:        register struct fs *fs;
                    116:        register struct mount *mp;
                    117:        struct proc *p = kernel_proc;   /* XXX - WMG*/
                    118:        struct ufsmount *ump;
                    119:        struct mfsnode *mfsp;
                    120:        size_t size;
                    121:        int error;
                    122: 
                    123:        /*
                    124:         * Get vnodes for swapdev and rootdev.
                    125:         */
                    126: #if 0
                    127:        if (bdevvp(swapdev, &swapdev_vp) || bdevvp(rootdev, &rootvp))
                    128:                panic("mfs_mountroot: can't setup bdevvp's");
                    129: #else
                    130:        if ( bdevvp(rootdev, &rootvp))
                    131:                panic("mfs_mountroot: can't setup bdevvp's");
                    132: 
                    133: #endif
                    134:        MALLOC_ZONE(mp, struct mount *,
                    135:                        sizeof(struct mount), M_MOUNT, M_WAITOK);
                    136:        bzero((char *)mp, (u_long)sizeof(struct mount));
                    137:        mp->mnt_op = &mfs_vfsops;
                    138:        mp->mnt_flag = MNT_RDONLY;
                    139:        MALLOC(mfsp, struct mfsnode *, sizeof(struct mfsnode), M_MFSNODE, M_WAITOK);
                    140:        rootvp->v_data = mfsp;
                    141:        rootvp->v_op = mfs_vnodeop_p;
                    142:        rootvp->v_tag = VT_MFS;
                    143:        mfsp->mfs_baseoff = mfs_rootbase;
                    144:        mfsp->mfs_size = mfs_rootsize;
                    145:        mfsp->mfs_vnode = rootvp;
                    146:        mfsp->mfs_pid = p->p_pid;
                    147:        mfsp->mfs_buflist = (struct buf *)0;
                    148:        if (error = ffs_mountfs(rootvp, mp, p)) {
                    149:                _FREE_ZONE(mp, sizeof (struct mount), M_MOUNT);
                    150:                _FREE(mfsp, M_MFSNODE);
                    151:                return (error);
                    152:        }
                    153:        if (error = vfs_lock(mp)) {
                    154:                (void)ffs_unmount(mp, 0, p);
                    155:                _FREE_ZONE(mp, sizeof (struct mount), M_MOUNT);
                    156:                _FREE(mfsp, M_MFSNODE);
                    157:                return (error);
                    158:        }
                    159:        CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list);
                    160:        mp->mnt_vnodecovered = NULLVP;
                    161:        ump = VFSTOUFS(mp);
                    162:        fs = ump->um_fs;
                    163:        bzero(fs->fs_fsmnt, sizeof(fs->fs_fsmnt));
                    164:        fs->fs_fsmnt[0] = '/';
                    165:        bcopy(fs->fs_fsmnt, mp->mnt_stat.f_mntonname, MNAMELEN);
                    166:        (void) copystr(ROOTNAME, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
                    167:            &size);
                    168:        bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
                    169:        (void)ffs_statfs(mp, &mp->mnt_stat, p);
                    170:        vfs_unlock(mp);
                    171:        inittodr((time_t)0);
                    172:        return (0);
                    173: }
                    174: 
                    175: /*
                    176:  * This is called early in boot to set the base address and size
                    177:  * of the mini-root.
                    178:  */
                    179: mfs_initminiroot(base)
                    180:        caddr_t base;
                    181: {
                    182:        struct fs *fs = (struct fs *)(base + SBOFF);
                    183:        extern int (*mountroot)();
                    184: 
                    185:        /* check for valid super block */
                    186:        if (fs->fs_magic != FS_MAGIC || fs->fs_bsize > MAXBSIZE ||
                    187:            fs->fs_bsize < sizeof(struct fs))
                    188:                return (0);
                    189:        mountroot = mfs_mountroot;
                    190:        mfs_rootbase = base;
                    191:        mfs_rootsize = fs->fs_fsize * fs->fs_size;
                    192:        rootdev = makedev(255, mfs_minor++);
                    193:        return (mfs_rootsize);
                    194: }
                    195: 
                    196: /*
                    197:  * VFS Operations.
                    198:  *
                    199:  * mount system call
                    200:  */
                    201: /* ARGSUSED */
                    202: int
                    203: mfs_mount(mp, path, data, ndp, p)
                    204:        register struct mount *mp;
                    205:        char *path;
                    206:        caddr_t data;
                    207:        struct nameidata *ndp;
                    208:        struct proc *p;
                    209: {
                    210:        struct vnode *devvp;
                    211:        struct mfs_args args;
                    212:        struct ufsmount *ump;
                    213:        register struct fs *fs;
                    214:        register struct mfsnode *mfsp;
                    215:        size_t size;
                    216:        int flags, error;
                    217: 
                    218:        if (error = copyin(data, (caddr_t)&args, sizeof (struct mfs_args)))
                    219:                return (error);
                    220: 
                    221:        /*
                    222:         * If updating, check whether changing from read-only to
                    223:         * read/write; if there is no device name, that's all we do.
                    224:         */
                    225:        if (mp->mnt_flag & MNT_UPDATE) {
                    226:                ump = VFSTOUFS(mp);
                    227:                fs = ump->um_fs;
                    228:                if (fs->fs_ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) {
                    229:                        flags = WRITECLOSE;
                    230:                        if (mp->mnt_flag & MNT_FORCE)
                    231:                                flags |= FORCECLOSE;
                    232:                        if (vfs_busy(mp))
                    233:                                return (EBUSY);
                    234:                        error = ffs_flushfiles(mp, flags, p);
                    235:                        vfs_unbusy(mp);
                    236:                        if (error)
                    237:                                return (error);
                    238:                }
                    239:                if (fs->fs_ronly && (mp->mnt_flag & MNT_WANTRDWR))
                    240:                        fs->fs_ronly = 0;
                    241: #ifdef EXPORTMFS
                    242:                if (args.fspec == 0)
                    243:                        return (vfs_export(mp, &ump->um_export, &args.export));
                    244: #endif
                    245:                return (0);
                    246:        }
                    247:        MALLOC(mfsp, struct mfsnode *, sizeof(struct mfsnode), M_MFSNODE, M_WAITOK);
                    248:        error = getnewvnode(VT_MFS, (struct mount *)0, mfs_vnodeop_p, &devvp);
                    249:        if (error) {
                    250:                FREE(mfsp, M_MFSNODE);
                    251:                return (error);
                    252:        }
                    253:        devvp->v_type = VBLK;
                    254:        if (checkalias(devvp, makedev(255, mfs_minor++), (struct mount *)0))
                    255:                panic("mfs_mount: dup dev");
                    256:        devvp->v_data = mfsp;
                    257:        mfsp->mfs_baseoff = args.base;
                    258:        mfsp->mfs_size = args.size;
                    259:        mfsp->mfs_vnode = devvp;
                    260:        mfsp->mfs_pid = p->p_pid;
                    261:        mfsp->mfs_buflist = (struct buf *)0;
                    262:        if (error = ffs_mountfs(devvp, mp, p)) {
                    263:                mfsp->mfs_buflist = (struct buf *)-1;
                    264:                vrele(devvp);
                    265:                return (error);
                    266:        }
                    267:        ump = VFSTOUFS(mp);
                    268:        fs = ump->um_fs;
                    269:        (void) copyinstr(path, fs->fs_fsmnt, sizeof(fs->fs_fsmnt) - 1, &size);
                    270:        bzero(fs->fs_fsmnt + size, sizeof(fs->fs_fsmnt) - size);
                    271:        bcopy(fs->fs_fsmnt, mp->mnt_stat.f_mntonname, MNAMELEN);
                    272:        (void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
                    273:            &size);
                    274:        bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
                    275:        return (0);
                    276: }
                    277: 
                    278: int    mfs_pri = PWAIT | PCATCH;               /* XXX prob. temp */
                    279: 
                    280: /*
                    281:  * Used to grab the process and keep it in the kernel to service
                    282:  * memory filesystem I/O requests.
                    283:  *
                    284:  * Loop servicing I/O requests.
                    285:  * Copy the requested data into or out of the memory filesystem
                    286:  * address space.
                    287:  */
                    288: /* ARGSUSED */
                    289: int
                    290: mfs_start(mp, flags, p)
                    291:        struct mount *mp;
                    292:        int flags;
                    293:        struct proc *p;
                    294: {
                    295:        register struct vnode *vp = VFSTOUFS(mp)->um_devvp;
                    296:        register struct mfsnode *mfsp = VTOMFS(vp);
                    297:        register struct buf *bp;
                    298:        register caddr_t base;
                    299:        int error = 0;
                    300: 
                    301:        base = mfsp->mfs_baseoff;
                    302:        while (mfsp->mfs_buflist != (struct buf *)(-1)) {
                    303:                while (bp = mfsp->mfs_buflist) {
                    304:                        mfsp->mfs_buflist = bp->b_actf;
                    305:                        mfs_doio(bp, base);
                    306:                        wakeup((caddr_t)bp);
                    307:                }
                    308:                /*
                    309:                 * If a non-ignored signal is received, try to unmount.
                    310:                 * If that fails, clear the signal (it has been "processed"),
                    311:                 * otherwise we will loop here, as tsleep will always return
                    312:                 * EINTR/ERESTART.
                    313:                 */
                    314:                if (error = tsleep((caddr_t)vp, mfs_pri, "mfsidl", 0))
                    315:                        if (dounmount(mp, 0, p) != 0)
                    316:                                CLRSIG(p, CURSIG(p));
                    317:        }
                    318:        return (error);
                    319: }
                    320: 
                    321: /*
                    322:  * Get file system statistics.
                    323:  */
                    324: mfs_statfs(mp, sbp, p)
                    325:        struct mount *mp;
                    326:        struct statfs *sbp;
                    327:        struct proc *p;
                    328: {
                    329:        int error;
                    330: 
                    331:        error = ffs_statfs(mp, sbp, p);
                    332: #ifdef COMPAT_09
                    333:        sbp->f_type = 3;
                    334: #else
                    335:        sbp->f_type = 0;
                    336: #endif
                    337:        strncpy(&sbp->f_fstypename[0], mp->mnt_op->vfs_name, MFSNAMELEN);
                    338:        sbp->f_fstypename[MFSNAMELEN] = '\0';
                    339:        return (error);
                    340: }

unix.superglobalmegacorp.com

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