|
|
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: mfs_vnops.c,v 1.5 1994/12/14 13:03:52 mycroft Exp $ */ ! 26: ! 27: /* ! 28: * Copyright (c) 1989, 1993 ! 29: * The Regents of the University of California. All rights reserved. ! 30: * ! 31: * Redistribution and use in source and binary forms, with or without ! 32: * modification, are permitted provided that the following conditions ! 33: * are met: ! 34: * 1. Redistributions of source code must retain the above copyright ! 35: * notice, this list of conditions and the following disclaimer. ! 36: * 2. Redistributions in binary form must reproduce the above copyright ! 37: * notice, this list of conditions and the following disclaimer in the ! 38: * documentation and/or other materials provided with the distribution. ! 39: * 3. All advertising materials mentioning features or use of this software ! 40: * must display the following acknowledgement: ! 41: * This product includes software developed by the University of ! 42: * California, Berkeley and its contributors. ! 43: * 4. Neither the name of the University nor the names of its contributors ! 44: * may be used to endorse or promote products derived from this software ! 45: * without specific prior written permission. ! 46: * ! 47: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ! 48: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! 49: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ! 50: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ! 51: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ! 52: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ! 53: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 54: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ! 55: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ! 56: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ! 57: * SUCH DAMAGE. ! 58: * ! 59: * @(#)mfs_vnops.c 8.5 (Berkeley) 7/28/94 ! 60: */ ! 61: ! 62: #include <sys/param.h> ! 63: #include <sys/systm.h> ! 64: #include <sys/time.h> ! 65: #include <sys/kernel.h> ! 66: #include <sys/proc.h> ! 67: #include <sys/buf.h> ! 68: #include <sys/map.h> ! 69: #include <sys/vnode.h> ! 70: #include <sys/malloc.h> ! 71: ! 72: #include <miscfs/specfs/specdev.h> ! 73: ! 74: #include <machine/vmparam.h> ! 75: ! 76: #include <ufs/mfs/mfsnode.h> ! 77: #include <ufs/mfs/mfsiom.h> ! 78: #include <ufs/mfs/mfs_extern.h> ! 79: ! 80: /* ! 81: * mfs vnode operations. ! 82: */ ! 83: int (**mfs_vnodeop_p)(); ! 84: struct vnodeopv_entry_desc mfs_vnodeop_entries[] = { ! 85: { &vop_default_desc, vn_default_error }, ! 86: { &vop_lookup_desc, mfs_lookup }, /* lookup */ ! 87: { &vop_create_desc, mfs_create }, /* create */ ! 88: { &vop_mknod_desc, mfs_mknod }, /* mknod */ ! 89: { &vop_open_desc, mfs_open }, /* open */ ! 90: { &vop_close_desc, mfs_close }, /* close */ ! 91: { &vop_access_desc, mfs_access }, /* access */ ! 92: { &vop_getattr_desc, mfs_getattr }, /* getattr */ ! 93: { &vop_setattr_desc, mfs_setattr }, /* setattr */ ! 94: { &vop_read_desc, mfs_read }, /* read */ ! 95: { &vop_write_desc, mfs_write }, /* write */ ! 96: { &vop_ioctl_desc, mfs_ioctl }, /* ioctl */ ! 97: { &vop_select_desc, mfs_select }, /* select */ ! 98: { &vop_mmap_desc, mfs_mmap }, /* mmap */ ! 99: { &vop_fsync_desc, spec_fsync }, /* fsync */ ! 100: { &vop_seek_desc, mfs_seek }, /* seek */ ! 101: { &vop_remove_desc, mfs_remove }, /* remove */ ! 102: { &vop_link_desc, mfs_link }, /* link */ ! 103: { &vop_rename_desc, mfs_rename }, /* rename */ ! 104: { &vop_mkdir_desc, mfs_mkdir }, /* mkdir */ ! 105: { &vop_rmdir_desc, mfs_rmdir }, /* rmdir */ ! 106: { &vop_symlink_desc, mfs_symlink }, /* symlink */ ! 107: { &vop_readdir_desc, mfs_readdir }, /* readdir */ ! 108: { &vop_readlink_desc, mfs_readlink }, /* readlink */ ! 109: { &vop_abortop_desc, mfs_abortop }, /* abortop */ ! 110: { &vop_inactive_desc, mfs_inactive }, /* inactive */ ! 111: { &vop_reclaim_desc, mfs_reclaim }, /* reclaim */ ! 112: { &vop_lock_desc, mfs_lock }, /* lock */ ! 113: { &vop_unlock_desc, mfs_unlock }, /* unlock */ ! 114: { &vop_bmap_desc, mfs_bmap }, /* bmap */ ! 115: { &vop_strategy_desc, mfs_strategy }, /* strategy */ ! 116: { &vop_print_desc, mfs_print }, /* print */ ! 117: { &vop_islocked_desc, mfs_islocked }, /* islocked */ ! 118: { &vop_pathconf_desc, mfs_pathconf }, /* pathconf */ ! 119: { &vop_advlock_desc, mfs_advlock }, /* advlock */ ! 120: { &vop_blkatoff_desc, mfs_blkatoff }, /* blkatoff */ ! 121: { &vop_valloc_desc, mfs_valloc }, /* valloc */ ! 122: { &vop_vfree_desc, mfs_vfree }, /* vfree */ ! 123: { &vop_truncate_desc, mfs_truncate }, /* truncate */ ! 124: { &vop_update_desc, mfs_update }, /* update */ ! 125: { &vop_bwrite_desc, mfs_bwrite }, /* bwrite */ ! 126: { &vop_pgrd_desc, mfs_pgrg }, /* pager read */ ! 127: { &vop_pgwr_desc, mfs_pgwr }, /* pager write */ ! 128: { (struct vnodeop_desc*)NULL, (int(*)())NULL } ! 129: }; ! 130: struct vnodeopv_desc mfs_vnodeop_opv_desc = ! 131: { &mfs_vnodeop_p, mfs_vnodeop_entries }; ! 132: ! 133: /* ! 134: * Vnode Operations. ! 135: * ! 136: * Open called to allow memory filesystem to initialize and ! 137: * validate before actual IO. Record our process identifier ! 138: * so we can tell when we are doing I/O to ourself. ! 139: */ ! 140: /* ARGSUSED */ ! 141: int ! 142: mfs_open(ap) ! 143: struct vop_open_args /* { ! 144: struct vnode *a_vp; ! 145: int a_mode; ! 146: struct ucred *a_cred; ! 147: struct proc *a_p; ! 148: } */ *ap; ! 149: { ! 150: ! 151: if (ap->a_vp->v_type != VBLK) { ! 152: panic("mfs_ioctl not VBLK"); ! 153: /* NOTREACHED */ ! 154: } ! 155: return (0); ! 156: } ! 157: ! 158: /* ! 159: * Ioctl operation. ! 160: */ ! 161: /* ARGSUSED */ ! 162: int ! 163: mfs_ioctl(ap) ! 164: struct vop_ioctl_args /* { ! 165: struct vnode *a_vp; ! 166: u_long a_command; ! 167: caddr_t a_data; ! 168: int a_fflag; ! 169: struct ucred *a_cred; ! 170: struct proc *a_p; ! 171: } */ *ap; ! 172: { ! 173: ! 174: return (ENOTTY); ! 175: } ! 176: ! 177: /* ! 178: * Pass I/O requests to the memory filesystem process. ! 179: */ ! 180: int ! 181: mfs_strategy(ap) ! 182: struct vop_strategy_args /* { ! 183: struct buf *a_bp; ! 184: } */ *ap; ! 185: { ! 186: register struct buf *bp = ap->a_bp; ! 187: register struct mfsnode *mfsp; ! 188: struct vnode *vp; ! 189: struct proc *p = curproc; /* XXX */ ! 190: ! 191: if (!vfinddev(bp->b_dev, VBLK, &vp) || vp->v_usecount == 0) ! 192: panic("mfs_strategy: bad dev"); ! 193: mfsp = VTOMFS(vp); ! 194: /* check for mini-root access */ ! 195: if (mfsp->mfs_pid == 0) { ! 196: caddr_t base; ! 197: ! 198: base = mfsp->mfs_baseoff + (bp->b_blkno << DEV_BSHIFT); ! 199: if (bp->b_flags & B_READ) ! 200: bcopy(base, bp->b_data, bp->b_bcount); ! 201: else ! 202: bcopy(bp->b_data, base, bp->b_bcount); ! 203: biodone(bp); ! 204: } else if (mfsp->mfs_pid == p->p_pid) { ! 205: mfs_doio(bp, mfsp->mfs_baseoff); ! 206: } else { ! 207: bp->b_actf = mfsp->mfs_buflist; ! 208: mfsp->mfs_buflist = bp; ! 209: wakeup((caddr_t)vp); ! 210: } ! 211: return (0); ! 212: } ! 213: ! 214: /* ! 215: * Memory file system I/O. ! 216: * ! 217: * Trivial on the HP since buffer has already been mapping into KVA space. ! 218: */ ! 219: void ! 220: mfs_doio(bp, base) ! 221: register struct buf *bp; ! 222: caddr_t base; ! 223: { ! 224: ! 225: base += (bp->b_blkno << DEV_BSHIFT); ! 226: if (bp->b_flags & B_READ) ! 227: bp->b_error = copyin(base, bp->b_data, bp->b_bcount); ! 228: else ! 229: bp->b_error = copyout(bp->b_data, base, bp->b_bcount); ! 230: if (bp->b_error) ! 231: bp->b_flags |= B_ERROR; ! 232: biodone(bp); ! 233: } ! 234: ! 235: /* ! 236: * This is a noop, simply returning what one has been given. ! 237: */ ! 238: int ! 239: mfs_bmap(ap) ! 240: struct vop_bmap_args /* { ! 241: struct vnode *a_vp; ! 242: daddr_t a_bn; ! 243: struct vnode **a_vpp; ! 244: daddr_t *a_bnp; ! 245: int *a_runp; ! 246: } */ *ap; ! 247: { ! 248: ! 249: if (ap->a_vpp != NULL) ! 250: *ap->a_vpp = ap->a_vp; ! 251: if (ap->a_bnp != NULL) ! 252: *ap->a_bnp = ap->a_bn; ! 253: return (0); ! 254: } ! 255: ! 256: /* ! 257: * Memory filesystem close routine ! 258: */ ! 259: /* ARGSUSED */ ! 260: int ! 261: mfs_close(ap) ! 262: struct vop_close_args /* { ! 263: struct vnode *a_vp; ! 264: int a_fflag; ! 265: struct ucred *a_cred; ! 266: struct proc *a_p; ! 267: } */ *ap; ! 268: { ! 269: register struct vnode *vp = ap->a_vp; ! 270: register struct mfsnode *mfsp = VTOMFS(vp); ! 271: register struct buf *bp; ! 272: int error; ! 273: ! 274: /* ! 275: * Finish any pending I/O requests. ! 276: */ ! 277: while (bp = mfsp->mfs_buflist) { ! 278: mfsp->mfs_buflist = bp->b_actf; ! 279: mfs_doio(bp, mfsp->mfs_baseoff); ! 280: wakeup((caddr_t)bp); ! 281: } ! 282: /* ! 283: * On last close of a memory filesystem ! 284: * we must invalidate any in core blocks, so that ! 285: * we can, free up its vnode. ! 286: */ ! 287: if (error = vinvalbuf(vp, 1, ap->a_cred, ap->a_p, 0, 0)) ! 288: return (error); ! 289: /* ! 290: * There should be no way to have any more uses of this ! 291: * vnode, so if we find any other uses, it is a panic. ! 292: */ ! 293: if (vp->v_usecount > 1) ! 294: printf("mfs_close: ref count %d > 1\n", vp->v_usecount); ! 295: if (vp->v_usecount > 1 || mfsp->mfs_buflist) ! 296: panic("mfs_close"); ! 297: /* ! 298: * Send a request to the filesystem server to exit. ! 299: */ ! 300: mfsp->mfs_buflist = (struct buf *)(-1); ! 301: wakeup((caddr_t)vp); ! 302: return (0); ! 303: } ! 304: ! 305: /* ! 306: * Memory filesystem inactive routine ! 307: */ ! 308: /* ARGSUSED */ ! 309: int ! 310: mfs_inactive(ap) ! 311: struct vop_inactive_args /* { ! 312: struct vnode *a_vp; ! 313: } */ *ap; ! 314: { ! 315: register struct mfsnode *mfsp = VTOMFS(ap->a_vp); ! 316: ! 317: if (mfsp->mfs_buflist && mfsp->mfs_buflist != (struct buf *)(-1)) ! 318: panic("mfs_inactive: not inactive (mfs_buflist %x)", ! 319: mfsp->mfs_buflist); ! 320: return (0); ! 321: } ! 322: ! 323: /* ! 324: * Reclaim a memory filesystem devvp so that it can be reused. ! 325: */ ! 326: int ! 327: mfs_reclaim(ap) ! 328: struct vop_reclaim_args /* { ! 329: struct vnode *a_vp; ! 330: } */ *ap; ! 331: { ! 332: register struct vnode *vp = ap->a_vp; ! 333: ! 334: FREE(vp->v_data, M_MFSNODE); ! 335: vp->v_data = NULL; ! 336: return (0); ! 337: } ! 338: ! 339: /* ! 340: * Print out the contents of an mfsnode. ! 341: */ ! 342: int ! 343: mfs_print(ap) ! 344: struct vop_print_args /* { ! 345: struct vnode *a_vp; ! 346: } */ *ap; ! 347: { ! 348: register struct mfsnode *mfsp = VTOMFS(ap->a_vp); ! 349: ! 350: printf("tag VT_MFS, pid %d, base %d, size %d\n", mfsp->mfs_pid, ! 351: mfsp->mfs_baseoff, mfsp->mfs_size); ! 352: return (0); ! 353: } ! 354: ! 355: /* ! 356: * Block device bad operation ! 357: */ ! 358: int ! 359: mfs_badop() ! 360: { ! 361: ! 362: panic("mfs_badop called\n"); ! 363: /* NOTREACHED */ ! 364: } ! 365: ! 366: /* ! 367: * Memory based filesystem initialization. ! 368: */ ! 369: mfs_init() ! 370: { ! 371: ! 372: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.