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