DragonFly kernel List (threaded) for 2006-01
Re: nullfs stabilization I
: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
: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