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