DragonFly BSD
DragonFly kernel List (threaded) for 2004-11
[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]

cache_inval


From: Richard Nyberg <rnyberg@xxxxxxxx>
Date: Mon, 15 Nov 2004 19:47:53 +0100

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




[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]