Commit | Line | Data |
---|---|---|
c153d43e | 1 | /* |
99315dca KB |
2 | * Copyright (c) 1992, 1993 |
3 | * The Regents of the University of California. All rights reserved. | |
c153d43e 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 | * | |
05c39890 | 11 | * @(#)lofs_vnops.c 8.2 (Berkeley) %G% |
c153d43e JSP |
12 | * |
13 | * $Id: lofs_vnops.c,v 1.11 1992/05/30 10:05:43 jsp Exp jsp $ | |
14 | */ | |
15 | ||
16 | /* | |
17 | * Loopback Filesystem | |
18 | */ | |
19 | ||
20 | #include <sys/param.h> | |
21 | #include <sys/systm.h> | |
22 | #include <sys/proc.h> | |
23 | #include <sys/time.h> | |
24 | #include <sys/types.h> | |
25 | #include <sys/vnode.h> | |
26 | #include <sys/mount.h> | |
27 | #include <sys/namei.h> | |
28 | #include <sys/malloc.h> | |
29 | #include <sys/buf.h> | |
6681df29 | 30 | #include <miscfs/lofs/lofs.h> |
c153d43e JSP |
31 | |
32 | /* | |
33 | * Basic strategy: as usual, do as little work as possible. | |
34 | * Nothing is ever locked in the lofs'ed filesystem, all | |
35 | * locks are held in the underlying filesystems. | |
36 | */ | |
37 | ||
38 | /* | |
39 | * Save a vnode and replace with | |
40 | * the lofs'ed one | |
41 | */ | |
42 | #define PUSHREF(v, nd) \ | |
43 | { \ | |
44 | struct { struct vnode *vnp; } v; \ | |
45 | v.vnp = (nd); \ | |
46 | (nd) = LOFSVP(v.vnp) | |
47 | ||
48 | /* | |
49 | * Undo the PUSHREF | |
50 | */ | |
51 | #define POP(v, nd) \ | |
52 | \ | |
53 | (nd) = v.vnp; \ | |
54 | } | |
55 | ||
c153d43e JSP |
56 | /* |
57 | * vp is the current namei directory | |
58 | * ndp is the name to locate in that directory... | |
59 | */ | |
05c39890 | 60 | int |
6681df29 KM |
61 | lofs_lookup(ap) |
62 | struct vop_lookup_args /* { | |
63 | struct vnode * a_dvp; | |
64 | struct vnode ** a_vpp; | |
65 | struct componentname * a_cnp; | |
66 | } */ *ap; | |
c153d43e | 67 | { |
50e716ac | 68 | struct vnode *dvp = ap->a_dvp; |
c153d43e JSP |
69 | struct vnode *newvp; |
70 | struct vnode *targetdvp; | |
71 | int error; | |
72 | int flag = ap->a_cnp->cn_nameiop /*& OPMASK*/; | |
73 | ||
c153d43e JSP |
74 | /* |
75 | * (ap->a_dvp) was locked when passed in, and it will be replaced | |
76 | * with the target vnode, BUT that will already have been | |
77 | * locked when (ap->a_dvp) was locked [see lofs_lock]. all that | |
78 | * must be done here is to keep track of reference counts. | |
79 | */ | |
50e716ac JSP |
80 | targetdvp = LOFSVP(dvp); |
81 | /*VREF(targetdvp);*/ | |
c153d43e JSP |
82 | |
83 | /* | |
84 | * Call lookup on the looped vnode | |
85 | */ | |
50e716ac JSP |
86 | error = VOP_LOOKUP(targetdvp, &newvp, ap->a_cnp); |
87 | /*vrele(targetdvp);*/ | |
c153d43e JSP |
88 | |
89 | if (error) { | |
90 | *ap->a_vpp = NULLVP; | |
c153d43e JSP |
91 | return (error); |
92 | } | |
c153d43e | 93 | |
50e716ac | 94 | *ap->a_vpp = newvp; |
c153d43e JSP |
95 | |
96 | /* | |
97 | * If we just found a directory then make | |
98 | * a loopback node for it and return the loopback | |
99 | * instead of the real vnode. Otherwise simply | |
100 | * return the aliased directory and vnode. | |
101 | */ | |
102 | if (newvp && newvp->v_type == VDIR && flag == LOOKUP) { | |
c153d43e JSP |
103 | /* |
104 | * At this point, newvp is the vnode to be looped. | |
105 | * Activate a loopback and return the looped vnode. | |
106 | */ | |
50e716ac | 107 | return (make_lofs(dvp->v_mount, ap->a_vpp)); |
c153d43e JSP |
108 | } |
109 | ||
c153d43e JSP |
110 | return (0); |
111 | } | |
112 | ||
113 | /* | |
114 | * this = ni_dvp | |
115 | * ni_dvp references the locked directory. | |
116 | * ni_vp is NULL. | |
117 | */ | |
05c39890 | 118 | int |
6681df29 KM |
119 | lofs_mknod(ap) |
120 | struct vop_mknod_args /* { | |
121 | struct vnode *a_dvp; | |
122 | struct vnode **a_vpp; | |
123 | struct componentname *a_cnp; | |
124 | struct vattr *a_vap; | |
125 | } */ *ap; | |
c153d43e | 126 | { |
c153d43e JSP |
127 | int error; |
128 | ||
c153d43e JSP |
129 | PUSHREF(xdvp, ap->a_dvp); |
130 | VREF(ap->a_dvp); | |
131 | ||
132 | error = VOP_MKNOD(ap->a_dvp, ap->a_vpp, ap->a_cnp, ap->a_vap); | |
133 | ||
134 | POP(xdvp, ap->a_dvp); | |
135 | vrele(ap->a_dvp); | |
136 | ||
137 | return (error); | |
138 | } | |
139 | ||
140 | /* | |
141 | * this = ni_dvp; | |
142 | * ni_dvp references the locked directory | |
143 | * ni_vp is NULL. | |
144 | */ | |
05c39890 | 145 | int |
6681df29 KM |
146 | lofs_create(ap) |
147 | struct vop_create_args /* { | |
148 | struct vnode *a_dvp; | |
149 | struct vnode **a_vpp; | |
150 | struct componentname *a_cnp; | |
151 | struct vattr *a_vap; | |
152 | } */ *ap; | |
c153d43e | 153 | { |
c153d43e JSP |
154 | int error; |
155 | ||
c153d43e JSP |
156 | PUSHREF(xdvp, ap->a_dvp); |
157 | VREF(ap->a_dvp); | |
158 | ||
159 | error = VOP_CREATE(ap->a_dvp, ap->a_vpp, ap->a_cnp, ap->a_vap); | |
160 | ||
161 | POP(xdvp, ap->a_dvp); | |
162 | vrele(ap->a_dvp); | |
163 | ||
c153d43e JSP |
164 | return (error); |
165 | } | |
166 | ||
05c39890 | 167 | int |
6681df29 KM |
168 | lofs_open(ap) |
169 | struct vop_open_args /* { | |
170 | struct vnode *a_vp; | |
171 | int a_mode; | |
172 | struct ucred *a_cred; | |
173 | struct proc *a_p; | |
174 | } */ *ap; | |
c153d43e | 175 | { |
6681df29 | 176 | |
05c39890 | 177 | return (VOP_OPEN(LOFSVP(ap->a_vp), ap->a_mode, ap->a_cred, ap->a_p)); |
c153d43e JSP |
178 | } |
179 | ||
05c39890 | 180 | int |
6681df29 KM |
181 | lofs_close(ap) |
182 | struct vop_close_args /* { | |
183 | struct vnode *a_vp; | |
184 | int a_fflag; | |
185 | struct ucred *a_cred; | |
186 | struct proc *a_p; | |
187 | } */ *ap; | |
c153d43e | 188 | { |
6681df29 | 189 | |
05c39890 | 190 | return (VOP_CLOSE(LOFSVP(ap->a_vp), ap->a_fflag, ap->a_cred, ap->a_p)); |
c153d43e JSP |
191 | } |
192 | ||
05c39890 | 193 | int |
6681df29 KM |
194 | lofs_access(ap) |
195 | struct vop_access_args /* { | |
196 | struct vnode *a_vp; | |
197 | int a_mode; | |
198 | struct ucred *a_cred; | |
199 | struct proc *a_p; | |
200 | } */ *ap; | |
c153d43e | 201 | { |
6681df29 | 202 | |
05c39890 | 203 | return (VOP_ACCESS(LOFSVP(ap->a_vp), ap->a_mode, ap->a_cred, ap->a_p)); |
c153d43e JSP |
204 | } |
205 | ||
05c39890 | 206 | int |
6681df29 KM |
207 | lofs_getattr(ap) |
208 | struct vop_getattr_args /* { | |
209 | struct vnode *a_vp; | |
210 | struct vattr *a_vap; | |
211 | struct ucred *a_cred; | |
212 | struct proc *a_p; | |
213 | } */ *ap; | |
c153d43e | 214 | { |
c153d43e JSP |
215 | int error; |
216 | ||
c153d43e JSP |
217 | /* |
218 | * Get the stats from the underlying filesystem | |
219 | */ | |
220 | error = VOP_GETATTR(LOFSVP(ap->a_vp), ap->a_vap, ap->a_cred, ap->a_p); | |
221 | if (error) | |
222 | return (error); | |
223 | /* | |
224 | * and replace the fsid field with the loopback number | |
225 | * to preserve the namespace. | |
226 | */ | |
227 | ap->a_vap->va_fsid = ap->a_vp->v_mount->mnt_stat.f_fsid.val[0]; | |
228 | return (0); | |
229 | } | |
230 | ||
05c39890 | 231 | int |
6681df29 KM |
232 | lofs_setattr(ap) |
233 | struct vop_setattr_args /* { | |
234 | struct vnode *a_vp; | |
235 | struct vattr *a_vap; | |
236 | struct ucred *a_cred; | |
237 | struct proc *a_p; | |
238 | } */ *ap; | |
c153d43e | 239 | { |
6681df29 | 240 | |
05c39890 | 241 | return (VOP_SETATTR(LOFSVP(ap->a_vp), ap->a_vap, ap->a_cred, ap->a_p)); |
c153d43e JSP |
242 | } |
243 | ||
05c39890 | 244 | int |
6681df29 KM |
245 | lofs_read(ap) |
246 | struct vop_read_args /* { | |
247 | struct vnode *a_vp; | |
248 | struct uio *a_uio; | |
249 | int a_ioflag; | |
250 | struct ucred *a_cred; | |
251 | } */ *ap; | |
c153d43e | 252 | { |
6681df29 | 253 | |
05c39890 | 254 | return (VOP_READ(LOFSVP(ap->a_vp), ap->a_uio, ap->a_ioflag, ap->a_cred)); |
c153d43e JSP |
255 | } |
256 | ||
05c39890 | 257 | int |
6681df29 KM |
258 | lofs_write(ap) |
259 | struct vop_write_args /* { | |
260 | struct vnode *a_vp; | |
261 | struct uio *a_uio; | |
262 | int a_ioflag; | |
263 | struct ucred *a_cred; | |
264 | } */ *ap; | |
c153d43e | 265 | { |
6681df29 | 266 | |
05c39890 | 267 | return (VOP_WRITE(LOFSVP(ap->a_vp), ap->a_uio, ap->a_ioflag, ap->a_cred)); |
c153d43e JSP |
268 | } |
269 | ||
05c39890 | 270 | int |
6681df29 KM |
271 | lofs_ioctl(ap) |
272 | struct vop_ioctl_args /* { | |
273 | struct vnode *a_vp; | |
274 | int a_command; | |
275 | caddr_t a_data; | |
276 | int a_fflag; | |
277 | struct ucred *a_cred; | |
278 | struct proc *a_p; | |
279 | } */ *ap; | |
c153d43e | 280 | { |
6681df29 | 281 | |
05c39890 | 282 | return (VOP_IOCTL(LOFSVP(ap->a_vp), ap->a_command, ap->a_data, ap->a_fflag, ap->a_cred, ap->a_p)); |
c153d43e JSP |
283 | } |
284 | ||
05c39890 | 285 | int |
6681df29 KM |
286 | lofs_select(ap) |
287 | struct vop_select_args /* { | |
288 | struct vnode *a_vp; | |
289 | int a_which; | |
290 | int a_fflags; | |
291 | struct ucred *a_cred; | |
292 | struct proc *a_p; | |
293 | } */ *ap; | |
c153d43e | 294 | { |
6681df29 | 295 | |
05c39890 | 296 | return (VOP_SELECT(LOFSVP(ap->a_vp), ap->a_which, ap->a_fflags, ap->a_cred, ap->a_p)); |
c153d43e JSP |
297 | } |
298 | ||
05c39890 | 299 | int |
6681df29 KM |
300 | lofs_mmap(ap) |
301 | struct vop_mmap_args /* { | |
302 | struct vnode *a_vp; | |
303 | int a_fflags; | |
304 | struct ucred *a_cred; | |
305 | struct proc *a_p; | |
306 | } */ *ap; | |
c153d43e | 307 | { |
6681df29 | 308 | |
05c39890 | 309 | return (VOP_MMAP(LOFSVP(ap->a_vp), ap->a_fflags, ap->a_cred, ap->a_p)); |
c153d43e JSP |
310 | } |
311 | ||
05c39890 | 312 | int |
6681df29 KM |
313 | lofs_fsync(ap) |
314 | struct vop_fsync_args /* { | |
315 | struct vnode *a_vp; | |
316 | struct ucred *a_cred; | |
317 | int a_waitfor; | |
318 | struct proc *a_p; | |
319 | } */ *ap; | |
c153d43e | 320 | { |
37cd2672 | 321 | struct vnode *targetvp = LOFSVP(ap->a_vp); |
6681df29 | 322 | |
37cd2672 | 323 | if (targetvp) |
05c39890 | 324 | return (VOP_FSYNC(targetvp, ap->a_cred, ap->a_waitfor, ap->a_p)); |
37cd2672 | 325 | return (0); |
c153d43e JSP |
326 | } |
327 | ||
05c39890 | 328 | int |
6681df29 KM |
329 | lofs_seek(ap) |
330 | struct vop_seek_args /* { | |
331 | struct vnode *a_vp; | |
332 | off_t a_oldoff; | |
333 | off_t a_newoff; | |
334 | struct ucred *a_cred; | |
335 | } */ *ap; | |
c153d43e | 336 | { |
6681df29 | 337 | |
05c39890 | 338 | return (VOP_SEEK(LOFSVP(ap->a_vp), ap->a_oldoff, ap->a_newoff, ap->a_cred)); |
c153d43e JSP |
339 | } |
340 | ||
05c39890 | 341 | int |
6681df29 KM |
342 | lofs_remove(ap) |
343 | struct vop_remove_args /* { | |
344 | struct vnode *a_dvp; | |
345 | struct vnode *a_vp; | |
346 | struct componentname *a_cnp; | |
347 | } */ *ap; | |
c153d43e | 348 | { |
c153d43e JSP |
349 | int error; |
350 | ||
c153d43e JSP |
351 | PUSHREF(xdvp, ap->a_dvp); |
352 | VREF(ap->a_dvp); | |
353 | PUSHREF(xvp, ap->a_vp); | |
354 | VREF(ap->a_vp); | |
355 | ||
356 | error = VOP_REMOVE(ap->a_dvp, ap->a_vp, ap->a_cnp); | |
357 | ||
358 | POP(xvp, ap->a_vp); | |
359 | vrele(ap->a_vp); | |
360 | POP(xdvp, ap->a_dvp); | |
361 | vrele(ap->a_dvp); | |
362 | ||
363 | return (error); | |
364 | } | |
365 | ||
366 | /* | |
367 | * vp is this. | |
368 | * ni_dvp is the locked parent of the target. | |
369 | * ni_vp is NULL. | |
370 | */ | |
05c39890 | 371 | int |
6681df29 KM |
372 | lofs_link(ap) |
373 | struct vop_link_args /* { | |
374 | struct vnode *a_vp; | |
375 | struct vnode *a_tdvp; | |
376 | struct componentname *a_cnp; | |
377 | } */ *ap; | |
c153d43e | 378 | { |
c153d43e JSP |
379 | int error; |
380 | ||
c153d43e JSP |
381 | PUSHREF(xdvp, ap->a_vp); |
382 | VREF(ap->a_vp); | |
383 | ||
384 | error = VOP_LINK(ap->a_vp, LOFSVP(ap->a_tdvp), ap->a_cnp); | |
385 | ||
386 | POP(xdvp, ap->a_vp); | |
387 | vrele(ap->a_vp); | |
388 | ||
389 | return (error); | |
390 | } | |
391 | ||
05c39890 | 392 | int |
6681df29 KM |
393 | lofs_rename(ap) |
394 | struct vop_rename_args /* { | |
395 | struct vnode *a_fdvp; | |
396 | struct vnode *a_fvp; | |
397 | struct componentname *a_fcnp; | |
398 | struct vnode *a_tdvp; | |
399 | struct vnode *a_tvp; | |
400 | struct componentname *a_tcnp; | |
401 | } */ *ap; | |
c153d43e | 402 | { |
c153d43e JSP |
403 | struct vnode *fvp, *tvp; |
404 | struct vnode *tdvp; | |
6681df29 | 405 | #ifdef notdef |
c153d43e JSP |
406 | struct vnode *fsvp, *tsvp; |
407 | #endif | |
408 | int error; | |
409 | ||
c153d43e JSP |
410 | /* |
411 | * Switch source directory to point to lofsed vnode | |
412 | */ | |
413 | PUSHREF(fdvp, ap->a_fdvp); | |
414 | VREF(ap->a_fdvp); | |
415 | ||
c153d43e JSP |
416 | /* |
417 | * And source object if it is lofsed... | |
418 | */ | |
419 | fvp = ap->a_fvp; | |
420 | if (fvp && fvp->v_op == lofs_vnodeop_p) { | |
421 | ap->a_fvp = LOFSVP(fvp); | |
422 | VREF(ap->a_fvp); | |
423 | } else { | |
424 | fvp = 0; | |
425 | } | |
426 | ||
6681df29 | 427 | #ifdef notdef |
c153d43e JSP |
428 | /* |
429 | * And source startdir object if it is lofsed... | |
430 | */ | |
431 | fsvp = fndp->ni_startdir; | |
432 | if (fsvp && fsvp->v_op == lofs_vnodeop_p) { | |
433 | fndp->ni_startdir = LOFSVP(fsvp); | |
434 | VREF(fndp->ni_startdir); | |
435 | } else { | |
436 | fsvp = 0; | |
437 | } | |
438 | #endif | |
439 | ||
c153d43e JSP |
440 | /* |
441 | * Switch target directory to point to lofsed vnode | |
442 | */ | |
443 | tdvp = ap->a_tdvp; | |
444 | if (tdvp && tdvp->v_op == lofs_vnodeop_p) { | |
445 | ap->a_tdvp = LOFSVP(tdvp); | |
446 | VREF(ap->a_tdvp); | |
447 | } else { | |
448 | tdvp = 0; | |
449 | } | |
450 | ||
c153d43e JSP |
451 | /* |
452 | * And target object if it is lofsed... | |
453 | */ | |
454 | tvp = ap->a_tvp; | |
455 | if (tvp && tvp->v_op == lofs_vnodeop_p) { | |
456 | ap->a_tvp = LOFSVP(tvp); | |
457 | VREF(ap->a_tvp); | |
458 | } else { | |
459 | tvp = 0; | |
460 | } | |
461 | ||
6681df29 | 462 | #ifdef notdef |
c153d43e JSP |
463 | /* |
464 | * And target startdir object if it is lofsed... | |
465 | */ | |
466 | tsvp = tndp->ni_startdir; | |
467 | if (tsvp && tsvp->v_op == lofs_vnodeop_p) { | |
468 | tndp->ni_startdir = LOFSVP(fsvp); | |
469 | VREF(tndp->ni_startdir); | |
470 | } else { | |
471 | tsvp = 0; | |
472 | } | |
473 | #endif | |
474 | ||
c153d43e JSP |
475 | error = VOP_RENAME(ap->a_fdvp, ap->a_fvp, ap->a_fcnp, ap->a_tdvp, ap->a_tvp, ap->a_tcnp); |
476 | ||
477 | /* | |
478 | * Put everything back... | |
479 | */ | |
480 | ||
6681df29 | 481 | #ifdef notdef |
c153d43e JSP |
482 | |
483 | if (tsvp) { | |
484 | if (tndp->ni_startdir) | |
485 | vrele(tndp->ni_startdir); | |
486 | tndp->ni_startdir = tsvp; | |
487 | } | |
488 | #endif | |
489 | ||
c153d43e JSP |
490 | if (tvp) { |
491 | ap->a_tvp = tvp; | |
492 | vrele(ap->a_tvp); | |
493 | } | |
494 | ||
c153d43e JSP |
495 | if (tdvp) { |
496 | ap->a_tdvp = tdvp; | |
497 | vrele(ap->a_tdvp); | |
498 | } | |
499 | ||
6681df29 | 500 | #ifdef notdef |
c153d43e JSP |
501 | |
502 | if (fsvp) { | |
503 | if (fndp->ni_startdir) | |
504 | vrele(fndp->ni_startdir); | |
505 | fndp->ni_startdir = fsvp; | |
506 | } | |
507 | #endif | |
508 | ||
c153d43e JSP |
509 | if (fvp) { |
510 | ap->a_fvp = fvp; | |
511 | vrele(ap->a_fvp); | |
512 | } | |
513 | ||
c153d43e JSP |
514 | POP(fdvp, ap->a_fdvp); |
515 | vrele(ap->a_fdvp); | |
516 | ||
517 | return (error); | |
518 | } | |
519 | ||
520 | /* | |
521 | * ni_dvp is the locked (alias) parent. | |
522 | * ni_vp is NULL. | |
523 | */ | |
05c39890 | 524 | int |
6681df29 KM |
525 | lofs_mkdir(ap) |
526 | struct vop_mkdir_args /* { | |
527 | struct vnode *a_dvp; | |
528 | struct vnode **a_vpp; | |
529 | struct componentname *a_cnp; | |
530 | struct vattr *a_vap; | |
531 | } */ *ap; | |
c153d43e | 532 | { |
c153d43e | 533 | int error; |
50e716ac | 534 | struct vnode *dvp = ap->a_dvp; |
c153d43e | 535 | struct vnode *xdvp; |
50e716ac | 536 | struct vnode *newvp; |
c153d43e | 537 | |
50e716ac JSP |
538 | xdvp = dvp; |
539 | dvp = LOFSVP(xdvp); | |
d41d1395 | 540 | VREF(dvp); |
c153d43e | 541 | |
50e716ac | 542 | error = VOP_MKDIR(dvp, &newvp, ap->a_cnp, ap->a_vap); |
c153d43e JSP |
543 | |
544 | if (error) { | |
50e716ac | 545 | *ap->a_vpp = NULLVP; |
d41d1395 | 546 | vrele(xdvp); |
c153d43e JSP |
547 | return (error); |
548 | } | |
549 | ||
550 | /* | |
551 | * Make a new lofs node | |
552 | */ | |
50e716ac | 553 | /*VREF(dvp);*/ |
c153d43e | 554 | |
50e716ac | 555 | error = make_lofs(dvp->v_mount, &newvp); |
c153d43e | 556 | |
50e716ac | 557 | *ap->a_vpp = newvp; |
c153d43e JSP |
558 | |
559 | return (error); | |
560 | } | |
561 | ||
562 | /* | |
563 | * ni_dvp is the locked parent. | |
564 | * ni_vp is the entry to be removed. | |
565 | */ | |
05c39890 | 566 | int |
6681df29 KM |
567 | lofs_rmdir(ap) |
568 | struct vop_rmdir_args /* { | |
569 | struct vnode *a_dvp; | |
570 | struct vnode *a_vp; | |
571 | struct componentname *a_cnp; | |
572 | } */ *ap; | |
c153d43e | 573 | { |
50e716ac JSP |
574 | struct vnode *vp = ap->a_vp; |
575 | struct vnode *dvp = ap->a_dvp; | |
c153d43e JSP |
576 | int error; |
577 | ||
50e716ac JSP |
578 | PUSHREF(xdvp, dvp); |
579 | VREF(dvp); | |
580 | PUSHREF(xvp, vp); | |
581 | VREF(vp); | |
c153d43e | 582 | |
50e716ac | 583 | error = VOP_RMDIR(dvp, vp, ap->a_cnp); |
c153d43e | 584 | |
50e716ac JSP |
585 | POP(xvp, vp); |
586 | vrele(vp); | |
587 | POP(xdvp, dvp); | |
588 | vrele(dvp); | |
c153d43e JSP |
589 | |
590 | return (error); | |
591 | } | |
592 | ||
593 | /* | |
594 | * ni_dvp is the locked parent. | |
595 | * ni_vp is NULL. | |
596 | */ | |
05c39890 | 597 | int |
6681df29 KM |
598 | lofs_symlink(ap) |
599 | struct vop_symlink_args /* { | |
600 | struct vnode *a_dvp; | |
601 | struct vnode **a_vpp; | |
602 | struct componentname *a_cnp; | |
603 | struct vattr *a_vap; | |
604 | char *a_target; | |
605 | } */ *ap; | |
c153d43e | 606 | { |
c153d43e JSP |
607 | int error; |
608 | ||
c153d43e JSP |
609 | PUSHREF(xdvp, ap->a_dvp); |
610 | VREF(ap->a_dvp); | |
611 | ||
612 | error = VOP_SYMLINK(ap->a_dvp, ap->a_vpp, ap->a_cnp, ap->a_vap, ap->a_target); | |
613 | ||
614 | POP(xdvp, ap->a_dvp); | |
615 | vrele(ap->a_dvp); | |
616 | ||
617 | return (error); | |
618 | } | |
619 | ||
05c39890 | 620 | int |
6681df29 KM |
621 | lofs_readdir(ap) |
622 | struct vop_readdir_args /* { | |
623 | struct vnode *a_vp; | |
624 | struct uio *a_uio; | |
625 | struct ucred *a_cred; | |
626 | } */ *ap; | |
c153d43e | 627 | { |
6681df29 | 628 | |
05c39890 | 629 | return (VOP_READDIR(LOFSVP(ap->a_vp), ap->a_uio, ap->a_cred)); |
c153d43e JSP |
630 | } |
631 | ||
05c39890 | 632 | int |
6681df29 KM |
633 | lofs_readlink(ap) |
634 | struct vop_readlink_args /* { | |
635 | struct vnode *a_vp; | |
636 | struct uio *a_uio; | |
637 | struct ucred *a_cred; | |
638 | } */ *ap; | |
c153d43e | 639 | { |
6681df29 | 640 | |
05c39890 | 641 | return (VOP_READLINK(LOFSVP(ap->a_vp), ap->a_uio, ap->a_cred)); |
c153d43e JSP |
642 | } |
643 | ||
644 | /* | |
645 | * Anyone's guess... | |
646 | */ | |
05c39890 | 647 | int |
6681df29 KM |
648 | lofs_abortop(ap) |
649 | struct vop_abortop_args /* { | |
650 | struct vnode *a_dvp; | |
651 | struct componentname *a_cnp; | |
652 | } */ *ap; | |
c153d43e | 653 | { |
c153d43e JSP |
654 | int error; |
655 | ||
656 | PUSHREF(xdvp, ap->a_dvp); | |
657 | ||
658 | error = VOP_ABORTOP(ap->a_dvp, ap->a_cnp); | |
659 | ||
660 | POP(xdvp, ap->a_dvp); | |
661 | ||
662 | return (error); | |
663 | } | |
664 | ||
05c39890 | 665 | int |
6681df29 KM |
666 | lofs_inactive(ap) |
667 | struct vop_inactive_args /* { | |
668 | struct vnode *a_vp; | |
669 | } */ *ap; | |
c153d43e | 670 | { |
c153d43e | 671 | struct vnode *targetvp = LOFSVP(ap->a_vp); |
6681df29 | 672 | |
c153d43e JSP |
673 | #ifdef DIAGNOSTIC |
674 | { extern int prtactive; | |
675 | if (prtactive && ap->a_vp->v_usecount != 0) | |
676 | vprint("lofs_inactive: pushing active", ap->a_vp); | |
677 | } | |
678 | #endif | |
679 | ||
680 | if (targetvp) { | |
681 | vrele(targetvp); | |
682 | LOFSP(ap->a_vp)->a_lofsvp = 0; | |
683 | } | |
684 | } | |
685 | ||
05c39890 | 686 | int |
6681df29 KM |
687 | lofs_reclaim(ap) |
688 | struct vop_reclaim_args /* { | |
689 | struct vnode *a_vp; | |
690 | } */ *ap; | |
c153d43e | 691 | { |
c153d43e | 692 | struct vnode *targetvp; |
6681df29 | 693 | |
c153d43e JSP |
694 | remque(LOFSP(ap->a_vp)); |
695 | targetvp = LOFSVP(ap->a_vp); | |
696 | if (targetvp) { | |
697 | printf("lofs: delayed vrele of %x\n", targetvp); | |
698 | vrele(targetvp); /* XXX should never happen */ | |
699 | } | |
700 | FREE(ap->a_vp->v_data, M_TEMP); | |
701 | ap->a_vp->v_data = 0; | |
702 | return (0); | |
703 | } | |
704 | ||
05c39890 | 705 | int |
6681df29 KM |
706 | lofs_lock(ap) |
707 | struct vop_lock_args /* { | |
708 | struct vnode *a_vp; | |
709 | } */ *ap; | |
c153d43e | 710 | { |
c153d43e | 711 | int error; |
12155578 KM |
712 | register struct vnode *vp = ap->a_vp; |
713 | struct vnode *targetvp; | |
714 | ||
715 | while (vp->v_flag & VXLOCK) { | |
716 | vp->v_flag |= VXWANT; | |
717 | sleep((caddr_t)vp, PINOD); | |
718 | } | |
719 | if (vp->v_tag == VT_NON) | |
720 | return (ENOENT); | |
721 | targetvp = LOFSVP(ap->a_vp); | |
c153d43e | 722 | |
12155578 KM |
723 | if (targetvp && (error = VOP_LOCK(targetvp))) |
724 | return (error); | |
c153d43e JSP |
725 | return (0); |
726 | } | |
727 | ||
05c39890 | 728 | int |
6681df29 KM |
729 | lofs_unlock(ap) |
730 | struct vop_unlock_args /* { | |
731 | struct vnode *a_vp; | |
732 | } */ *ap; | |
c153d43e | 733 | { |
c153d43e JSP |
734 | struct vnode *targetvp = LOFSVP(ap->a_vp); |
735 | ||
c153d43e JSP |
736 | if (targetvp) |
737 | return (VOP_UNLOCK(targetvp)); | |
738 | return (0); | |
739 | } | |
740 | ||
05c39890 | 741 | int |
6681df29 KM |
742 | lofs_bmap(ap) |
743 | struct vop_bmap_args /* { | |
744 | struct vnode *a_vp; | |
745 | daddr_t a_bn; | |
746 | struct vnode **a_vpp; | |
747 | daddr_t *a_bnp; | |
45ee8885 | 748 | int *a_runp; |
6681df29 | 749 | } */ *ap; |
c153d43e | 750 | { |
6681df29 | 751 | |
05c39890 | 752 | return (VOP_BMAP(LOFSVP(ap->a_vp), ap->a_bn, ap->a_vpp, ap->a_bnp, ap->a_runp)); |
c153d43e JSP |
753 | } |
754 | ||
05c39890 | 755 | int |
6681df29 KM |
756 | lofs_strategy(ap) |
757 | struct vop_strategy_args /* { | |
758 | struct buf *a_bp; | |
759 | } */ *ap; | |
c153d43e | 760 | { |
c153d43e JSP |
761 | int error; |
762 | ||
c153d43e JSP |
763 | PUSHREF(vp, ap->a_bp->b_vp); |
764 | ||
765 | error = VOP_STRATEGY(ap->a_bp); | |
766 | ||
767 | POP(vp, ap->a_bp->b_vp); | |
768 | ||
769 | return (error); | |
770 | } | |
771 | ||
05c39890 | 772 | int |
6681df29 KM |
773 | lofs_print(ap) |
774 | struct vop_print_args /* { | |
775 | struct vnode *a_vp; | |
776 | } */ *ap; | |
c153d43e | 777 | { |
6681df29 | 778 | |
c153d43e JSP |
779 | struct vnode *targetvp = LOFSVP(ap->a_vp); |
780 | printf("tag VT_LOFS ref "); | |
781 | if (targetvp) | |
782 | return (VOP_PRINT(targetvp)); | |
783 | printf("NULLVP\n"); | |
784 | return (0); | |
785 | } | |
786 | ||
05c39890 | 787 | int |
6681df29 KM |
788 | lofs_islocked(ap) |
789 | struct vop_islocked_args /* { | |
790 | struct vnode *a_vp; | |
791 | } */ *ap; | |
c153d43e | 792 | { |
6681df29 | 793 | |
c153d43e JSP |
794 | struct vnode *targetvp = LOFSVP(ap->a_vp); |
795 | if (targetvp) | |
796 | return (VOP_ISLOCKED(targetvp)); | |
797 | return (0); | |
798 | } | |
799 | ||
05c39890 | 800 | int |
6681df29 KM |
801 | lofs_advlock(ap) |
802 | struct vop_advlock_args /* { | |
803 | struct vnode *a_vp; | |
804 | caddr_t a_id; | |
805 | int a_op; | |
806 | struct flock *a_fl; | |
807 | int a_flags; | |
808 | } */ *ap; | |
c153d43e | 809 | { |
6681df29 | 810 | |
05c39890 | 811 | return (VOP_ADVLOCK(LOFSVP(ap->a_vp), ap->a_id, ap->a_op, ap->a_fl, ap->a_flags)); |
c153d43e JSP |
812 | } |
813 | ||
814 | /* | |
815 | * LOFS directory offset lookup. | |
816 | * Currently unsupported. | |
817 | */ | |
05c39890 | 818 | int |
6681df29 KM |
819 | lofs_blkatoff(ap) |
820 | struct vop_blkatoff_args /* { | |
821 | struct vnode *a_vp; | |
822 | off_t a_offset; | |
823 | char **a_res; | |
824 | struct buf **a_bpp; | |
825 | } */ *ap; | |
c153d43e JSP |
826 | { |
827 | ||
828 | return (EOPNOTSUPP); | |
829 | } | |
830 | ||
c153d43e JSP |
831 | /* |
832 | * LOFS flat namespace allocation. | |
833 | * Currently unsupported. | |
834 | */ | |
05c39890 | 835 | int |
6681df29 KM |
836 | lofs_valloc(ap) |
837 | struct vop_valloc_args /* { | |
838 | struct vnode *a_pvp; | |
839 | int a_mode; | |
840 | struct ucred *a_cred; | |
841 | struct vnode **a_vpp; | |
842 | } */ *ap; | |
c153d43e JSP |
843 | { |
844 | ||
845 | return (EOPNOTSUPP); | |
846 | } | |
847 | ||
848 | /* | |
849 | * LOFS flat namespace free. | |
850 | * Currently unsupported. | |
851 | */ | |
852 | /*void*/ | |
05c39890 | 853 | int |
6681df29 KM |
854 | lofs_vfree(ap) |
855 | struct vop_vfree_args /* { | |
856 | struct vnode *a_pvp; | |
857 | ino_t a_ino; | |
858 | int a_mode; | |
859 | } */ *ap; | |
c153d43e JSP |
860 | { |
861 | ||
6681df29 | 862 | return (0); |
c153d43e JSP |
863 | } |
864 | ||
865 | /* | |
866 | * LOFS file truncation. | |
867 | */ | |
05c39890 | 868 | int |
6681df29 KM |
869 | lofs_truncate(ap) |
870 | struct vop_truncate_args /* { | |
871 | struct vnode *a_vp; | |
872 | off_t a_length; | |
873 | int a_flags; | |
874 | struct ucred *a_cred; | |
875 | struct proc *a_p; | |
876 | } */ *ap; | |
c153d43e JSP |
877 | { |
878 | ||
879 | /* Use lofs_setattr */ | |
880 | printf("lofs_truncate: need to implement!!"); | |
881 | return (EOPNOTSUPP); | |
882 | } | |
883 | ||
884 | /* | |
885 | * LOFS update. | |
886 | */ | |
05c39890 | 887 | int |
6681df29 KM |
888 | lofs_update(ap) |
889 | struct vop_update_args /* { | |
890 | struct vnode *a_vp; | |
891 | struct timeval *a_ta; | |
892 | struct timeval *a_tm; | |
893 | int a_waitfor; | |
894 | } */ *ap; | |
c153d43e JSP |
895 | { |
896 | ||
897 | /* Use lofs_setattr */ | |
898 | printf("lofs_update: need to implement!!"); | |
899 | return (EOPNOTSUPP); | |
900 | } | |
901 | ||
902 | /* | |
903 | * LOFS bwrite | |
904 | */ | |
05c39890 | 905 | int |
6681df29 KM |
906 | lofs_bwrite(ap) |
907 | struct vop_bwrite_args /* { | |
908 | struct buf *a_bp; | |
909 | } */ *ap; | |
c153d43e | 910 | { |
6681df29 | 911 | |
c153d43e JSP |
912 | return (EOPNOTSUPP); |
913 | } | |
914 | ||
915 | /* | |
916 | * Global vfs data structures for ufs | |
917 | */ | |
918 | int (**lofs_vnodeop_p)(); | |
919 | struct vnodeopv_entry_desc lofs_vnodeop_entries[] = { | |
920 | { &vop_default_desc, vn_default_error }, | |
921 | { &vop_lookup_desc, lofs_lookup }, /* lookup */ | |
922 | { &vop_create_desc, lofs_create }, /* create */ | |
923 | { &vop_mknod_desc, lofs_mknod }, /* mknod */ | |
924 | { &vop_open_desc, lofs_open }, /* open */ | |
925 | { &vop_close_desc, lofs_close }, /* close */ | |
926 | { &vop_access_desc, lofs_access }, /* access */ | |
927 | { &vop_getattr_desc, lofs_getattr }, /* getattr */ | |
928 | { &vop_setattr_desc, lofs_setattr }, /* setattr */ | |
929 | { &vop_read_desc, lofs_read }, /* read */ | |
930 | { &vop_write_desc, lofs_write }, /* write */ | |
931 | { &vop_ioctl_desc, lofs_ioctl }, /* ioctl */ | |
932 | { &vop_select_desc, lofs_select }, /* select */ | |
933 | { &vop_mmap_desc, lofs_mmap }, /* mmap */ | |
934 | { &vop_fsync_desc, lofs_fsync }, /* fsync */ | |
935 | { &vop_seek_desc, lofs_seek }, /* seek */ | |
936 | { &vop_remove_desc, lofs_remove }, /* remove */ | |
937 | { &vop_link_desc, lofs_link }, /* link */ | |
938 | { &vop_rename_desc, lofs_rename }, /* rename */ | |
939 | { &vop_mkdir_desc, lofs_mkdir }, /* mkdir */ | |
940 | { &vop_rmdir_desc, lofs_rmdir }, /* rmdir */ | |
941 | { &vop_symlink_desc, lofs_symlink }, /* symlink */ | |
942 | { &vop_readdir_desc, lofs_readdir }, /* readdir */ | |
943 | { &vop_readlink_desc, lofs_readlink }, /* readlink */ | |
944 | { &vop_abortop_desc, lofs_abortop }, /* abortop */ | |
945 | { &vop_inactive_desc, lofs_inactive }, /* inactive */ | |
946 | { &vop_reclaim_desc, lofs_reclaim }, /* reclaim */ | |
947 | { &vop_lock_desc, lofs_lock }, /* lock */ | |
948 | { &vop_unlock_desc, lofs_unlock }, /* unlock */ | |
949 | { &vop_bmap_desc, lofs_bmap }, /* bmap */ | |
950 | { &vop_strategy_desc, lofs_strategy }, /* strategy */ | |
951 | { &vop_print_desc, lofs_print }, /* print */ | |
952 | { &vop_islocked_desc, lofs_islocked }, /* islocked */ | |
953 | { &vop_advlock_desc, lofs_advlock }, /* advlock */ | |
954 | { &vop_blkatoff_desc, lofs_blkatoff }, /* blkatoff */ | |
c153d43e JSP |
955 | { &vop_valloc_desc, lofs_valloc }, /* valloc */ |
956 | { &vop_vfree_desc, lofs_vfree }, /* vfree */ | |
957 | { &vop_truncate_desc, lofs_truncate }, /* truncate */ | |
958 | { &vop_update_desc, lofs_update }, /* update */ | |
959 | { &vop_bwrite_desc, lofs_bwrite }, /* bwrite */ | |
960 | { (struct vnodeop_desc*)NULL, (int(*)())NULL } | |
961 | }; | |
962 | struct vnodeopv_desc lofs_vnodeop_opv_desc = | |
963 | { &lofs_vnodeop_p, lofs_vnodeop_entries }; |