summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2019-06-05 12:42:05 -0400
committerJ. Bruce Fields <bfields@redhat.com>2019-07-03 20:54:03 -0400
commit791234448d4798f589110c17d2baaf1bbcc56cb8 (patch)
treeec3385bef711d86168e70e4ef192a3af6071ff18
parent6f4859b8a72638f60c7051247aac63a761f01933 (diff)
nfsd: decode implementation id
Decode the implementation ID and display in nfsd/clients/#/info. It may be help identify the client. It won't be used otherwise. (When this went into the protocol, I thought the implementation ID would be a slippery slope towards implementation-specific workarounds as with the http user-agent. But I guess I was wrong, the risk seems pretty low now.) Signed-off-by: J. Bruce Fields <bfields@redhat.com>
-rw-r--r--fs/nfsd/nfs4state.c30
-rw-r--r--fs/nfsd/nfs4xdr.c21
-rw-r--r--fs/nfsd/state.h4
-rw-r--r--fs/nfsd/xdr4.h3
4 files changed, 46 insertions, 12 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 640cd221fc77..94de5c348a41 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -1899,6 +1899,8 @@ static void __free_client(struct kref *k)
1899 free_svc_cred(&clp->cl_cred); 1899 free_svc_cred(&clp->cl_cred);
1900 kfree(clp->cl_ownerstr_hashtbl); 1900 kfree(clp->cl_ownerstr_hashtbl);
1901 kfree(clp->cl_name.data); 1901 kfree(clp->cl_name.data);
1902 kfree(clp->cl_nii_domain.data);
1903 kfree(clp->cl_nii_name.data);
1902 idr_destroy(&clp->cl_stateids); 1904 idr_destroy(&clp->cl_stateids);
1903 kmem_cache_free(client_slab, clp); 1905 kmem_cache_free(client_slab, clp);
1904} 1906}
@@ -2261,6 +2263,15 @@ static int client_info_show(struct seq_file *m, void *v)
2261 seq_printf(m, "name: "); 2263 seq_printf(m, "name: ");
2262 seq_quote_mem(m, clp->cl_name.data, clp->cl_name.len); 2264 seq_quote_mem(m, clp->cl_name.data, clp->cl_name.len);
2263 seq_printf(m, "\nminor version: %d\n", clp->cl_minorversion); 2265 seq_printf(m, "\nminor version: %d\n", clp->cl_minorversion);
2266 if (clp->cl_nii_domain.data) {
2267 seq_printf(m, "Implementation domain: ");
2268 seq_quote_mem(m, clp->cl_nii_domain.data,
2269 clp->cl_nii_domain.len);
2270 seq_printf(m, "\nImplementation name: ");
2271 seq_quote_mem(m, clp->cl_nii_name.data, clp->cl_nii_name.len);
2272 seq_printf(m, "\nImplementation time: [%ld, %ld]\n",
2273 clp->cl_nii_time.tv_sec, clp->cl_nii_time.tv_nsec);
2274 }
2264 drop_client(clp); 2275 drop_client(clp);
2265 2276
2266 return 0; 2277 return 0;
@@ -2901,6 +2912,22 @@ static bool client_has_state(struct nfs4_client *clp)
2901 || !list_empty(&clp->async_copies); 2912 || !list_empty(&clp->async_copies);
2902} 2913}
2903 2914
2915static __be32 copy_impl_id(struct nfs4_client *clp,
2916 struct nfsd4_exchange_id *exid)
2917{
2918 if (!exid->nii_domain.data)
2919 return 0;
2920 xdr_netobj_dup(&clp->cl_nii_domain, &exid->nii_domain, GFP_KERNEL);
2921 if (!clp->cl_nii_domain.data)
2922 return nfserr_jukebox;
2923 xdr_netobj_dup(&clp->cl_nii_name, &exid->nii_name, GFP_KERNEL);
2924 if (!clp->cl_nii_name.data)
2925 return nfserr_jukebox;
2926 clp->cl_nii_time.tv_sec = exid->nii_time.tv_sec;
2927 clp->cl_nii_time.tv_nsec = exid->nii_time.tv_nsec;
2928 return 0;
2929}
2930
2904__be32 2931__be32
2905nfsd4_exchange_id(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 2932nfsd4_exchange_id(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
2906 union nfsd4_op_u *u) 2933 union nfsd4_op_u *u)
@@ -2927,6 +2954,9 @@ nfsd4_exchange_id(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
2927 new = create_client(exid->clname, rqstp, &verf); 2954 new = create_client(exid->clname, rqstp, &verf);
2928 if (new == NULL) 2955 if (new == NULL)
2929 return nfserr_jukebox; 2956 return nfserr_jukebox;
2957 status = copy_impl_id(new, exid);
2958 if (status)
2959 goto out_nolock;
2930 2960
2931 switch (exid->spa_how) { 2961 switch (exid->spa_how) {
2932 case SP4_MACH_CRED: 2962 case SP4_MACH_CRED:
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 548a5a843b67..442811809f3d 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1389,7 +1389,6 @@ nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
1389 goto xdr_error; 1389 goto xdr_error;
1390 } 1390 }
1391 1391
1392 /* Ignore Implementation ID */
1393 READ_BUF(4); /* nfs_impl_id4 array length */ 1392 READ_BUF(4); /* nfs_impl_id4 array length */
1394 dummy = be32_to_cpup(p++); 1393 dummy = be32_to_cpup(p++);
1395 1394
@@ -1397,21 +1396,19 @@ nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
1397 goto xdr_error; 1396 goto xdr_error;
1398 1397
1399 if (dummy == 1) { 1398 if (dummy == 1) {
1400 /* nii_domain */ 1399 status = nfsd4_decode_opaque(argp, &exid->nii_domain);
1401 READ_BUF(4); 1400 if (status)
1402 dummy = be32_to_cpup(p++); 1401 goto xdr_error;
1403 READ_BUF(dummy);
1404 p += XDR_QUADLEN(dummy);
1405 1402
1406 /* nii_name */ 1403 /* nii_name */
1407 READ_BUF(4); 1404 status = nfsd4_decode_opaque(argp, &exid->nii_name);
1408 dummy = be32_to_cpup(p++); 1405 if (status)
1409 READ_BUF(dummy); 1406 goto xdr_error;
1410 p += XDR_QUADLEN(dummy);
1411 1407
1412 /* nii_date */ 1408 /* nii_date */
1413 READ_BUF(12); 1409 status = nfsd4_decode_time(argp, &exid->nii_time);
1414 p += 3; 1410 if (status)
1411 goto xdr_error;
1415 } 1412 }
1416 DECODE_TAIL; 1413 DECODE_TAIL;
1417} 1414}
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index 81852cbf6b0a..8cb20cab012b 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -317,6 +317,10 @@ struct nfs4_client {
317 clientid_t cl_clientid; /* generated by server */ 317 clientid_t cl_clientid; /* generated by server */
318 nfs4_verifier cl_confirm; /* generated by server */ 318 nfs4_verifier cl_confirm; /* generated by server */
319 u32 cl_minorversion; 319 u32 cl_minorversion;
320 /* NFSv4.1 client implementation id: */
321 struct xdr_netobj cl_nii_domain;
322 struct xdr_netobj cl_nii_name;
323 struct timespec cl_nii_time;
320 324
321 /* for v4.0 and v4.1 callbacks: */ 325 /* for v4.0 and v4.1 callbacks: */
322 struct nfs4_cb_conn cl_cb_conn; 326 struct nfs4_cb_conn cl_cb_conn;
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index c2b631eefc6d..d64c870f998a 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -410,6 +410,9 @@ struct nfsd4_exchange_id {
410 int spa_how; 410 int spa_how;
411 u32 spo_must_enforce[3]; 411 u32 spo_must_enforce[3];
412 u32 spo_must_allow[3]; 412 u32 spo_must_allow[3];
413 struct xdr_netobj nii_domain;
414 struct xdr_netobj nii_name;
415 struct timespec64 nii_time;
413}; 416};
414 417
415struct nfsd4_sequence { 418struct nfsd4_sequence {