All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] SUNRPC: PipeFS races fixes
@ 2013-06-10 14:39 Stanislav Kinsbursky
  2013-06-10 14:40 ` [PATCH 1/3] SUNRPC: fix races on PipeFS UMOUNT notifications Stanislav Kinsbursky
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Stanislav Kinsbursky @ 2013-06-10 14:39 UTC (permalink / raw)
  To: Trond.Myklebust; +Cc: linux-nfs, devel, linux-kernel, jlayton

This series fixed races between PipeFS mount/umount notification calls and
SUNRPC clients creation and destruction.

https://bugzilla.redhat.com/show_bug.cgi?id=924649

The following series implements...

---

Stanislav Kinsbursky (3):
      SUNRPC: fix races on PipeFS UMOUNT notifications
      SUNRPC: fix races on PipeFS UMOUNT notifications
      SUNRPC: PipeFS MOUNT notification optimization for dying clients


 net/sunrpc/clnt.c     |   14 +++++++++-----
 net/sunrpc/rpc_pipe.c |    5 ++++-
 2 files changed, 13 insertions(+), 6 deletions(-)


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

* [PATCH 1/3] SUNRPC: fix races on PipeFS UMOUNT notifications
  2013-06-10 14:39 [PATCH 0/3] SUNRPC: PipeFS races fixes Stanislav Kinsbursky
@ 2013-06-10 14:40 ` Stanislav Kinsbursky
  2013-06-10 14:40 ` [PATCH 2/3] " Stanislav Kinsbursky
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Stanislav Kinsbursky @ 2013-06-10 14:40 UTC (permalink / raw)
  To: Trond.Myklebust; +Cc: linux-nfs, devel, linux-kernel, jlayton

Below are races, when RPC client can be created without PiepFS dentries

CPU#0					CPU#1
-----------------------------		-----------------------------
rpc_new_client				rpc_fill_super
rpc_setup_pipedir
mutex_lock(&sn->pipefs_sb_lock)
rpc_get_sb_net == NULL
(no per-net PipeFS superblock)
					sn->pipefs_sb = sb;
					notifier_call_chain(MOUNT)
					(client is not in the list)
rpc_register_client
(client without pipes dentries)

To fix this patch:
1) makes PipeFS mount notification call with pipefs_sb_lock being held.
2) releases pipefs_sb_lock on new SUNRPC client creation only after
registration.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
Cc: stable@vger.kernel.org
---
 net/sunrpc/clnt.c     |    7 ++++++-
 net/sunrpc/rpc_pipe.c |    3 +++
 2 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 5a750b9..cf5b226 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -170,7 +170,10 @@ rpc_setup_pipedir(struct rpc_clnt *clnt, const char *dir_name)
 	if (!pipefs_sb)
 		return 0;
 	dentry = rpc_setup_pipedir_sb(pipefs_sb, clnt, dir_name);
-	rpc_put_sb_net(net);
+	/*
+	 * PipeFS superblock will be put after client registration to prevent
+	 * races with PipeFS mount call.
+	 */
 	if (IS_ERR(dentry))
 		return PTR_ERR(dentry);
 	clnt->cl_dentry = dentry;
@@ -369,11 +372,13 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru
 	/* save the nodename */
 	rpc_clnt_set_nodename(clnt, utsname()->nodename);
 	rpc_register_client(clnt);
+	rpc_put_sb_net(xprt->xprt_net);
 	return clnt;
 
 out_no_auth:
 	rpc_clnt_remove_pipedir(clnt);
 out_no_path:
+	rpc_put_sb_net(xprt->xprt_net);
 	kfree(clnt->cl_principal);
 out_no_principal:
 	rpc_free_iostats(clnt->cl_metrics);
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index e7ce4b3..c512448 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -1126,6 +1126,7 @@ rpc_fill_super(struct super_block *sb, void *data, int silent)
 		return -ENOMEM;
 	dprintk("RPC:       sending pipefs MOUNT notification for net %p%s\n",
 		net, NET_NAME(net));
+	mutex_lock(&sn->pipefs_sb_lock);
 	sn->pipefs_sb = sb;
 	err = blocking_notifier_call_chain(&rpc_pipefs_notifier_list,
 					   RPC_PIPEFS_MOUNT,
@@ -1133,6 +1134,7 @@ rpc_fill_super(struct super_block *sb, void *data, int silent)
 	if (err)
 		goto err_depopulate;
 	sb->s_fs_info = get_net(net);
+	mutex_unlock(&sn->pipefs_sb_lock);
 	return 0;
 
 err_depopulate:
@@ -1141,6 +1143,7 @@ err_depopulate:
 					   sb);
 	sn->pipefs_sb = NULL;
 	__rpc_depopulate(root, files, RPCAUTH_lockd, RPCAUTH_RootEOF);
+	mutex_unlock(&sn->pipefs_sb_lock);
 	return err;
 }
 


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

* [PATCH 2/3] SUNRPC: fix races on PipeFS UMOUNT notifications
  2013-06-10 14:39 [PATCH 0/3] SUNRPC: PipeFS races fixes Stanislav Kinsbursky
  2013-06-10 14:40 ` [PATCH 1/3] SUNRPC: fix races on PipeFS UMOUNT notifications Stanislav Kinsbursky
@ 2013-06-10 14:40 ` Stanislav Kinsbursky
  2013-06-10 14:40 ` [PATCH 3/3] SUNRPC: PipeFS MOUNT notification optimization for dying clients Stanislav Kinsbursky
  2013-06-10 14:41 ` [PATCH 0/3] SUNRPC: PipeFS races fixes Stanislav Kinsbursky
  3 siblings, 0 replies; 5+ messages in thread
From: Stanislav Kinsbursky @ 2013-06-10 14:40 UTC (permalink / raw)
  To: Trond.Myklebust; +Cc: linux-nfs, devel, linux-kernel, jlayton

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(-)

diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index cf5b226..3c133f2 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -244,8 +244,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;
 	}
@@ -262,7 +260,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;
 	}
@@ -642,8 +639,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..efca2f7 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -1165,7 +1165,6 @@ 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,
@@ -1173,6 +1172,7 @@ static void rpc_kill_sb(struct super_block *sb)
 					   sb);
 	put_net(net);
 out:
+	mutex_unlock(&sn->pipefs_sb_lock);
 	kill_litter_super(sb);
 }
 


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

* [PATCH 3/3] SUNRPC: PipeFS MOUNT notification optimization for dying clients
  2013-06-10 14:39 [PATCH 0/3] SUNRPC: PipeFS races fixes Stanislav Kinsbursky
  2013-06-10 14:40 ` [PATCH 1/3] SUNRPC: fix races on PipeFS UMOUNT notifications Stanislav Kinsbursky
  2013-06-10 14:40 ` [PATCH 2/3] " Stanislav Kinsbursky
@ 2013-06-10 14:40 ` Stanislav Kinsbursky
  2013-06-10 14:41 ` [PATCH 0/3] SUNRPC: PipeFS races fixes Stanislav Kinsbursky
  3 siblings, 0 replies; 5+ messages in thread
From: Stanislav Kinsbursky @ 2013-06-10 14:40 UTC (permalink / raw)
  To: Trond.Myklebust; +Cc: linux-nfs, devel, linux-kernel, jlayton

Not need to create pipes for dying client. So just skip them.

Note: we can safely dereference the client structure, because notification
caller is holding sn->pipefs_sb_lock.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
Cc: stable@vger.kernel.org
---
 net/sunrpc/clnt.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 3c133f2..fc4f4d1 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -185,6 +185,8 @@ static inline int rpc_clnt_skip_event(struct rpc_clnt *clnt, unsigned long event
 	if (((event == RPC_PIPEFS_MOUNT) && clnt->cl_dentry) ||
 	    ((event == RPC_PIPEFS_UMOUNT) && !clnt->cl_dentry))
 		return 1;
+	if ((event == RPC_PIPEFS_MOUNT) && atomic_read(&clnt->cl_count) == 0)
+		return 1;
 	return 0;
 }
 


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

* Re: [PATCH 0/3] SUNRPC: PipeFS races fixes
  2013-06-10 14:39 [PATCH 0/3] SUNRPC: PipeFS races fixes Stanislav Kinsbursky
                   ` (2 preceding siblings ...)
  2013-06-10 14:40 ` [PATCH 3/3] SUNRPC: PipeFS MOUNT notification optimization for dying clients Stanislav Kinsbursky
@ 2013-06-10 14:41 ` Stanislav Kinsbursky
  3 siblings, 0 replies; 5+ messages in thread
From: Stanislav Kinsbursky @ 2013-06-10 14:41 UTC (permalink / raw)
  To: Trond.Myklebust; +Cc: linux-nfs, devel, linux-kernel, jlayton

This series has flaws. Will fix and resend.
Sorry for noise.

10.06.2013 18:39, Stanislav Kinsbursky пишет:
> This series fixed races between PipeFS mount/umount notification calls and
> SUNRPC clients creation and destruction.
>
> https://bugzilla.redhat.com/show_bug.cgi?id=924649
>
> The following series implements...
>
> ---
>
> Stanislav Kinsbursky (3):
>        SUNRPC: fix races on PipeFS UMOUNT notifications
>        SUNRPC: fix races on PipeFS UMOUNT notifications
>        SUNRPC: PipeFS MOUNT notification optimization for dying clients
>
>
>   net/sunrpc/clnt.c     |   14 +++++++++-----
>   net/sunrpc/rpc_pipe.c |    5 ++++-
>   2 files changed, 13 insertions(+), 6 deletions(-)
>


-- 
Best regards,
Stanislav Kinsbursky

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

end of thread, other threads:[~2013-06-10 14:41 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-06-10 14:39 [PATCH 0/3] SUNRPC: PipeFS races fixes Stanislav Kinsbursky
2013-06-10 14:40 ` [PATCH 1/3] SUNRPC: fix races on PipeFS UMOUNT notifications Stanislav Kinsbursky
2013-06-10 14:40 ` [PATCH 2/3] " Stanislav Kinsbursky
2013-06-10 14:40 ` [PATCH 3/3] SUNRPC: PipeFS MOUNT notification optimization for dying clients Stanislav Kinsbursky
2013-06-10 14:41 ` [PATCH 0/3] SUNRPC: PipeFS races fixes Stanislav Kinsbursky

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.