lkml.org 
[lkml]   [1999]   [Jan]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: 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/

\
 
 \ /
  Last update: 2005-03-22 13:49    [W:0.072 / U:0.112 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site