From 3f491ba7c19017f58f79fe37cce8717d3b2de176 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 4 Mar 2011 14:39:30 -0500 Subject: [PATCH] --- yaml --- r: 234256 b: refs/heads/master c: a7472baba22dd5d68580f528374f93421b33667e h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/fs/namei.c | 16 +++++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/[refs] b/[refs] index 4badbb55a6a3..001b66035f3b 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: ef7562d5283a91da3ba5c14de3221f47b7f08823 +refs/heads/master: a7472baba22dd5d68580f528374f93421b33667e diff --git a/trunk/fs/namei.c b/trunk/fs/namei.c index ea14bfb04785..53bba7c1a520 100644 --- a/trunk/fs/namei.c +++ b/trunk/fs/namei.c @@ -498,8 +498,15 @@ static int nameidata_dentry_drop_rcu(struct nameidata *nd, struct dentry *dentry /* Try to drop out of rcu-walk mode if we were in it, otherwise do nothing. */ static inline int nameidata_dentry_drop_rcu_maybe(struct nameidata *nd, struct dentry *dentry) { - if (nd->flags & LOOKUP_RCU) - return nameidata_dentry_drop_rcu(nd, dentry); + if (nd->flags & LOOKUP_RCU) { + if (unlikely(nameidata_dentry_drop_rcu(nd, dentry))) { + nd->flags &= ~LOOKUP_RCU; + nd->root.mnt = NULL; + rcu_read_unlock(); + br_read_unlock(vfsmount_lock); + return -ECHILD; + } + } return 0; } @@ -1424,7 +1431,7 @@ static int link_path_walk(const char *name, struct nameidata *nd) if (inode && inode->i_op->follow_link) { err = do_follow_link(inode, &next, nd); if (err) - goto return_err; + return err; nd->inode = nd->path.dentry->d_inode; } else { path_to_nameidata(&next, nd); @@ -1455,7 +1462,7 @@ static int link_path_walk(const char *name, struct nameidata *nd) (lookup_flags & LOOKUP_FOLLOW)) { err = do_follow_link(inode, &next, nd); if (err) - goto return_err; + return err; nd->inode = nd->path.dentry->d_inode; } else { path_to_nameidata(&next, nd); @@ -1477,7 +1484,6 @@ static int link_path_walk(const char *name, struct nameidata *nd) } if (!(nd->flags & LOOKUP_RCU)) path_put(&nd->path); -return_err: if (nd->flags & LOOKUP_RCU) { nd->flags &= ~LOOKUP_RCU; nd->root.mnt = NULL;