linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: opendir() returns valid DIR* pointer even in case when that directory no longer exists - it has (just) been removed
       [not found]                 ` <524f69650901130906g6c00c14agb0f224a20b7f0f8b@mail.gmail.com>
@ 2009-01-13 18:33                   ` Steve French
  2009-01-14  3:03                     ` [linux-cifs-client] " Günter Kukkukk
  0 siblings, 1 reply; 2+ messages in thread
From: Steve French @ 2009-01-13 18:33 UTC (permalink / raw)
  To: Jeff Layton
  Cc: Günter Kukkukk, linux-cifs-client@lists.samba.org,
	linux-fsdevel

On Thu, Jan 8, 2009 at 8:40 PM, Günter Kukkukk <linux@kukkukk.com> wrote:
> Hi Steve, Jeff,
>
> got the following failure notification on irc #samba:
>
> A user was updating from subversion 1.4 to 1.5, where the
> repository is located on a samba share (independent of
> unix extensions = Yes or No).
> svn 1.4 did work, 1.5 does not.
>
> The user did a lot of stracing of subversion - and wrote a
> testapplet to simulate the failing behaviour.
> I've converted the C++ source to C and added some error cases.
>
> When using "./testdir" on a local file system, "result2"
> is always (nil) as expected - cifs vfs behaves different here!
>
>   ./testdir /mnt/cifs/mounted/share
>
> returns a (failing) valid pointer.
>
> Some shell scripting:
> for a in a b c d e f g h i;
> do ./testdir /mnt/cifs/mounted/share; done
>
> and
> for a in a b c d e f g h i;
> do ./testdir /mnt/cifs/mounted/share; sleep 1; done
>
> show different results too ...

The cause of the problem turned out to be stranger than I expected.
The sequence of events is:
1) cifs_rmdir sets the number of links to zero (probably doesn't need
to do both drop_nlink and clear_nlink though, just the clear should be
good enough)

2) rmdir sets the inode's time to zero which would force revalidate to
go over the network if someone tried a lookup on that, but svn was
redoing the getdents before the lookup

3) the app does a getdents on the parent directory, finding an
existing pending search so it uses those cached results and recreates
the dentry/inode for "magic_dir" from the stale results
4) lookup finds the newly created magic_dir's inode and since it was
recently created (inode time is not zero) ... uses it for up to a
second


In the cifs_unlink case we already reset the time on the parent
directory which avoids this problem, but we don't for rmdir (see fix
below) - this should fix the problem

diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 5ab9896..da70a54 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -1285,6 +1285,11 @@ int cifs_rmdir(struct inode *inode, struct
dentry *direntry)
        cifsInode = CIFS_I(direntry->d_inode);
        cifsInode->time = 0;    /* force revalidate to go get info when
                                   needed */
+       cifsInode = CIFS_I(inode);
+       cifsInode->time = 0;    /* force revalidate to go get info
+                                  on parent directory since link count
+                                  changed and search buffer can no longer
+                                  be cached */
        direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime =
                current_fs_time(inode->i_sb);

I wonder if this also would fix the cleanup problem we saw in some
versions of dbench

Gunter,
Thanks - good job on those traces and test case (which made it much
easier to debug).

-- 
Thanks,

Steve
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [linux-cifs-client] Re: opendir() returns valid DIR* pointer even in case when that directory no longer exists - it has (just) been removed
  2009-01-13 18:33                   ` opendir() returns valid DIR* pointer even in case when that directory no longer exists - it has (just) been removed Steve French
@ 2009-01-14  3:03                     ` Günter Kukkukk
  0 siblings, 0 replies; 2+ messages in thread
From: Günter Kukkukk @ 2009-01-14  3:03 UTC (permalink / raw)
  To: linux-cifs-client; +Cc: Steve French, Jeff Layton, linux-fsdevel

Am Dienstag, 13. Januar 2009 schrieb Steve French:
> On Thu, Jan 8, 2009 at 8:40 PM, Günter Kukkukk <linux@kukkukk.com> wrote:
> > Hi Steve, Jeff,
> >
> > got the following failure notification on irc #samba:
> >
> > A user was updating from subversion 1.4 to 1.5, where the
> > repository is located on a samba share (independent of
> > unix extensions = Yes or No).
> > svn 1.4 did work, 1.5 does not.
> >
> > The user did a lot of stracing of subversion - and wrote a
> > testapplet to simulate the failing behaviour.
> > I've converted the C++ source to C and added some error cases.
> >
> > When using "./testdir" on a local file system, "result2"
> > is always (nil) as expected - cifs vfs behaves different here!
> >
> >   ./testdir /mnt/cifs/mounted/share
> >
> > returns a (failing) valid pointer.
> >
> > Some shell scripting:
> > for a in a b c d e f g h i;
> > do ./testdir /mnt/cifs/mounted/share; done
> >
> > and
> > for a in a b c d e f g h i;
> > do ./testdir /mnt/cifs/mounted/share; sleep 1; done
> >
> > show different results too ...
> 
> The cause of the problem turned out to be stranger than I expected.
> The sequence of events is:
> 1) cifs_rmdir sets the number of links to zero (probably doesn't need
> to do both drop_nlink and clear_nlink though, just the clear should be
> good enough)
> 
> 2) rmdir sets the inode's time to zero which would force revalidate to
> go over the network if someone tried a lookup on that, but svn was
> redoing the getdents before the lookup
> 
> 3) the app does a getdents on the parent directory, finding an
> existing pending search so it uses those cached results and recreates
> the dentry/inode for "magic_dir" from the stale results
> 4) lookup finds the newly created magic_dir's inode and since it was
> recently created (inode time is not zero) ... uses it for up to a
> second
> 
> 
> In the cifs_unlink case we already reset the time on the parent
> directory which avoids this problem, but we don't for rmdir (see fix
> below) - this should fix the problem
> 
> diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
> index 5ab9896..da70a54 100644
> --- a/fs/cifs/inode.c
> +++ b/fs/cifs/inode.c
> @@ -1285,6 +1285,11 @@ int cifs_rmdir(struct inode *inode, struct
> dentry *direntry)
>         cifsInode = CIFS_I(direntry->d_inode);
>         cifsInode->time = 0;    /* force revalidate to go get info when
>                                    needed */
> +       cifsInode = CIFS_I(inode);
> +       cifsInode->time = 0;    /* force revalidate to go get info
> +                                  on parent directory since link count
> +                                  changed and search buffer can no longer
> +                                  be cached */
>         direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime =
>                 current_fs_time(inode->i_sb);
> 
> I wonder if this also would fix the cleanup problem we saw in some
> versions of dbench
> 
> Gunter,
> Thanks - good job on those traces and test case (which made it much
> easier to debug).
> 

Hi Steve,
your patch works here on kernels
  - 2.6.22.18-0.2-default
  - 2.6.28
it seems to be an outstanding one, which is fixed now. :-)

I've send your patch to the bug reporter (to build a new cifs vfs
module...) - till now no response whether subversion 1.5 is failing
or not.
I'm sure the bug is fixed...
Cheers,  Günter
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2009-01-14  3:06 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <200901090340.44200.linux@kukkukk.com>
     [not found] ` <524f69650901081933j518465b7g130a7f01ebdceff0@mail.gmail.com>
     [not found]   ` <200901100129.32470.linux@kukkukk.com>
     [not found]     ` <524f69650901101013q3ce5e727ye830cef83901ca37@mail.gmail.com>
     [not found]       ` <524f69650901121204v63fb4b84q151a27479109c647@mail.gmail.com>
     [not found]         ` <20090112151335.0e00c74e@tleilax.poochiereds.net>
     [not found]           ` <524f69650901121223h6d068e07r86f0694bf8d6c1a8@mail.gmail.com>
     [not found]             ` <524f69650901121231s3c5608bex7834d645d21d3627@mail.gmail.com>
     [not found]               ` <524f69650901122000i7f4b85fu3b0d5fa43d322efc@mail.gmail.com>
     [not found]                 ` <524f69650901130906g6c00c14agb0f224a20b7f0f8b@mail.gmail.com>
2009-01-13 18:33                   ` opendir() returns valid DIR* pointer even in case when that directory no longer exists - it has (just) been removed Steve French
2009-01-14  3:03                     ` [linux-cifs-client] " Günter Kukkukk

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).