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