Skip to content

Commit 0cc2ea8

Browse files
committed
Merge tag 'nfsd-5.14' of git://linux-nfs.org/~bfields/linux
Pull nfsd updates from Bruce Fields: - add tracepoints for callbacks and for client creation and destruction - cache the mounts used for server-to-server copies - expose callback information in /proc/fs/nfsd/clients/*/info - don't hold locks unnecessarily while waiting for commits - update NLM to use xdr_stream, as we have for NFSv2/v3/v4 * tag 'nfsd-5.14' of git://linux-nfs.org/~bfields/linux: (69 commits) nfsd: fix NULL dereference in nfs3svc_encode_getaclres NFSD: Prevent a possible oops in the nfs_dirent() tracepoint nfsd: remove redundant assignment to pointer 'this' nfsd: Reduce contention for the nfsd_file nf_rwsem lockd: Update the NLMv4 SHARE results encoder to use struct xdr_stream lockd: Update the NLMv4 nlm_res results encoder to use struct xdr_stream lockd: Update the NLMv4 TEST results encoder to use struct xdr_stream lockd: Update the NLMv4 void results encoder to use struct xdr_stream lockd: Update the NLMv4 FREE_ALL arguments decoder to use struct xdr_stream lockd: Update the NLMv4 SHARE arguments decoder to use struct xdr_stream lockd: Update the NLMv4 SM_NOTIFY arguments decoder to use struct xdr_stream lockd: Update the NLMv4 nlm_res arguments decoder to use struct xdr_stream lockd: Update the NLMv4 UNLOCK arguments decoder to use struct xdr_stream lockd: Update the NLMv4 CANCEL arguments decoder to use struct xdr_stream lockd: Update the NLMv4 LOCK arguments decoder to use struct xdr_stream lockd: Update the NLMv4 TEST arguments decoder to use struct xdr_stream lockd: Update the NLMv4 void arguments decoder to use struct xdr_stream lockd: Update the NLMv1 SHARE results encoder to use struct xdr_stream lockd: Update the NLMv1 nlm_res results encoder to use struct xdr_stream lockd: Update the NLMv1 TEST results encoder to use struct xdr_stream ...
2 parents a931dd3 + ab1016d commit 0cc2ea8

File tree

21 files changed

+1175
-538
lines changed

21 files changed

+1175
-538
lines changed

fs/lockd/svc.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,46 @@ static void __exit exit_nlm(void)
766766
module_init(init_nlm);
767767
module_exit(exit_nlm);
768768

769+
/**
770+
* nlmsvc_dispatch - Process an NLM Request
771+
* @rqstp: incoming request
772+
* @statp: pointer to location of accept_stat field in RPC Reply buffer
773+
*
774+
* Return values:
775+
* %0: Processing complete; do not send a Reply
776+
* %1: Processing complete; send Reply in rqstp->rq_res
777+
*/
778+
static int nlmsvc_dispatch(struct svc_rqst *rqstp, __be32 *statp)
779+
{
780+
const struct svc_procedure *procp = rqstp->rq_procinfo;
781+
struct kvec *argv = rqstp->rq_arg.head;
782+
struct kvec *resv = rqstp->rq_res.head;
783+
784+
svcxdr_init_decode(rqstp);
785+
if (!procp->pc_decode(rqstp, argv->iov_base))
786+
goto out_decode_err;
787+
788+
*statp = procp->pc_func(rqstp);
789+
if (*statp == rpc_drop_reply)
790+
return 0;
791+
if (*statp != rpc_success)
792+
return 1;
793+
794+
svcxdr_init_encode(rqstp);
795+
if (!procp->pc_encode(rqstp, resv->iov_base + resv->iov_len))
796+
goto out_encode_err;
797+
798+
return 1;
799+
800+
out_decode_err:
801+
*statp = rpc_garbage_args;
802+
return 1;
803+
804+
out_encode_err:
805+
*statp = rpc_system_err;
806+
return 1;
807+
}
808+
769809
/*
770810
* Define NLM program and procedures
771811
*/
@@ -775,6 +815,7 @@ static const struct svc_version nlmsvc_version1 = {
775815
.vs_nproc = 17,
776816
.vs_proc = nlmsvc_procedures,
777817
.vs_count = nlmsvc_version1_count,
818+
.vs_dispatch = nlmsvc_dispatch,
778819
.vs_xdrsize = NLMSVC_XDRSIZE,
779820
};
780821
static unsigned int nlmsvc_version3_count[24];
@@ -783,6 +824,7 @@ static const struct svc_version nlmsvc_version3 = {
783824
.vs_nproc = 24,
784825
.vs_proc = nlmsvc_procedures,
785826
.vs_count = nlmsvc_version3_count,
827+
.vs_dispatch = nlmsvc_dispatch,
786828
.vs_xdrsize = NLMSVC_XDRSIZE,
787829
};
788830
#ifdef CONFIG_LOCKD_V4
@@ -792,6 +834,7 @@ static const struct svc_version nlmsvc_version4 = {
792834
.vs_nproc = 24,
793835
.vs_proc = nlmsvc_procedures4,
794836
.vs_count = nlmsvc_version4_count,
837+
.vs_dispatch = nlmsvc_dispatch,
795838
.vs_xdrsize = NLMSVC_XDRSIZE,
796839
};
797840
#endif

fs/lockd/svcxdr.h

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
/*
3+
* Encode/decode NLM basic data types
4+
*
5+
* Basic NLMv3 XDR data types are not defined in an IETF standards
6+
* document. X/Open has a description of these data types that
7+
* is useful. See Chapter 10 of "Protocols for Interworking:
8+
* XNFS, Version 3W".
9+
*
10+
* Basic NLMv4 XDR data types are defined in Appendix II.1.4 of
11+
* RFC 1813: "NFS Version 3 Protocol Specification".
12+
*
13+
* Author: Chuck Lever <[email protected]>
14+
*
15+
* Copyright (c) 2020, Oracle and/or its affiliates.
16+
*/
17+
18+
#ifndef _LOCKD_SVCXDR_H_
19+
#define _LOCKD_SVCXDR_H_
20+
21+
static inline bool
22+
svcxdr_decode_stats(struct xdr_stream *xdr, __be32 *status)
23+
{
24+
__be32 *p;
25+
26+
p = xdr_inline_decode(xdr, XDR_UNIT);
27+
if (!p)
28+
return false;
29+
*status = *p;
30+
31+
return true;
32+
}
33+
34+
static inline bool
35+
svcxdr_encode_stats(struct xdr_stream *xdr, __be32 status)
36+
{
37+
__be32 *p;
38+
39+
p = xdr_reserve_space(xdr, XDR_UNIT);
40+
if (!p)
41+
return false;
42+
*p = status;
43+
44+
return true;
45+
}
46+
47+
static inline bool
48+
svcxdr_decode_string(struct xdr_stream *xdr, char **data, unsigned int *data_len)
49+
{
50+
__be32 *p;
51+
u32 len;
52+
53+
if (xdr_stream_decode_u32(xdr, &len) < 0)
54+
return false;
55+
if (len > NLM_MAXSTRLEN)
56+
return false;
57+
p = xdr_inline_decode(xdr, len);
58+
if (!p)
59+
return false;
60+
*data_len = len;
61+
*data = (char *)p;
62+
63+
return true;
64+
}
65+
66+
/*
67+
* NLM cookies are defined by specification to be a variable-length
68+
* XDR opaque no longer than 1024 bytes. However, this implementation
69+
* limits their length to 32 bytes, and treats zero-length cookies
70+
* specially.
71+
*/
72+
static inline bool
73+
svcxdr_decode_cookie(struct xdr_stream *xdr, struct nlm_cookie *cookie)
74+
{
75+
__be32 *p;
76+
u32 len;
77+
78+
if (xdr_stream_decode_u32(xdr, &len) < 0)
79+
return false;
80+
if (len > NLM_MAXCOOKIELEN)
81+
return false;
82+
if (!len)
83+
goto out_hpux;
84+
85+
p = xdr_inline_decode(xdr, len);
86+
if (!p)
87+
return false;
88+
cookie->len = len;
89+
memcpy(cookie->data, p, len);
90+
91+
return true;
92+
93+
/* apparently HPUX can return empty cookies */
94+
out_hpux:
95+
cookie->len = 4;
96+
memset(cookie->data, 0, 4);
97+
return true;
98+
}
99+
100+
static inline bool
101+
svcxdr_encode_cookie(struct xdr_stream *xdr, const struct nlm_cookie *cookie)
102+
{
103+
__be32 *p;
104+
105+
if (xdr_stream_encode_u32(xdr, cookie->len) < 0)
106+
return false;
107+
p = xdr_reserve_space(xdr, cookie->len);
108+
if (!p)
109+
return false;
110+
memcpy(p, cookie->data, cookie->len);
111+
112+
return true;
113+
}
114+
115+
static inline bool
116+
svcxdr_decode_owner(struct xdr_stream *xdr, struct xdr_netobj *obj)
117+
{
118+
__be32 *p;
119+
u32 len;
120+
121+
if (xdr_stream_decode_u32(xdr, &len) < 0)
122+
return false;
123+
if (len > XDR_MAX_NETOBJ)
124+
return false;
125+
p = xdr_inline_decode(xdr, len);
126+
if (!p)
127+
return false;
128+
obj->len = len;
129+
obj->data = (u8 *)p;
130+
131+
return true;
132+
}
133+
134+
static inline bool
135+
svcxdr_encode_owner(struct xdr_stream *xdr, const struct xdr_netobj *obj)
136+
{
137+
unsigned int quadlen = XDR_QUADLEN(obj->len);
138+
__be32 *p;
139+
140+
if (xdr_stream_encode_u32(xdr, obj->len) < 0)
141+
return false;
142+
p = xdr_reserve_space(xdr, obj->len);
143+
if (!p)
144+
return false;
145+
p[quadlen - 1] = 0; /* XDR pad */
146+
memcpy(p, obj->data, obj->len);
147+
148+
return true;
149+
}
150+
151+
#endif /* _LOCKD_SVCXDR_H_ */

0 commit comments

Comments
 (0)