|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.