|
|
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.