From: Chuck Lever <chuck.lever@oracle.com>
To: trond.myklebust@netapp.com
Cc: linux-nfs@vger.kernel.org
Subject: [PATCH 3/5] SUNRPC: Prepare gss_pipes_dentries_create() for sharing pipe data
Date: Mon, 13 Aug 2012 17:21:51 -0400 [thread overview]
Message-ID: <20120813212150.1680.96757.stgit@degas.1015granger.net> (raw)
In-Reply-To: <20120813210739.1680.53741.stgit@degas.1015granger.net>
We are about to make pipe data shareable. gss_pipes_dentries_create()
and gss_pipes_dentries_destroy() have to be more careful when dealing
with their dentry pointers. Namely:
1. When asked to create a dentry, don't write over possibly valid
pointers, but instead preserve an existing dentry
2. When unlinking a dentry, make sure the ->dentry pointer is NULL
3. If creating a dentry fails, don't leak the ERR_PTR value, make
sure the ->dentry pointer is NULL
2. and 3. are needed so that 1. can recognize when a new dentry
should be created.
This is clean up, mostly. But it's necessary because unmounting a
pipe FS can cause pipe dentries, but not the pipe data, to be
released (via ->pipes_destroy).
The functions that manage pipe data for gss_create() have to be
prepared for finding an existing shared rpc_pipe_data object that
has a dentry, or doesn't, and then do the correct thing in either
case.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Acked-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
---
net/sunrpc/auth_gss/auth_gss.c | 67 +++++++++++++++++++++++++++++-----------
1 files changed, 49 insertions(+), 18 deletions(-)
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index 909dc0c..947ab01 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -757,42 +757,73 @@ gss_pipe_destroy_msg(struct rpc_pipe_msg *msg)
}
}
+static void gss_pipe_dentry_destroy(struct rpc_pipe *pipe)
+{
+ if (pipe->dentry != NULL) {
+ rpc_unlink(pipe->dentry);
+ pipe->dentry = NULL;
+ }
+}
+
+/*
+ * Release existing pipe dentries, but leave the rpc_pipe data
+ * ready to receive fresh dentries if subsequently needed.
+ */
static void gss_pipes_dentries_destroy(struct rpc_auth *auth)
{
struct gss_auth *gss_auth;
gss_auth = container_of(auth, struct gss_auth, rpc_auth);
- if (gss_auth->pipe[0]->dentry)
- rpc_unlink(gss_auth->pipe[0]->dentry);
- if (gss_auth->pipe[1]->dentry)
- rpc_unlink(gss_auth->pipe[1]->dentry);
+
+ dprintk("RPC: %s auth=%p, clnt=%p\n",
+ __func__, auth, gss_auth->client);
+
+ gss_pipe_dentry_destroy(gss_auth->pipe[0]);
+ gss_pipe_dentry_destroy(gss_auth->pipe[1]);
}
+/*
+ * On success, zero is returned and both elements of the rpc_pipe
+ * array are populated with valid dentries. Otherwise an error value
+ * is returned, the dentries are freed, and both ->dentry pointers are
+ * set to NULL.
+ */
static int gss_pipes_dentries_create(struct rpc_auth *auth)
{
- int err;
+ int err = 0;
struct gss_auth *gss_auth;
struct rpc_clnt *clnt;
gss_auth = container_of(auth, struct gss_auth, rpc_auth);
clnt = gss_auth->client;
- gss_auth->pipe[1]->dentry = rpc_mkpipe_dentry(clnt->cl_dentry,
- "gssd",
- clnt, gss_auth->pipe[1]);
- if (IS_ERR(gss_auth->pipe[1]->dentry))
- return PTR_ERR(gss_auth->pipe[1]->dentry);
- gss_auth->pipe[0]->dentry = rpc_mkpipe_dentry(clnt->cl_dentry,
- gss_auth->mech->gm_name,
- clnt, gss_auth->pipe[0]);
- if (IS_ERR(gss_auth->pipe[0]->dentry)) {
- err = PTR_ERR(gss_auth->pipe[0]->dentry);
- goto err_unlink_pipe_1;
+ if (gss_auth->pipe[1]->dentry == NULL) {
+ gss_auth->pipe[1]->dentry =
+ rpc_mkpipe_dentry(clnt->cl_dentry, "gssd", clnt,
+ gss_auth->pipe[1]);
+ if (IS_ERR(gss_auth->pipe[1]->dentry)) {
+ err = PTR_ERR(gss_auth->pipe[1]->dentry);
+ gss_auth->pipe[1]->dentry = NULL;
+ goto out_err;
+ }
}
+
+ if (gss_auth->pipe[0]->dentry == NULL) {
+ gss_auth->pipe[0]->dentry =
+ rpc_mkpipe_dentry(clnt->cl_dentry,
+ gss_auth->mech->gm_name,
+ clnt, gss_auth->pipe[0]);
+ if (IS_ERR(gss_auth->pipe[0]->dentry)) {
+ err = PTR_ERR(gss_auth->pipe[0]->dentry);
+ gss_auth->pipe[0]->dentry = NULL;
+ goto out_err;
+ }
+ }
+
return 0;
-err_unlink_pipe_1:
- rpc_unlink(gss_auth->pipe[1]->dentry);
+out_err:
+ gss_pipes_dentries_destroy(auth);
return err;
}
next prev parent reply other threads:[~2012-08-13 21:21 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-08-13 21:21 [PATCH 0/5] (v2) rpcauth_create() returns -EEXIST Chuck Lever
2012-08-13 21:21 ` [PATCH 1/5] SUNRPC: Clean up dprintk messages in rpc_pipe.c Chuck Lever
2012-08-13 21:21 ` [PATCH 2/5] SUNRPC: Use __func__ in dprintk() in auth_gss.c Chuck Lever
2012-08-13 21:21 ` Chuck Lever [this message]
2012-08-13 21:21 ` [PATCH 4/5] SUNRPC: Insert a shim under gss_create() Chuck Lever
2012-08-13 21:22 ` [PATCH 5/5] SUNRPC: Share upcall pipes among an rpc_clnt's rpc_auth objects Chuck Lever
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20120813212150.1680.96757.stgit@degas.1015granger.net \
--to=chuck.lever@oracle.com \
--cc=linux-nfs@vger.kernel.org \
--cc=trond.myklebust@netapp.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).