Messages in this thread | | | Date | Wed, 6 Jan 1999 14:46:30 -0500 (EST) | From | Alexander Viro <> | Subject | Re: dcache problems with vfat |
| |
On Tue, 5 Jan 1999, Linus Torvalds wrote:
> > > On Tue, 5 Jan 1999, Alexander Viro wrote: > > > > The first entry was dropped, right, but it still remains our cwd. > > So cd .. should get rid of it. Looks like it didn't. > > Right, and that sounds like a bug. A the last dput() of a non-hashed > dentry should make the dentry go away, and we _shouldn't_ have any inode > with a double count. > > I wonder if maybe vfat (or even the VFS layer) has a dentry count leak > somewhere, so that the "last" dput() doesn't actually see a d_count of > zero because something else forgot to decrement it..
OK, I've found it. It's caused by changes in d_invalidate(). Deatils: After touch a ../b we have the following picture:
- P 3 b H P 0 foo H P 2 <-- cwd a H P 0
Now we are doing cd /tmp/foo/a
cached_lookup() on foo gives
- P 3 b H P 0 foo H P 3 <-- cwd a H P 0
d_invalidate() calls shrink_dcache_parent(). Result being
- P 3 b H P 0 foo H P 2 <-- cwd
Now, old d_invalidate() would decide that it can't do d_drop() since d_count is greater than 1. New one drops it. Rest is trivial. We end up with the following:
- P 4 b H P 0 foo - P 1 <-- cwd foo H P 1 a H P 0
Now we do rm a and shit finally hits the fan: lookup on a gives us
- P 4 b H P 0 foo - P 2 <-- cwd a H P 1 foo H P 1 a H P 0
... and drop_replace_inodes along with d_delete() results in
- P 4 b H P 0 foo - P 2 <-- cwd a H N 0 foo H P 1 a - P 0
i.e. it unhashes dentry with zero d_count _and_ leaves it positive and leaves a new dentry hashed but negative.
cd .. simply does dput() on the unhashed dentry of foo. Nothing interesting - d_count remains positive. Attempt of rmdir doesn't even touch the sucker - lookup gets hashed version.
Summary: changes in d_invalidate() made in 2.1.132 are incorrect; we can't unhash the sucker if it can get children in the future. drop_replace_inodes() is *badly* broken since it doesn't check d_count on aliases. Old d_invalidate() somewhat masked it, but attempt to open something via the short name followed by unlink via long one would leave us with the interesting situation on hands.
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |