commit 5bda7fa0e4cc083376f748e4d8a6778727fb0596 Author: Mikolaj Golub Date: Sat Oct 15 14:41:56 2011 +0300 For lookup and create operations on VSOCK vnodes return the lower layer vnode so the socket is bind to it and the socket is accessible from both lower and upper fs. It makes unix sockets created on the lower fs be accessible from the upper fs. The only known issue with this approach is that as the upper vnode is not reference counted unmount will not return EBUSY if the socket is still opened. diff --git a/sys/fs/nullfs/null_vnops.c b/sys/fs/nullfs/null_vnops.c index 30a38da..74c50ad 100644 --- a/sys/fs/nullfs/null_vnops.c +++ b/sys/fs/nullfs/null_vnops.c @@ -364,17 +364,62 @@ null_lookup(struct vop_lookup_args *ap) VREF(dvp); vrele(lvp); } else { - error = null_nodeget(dvp->v_mount, lvp, &vp); - if (error) - vput(lvp); - else - *ap->a_vpp = vp; + if (lvp->v_type == VSOCK) { + /* + * For a socket vnode we shold provide access to + * the socket via v_un. We return the lower + * vnode so the socket is bind to it and the + * socket is accessible from both lower and + * upper fs. + * + * The only known issue with this approach is + * that as the upper vnode is not reference + * counted unmount will not return EBUSY if the + * socket is still opened. + */ + *ap->a_vpp = lvp; + } else { + error = null_nodeget(dvp->v_mount, lvp, &vp); + if (error) + vput(lvp); + else + *ap->a_vpp = vp; + } } } return (error); } static int +null_create(struct vop_create_args *ap) +{ + struct componentname *cnp = ap->a_cnp; + struct vattr *vap = ap->a_vap; + struct vnode *dvp = ap->a_dvp; + struct vnode *lvp, *ldvp; + int error; + + if (vap->va_type == VSOCK) { + /* + * See the note in null_lookup() about VSOCK. + */ + ldvp = NULLVPTOLOWERVP(dvp); + lvp = NULL; + error = VOP_CREATE(ldvp, &lvp, cnp, vap); + if (error == EJUSTRETURN && + (dvp->v_mount->mnt_flag & MNT_RDONLY)) + error = EROFS; + + if ((error == 0 || error == EJUSTRETURN) && lvp != NULL) + *ap->a_vpp = lvp; + } else { + error = null_bypass(&ap->a_gen); + } + + return (error); +} + +static int null_open(struct vop_open_args *ap) { int retval; @@ -826,6 +871,7 @@ struct vop_vector null_vnodeops = { .vop_accessx = null_accessx, .vop_advlockpurge = vop_stdadvlockpurge, .vop_bmap = VOP_EOPNOTSUPP, + .vop_create = null_create, .vop_getattr = null_getattr, .vop_getwritemount = null_getwritemount, .vop_inactive = null_inactive,