History

Merge tag 'nfsd-6.10' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux

Pull nfsd updates from Chuck Lever: "This is a light release containing mostly optimizations, code clean- ups, and minor bug fixes. This development cycle has focused on non- upstream kernel work: 1. Continuing to build upstream CI for NFSD, based on kdevops 2. Backporting NFSD filecache-related fixes to selected LTS kernels One notable new feature in v6.10 NFSD is the addition of a new netlink protocol dedicated to configuring NFSD. A new user space tool, nfsdctl, is to be added to nfs-utils. Lots more to come here. As always I am very grateful to NFSD contributors, reviewers, testers, and bug reporters who participated during this cycle" * tag 'nfsd-6.10' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux: (29 commits) NFSD: Force all NFSv4.2 COPY requests to be synchronous SUNRPC: Fix gss_free_in_token_pages() NFS/knfsd: Remove the invalid NFS error 'NFSERR_OPNOTSUPP' knfsd: LOOKUP can return an illegal error value nfsd: set security label during create operations NFSD: Add COPY status code to OFFLOAD_STATUS response NFSD: Record status of async copy operation in struct nfsd4_copy SUNRPC: Remove comment for sp_lock NFSD: add listener-{set,get} netlink command SUNRPC: add a new svc_find_listener helper SUNRPC: introduce svc_xprt_create_from_sa utility routine NFSD: add write_version to netlink command NFSD: convert write_threads to netlink command NFSD: allow callers to pass in scope string to nfsd_svc NFSD: move nfsd_mutex handling into nfsd_svc callers lockd: host: Remove unnecessary statements'host = NULL;' nfsd: don't create nfsv4recoverydir in nfsdfs when not used. nfsd: optimise recalculate_deny_mode() for a common case nfsd: add tracepoint in mark_client_expired_locked nfsd: new tracepoint for check_slot_seqid ...

Linus Torvalds committed 2 years ago

Commit 61ea6472 parents 25f4874 8d915bb29 files · +1286 −271Browse files

Unified · Split

29 files
  1. Documentation/netlink/specs/nfsd.yaml +110 −0
  2. fs/lockd/host.c +0 −1
  3. fs/nfsd/export.c +10 −6
  4. fs/nfsd/netlink.c +66 −0
  5. fs/nfsd/netlink.h +10 −0
  6. fs/nfsd/netns.h +1 −0
  7. fs/nfsd/nfs4callback.c +9 −22
  8. fs/nfsd/nfs4proc.c +66 −13
  9. fs/nfsd/nfs4state.c +104 −84
  10. fs/nfsd/nfs4xdr.c +80 −3
  11. fs/nfsd/nfsctl.c +521 −5
  12. fs/nfsd/nfsd.h +1 −2
  13. fs/nfsd/nfsfh.c +2 −2
  14. fs/nfsd/nfssvc.c +5 −6
  15. fs/nfsd/state.h +3 −3
  16. fs/nfsd/stats.c +0 −42
  17. fs/nfsd/stats.h +0 −5
  18. fs/nfsd/trace.h +97 −3
  19. fs/nfsd/vfs.c +1 −1
  20. fs/nfsd/vfs.h +8 −0
  21. fs/nfsd/xdr4.h +23 −1
  22. include/linux/nfs4.h +6 −0
  23. include/linux/sunrpc/svc_xprt.h +5 −0
  24. include/trace/misc/nfs.h +0 −2
  25. include/uapi/linux/nfs.h +0 −1
  26. include/uapi/linux/nfsd_netlink.h +47 −0
  27. net/sunrpc/auth_gss/svcauth_gss.c +2 −8
  28. net/sunrpc/svc.c +0 −2
  29. net/sunrpc/svc_xprt.c +109 −59
Documentation/netlink/specs/nfsd.yaml+110−0
@@ -62,6 +62,59 @@ attribute-sets: · 61 unmodified lines
62 name: compound-ops62 name: compound-ops
63 type: u3263 type: u32
64 multi-attr: true64 multi-attr: true
65 -
66 name: server
67 attributes:
68 -
69 name: threads
70 type: u32
71 multi-attr: true
72 -
73 name: gracetime
74 type: u32
75 -
76 name: leasetime
77 type: u32
78 -
79 name: scope
80 type: string
81 -
82 name: version
83 attributes:
84 -
85 name: major
86 type: u32
87 -
88 name: minor
89 type: u32
90 -
91 name: enabled
92 type: flag
93 -
94 name: server-proto
95 attributes:
96 -
97 name: version
98 type: nest
99 nested-attributes: version
100 multi-attr: true
101 -
102 name: sock
103 attributes:
104 -
105 name: addr
106 type: binary
107 -
108 name: transport-name
109 type: string
110 -
111 name: server-sock
112 attributes:
113 -
114 name: addr
115 type: nest
116 nested-attributes: sock
117 multi-attr: true
65 118
66operations:119operations:
67 list:120 list:
@@ -87,3 +140,60 @@ operations: · 19 unmodified lines
87 - sport140 - sport
88 - dport141 - dport
89 - compound-ops142 - compound-ops
143 -
144 name: threads-set
145 doc: set the number of running threads
146 attribute-set: server
147 flags: [ admin-perm ]
148 do:
149 request:
150 attributes:
151 - threads
152 - gracetime
153 - leasetime
154 - scope
155 -
156 name: threads-get
157 doc: get the number of running threads
158 attribute-set: server
159 do:
160 reply:
161 attributes:
162 - threads
163 - gracetime
164 - leasetime
165 - scope
166 -
167 name: version-set
168 doc: set nfs enabled versions
169 attribute-set: server-proto
170 flags: [ admin-perm ]
171 do:
172 request:
173 attributes:
174 - version
175 -
176 name: version-get
177 doc: get nfs enabled versions
178 attribute-set: server-proto
179 do:
180 reply:
181 attributes:
182 - version
183 -
184 name: listener-set
185 doc: set nfs running sockets
186 attribute-set: server-sock
187 flags: [ admin-perm ]
188 do:
189 request:
190 attributes:
191 - addr
192 -
193 name: listener-get
194 doc: get nfs running listeners
195 attribute-set: server-sock
196 do:
197 reply:
198 attributes:
199 - addr
fs/lockd/host.c+0−1
@@ -117,7 +117,6 @@ static struct nlm_host *nlm_alloc_host(struct nlm_lookup_host_info *ni, · 116 unmodified lines
117 if (nsm != NULL)117 if (nsm != NULL)
118 refcount_inc(&nsm->sm_count);118 refcount_inc(&nsm->sm_count);
119 else {119 else {
120 host = NULL;
121 nsm = nsm_get_handle(ni->net, ni->sap, ni->salen,120 nsm = nsm_get_handle(ni->net, ni->sap, ni->salen,
122 ni->hostname, ni->hostname_len);121 ni->hostname, ni->hostname_len);
123 if (unlikely(nsm == NULL)) {122 if (unlikely(nsm == NULL)) {
fs/nfsd/export.c+10−6
@@ -334,21 +334,25 @@ static void nfsd4_fslocs_free(struct nfsd4_fs_locations *fsloc) · 333 unmodified lines
334static int export_stats_init(struct export_stats *stats)334static int export_stats_init(struct export_stats *stats)
335{335{
336 stats->start_time = ktime_get_seconds();336 stats->start_time = ktime_get_seconds();
337 return nfsd_percpu_counters_init(stats->counter, EXP_STATS_COUNTERS_NUM);337 return percpu_counter_init_many(stats->counter, 0, GFP_KERNEL,
338 EXP_STATS_COUNTERS_NUM);
338}339}
339 340
340static void export_stats_reset(struct export_stats *stats)341static void export_stats_reset(struct export_stats *stats)
341{342{
342 if (stats)343 if (stats) {
343 nfsd_percpu_counters_reset(stats->counter,344 int i;
344 EXP_STATS_COUNTERS_NUM);345
346 for (i = 0; i < EXP_STATS_COUNTERS_NUM; i++)
347 percpu_counter_set(&stats->counter[i], 0);
348 }
345}349}
346 350
347static void export_stats_destroy(struct export_stats *stats)351static void export_stats_destroy(struct export_stats *stats)
348{352{
349 if (stats)353 if (stats)
350 nfsd_percpu_counters_destroy(stats->counter,354 percpu_counter_destroy_many(stats->counter,
351 EXP_STATS_COUNTERS_NUM);355 EXP_STATS_COUNTERS_NUM);
352}356}
353 357
354static void svc_export_put(struct kref *ref)358static void svc_export_put(struct kref *ref)
fs/nfsd/netlink.c+66−0
@@ -10,6 +10,36 @@ · 9 unmodified lines
10 10
11#include <uapi/linux/nfsd_netlink.h>11#include <uapi/linux/nfsd_netlink.h>
12 12
13/* Common nested types */
14const struct nla_policy nfsd_sock_nl_policy[NFSD_A_SOCK_TRANSPORT_NAME + 1] = {
15 [NFSD_A_SOCK_ADDR] = { .type = NLA_BINARY, },
16 [NFSD_A_SOCK_TRANSPORT_NAME] = { .type = NLA_NUL_STRING, },
17};
18
19const struct nla_policy nfsd_version_nl_policy[NFSD_A_VERSION_ENABLED + 1] = {
20 [NFSD_A_VERSION_MAJOR] = { .type = NLA_U32, },
21 [NFSD_A_VERSION_MINOR] = { .type = NLA_U32, },
22 [NFSD_A_VERSION_ENABLED] = { .type = NLA_FLAG, },
23};
24
25/* NFSD_CMD_THREADS_SET - do */
26static const struct nla_policy nfsd_threads_set_nl_policy[NFSD_A_SERVER_SCOPE + 1] = {
27 [NFSD_A_SERVER_THREADS] = { .type = NLA_U32, },
28 [NFSD_A_SERVER_GRACETIME] = { .type = NLA_U32, },
29 [NFSD_A_SERVER_LEASETIME] = { .type = NLA_U32, },
30 [NFSD_A_SERVER_SCOPE] = { .type = NLA_NUL_STRING, },
31};
32
33/* NFSD_CMD_VERSION_SET - do */
34static const struct nla_policy nfsd_version_set_nl_policy[NFSD_A_SERVER_PROTO_VERSION + 1] = {
35 [NFSD_A_SERVER_PROTO_VERSION] = NLA_POLICY_NESTED(nfsd_version_nl_policy),
36};
37
38/* NFSD_CMD_LISTENER_SET - do */
39static const struct nla_policy nfsd_listener_set_nl_policy[NFSD_A_SERVER_SOCK_ADDR + 1] = {
40 [NFSD_A_SERVER_SOCK_ADDR] = NLA_POLICY_NESTED(nfsd_sock_nl_policy),
41};
42
13/* Ops table for nfsd */43/* Ops table for nfsd */
14static const struct genl_split_ops nfsd_nl_ops[] = {44static const struct genl_split_ops nfsd_nl_ops[] = {
15 {45 {
@@ -19,6 +49,42 @@ static const struct genl_split_ops nfsd_nl_ops[] = { · 3 unmodified lines
19 .done = nfsd_nl_rpc_status_get_done,49 .done = nfsd_nl_rpc_status_get_done,
20 .flags = GENL_CMD_CAP_DUMP,50 .flags = GENL_CMD_CAP_DUMP,
21 },51 },
52 {
53 .cmd = NFSD_CMD_THREADS_SET,
54 .doit = nfsd_nl_threads_set_doit,
55 .policy = nfsd_threads_set_nl_policy,
56 .maxattr = NFSD_A_SERVER_SCOPE,
57 .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
58 },
59 {
60 .cmd = NFSD_CMD_THREADS_GET,
61 .doit = nfsd_nl_threads_get_doit,
62 .flags = GENL_CMD_CAP_DO,
63 },
64 {
65 .cmd = NFSD_CMD_VERSION_SET,
66 .doit = nfsd_nl_version_set_doit,
67 .policy = nfsd_version_set_nl_policy,
68 .maxattr = NFSD_A_SERVER_PROTO_VERSION,
69 .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
70 },
71 {
72 .cmd = NFSD_CMD_VERSION_GET,
73 .doit = nfsd_nl_version_get_doit,
74 .flags = GENL_CMD_CAP_DO,
75 },
76 {
77 .cmd = NFSD_CMD_LISTENER_SET,
78 .doit = nfsd_nl_listener_set_doit,
79 .policy = nfsd_listener_set_nl_policy,
80 .maxattr = NFSD_A_SERVER_SOCK_ADDR,
81 .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
82 },
83 {
84 .cmd = NFSD_CMD_LISTENER_GET,
85 .doit = nfsd_nl_listener_get_doit,
86 .flags = GENL_CMD_CAP_DO,
87 },
22};88};
23 89
24struct genl_family nfsd_nl_family __ro_after_init = {90struct genl_family nfsd_nl_family __ro_after_init = {
fs/nfsd/netlink.h+10−0
@@ -11,11 +11,21 @@ · 10 unmodified lines
11 11
12#include <uapi/linux/nfsd_netlink.h>12#include <uapi/linux/nfsd_netlink.h>
13 13
14/* Common nested types */
15extern const struct nla_policy nfsd_sock_nl_policy[NFSD_A_SOCK_TRANSPORT_NAME + 1];
16extern const struct nla_policy nfsd_version_nl_policy[NFSD_A_VERSION_ENABLED + 1];
17
14int nfsd_nl_rpc_status_get_start(struct netlink_callback *cb);18int nfsd_nl_rpc_status_get_start(struct netlink_callback *cb);
15int nfsd_nl_rpc_status_get_done(struct netlink_callback *cb);19int nfsd_nl_rpc_status_get_done(struct netlink_callback *cb);
16 20
17int nfsd_nl_rpc_status_get_dumpit(struct sk_buff *skb,21int nfsd_nl_rpc_status_get_dumpit(struct sk_buff *skb,
18 struct netlink_callback *cb);22 struct netlink_callback *cb);
23int nfsd_nl_threads_set_doit(struct sk_buff *skb, struct genl_info *info);
24int nfsd_nl_threads_get_doit(struct sk_buff *skb, struct genl_info *info);
25int nfsd_nl_version_set_doit(struct sk_buff *skb, struct genl_info *info);
26int nfsd_nl_version_get_doit(struct sk_buff *skb, struct genl_info *info);
27int nfsd_nl_listener_set_doit(struct sk_buff *skb, struct genl_info *info);
28int nfsd_nl_listener_get_doit(struct sk_buff *skb, struct genl_info *info);
19 29
20extern struct genl_family nfsd_nl_family;30extern struct genl_family nfsd_nl_family;
21 31
fs/nfsd/netns.h+1−0
@@ -218,6 +218,7 @@ struct nfsd_net { · 217 unmodified lines
218/* Simple check to find out if a given net was properly initialized */218/* Simple check to find out if a given net was properly initialized */
219#define nfsd_netns_ready(nn) ((nn)->sessionid_hashtbl)219#define nfsd_netns_ready(nn) ((nn)->sessionid_hashtbl)
220 220
221extern bool nfsd_support_version(int vers);
221extern void nfsd_netns_free_versions(struct nfsd_net *nn);222extern void nfsd_netns_free_versions(struct nfsd_net *nn);
222 223
223extern unsigned int nfsd_net_id;224extern unsigned int nfsd_net_id;
fs/nfsd/nfs4callback.c+9−22
@@ -978,12 +978,12 @@ static int max_cb_time(struct net *net) · 977 unmodified lines
978 return max(((u32)nn->nfsd4_lease)/10, 1u) * HZ;978 return max(((u32)nn->nfsd4_lease)/10, 1u) * HZ;
979}979}
980 980
981static struct workqueue_struct *callback_wq;
982
983static bool nfsd4_queue_cb(struct nfsd4_callback *cb)981static bool nfsd4_queue_cb(struct nfsd4_callback *cb)
984{982{
985 trace_nfsd_cb_queue(cb->cb_clp, cb);983 struct nfs4_client *clp = cb->cb_clp;
986 return queue_work(callback_wq, &cb->cb_work);984
985 trace_nfsd_cb_queue(clp, cb);
986 return queue_work(clp->cl_callback_wq, &cb->cb_work);
987}987}
988 988
989static void nfsd41_cb_inflight_begin(struct nfs4_client *clp)989static void nfsd41_cb_inflight_begin(struct nfs4_client *clp)
@@ -1153,7 +1153,7 @@ void nfsd4_probe_callback(struct nfs4_client *clp) · 163 unmodified lines
1153void nfsd4_probe_callback_sync(struct nfs4_client *clp)1153void nfsd4_probe_callback_sync(struct nfs4_client *clp)
1154{1154{
1155 nfsd4_probe_callback(clp);1155 nfsd4_probe_callback(clp);
1156 flush_workqueue(callback_wq);1156 flush_workqueue(clp->cl_callback_wq);
1157}1157}
1158 1158
1159void nfsd4_change_callback(struct nfs4_client *clp, struct nfs4_cb_conn *conn)1159void nfsd4_change_callback(struct nfs4_client *clp, struct nfs4_cb_conn *conn)
@@ -1372,19 +1372,6 @@ static const struct rpc_call_ops nfsd4_cb_ops = { · 212 unmodified lines
1372 .rpc_release = nfsd4_cb_release,1372 .rpc_release = nfsd4_cb_release,
1373};1373};
1374 1374
1375int nfsd4_create_callback_queue(void)
1376{
1377 callback_wq = alloc_ordered_workqueue("nfsd4_callbacks", 0);
1378 if (!callback_wq)
1379 return -ENOMEM;
1380 return 0;
1381}
1382
1383void nfsd4_destroy_callback_queue(void)
1384{
1385 destroy_workqueue(callback_wq);
1386}
1387
1388/* must be called under the state lock */1375/* must be called under the state lock */
1389void nfsd4_shutdown_callback(struct nfs4_client *clp)1376void nfsd4_shutdown_callback(struct nfs4_client *clp)
1390{1377{
@@ -1398,7 +1385,7 @@ void nfsd4_shutdown_callback(struct nfs4_client *clp) · 7 unmodified lines
1398 * client, destroy the rpc client, and stop:1385 * client, destroy the rpc client, and stop:
1399 */1386 */
1400 nfsd4_run_cb(&clp->cl_cb_null);1387 nfsd4_run_cb(&clp->cl_cb_null);
1401 flush_workqueue(callback_wq);1388 flush_workqueue(clp->cl_callback_wq);
1402 nfsd41_cb_inflight_wait_complete(clp);1389 nfsd41_cb_inflight_wait_complete(clp);
1403}1390}
1404 1391
@@ -1420,9 +1407,9 @@ static struct nfsd4_conn * __nfsd4_find_backchannel(struct nfs4_client *clp) · 15 unmodified lines
1420 1407
1421/*1408/*
1422 * Note there isn't a lot of locking in this code; instead we depend on1409 * Note there isn't a lot of locking in this code; instead we depend on
1423 * the fact that it is run from the callback_wq, which won't run two1410 * the fact that it is run from clp->cl_callback_wq, which won't run two
1424 * work items at once. So, for example, callback_wq handles all access1411 * work items at once. So, for example, clp->cl_callback_wq handles all
1425 * of cl_cb_client and all calls to rpc_create or rpc_shutdown_client.1412 * access of cl_cb_client and all calls to rpc_create or rpc_shutdown_client.
1426 */1413 */
1427static void nfsd4_process_cb_update(struct nfsd4_callback *cb)1414static void nfsd4_process_cb_update(struct nfsd4_callback *cb)
1428{1415{
fs/nfsd/nfs4proc.c+66−13
@@ -1737,7 +1737,7 @@ static void cleanup_async_copy(struct nfsd4_copy *copy) · 1736 unmodified lines
1737 nfs4_put_copy(copy);1737 nfs4_put_copy(copy);
1738}1738}
1739 1739
1740static void nfsd4_send_cb_offload(struct nfsd4_copy *copy, __be32 nfserr)1740static void nfsd4_send_cb_offload(struct nfsd4_copy *copy)
1741{1741{
1742 struct nfsd4_cb_offload *cbo;1742 struct nfsd4_cb_offload *cbo;
1743 1743
@@ -1747,12 +1747,12 @@ static void nfsd4_send_cb_offload(struct nfsd4_copy *copy, __be32 nfserr) · 3 unmodified lines
1747 1747
1748 memcpy(&cbo->co_res, &copy->cp_res, sizeof(copy->cp_res));1748 memcpy(&cbo->co_res, &copy->cp_res, sizeof(copy->cp_res));
1749 memcpy(&cbo->co_fh, &copy->fh, sizeof(copy->fh));1749 memcpy(&cbo->co_fh, &copy->fh, sizeof(copy->fh));
1750 cbo->co_nfserr = nfserr;1750 cbo->co_nfserr = copy->nfserr;
1751 1751
1752 nfsd4_init_cb(&cbo->co_cb, copy->cp_clp, &nfsd4_cb_offload_ops,1752 nfsd4_init_cb(&cbo->co_cb, copy->cp_clp, &nfsd4_cb_offload_ops,
1753 NFSPROC4_CLNT_CB_OFFLOAD);1753 NFSPROC4_CLNT_CB_OFFLOAD);
1754 trace_nfsd_cb_offload(copy->cp_clp, &cbo->co_res.cb_stateid,1754 trace_nfsd_cb_offload(copy->cp_clp, &cbo->co_res.cb_stateid,
1755 &cbo->co_fh, copy->cp_count, nfserr);1755 &cbo->co_fh, copy->cp_count, copy->nfserr);
1756 nfsd4_run_cb(&cbo->co_cb);1756 nfsd4_run_cb(&cbo->co_cb);
1757}1757}
1758 1758
@@ -1766,7 +1766,6 @@ static void nfsd4_send_cb_offload(struct nfsd4_copy *copy, __be32 nfserr) · 7 unmodified lines
1766static int nfsd4_do_async_copy(void *data)1766static int nfsd4_do_async_copy(void *data)
1767{1767{
1768 struct nfsd4_copy *copy = (struct nfsd4_copy *)data;1768 struct nfsd4_copy *copy = (struct nfsd4_copy *)data;
1769 __be32 nfserr;
1770 1769
1771 trace_nfsd_copy_do_async(copy);1770 trace_nfsd_copy_do_async(copy);
1772 if (nfsd4_ssc_is_inter(copy)) {1771 if (nfsd4_ssc_is_inter(copy)) {
@@ -1777,24 +1776,25 @@ static int nfsd4_do_async_copy(void *data) · 4 unmodified lines
1777 if (IS_ERR(filp)) {1776 if (IS_ERR(filp)) {
1778 switch (PTR_ERR(filp)) {1777 switch (PTR_ERR(filp)) {
1779 case -EBADF:1778 case -EBADF:
1780 nfserr = nfserr_wrong_type;1779 copy->nfserr = nfserr_wrong_type;
1781 break;1780 break;
1782 default:1781 default:
1783 nfserr = nfserr_offload_denied;1782 copy->nfserr = nfserr_offload_denied;
1784 }1783 }
1785 /* ss_mnt will be unmounted by the laundromat */1784 /* ss_mnt will be unmounted by the laundromat */
1786 goto do_callback;1785 goto do_callback;
1787 }1786 }
1788 nfserr = nfsd4_do_copy(copy, filp, copy->nf_dst->nf_file,1787 copy->nfserr = nfsd4_do_copy(copy, filp, copy->nf_dst->nf_file,
1789 false);1788 false);
1790 nfsd4_cleanup_inter_ssc(copy->ss_nsui, filp, copy->nf_dst);1789 nfsd4_cleanup_inter_ssc(copy->ss_nsui, filp, copy->nf_dst);
1791 } else {1790 } else {
1792 nfserr = nfsd4_do_copy(copy, copy->nf_src->nf_file,1791 copy->nfserr = nfsd4_do_copy(copy, copy->nf_src->nf_file,
1793 copy->nf_dst->nf_file, false);1792 copy->nf_dst->nf_file, false);
1794 }1793 }
1795 1794
1796do_callback:1795do_callback:
1797 nfsd4_send_cb_offload(copy, nfserr);1796 set_bit(NFSD4_COPY_F_COMPLETED, &copy->cp_flags);
1797 nfsd4_send_cb_offload(copy);
1798 cleanup_async_copy(copy);1798 cleanup_async_copy(copy);
1799 return 0;1799 return 0;
1800}1800}
@@ -1807,6 +1807,13 @@ nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, · 6 unmodified lines
1807 __be32 status;1807 __be32 status;
1808 struct nfsd4_copy *async_copy = NULL;1808 struct nfsd4_copy *async_copy = NULL;
1809 1809
1810 /*
1811 * Currently, async COPY is not reliable. Force all COPY
1812 * requests to be synchronous to avoid client application
1813 * hangs waiting for COPY completion.
1814 */
1815 nfsd4_copy_set_sync(copy, true);
1816
1810 copy->cp_clp = cstate->clp;1817 copy->cp_clp = cstate->clp;
1811 if (nfsd4_ssc_is_inter(copy)) {1818 if (nfsd4_ssc_is_inter(copy)) {
1812 trace_nfsd_copy_inter(copy);1819 trace_nfsd_copy_inter(copy);
@@ -2003,11 +2010,16 @@ nfsd4_offload_status(struct svc_rqst *rqstp, · 190 unmodified lines
2003 struct nfsd4_copy *copy;2010 struct nfsd4_copy *copy;
2004 struct nfs4_client *clp = cstate->clp;2011 struct nfs4_client *clp = cstate->clp;
2005 2012
2013 os->completed = false;
2006 spin_lock(&clp->async_lock);2014 spin_lock(&clp->async_lock);
2007 copy = find_async_copy_locked(clp, &os->stateid);2015 copy = find_async_copy_locked(clp, &os->stateid);
2008 if (copy)2016 if (copy) {
2009 os->count = copy->cp_res.wr_bytes_written;2017 os->count = copy->cp_res.wr_bytes_written;
2010 else2018 if (test_bit(NFSD4_COPY_F_COMPLETED, &copy->cp_flags)) {
2019 os->completed = true;
2020 os->status = copy->nfserr;
2021 }
2022 } else
2011 status = nfserr_bad_stateid;2023 status = nfserr_bad_stateid;
2012 spin_unlock(&clp->async_lock);2024 spin_unlock(&clp->async_lock);
2013 2025
@@ -2154,6 +2166,29 @@ nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, · 140 unmodified lines
2154 return status == nfserr_same ? nfs_ok : status;2166 return status == nfserr_same ? nfs_ok : status;
2155}2167}
2156 2168
2169static __be32
2170nfsd4_get_dir_delegation(struct svc_rqst *rqstp,
2171 struct nfsd4_compound_state *cstate,
2172 union nfsd4_op_u *u)
2173{
2174 struct nfsd4_get_dir_delegation *gdd = &u->get_dir_delegation;
2175
2176 /*
2177 * RFC 8881, section 18.39.3 says:
2178 *
2179 * "The server may refuse to grant the delegation. In that case, the
2180 * server will return NFS4ERR_DIRDELEG_UNAVAIL."
2181 *
2182 * This is sub-optimal, since it means that the server would need to
2183 * abort compound processing just because the delegation wasn't
2184 * available. RFC8881bis should change this to allow the server to
2185 * return NFS4_OK with a non-fatal status of GDD4_UNAVAIL in this
2186 * situation.
2187 */
2188 gdd->gddrnf_status = GDD4_UNAVAIL;
2189 return nfs_ok;
2190}
2191
2157#ifdef CONFIG_NFSD_PNFS2192#ifdef CONFIG_NFSD_PNFS
2158static const struct nfsd4_layout_ops *2193static const struct nfsd4_layout_ops *
2159nfsd4_layout_verify(struct svc_export *exp, unsigned int layout_type)2194nfsd4_layout_verify(struct svc_export *exp, unsigned int layout_type)
@@ -3082,6 +3117,18 @@ static u32 nfsd4_copy_notify_rsize(const struct svc_rqst *rqstp, · 922 unmodified lines
3082 * sizeof(__be32);3117 * sizeof(__be32);
3083}3118}
3084 3119
3120static u32 nfsd4_get_dir_delegation_rsize(const struct svc_rqst *rqstp,
3121 const struct nfsd4_op *op)
3122{
3123 return (op_encode_hdr_size +
3124 1 /* gddr_status */ +
3125 op_encode_verifier_maxsz +
3126 op_encode_stateid_maxsz +
3127 2 /* gddr_notification */ +
3128 2 /* gddr_child_attributes */ +
3129 2 /* gddr_dir_attributes */);
3130}
3131
3085#ifdef CONFIG_NFSD_PNFS3132#ifdef CONFIG_NFSD_PNFS
3086static u32 nfsd4_getdeviceinfo_rsize(const struct svc_rqst *rqstp,3133static u32 nfsd4_getdeviceinfo_rsize(const struct svc_rqst *rqstp,
3087 const struct nfsd4_op *op)3134 const struct nfsd4_op *op)
@@ -3470,6 +3517,12 @@ static const struct nfsd4_operation nfsd4_ops[] = { · 382 unmodified lines
3470 .op_get_currentstateid = nfsd4_get_freestateid,3517 .op_get_currentstateid = nfsd4_get_freestateid,
3471 .op_rsize_bop = nfsd4_only_status_rsize,3518 .op_rsize_bop = nfsd4_only_status_rsize,
3472 },3519 },
3520 [OP_GET_DIR_DELEGATION] = {
3521 .op_func = nfsd4_get_dir_delegation,
3522 .op_flags = OP_MODIFIES_SOMETHING,
3523 .op_name = "OP_GET_DIR_DELEGATION",
3524 .op_rsize_bop = nfsd4_get_dir_delegation_rsize,
3525 },
3473#ifdef CONFIG_NFSD_PNFS3526#ifdef CONFIG_NFSD_PNFS
3474 [OP_GETDEVICEINFO] = {3527 [OP_GETDEVICEINFO] = {
3475 .op_func = nfsd4_getdeviceinfo,3528 .op_func = nfsd4_getdeviceinfo,
fs/nfsd/nfs4state.c+104−84
@@ -541,7 +541,7 @@ same_owner_str(struct nfs4_stateowner *sop, struct xdr_netobj *owner) · 540 unmodified lines
541}541}
542 542
543static struct nfs4_openowner *543static struct nfs4_openowner *
544find_openstateowner_str_locked(unsigned int hashval, struct nfsd4_open *open,544find_openstateowner_str(unsigned int hashval, struct nfsd4_open *open,
545 struct nfs4_client *clp)545 struct nfs4_client *clp)
546{546{
547 struct nfs4_stateowner *so;547 struct nfs4_stateowner *so;
@@ -558,18 +558,6 @@ find_openstateowner_str_locked(unsigned int hashval, struct nfsd4_open *open, · 10 unmodified lines
558 return NULL;558 return NULL;
559}559}
560 560
561static struct nfs4_openowner *
562find_openstateowner_str(unsigned int hashval, struct nfsd4_open *open,
563 struct nfs4_client *clp)
564{
565 struct nfs4_openowner *oo;
566
567 spin_lock(&clp->cl_lock);
568 oo = find_openstateowner_str_locked(hashval, open, clp);
569 spin_unlock(&clp->cl_lock);
570 return oo;
571}
572
573static inline u32561static inline u32
574opaque_hashval(const void *ptr, int nbytes)562opaque_hashval(const void *ptr, int nbytes)
575{563{
@@ -1409,11 +1397,16 @@ static void · 833 unmodified lines
1409recalculate_deny_mode(struct nfs4_file *fp)1397recalculate_deny_mode(struct nfs4_file *fp)
1410{1398{
1411 struct nfs4_ol_stateid *stp;1399 struct nfs4_ol_stateid *stp;
1400 u32 old_deny;
1412 1401
1413 spin_lock(&fp->fi_lock);1402 spin_lock(&fp->fi_lock);
1403 old_deny = fp->fi_share_deny;
1414 fp->fi_share_deny = 0;1404 fp->fi_share_deny = 0;
1415 list_for_each_entry(stp, &fp->fi_stateids, st_perfile)1405 list_for_each_entry(stp, &fp->fi_stateids, st_perfile) {
1416 fp->fi_share_deny |= bmap_to_share_mode(stp->st_deny_bmap);1406 fp->fi_share_deny |= bmap_to_share_mode(stp->st_deny_bmap);
1407 if (fp->fi_share_deny == old_deny)
1408 break;
1409 }
1417 spin_unlock(&fp->fi_lock);1410 spin_unlock(&fp->fi_lock);
1418}1411}
1419 1412
@@ -2245,6 +2238,10 @@ static struct nfs4_client *alloc_client(struct xdr_netobj name, · 825 unmodified lines
2245 GFP_KERNEL);2238 GFP_KERNEL);
2246 if (!clp->cl_ownerstr_hashtbl)2239 if (!clp->cl_ownerstr_hashtbl)
2247 goto err_no_hashtbl;2240 goto err_no_hashtbl;
2241 clp->cl_callback_wq = alloc_ordered_workqueue("nfsd4_callbacks", 0);
2242 if (!clp->cl_callback_wq)
2243 goto err_no_callback_wq;
2244
2248 for (i = 0; i < OWNER_HASH_SIZE; i++)2245 for (i = 0; i < OWNER_HASH_SIZE; i++)
2249 INIT_LIST_HEAD(&clp->cl_ownerstr_hashtbl[i]);2246 INIT_LIST_HEAD(&clp->cl_ownerstr_hashtbl[i]);
2250 INIT_LIST_HEAD(&clp->cl_sessions);2247 INIT_LIST_HEAD(&clp->cl_sessions);
@@ -2267,6 +2264,8 @@ static struct nfs4_client *alloc_client(struct xdr_netobj name, · 16 unmodified lines
2267 spin_lock_init(&clp->cl_lock);2264 spin_lock_init(&clp->cl_lock);
2268 rpc_init_wait_queue(&clp->cl_cb_waitq, "Backchannel slot table");2265 rpc_init_wait_queue(&clp->cl_cb_waitq, "Backchannel slot table");
2269 return clp;2266 return clp;
2267err_no_callback_wq:
2268 kfree(clp->cl_ownerstr_hashtbl);
2270err_no_hashtbl:2269err_no_hashtbl:
2271 kfree(clp->cl_name.data);2270 kfree(clp->cl_name.data);
2272err_no_name:2271err_no_name:
@@ -2280,6 +2279,7 @@ static void __free_client(struct kref *k) · 7 unmodified lines
2280 struct nfs4_client *clp = container_of(c, struct nfs4_client, cl_nfsdfs);2279 struct nfs4_client *clp = container_of(c, struct nfs4_client, cl_nfsdfs);
2281 2280
2282 free_svc_cred(&clp->cl_cred);2281 free_svc_cred(&clp->cl_cred);
2282 destroy_workqueue(clp->cl_callback_wq);
2283 kfree(clp->cl_ownerstr_hashtbl);2283 kfree(clp->cl_ownerstr_hashtbl);
2284 kfree(clp->cl_name.data);2284 kfree(clp->cl_name.data);
2285 kfree(clp->cl_nii_domain.data);2285 kfree(clp->cl_nii_domain.data);
@@ -2352,7 +2352,11 @@ unhash_client(struct nfs4_client *clp) · 66 unmodified lines
2352 2352
2353static __be32 mark_client_expired_locked(struct nfs4_client *clp)2353static __be32 mark_client_expired_locked(struct nfs4_client *clp)
2354{2354{
2355 if (atomic_read(&clp->cl_rpc_users))2355 int users = atomic_read(&clp->cl_rpc_users);
2356
2357 trace_nfsd_mark_client_expired(clp, users);
2358
2359 if (users)
2356 return nfserr_jukebox;2360 return nfserr_jukebox;
2357 unhash_client_locked(clp);2361 unhash_client_locked(clp);
2358 return nfs_ok;2362 return nfs_ok;
@@ -3641,12 +3645,8 @@ out_nolock: · 1282 unmodified lines
3641 return status;3645 return status;
3642}3646}
3643 3647
3644static __be323648static __be32 check_slot_seqid(u32 seqid, u32 slot_seqid, bool slot_inuse)
3645check_slot_seqid(u32 seqid, u32 slot_seqid, int slot_inuse)
3646{3649{
3647 dprintk("%s enter. seqid %d slot_seqid %d\n", __func__, seqid,
3648 slot_seqid);
3649
3650 /* The slot is in use, and no response has been sent. */3650 /* The slot is in use, and no response has been sent. */
3651 if (slot_inuse) {3651 if (slot_inuse) {
3652 if (seqid == slot_seqid)3652 if (seqid == slot_seqid)
@@ -3823,10 +3823,13 @@ nfsd4_create_session(struct svc_rqst *rqstp, · 170 unmodified lines
3823 }3823 }
3824 3824
3825 /* RFC 8881 Section 18.36.4 Phase 2: Sequence ID processing. */3825 /* RFC 8881 Section 18.36.4 Phase 2: Sequence ID processing. */
3826 if (conf)3826 if (conf) {
3827 cs_slot = &conf->cl_cs_slot;3827 cs_slot = &conf->cl_cs_slot;
3828 else3828 trace_nfsd_slot_seqid_conf(conf, cr_ses);
3829 } else {
3829 cs_slot = &unconf->cl_cs_slot;3830 cs_slot = &unconf->cl_cs_slot;
3831 trace_nfsd_slot_seqid_unconf(unconf, cr_ses);
3832 }
3830 status = check_slot_seqid(cr_ses->seqid, cs_slot->sl_seqid, 0);3833 status = check_slot_seqid(cr_ses->seqid, cs_slot->sl_seqid, 0);
3831 switch (status) {3834 switch (status) {
3832 case nfs_ok:3835 case nfs_ok:
@@ -4221,6 +4224,7 @@ nfsd4_sequence(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, · 388 unmodified lines
4221 * sr_highest_slotid and the sr_target_slot id to maxslots */4224 * sr_highest_slotid and the sr_target_slot id to maxslots */
4222 seq->maxslots = session->se_fchannel.maxreqs;4225 seq->maxslots = session->se_fchannel.maxreqs;
4223 4226
4227 trace_nfsd_slot_seqid_sequence(clp, seq, slot);
4224 status = check_slot_seqid(seq->seqid, slot->sl_seqid,4228 status = check_slot_seqid(seq->seqid, slot->sl_seqid,
4225 slot->sl_flags & NFSD4_SLOT_INUSE);4229 slot->sl_flags & NFSD4_SLOT_INUSE);
4226 if (status == nfserr_replay_cache) {4230 if (status == nfserr_replay_cache) {
@@ -4662,21 +4666,32 @@ nfsd4_init_leases_net(struct nfsd_net *nn) · 435 unmodified lines
4662 atomic_set(&nn->nfsd_courtesy_clients, 0);4666 atomic_set(&nn->nfsd_courtesy_clients, 0);
4663}4667}
4664 4668
4669enum rp_lock {
4670 RP_UNLOCKED,
4671 RP_LOCKED,
4672 RP_UNHASHED,
4673};
4674
4665static void init_nfs4_replay(struct nfs4_replay *rp)4675static void init_nfs4_replay(struct nfs4_replay *rp)
4666{4676{
4667 rp->rp_status = nfserr_serverfault;4677 rp->rp_status = nfserr_serverfault;
4668 rp->rp_buflen = 0;4678 rp->rp_buflen = 0;
4669 rp->rp_buf = rp->rp_ibuf;4679 rp->rp_buf = rp->rp_ibuf;
4670 mutex_init(&rp->rp_mutex);4680 atomic_set(&rp->rp_locked, RP_UNLOCKED);
4671}4681}
4672 4682
4673static void nfsd4_cstate_assign_replay(struct nfsd4_compound_state *cstate,4683static int nfsd4_cstate_assign_replay(struct nfsd4_compound_state *cstate,
4674 struct nfs4_stateowner *so)4684 struct nfs4_stateowner *so)
4675{4685{
4676 if (!nfsd4_has_session(cstate)) {4686 if (!nfsd4_has_session(cstate)) {
4677 mutex_lock(&so->so_replay.rp_mutex);4687 wait_var_event(&so->so_replay.rp_locked,
4688 atomic_cmpxchg(&so->so_replay.rp_locked,
4689 RP_UNLOCKED, RP_LOCKED) != RP_LOCKED);
4690 if (atomic_read(&so->so_replay.rp_locked) == RP_UNHASHED)
4691 return -EAGAIN;
4678 cstate->replay_owner = nfs4_get_stateowner(so);4692 cstate->replay_owner = nfs4_get_stateowner(so);
4679 }4693 }
4694 return 0;
4680}4695}
4681 4696
4682void nfsd4_cstate_clear_replay(struct nfsd4_compound_state *cstate)4697void nfsd4_cstate_clear_replay(struct nfsd4_compound_state *cstate)
@@ -4685,7 +4700,8 @@ void nfsd4_cstate_clear_replay(struct nfsd4_compound_state *cstate) · 2 unmodified lines
4685 4700
4686 if (so != NULL) {4701 if (so != NULL) {
4687 cstate->replay_owner = NULL;4702 cstate->replay_owner = NULL;
4688 mutex_unlock(&so->so_replay.rp_mutex);4703 atomic_set(&so->so_replay.rp_locked, RP_UNLOCKED);
4704 wake_up_var(&so->so_replay.rp_locked);
4689 nfs4_put_stateowner(so);4705 nfs4_put_stateowner(so);
4690 }4706 }
4691}4707}
@@ -4866,34 +4882,46 @@ nfsd4_find_and_lock_existing_open(struct nfs4_file *fp, struct nfsd4_open *open) · 174 unmodified lines
4866}4882}
4867 4883
4868static struct nfs4_openowner *4884static struct nfs4_openowner *
4869alloc_init_open_stateowner(unsigned int strhashval, struct nfsd4_open *open,4885find_or_alloc_open_stateowner(unsigned int strhashval, struct nfsd4_open *open,
4870 struct nfsd4_compound_state *cstate)4886 struct nfsd4_compound_state *cstate)
4871{4887{
4872 struct nfs4_client *clp = cstate->clp;4888 struct nfs4_client *clp = cstate->clp;
4873 struct nfs4_openowner *oo, *ret;4889 struct nfs4_openowner *oo, *new = NULL;
4874 4890
4875 oo = alloc_stateowner(openowner_slab, &open->op_owner, clp);4891retry:
4876 if (!oo)
4877 return NULL;
4878 oo->oo_owner.so_ops = &openowner_ops;
4879 oo->oo_owner.so_is_open_owner = 1;
4880 oo->oo_owner.so_seqid = open->op_seqid;
4881 oo->oo_flags = 0;
4882 if (nfsd4_has_session(cstate))
4883 oo->oo_flags |= NFS4_OO_CONFIRMED;
4884 oo->oo_time = 0;
4885 oo->oo_last_closed_stid = NULL;
4886 INIT_LIST_HEAD(&oo->oo_close_lru);
4887 spin_lock(&clp->cl_lock);4892 spin_lock(&clp->cl_lock);
4888 ret = find_openstateowner_str_locked(strhashval, open, clp);4893 oo = find_openstateowner_str(strhashval, open, clp);
4889 if (ret == NULL) {4894 if (!oo && new) {
4890 hash_openowner(oo, clp, strhashval);4895 hash_openowner(new, clp, strhashval);
4891 ret = oo;4896 spin_unlock(&clp->cl_lock);
4892 } else4897 return new;
4893 nfs4_free_stateowner(&oo->oo_owner);4898 }
4894
4895 spin_unlock(&clp->cl_lock);4899 spin_unlock(&clp->cl_lock);
4896 return ret;4900
4901 if (oo && !(oo->oo_flags & NFS4_OO_CONFIRMED)) {
4902 /* Replace unconfirmed owners without checking for replay. */
4903 release_openowner(oo);
4904 oo = NULL;
4905 }
4906 if (oo) {
4907 if (new)
4908 nfs4_free_stateowner(&new->oo_owner);
4909 return oo;
4910 }
4911
4912 new = alloc_stateowner(openowner_slab, &open->op_owner, clp);
4913 if (!new)
4914 return NULL;
4915 new->oo_owner.so_ops = &openowner_ops;
4916 new->oo_owner.so_is_open_owner = 1;
4917 new->oo_owner.so_seqid = open->op_seqid;
4918 new->oo_flags = 0;
4919 if (nfsd4_has_session(cstate))
4920 new->oo_flags |= NFS4_OO_CONFIRMED;
4921 new->oo_time = 0;
4922 new->oo_last_closed_stid = NULL;
4923 INIT_LIST_HEAD(&new->oo_close_lru);
4924 goto retry;
4897}4925}
4898 4926
4899static struct nfs4_ol_stateid *4927static struct nfs4_ol_stateid *
@@ -4969,7 +4997,11 @@ move_to_close_lru(struct nfs4_ol_stateid *s, struct net *net) · 69 unmodified lines
4969 * Wait for the refcount to drop to 2. Since it has been unhashed,4997 * Wait for the refcount to drop to 2. Since it has been unhashed,
4970 * there should be no danger of the refcount going back up again at4998 * there should be no danger of the refcount going back up again at
4971 * this point.4999 * this point.
5000 * Some threads with a reference might be waiting for rp_locked,
5001 * so tell them to stop waiting.
4972 */5002 */
5003 atomic_set(&oo->oo_owner.so_replay.rp_locked, RP_UNHASHED);
5004 wake_up_var(&oo->oo_owner.so_replay.rp_locked);
4973 wait_event(close_wq, refcount_read(&s->st_stid.sc_count) == 2);5005 wait_event(close_wq, refcount_read(&s->st_stid.sc_count) == 2);
4974 5006
4975 release_all_access(s);5007 release_all_access(s);
@@ -5342,27 +5374,19 @@ nfsd4_process_open1(struct nfsd4_compound_state *cstate, · 366 unmodified lines
5342 clp = cstate->clp;5374 clp = cstate->clp;
5343 5375
5344 strhashval = ownerstr_hashval(&open->op_owner);5376 strhashval = ownerstr_hashval(&open->op_owner);
5345 oo = find_openstateowner_str(strhashval, open, clp);5377retry:
5378 oo = find_or_alloc_open_stateowner(strhashval, open, cstate);
5346 open->op_openowner = oo;5379 open->op_openowner = oo;
5347 if (!oo) {5380 if (!oo)
5348 goto new_owner;5381 return nfserr_jukebox;
5349 }5382 if (nfsd4_cstate_assign_replay(cstate, &oo->oo_owner) == -EAGAIN) {
5350 if (!(oo->oo_flags & NFS4_OO_CONFIRMED)) {5383 nfs4_put_stateowner(&oo->oo_owner);
5351 /* Replace unconfirmed owners without checking for replay. */5384 goto retry;
5352 release_openowner(oo);
5353 open->op_openowner = NULL;
5354 goto new_owner;
5355 }5385 }
5356 status = nfsd4_check_seqid(cstate, &oo->oo_owner, open->op_seqid);5386 status = nfsd4_check_seqid(cstate, &oo->oo_owner, open->op_seqid);
5357 if (status)5387 if (status)
5358 return status;5388 return status;
5359 goto alloc_stateid;5389
5360new_owner:
5361 oo = alloc_init_open_stateowner(strhashval, open, cstate);
5362 if (oo == NULL)
5363 return nfserr_jukebox;
5364 open->op_openowner = oo;
5365alloc_stateid:
5366 open->op_stp = nfs4_alloc_open_stateid(clp);5390 open->op_stp = nfs4_alloc_open_stateid(clp);
5367 if (!open->op_stp)5391 if (!open->op_stp)
5368 return nfserr_jukebox;5392 return nfserr_jukebox;
@@ -6133,12 +6157,8 @@ out: · 764 unmodified lines
6133void nfsd4_cleanup_open_state(struct nfsd4_compound_state *cstate,6157void nfsd4_cleanup_open_state(struct nfsd4_compound_state *cstate,
6134 struct nfsd4_open *open)6158 struct nfsd4_open *open)
6135{6159{
6136 if (open->op_openowner) {6160 if (open->op_openowner)
6137 struct nfs4_stateowner *so = &open->op_openowner->oo_owner;6161 nfs4_put_stateowner(&open->op_openowner->oo_owner);
6138
6139 nfsd4_cstate_assign_replay(cstate, so);
6140 nfs4_put_stateowner(so);
6141 }
6142 if (open->op_file)6162 if (open->op_file)
6143 kmem_cache_free(file_slab, open->op_file);6163 kmem_cache_free(file_slab, open->op_file);
6144 if (open->op_stp)6164 if (open->op_stp)
@@ -7202,12 +7222,16 @@ nfs4_preprocess_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid, · 1057 unmodified lines
7202 trace_nfsd_preprocess(seqid, stateid);7222 trace_nfsd_preprocess(seqid, stateid);
7203 7223
7204 *stpp = NULL;7224 *stpp = NULL;
7225retry:
7205 status = nfsd4_lookup_stateid(cstate, stateid,7226 status = nfsd4_lookup_stateid(cstate, stateid,
7206 typemask, statusmask, &s, nn);7227 typemask, statusmask, &s, nn);
7207 if (status)7228 if (status)
7208 return status;7229 return status;
7209 stp = openlockstateid(s);7230 stp = openlockstateid(s);
7210 nfsd4_cstate_assign_replay(cstate, stp->st_stateowner);7231 if (nfsd4_cstate_assign_replay(cstate, stp->st_stateowner) == -EAGAIN) {
7232 nfs4_put_stateowner(stp->st_stateowner);
7233 goto retry;
7234 }
7211 7235
7212 status = nfs4_seqid_op_checks(cstate, stateid, seqid, stp);7236 status = nfs4_seqid_op_checks(cstate, stateid, seqid, stp);
7213 if (!status)7237 if (!status)
@@ -7349,7 +7373,7 @@ out: · 135 unmodified lines
7349 return status;7373 return status;
7350}7374}
7351 7375
7352static void nfsd4_close_open_stateid(struct nfs4_ol_stateid *s)7376static bool nfsd4_close_open_stateid(struct nfs4_ol_stateid *s)
7353{7377{
7354 struct nfs4_client *clp = s->st_stid.sc_client;7378 struct nfs4_client *clp = s->st_stid.sc_client;
7355 bool unhashed;7379 bool unhashed;
@@ -7366,11 +7390,11 @@ static void nfsd4_close_open_stateid(struct nfs4_ol_stateid *s) · 10 unmodified lines
7366 list_for_each_entry(stp, &reaplist, st_locks)7390 list_for_each_entry(stp, &reaplist, st_locks)
7367 nfs4_free_cpntf_statelist(clp->net, &stp->st_stid);7391 nfs4_free_cpntf_statelist(clp->net, &stp->st_stid);
7368 free_ol_stateid_reaplist(&reaplist);7392 free_ol_stateid_reaplist(&reaplist);
7393 return false;
7369 } else {7394 } else {
7370 spin_unlock(&clp->cl_lock);7395 spin_unlock(&clp->cl_lock);
7371 free_ol_stateid_reaplist(&reaplist);7396 free_ol_stateid_reaplist(&reaplist);
7372 if (unhashed)7397 return unhashed;
7373 move_to_close_lru(s, clp->net);
7374 }7398 }
7375}7399}
7376 7400
@@ -7386,6 +7410,7 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, · 9 unmodified lines
7386 struct nfs4_ol_stateid *stp;7410 struct nfs4_ol_stateid *stp;
7387 struct net *net = SVC_NET(rqstp);7411 struct net *net = SVC_NET(rqstp);
7388 struct nfsd_net *nn = net_generic(net, nfsd_net_id);7412 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
7413 bool need_move_to_close_list;
7389 7414
7390 dprintk("NFSD: nfsd4_close on file %pd\n",7415 dprintk("NFSD: nfsd4_close on file %pd\n",
7391 cstate->current_fh.fh_dentry);7416 cstate->current_fh.fh_dentry);
@@ -7410,8 +7435,10 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, · 18 unmodified lines
7410 */7435 */
7411 nfs4_inc_and_copy_stateid(&close->cl_stateid, &stp->st_stid);7436 nfs4_inc_and_copy_stateid(&close->cl_stateid, &stp->st_stid);
7412 7437
7413 nfsd4_close_open_stateid(stp);7438 need_move_to_close_list = nfsd4_close_open_stateid(stp);
7414 mutex_unlock(&stp->st_mutex);7439 mutex_unlock(&stp->st_mutex);
7440 if (need_move_to_close_list)
7441 move_to_close_lru(stp, net);
7415 7442
7416 /* v4.1+ suggests that we send a special stateid in here, since the7443 /* v4.1+ suggests that we send a special stateid in here, since the
7417 * clients should just ignore this anyway. Since this is not useful7444 * clients should just ignore this anyway. Since this is not useful
@@ -8625,12 +8652,6 @@ nfs4_state_start(void) · 1207 unmodified lines
8625 if (ret)8652 if (ret)
8626 return ret;8653 return ret;
8627 8654
8628 ret = nfsd4_create_callback_queue();
8629 if (ret) {
8630 rhltable_destroy(&nfs4_file_rhltable);
8631 return ret;
8632 }
8633
8634 set_max_delegations();8655 set_max_delegations();
8635 return 0;8656 return 0;
8636}8657}
@@ -8671,7 +8692,6 @@ nfs4_state_shutdown_net(struct net *net) · 34 unmodified lines
8671void8692void
8672nfs4_state_shutdown(void)8693nfs4_state_shutdown(void)
8673{8694{
8674 nfsd4_destroy_callback_queue();
8675 rhltable_destroy(&nfs4_file_rhltable);8695 rhltable_destroy(&nfs4_file_rhltable);
8676}8696}
8677 8697
fs/nfsd/nfs4xdr.c+80−3
@@ -1732,6 +1732,35 @@ nfsd4_decode_free_stateid(struct nfsd4_compoundargs *argp, · 1731 unmodified lines
1732 return nfsd4_decode_stateid4(argp, &free_stateid->fr_stateid);1732 return nfsd4_decode_stateid4(argp, &free_stateid->fr_stateid);
1733}1733}
1734 1734
1735static __be32
1736nfsd4_decode_get_dir_delegation(struct nfsd4_compoundargs *argp,
1737 union nfsd4_op_u *u)
1738{
1739 struct nfsd4_get_dir_delegation *gdd = &u->get_dir_delegation;
1740 __be32 status;
1741
1742 memset(gdd, 0, sizeof(*gdd));
1743
1744 if (xdr_stream_decode_bool(argp->xdr, &gdd->gdda_signal_deleg_avail) < 0)
1745 return nfserr_bad_xdr;
1746 status = nfsd4_decode_bitmap4(argp, gdd->gdda_notification_types,
1747 ARRAY_SIZE(gdd->gdda_notification_types));
1748 if (status)
1749 return status;
1750 status = nfsd4_decode_nfstime4(argp, &gdd->gdda_child_attr_delay);
1751 if (status)
1752 return status;
1753 status = nfsd4_decode_nfstime4(argp, &gdd->gdda_dir_attr_delay);
1754 if (status)
1755 return status;
1756 status = nfsd4_decode_bitmap4(argp, gdd->gdda_child_attributes,
1757 ARRAY_SIZE(gdd->gdda_child_attributes));
1758 if (status)
1759 return status;
1760 return nfsd4_decode_bitmap4(argp, gdd->gdda_dir_attributes,
1761 ARRAY_SIZE(gdd->gdda_dir_attributes));
1762}
1763
1735#ifdef CONFIG_NFSD_PNFS1764#ifdef CONFIG_NFSD_PNFS
1736static __be321765static __be32
1737nfsd4_decode_getdeviceinfo(struct nfsd4_compoundargs *argp,1766nfsd4_decode_getdeviceinfo(struct nfsd4_compoundargs *argp,
@@ -2370,7 +2399,7 @@ static const nfsd4_dec nfsd4_dec_ops[] = { · 632 unmodified lines
2370 [OP_CREATE_SESSION] = nfsd4_decode_create_session,2399 [OP_CREATE_SESSION] = nfsd4_decode_create_session,
2371 [OP_DESTROY_SESSION] = nfsd4_decode_destroy_session,2400 [OP_DESTROY_SESSION] = nfsd4_decode_destroy_session,
2372 [OP_FREE_STATEID] = nfsd4_decode_free_stateid,2401 [OP_FREE_STATEID] = nfsd4_decode_free_stateid,
2373 [OP_GET_DIR_DELEGATION] = nfsd4_decode_notsupp,2402 [OP_GET_DIR_DELEGATION] = nfsd4_decode_get_dir_delegation,
2374#ifdef CONFIG_NFSD_PNFS2403#ifdef CONFIG_NFSD_PNFS
2375 [OP_GETDEVICEINFO] = nfsd4_decode_getdeviceinfo,2404 [OP_GETDEVICEINFO] = nfsd4_decode_getdeviceinfo,
2376 [OP_GETDEVICELIST] = nfsd4_decode_notsupp,2405 [OP_GETDEVICELIST] = nfsd4_decode_notsupp,
@@ -4963,6 +4992,49 @@ nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, __be32 nfserr, · 2586 unmodified lines
4963 return nfs_ok;4992 return nfs_ok;
4964}4993}
4965 4994
4995static __be32
4996nfsd4_encode_get_dir_delegation(struct nfsd4_compoundres *resp, __be32 nfserr,
4997 union nfsd4_op_u *u)
4998{
4999 struct nfsd4_get_dir_delegation *gdd = &u->get_dir_delegation;
5000 struct xdr_stream *xdr = resp->xdr;
5001 __be32 status = nfserr_resource;
5002
5003 switch(gdd->gddrnf_status) {
5004 case GDD4_OK:
5005 if (xdr_stream_encode_u32(xdr, GDD4_OK) != XDR_UNIT)
5006 break;
5007 status = nfsd4_encode_verifier4(xdr, &gdd->gddr_cookieverf);
5008 if (status)
5009 break;
5010 status = nfsd4_encode_stateid4(xdr, &gdd->gddr_stateid);
5011 if (status)
5012 break;
5013 status = nfsd4_encode_bitmap4(xdr, gdd->gddr_notification[0], 0, 0);
5014 if (status)
5015 break;
5016 status = nfsd4_encode_bitmap4(xdr, gdd->gddr_child_attributes[0],
5017 gdd->gddr_child_attributes[1],
5018 gdd->gddr_child_attributes[2]);
5019 if (status)
5020 break;
5021 status = nfsd4_encode_bitmap4(xdr, gdd->gddr_dir_attributes[0],
5022 gdd->gddr_dir_attributes[1],
5023 gdd->gddr_dir_attributes[2]);
5024 break;
5025 default:
5026 pr_warn("nfsd: bad gddrnf_status (%u)\n", gdd->gddrnf_status);
5027 gdd->gddrnf_will_signal_deleg_avail = 0;
5028 fallthrough;
5029 case GDD4_UNAVAIL:
5030 if (xdr_stream_encode_u32(xdr, GDD4_UNAVAIL) != XDR_UNIT)
5031 break;
5032 status = nfsd4_encode_bool(xdr, gdd->gddrnf_will_signal_deleg_avail);
5033 break;
5034 }
5035 return status;
5036}
5037
4966#ifdef CONFIG_NFSD_PNFS5038#ifdef CONFIG_NFSD_PNFS
4967static __be325039static __be32
4968nfsd4_encode_device_addr4(struct xdr_stream *xdr,5040nfsd4_encode_device_addr4(struct xdr_stream *xdr,
@@ -5199,7 +5271,12 @@ nfsd4_encode_offload_status(struct nfsd4_compoundres *resp, __be32 nfserr, · 230 unmodified lines
5199 if (nfserr != nfs_ok)5271 if (nfserr != nfs_ok)
5200 return nfserr;5272 return nfserr;
5201 /* osr_complete<1> */5273 /* osr_complete<1> */
5202 if (xdr_stream_encode_u32(xdr, 0) != XDR_UNIT)5274 if (os->completed) {
5275 if (xdr_stream_encode_u32(xdr, 1) != XDR_UNIT)
5276 return nfserr_resource;
5277 if (xdr_stream_encode_be32(xdr, os->status) != XDR_UNIT)
5278 return nfserr_resource;
5279 } else if (xdr_stream_encode_u32(xdr, 0) != XDR_UNIT)
5203 return nfserr_resource;5280 return nfserr_resource;
5204 return nfs_ok;5281 return nfs_ok;
5205}5282}
@@ -5579,7 +5656,7 @@ static const nfsd4_enc nfsd4_enc_ops[] = { · 373 unmodified lines
5579 [OP_CREATE_SESSION] = nfsd4_encode_create_session,5656 [OP_CREATE_SESSION] = nfsd4_encode_create_session,
5580 [OP_DESTROY_SESSION] = nfsd4_encode_noop,5657 [OP_DESTROY_SESSION] = nfsd4_encode_noop,
5581 [OP_FREE_STATEID] = nfsd4_encode_noop,5658 [OP_FREE_STATEID] = nfsd4_encode_noop,
5582 [OP_GET_DIR_DELEGATION] = nfsd4_encode_noop,5659 [OP_GET_DIR_DELEGATION] = nfsd4_encode_get_dir_delegation,
5583#ifdef CONFIG_NFSD_PNFS5660#ifdef CONFIG_NFSD_PNFS
5584 [OP_GETDEVICEINFO] = nfsd4_encode_getdeviceinfo,5661 [OP_GETDEVICEINFO] = nfsd4_encode_getdeviceinfo,
5585 [OP_GETDEVICELIST] = nfsd4_encode_noop,5662 [OP_GETDEVICELIST] = nfsd4_encode_noop,
fs/nfsd/nfsctl.c+521−5
@@ -15,6 +15,7 @@ · 14 unmodified lines
15#include <linux/sunrpc/addr.h>15#include <linux/sunrpc/addr.h>
16#include <linux/sunrpc/gss_api.h>16#include <linux/sunrpc/gss_api.h>
17#include <linux/sunrpc/rpc_pipe_fs.h>17#include <linux/sunrpc/rpc_pipe_fs.h>
18#include <linux/sunrpc/svc.h>
18#include <linux/module.h>19#include <linux/module.h>
19#include <linux/fsnotify.h>20#include <linux/fsnotify.h>
20 21
@@ -48,12 +49,10 @@ enum { · 27 unmodified lines
48 NFSD_MaxBlkSize,49 NFSD_MaxBlkSize,
49 NFSD_MaxConnections,50 NFSD_MaxConnections,
50 NFSD_Filecache,51 NFSD_Filecache,
51#ifdef CONFIG_NFSD_V4
52 NFSD_Leasetime,52 NFSD_Leasetime,
53 NFSD_Gracetime,53 NFSD_Gracetime,
54 NFSD_RecoveryDir,54 NFSD_RecoveryDir,
55 NFSD_V4EndGrace,55 NFSD_V4EndGrace,
56#endif
57 NFSD_MaxReserved56 NFSD_MaxReserved
58};57};
59 58
@@ -406,7 +405,9 @@ static ssize_t write_threads(struct file *file, char *buf, size_t size) · 346 unmodified lines
406 if (newthreads < 0)405 if (newthreads < 0)
407 return -EINVAL;406 return -EINVAL;
408 trace_nfsd_ctl_threads(net, newthreads);407 trace_nfsd_ctl_threads(net, newthreads);
409 rv = nfsd_svc(newthreads, net, file->f_cred);408 mutex_lock(&nfsd_mutex);
409 rv = nfsd_svc(newthreads, net, file->f_cred, NULL);
410 mutex_unlock(&nfsd_mutex);
410 if (rv < 0)411 if (rv < 0)
411 return rv;412 return rv;
412 } else413 } else
@@ -1360,7 +1361,9 @@ static int nfsd_fill_super(struct super_block *sb, struct fs_context *fc) · 947 unmodified lines
1360#ifdef CONFIG_NFSD_V41361#ifdef CONFIG_NFSD_V4
1361 [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},1362 [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},
1362 [NFSD_Gracetime] = {"nfsv4gracetime", &transaction_ops, S_IWUSR|S_IRUSR},1363 [NFSD_Gracetime] = {"nfsv4gracetime", &transaction_ops, S_IWUSR|S_IRUSR},
1364#ifdef CONFIG_NFSD_LEGACY_CLIENT_TRACKING
1363 [NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR},1365 [NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR},
1366#endif
1364 [NFSD_V4EndGrace] = {"v4_end_grace", &transaction_ops, S_IWUSR|S_IRUGO},1367 [NFSD_V4EndGrace] = {"v4_end_grace", &transaction_ops, S_IWUSR|S_IRUGO},
1365#endif1368#endif
1366 /* last one */ {""}1369 /* last one */ {""}
@@ -1651,6 +1654,518 @@ int nfsd_nl_rpc_status_get_done(struct netlink_callback *cb) · 284 unmodified lines
1651 return 0;1654 return 0;
1652}1655}
1653 1656
1657/**
1658 * nfsd_nl_threads_set_doit - set the number of running threads
1659 * @skb: reply buffer
1660 * @info: netlink metadata and command arguments
1661 *
1662 * Return 0 on success or a negative errno.
1663 */
1664int nfsd_nl_threads_set_doit(struct sk_buff *skb, struct genl_info *info)
1665{
1666 int nthreads = 0, count = 0, nrpools, ret = -EOPNOTSUPP, rem;
1667 struct net *net = genl_info_net(info);
1668 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
1669 const struct nlattr *attr;
1670 const char *scope = NULL;
1671
1672 if (GENL_REQ_ATTR_CHECK(info, NFSD_A_SERVER_THREADS))
1673 return -EINVAL;
1674
1675 /* count number of SERVER_THREADS values */
1676 nlmsg_for_each_attr(attr, info->nlhdr, GENL_HDRLEN, rem) {
1677 if (nla_type(attr) == NFSD_A_SERVER_THREADS)
1678 count++;
1679 }
1680
1681 mutex_lock(&nfsd_mutex);
1682
1683 nrpools = nfsd_nrpools(net);
1684 if (nrpools && count > nrpools)
1685 count = nrpools;
1686
1687 /* XXX: make this handle non-global pool-modes */
1688 if (count > 1)
1689 goto out_unlock;
1690
1691 nthreads = nla_get_u32(info->attrs[NFSD_A_SERVER_THREADS]);
1692 if (info->attrs[NFSD_A_SERVER_GRACETIME] ||
1693 info->attrs[NFSD_A_SERVER_LEASETIME] ||
1694 info->attrs[NFSD_A_SERVER_SCOPE]) {
1695 ret = -EBUSY;
1696 if (nn->nfsd_serv && nn->nfsd_serv->sv_nrthreads)
1697 goto out_unlock;
1698
1699 ret = -EINVAL;
1700 attr = info->attrs[NFSD_A_SERVER_GRACETIME];
1701 if (attr) {
1702 u32 gracetime = nla_get_u32(attr);
1703
1704 if (gracetime < 10 || gracetime > 3600)
1705 goto out_unlock;
1706
1707 nn->nfsd4_grace = gracetime;
1708 }
1709
1710 attr = info->attrs[NFSD_A_SERVER_LEASETIME];
1711 if (attr) {
1712 u32 leasetime = nla_get_u32(attr);
1713
1714 if (leasetime < 10 || leasetime > 3600)
1715 goto out_unlock;
1716
1717 nn->nfsd4_lease = leasetime;
1718 }
1719
1720 attr = info->attrs[NFSD_A_SERVER_SCOPE];
1721 if (attr)
1722 scope = nla_data(attr);
1723 }
1724
1725 ret = nfsd_svc(nthreads, net, get_current_cred(), scope);
1726
1727out_unlock:
1728 mutex_unlock(&nfsd_mutex);
1729
1730 return ret == nthreads ? 0 : ret;
1731}
1732
1733/**
1734 * nfsd_nl_threads_get_doit - get the number of running threads
1735 * @skb: reply buffer
1736 * @info: netlink metadata and command arguments
1737 *
1738 * Return 0 on success or a negative errno.
1739 */
1740int nfsd_nl_threads_get_doit(struct sk_buff *skb, struct genl_info *info)
1741{
1742 struct net *net = genl_info_net(info);
1743 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
1744 void *hdr;
1745 int err;
1746
1747 skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
1748 if (!skb)
1749 return -ENOMEM;
1750
1751 hdr = genlmsg_iput(skb, info);
1752 if (!hdr) {
1753 err = -EMSGSIZE;
1754 goto err_free_msg;
1755 }
1756
1757 mutex_lock(&nfsd_mutex);
1758
1759 err = nla_put_u32(skb, NFSD_A_SERVER_GRACETIME,
1760 nn->nfsd4_grace) ||
1761 nla_put_u32(skb, NFSD_A_SERVER_LEASETIME,
1762 nn->nfsd4_lease) ||
1763 nla_put_string(skb, NFSD_A_SERVER_SCOPE,
1764 nn->nfsd_name);
1765 if (err)
1766 goto err_unlock;
1767
1768 if (nn->nfsd_serv) {
1769 int i;
1770
1771 for (i = 0; i < nfsd_nrpools(net); ++i) {
1772 struct svc_pool *sp = &nn->nfsd_serv->sv_pools[i];
1773
1774 err = nla_put_u32(skb, NFSD_A_SERVER_THREADS,
1775 atomic_read(&sp->sp_nrthreads));
1776 if (err)
1777 goto err_unlock;
1778 }
1779 } else {
1780 err = nla_put_u32(skb, NFSD_A_SERVER_THREADS, 0);
1781 if (err)
1782 goto err_unlock;
1783 }
1784
1785 mutex_unlock(&nfsd_mutex);
1786
1787 genlmsg_end(skb, hdr);
1788
1789 return genlmsg_reply(skb, info);
1790
1791err_unlock:
1792 mutex_unlock(&nfsd_mutex);
1793err_free_msg:
1794 nlmsg_free(skb);
1795
1796 return err;
1797}
1798
1799/**
1800 * nfsd_nl_version_set_doit - set the nfs enabled versions
1801 * @skb: reply buffer
1802 * @info: netlink metadata and command arguments
1803 *
1804 * Return 0 on success or a negative errno.
1805 */
1806int nfsd_nl_version_set_doit(struct sk_buff *skb, struct genl_info *info)
1807{
1808 const struct nlattr *attr;
1809 struct nfsd_net *nn;
1810 int i, rem;
1811
1812 if (GENL_REQ_ATTR_CHECK(info, NFSD_A_SERVER_PROTO_VERSION))
1813 return -EINVAL;
1814
1815 mutex_lock(&nfsd_mutex);
1816
1817 nn = net_generic(genl_info_net(info), nfsd_net_id);
1818 if (nn->nfsd_serv) {
1819 mutex_unlock(&nfsd_mutex);
1820 return -EBUSY;
1821 }
1822
1823 /* clear current supported versions. */
1824 nfsd_vers(nn, 2, NFSD_CLEAR);
1825 nfsd_vers(nn, 3, NFSD_CLEAR);
1826 for (i = 0; i <= NFSD_SUPPORTED_MINOR_VERSION; i++)
1827 nfsd_minorversion(nn, i, NFSD_CLEAR);
1828
1829 nlmsg_for_each_attr(attr, info->nlhdr, GENL_HDRLEN, rem) {
1830 struct nlattr *tb[NFSD_A_VERSION_MAX + 1];
1831 u32 major, minor = 0;
1832 bool enabled;
1833
1834 if (nla_type(attr) != NFSD_A_SERVER_PROTO_VERSION)
1835 continue;
1836
1837 if (nla_parse_nested(tb, NFSD_A_VERSION_MAX, attr,
1838 nfsd_version_nl_policy, info->extack) < 0)
1839 continue;
1840
1841 if (!tb[NFSD_A_VERSION_MAJOR])
1842 continue;
1843
1844 major = nla_get_u32(tb[NFSD_A_VERSION_MAJOR]);
1845 if (tb[NFSD_A_VERSION_MINOR])
1846 minor = nla_get_u32(tb[NFSD_A_VERSION_MINOR]);
1847
1848 enabled = nla_get_flag(tb[NFSD_A_VERSION_ENABLED]);
1849
1850 switch (major) {
1851 case 4:
1852 nfsd_minorversion(nn, minor, enabled ? NFSD_SET : NFSD_CLEAR);
1853 break;
1854 case 3:
1855 case 2:
1856 if (!minor)
1857 nfsd_vers(nn, major, enabled ? NFSD_SET : NFSD_CLEAR);
1858 break;
1859 default:
1860 break;
1861 }
1862 }
1863
1864 mutex_unlock(&nfsd_mutex);
1865
1866 return 0;
1867}
1868
1869/**
1870 * nfsd_nl_version_get_doit - get the enabled status for all supported nfs versions
1871 * @skb: reply buffer
1872 * @info: netlink metadata and command arguments
1873 *
1874 * Return 0 on success or a negative errno.
1875 */
1876int nfsd_nl_version_get_doit(struct sk_buff *skb, struct genl_info *info)
1877{
1878 struct nfsd_net *nn;
1879 int i, err;
1880 void *hdr;
1881
1882 skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
1883 if (!skb)
1884 return -ENOMEM;
1885
1886 hdr = genlmsg_iput(skb, info);
1887 if (!hdr) {
1888 err = -EMSGSIZE;
1889 goto err_free_msg;
1890 }
1891
1892 mutex_lock(&nfsd_mutex);
1893 nn = net_generic(genl_info_net(info), nfsd_net_id);
1894
1895 for (i = 2; i <= 4; i++) {
1896 int j;
1897
1898 for (j = 0; j <= NFSD_SUPPORTED_MINOR_VERSION; j++) {
1899 struct nlattr *attr;
1900
1901 /* Don't record any versions the kernel doesn't have
1902 * compiled in
1903 */
1904 if (!nfsd_support_version(i))
1905 continue;
1906
1907 /* NFSv{2,3} does not support minor numbers */
1908 if (i < 4 && j)
1909 continue;
1910
1911 attr = nla_nest_start(skb,
1912 NFSD_A_SERVER_PROTO_VERSION);
1913 if (!attr) {
1914 err = -EINVAL;
1915 goto err_nfsd_unlock;
1916 }
1917
1918 if (nla_put_u32(skb, NFSD_A_VERSION_MAJOR, i) ||
1919 nla_put_u32(skb, NFSD_A_VERSION_MINOR, j)) {
1920 err = -EINVAL;
1921 goto err_nfsd_unlock;
1922 }
1923
1924 /* Set the enabled flag if the version is enabled */
1925 if (nfsd_vers(nn, i, NFSD_TEST) &&
1926 (i < 4 || nfsd_minorversion(nn, j, NFSD_TEST)) &&
1927 nla_put_flag(skb, NFSD_A_VERSION_ENABLED)) {
1928 err = -EINVAL;
1929 goto err_nfsd_unlock;
1930 }
1931
1932 nla_nest_end(skb, attr);
1933 }
1934 }
1935
1936 mutex_unlock(&nfsd_mutex);
1937 genlmsg_end(skb, hdr);
1938
1939 return genlmsg_reply(skb, info);
1940
1941err_nfsd_unlock:
1942 mutex_unlock(&nfsd_mutex);
1943err_free_msg:
1944 nlmsg_free(skb);
1945
1946 return err;
1947}
1948
1949/**
1950 * nfsd_nl_listener_set_doit - set the nfs running sockets
1951 * @skb: reply buffer
1952 * @info: netlink metadata and command arguments
1953 *
1954 * Return 0 on success or a negative errno.
1955 */
1956int nfsd_nl_listener_set_doit(struct sk_buff *skb, struct genl_info *info)
1957{
1958 struct net *net = genl_info_net(info);
1959 struct svc_xprt *xprt, *tmp;
1960 const struct nlattr *attr;
1961 struct svc_serv *serv;
1962 LIST_HEAD(permsocks);
1963 struct nfsd_net *nn;
1964 int err, rem;
1965
1966 mutex_lock(&nfsd_mutex);
1967
1968 err = nfsd_create_serv(net);
1969 if (err) {
1970 mutex_unlock(&nfsd_mutex);
1971 return err;
1972 }
1973
1974 nn = net_generic(net, nfsd_net_id);
1975 serv = nn->nfsd_serv;
1976
1977 spin_lock_bh(&serv->sv_lock);
1978
1979 /* Move all of the old listener sockets to a temp list */
1980 list_splice_init(&serv->sv_permsocks, &permsocks);
1981
1982 /*
1983 * Walk the list of server_socks from userland and move any that match
1984 * back to sv_permsocks
1985 */
1986 nlmsg_for_each_attr(attr, info->nlhdr, GENL_HDRLEN, rem) {
1987 struct nlattr *tb[NFSD_A_SOCK_MAX + 1];
1988 const char *xcl_name;
1989 struct sockaddr *sa;
1990
1991 if (nla_type(attr) != NFSD_A_SERVER_SOCK_ADDR)
1992 continue;
1993
1994 if (nla_parse_nested(tb, NFSD_A_SOCK_MAX, attr,
1995 nfsd_sock_nl_policy, info->extack) < 0)
1996 continue;
1997
1998 if (!tb[NFSD_A_SOCK_ADDR] || !tb[NFSD_A_SOCK_TRANSPORT_NAME])
1999 continue;
2000
2001 if (nla_len(tb[NFSD_A_SOCK_ADDR]) < sizeof(*sa))
2002 continue;
2003
2004 xcl_name = nla_data(tb[NFSD_A_SOCK_TRANSPORT_NAME]);
2005 sa = nla_data(tb[NFSD_A_SOCK_ADDR]);
2006
2007 /* Put back any matching sockets */
2008 list_for_each_entry_safe(xprt, tmp, &permsocks, xpt_list) {
2009 /* This shouldn't be possible */
2010 if (WARN_ON_ONCE(xprt->xpt_net != net)) {
2011 list_move(&xprt->xpt_list, &serv->sv_permsocks);
2012 continue;
2013 }
2014
2015 /* If everything matches, put it back */
2016 if (!strcmp(xprt->xpt_class->xcl_name, xcl_name) &&
2017 rpc_cmp_addr_port(sa, (struct sockaddr *)&xprt->xpt_local)) {
2018 list_move(&xprt->xpt_list, &serv->sv_permsocks);
2019 break;
2020 }
2021 }
2022 }
2023
2024 /* For now, no removing old sockets while server is running */
2025 if (serv->sv_nrthreads && !list_empty(&permsocks)) {
2026 list_splice_init(&permsocks, &serv->sv_permsocks);
2027 spin_unlock_bh(&serv->sv_lock);
2028 err = -EBUSY;
2029 goto out_unlock_mtx;
2030 }
2031
2032 /* Close the remaining sockets on the permsocks list */
2033 while (!list_empty(&permsocks)) {
2034 xprt = list_first_entry(&permsocks, struct svc_xprt, xpt_list);
2035 list_move(&xprt->xpt_list, &serv->sv_permsocks);
2036
2037 /*
2038 * Newly-created sockets are born with the BUSY bit set. Clear
2039 * it if there are no threads, since nothing can pick it up
2040 * in that case.
2041 */
2042 if (!serv->sv_nrthreads)
2043 clear_bit(XPT_BUSY, &xprt->xpt_flags);
2044
2045 set_bit(XPT_CLOSE, &xprt->xpt_flags);
2046 spin_unlock_bh(&serv->sv_lock);
2047 svc_xprt_close(xprt);
2048 spin_lock_bh(&serv->sv_lock);
2049 }
2050
2051 spin_unlock_bh(&serv->sv_lock);
2052
2053 /* walk list of addrs again, open any that still don't exist */
2054 nlmsg_for_each_attr(attr, info->nlhdr, GENL_HDRLEN, rem) {
2055 struct nlattr *tb[NFSD_A_SOCK_MAX + 1];
2056 const char *xcl_name;
2057 struct sockaddr *sa;
2058 int ret;
2059
2060 if (nla_type(attr) != NFSD_A_SERVER_SOCK_ADDR)
2061 continue;
2062
2063 if (nla_parse_nested(tb, NFSD_A_SOCK_MAX, attr,
2064 nfsd_sock_nl_policy, info->extack) < 0)
2065 continue;
2066
2067 if (!tb[NFSD_A_SOCK_ADDR] || !tb[NFSD_A_SOCK_TRANSPORT_NAME])
2068 continue;
2069
2070 if (nla_len(tb[NFSD_A_SOCK_ADDR]) < sizeof(*sa))
2071 continue;
2072
2073 xcl_name = nla_data(tb[NFSD_A_SOCK_TRANSPORT_NAME]);
2074 sa = nla_data(tb[NFSD_A_SOCK_ADDR]);
2075
2076 xprt = svc_find_listener(serv, xcl_name, net, sa);
2077 if (xprt) {
2078 svc_xprt_put(xprt);
2079 continue;
2080 }
2081
2082 ret = svc_xprt_create_from_sa(serv, xcl_name, net, sa,
2083 SVC_SOCK_ANONYMOUS,
2084 get_current_cred());
2085 /* always save the latest error */
2086 if (ret < 0)
2087 err = ret;
2088 }
2089
2090 if (!serv->sv_nrthreads && list_empty(&nn->nfsd_serv->sv_permsocks))
2091 nfsd_destroy_serv(net);
2092
2093out_unlock_mtx:
2094 mutex_unlock(&nfsd_mutex);
2095
2096 return err;
2097}
2098
2099/**
2100 * nfsd_nl_listener_get_doit - get the nfs running listeners
2101 * @skb: reply buffer
2102 * @info: netlink metadata and command arguments
2103 *
2104 * Return 0 on success or a negative errno.
2105 */
2106int nfsd_nl_listener_get_doit(struct sk_buff *skb, struct genl_info *info)
2107{
2108 struct svc_xprt *xprt;
2109 struct svc_serv *serv;
2110 struct nfsd_net *nn;
2111 void *hdr;
2112 int err;
2113
2114 skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
2115 if (!skb)
2116 return -ENOMEM;
2117
2118 hdr = genlmsg_iput(skb, info);
2119 if (!hdr) {
2120 err = -EMSGSIZE;
2121 goto err_free_msg;
2122 }
2123
2124 mutex_lock(&nfsd_mutex);
2125 nn = net_generic(genl_info_net(info), nfsd_net_id);
2126
2127 /* no nfs server? Just send empty socket list */
2128 if (!nn->nfsd_serv)
2129 goto out_unlock_mtx;
2130
2131 serv = nn->nfsd_serv;
2132 spin_lock_bh(&serv->sv_lock);
2133 list_for_each_entry(xprt, &serv->sv_permsocks, xpt_list) {
2134 struct nlattr *attr;
2135
2136 attr = nla_nest_start(skb, NFSD_A_SERVER_SOCK_ADDR);
2137 if (!attr) {
2138 err = -EINVAL;
2139 goto err_serv_unlock;
2140 }
2141
2142 if (nla_put_string(skb, NFSD_A_SOCK_TRANSPORT_NAME,
2143 xprt->xpt_class->xcl_name) ||
2144 nla_put(skb, NFSD_A_SOCK_ADDR,
2145 sizeof(struct sockaddr_storage),
2146 &xprt->xpt_local)) {
2147 err = -EINVAL;
2148 goto err_serv_unlock;
2149 }
2150
2151 nla_nest_end(skb, attr);
2152 }
2153 spin_unlock_bh(&serv->sv_lock);
2154out_unlock_mtx:
2155 mutex_unlock(&nfsd_mutex);
2156 genlmsg_end(skb, hdr);
2157
2158 return genlmsg_reply(skb, info);
2159
2160err_serv_unlock:
2161 spin_unlock_bh(&serv->sv_lock);
2162 mutex_unlock(&nfsd_mutex);
2163err_free_msg:
2164 nlmsg_free(skb);
2165
2166 return err;
2167}
2168
1654/**2169/**
1655 * nfsd_net_init - Prepare the nfsd_net portion of a new net namespace2170 * nfsd_net_init - Prepare the nfsd_net portion of a new net namespace
1656 * @net: a freshly-created network namespace2171 * @net: a freshly-created network namespace
@@ -1672,7 +2187,8 @@ static __net_init int nfsd_net_init(struct net *net) · 15 unmodified lines
1672 retval = nfsd_idmap_init(net);2187 retval = nfsd_idmap_init(net);
1673 if (retval)2188 if (retval)
1674 goto out_idmap_error;2189 goto out_idmap_error;
1675 retval = nfsd_stat_counters_init(nn);2190 retval = percpu_counter_init_many(nn->counter, 0, GFP_KERNEL,
2191 NFSD_STATS_COUNTERS_NUM);
1676 if (retval)2192 if (retval)
1677 goto out_repcache_error;2193 goto out_repcache_error;
1678 memset(&nn->nfsd_svcstats, 0, sizeof(nn->nfsd_svcstats));2194 memset(&nn->nfsd_svcstats, 0, sizeof(nn->nfsd_svcstats));
@@ -1704,7 +2220,7 @@ static __net_exit void nfsd_net_exit(struct net *net) · 25 unmodified lines
1704 struct nfsd_net *nn = net_generic(net, nfsd_net_id);2220 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
1705 2221
1706 nfsd_proc_stat_shutdown(net);2222 nfsd_proc_stat_shutdown(net);
1707 nfsd_stat_counters_destroy(nn);2223 percpu_counter_destroy_many(nn->counter, NFSD_STATS_COUNTERS_NUM);
1708 nfsd_idmap_shutdown(net);2224 nfsd_idmap_shutdown(net);
1709 nfsd_export_shutdown(net);2225 nfsd_export_shutdown(net);
1710 nfsd_netns_free_versions(nn);2226 nfsd_netns_free_versions(nn);
fs/nfsd/nfsd.h+1−2
@@ -103,7 +103,7 @@ bool nfssvc_encode_voidres(struct svc_rqst *rqstp, · 102 unmodified lines
103/*103/*
104 * Function prototypes.104 * Function prototypes.
105 */105 */
106int nfsd_svc(int nrservs, struct net *net, const struct cred *cred);106int nfsd_svc(int nrservs, struct net *net, const struct cred *cred, const char *scope);
107int nfsd_dispatch(struct svc_rqst *rqstp);107int nfsd_dispatch(struct svc_rqst *rqstp);
108 108
109int nfsd_nrthreads(struct net *);109int nfsd_nrthreads(struct net *);
@@ -230,7 +230,6 @@ void nfsd_lockd_shutdown(void); · 120 unmodified lines
230#define nfserr_nospc cpu_to_be32(NFSERR_NOSPC)230#define nfserr_nospc cpu_to_be32(NFSERR_NOSPC)
231#define nfserr_rofs cpu_to_be32(NFSERR_ROFS)231#define nfserr_rofs cpu_to_be32(NFSERR_ROFS)
232#define nfserr_mlink cpu_to_be32(NFSERR_MLINK)232#define nfserr_mlink cpu_to_be32(NFSERR_MLINK)
233#define nfserr_opnotsupp cpu_to_be32(NFSERR_OPNOTSUPP)
234#define nfserr_nametoolong cpu_to_be32(NFSERR_NAMETOOLONG)233#define nfserr_nametoolong cpu_to_be32(NFSERR_NAMETOOLONG)
235#define nfserr_notempty cpu_to_be32(NFSERR_NOTEMPTY)234#define nfserr_notempty cpu_to_be32(NFSERR_NOTEMPTY)
236#define nfserr_dquot cpu_to_be32(NFSERR_DQUOT)235#define nfserr_dquot cpu_to_be32(NFSERR_DQUOT)
fs/nfsd/nfsfh.c+2−2
@@ -573,7 +573,7 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, · 572 unmodified lines
573 _fh_update(fhp, exp, dentry);573 _fh_update(fhp, exp, dentry);
574 if (fhp->fh_handle.fh_fileid_type == FILEID_INVALID) {574 if (fhp->fh_handle.fh_fileid_type == FILEID_INVALID) {
575 fh_put(fhp);575 fh_put(fhp);
576 return nfserr_opnotsupp;576 return nfserr_stale;
577 }577 }
578 578
579 return 0;579 return 0;
@@ -599,7 +599,7 @@ fh_update(struct svc_fh *fhp) · 19 unmodified lines
599 599
600 _fh_update(fhp, fhp->fh_export, dentry);600 _fh_update(fhp, fhp->fh_export, dentry);
601 if (fhp->fh_handle.fh_fileid_type == FILEID_INVALID)601 if (fhp->fh_handle.fh_fileid_type == FILEID_INVALID)
602 return nfserr_opnotsupp;602 return nfserr_stale;
603 return 0;603 return 0;
604out_bad:604out_bad:
605 printk(KERN_ERR "fh_update: fh not verified!\n");605 printk(KERN_ERR "fh_update: fh not verified!\n");
fs/nfsd/nfssvc.c+5−6
@@ -133,8 +133,7 @@ struct svc_program nfsd_program = { · 132 unmodified lines
133 .pg_rpcbind_set = nfsd_rpcbind_set,133 .pg_rpcbind_set = nfsd_rpcbind_set,
134};134};
135 135
136static bool136bool nfsd_support_version(int vers)
137nfsd_support_version(int vers)
138{137{
139 if (vers >= NFSD_MINVERS && vers < NFSD_NRVERS)138 if (vers >= NFSD_MINVERS && vers < NFSD_NRVERS)
140 return nfsd_version[vers] != NULL;139 return nfsd_version[vers] != NULL;
@@ -769,13 +768,14 @@ int nfsd_set_nrthreads(int n, int *nthreads, struct net *net) · 628 unmodified lines
769 * this is the first time nrservs is nonzero.768 * this is the first time nrservs is nonzero.
770 */769 */
771int770int
772nfsd_svc(int nrservs, struct net *net, const struct cred *cred)771nfsd_svc(int nrservs, struct net *net, const struct cred *cred, const char *scope)
773{772{
774 int error;773 int error;
775 struct nfsd_net *nn = net_generic(net, nfsd_net_id);774 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
776 struct svc_serv *serv;775 struct svc_serv *serv;
777 776
778 mutex_lock(&nfsd_mutex);777 lockdep_assert_held(&nfsd_mutex);
778
779 dprintk("nfsd: creating service\n");779 dprintk("nfsd: creating service\n");
780 780
781 nrservs = max(nrservs, 0);781 nrservs = max(nrservs, 0);
@@ -785,7 +785,7 @@ nfsd_svc(int nrservs, struct net *net, const struct cred *cred) · 3 unmodified lines
785 if (nrservs == 0 && nn->nfsd_serv == NULL)785 if (nrservs == 0 && nn->nfsd_serv == NULL)
786 goto out;786 goto out;
787 787
788 strscpy(nn->nfsd_name, utsname()->nodename,788 strscpy(nn->nfsd_name, scope ? scope : utsname()->nodename,
789 sizeof(nn->nfsd_name));789 sizeof(nn->nfsd_name));
790 790
791 error = nfsd_create_serv(net);791 error = nfsd_create_serv(net);
@@ -804,7 +804,6 @@ out_put: · 12 unmodified lines
804 if (serv->sv_nrthreads == 0)804 if (serv->sv_nrthreads == 0)
805 nfsd_destroy_serv(net);805 nfsd_destroy_serv(net);
806out:806out:
807 mutex_unlock(&nfsd_mutex);
808 return error;807 return error;
809}808}
810 809
fs/nfsd/state.h+3−3
@@ -408,6 +408,8 @@ struct nfs4_client { · 407 unmodified lines
408 1 << NFSD4_CLIENT_CB_KILL)408 1 << NFSD4_CLIENT_CB_KILL)
409#define NFSD4_CLIENT_CB_RECALL_ANY (6)409#define NFSD4_CLIENT_CB_RECALL_ANY (6)
410 unsigned long cl_flags;410 unsigned long cl_flags;
411
412 struct workqueue_struct *cl_callback_wq;
411 const struct cred *cl_cb_cred;413 const struct cred *cl_cb_cred;
412 struct rpc_clnt *cl_cb_client;414 struct rpc_clnt *cl_cb_client;
413 u32 cl_cb_ident;415 u32 cl_cb_ident;
@@ -486,7 +488,7 @@ struct nfs4_replay { · 72 unmodified lines
486 unsigned int rp_buflen;488 unsigned int rp_buflen;
487 char *rp_buf;489 char *rp_buf;
488 struct knfsd_fh rp_openfh;490 struct knfsd_fh rp_openfh;
489 struct mutex rp_mutex;491 atomic_t rp_locked;
490 char rp_ibuf[NFSD4_REPLAY_ISIZE];492 char rp_ibuf[NFSD4_REPLAY_ISIZE];
491};493};
492 494
@@ -735,8 +737,6 @@ extern void nfsd4_change_callback(struct nfs4_client *clp, struct nfs4_cb_conn * · 242 unmodified lines
735extern void nfsd4_init_cb(struct nfsd4_callback *cb, struct nfs4_client *clp,737extern void nfsd4_init_cb(struct nfsd4_callback *cb, struct nfs4_client *clp,
736 const struct nfsd4_callback_ops *ops, enum nfsd4_cb_op op);738 const struct nfsd4_callback_ops *ops, enum nfsd4_cb_op op);
737extern bool nfsd4_run_cb(struct nfsd4_callback *cb);739extern bool nfsd4_run_cb(struct nfsd4_callback *cb);
738extern int nfsd4_create_callback_queue(void);
739extern void nfsd4_destroy_callback_queue(void);
740extern void nfsd4_shutdown_callback(struct nfs4_client *);740extern void nfsd4_shutdown_callback(struct nfs4_client *);
741extern void nfsd4_shutdown_copy(struct nfs4_client *clp);741extern void nfsd4_shutdown_copy(struct nfs4_client *clp);
742extern struct nfs4_client_reclaim *nfs4_client_to_reclaim(struct xdr_netobj name,742extern struct nfs4_client_reclaim *nfs4_client_to_reclaim(struct xdr_netobj name,
fs/nfsd/stats.c+0−42
@@ -73,48 +73,6 @@ static int nfsd_show(struct seq_file *seq, void *v) · 72 unmodified lines
73 73
74DEFINE_PROC_SHOW_ATTRIBUTE(nfsd);74DEFINE_PROC_SHOW_ATTRIBUTE(nfsd);
75 75
76int nfsd_percpu_counters_init(struct percpu_counter *counters, int num)
77{
78 int i, err = 0;
79
80 for (i = 0; !err && i < num; i++)
81 err = percpu_counter_init(&counters[i], 0, GFP_KERNEL);
82
83 if (!err)
84 return 0;
85
86 for (; i > 0; i--)
87 percpu_counter_destroy(&counters[i-1]);
88
89 return err;
90}
91
92void nfsd_percpu_counters_reset(struct percpu_counter counters[], int num)
93{
94 int i;
95
96 for (i = 0; i < num; i++)
97 percpu_counter_set(&counters[i], 0);
98}
99
100void nfsd_percpu_counters_destroy(struct percpu_counter counters[], int num)
101{
102 int i;
103
104 for (i = 0; i < num; i++)
105 percpu_counter_destroy(&counters[i]);
106}
107
108int nfsd_stat_counters_init(struct nfsd_net *nn)
109{
110 return nfsd_percpu_counters_init(nn->counter, NFSD_STATS_COUNTERS_NUM);
111}
112
113void nfsd_stat_counters_destroy(struct nfsd_net *nn)
114{
115 nfsd_percpu_counters_destroy(nn->counter, NFSD_STATS_COUNTERS_NUM);
116}
117
118void nfsd_proc_stat_init(struct net *net)76void nfsd_proc_stat_init(struct net *net)
119{77{
120 struct nfsd_net *nn = net_generic(net, nfsd_net_id);78 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
fs/nfsd/stats.h+0−5
@@ -10,11 +10,6 @@ · 9 unmodified lines
10#include <uapi/linux/nfsd/stats.h>10#include <uapi/linux/nfsd/stats.h>
11#include <linux/percpu_counter.h>11#include <linux/percpu_counter.h>
12 12
13int nfsd_percpu_counters_init(struct percpu_counter *counters, int num);
14void nfsd_percpu_counters_reset(struct percpu_counter *counters, int num);
15void nfsd_percpu_counters_destroy(struct percpu_counter *counters, int num);
16int nfsd_stat_counters_init(struct nfsd_net *nn);
17void nfsd_stat_counters_destroy(struct nfsd_net *nn);
18void nfsd_proc_stat_init(struct net *net);13void nfsd_proc_stat_init(struct net *net);
19void nfsd_proc_stat_shutdown(struct net *net);14void nfsd_proc_stat_shutdown(struct net *net);
20 15
fs/nfsd/trace.h+97−3
@@ -749,6 +749,76 @@ TRACE_EVENT_CONDITION(nfsd_seq4_status, · 748 unmodified lines
749 )749 )
750);750);
751 751
752DECLARE_EVENT_CLASS(nfsd_cs_slot_class,
753 TP_PROTO(
754 const struct nfs4_client *clp,
755 const struct nfsd4_create_session *cs
756 ),
757 TP_ARGS(clp, cs),
758 TP_STRUCT__entry(
759 __field(u32, seqid)
760 __field(u32, slot_seqid)
761 __field(u32, cl_boot)
762 __field(u32, cl_id)
763 __sockaddr(addr, clp->cl_cb_conn.cb_addrlen)
764 ),
765 TP_fast_assign(
766 const struct nfsd4_clid_slot *slot = &clp->cl_cs_slot;
767
768 __entry->cl_boot = clp->cl_clientid.cl_boot;
769 __entry->cl_id = clp->cl_clientid.cl_id;
770 __assign_sockaddr(addr, &clp->cl_cb_conn.cb_addr,
771 clp->cl_cb_conn.cb_addrlen);
772 __entry->seqid = cs->seqid;
773 __entry->slot_seqid = slot->sl_seqid;
774 ),
775 TP_printk("addr=%pISpc client %08x:%08x seqid=%u slot_seqid=%u",
776 __get_sockaddr(addr), __entry->cl_boot, __entry->cl_id,
777 __entry->seqid, __entry->slot_seqid
778 )
779);
780
781#define DEFINE_CS_SLOT_EVENT(name) \
782DEFINE_EVENT(nfsd_cs_slot_class, nfsd_##name, \
783 TP_PROTO( \
784 const struct nfs4_client *clp, \
785 const struct nfsd4_create_session *cs \
786 ), \
787 TP_ARGS(clp, cs))
788
789DEFINE_CS_SLOT_EVENT(slot_seqid_conf);
790DEFINE_CS_SLOT_EVENT(slot_seqid_unconf);
791
792TRACE_EVENT(nfsd_slot_seqid_sequence,
793 TP_PROTO(
794 const struct nfs4_client *clp,
795 const struct nfsd4_sequence *seq,
796 const struct nfsd4_slot *slot
797 ),
798 TP_ARGS(clp, seq, slot),
799 TP_STRUCT__entry(
800 __field(u32, seqid)
801 __field(u32, slot_seqid)
802 __field(u32, cl_boot)
803 __field(u32, cl_id)
804 __sockaddr(addr, clp->cl_cb_conn.cb_addrlen)
805 __field(bool, in_use)
806 ),
807 TP_fast_assign(
808 __entry->cl_boot = clp->cl_clientid.cl_boot;
809 __entry->cl_id = clp->cl_clientid.cl_id;
810 __assign_sockaddr(addr, &clp->cl_cb_conn.cb_addr,
811 clp->cl_cb_conn.cb_addrlen);
812 __entry->seqid = seq->seqid;
813 __entry->slot_seqid = slot->sl_seqid;
814 ),
815 TP_printk("addr=%pISpc client %08x:%08x seqid=%u slot_seqid=%u (%sin use)",
816 __get_sockaddr(addr), __entry->cl_boot, __entry->cl_id,
817 __entry->seqid, __entry->slot_seqid,
818 __entry->in_use ? "" : "not "
819 )
820);
821
752DECLARE_EVENT_CLASS(nfsd_clientid_class,822DECLARE_EVENT_CLASS(nfsd_clientid_class,
753 TP_PROTO(const clientid_t *clid),823 TP_PROTO(const clientid_t *clid),
754 TP_ARGS(clid),824 TP_ARGS(clid),
@@ -778,6 +848,30 @@ DEFINE_CLIENTID_EVENT(purged); · 23 unmodified lines
778DEFINE_CLIENTID_EVENT(renew);848DEFINE_CLIENTID_EVENT(renew);
779DEFINE_CLIENTID_EVENT(stale);849DEFINE_CLIENTID_EVENT(stale);
780 850
851TRACE_EVENT(nfsd_mark_client_expired,
852 TP_PROTO(
853 const struct nfs4_client *clp,
854 int cl_rpc_users
855 ),
856 TP_ARGS(clp, cl_rpc_users),
857 TP_STRUCT__entry(
858 __field(int, cl_rpc_users)
859 __field(u32, cl_boot)
860 __field(u32, cl_id)
861 __sockaddr(addr, clp->cl_cb_conn.cb_addrlen)
862 ),
863 TP_fast_assign(
864 __entry->cl_rpc_users = cl_rpc_users;
865 __entry->cl_boot = clp->cl_clientid.cl_boot;
866 __entry->cl_id = clp->cl_clientid.cl_id;
867 __assign_sockaddr(addr, &clp->cl_cb_conn.cb_addr,
868 clp->cl_cb_conn.cb_addrlen)
869 ),
870 TP_printk("addr=%pISpc client %08x:%08x cl_rpc_users=%d",
871 __get_sockaddr(addr), __entry->cl_boot, __entry->cl_id,
872 __entry->cl_rpc_users)
873);
874
781DECLARE_EVENT_CLASS(nfsd_net_class,875DECLARE_EVENT_CLASS(nfsd_net_class,
782 TP_PROTO(const struct nfsd_net *nn),876 TP_PROTO(const struct nfsd_net *nn),
783 TP_ARGS(nn),877 TP_ARGS(nn),
@@ -1534,7 +1628,7 @@ TRACE_EVENT(nfsd_cb_seq_status, · 750 unmodified lines
1534 __entry->seq_status = cb->cb_seq_status;1628 __entry->seq_status = cb->cb_seq_status;
1535 ),1629 ),
1536 TP_printk(SUNRPC_TRACE_TASK_SPECIFIER1630 TP_printk(SUNRPC_TRACE_TASK_SPECIFIER
1537 " sessionid=%08x:%08x:%08x:%08x tk_status=%d seq_status=%d\n",1631 " sessionid=%08x:%08x:%08x:%08x tk_status=%d seq_status=%d",
1538 __entry->task_id, __entry->client_id,1632 __entry->task_id, __entry->client_id,
1539 __entry->cl_boot, __entry->cl_id,1633 __entry->cl_boot, __entry->cl_id,
1540 __entry->seqno, __entry->reserved,1634 __entry->seqno, __entry->reserved,
@@ -1573,7 +1667,7 @@ TRACE_EVENT(nfsd_cb_free_slot, · 32 unmodified lines
1573 __entry->slot_seqno = session->se_cb_seq_nr;1667 __entry->slot_seqno = session->se_cb_seq_nr;
1574 ),1668 ),
1575 TP_printk(SUNRPC_TRACE_TASK_SPECIFIER1669 TP_printk(SUNRPC_TRACE_TASK_SPECIFIER
1576 " sessionid=%08x:%08x:%08x:%08x new slot seqno=%u\n",1670 " sessionid=%08x:%08x:%08x:%08x new slot seqno=%u",
1577 __entry->task_id, __entry->client_id,1671 __entry->task_id, __entry->client_id,
1578 __entry->cl_boot, __entry->cl_id,1672 __entry->cl_boot, __entry->cl_id,
1579 __entry->seqno, __entry->reserved,1673 __entry->seqno, __entry->reserved,
@@ -1978,7 +2072,7 @@ TRACE_EVENT(nfsd_ctl_time, · 398 unmodified lines
1978 __entry->time = time;2072 __entry->time = time;
1979 __assign_str(name, name);2073 __assign_str(name, name);
1980 ),2074 ),
1981 TP_printk("file=%s time=%d\n",2075 TP_printk("file=%s time=%d",
1982 __get_str(name), __entry->time2076 __get_str(name), __entry->time
1983 )2077 )
1984);2078);
fs/nfsd/vfs.c+1−1
@@ -1422,7 +1422,7 @@ nfsd_create_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, · 1421 unmodified lines
1422 * Callers expect new file metadata to be committed even1422 * Callers expect new file metadata to be committed even
1423 * if the attributes have not changed.1423 * if the attributes have not changed.
1424 */1424 */
1425 if (iap->ia_valid)1425 if (nfsd_attrs_valid(attrs))
1426 status = nfsd_setattr(rqstp, resfhp, attrs, NULL);1426 status = nfsd_setattr(rqstp, resfhp, attrs, NULL);
1427 else1427 else
1428 status = nfserrno(commit_metadata(resfhp));1428 status = nfserrno(commit_metadata(resfhp));
fs/nfsd/vfs.h+8−0
@@ -60,6 +60,14 @@ static inline void nfsd_attrs_free(struct nfsd_attrs *attrs) · 59 unmodified lines
60 posix_acl_release(attrs->na_dpacl);60 posix_acl_release(attrs->na_dpacl);
61}61}
62 62
63static inline bool nfsd_attrs_valid(struct nfsd_attrs *attrs)
64{
65 struct iattr *iap = attrs->na_iattr;
66
67 return (iap->ia_valid || (attrs->na_seclabel &&
68 attrs->na_seclabel->len));
69}
70
63__be32 nfserrno (int errno);71__be32 nfserrno (int errno);
64int nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp,72int nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp,
65 struct svc_export **expp);73 struct svc_export **expp);
fs/nfsd/xdr4.h+23−1
@@ -518,6 +518,24 @@ struct nfsd4_free_stateid { · 517 unmodified lines
518 stateid_t fr_stateid; /* request */518 stateid_t fr_stateid; /* request */
519};519};
520 520
521struct nfsd4_get_dir_delegation {
522 /* request */
523 u32 gdda_signal_deleg_avail;
524 u32 gdda_notification_types[1];
525 struct timespec64 gdda_child_attr_delay;
526 struct timespec64 gdda_dir_attr_delay;
527 u32 gdda_child_attributes[3];
528 u32 gdda_dir_attributes[3];
529 /* response */
530 u32 gddrnf_status;
531 nfs4_verifier gddr_cookieverf;
532 stateid_t gddr_stateid;
533 u32 gddr_notification[1];
534 u32 gddr_child_attributes[3];
535 u32 gddr_dir_attributes[3];
536 bool gddrnf_will_signal_deleg_avail;
537};
538
521/* also used for NVERIFY */539/* also used for NVERIFY */
522struct nfsd4_verify {540struct nfsd4_verify {
523 u32 ve_bmval[3]; /* request */541 u32 ve_bmval[3]; /* request */
@@ -674,8 +692,10 @@ struct nfsd4_copy { · 150 unmodified lines
674#define NFSD4_COPY_F_INTRA (1)692#define NFSD4_COPY_F_INTRA (1)
675#define NFSD4_COPY_F_SYNCHRONOUS (2)693#define NFSD4_COPY_F_SYNCHRONOUS (2)
676#define NFSD4_COPY_F_COMMITTED (3)694#define NFSD4_COPY_F_COMMITTED (3)
695#define NFSD4_COPY_F_COMPLETED (4)
677 696
678 /* response */697 /* response */
698 __be32 nfserr;
679 struct nfsd42_write_res cp_res;699 struct nfsd42_write_res cp_res;
680 struct knfsd_fh fh;700 struct knfsd_fh fh;
681 701
@@ -735,7 +755,8 @@ struct nfsd4_offload_status { · 53 unmodified lines
735 755
736 /* response */756 /* response */
737 u64 count;757 u64 count;
738 u32 status;758 __be32 status;
759 bool completed;
739};760};
740 761
741struct nfsd4_copy_notify {762struct nfsd4_copy_notify {
@@ -797,6 +818,7 @@ struct nfsd4_op { · 55 unmodified lines
797 struct nfsd4_reclaim_complete reclaim_complete;818 struct nfsd4_reclaim_complete reclaim_complete;
798 struct nfsd4_test_stateid test_stateid;819 struct nfsd4_test_stateid test_stateid;
799 struct nfsd4_free_stateid free_stateid;820 struct nfsd4_free_stateid free_stateid;
821 struct nfsd4_get_dir_delegation get_dir_delegation;
800 struct nfsd4_getdeviceinfo getdeviceinfo;822 struct nfsd4_getdeviceinfo getdeviceinfo;
801 struct nfsd4_layoutget layoutget;823 struct nfsd4_layoutget layoutget;
802 struct nfsd4_layoutcommit layoutcommit;824 struct nfsd4_layoutcommit layoutcommit;
include/linux/nfs4.h+6−0
@@ -701,6 +701,12 @@ enum state_protect_how4 { · 700 unmodified lines
701 SP4_SSV = 2701 SP4_SSV = 2
702};702};
703 703
704/* GET_DIR_DELEGATION non-fatal status codes */
705enum gddrnf4_status {
706 GDD4_OK = 0,
707 GDD4_UNAVAIL = 1
708};
709
704enum pnfs_layouttype {710enum pnfs_layouttype {
705 LAYOUT_NFSV4_1_FILES = 1,711 LAYOUT_NFSV4_1_FILES = 1,
706 LAYOUT_OSD2_OBJECTS = 2,712 LAYOUT_OSD2_OBJECTS = 2,
include/linux/sunrpc/svc_xprt.h+5−0
@@ -135,6 +135,9 @@ int svc_reg_xprt_class(struct svc_xprt_class *); · 134 unmodified lines
135void svc_unreg_xprt_class(struct svc_xprt_class *);135void svc_unreg_xprt_class(struct svc_xprt_class *);
136void svc_xprt_init(struct net *, struct svc_xprt_class *, struct svc_xprt *,136void svc_xprt_init(struct net *, struct svc_xprt_class *, struct svc_xprt *,
137 struct svc_serv *);137 struct svc_serv *);
138int svc_xprt_create_from_sa(struct svc_serv *serv, const char *xprt_name,
139 struct net *net, struct sockaddr *sap,
140 int flags, const struct cred *cred);
138int svc_xprt_create(struct svc_serv *serv, const char *xprt_name,141int svc_xprt_create(struct svc_serv *serv, const char *xprt_name,
139 struct net *net, const int family,142 struct net *net, const int family,
140 const unsigned short port, int flags,143 const unsigned short port, int flags,
@@ -147,6 +150,8 @@ void svc_xprt_copy_addrs(struct svc_rqst *rqstp, struct svc_xprt *xprt); · 6 unmodified lines
147void svc_xprt_close(struct svc_xprt *xprt);150void svc_xprt_close(struct svc_xprt *xprt);
148int svc_port_is_privileged(struct sockaddr *sin);151int svc_port_is_privileged(struct sockaddr *sin);
149int svc_print_xprts(char *buf, int maxlen);152int svc_print_xprts(char *buf, int maxlen);
153struct svc_xprt *svc_find_listener(struct svc_serv *serv, const char *xcl_name,
154 struct net *net, const struct sockaddr *sa);
150struct svc_xprt *svc_find_xprt(struct svc_serv *serv, const char *xcl_name,155struct svc_xprt *svc_find_xprt(struct svc_serv *serv, const char *xcl_name,
151 struct net *net, const sa_family_t af,156 struct net *net, const sa_family_t af,
152 const unsigned short port);157 const unsigned short port);
include/trace/misc/nfs.h+0−2
@@ -28,7 +28,6 @@ TRACE_DEFINE_ENUM(NFSERR_FBIG); · 27 unmodified lines
28TRACE_DEFINE_ENUM(NFSERR_NOSPC);28TRACE_DEFINE_ENUM(NFSERR_NOSPC);
29TRACE_DEFINE_ENUM(NFSERR_ROFS);29TRACE_DEFINE_ENUM(NFSERR_ROFS);
30TRACE_DEFINE_ENUM(NFSERR_MLINK);30TRACE_DEFINE_ENUM(NFSERR_MLINK);
31TRACE_DEFINE_ENUM(NFSERR_OPNOTSUPP);
32TRACE_DEFINE_ENUM(NFSERR_NAMETOOLONG);31TRACE_DEFINE_ENUM(NFSERR_NAMETOOLONG);
33TRACE_DEFINE_ENUM(NFSERR_NOTEMPTY);32TRACE_DEFINE_ENUM(NFSERR_NOTEMPTY);
34TRACE_DEFINE_ENUM(NFSERR_DQUOT);33TRACE_DEFINE_ENUM(NFSERR_DQUOT);
@@ -64,7 +63,6 @@ TRACE_DEFINE_ENUM(NFSERR_JUKEBOX); · 29 unmodified lines
64 { NFSERR_NOSPC, "NOSPC" }, \63 { NFSERR_NOSPC, "NOSPC" }, \
65 { NFSERR_ROFS, "ROFS" }, \64 { NFSERR_ROFS, "ROFS" }, \
66 { NFSERR_MLINK, "MLINK" }, \65 { NFSERR_MLINK, "MLINK" }, \
67 { NFSERR_OPNOTSUPP, "OPNOTSUPP" }, \
68 { NFSERR_NAMETOOLONG, "NAMETOOLONG" }, \66 { NFSERR_NAMETOOLONG, "NAMETOOLONG" }, \
69 { NFSERR_NOTEMPTY, "NOTEMPTY" }, \67 { NFSERR_NOTEMPTY, "NOTEMPTY" }, \
70 { NFSERR_DQUOT, "DQUOT" }, \68 { NFSERR_DQUOT, "DQUOT" }, \
include/uapi/linux/nfs.h+0−1
@@ -61,7 +61,6 @@ · 60 unmodified lines
61 NFSERR_NOSPC = 28, /* v2 v3 v4 */61 NFSERR_NOSPC = 28, /* v2 v3 v4 */
62 NFSERR_ROFS = 30, /* v2 v3 v4 */62 NFSERR_ROFS = 30, /* v2 v3 v4 */
63 NFSERR_MLINK = 31, /* v3 v4 */63 NFSERR_MLINK = 31, /* v3 v4 */
64 NFSERR_OPNOTSUPP = 45, /* v2 v3 */
65 NFSERR_NAMETOOLONG = 63, /* v2 v3 v4 */64 NFSERR_NAMETOOLONG = 63, /* v2 v3 v4 */
66 NFSERR_NOTEMPTY = 66, /* v2 v3 v4 */65 NFSERR_NOTEMPTY = 66, /* v2 v3 v4 */
67 NFSERR_DQUOT = 69, /* v2 v3 v4 */66 NFSERR_DQUOT = 69, /* v2 v3 v4 */
include/uapi/linux/nfsd_netlink.h+47−0
@@ -29,8 +29,55 @@ enum { · 28 unmodified lines
29 NFSD_A_RPC_STATUS_MAX = (__NFSD_A_RPC_STATUS_MAX - 1)29 NFSD_A_RPC_STATUS_MAX = (__NFSD_A_RPC_STATUS_MAX - 1)
30};30};
31 31
32enum {
33 NFSD_A_SERVER_THREADS = 1,
34 NFSD_A_SERVER_GRACETIME,
35 NFSD_A_SERVER_LEASETIME,
36 NFSD_A_SERVER_SCOPE,
37
38 __NFSD_A_SERVER_MAX,
39 NFSD_A_SERVER_MAX = (__NFSD_A_SERVER_MAX - 1)
40};
41
42enum {
43 NFSD_A_VERSION_MAJOR = 1,
44 NFSD_A_VERSION_MINOR,
45 NFSD_A_VERSION_ENABLED,
46
47 __NFSD_A_VERSION_MAX,
48 NFSD_A_VERSION_MAX = (__NFSD_A_VERSION_MAX - 1)
49};
50
51enum {
52 NFSD_A_SERVER_PROTO_VERSION = 1,
53
54 __NFSD_A_SERVER_PROTO_MAX,
55 NFSD_A_SERVER_PROTO_MAX = (__NFSD_A_SERVER_PROTO_MAX - 1)
56};
57
58enum {
59 NFSD_A_SOCK_ADDR = 1,
60 NFSD_A_SOCK_TRANSPORT_NAME,
61
62 __NFSD_A_SOCK_MAX,
63 NFSD_A_SOCK_MAX = (__NFSD_A_SOCK_MAX - 1)
64};
65
66enum {
67 NFSD_A_SERVER_SOCK_ADDR = 1,
68
69 __NFSD_A_SERVER_SOCK_MAX,
70 NFSD_A_SERVER_SOCK_MAX = (__NFSD_A_SERVER_SOCK_MAX - 1)
71};
72
32enum {73enum {
33 NFSD_CMD_RPC_STATUS_GET = 1,74 NFSD_CMD_RPC_STATUS_GET = 1,
75 NFSD_CMD_THREADS_SET,
76 NFSD_CMD_THREADS_GET,
77 NFSD_CMD_VERSION_SET,
78 NFSD_CMD_VERSION_GET,
79 NFSD_CMD_LISTENER_SET,
80 NFSD_CMD_LISTENER_GET,
34 81
35 __NFSD_CMD_MAX,82 __NFSD_CMD_MAX,
36 NFSD_CMD_MAX = (__NFSD_CMD_MAX - 1)83 NFSD_CMD_MAX = (__NFSD_CMD_MAX - 1)
net/sunrpc/auth_gss/svcauth_gss.c+2−8
@@ -1033,17 +1033,11 @@ null_verifier: · 1032 unmodified lines
1033 1033
1034static void gss_free_in_token_pages(struct gssp_in_token *in_token)1034static void gss_free_in_token_pages(struct gssp_in_token *in_token)
1035{1035{
1036 u32 inlen;
1037 int i;1036 int i;
1038 1037
1039 i = 0;1038 i = 0;
1040 inlen = in_token->page_len;1039 while (in_token->pages[i])
1041 while (inlen) {1040 put_page(in_token->pages[i++]);
1042 if (in_token->pages[i])
1043 put_page(in_token->pages[i]);
1044 inlen -= inlen > PAGE_SIZE ? PAGE_SIZE : inlen;
1045 }
1046
1047 kfree(in_token->pages);1041 kfree(in_token->pages);
1048 in_token->pages = NULL;1042 in_token->pages = NULL;
1049}1043}
net/sunrpc/svc.c+0−2
@@ -1265,8 +1265,6 @@ svc_generic_init_request(struct svc_rqst *rqstp, · 1264 unmodified lines
1265 if (rqstp->rq_proc >= versp->vs_nproc)1265 if (rqstp->rq_proc >= versp->vs_nproc)
1266 goto err_bad_proc;1266 goto err_bad_proc;
1267 rqstp->rq_procinfo = procp = &versp->vs_proc[rqstp->rq_proc];1267 rqstp->rq_procinfo = procp = &versp->vs_proc[rqstp->rq_proc];
1268 if (!procp)
1269 goto err_bad_proc;
1270 1268
1271 /* Initialize storage for argp and resp */1269 /* Initialize storage for argp and resp */
1272 memset(rqstp->rq_argp, 0, procp->pc_argzero);1270 memset(rqstp->rq_argp, 0, procp->pc_argzero);
net/sunrpc/svc_xprt.c+109−59
@@ -46,7 +46,6 @@ static LIST_HEAD(svc_xprt_class_list); · 45 unmodified lines
46 46
47/* SMP locking strategy:47/* SMP locking strategy:
48 *48 *
49 * svc_pool->sp_lock protects most of the fields of that pool.
50 * svc_serv->sv_lock protects sv_tempsocks, sv_permsocks, sv_tmpcnt.49 * svc_serv->sv_lock protects sv_tempsocks, sv_permsocks, sv_tmpcnt.
51 * when both need to be taken (rare), svc_serv->sv_lock is first.50 * when both need to be taken (rare), svc_serv->sv_lock is first.
52 * The "service mutex" protects svc_serv->sv_nrthread.51 * The "service mutex" protects svc_serv->sv_nrthread.
@@ -211,51 +210,6 @@ void svc_xprt_init(struct net *net, struct svc_xprt_class *xcl, · 158 unmodified lines
211}210}
212EXPORT_SYMBOL_GPL(svc_xprt_init);211EXPORT_SYMBOL_GPL(svc_xprt_init);
213 212
214static struct svc_xprt *__svc_xpo_create(struct svc_xprt_class *xcl,
215 struct svc_serv *serv,
216 struct net *net,
217 const int family,
218 const unsigned short port,
219 int flags)
220{
221 struct sockaddr_in sin = {
222 .sin_family = AF_INET,
223 .sin_addr.s_addr = htonl(INADDR_ANY),
224 .sin_port = htons(port),
225 };
226#if IS_ENABLED(CONFIG_IPV6)
227 struct sockaddr_in6 sin6 = {
228 .sin6_family = AF_INET6,
229 .sin6_addr = IN6ADDR_ANY_INIT,
230 .sin6_port = htons(port),
231 };
232#endif
233 struct svc_xprt *xprt;
234 struct sockaddr *sap;
235 size_t len;
236
237 switch (family) {
238 case PF_INET:
239 sap = (struct sockaddr *)&sin;
240 len = sizeof(sin);
241 break;
242#if IS_ENABLED(CONFIG_IPV6)
243 case PF_INET6:
244 sap = (struct sockaddr *)&sin6;
245 len = sizeof(sin6);
246 break;
247#endif
248 default:
249 return ERR_PTR(-EAFNOSUPPORT);
250 }
251
252 xprt = xcl->xcl_ops->xpo_create(serv, net, sap, len, flags);
253 if (IS_ERR(xprt))
254 trace_svc_xprt_create_err(serv->sv_program->pg_name,
255 xcl->xcl_name, sap, len, xprt);
256 return xprt;
257}
258
259/**213/**
260 * svc_xprt_received - start next receiver thread214 * svc_xprt_received - start next receiver thread
261 * @xprt: controlling transport215 * @xprt: controlling transport
@@ -294,9 +248,8 @@ void svc_add_new_perm_xprt(struct svc_serv *serv, struct svc_xprt *new) · 32 unmodified lines
294}248}
295 249
296static int _svc_xprt_create(struct svc_serv *serv, const char *xprt_name,250static int _svc_xprt_create(struct svc_serv *serv, const char *xprt_name,
297 struct net *net, const int family,251 struct net *net, struct sockaddr *sap,
298 const unsigned short port, int flags,252 size_t len, int flags, const struct cred *cred)
299 const struct cred *cred)
300{253{
301 struct svc_xprt_class *xcl;254 struct svc_xprt_class *xcl;
302 255
@@ -312,8 +265,11 @@ static int _svc_xprt_create(struct svc_serv *serv, const char *xprt_name, · 9 unmodified lines
312 goto err;265 goto err;
313 266
314 spin_unlock(&svc_xprt_class_lock);267 spin_unlock(&svc_xprt_class_lock);
315 newxprt = __svc_xpo_create(xcl, serv, net, family, port, flags);268 newxprt = xcl->xcl_ops->xpo_create(serv, net, sap, len, flags);
316 if (IS_ERR(newxprt)) {269 if (IS_ERR(newxprt)) {
270 trace_svc_xprt_create_err(serv->sv_program->pg_name,
271 xcl->xcl_name, sap, len,
272 newxprt);
317 module_put(xcl->xcl_owner);273 module_put(xcl->xcl_owner);
318 return PTR_ERR(newxprt);274 return PTR_ERR(newxprt);
319 }275 }
@@ -329,6 +285,48 @@ static int _svc_xprt_create(struct svc_serv *serv, const char *xprt_name, · 9 unmodified lines
329 return -EPROTONOSUPPORT;285 return -EPROTONOSUPPORT;
330}286}
331 287
288/**
289 * svc_xprt_create_from_sa - Add a new listener to @serv from socket address
290 * @serv: target RPC service
291 * @xprt_name: transport class name
292 * @net: network namespace
293 * @sap: socket address pointer
294 * @flags: SVC_SOCK flags
295 * @cred: credential to bind to this transport
296 *
297 * Return local xprt port on success or %-EPROTONOSUPPORT on failure
298 */
299int svc_xprt_create_from_sa(struct svc_serv *serv, const char *xprt_name,
300 struct net *net, struct sockaddr *sap,
301 int flags, const struct cred *cred)
302{
303 size_t len;
304 int err;
305
306 switch (sap->sa_family) {
307 case AF_INET:
308 len = sizeof(struct sockaddr_in);
309 break;
310#if IS_ENABLED(CONFIG_IPV6)
311 case AF_INET6:
312 len = sizeof(struct sockaddr_in6);
313 break;
314#endif
315 default:
316 return -EAFNOSUPPORT;
317 }
318
319 err = _svc_xprt_create(serv, xprt_name, net, sap, len, flags, cred);
320 if (err == -EPROTONOSUPPORT) {
321 request_module("svc%s", xprt_name);
322 err = _svc_xprt_create(serv, xprt_name, net, sap, len, flags,
323 cred);
324 }
325
326 return err;
327}
328EXPORT_SYMBOL_GPL(svc_xprt_create_from_sa);
329
332/**330/**
333 * svc_xprt_create - Add a new listener to @serv331 * svc_xprt_create - Add a new listener to @serv
334 * @serv: target RPC service332 * @serv: target RPC service
@@ -339,23 +337,41 @@ static int _svc_xprt_create(struct svc_serv *serv, const char *xprt_name, · 4 unmodified lines
339 * @flags: SVC_SOCK flags337 * @flags: SVC_SOCK flags
340 * @cred: credential to bind to this transport338 * @cred: credential to bind to this transport
341 *339 *
342 * Return values:340 * Return local xprt port on success or %-EPROTONOSUPPORT on failure
343 * %0: New listener added successfully
344 * %-EPROTONOSUPPORT: Requested transport type not supported
345 */341 */
346int svc_xprt_create(struct svc_serv *serv, const char *xprt_name,342int svc_xprt_create(struct svc_serv *serv, const char *xprt_name,
347 struct net *net, const int family,343 struct net *net, const int family,
348 const unsigned short port, int flags,344 const unsigned short port, int flags,
349 const struct cred *cred)345 const struct cred *cred)
350{346{
351 int err;347 struct sockaddr_in sin = {
348 .sin_family = AF_INET,
349 .sin_addr.s_addr = htonl(INADDR_ANY),
350 .sin_port = htons(port),
351 };
352#if IS_ENABLED(CONFIG_IPV6)
353 struct sockaddr_in6 sin6 = {
354 .sin6_family = AF_INET6,
355 .sin6_addr = IN6ADDR_ANY_INIT,
356 .sin6_port = htons(port),
357 };
358#endif
359 struct sockaddr *sap;
352 360
353 err = _svc_xprt_create(serv, xprt_name, net, family, port, flags, cred);361 switch (family) {
354 if (err == -EPROTONOSUPPORT) {362 case PF_INET:
355 request_module("svc%s", xprt_name);363 sap = (struct sockaddr *)&sin;
356 err = _svc_xprt_create(serv, xprt_name, net, family, port, flags, cred);364 break;
365#if IS_ENABLED(CONFIG_IPV6)
366 case PF_INET6:
367 sap = (struct sockaddr *)&sin6;
368 break;
369#endif
370 default:
371 return -EAFNOSUPPORT;
357 }372 }
358 return err;373
374 return svc_xprt_create_from_sa(serv, xprt_name, net, sap, flags, cred);
359}375}
360EXPORT_SYMBOL_GPL(svc_xprt_create);376EXPORT_SYMBOL_GPL(svc_xprt_create);
361 377
@@ -1259,6 +1275,40 @@ static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt) · 897 unmodified lines
1259 return dr;1275 return dr;
1260}1276}
1261 1277
1278/**
1279 * svc_find_listener - find an RPC transport instance
1280 * @serv: pointer to svc_serv to search
1281 * @xcl_name: C string containing transport's class name
1282 * @net: owner net pointer
1283 * @sa: sockaddr containing address
1284 *
1285 * Return the transport instance pointer for the endpoint accepting
1286 * connections/peer traffic from the specified transport class,
1287 * and matching sockaddr.
1288 */
1289struct svc_xprt *svc_find_listener(struct svc_serv *serv, const char *xcl_name,
1290 struct net *net, const struct sockaddr *sa)
1291{
1292 struct svc_xprt *xprt;
1293 struct svc_xprt *found = NULL;
1294
1295 spin_lock_bh(&serv->sv_lock);
1296 list_for_each_entry(xprt, &serv->sv_permsocks, xpt_list) {
1297 if (xprt->xpt_net != net)
1298 continue;
1299 if (strcmp(xprt->xpt_class->xcl_name, xcl_name))
1300 continue;
1301 if (!rpc_cmp_addr_port(sa, (struct sockaddr *)&xprt->xpt_local))
1302 continue;
1303 found = xprt;
1304 svc_xprt_get(xprt);
1305 break;
1306 }
1307 spin_unlock_bh(&serv->sv_lock);
1308 return found;
1309}
1310EXPORT_SYMBOL_GPL(svc_find_listener);
1311
1262/**1312/**
1263 * svc_find_xprt - find an RPC transport instance1313 * svc_find_xprt - find an RPC transport instance
1264 * @serv: pointer to svc_serv to search1314 * @serv: pointer to svc_serv to search