153842Spendry /*
263237Sbostic * Copyright (c) 1992, 1993
363237Sbostic * The Regents of the University of California. All rights reserved.
453842Spendry *
553842Spendry * This code is derived from software donated to Berkeley by
653842Spendry * Jan-Simon Pendry.
753842Spendry *
853842Spendry * %sccs.include.redist.c%
953842Spendry *
10*65803Sbostic * @(#)lofs_vnops.c 8.4 (Berkeley) 01/21/94
1153842Spendry *
1253842Spendry * $Id: lofs_vnops.c,v 1.11 1992/05/30 10:05:43 jsp Exp jsp $
1353842Spendry */
1453842Spendry
1553842Spendry /*
1653842Spendry * Loopback Filesystem
1753842Spendry */
1853842Spendry
1953842Spendry #include <sys/param.h>
2053842Spendry #include <sys/systm.h>
2153842Spendry #include <sys/proc.h>
2253842Spendry #include <sys/time.h>
2353842Spendry #include <sys/types.h>
2453842Spendry #include <sys/vnode.h>
2553842Spendry #include <sys/mount.h>
2653842Spendry #include <sys/namei.h>
2753842Spendry #include <sys/malloc.h>
2853842Spendry #include <sys/buf.h>
2955022Smckusick #include <miscfs/lofs/lofs.h>
3053842Spendry
3153842Spendry /*
3253842Spendry * Basic strategy: as usual, do as little work as possible.
3353842Spendry * Nothing is ever locked in the lofs'ed filesystem, all
3453842Spendry * locks are held in the underlying filesystems.
3553842Spendry */
3653842Spendry
3753842Spendry /*
3853842Spendry * Save a vnode and replace with
3953842Spendry * the lofs'ed one
4053842Spendry */
4153842Spendry #define PUSHREF(v, nd) \
4253842Spendry { \
4353842Spendry struct { struct vnode *vnp; } v; \
4453842Spendry v.vnp = (nd); \
4553842Spendry (nd) = LOFSVP(v.vnp)
4653842Spendry
4753842Spendry /*
4853842Spendry * Undo the PUSHREF
4953842Spendry */
5053842Spendry #define POP(v, nd) \
5153842Spendry \
5253842Spendry (nd) = v.vnp; \
5353842Spendry }
5453842Spendry
5553842Spendry /*
5653842Spendry * vp is the current namei directory
5753842Spendry * ndp is the name to locate in that directory...
5853842Spendry */
5965518Spendry int
lofs_lookup(ap)6055022Smckusick lofs_lookup(ap)
6155022Smckusick struct vop_lookup_args /* {
6255022Smckusick struct vnode * a_dvp;
6355022Smckusick struct vnode ** a_vpp;
6455022Smckusick struct componentname * a_cnp;
6555022Smckusick } */ *ap;
6653842Spendry {
6754052Spendry struct vnode *dvp = ap->a_dvp;
6853842Spendry struct vnode *newvp;
6953842Spendry struct vnode *targetdvp;
7053842Spendry int error;
7153842Spendry int flag = ap->a_cnp->cn_nameiop /*& OPMASK*/;
7253842Spendry
7353842Spendry /*
7453842Spendry * (ap->a_dvp) was locked when passed in, and it will be replaced
7553842Spendry * with the target vnode, BUT that will already have been
7653842Spendry * locked when (ap->a_dvp) was locked [see lofs_lock]. all that
7753842Spendry * must be done here is to keep track of reference counts.
7853842Spendry */
7954052Spendry targetdvp = LOFSVP(dvp);
8054052Spendry /*VREF(targetdvp);*/
8153842Spendry
8253842Spendry /*
8353842Spendry * Call lookup on the looped vnode
8453842Spendry */
8554052Spendry error = VOP_LOOKUP(targetdvp, &newvp, ap->a_cnp);
8654052Spendry /*vrele(targetdvp);*/
8753842Spendry
8853842Spendry if (error) {
8953842Spendry *ap->a_vpp = NULLVP;
9053842Spendry return (error);
9153842Spendry }
9253842Spendry
9354052Spendry *ap->a_vpp = newvp;
9453842Spendry
9553842Spendry /*
9653842Spendry * If we just found a directory then make
9753842Spendry * a loopback node for it and return the loopback
9853842Spendry * instead of the real vnode. Otherwise simply
9953842Spendry * return the aliased directory and vnode.
10053842Spendry */
10153842Spendry if (newvp && newvp->v_type == VDIR && flag == LOOKUP) {
10253842Spendry /*
10353842Spendry * At this point, newvp is the vnode to be looped.
10453842Spendry * Activate a loopback and return the looped vnode.
10553842Spendry */
10654052Spendry return (make_lofs(dvp->v_mount, ap->a_vpp));
10753842Spendry }
10853842Spendry
10953842Spendry return (0);
11053842Spendry }
11153842Spendry
11253842Spendry /*
11353842Spendry * this = ni_dvp
11453842Spendry * ni_dvp references the locked directory.
11553842Spendry * ni_vp is NULL.
11653842Spendry */
11765518Spendry int
lofs_mknod(ap)11855022Smckusick lofs_mknod(ap)
11955022Smckusick struct vop_mknod_args /* {
12055022Smckusick struct vnode *a_dvp;
12155022Smckusick struct vnode **a_vpp;
12255022Smckusick struct componentname *a_cnp;
12355022Smckusick struct vattr *a_vap;
12455022Smckusick } */ *ap;
12553842Spendry {
12653842Spendry int error;
12753842Spendry
12853842Spendry PUSHREF(xdvp, ap->a_dvp);
12953842Spendry VREF(ap->a_dvp);
13053842Spendry
13153842Spendry error = VOP_MKNOD(ap->a_dvp, ap->a_vpp, ap->a_cnp, ap->a_vap);
13253842Spendry
13353842Spendry POP(xdvp, ap->a_dvp);
13453842Spendry vrele(ap->a_dvp);
13553842Spendry
13653842Spendry return (error);
13753842Spendry }
13853842Spendry
13953842Spendry /*
14053842Spendry * this = ni_dvp;
14153842Spendry * ni_dvp references the locked directory
14253842Spendry * ni_vp is NULL.
14353842Spendry */
14465518Spendry int
lofs_create(ap)14555022Smckusick lofs_create(ap)
14655022Smckusick struct vop_create_args /* {
14755022Smckusick struct vnode *a_dvp;
14855022Smckusick struct vnode **a_vpp;
14955022Smckusick struct componentname *a_cnp;
15055022Smckusick struct vattr *a_vap;
15155022Smckusick } */ *ap;
15253842Spendry {
15353842Spendry int error;
15453842Spendry
15553842Spendry PUSHREF(xdvp, ap->a_dvp);
15653842Spendry VREF(ap->a_dvp);
15753842Spendry
15853842Spendry error = VOP_CREATE(ap->a_dvp, ap->a_vpp, ap->a_cnp, ap->a_vap);
15953842Spendry
16053842Spendry POP(xdvp, ap->a_dvp);
16153842Spendry vrele(ap->a_dvp);
16253842Spendry
16353842Spendry return (error);
16453842Spendry }
16553842Spendry
16665518Spendry int
lofs_open(ap)16755022Smckusick lofs_open(ap)
16855022Smckusick struct vop_open_args /* {
16955022Smckusick struct vnode *a_vp;
17055022Smckusick int a_mode;
17155022Smckusick struct ucred *a_cred;
17255022Smckusick struct proc *a_p;
17355022Smckusick } */ *ap;
17453842Spendry {
17555022Smckusick
17665518Spendry return (VOP_OPEN(LOFSVP(ap->a_vp), ap->a_mode, ap->a_cred, ap->a_p));
17753842Spendry }
17853842Spendry
17965518Spendry int
lofs_close(ap)18055022Smckusick lofs_close(ap)
18155022Smckusick struct vop_close_args /* {
18255022Smckusick struct vnode *a_vp;
18355022Smckusick int a_fflag;
18455022Smckusick struct ucred *a_cred;
18555022Smckusick struct proc *a_p;
18655022Smckusick } */ *ap;
18753842Spendry {
18855022Smckusick
18965518Spendry return (VOP_CLOSE(LOFSVP(ap->a_vp), ap->a_fflag, ap->a_cred, ap->a_p));
19053842Spendry }
19153842Spendry
19265518Spendry int
lofs_access(ap)19355022Smckusick lofs_access(ap)
19455022Smckusick struct vop_access_args /* {
19555022Smckusick struct vnode *a_vp;
19655022Smckusick int a_mode;
19755022Smckusick struct ucred *a_cred;
19855022Smckusick struct proc *a_p;
19955022Smckusick } */ *ap;
20053842Spendry {
20155022Smckusick
20265518Spendry return (VOP_ACCESS(LOFSVP(ap->a_vp), ap->a_mode, ap->a_cred, ap->a_p));
20353842Spendry }
20453842Spendry
20565518Spendry int
lofs_getattr(ap)20655022Smckusick lofs_getattr(ap)
20755022Smckusick struct vop_getattr_args /* {
20855022Smckusick struct vnode *a_vp;
20955022Smckusick struct vattr *a_vap;
21055022Smckusick struct ucred *a_cred;
21155022Smckusick struct proc *a_p;
21255022Smckusick } */ *ap;
21353842Spendry {
21453842Spendry int error;
21553842Spendry
21653842Spendry /*
21753842Spendry * Get the stats from the underlying filesystem
21853842Spendry */
21953842Spendry error = VOP_GETATTR(LOFSVP(ap->a_vp), ap->a_vap, ap->a_cred, ap->a_p);
22053842Spendry if (error)
22153842Spendry return (error);
22253842Spendry /*
22353842Spendry * and replace the fsid field with the loopback number
22453842Spendry * to preserve the namespace.
22553842Spendry */
22653842Spendry ap->a_vap->va_fsid = ap->a_vp->v_mount->mnt_stat.f_fsid.val[0];
22753842Spendry return (0);
22853842Spendry }
22953842Spendry
23065518Spendry int
lofs_setattr(ap)23155022Smckusick lofs_setattr(ap)
23255022Smckusick struct vop_setattr_args /* {
23355022Smckusick struct vnode *a_vp;
23455022Smckusick struct vattr *a_vap;
23555022Smckusick struct ucred *a_cred;
23655022Smckusick struct proc *a_p;
23755022Smckusick } */ *ap;
23853842Spendry {
23955022Smckusick
24065518Spendry return (VOP_SETATTR(LOFSVP(ap->a_vp), ap->a_vap, ap->a_cred, ap->a_p));
24153842Spendry }
24253842Spendry
24365518Spendry int
lofs_read(ap)24455022Smckusick lofs_read(ap)
24555022Smckusick struct vop_read_args /* {
24655022Smckusick struct vnode *a_vp;
24755022Smckusick struct uio *a_uio;
24855022Smckusick int a_ioflag;
24955022Smckusick struct ucred *a_cred;
25055022Smckusick } */ *ap;
25153842Spendry {
25255022Smckusick
25365518Spendry return (VOP_READ(LOFSVP(ap->a_vp), ap->a_uio, ap->a_ioflag, ap->a_cred));
25453842Spendry }
25553842Spendry
25665518Spendry int
lofs_write(ap)25755022Smckusick lofs_write(ap)
25855022Smckusick struct vop_write_args /* {
25955022Smckusick struct vnode *a_vp;
26055022Smckusick struct uio *a_uio;
26155022Smckusick int a_ioflag;
26255022Smckusick struct ucred *a_cred;
26355022Smckusick } */ *ap;
26453842Spendry {
26555022Smckusick
26665518Spendry return (VOP_WRITE(LOFSVP(ap->a_vp), ap->a_uio, ap->a_ioflag, ap->a_cred));
26753842Spendry }
26853842Spendry
26965518Spendry int
lofs_ioctl(ap)27055022Smckusick lofs_ioctl(ap)
27155022Smckusick struct vop_ioctl_args /* {
27255022Smckusick struct vnode *a_vp;
27355022Smckusick int a_command;
27455022Smckusick caddr_t a_data;
27555022Smckusick int a_fflag;
27655022Smckusick struct ucred *a_cred;
27755022Smckusick struct proc *a_p;
27855022Smckusick } */ *ap;
27953842Spendry {
28055022Smckusick
28165518Spendry return (VOP_IOCTL(LOFSVP(ap->a_vp), ap->a_command, ap->a_data, ap->a_fflag, ap->a_cred, ap->a_p));
28253842Spendry }
28353842Spendry
28465518Spendry int
lofs_select(ap)28555022Smckusick lofs_select(ap)
28655022Smckusick struct vop_select_args /* {
28755022Smckusick struct vnode *a_vp;
28855022Smckusick int a_which;
28955022Smckusick int a_fflags;
29055022Smckusick struct ucred *a_cred;
29155022Smckusick struct proc *a_p;
29255022Smckusick } */ *ap;
29353842Spendry {
29455022Smckusick
29565518Spendry return (VOP_SELECT(LOFSVP(ap->a_vp), ap->a_which, ap->a_fflags, ap->a_cred, ap->a_p));
29653842Spendry }
29753842Spendry
29865518Spendry int
lofs_mmap(ap)29955022Smckusick lofs_mmap(ap)
30055022Smckusick struct vop_mmap_args /* {
30155022Smckusick struct vnode *a_vp;
30255022Smckusick int a_fflags;
30355022Smckusick struct ucred *a_cred;
30455022Smckusick struct proc *a_p;
30555022Smckusick } */ *ap;
30653842Spendry {
30755022Smckusick
30865518Spendry return (VOP_MMAP(LOFSVP(ap->a_vp), ap->a_fflags, ap->a_cred, ap->a_p));
30953842Spendry }
31053842Spendry
31165518Spendry int
lofs_fsync(ap)31255022Smckusick lofs_fsync(ap)
31355022Smckusick struct vop_fsync_args /* {
31455022Smckusick struct vnode *a_vp;
31555022Smckusick struct ucred *a_cred;
31655022Smckusick int a_waitfor;
31755022Smckusick struct proc *a_p;
31855022Smckusick } */ *ap;
31953842Spendry {
32063133Smckusick struct vnode *targetvp = LOFSVP(ap->a_vp);
32155022Smckusick
32263133Smckusick if (targetvp)
32365518Spendry return (VOP_FSYNC(targetvp, ap->a_cred, ap->a_waitfor, ap->a_p));
32463133Smckusick return (0);
32553842Spendry }
32653842Spendry
32765518Spendry int
lofs_seek(ap)32855022Smckusick lofs_seek(ap)
32955022Smckusick struct vop_seek_args /* {
33055022Smckusick struct vnode *a_vp;
33155022Smckusick off_t a_oldoff;
33255022Smckusick off_t a_newoff;
33355022Smckusick struct ucred *a_cred;
33455022Smckusick } */ *ap;
33553842Spendry {
33655022Smckusick
33765518Spendry return (VOP_SEEK(LOFSVP(ap->a_vp), ap->a_oldoff, ap->a_newoff, ap->a_cred));
33853842Spendry }
33953842Spendry
34065518Spendry int
lofs_remove(ap)34155022Smckusick lofs_remove(ap)
34255022Smckusick struct vop_remove_args /* {
34355022Smckusick struct vnode *a_dvp;
34455022Smckusick struct vnode *a_vp;
34555022Smckusick struct componentname *a_cnp;
34655022Smckusick } */ *ap;
34753842Spendry {
34853842Spendry int error;
34953842Spendry
35053842Spendry PUSHREF(xdvp, ap->a_dvp);
35153842Spendry VREF(ap->a_dvp);
35253842Spendry PUSHREF(xvp, ap->a_vp);
35353842Spendry VREF(ap->a_vp);
35453842Spendry
35553842Spendry error = VOP_REMOVE(ap->a_dvp, ap->a_vp, ap->a_cnp);
35653842Spendry
35753842Spendry POP(xvp, ap->a_vp);
35853842Spendry vrele(ap->a_vp);
35953842Spendry POP(xdvp, ap->a_dvp);
36053842Spendry vrele(ap->a_dvp);
36153842Spendry
36253842Spendry return (error);
36353842Spendry }
36453842Spendry
36553842Spendry /*
36653842Spendry * vp is this.
36753842Spendry * ni_dvp is the locked parent of the target.
36853842Spendry * ni_vp is NULL.
36953842Spendry */
37065518Spendry int
lofs_link(ap)37155022Smckusick lofs_link(ap)
37255022Smckusick struct vop_link_args /* {
37355022Smckusick struct vnode *a_vp;
37455022Smckusick struct vnode *a_tdvp;
37555022Smckusick struct componentname *a_cnp;
37655022Smckusick } */ *ap;
37753842Spendry {
37853842Spendry int error;
37953842Spendry
38053842Spendry PUSHREF(xdvp, ap->a_vp);
38153842Spendry VREF(ap->a_vp);
38253842Spendry
38353842Spendry error = VOP_LINK(ap->a_vp, LOFSVP(ap->a_tdvp), ap->a_cnp);
38453842Spendry
38553842Spendry POP(xdvp, ap->a_vp);
38653842Spendry vrele(ap->a_vp);
38753842Spendry
38853842Spendry return (error);
38953842Spendry }
39053842Spendry
39165518Spendry int
lofs_rename(ap)39255022Smckusick lofs_rename(ap)
39355022Smckusick struct vop_rename_args /* {
39455022Smckusick struct vnode *a_fdvp;
39555022Smckusick struct vnode *a_fvp;
39655022Smckusick struct componentname *a_fcnp;
39755022Smckusick struct vnode *a_tdvp;
39855022Smckusick struct vnode *a_tvp;
39955022Smckusick struct componentname *a_tcnp;
40055022Smckusick } */ *ap;
40153842Spendry {
40253842Spendry struct vnode *fvp, *tvp;
40353842Spendry struct vnode *tdvp;
40455022Smckusick #ifdef notdef
40553842Spendry struct vnode *fsvp, *tsvp;
40653842Spendry #endif
40753842Spendry int error;
40853842Spendry
40953842Spendry /*
41053842Spendry * Switch source directory to point to lofsed vnode
41153842Spendry */
41253842Spendry PUSHREF(fdvp, ap->a_fdvp);
41353842Spendry VREF(ap->a_fdvp);
41453842Spendry
41553842Spendry /*
41653842Spendry * And source object if it is lofsed...
41753842Spendry */
41853842Spendry fvp = ap->a_fvp;
41953842Spendry if (fvp && fvp->v_op == lofs_vnodeop_p) {
42053842Spendry ap->a_fvp = LOFSVP(fvp);
42153842Spendry VREF(ap->a_fvp);
42253842Spendry } else {
42353842Spendry fvp = 0;
42453842Spendry }
42553842Spendry
42655022Smckusick #ifdef notdef
42753842Spendry /*
42853842Spendry * And source startdir object if it is lofsed...
42953842Spendry */
43053842Spendry fsvp = fndp->ni_startdir;
43153842Spendry if (fsvp && fsvp->v_op == lofs_vnodeop_p) {
43253842Spendry fndp->ni_startdir = LOFSVP(fsvp);
43353842Spendry VREF(fndp->ni_startdir);
43453842Spendry } else {
43553842Spendry fsvp = 0;
43653842Spendry }
43753842Spendry #endif
43853842Spendry
43953842Spendry /*
44053842Spendry * Switch target directory to point to lofsed vnode
44153842Spendry */
44253842Spendry tdvp = ap->a_tdvp;
44353842Spendry if (tdvp && tdvp->v_op == lofs_vnodeop_p) {
44453842Spendry ap->a_tdvp = LOFSVP(tdvp);
44553842Spendry VREF(ap->a_tdvp);
44653842Spendry } else {
44753842Spendry tdvp = 0;
44853842Spendry }
44953842Spendry
45053842Spendry /*
45153842Spendry * And target object if it is lofsed...
45253842Spendry */
45353842Spendry tvp = ap->a_tvp;
45453842Spendry if (tvp && tvp->v_op == lofs_vnodeop_p) {
45553842Spendry ap->a_tvp = LOFSVP(tvp);
45653842Spendry VREF(ap->a_tvp);
45753842Spendry } else {
45853842Spendry tvp = 0;
45953842Spendry }
46053842Spendry
46155022Smckusick #ifdef notdef
46253842Spendry /*
46353842Spendry * And target startdir object if it is lofsed...
46453842Spendry */
46553842Spendry tsvp = tndp->ni_startdir;
46653842Spendry if (tsvp && tsvp->v_op == lofs_vnodeop_p) {
46753842Spendry tndp->ni_startdir = LOFSVP(fsvp);
46853842Spendry VREF(tndp->ni_startdir);
46953842Spendry } else {
47053842Spendry tsvp = 0;
47153842Spendry }
47253842Spendry #endif
47353842Spendry
47453842Spendry error = VOP_RENAME(ap->a_fdvp, ap->a_fvp, ap->a_fcnp, ap->a_tdvp, ap->a_tvp, ap->a_tcnp);
47553842Spendry
47653842Spendry /*
47753842Spendry * Put everything back...
47853842Spendry */
47953842Spendry
48055022Smckusick #ifdef notdef
48153842Spendry
48253842Spendry if (tsvp) {
48353842Spendry if (tndp->ni_startdir)
48453842Spendry vrele(tndp->ni_startdir);
48553842Spendry tndp->ni_startdir = tsvp;
48653842Spendry }
48753842Spendry #endif
48853842Spendry
48953842Spendry if (tvp) {
49053842Spendry ap->a_tvp = tvp;
49153842Spendry vrele(ap->a_tvp);
49253842Spendry }
49353842Spendry
49453842Spendry if (tdvp) {
49553842Spendry ap->a_tdvp = tdvp;
49653842Spendry vrele(ap->a_tdvp);
49753842Spendry }
49853842Spendry
49955022Smckusick #ifdef notdef
50053842Spendry
50153842Spendry if (fsvp) {
50253842Spendry if (fndp->ni_startdir)
50353842Spendry vrele(fndp->ni_startdir);
50453842Spendry fndp->ni_startdir = fsvp;
50553842Spendry }
50653842Spendry #endif
50753842Spendry
50853842Spendry if (fvp) {
50953842Spendry ap->a_fvp = fvp;
51053842Spendry vrele(ap->a_fvp);
51153842Spendry }
51253842Spendry
51353842Spendry POP(fdvp, ap->a_fdvp);
51453842Spendry vrele(ap->a_fdvp);
51553842Spendry
51653842Spendry return (error);
51753842Spendry }
51853842Spendry
51953842Spendry /*
52053842Spendry * ni_dvp is the locked (alias) parent.
52153842Spendry * ni_vp is NULL.
52253842Spendry */
52365518Spendry int
lofs_mkdir(ap)52455022Smckusick lofs_mkdir(ap)
52555022Smckusick struct vop_mkdir_args /* {
52655022Smckusick struct vnode *a_dvp;
52755022Smckusick struct vnode **a_vpp;
52855022Smckusick struct componentname *a_cnp;
52955022Smckusick struct vattr *a_vap;
53055022Smckusick } */ *ap;
53153842Spendry {
53253842Spendry int error;
53354052Spendry struct vnode *dvp = ap->a_dvp;
53453842Spendry struct vnode *xdvp;
53554052Spendry struct vnode *newvp;
53653842Spendry
53754052Spendry xdvp = dvp;
53854052Spendry dvp = LOFSVP(xdvp);
53955254Spendry VREF(dvp);
54053842Spendry
54154052Spendry error = VOP_MKDIR(dvp, &newvp, ap->a_cnp, ap->a_vap);
54253842Spendry
54353842Spendry if (error) {
54454052Spendry *ap->a_vpp = NULLVP;
54555254Spendry vrele(xdvp);
54653842Spendry return (error);
54753842Spendry }
54853842Spendry
54953842Spendry /*
55053842Spendry * Make a new lofs node
55153842Spendry */
55254052Spendry /*VREF(dvp);*/
55353842Spendry
55454052Spendry error = make_lofs(dvp->v_mount, &newvp);
55553842Spendry
55654052Spendry *ap->a_vpp = newvp;
55753842Spendry
55853842Spendry return (error);
55953842Spendry }
56053842Spendry
56153842Spendry /*
56253842Spendry * ni_dvp is the locked parent.
56353842Spendry * ni_vp is the entry to be removed.
56453842Spendry */
56565518Spendry int
lofs_rmdir(ap)56655022Smckusick lofs_rmdir(ap)
56755022Smckusick struct vop_rmdir_args /* {
56855022Smckusick struct vnode *a_dvp;
56955022Smckusick struct vnode *a_vp;
57055022Smckusick struct componentname *a_cnp;
57155022Smckusick } */ *ap;
57253842Spendry {
57354052Spendry struct vnode *vp = ap->a_vp;
57454052Spendry struct vnode *dvp = ap->a_dvp;
57553842Spendry int error;
57653842Spendry
57754052Spendry PUSHREF(xdvp, dvp);
57854052Spendry VREF(dvp);
57954052Spendry PUSHREF(xvp, vp);
58054052Spendry VREF(vp);
58153842Spendry
58254052Spendry error = VOP_RMDIR(dvp, vp, ap->a_cnp);
58353842Spendry
58454052Spendry POP(xvp, vp);
58554052Spendry vrele(vp);
58654052Spendry POP(xdvp, dvp);
58754052Spendry vrele(dvp);
58853842Spendry
58953842Spendry return (error);
59053842Spendry }
59153842Spendry
59253842Spendry /*
59353842Spendry * ni_dvp is the locked parent.
59453842Spendry * ni_vp is NULL.
59553842Spendry */
59665518Spendry int
lofs_symlink(ap)59755022Smckusick lofs_symlink(ap)
59855022Smckusick struct vop_symlink_args /* {
59955022Smckusick struct vnode *a_dvp;
60055022Smckusick struct vnode **a_vpp;
60155022Smckusick struct componentname *a_cnp;
60255022Smckusick struct vattr *a_vap;
60355022Smckusick char *a_target;
60455022Smckusick } */ *ap;
60553842Spendry {
60653842Spendry int error;
60753842Spendry
60853842Spendry PUSHREF(xdvp, ap->a_dvp);
60953842Spendry VREF(ap->a_dvp);
61053842Spendry
61153842Spendry error = VOP_SYMLINK(ap->a_dvp, ap->a_vpp, ap->a_cnp, ap->a_vap, ap->a_target);
61253842Spendry
61353842Spendry POP(xdvp, ap->a_dvp);
61453842Spendry vrele(ap->a_dvp);
61553842Spendry
61653842Spendry return (error);
61753842Spendry }
61853842Spendry
61965518Spendry int
lofs_readdir(ap)62055022Smckusick lofs_readdir(ap)
62155022Smckusick struct vop_readdir_args /* {
62255022Smckusick struct vnode *a_vp;
62355022Smckusick struct uio *a_uio;
62455022Smckusick struct ucred *a_cred;
62555022Smckusick } */ *ap;
62653842Spendry {
62755022Smckusick
62865518Spendry return (VOP_READDIR(LOFSVP(ap->a_vp), ap->a_uio, ap->a_cred));
62953842Spendry }
63053842Spendry
63165518Spendry int
lofs_readlink(ap)63255022Smckusick lofs_readlink(ap)
63355022Smckusick struct vop_readlink_args /* {
63455022Smckusick struct vnode *a_vp;
63555022Smckusick struct uio *a_uio;
63655022Smckusick struct ucred *a_cred;
63755022Smckusick } */ *ap;
63853842Spendry {
63955022Smckusick
64065518Spendry return (VOP_READLINK(LOFSVP(ap->a_vp), ap->a_uio, ap->a_cred));
64153842Spendry }
64253842Spendry
64353842Spendry /*
64453842Spendry * Anyone's guess...
64553842Spendry */
64665518Spendry int
lofs_abortop(ap)64755022Smckusick lofs_abortop(ap)
64855022Smckusick struct vop_abortop_args /* {
64955022Smckusick struct vnode *a_dvp;
65055022Smckusick struct componentname *a_cnp;
65155022Smckusick } */ *ap;
65253842Spendry {
65353842Spendry int error;
65453842Spendry
65553842Spendry PUSHREF(xdvp, ap->a_dvp);
65653842Spendry
65753842Spendry error = VOP_ABORTOP(ap->a_dvp, ap->a_cnp);
65853842Spendry
65953842Spendry POP(xdvp, ap->a_dvp);
66053842Spendry
66153842Spendry return (error);
66253842Spendry }
66353842Spendry
66465518Spendry int
lofs_inactive(ap)66555022Smckusick lofs_inactive(ap)
66655022Smckusick struct vop_inactive_args /* {
66755022Smckusick struct vnode *a_vp;
66855022Smckusick } */ *ap;
66953842Spendry {
67053842Spendry struct vnode *targetvp = LOFSVP(ap->a_vp);
67155022Smckusick
67253842Spendry #ifdef DIAGNOSTIC
67353842Spendry { extern int prtactive;
67453842Spendry if (prtactive && ap->a_vp->v_usecount != 0)
67553842Spendry vprint("lofs_inactive: pushing active", ap->a_vp);
67653842Spendry }
67753842Spendry #endif
67853842Spendry
67953842Spendry if (targetvp) {
68053842Spendry vrele(targetvp);
68153842Spendry LOFSP(ap->a_vp)->a_lofsvp = 0;
68253842Spendry }
68353842Spendry }
68453842Spendry
68565518Spendry int
lofs_reclaim(ap)68655022Smckusick lofs_reclaim(ap)
68755022Smckusick struct vop_reclaim_args /* {
68855022Smckusick struct vnode *a_vp;
68955022Smckusick } */ *ap;
69053842Spendry {
69153842Spendry struct vnode *targetvp;
69255022Smckusick
69353842Spendry remque(LOFSP(ap->a_vp));
69453842Spendry targetvp = LOFSVP(ap->a_vp);
69553842Spendry if (targetvp) {
69653842Spendry printf("lofs: delayed vrele of %x\n", targetvp);
69753842Spendry vrele(targetvp); /* XXX should never happen */
69853842Spendry }
69953842Spendry FREE(ap->a_vp->v_data, M_TEMP);
70053842Spendry ap->a_vp->v_data = 0;
70153842Spendry return (0);
70253842Spendry }
70353842Spendry
70465518Spendry int
lofs_lock(ap)70555022Smckusick lofs_lock(ap)
70655022Smckusick struct vop_lock_args /* {
70755022Smckusick struct vnode *a_vp;
70855022Smckusick } */ *ap;
70953842Spendry {
71053842Spendry int error;
71156807Smckusick register struct vnode *vp = ap->a_vp;
71256807Smckusick struct vnode *targetvp;
71353842Spendry
71456807Smckusick while (vp->v_flag & VXLOCK) {
71556807Smckusick vp->v_flag |= VXWANT;
71656807Smckusick sleep((caddr_t)vp, PINOD);
71756807Smckusick }
71856807Smckusick if (vp->v_tag == VT_NON)
71956807Smckusick return (ENOENT);
72056807Smckusick targetvp = LOFSVP(ap->a_vp);
72156807Smckusick
72256807Smckusick if (targetvp && (error = VOP_LOCK(targetvp)))
72356807Smckusick return (error);
72453842Spendry return (0);
72553842Spendry }
72653842Spendry
72765518Spendry int
lofs_unlock(ap)72855022Smckusick lofs_unlock(ap)
72955022Smckusick struct vop_unlock_args /* {
73055022Smckusick struct vnode *a_vp;
73155022Smckusick } */ *ap;
73253842Spendry {
73353842Spendry struct vnode *targetvp = LOFSVP(ap->a_vp);
73453842Spendry
73553842Spendry if (targetvp)
73653842Spendry return (VOP_UNLOCK(targetvp));
73753842Spendry return (0);
73853842Spendry }
73953842Spendry
74065518Spendry int
lofs_bmap(ap)74155022Smckusick lofs_bmap(ap)
74255022Smckusick struct vop_bmap_args /* {
74355022Smckusick struct vnode *a_vp;
74455022Smckusick daddr_t a_bn;
74555022Smckusick struct vnode **a_vpp;
74655022Smckusick daddr_t *a_bnp;
74756455Smargo int *a_runp;
74855022Smckusick } */ *ap;
74953842Spendry {
75055022Smckusick
75165518Spendry return (VOP_BMAP(LOFSVP(ap->a_vp), ap->a_bn, ap->a_vpp, ap->a_bnp, ap->a_runp));
75253842Spendry }
75353842Spendry
75465518Spendry int
lofs_strategy(ap)75555022Smckusick lofs_strategy(ap)
75655022Smckusick struct vop_strategy_args /* {
75755022Smckusick struct buf *a_bp;
75855022Smckusick } */ *ap;
75953842Spendry {
76053842Spendry int error;
76153842Spendry
76253842Spendry PUSHREF(vp, ap->a_bp->b_vp);
76353842Spendry
76453842Spendry error = VOP_STRATEGY(ap->a_bp);
76553842Spendry
76653842Spendry POP(vp, ap->a_bp->b_vp);
76753842Spendry
76853842Spendry return (error);
76953842Spendry }
77053842Spendry
77165518Spendry int
lofs_print(ap)77255022Smckusick lofs_print(ap)
77355022Smckusick struct vop_print_args /* {
77455022Smckusick struct vnode *a_vp;
77555022Smckusick } */ *ap;
77653842Spendry {
77755022Smckusick
77853842Spendry struct vnode *targetvp = LOFSVP(ap->a_vp);
77953842Spendry printf("tag VT_LOFS ref ");
78053842Spendry if (targetvp)
78153842Spendry return (VOP_PRINT(targetvp));
78253842Spendry printf("NULLVP\n");
78353842Spendry return (0);
78453842Spendry }
78553842Spendry
78665518Spendry int
lofs_islocked(ap)78755022Smckusick lofs_islocked(ap)
78855022Smckusick struct vop_islocked_args /* {
78955022Smckusick struct vnode *a_vp;
79055022Smckusick } */ *ap;
79153842Spendry {
79255022Smckusick
79353842Spendry struct vnode *targetvp = LOFSVP(ap->a_vp);
79453842Spendry if (targetvp)
79553842Spendry return (VOP_ISLOCKED(targetvp));
79653842Spendry return (0);
79753842Spendry }
79853842Spendry
79965518Spendry int
lofs_pathconf(ap)80065743Spendry lofs_pathconf(ap)
80165743Spendry struct vop_pathconf_args *ap;
80265743Spendry {
80365743Spendry
80465743Spendry return (VOP_PATHCONF(LOFSVP(ap->a_vp), ap->a_name, ap->a_retval));
80565743Spendry }
80665743Spendry
80765743Spendry int
lofs_advlock(ap)80855022Smckusick lofs_advlock(ap)
80955022Smckusick struct vop_advlock_args /* {
81055022Smckusick struct vnode *a_vp;
81155022Smckusick caddr_t a_id;
81255022Smckusick int a_op;
81355022Smckusick struct flock *a_fl;
81455022Smckusick int a_flags;
81555022Smckusick } */ *ap;
81653842Spendry {
81755022Smckusick
81865518Spendry return (VOP_ADVLOCK(LOFSVP(ap->a_vp), ap->a_id, ap->a_op, ap->a_fl, ap->a_flags));
81953842Spendry }
82053842Spendry
82153842Spendry /*
82253842Spendry * LOFS directory offset lookup.
82353842Spendry * Currently unsupported.
82453842Spendry */
82565518Spendry int
lofs_blkatoff(ap)82655022Smckusick lofs_blkatoff(ap)
82755022Smckusick struct vop_blkatoff_args /* {
82855022Smckusick struct vnode *a_vp;
82955022Smckusick off_t a_offset;
83055022Smckusick char **a_res;
83155022Smckusick struct buf **a_bpp;
83255022Smckusick } */ *ap;
83353842Spendry {
83453842Spendry
83553842Spendry return (EOPNOTSUPP);
83653842Spendry }
83753842Spendry
83853842Spendry /*
83953842Spendry * LOFS flat namespace allocation.
84053842Spendry * Currently unsupported.
84153842Spendry */
84265518Spendry int
lofs_valloc(ap)84355022Smckusick lofs_valloc(ap)
84455022Smckusick struct vop_valloc_args /* {
84555022Smckusick struct vnode *a_pvp;
84655022Smckusick int a_mode;
84755022Smckusick struct ucred *a_cred;
84855022Smckusick struct vnode **a_vpp;
84955022Smckusick } */ *ap;
85053842Spendry {
85153842Spendry
85253842Spendry return (EOPNOTSUPP);
85353842Spendry }
85453842Spendry
85553842Spendry /*
85653842Spendry * LOFS flat namespace free.
85753842Spendry * Currently unsupported.
85853842Spendry */
85953842Spendry /*void*/
86065518Spendry int
lofs_vfree(ap)86155022Smckusick lofs_vfree(ap)
86255022Smckusick struct vop_vfree_args /* {
86355022Smckusick struct vnode *a_pvp;
86455022Smckusick ino_t a_ino;
86555022Smckusick int a_mode;
86655022Smckusick } */ *ap;
86753842Spendry {
86853842Spendry
86955022Smckusick return (0);
87053842Spendry }
87153842Spendry
87253842Spendry /*
87353842Spendry * LOFS file truncation.
87453842Spendry */
87565518Spendry int
lofs_truncate(ap)87655022Smckusick lofs_truncate(ap)
87755022Smckusick struct vop_truncate_args /* {
87855022Smckusick struct vnode *a_vp;
87955022Smckusick off_t a_length;
88055022Smckusick int a_flags;
88155022Smckusick struct ucred *a_cred;
88255022Smckusick struct proc *a_p;
88355022Smckusick } */ *ap;
88453842Spendry {
88553842Spendry
88653842Spendry /* Use lofs_setattr */
88753842Spendry printf("lofs_truncate: need to implement!!");
88853842Spendry return (EOPNOTSUPP);
88953842Spendry }
89053842Spendry
89153842Spendry /*
89253842Spendry * LOFS update.
89353842Spendry */
89465518Spendry int
lofs_update(ap)89555022Smckusick lofs_update(ap)
89655022Smckusick struct vop_update_args /* {
89755022Smckusick struct vnode *a_vp;
89855022Smckusick struct timeval *a_ta;
89955022Smckusick struct timeval *a_tm;
90055022Smckusick int a_waitfor;
90155022Smckusick } */ *ap;
90253842Spendry {
90353842Spendry
90453842Spendry /* Use lofs_setattr */
90553842Spendry printf("lofs_update: need to implement!!");
90653842Spendry return (EOPNOTSUPP);
90753842Spendry }
90853842Spendry
90953842Spendry /*
91053842Spendry * LOFS bwrite
91153842Spendry */
91265518Spendry int
lofs_bwrite(ap)91355022Smckusick lofs_bwrite(ap)
91455022Smckusick struct vop_bwrite_args /* {
91555022Smckusick struct buf *a_bp;
91655022Smckusick } */ *ap;
91753842Spendry {
91855022Smckusick
91953842Spendry return (EOPNOTSUPP);
92053842Spendry }
92153842Spendry
92253842Spendry /*
92353842Spendry * Global vfs data structures for ufs
92453842Spendry */
92553842Spendry int (**lofs_vnodeop_p)();
92653842Spendry struct vnodeopv_entry_desc lofs_vnodeop_entries[] = {
92753842Spendry { &vop_default_desc, vn_default_error },
92853842Spendry { &vop_lookup_desc, lofs_lookup }, /* lookup */
92953842Spendry { &vop_create_desc, lofs_create }, /* create */
93053842Spendry { &vop_mknod_desc, lofs_mknod }, /* mknod */
93165743Spendry { &vop_open_desc, lofs_open }, /* open */
93253842Spendry { &vop_close_desc, lofs_close }, /* close */
93353842Spendry { &vop_access_desc, lofs_access }, /* access */
93453842Spendry { &vop_getattr_desc, lofs_getattr }, /* getattr */
93553842Spendry { &vop_setattr_desc, lofs_setattr }, /* setattr */
93665743Spendry { &vop_read_desc, lofs_read }, /* read */
93753842Spendry { &vop_write_desc, lofs_write }, /* write */
93853842Spendry { &vop_ioctl_desc, lofs_ioctl }, /* ioctl */
93953842Spendry { &vop_select_desc, lofs_select }, /* select */
94065743Spendry { &vop_mmap_desc, lofs_mmap }, /* mmap */
94153842Spendry { &vop_fsync_desc, lofs_fsync }, /* fsync */
94265743Spendry { &vop_seek_desc, lofs_seek }, /* seek */
94353842Spendry { &vop_remove_desc, lofs_remove }, /* remove */
94465743Spendry { &vop_link_desc, lofs_link }, /* link */
94553842Spendry { &vop_rename_desc, lofs_rename }, /* rename */
94653842Spendry { &vop_mkdir_desc, lofs_mkdir }, /* mkdir */
94753842Spendry { &vop_rmdir_desc, lofs_rmdir }, /* rmdir */
94853842Spendry { &vop_symlink_desc, lofs_symlink }, /* symlink */
94953842Spendry { &vop_readdir_desc, lofs_readdir }, /* readdir */
95053842Spendry { &vop_readlink_desc, lofs_readlink }, /* readlink */
95153842Spendry { &vop_abortop_desc, lofs_abortop }, /* abortop */
95253842Spendry { &vop_inactive_desc, lofs_inactive }, /* inactive */
95353842Spendry { &vop_reclaim_desc, lofs_reclaim }, /* reclaim */
95465743Spendry { &vop_lock_desc, lofs_lock }, /* lock */
95553842Spendry { &vop_unlock_desc, lofs_unlock }, /* unlock */
95665743Spendry { &vop_bmap_desc, lofs_bmap }, /* bmap */
95753842Spendry { &vop_strategy_desc, lofs_strategy }, /* strategy */
95853842Spendry { &vop_print_desc, lofs_print }, /* print */
95953842Spendry { &vop_islocked_desc, lofs_islocked }, /* islocked */
96065743Spendry { &vop_pathconf_desc, lofs_pathconf }, /* pathconf */
96153842Spendry { &vop_advlock_desc, lofs_advlock }, /* advlock */
96253842Spendry { &vop_blkatoff_desc, lofs_blkatoff }, /* blkatoff */
96353842Spendry { &vop_valloc_desc, lofs_valloc }, /* valloc */
96453842Spendry { &vop_vfree_desc, lofs_vfree }, /* vfree */
96553842Spendry { &vop_truncate_desc, lofs_truncate }, /* truncate */
96653842Spendry { &vop_update_desc, lofs_update }, /* update */
96753842Spendry { &vop_bwrite_desc, lofs_bwrite }, /* bwrite */
96853842Spendry { (struct vnodeop_desc*)NULL, (int(*)())NULL }
96953842Spendry };
97053842Spendry struct vnodeopv_desc lofs_vnodeop_opv_desc =
97153842Spendry { &lofs_vnodeop_p, lofs_vnodeop_entries };
972