[RFC 47/85] nfs41: get cred in exchange_id when cred arg is NULL

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



When creating a session to a pnfs data server, the cred is passed
down as NULL.  Either use the saved cl_ex_cred or get a new one
using nfs4_get_setclientid_cred.

Signed-off-by: Benny Halevy <bhalevy@xxxxxxxxxxx>
---
 fs/nfs/nfs4_fs.h   |    1 +
 fs/nfs/nfs4proc.c  |   18 +++++++++++++++---
 fs/nfs/nfs4state.c |    2 +-
 3 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 904b19e..b9771f2 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -229,6 +229,7 @@ extern void nfs4_renew_state(struct work_struct *);
 
 /* nfs4state.c */
 struct rpc_cred *nfs4_get_renew_cred(struct nfs_client *clp);
+struct rpc_cred *nfs4_get_setclientid_cred(struct nfs_client *clp);
 #ifdef CONFIG_NFS_V4_1
 struct rpc_cred *nfs41_get_state_renewal_cred(struct nfs_client *clp);
 #endif /* CONFIG_NFS_V4_1 */
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 5b1f6d0..8c28d0c 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -4276,6 +4276,7 @@ static int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
 	};
 	int status;
 	int loop = 0;
+	int got_cred = 0;
 	struct rpc_message msg = {
 		.rpc_proc = nfs4_proc(clp, NFSPROC4_CLNT_EXCHANGE_ID),
 		.rpc_argp = &args,
@@ -4286,6 +4287,16 @@ static int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
 
 	dprintk("--> %s\n", __func__);
 	BUG_ON(clp == NULL);
+
+	if (!cred) {
+		/* FIXME: do we need to lock clp and take a ref count on cl_ex_cred? */
+		cred = clp->cl_ex_cred;
+		if (!cred) {
+			cred = nfs4_get_setclientid_cred(clp);
+			got_cred = (cred != NULL);
+		}
+	}
+
 	p = (u32 *)verifier.data;
 	*p++ = htonl((u32)clp->cl_boot_time.tv_sec);
 	*p = htonl((u32)clp->cl_boot_time.tv_nsec);
@@ -4317,17 +4328,18 @@ static int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
 		else if (++clp->cl_id_uniquifier == 0)
 			break;
 	}
-	if (status == 0) {
+	if ((status == 0) && (cred != clp->cl_ex_cred) && (cred != NULL)) {
+		/* FIXME: do we need to lock clp here? */
 		if (clp->cl_ex_cred) {
 			dprintk("%s put cl_ex_cred %p\n", __func__,
 				clp->cl_ex_cred);
 			put_rpccred(clp->cl_ex_cred);
 		}
-
-		BUG_ON(cred == NULL);
 		clp->cl_ex_cred = get_rpccred(cred);
 		dprintk("%s set cl_ex_cred %p\n", __func__, clp->cl_ex_cred);
 	}
+	if (got_cred)
+		put_rpccred(cred);
 
 	dprintk("<-- %s status= %d\n", __func__, status);
 	return status;
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 5a91072..693e5a6 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -122,7 +122,7 @@ struct rpc_cred *nfs4_get_renew_cred(struct nfs_client *clp)
 	return cred;
 }
 
-static struct rpc_cred *nfs4_get_setclientid_cred(struct nfs_client *clp)
+struct rpc_cred *nfs4_get_setclientid_cred(struct nfs_client *clp)
 {
 	struct nfs4_state_owner *sp;
 	struct rb_node *pos;
-- 
1.6.0.2

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux