Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 23 Dec 2011 09:23:16 -0500
From:      John Baldwin <jhb@freebsd.org>
To:        "Robert N. M. Watson" <rwatson@freebsd.org>
Cc:        arch@freebsd.org
Subject:   Re: Post NOTE_ATTRIB EVFILT_VNODE events for extattr changes
Message-ID:  <201112230923.16333.jhb@freebsd.org>
In-Reply-To: <E6AD9F35-90F2-466F-89A2-587E0C1309FF@freebsd.org>
References:  <201112221105.31746.jhb@freebsd.org> <E6AD9F35-90F2-466F-89A2-587E0C1309FF@freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Thursday, December 22, 2011 6:19:27 pm Robert N. M. Watson wrote:
> 
> On 22 Dec 2011, at 16:05, John Baldwin wrote:
> 
> > A co-worker noticed that there is currently no way to get an EVFILT_VNODE 
> > notification if the extended attributes for a given file change.  I looked at 
> > OS X and found that it posts a NOTE_ATTRIB event (typically used for 
> > VOP_SETATTR()) for successful attempts to set or delete an extended attribute.  
> > I have a patch to do the same along with a test application for both OS X and 
> > FreeBSD.  With this patch FreeBSD now has the same behavior as OS X.
> 
> This seems reasonable to me, although I've not tested the patch you attached myself.
> 
> I'm not familiar with the pre/post-vop hook mechanism, but I assume that this will fire when internal extended attribute I/O, for example 
triggered by ACL changes, occurs?

The hooks fire anytime VOP_SETEXTATTR() or VOP_DELETEEXTATTR() are called.  What
happens is that calls to the hooks are inserted into the macro functions generated
in vnode_if.c, for example:

int
VOP_SETEXTATTR_APV(struct vop_vector *vop, struct vop_setextattr_args *a)
{
        int rc;

        VNASSERT(a->a_gen.a_desc == &vop_setextattr_desc, a->a_vp,
            ("Wrong a_desc in vop_setextattr(%p, %p)", a->a_vp, a));
        while(vop != NULL && \
            vop->vop_setextattr == NULL && vop->vop_bypass == NULL)
                vop = vop->vop_default;
        VNASSERT(vop != NULL, a->a_vp, ("No vop_setextattr(%p, %p)", a->a_vp, a));
        SDT_PROBE(vfs, vop, vop_setextattr, entry, a->a_vp, a, 0, 0, 0);

        ASSERT_VI_UNLOCKED(a->a_vp, "VOP_SETEXTATTR");
        ASSERT_VOP_ELOCKED(a->a_vp, "VOP_SETEXTATTR");
        if (vop->vop_setextattr != NULL)
                rc = vop->vop_setextattr(a);
        else
                rc = vop->vop_bypass(&a->a_gen);
        CTR6(KTR_VOP,
            "VOP_SETEXTATTR(vp 0x%lX, attrnamespace %ld, name 0x%lX, uio 0x%lX, cred 0x%lX, td 0x%lX)",
            a->a_vp, a->a_attrnamespace, a->a_name, a->a_uio, a->a_cred, a->a_td);
        SDT_PROBE(vfs, vop, vop_setextattr, return, a->a_vp, a, rc, 0, 0);

        if (rc == 0) {
                ASSERT_VI_UNLOCKED(a->a_vp, "VOP_SETEXTATTR");
                ASSERT_VOP_ELOCKED(a->a_vp, "VOP_SETEXTATTR");
        } else {
                ASSERT_VI_UNLOCKED(a->a_vp, "VOP_SETEXTATTR");
                ASSERT_VOP_ELOCKED(a->a_vp, "VOP_SETEXTATTR");
        }
        vop_setextattr_post(a, rc);
        return (rc);
}

Thus, if the ACL code uses VOP_SETEXTATTR() and VOP_DELETEEXTATTR() then it
will trigger this, yes.  Checking UFS, it's ACL VOPs use vn_extattr_rm() and
vn_extattr_set() which are wrappers around the the EA VOP's, so toggling
ACL's will trigger NOTE_ATTRIB on UFS.  I'm not sure if it is worth it to
fire an explicit event for VOP_SETACL() as well.  OS X does not appear to
have a VOP_SETACL() that I can see (they just assume ACL's are always stored
as EA's at the vnode layer), so I can't use that as a model.

-- 
John Baldwin



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201112230923.16333.jhb>