* 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).