@@ -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;
}