aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/client.c1
-rw-r--r--fs/nfs/nfs4proc.c21
-rw-r--r--fs/nfs/nfs4xdr.c42
-rw-r--r--fs/nfs/super.c8
4 files changed, 67 insertions, 5 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 592b5583aa3a..1506adf4d4ed 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -304,6 +304,7 @@ static void nfs_free_client(struct nfs_client *clp)
304 put_net(clp->net); 304 put_net(clp->net);
305 kfree(clp->cl_hostname); 305 kfree(clp->cl_hostname);
306 kfree(clp->server_scope); 306 kfree(clp->server_scope);
307 kfree(clp->impl_id);
307 kfree(clp); 308 kfree(clp);
308 309
309 dprintk("<-- nfs_free_client()\n"); 310 dprintk("<-- nfs_free_client()\n");
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 20c3bb06763a..90a17cc3ebc9 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -4950,11 +4950,24 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
4950 goto out; 4950 goto out;
4951 } 4951 }
4952 4952
4953 res.impl_id = kzalloc(sizeof(struct nfs41_impl_id), GFP_KERNEL);
4954 if (unlikely(!res.impl_id)) {
4955 status = -ENOMEM;
4956 goto out_server_scope;
4957 }
4958
4953 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); 4959 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
4954 if (!status) 4960 if (!status)
4955 status = nfs4_check_cl_exchange_flags(clp->cl_exchange_flags); 4961 status = nfs4_check_cl_exchange_flags(clp->cl_exchange_flags);
4956 4962
4957 if (!status) { 4963 if (!status) {
4964 /* use the most recent implementation id */
4965 kfree(clp->impl_id);
4966 clp->impl_id = res.impl_id;
4967 } else
4968 kfree(res.impl_id);
4969
4970 if (!status) {
4958 if (clp->server_scope && 4971 if (clp->server_scope &&
4959 !nfs41_same_server_scope(clp->server_scope, 4972 !nfs41_same_server_scope(clp->server_scope,
4960 res.server_scope)) { 4973 res.server_scope)) {
@@ -4970,8 +4983,16 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
4970 goto out; 4983 goto out;
4971 } 4984 }
4972 } 4985 }
4986
4987out_server_scope:
4973 kfree(res.server_scope); 4988 kfree(res.server_scope);
4974out: 4989out:
4990 if (clp->impl_id)
4991 dprintk("%s: Server Implementation ID: "
4992 "domain: %s, name: %s, date: %llu,%u\n",
4993 __func__, clp->impl_id->domain, clp->impl_id->name,
4994 clp->impl_id->date.seconds,
4995 clp->impl_id->date.nseconds);
4975 dprintk("<-- %s status= %d\n", __func__, status); 4996 dprintk("<-- %s status= %d\n", __func__, status);
4976 return status; 4997 return status;
4977} 4998}
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index d824aedb1237..b7c04339fdc1 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -291,7 +291,11 @@ static int nfs4_stat_to_errno(int);
291 /* eir_server_scope<> */ \ 291 /* eir_server_scope<> */ \
292 XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 + \ 292 XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 + \
293 1 /* eir_server_impl_id array length */ + \ 293 1 /* eir_server_impl_id array length */ + \
294 0 /* ignored eir_server_impl_id contents */) 294 1 /* nii_domain */ + \
295 XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + \
296 1 /* nii_name */ + \
297 XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + \
298 3 /* nii_date */)
295#define encode_channel_attrs_maxsz (6 + 1 /* ca_rdma_ird.len (0) */) 299#define encode_channel_attrs_maxsz (6 + 1 /* ca_rdma_ird.len (0) */)
296#define decode_channel_attrs_maxsz (6 + \ 300#define decode_channel_attrs_maxsz (6 + \
297 1 /* ca_rdma_ird.len */ + \ 301 1 /* ca_rdma_ird.len */ + \
@@ -5256,6 +5260,7 @@ static int decode_exchange_id(struct xdr_stream *xdr,
5256 char *dummy_str; 5260 char *dummy_str;
5257 int status; 5261 int status;
5258 struct nfs_client *clp = res->client; 5262 struct nfs_client *clp = res->client;
5263 uint32_t impl_id_count;
5259 5264
5260 status = decode_op_hdr(xdr, OP_EXCHANGE_ID); 5265 status = decode_op_hdr(xdr, OP_EXCHANGE_ID);
5261 if (status) 5266 if (status)
@@ -5297,11 +5302,38 @@ static int decode_exchange_id(struct xdr_stream *xdr,
5297 memcpy(res->server_scope->server_scope, dummy_str, dummy); 5302 memcpy(res->server_scope->server_scope, dummy_str, dummy);
5298 res->server_scope->server_scope_sz = dummy; 5303 res->server_scope->server_scope_sz = dummy;
5299 5304
5300 /* Throw away Implementation id array */ 5305 /* Implementation Id */
5301 status = decode_opaque_inline(xdr, &dummy, &dummy_str); 5306 p = xdr_inline_decode(xdr, 4);
5302 if (unlikely(status)) 5307 if (unlikely(!p))
5303 return status; 5308 goto out_overflow;
5309 impl_id_count = be32_to_cpup(p++);
5304 5310
5311 if (impl_id_count) {
5312 /* nii_domain */
5313 status = decode_opaque_inline(xdr, &dummy, &dummy_str);
5314 if (unlikely(status))
5315 return status;
5316 if (unlikely(dummy > NFS4_OPAQUE_LIMIT))
5317 return -EIO;
5318 memcpy(res->impl_id->domain, dummy_str, dummy);
5319
5320 /* nii_name */
5321 status = decode_opaque_inline(xdr, &dummy, &dummy_str);
5322 if (unlikely(status))
5323 return status;
5324 if (unlikely(dummy > NFS4_OPAQUE_LIMIT))
5325 return -EIO;
5326 memcpy(res->impl_id->name, dummy_str, dummy);
5327
5328 /* nii_date */
5329 p = xdr_inline_decode(xdr, 12);
5330 if (unlikely(!p))
5331 goto out_overflow;
5332 p = xdr_decode_hyper(p, &res->impl_id->date.seconds);
5333 res->impl_id->date.nseconds = be32_to_cpup(p);
5334
5335 /* if there's more than one entry, ignore the rest */
5336 }
5305 return 0; 5337 return 0;
5306out_overflow: 5338out_overflow:
5307 print_overflow_msg(__func__, xdr); 5339 print_overflow_msg(__func__, xdr);
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 6708f3044eb0..8154accd1168 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -809,6 +809,14 @@ static int nfs_show_stats(struct seq_file *m, struct dentry *root)
809 809
810 seq_printf(m, "\n\tage:\t%lu", (jiffies - nfss->mount_time) / HZ); 810 seq_printf(m, "\n\tage:\t%lu", (jiffies - nfss->mount_time) / HZ);
811 811
812 if (nfss->nfs_client && nfss->nfs_client->impl_id) {
813 struct nfs41_impl_id *impl_id = nfss->nfs_client->impl_id;
814 seq_printf(m, "\n\timpl_id:\tname='%s',domain='%s',"
815 "date='%llu,%u'",
816 impl_id->name, impl_id->domain,
817 impl_id->date.seconds, impl_id->date.nseconds);
818 }
819
812 seq_printf(m, "\n\tcaps:\t"); 820 seq_printf(m, "\n\tcaps:\t");
813 seq_printf(m, "caps=0x%x", nfss->caps); 821 seq_printf(m, "caps=0x%x", nfss->caps);
814 seq_printf(m, ",wtmult=%u", nfss->wtmult); 822 seq_printf(m, ",wtmult=%u", nfss->wtmult);