Message ID | 20130626061448.32202.192.stgit@localhost.localdomain (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Wed, Jun 26, 2013 at 8:15 AM, Stanislav Kinsbursky <skinsbursky@parallels.com> wrote: > diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c > index b827a4b..41f180c 100644 > --- a/net/sunrpc/clnt.c > +++ b/net/sunrpc/clnt.c > @@ -236,8 +236,6 @@ static struct rpc_clnt *rpc_get_client_for_event(struct net *net, int event) > continue; > if (rpc_clnt_skip_event(clnt, event)) > continue; > - if (atomic_inc_not_zero(&clnt->cl_count) == 0) > - continue; > spin_unlock(&sn->rpc_client_lock); > return clnt; > } > @@ -254,7 +252,6 @@ static int rpc_pipefs_event(struct notifier_block *nb, unsigned long event, > > while ((clnt = rpc_get_client_for_event(sb->s_fs_info, event))) { > error = __rpc_pipefs_event(clnt, event, sb); > - rpc_release_client(clnt); > if (error) > break; > } > @@ -641,8 +638,8 @@ rpc_free_client(struct rpc_clnt *clnt) > rcu_dereference(clnt->cl_xprt)->servername); > if (clnt->cl_parent != clnt) > rpc_release_client(clnt->cl_parent); > - rpc_unregister_client(clnt); > rpc_clnt_remove_pipedir(clnt); > + rpc_unregister_client(clnt); > rpc_free_iostats(clnt->cl_metrics); > kfree(clnt->cl_principal); > clnt->cl_metrics = NULL; > diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c > index c512448..9b4ec5b 100644 > --- a/net/sunrpc/rpc_pipe.c > +++ b/net/sunrpc/rpc_pipe.c > @@ -1165,12 +1165,12 @@ static void rpc_kill_sb(struct super_block *sb) > goto out; > } > sn->pipefs_sb = NULL; > - mutex_unlock(&sn->pipefs_sb_lock); > dprintk("RPC: sending pipefs UMOUNT notification for net %p%s\n", > net, NET_NAME(net)); > blocking_notifier_call_chain(&rpc_pipefs_notifier_list, > RPC_PIPEFS_UMOUNT, > sb); > + mutex_unlock(&sn->pipefs_sb_lock); > put_net(net); > out: > kill_litter_super(sb); are these patches validated? any chance to see them in tree soon? I wasn't able to find them on http://git.linux-nfs.org/?p=trondmy/linux-nfs.git Thanks, -- William -- 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/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index b827a4b..41f180c 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -236,8 +236,6 @@ static struct rpc_clnt *rpc_get_client_for_event(struct net *net, int event) continue; if (rpc_clnt_skip_event(clnt, event)) continue; - if (atomic_inc_not_zero(&clnt->cl_count) == 0) - continue; spin_unlock(&sn->rpc_client_lock); return clnt; } @@ -254,7 +252,6 @@ static int rpc_pipefs_event(struct notifier_block *nb, unsigned long event, while ((clnt = rpc_get_client_for_event(sb->s_fs_info, event))) { error = __rpc_pipefs_event(clnt, event, sb); - rpc_release_client(clnt); if (error) break; } @@ -641,8 +638,8 @@ rpc_free_client(struct rpc_clnt *clnt) rcu_dereference(clnt->cl_xprt)->servername); if (clnt->cl_parent != clnt) rpc_release_client(clnt->cl_parent); - rpc_unregister_client(clnt); rpc_clnt_remove_pipedir(clnt); + rpc_unregister_client(clnt); rpc_free_iostats(clnt->cl_metrics); kfree(clnt->cl_principal); clnt->cl_metrics = NULL; diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index c512448..9b4ec5b 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c @@ -1165,12 +1165,12 @@ static void rpc_kill_sb(struct super_block *sb) goto out; } sn->pipefs_sb = NULL; - mutex_unlock(&sn->pipefs_sb_lock); dprintk("RPC: sending pipefs UMOUNT notification for net %p%s\n", net, NET_NAME(net)); blocking_notifier_call_chain(&rpc_pipefs_notifier_list, RPC_PIPEFS_UMOUNT, sb); + mutex_unlock(&sn->pipefs_sb_lock); put_net(net); out: kill_litter_super(sb);
CPU#0 CPU#1 ----------------------------- ----------------------------- rpc_kill_sb sn->pipefs_sb = NULL rpc_release_client (UMOUNT_EVENT) rpc_free_auth rpc_pipefs_event rpc_get_client_for_event !atomic_inc_not_zero(cl_count) <skip the client> atomic_inc(cl_count) rpc_free_client rpc_clnt_remove_pipedir <skip client dir removing> To fix this, this patch does the following: 1) Calls RPC_PIPEFS_UMOUNT notification with sn->pipefs_sb_lock being held. 2) Removes SUNRPC client from the list AFTER pipes destroying. 3) Doesn't hold RPC client on notification: if client in the list, then it can't be destroyed while sn->pipefs_sb_lock in hold by notification caller. Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com> Cc: stable@vger.kernel.org --- net/sunrpc/clnt.c | 5 +---- net/sunrpc/rpc_pipe.c | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) -- 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