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