4.4BSD snapshot (revision 8.1); add 1993 to copyright
[unix-history] / usr / src / sys / deprecated / lofs / lofs_vfsops.c
CommitLineData
6764856a 1/*
99315dca
KB
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
6764856a
JSP
4 * All rights reserved.
5 *
6 * This code is derived from software donated to Berkeley by
7 * Jan-Simon Pendry.
8 *
9 * %sccs.include.redist.c%
10 *
99315dca 11 * @(#)lofs_vfsops.c 8.1 (Berkeley) %G%
6764856a
JSP
12 *
13 * $Id: lofs_vfsops.c,v 1.9 1992/05/30 10:26:24 jsp Exp jsp $
14 */
15
16/*
17 * Loopback Filesystem
18 */
19
20#include <sys/param.h>
21#include <sys/systm.h>
22#include <sys/time.h>
23#include <sys/types.h>
24#include <sys/vnode.h>
25#include <sys/mount.h>
26#include <sys/namei.h>
27#include <sys/malloc.h>
6681df29 28#include <miscfs/lofs/lofs.h>
6764856a
JSP
29
30/*
31 * Mount loopback copy of existing name space
32 */
33lofs_mount(mp, path, data, ndp, p)
34 struct mount *mp;
35 char *path;
36 caddr_t data;
37 struct nameidata *ndp;
38 struct proc *p;
39{
6764856a
JSP
40 int error = 0;
41 struct lofs_args args;
42 struct vnode *vp;
43 struct vnode *rootvp;
44 struct lofsmount *amp;
45 u_int size;
46
47#ifdef LOFS_DIAGNOSTIC
48 printf("lofs_mount(mp = %x)\n", mp);
49#endif
50
51 /*
52 * Update is a no-op
53 */
54 if (mp->mnt_flag & MNT_UPDATE) {
55 return (EOPNOTSUPP);
56 /* return VFS_MOUNT(VFSTOLOFS(mp)->looped_vfs, path, data, ndp, p);*/
57 }
58
59 /*
60 * Get argument
61 */
62 if (error = copyin(data, (caddr_t)&args, sizeof(struct lofs_args)))
63 return (error);
64
65 /*
66 * Find target node
67 */
68 NDINIT(ndp, LOOKUP, FOLLOW|WANTPARENT|LOCKLEAF,
69 UIO_USERSPACE, args.target, p);
70 if (error = namei(ndp))
71 return (error);
72
73 /*
74 * Sanity check on target vnode
75 */
76 vp = ndp->ni_vp;
77#ifdef LOFS_DIAGNOSTIC
78 printf("vp = %x, check for VDIR...\n", vp);
79#endif
80 vrele(ndp->ni_dvp);
81 ndp->ni_dvp = 0;
82
83 if (vp->v_type != VDIR) {
84 vput(vp);
85 return (EINVAL);
86 }
87
88#ifdef LOFS_DIAGNOSTIC
89 printf("mp = %x\n", mp);
90#endif
91
92 amp = (struct lofsmount *) malloc(sizeof(struct lofsmount),
93 M_UFSMNT, M_WAITOK); /* XXX */
94
95 /*
96 * Save reference to underlying target FS
97 */
98 amp->looped_vfs = vp->v_mount;
99
100 /*
101 * Save reference. Each mount also holds
102 * a reference on the root vnode.
103 */
104 error = make_lofs(mp, &vp);
105 /*
106 * Unlock the node (either the target or the alias)
107 */
108 VOP_UNLOCK(vp);
109 /*
110 * Make sure the node alias worked
111 */
112 if (error) {
113 vrele(vp);
114 free(amp, M_UFSMNT); /* XXX */
115 return (error);
116 }
117
118 /*
119 * Keep a held reference to the root vnode.
120 * It is vrele'd in lofs_unmount.
121 */
122 rootvp = vp;
123 rootvp->v_flag |= VROOT;
124 amp->rootvp = rootvp;
125 if (LOFSVP(rootvp)->v_mount->mnt_flag & MNT_LOCAL)
126 mp->mnt_flag |= MNT_LOCAL;
127 mp->mnt_data = (qaddr_t) amp;
128 getnewfsid(mp, MOUNT_LOFS);
129
130 (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
131 bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
132 (void) copyinstr(args.target, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
133 &size);
134 bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
135#ifdef LOFS_DIAGNOSTIC
136 printf("lofs_mount: target %s, alias at %s\n",
137 mp->mnt_stat.f_mntfromname, mp->mnt_stat.f_mntonname);
138#endif
139 return (0);
140}
141
142/*
143 * VFS start. Nothing needed here - the start routine
144 * on the underlying filesystem will have been called
145 * when that filesystem was mounted.
146 */
147lofs_start(mp, flags, p)
148 struct mount *mp;
149 int flags;
150 struct proc *p;
151{
152 return (0);
153 /* return VFS_START(VFSTOLOFS(mp)->looped_vfs, flags, p); */
154}
155
156/*
157 * Free reference to looped FS
158 */
159lofs_unmount(mp, mntflags, p)
160 struct mount *mp;
161 int mntflags;
162 struct proc *p;
163{
164 struct vnode *rootvp = VFSTOLOFS(mp)->rootvp;
165 int error;
166 int flags = 0;
167 extern int doforce;
168
169#ifdef LOFS_DIAGNOSTIC
170 printf("lofs_unmount(mp = %x)\n", mp);
171#endif
172
173 if (mntflags & MNT_FORCE) {
174 /* lofs can never be rootfs so don't check for it */
175 if (!doforce)
176 return (EINVAL);
177 flags |= FORCECLOSE;
178 }
179
180 /*
181 * Clear out buffer cache. I don't think we
182 * ever get anything cached at this level at the
183 * moment, but who knows...
184 */
6764856a
JSP
185 if (rootvp->v_usecount > 1)
186 return (EBUSY);
187 if (error = vflush(mp, rootvp, flags))
188 return (error);
189
190#ifdef LOFS_DIAGNOSTIC
191 /*
192 * Flush any remaining vnode references
193 */
194 lofs_flushmp(mp);
195#endif
196
197#ifdef LOFS_DIAGNOSTIC
198 vprint("alias root of target", rootvp);
199#endif
200 /*
201 * Release reference on underlying root vnode
202 */
203 vrele(rootvp);
204 /*
205 * And blow it away for future re-use
206 */
207 vgone(rootvp);
208 /*
209 * Finally, throw away the lofsmount structure
210 */
211 free(mp->mnt_data, M_UFSMNT); /* XXX */
212 mp->mnt_data = 0;
213 return 0;
214}
215
216lofs_root(mp, vpp)
217 struct mount *mp;
218 struct vnode **vpp;
219{
6764856a
JSP
220 struct vnode *vp;
221
222#ifdef LOFS_DIAGNOSTIC
223 printf("lofs_root(mp = %x, vp = %x->%x)\n", mp,
224 VFSTOLOFS(mp)->rootvp,
225 LOFSVP(VFSTOLOFS(mp)->rootvp)
226 );
227#endif
228
229 /*
230 * Return locked reference to root.
231 */
232 vp = VFSTOLOFS(mp)->rootvp;
233 VREF(vp);
234 VOP_LOCK(vp);
235 *vpp = vp;
236 return 0;
237}
238
239lofs_quotactl(mp, cmd, uid, arg, p)
240 struct mount *mp;
241 int cmd;
242 uid_t uid;
243 caddr_t arg;
244 struct proc *p;
245{
246 return VFS_QUOTACTL(VFSTOLOFS(mp)->looped_vfs, cmd, uid, arg, p);
247}
248
249lofs_statfs(mp, sbp, p)
250 struct mount *mp;
251 struct statfs *sbp;
252 struct proc *p;
253{
254 int error;
255 struct statfs mstat;
256
257#ifdef LOFS_DIAGNOSTIC
258 printf("lofs_statfs(mp = %x, vp = %x->%x)\n", mp,
259 VFSTOLOFS(mp)->rootvp,
260 LOFSVP(VFSTOLOFS(mp)->rootvp)
261 );
262#endif
263
264 bzero(&mstat, sizeof(mstat));
265
266 error = VFS_STATFS(VFSTOLOFS(mp)->looped_vfs, &mstat, p);
267 if (error)
268 return (error);
269
270 /* now copy across the "interesting" information and fake the rest */
271 sbp->f_type = mstat.f_type;
272 sbp->f_flags = mstat.f_flags;
273 sbp->f_bsize = mstat.f_bsize;
274 sbp->f_iosize = mstat.f_iosize;
275 sbp->f_blocks = mstat.f_blocks;
276 sbp->f_bfree = mstat.f_bfree;
277 sbp->f_bavail = mstat.f_bavail;
278 sbp->f_files = mstat.f_files;
279 sbp->f_ffree = mstat.f_ffree;
280 if (sbp != &mp->mnt_stat) {
281 bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid));
282 bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
283 bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
284 }
285 return (0);
286}
287
288lofs_sync(mp, waitfor)
289struct mount *mp;
290int waitfor;
291{
279e0ea4 292 return (0);
6764856a
JSP
293}
294
e28b0770
JSP
295/*
296 * LOFS flat namespace lookup.
297 * Currently unsupported.
298 */
299lofs_vget(mp, ino, vpp)
6764856a 300 struct mount *mp;
e28b0770
JSP
301 ino_t ino;
302 struct vnode **vpp;
303{
304
305 return (EOPNOTSUPP);
306}
307
308lofs_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp)
309 register struct mount *mp;
6764856a 310 struct fid *fhp;
e28b0770 311 struct mbuf *nam;
6764856a 312 struct vnode **vpp;
e28b0770
JSP
313 int *exflagsp;
314 struct ucred **credanonp;
6764856a 315{
e28b0770 316 return VFS_FHTOVP(VFSTOLOFS(mp)->looped_vfs, fhp, nam, vpp, exflagsp, credanonp);
6764856a
JSP
317}
318
319lofs_vptofh(vp, fhp)
320 struct vnode *vp;
321 struct fid *fhp;
322{
323 return VFS_VPTOFH(LOFSVP(vp), fhp);
324}
325
326int lofs_init __P((void));
327
328struct vfsops lofs_vfsops = {
329 lofs_mount,
330 lofs_start,
331 lofs_unmount,
332 lofs_root,
333 lofs_quotactl,
334 lofs_statfs,
335 lofs_sync,
e28b0770 336 lofs_vget,
6764856a
JSP
337 lofs_fhtovp,
338 lofs_vptofh,
339 lofs_init,
340};