nullfs stabilization I

Matthew Dillon dillon at
Thu Jan 12 10:48:13 PST 2006

:So, that's what I've been meditating on recently.
:Say we want our upper f_oo entry to shadow Foo which doens'nt yet exist.
:As you suggest, the event chain is as follows, IIRC:
: * Userspace asks for f_oo (open("f_oo", O_CREAT | ...)).
: * f_oo namecache entry gets locked, but we also want to lock the lower one
:   for the sake of coherency.
: * Alas, cache layer can't divine whom to lock down there, hence calls into
:   the vfs to dig up that entry.
: ...
:but why not:
: * Userspace asks for f_oo.
: * With f_oo namecache entry locked, our vfs is asked to resolve it;
:   at this stage the the cache layer doesn't know of shadowing.
: * 
:   a) The vfs does know that it wants to shadow Foo. Now if the vfs would start
:   to resolve in the wild, then locking is not present in the lower layer and
:   the bad guys can sneak in. So it performs a cache layer callback
:   (cache_getshadow("Foo", ...) ?), which would inform the cache layer
:   about the shadowing intent.
:|  b) After returning from the callback, the vfs could do the resolution as it
:|  feels like, happily ignorant of ncp locking issues as ever.
:`* Under the hood the cache layer gets the post about shadowing intent.
:   It locks down Foo, and ensures coherency before giving the control back to
:   the vfs.
:   ...
:The usual, "core" part of the resolution would take place with all
:relevant parties having their respective locks set up, since it would
:happen in stage b). The difference from your scheme is that the callback would
:go from the vfs to the cache layer, not from the cache layer to the vfs
:(so then it would be a systemwide function, not just a locally
:available/relevant method).
:Do you think it would be feasible?

    Let me suggest an alternative approach.  The real problem here is
    always going to be locking of the namecache record(s).  The creation
    aspect of the namecache record(s) (the shadow chain) is trivial since
    an upper layer can simply do the translation and ask for the lower
    layer.  In the absense of locking, we do not have any deadlock issues
    with this approach.  The code would also be more readable.

    So perhaps the solution here is to create an auxillary locking structure
    that all related namecache records can share.  This locking structure
    would serve to 'glue' the namecache records in the chain together.

    Although I didn't want do it, from a coding perspective we can make
    this glue sticky... that is, we can disallow the destruction of 
    a lower layer namecache record while a higher layer namecache record
    in the same chain exists.  This would remove the requirement that
    lower layers do callbacks to upper layers.

    If the chain shares the same locking structure, now we no longer have
    to recurse to lock the upper layer namecache.  We just lock it and
    the entire chain gets locked by virtue of sharing the same locking

					Matthew Dillon 
					<dillon at xxxxxxxxxxxxx>

More information about the Kernel mailing list