|
|
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) 1992, 1993, 1995 ! 28: * The Regents of the University of California. All rights reserved. ! 29: * ! 30: * This code is derived from software donated to Berkeley by ! 31: * Jan-Simon Pendry. ! 32: * ! 33: * Redistribution and use in source and binary forms, with or without ! 34: * modification, are permitted provided that the following conditions ! 35: * are met: ! 36: * 1. Redistributions of source code must retain the above copyright ! 37: * notice, this list of conditions and the following disclaimer. ! 38: * 2. Redistributions in binary form must reproduce the above copyright ! 39: * notice, this list of conditions and the following disclaimer in the ! 40: * documentation and/or other materials provided with the distribution. ! 41: * 3. All advertising materials mentioning features or use of this software ! 42: * must display the following acknowledgement: ! 43: * This product includes software developed by the University of ! 44: * California, Berkeley and its contributors. ! 45: * 4. Neither the name of the University nor the names of its contributors ! 46: * may be used to endorse or promote products derived from this software ! 47: * without specific prior written permission. ! 48: * ! 49: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ! 50: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! 51: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ! 52: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ! 53: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ! 54: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ! 55: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 56: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ! 57: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ! 58: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ! 59: * SUCH DAMAGE. ! 60: * ! 61: * @(#)null_vfsops.c 8.7 (Berkeley) 5/14/95 ! 62: * ! 63: * @(#)lofs_vfsops.c 1.2 (Berkeley) 6/18/92 ! 64: */ ! 65: ! 66: /* ! 67: * Null Layer ! 68: * (See null_vnops.c for a description of what this does.) ! 69: */ ! 70: ! 71: #include <sys/param.h> ! 72: #include <sys/systm.h> ! 73: #include <sys/proc.h> ! 74: #include <sys/time.h> ! 75: #include <sys/types.h> ! 76: #include <sys/vnode.h> ! 77: #include <sys/mount.h> ! 78: #include <sys/namei.h> ! 79: #include <sys/malloc.h> ! 80: #include <miscfs/nullfs/null.h> ! 81: ! 82: /* ! 83: * Mount null layer ! 84: */ ! 85: int ! 86: nullfs_mount(mp, path, data, ndp, p) ! 87: struct mount *mp; ! 88: char *path; ! 89: caddr_t data; ! 90: struct nameidata *ndp; ! 91: struct proc *p; ! 92: { ! 93: int error = 0; ! 94: struct null_args args; ! 95: struct vnode *lowerrootvp, *vp; ! 96: struct vnode *nullm_rootvp; ! 97: struct null_mount *xmp; ! 98: u_int size; ! 99: ! 100: #ifdef NULLFS_DIAGNOSTIC ! 101: printf("nullfs_mount(mp = %x)\n", mp); ! 102: #endif ! 103: ! 104: /* ! 105: * Update is a no-op ! 106: */ ! 107: if (mp->mnt_flag & MNT_UPDATE) { ! 108: return (EOPNOTSUPP); ! 109: /* return VFS_MOUNT(MOUNTTONULLMOUNT(mp)->nullm_vfs, path, data, ndp, p);*/ ! 110: } ! 111: ! 112: /* ! 113: * Get argument ! 114: */ ! 115: if (error = copyin(data, (caddr_t)&args, sizeof(struct null_args))) ! 116: return (error); ! 117: ! 118: /* ! 119: * Find lower node ! 120: */ ! 121: NDINIT(ndp, LOOKUP, FOLLOW|WANTPARENT|LOCKLEAF, ! 122: UIO_USERSPACE, args.target, p); ! 123: if (error = namei(ndp)) ! 124: return (error); ! 125: ! 126: /* ! 127: * Sanity check on lower vnode ! 128: */ ! 129: lowerrootvp = ndp->ni_vp; ! 130: ! 131: vrele(ndp->ni_dvp); ! 132: ndp->ni_dvp = NULL; ! 133: ! 134: xmp = (struct null_mount *) malloc(sizeof(struct null_mount), ! 135: M_UFSMNT, M_WAITOK); /* XXX */ ! 136: ! 137: /* ! 138: * Save reference to underlying FS ! 139: */ ! 140: xmp->nullm_vfs = lowerrootvp->v_mount; ! 141: ! 142: /* ! 143: * Save reference. Each mount also holds ! 144: * a reference on the root vnode. ! 145: */ ! 146: error = null_node_create(mp, lowerrootvp, &vp); ! 147: /* ! 148: * Unlock the node (either the lower or the alias) ! 149: */ ! 150: VOP_UNLOCK(vp, 0, p); ! 151: /* ! 152: * Make sure the node alias worked ! 153: */ ! 154: if (error) { ! 155: vrele(lowerrootvp); ! 156: free(xmp, M_UFSMNT); /* XXX */ ! 157: return (error); ! 158: } ! 159: ! 160: /* ! 161: * Keep a held reference to the root vnode. ! 162: * It is vrele'd in nullfs_unmount. ! 163: */ ! 164: nullm_rootvp = vp; ! 165: nullm_rootvp->v_flag |= VROOT; ! 166: xmp->nullm_rootvp = nullm_rootvp; ! 167: if (NULLVPTOLOWERVP(nullm_rootvp)->v_mount->mnt_flag & MNT_LOCAL) ! 168: mp->mnt_flag |= MNT_LOCAL; ! 169: mp->mnt_data = (qaddr_t) xmp; ! 170: vfs_getnewfsid(mp); ! 171: ! 172: (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); ! 173: bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); ! 174: (void) copyinstr(args.target, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, ! 175: &size); ! 176: bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); ! 177: #ifdef NULLFS_DIAGNOSTIC ! 178: printf("nullfs_mount: lower %s, alias at %s\n", ! 179: mp->mnt_stat.f_mntfromname, mp->mnt_stat.f_mntonname); ! 180: #endif ! 181: return (0); ! 182: } ! 183: ! 184: /* ! 185: * VFS start. Nothing needed here - the start routine ! 186: * on the underlying filesystem will have been called ! 187: * when that filesystem was mounted. ! 188: */ ! 189: int ! 190: nullfs_start(mp, flags, p) ! 191: struct mount *mp; ! 192: int flags; ! 193: struct proc *p; ! 194: { ! 195: return (0); ! 196: /* return VFS_START(MOUNTTONULLMOUNT(mp)->nullm_vfs, flags, p); */ ! 197: } ! 198: ! 199: /* ! 200: * Free reference to null layer ! 201: */ ! 202: int ! 203: nullfs_unmount(mp, mntflags, p) ! 204: struct mount *mp; ! 205: int mntflags; ! 206: struct proc *p; ! 207: { ! 208: struct vnode *nullm_rootvp = MOUNTTONULLMOUNT(mp)->nullm_rootvp; ! 209: int error; ! 210: int flags = 0; ! 211: ! 212: #ifdef NULLFS_DIAGNOSTIC ! 213: printf("nullfs_unmount(mp = %x)\n", mp); ! 214: #endif ! 215: ! 216: if (mntflags & MNT_FORCE) ! 217: flags |= FORCECLOSE; ! 218: ! 219: /* ! 220: * Clear out buffer cache. I don't think we ! 221: * ever get anything cached at this level at the ! 222: * moment, but who knows... ! 223: */ ! 224: #if 0 ! 225: mntflushbuf(mp, 0); ! 226: if (mntinvalbuf(mp, 1)) ! 227: return (EBUSY); ! 228: #endif ! 229: if (nullm_rootvp->v_usecount > 1) ! 230: return (EBUSY); ! 231: if (error = vflush(mp, nullm_rootvp, flags)) ! 232: return (error); ! 233: ! 234: #ifdef NULLFS_DIAGNOSTIC ! 235: vprint("alias root of lower", nullm_rootvp); ! 236: #endif ! 237: /* ! 238: * Release reference on underlying root vnode ! 239: */ ! 240: vrele(nullm_rootvp); ! 241: /* ! 242: * And blow it away for future re-use ! 243: */ ! 244: vgone(nullm_rootvp); ! 245: /* ! 246: * Finally, throw away the null_mount structure ! 247: */ ! 248: free(mp->mnt_data, M_UFSMNT); /* XXX */ ! 249: mp->mnt_data = 0; ! 250: return 0; ! 251: } ! 252: ! 253: int ! 254: nullfs_root(mp, vpp) ! 255: struct mount *mp; ! 256: struct vnode **vpp; ! 257: { ! 258: struct proc *p = curproc; /* XXX */ ! 259: struct vnode *vp; ! 260: ! 261: #ifdef NULLFS_DIAGNOSTIC ! 262: printf("nullfs_root(mp = %x, vp = %x->%x)\n", mp, ! 263: MOUNTTONULLMOUNT(mp)->nullm_rootvp, ! 264: NULLVPTOLOWERVP(MOUNTTONULLMOUNT(mp)->nullm_rootvp) ! 265: ); ! 266: #endif ! 267: ! 268: /* ! 269: * Return locked reference to root. ! 270: */ ! 271: vp = MOUNTTONULLMOUNT(mp)->nullm_rootvp; ! 272: VREF(vp); ! 273: vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); ! 274: *vpp = vp; ! 275: return 0; ! 276: } ! 277: ! 278: int ! 279: nullfs_quotactl(mp, cmd, uid, arg, p) ! 280: struct mount *mp; ! 281: int cmd; ! 282: uid_t uid; ! 283: caddr_t arg; ! 284: struct proc *p; ! 285: { ! 286: return VFS_QUOTACTL(MOUNTTONULLMOUNT(mp)->nullm_vfs, cmd, uid, arg, p); ! 287: } ! 288: ! 289: int ! 290: nullfs_statfs(mp, sbp, p) ! 291: struct mount *mp; ! 292: struct statfs *sbp; ! 293: struct proc *p; ! 294: { ! 295: int error; ! 296: struct statfs mstat; ! 297: ! 298: #ifdef NULLFS_DIAGNOSTIC ! 299: printf("nullfs_statfs(mp = %x, vp = %x->%x)\n", mp, ! 300: MOUNTTONULLMOUNT(mp)->nullm_rootvp, ! 301: NULLVPTOLOWERVP(MOUNTTONULLMOUNT(mp)->nullm_rootvp) ! 302: ); ! 303: #endif ! 304: ! 305: bzero(&mstat, sizeof(mstat)); ! 306: ! 307: error = VFS_STATFS(MOUNTTONULLMOUNT(mp)->nullm_vfs, &mstat, p); ! 308: if (error) ! 309: return (error); ! 310: ! 311: /* now copy across the "interesting" information and fake the rest */ ! 312: sbp->f_type = mstat.f_type; ! 313: sbp->f_flags = mstat.f_flags; ! 314: sbp->f_bsize = mstat.f_bsize; ! 315: sbp->f_iosize = mstat.f_iosize; ! 316: sbp->f_blocks = mstat.f_blocks; ! 317: sbp->f_bfree = mstat.f_bfree; ! 318: sbp->f_bavail = mstat.f_bavail; ! 319: sbp->f_files = mstat.f_files; ! 320: sbp->f_ffree = mstat.f_ffree; ! 321: if (sbp != &mp->mnt_stat) { ! 322: bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); ! 323: bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); ! 324: bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); ! 325: } ! 326: return (0); ! 327: } ! 328: ! 329: int ! 330: nullfs_sync(mp, waitfor, cred, p) ! 331: struct mount *mp; ! 332: int waitfor; ! 333: struct ucred *cred; ! 334: struct proc *p; ! 335: { ! 336: /* ! 337: * XXX - Assumes no data cached at null layer. ! 338: */ ! 339: return (0); ! 340: } ! 341: ! 342: int ! 343: nullfs_vget(mp, ino, vpp) ! 344: struct mount *mp; ! 345: ino_t ino; ! 346: struct vnode **vpp; ! 347: { ! 348: ! 349: return VFS_VGET(MOUNTTONULLMOUNT(mp)->nullm_vfs, ino, vpp); ! 350: } ! 351: ! 352: int ! 353: nullfs_fhtovp(mp, fidp, nam, vpp, exflagsp, credanonp) ! 354: struct mount *mp; ! 355: struct fid *fidp; ! 356: struct mbuf *nam; ! 357: struct vnode **vpp; ! 358: int *exflagsp; ! 359: struct ucred**credanonp; ! 360: { ! 361: ! 362: return VFS_FHTOVP(MOUNTTONULLMOUNT(mp)->nullm_vfs, fidp, nam, vpp, exflagsp,credanonp); ! 363: } ! 364: ! 365: int ! 366: nullfs_vptofh(vp, fhp) ! 367: struct vnode *vp; ! 368: struct fid *fhp; ! 369: { ! 370: return VFS_VPTOFH(NULLVPTOLOWERVP(vp), fhp); ! 371: } ! 372: ! 373: int nullfs_init __P((struct vfsconf *)); ! 374: ! 375: #define nullfs_sysctl ((int (*) __P((int *, u_int, void *, size_t *, void *, \ ! 376: size_t, struct proc *)))eopnotsupp) ! 377: ! 378: struct vfsops null_vfsops = { ! 379: nullfs_mount, ! 380: nullfs_start, ! 381: nullfs_unmount, ! 382: nullfs_root, ! 383: nullfs_quotactl, ! 384: nullfs_statfs, ! 385: nullfs_sync, ! 386: nullfs_vget, ! 387: nullfs_fhtovp, ! 388: nullfs_vptofh, ! 389: nullfs_init, ! 390: nullfs_sysctl, ! 391: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.