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