Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>

authored by

Chuck Lever and committed by
Trond Myklebust
acdeb69d 4bf590e0

+31 -10
+1
fs/nfs/client.c
··· 237 237 nfs_idmap_delete(clp); 238 238 239 239 rpc_destroy_wait_queue(&clp->cl_rpcwaitq); 240 + kfree(clp->cl_serverowner); 240 241 kfree(clp->cl_serverscope); 241 242 kfree(clp->cl_implid); 242 243 }
+16 -1
fs/nfs/nfs4proc.c
··· 5109 5109 clp->cl_rpcclient->cl_nodename, 5110 5110 clp->cl_rpcclient->cl_auth->au_flavor); 5111 5111 5112 + res.server_owner = kzalloc(sizeof(struct nfs41_server_owner), 5113 + GFP_KERNEL); 5114 + if (unlikely(res.server_owner == NULL)) { 5115 + status = -ENOMEM; 5116 + goto out; 5117 + } 5118 + 5112 5119 res.server_scope = kzalloc(sizeof(struct nfs41_server_scope), 5113 5120 GFP_KERNEL); 5114 5121 if (unlikely(res.server_scope == NULL)) { 5115 5122 status = -ENOMEM; 5116 - goto out; 5123 + goto out_server_owner; 5117 5124 } 5118 5125 5119 5126 res.impl_id = kzalloc(sizeof(struct nfs41_impl_id), GFP_KERNEL); ··· 5132 5125 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); 5133 5126 if (status == 0) 5134 5127 status = nfs4_check_cl_exchange_flags(clp->cl_exchange_flags); 5128 + 5129 + if (status == 0) { 5130 + kfree(clp->cl_serverowner); 5131 + clp->cl_serverowner = res.server_owner; 5132 + res.server_owner = NULL; 5133 + } 5135 5134 5136 5135 if (status == 0) { 5137 5136 /* use the most recent implementation id */ ··· 5163 5150 } 5164 5151 } 5165 5152 5153 + out_server_owner: 5154 + kfree(res.server_owner); 5166 5155 out_server_scope: 5167 5156 kfree(res.server_scope); 5168 5157 out:
+11 -8
fs/nfs/nfs4xdr.c
··· 5144 5144 if (dummy != SP4_NONE) 5145 5145 return -EIO; 5146 5146 5147 - /* Throw away minor_id */ 5147 + /* server_owner4.so_minor_id */ 5148 5148 p = xdr_inline_decode(xdr, 8); 5149 5149 if (unlikely(!p)) 5150 5150 goto out_overflow; 5151 + p = xdr_decode_hyper(p, &res->server_owner->minor_id); 5151 5152 5152 - /* Throw away Major id */ 5153 + /* server_owner4.so_major_id */ 5153 5154 status = decode_opaque_inline(xdr, &dummy, &dummy_str); 5154 5155 if (unlikely(status)) 5155 5156 return status; 5156 - 5157 - /* Save server_scope */ 5158 - status = decode_opaque_inline(xdr, &dummy, &dummy_str); 5159 - if (unlikely(status)) 5160 - return status; 5161 - 5162 5157 if (unlikely(dummy > NFS4_OPAQUE_LIMIT)) 5163 5158 return -EIO; 5159 + memcpy(res->server_owner->major_id, dummy_str, dummy); 5160 + res->server_owner->major_id_sz = dummy; 5164 5161 5162 + /* server_scope4 */ 5163 + status = decode_opaque_inline(xdr, &dummy, &dummy_str); 5164 + if (unlikely(status)) 5165 + return status; 5166 + if (unlikely(dummy > NFS4_OPAQUE_LIMIT)) 5167 + return -EIO; 5165 5168 memcpy(res->server_scope->server_scope, dummy_str, dummy); 5166 5169 res->server_scope->server_scope_sz = dummy; 5167 5170
+1
include/linux/nfs_fs_sb.h
··· 80 80 /* The flags used for obtaining the clientid during EXCHANGE_ID */ 81 81 u32 cl_exchange_flags; 82 82 struct nfs4_session *cl_session; /* shared session */ 83 + struct nfs41_server_owner *cl_serverowner; 83 84 struct nfs41_server_scope *cl_serverscope; 84 85 struct nfs41_impl_id *cl_implid; 85 86 #endif /* CONFIG_NFS_V4 */
+2 -1
include/linux/nfs_xdr.h
··· 1098 1098 u32 flags; 1099 1099 }; 1100 1100 1101 - struct server_owner { 1101 + struct nfs41_server_owner { 1102 1102 uint64_t minor_id; 1103 1103 uint32_t major_id_sz; 1104 1104 char major_id[NFS4_OPAQUE_LIMIT]; ··· 1118 1118 struct nfs41_exchange_id_res { 1119 1119 struct nfs_client *client; 1120 1120 u32 flags; 1121 + struct nfs41_server_owner *server_owner; 1121 1122 struct nfs41_server_scope *server_scope; 1122 1123 struct nfs41_impl_id *impl_id; 1123 1124 };