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