Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit acdeb69d authored by Chuck Lever's avatar Chuck Lever Committed by Trond Myklebust
Browse files

NFS: EXCHANGE_ID should save the server major and minor ID



Save the server major and minor ID results from EXCHANGE_ID, as they
are needed for detecting server trunking.

Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 4bf590e0
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -237,6 +237,7 @@ static void nfs4_shutdown_client(struct nfs_client *clp)
		nfs_idmap_delete(clp);

	rpc_destroy_wait_queue(&clp->cl_rpcwaitq);
	kfree(clp->cl_serverowner);
	kfree(clp->cl_serverscope);
	kfree(clp->cl_implid);
}
+16 −1
Original line number Diff line number Diff line
@@ -5109,11 +5109,18 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
				clp->cl_rpcclient->cl_nodename,
				clp->cl_rpcclient->cl_auth->au_flavor);

	res.server_owner = kzalloc(sizeof(struct nfs41_server_owner),
					GFP_KERNEL);
	if (unlikely(res.server_owner == NULL)) {
		status = -ENOMEM;
		goto out;
	}

	res.server_scope = kzalloc(sizeof(struct nfs41_server_scope),
					GFP_KERNEL);
	if (unlikely(res.server_scope == NULL)) {
		status = -ENOMEM;
		goto out;
		goto out_server_owner;
	}

	res.impl_id = kzalloc(sizeof(struct nfs41_impl_id), GFP_KERNEL);
@@ -5126,6 +5133,12 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
	if (status == 0)
		status = nfs4_check_cl_exchange_flags(clp->cl_exchange_flags);

	if (status == 0) {
		kfree(clp->cl_serverowner);
		clp->cl_serverowner = res.server_owner;
		res.server_owner = NULL;
	}

	if (status == 0) {
		/* use the most recent implementation id */
		kfree(clp->cl_implid);
@@ -5150,6 +5163,8 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
		}
	}

out_server_owner:
	kfree(res.server_owner);
out_server_scope:
	kfree(res.server_scope);
out:
+8 −5
Original line number Diff line number Diff line
@@ -5144,24 +5144,27 @@ static int decode_exchange_id(struct xdr_stream *xdr,
	if (dummy != SP4_NONE)
		return -EIO;

	/* Throw away minor_id */
	/* server_owner4.so_minor_id */
	p = xdr_inline_decode(xdr, 8);
	if (unlikely(!p))
		goto out_overflow;
	p = xdr_decode_hyper(p, &res->server_owner->minor_id);

	/* Throw away Major id */
	/* server_owner4.so_major_id */
	status = decode_opaque_inline(xdr, &dummy, &dummy_str);
	if (unlikely(status))
		return status;
	if (unlikely(dummy > NFS4_OPAQUE_LIMIT))
		return -EIO;
	memcpy(res->server_owner->major_id, dummy_str, dummy);
	res->server_owner->major_id_sz = dummy;

	/* Save server_scope */
	/* server_scope4 */
	status = decode_opaque_inline(xdr, &dummy, &dummy_str);
	if (unlikely(status))
		return status;

	if (unlikely(dummy > NFS4_OPAQUE_LIMIT))
		return -EIO;

	memcpy(res->server_scope->server_scope, dummy_str, dummy);
	res->server_scope->server_scope_sz = dummy;

+1 −0
Original line number Diff line number Diff line
@@ -80,6 +80,7 @@ struct nfs_client {
	/* The flags used for obtaining the clientid during EXCHANGE_ID */
	u32			cl_exchange_flags;
	struct nfs4_session	*cl_session;	/* shared session */
	struct nfs41_server_owner *cl_serverowner;
	struct nfs41_server_scope *cl_serverscope;
	struct nfs41_impl_id	*cl_implid;
#endif /* CONFIG_NFS_V4 */
+2 −1
Original line number Diff line number Diff line
@@ -1098,7 +1098,7 @@ struct nfs41_exchange_id_args {
	u32				flags;
};

struct server_owner {
struct nfs41_server_owner {
	uint64_t			minor_id;
	uint32_t			major_id_sz;
	char				major_id[NFS4_OPAQUE_LIMIT];
@@ -1118,6 +1118,7 @@ struct nfs41_impl_id {
struct nfs41_exchange_id_res {
	struct nfs_client		*client;
	u32				flags;
	struct nfs41_server_owner	*server_owner;
	struct nfs41_server_scope	*server_scope;
	struct nfs41_impl_id		*impl_id;
};