cache_inval
Richard Nyberg
rnyberg at it.su.se
Mon Nov 15 10:47:53 PST 2004
First of all: thanks for your excellent VFS work Matt!
That the kernel now only uses the new namecache API has
made things much simpler for me. My port of arla's nnpfs
is now working again.
cache_inval doesn't seem to perform as advertized.
I've inlined most of the function below and marked
the portions I'm a bit confused about.
[
/*
* Children are invalidated when the parent is destroyed. This
* basically disconnects the children from the parent. Anyone
* CD'd into a child will no longer be able to ".." back up.
*
* Any unresolved or negative cache-hit children with a ref count
* of 0 must be immediately and recursively destroyed or this
* disconnection may leave them dangling forever. XXX this recursion
* could run the kernel out of stack, the children should be placed
* on a to-destroy list instead.
*/
if (flags & CINV_CHILDREN) {
if ((kid = TAILQ_FIRST(&ncp->nc_list)) != NULL)
cache_hold(kid);
while (kid) {
if ((nextkid = TAILQ_NEXT(kid, nc_entry)) != NULL)
cache_hold(nextkid);
if (kid->nc_refs == 0 && ??? [1]
((kid->nc_flag & NCF_UNRESOLVED) ||
kid->nc_vp == NULL)
) {
cache_inval(kid, CINV_PARENT); ??? [2]
}
cache_unlink_parent(kid);
cache_drop(kid);
kid = nextkid;
}
}
]
??? [1]: Isn't kid->nc_refs always > 0 here? We have done a cache_hold on
the kid earlier in the code.
??? [2]: Shouldn't it be CINV_CHILDREN instead of CINV_PARENT?
The comments talk about recursing but it's really just
doing cache_unlink_parent(kid) which is done after anyway.
I'm using a similar function to cache_inval in nnpfs.
I recurse on children to set them to unresolved.
The reason for this is that I can get a message saying
that the contents of a directory has changed so
1) I don't want to unlink children that still exists and
2) I want to force reresolving so that unexisting children
isn't still in the cache.
Is it safe to do this? Except for the kernel stack issue :)
[
if ((kid = TAILQ_FIRST(&ncp->nc_list)) != NULL)
cache_hold(kid);
while (kid) {
if ((nextkid = TAILQ_NEXT(kid, nc_entry)) != NULL)
cache_hold(nextkid);
nnpfs_inval(kid, CINV_SELF|CINV_CHILDREN);
cache_drop(kid);
kid = nextkid;
}
]
Happy hacking!
-Richard
More information about the Kernel
mailing list