Message ID | 1381869574-10662-2-git-send-email-bfields@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Tue, Oct 15, 2013 at 04:39:29PM -0400, J. Bruce Fields wrote: > From: "J. Bruce Fields" <bfields@redhat.com> > > Once we've found any connected parent, we know all our parents are > connected--that's true even if there's a concurrent rename. May as well > clear them all at once. > > Signed-off-by: J. Bruce Fields <bfields@redhat.com> Looks good, Reviewed-by: Christoph Hellwig <hch@lst.de> > if (!IS_ROOT(pd)) { > /* must have found a connected parent - great */ > - spin_lock(&pd->d_lock); > - pd->d_flags &= ~DCACHE_DISCONNECTED; > - spin_unlock(&pd->d_lock); > + clear_disconnected(target_dir); > noprogress = 0; > } else if (pd == mnt->mnt_sb->s_root) { > printk(KERN_ERR "export: Eeek filesystem root is not connected, impossible\n"); You might as well throw a patch in to make this condition a BUG_ON, it would indicate a nasty bug in the dcache and has never triggered in the last 10 years as far as I know. -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Wed, Oct 16, 2013 at 12:13:43AM -0700, Christoph Hellwig wrote: > On Tue, Oct 15, 2013 at 04:39:29PM -0400, J. Bruce Fields wrote: > > From: "J. Bruce Fields" <bfields@redhat.com> > > > > Once we've found any connected parent, we know all our parents are > > connected--that's true even if there's a concurrent rename. May as well > > clear them all at once. > > > > Signed-off-by: J. Bruce Fields <bfields@redhat.com> > > Looks good, > > Reviewed-by: Christoph Hellwig <hch@lst.de> > > > if (!IS_ROOT(pd)) { > > /* must have found a connected parent - great */ > > - spin_lock(&pd->d_lock); > > - pd->d_flags &= ~DCACHE_DISCONNECTED; > > - spin_unlock(&pd->d_lock); > > + clear_disconnected(target_dir); > > noprogress = 0; > > } else if (pd == mnt->mnt_sb->s_root) { > > printk(KERN_ERR "export: Eeek filesystem root is not connected, impossible\n"); > > You might as well throw a patch in to make this condition a BUG_ON, it > would indicate a nasty bug in the dcache and has never triggered in the > last 10 years as far as I know. We've seen some ugly crashes made uglier by unnecessary BUG()s. I guess that wouldn't be the case here as we're not holding any critical locks and all we're going to kill is an nfsd thread or open_by_handle caller. And like you say it's a very unlikely case anyway. So, OK, I'll turn this case into a BUG_ON in a separate patch. --b. -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c index c43fe9b..455b0bb 100644 --- a/fs/exportfs/expfs.c +++ b/fs/exportfs/expfs.c @@ -90,6 +90,22 @@ find_disconnected_root(struct dentry *dentry) return dentry; } +static void clear_disconnected(struct dentry *dentry) +{ + dget(dentry); + while (dentry->d_flags & DCACHE_DISCONNECTED) { + struct dentry *parent = dget_parent(dentry); + + spin_lock(&dentry->d_lock); + dentry->d_flags &= ~DCACHE_DISCONNECTED; + spin_unlock(&dentry->d_lock); + + dput(dentry); + dentry = parent; + } + dput(dentry); +} + /* * Make sure target_dir is fully connected to the dentry tree. * @@ -114,15 +130,11 @@ reconnect_path(struct vfsmount *mnt, struct dentry *target_dir, char *nbuf) if (!IS_ROOT(pd)) { /* must have found a connected parent - great */ - spin_lock(&pd->d_lock); - pd->d_flags &= ~DCACHE_DISCONNECTED; - spin_unlock(&pd->d_lock); + clear_disconnected(target_dir); noprogress = 0; } else if (pd == mnt->mnt_sb->s_root) { printk(KERN_ERR "export: Eeek filesystem root is not connected, impossible\n"); - spin_lock(&pd->d_lock); - pd->d_flags &= ~DCACHE_DISCONNECTED; - spin_unlock(&pd->d_lock); + clear_disconnected(target_dir); noprogress = 0; } else { /*