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
6262 name: compound-ops
6363 type: u32
6464 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
65118
66119 operations:
67120 list:
@@ -87,3 +140,60 @@ operations: · 19 unmodified lines
87140 - sport
88141 - dport
89142 - 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
117117 if (nsm != NULL)
118118 refcount_inc(&nsm->sm_count);
119119 else {
120− host = NULL;
121120 nsm = nsm_get_handle(ni->net, ni->sap, ni->salen,
122121 ni->hostname, ni->hostname_len);
123122 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
334334 static int export_stats_init(struct export_stats *stats)
335335 {
336336 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);
338339 }
339340
340341 static void export_stats_reset(struct export_stats *stats)
341342 {
342− if (stats)
343− nfsd_percpu_counters_reset(stats->counter,
344− EXP_STATS_COUNTERS_NUM);
343+ if (stats) {
344+ int i;
345+
346+ for (i = 0; i < EXP_STATS_COUNTERS_NUM; i++)
347+ percpu_counter_set(&stats->counter[i], 0);
348+ }
345349 }
346350
347351 static void export_stats_destroy(struct export_stats *stats)
348352 {
349353 if (stats)
350− nfsd_percpu_counters_destroy(stats->counter,
351− EXP_STATS_COUNTERS_NUM);
354+ percpu_counter_destroy_many(stats->counter,
355+ EXP_STATS_COUNTERS_NUM);
352356 }
353357
354358 static void svc_export_put(struct kref *ref)
fs/nfsd/netlink.c+66−0
@@ -10,6 +10,36 @@ · 9 unmodified lines
1010
1111 #include <uapi/linux/nfsd_netlink.h>
1212
13+/* Common nested types */
14+const 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+
19+const 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 */
26+static 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 */
34+static 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 */
39+static 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+
1343 /* Ops table for nfsd */
1444 static const struct genl_split_ops nfsd_nl_ops[] = {
1545 {
@@ -19,6 +49,42 @@ static const struct genl_split_ops nfsd_nl_ops[] = { · 3 unmodified lines
1949 .done = nfsd_nl_rpc_status_get_done,
2050 .flags = GENL_CMD_CAP_DUMP,
2151 },
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+ },
2288 };
2389
2490 struct genl_family nfsd_nl_family __ro_after_init = {
fs/nfsd/netlink.h+10−0
@@ -11,11 +11,21 @@ · 10 unmodified lines
1111
1212 #include <uapi/linux/nfsd_netlink.h>
1313
14+/* Common nested types */
15+extern const struct nla_policy nfsd_sock_nl_policy[NFSD_A_SOCK_TRANSPORT_NAME + 1];
16+extern const struct nla_policy nfsd_version_nl_policy[NFSD_A_VERSION_ENABLED + 1];
17+
1418 int nfsd_nl_rpc_status_get_start(struct netlink_callback *cb);
1519 int nfsd_nl_rpc_status_get_done(struct netlink_callback *cb);
1620
1721 int nfsd_nl_rpc_status_get_dumpit(struct sk_buff *skb,
1822 struct netlink_callback *cb);
23+int nfsd_nl_threads_set_doit(struct sk_buff *skb, struct genl_info *info);
24+int nfsd_nl_threads_get_doit(struct sk_buff *skb, struct genl_info *info);
25+int nfsd_nl_version_set_doit(struct sk_buff *skb, struct genl_info *info);
26+int nfsd_nl_version_get_doit(struct sk_buff *skb, struct genl_info *info);
27+int nfsd_nl_listener_set_doit(struct sk_buff *skb, struct genl_info *info);
28+int nfsd_nl_listener_get_doit(struct sk_buff *skb, struct genl_info *info);
1929
2030 extern struct genl_family nfsd_nl_family;
2131
fs/nfsd/netns.h+1−0
@@ -218,6 +218,7 @@ struct nfsd_net { · 217 unmodified lines
218218 /* Simple check to find out if a given net was properly initialized */
219219 #define nfsd_netns_ready(nn) ((nn)->sessionid_hashtbl)
220220
221+extern bool nfsd_support_version(int vers);
221222 extern void nfsd_netns_free_versions(struct nfsd_net *nn);
222223
223224 extern 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
978978 return max(((u32)nn->nfsd4_lease)/10, 1u) * HZ;
979979 }
980980
981−static struct workqueue_struct *callback_wq;
982−
983981 static bool nfsd4_queue_cb(struct nfsd4_callback *cb)
984982 {
985− trace_nfsd_cb_queue(cb->cb_clp, cb);
986− return queue_work(callback_wq, &cb->cb_work);
983+ struct nfs4_client *clp = cb->cb_clp;
984+
985+ trace_nfsd_cb_queue(clp, cb);
986+ return queue_work(clp->cl_callback_wq, &cb->cb_work);
987987 }
988988
989989 static void nfsd41_cb_inflight_begin(struct nfs4_client *clp)
@@ -1153,7 +1153,7 @@ void nfsd4_probe_callback(struct nfs4_client *clp) · 163 unmodified lines
11531153 void nfsd4_probe_callback_sync(struct nfs4_client *clp)
11541154 {
11551155 nfsd4_probe_callback(clp);
1156− flush_workqueue(callback_wq);
1156+ flush_workqueue(clp->cl_callback_wq);
11571157 }
11581158
11591159 void 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
13721372 .rpc_release = nfsd4_cb_release,
13731373 };
13741374
1375−int 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−
1383−void nfsd4_destroy_callback_queue(void)
1384−{
1385− destroy_workqueue(callback_wq);
1386−}
1387−
13881375 /* must be called under the state lock */
13891376 void nfsd4_shutdown_callback(struct nfs4_client *clp)
13901377 {
@@ -1398,7 +1385,7 @@ void nfsd4_shutdown_callback(struct nfs4_client *clp) · 7 unmodified lines
13981385 * client, destroy the rpc client, and stop:
13991386 */
14001387 nfsd4_run_cb(&clp->cl_cb_null);
1401− flush_workqueue(callback_wq);
1388+ flush_workqueue(clp->cl_callback_wq);
14021389 nfsd41_cb_inflight_wait_complete(clp);
14031390 }
14041391
@@ -1420,9 +1407,9 @@ static struct nfsd4_conn * __nfsd4_find_backchannel(struct nfs4_client *clp) · 15 unmodified lines
14201407
14211408 /*
14221409 * 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 two
1424− * work items at once. So, for example, callback_wq handles all access
1425− * of cl_cb_client and all calls to rpc_create or rpc_shutdown_client.
1410+ * the fact that it is run from clp->cl_callback_wq, which won't run two
1411+ * work items at once. So, for example, clp->cl_callback_wq handles all
1412+ * access of cl_cb_client and all calls to rpc_create or rpc_shutdown_client.
14261413 */
14271414 static void nfsd4_process_cb_update(struct nfsd4_callback *cb)
14281415 {
fs/nfsd/nfs4proc.c+66−13
@@ -1737,7 +1737,7 @@ static void cleanup_async_copy(struct nfsd4_copy *copy) · 1736 unmodified lines
17371737 nfs4_put_copy(copy);
17381738 }
17391739
1740−static void nfsd4_send_cb_offload(struct nfsd4_copy *copy, __be32 nfserr)
1740+static void nfsd4_send_cb_offload(struct nfsd4_copy *copy)
17411741 {
17421742 struct nfsd4_cb_offload *cbo;
17431743
@@ -1747,12 +1747,12 @@ static void nfsd4_send_cb_offload(struct nfsd4_copy *copy, __be32 nfserr) · 3 unmodified lines
17471747
17481748 memcpy(&cbo->co_res, &copy->cp_res, sizeof(copy->cp_res));
17491749 memcpy(&cbo->co_fh, &copy->fh, sizeof(copy->fh));
1750− cbo->co_nfserr = nfserr;
1750+ cbo->co_nfserr = copy->nfserr;
17511751
17521752 nfsd4_init_cb(&cbo->co_cb, copy->cp_clp, &nfsd4_cb_offload_ops,
17531753 NFSPROC4_CLNT_CB_OFFLOAD);
17541754 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);
17561756 nfsd4_run_cb(&cbo->co_cb);
17571757 }
17581758
@@ -1766,7 +1766,6 @@ static void nfsd4_send_cb_offload(struct nfsd4_copy *copy, __be32 nfserr) · 7 unmodified lines
17661766 static int nfsd4_do_async_copy(void *data)
17671767 {
17681768 struct nfsd4_copy *copy = (struct nfsd4_copy *)data;
1769− __be32 nfserr;
17701769
17711770 trace_nfsd_copy_do_async(copy);
17721771 if (nfsd4_ssc_is_inter(copy)) {
@@ -1777,24 +1776,25 @@ static int nfsd4_do_async_copy(void *data) · 4 unmodified lines
17771776 if (IS_ERR(filp)) {
17781777 switch (PTR_ERR(filp)) {
17791778 case -EBADF:
1780− nfserr = nfserr_wrong_type;
1779+ copy->nfserr = nfserr_wrong_type;
17811780 break;
17821781 default:
1783− nfserr = nfserr_offload_denied;
1782+ copy->nfserr = nfserr_offload_denied;
17841783 }
17851784 /* ss_mnt will be unmounted by the laundromat */
17861785 goto do_callback;
17871786 }
1788− nfserr = nfsd4_do_copy(copy, filp, copy->nf_dst->nf_file,
1789− false);
1787+ copy->nfserr = nfsd4_do_copy(copy, filp, copy->nf_dst->nf_file,
1788+ false);
17901789 nfsd4_cleanup_inter_ssc(copy->ss_nsui, filp, copy->nf_dst);
17911790 } else {
1792− nfserr = nfsd4_do_copy(copy, copy->nf_src->nf_file,
1793− copy->nf_dst->nf_file, false);
1791+ copy->nfserr = nfsd4_do_copy(copy, copy->nf_src->nf_file,
1792+ copy->nf_dst->nf_file, false);
17941793 }
17951794
17961795 do_callback:
1797− nfsd4_send_cb_offload(copy, nfserr);
1796+ set_bit(NFSD4_COPY_F_COMPLETED, &copy->cp_flags);
1797+ nfsd4_send_cb_offload(copy);
17981798 cleanup_async_copy(copy);
17991799 return 0;
18001800 }
@@ -1807,6 +1807,13 @@ nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, · 6 unmodified lines
18071807 __be32 status;
18081808 struct nfsd4_copy *async_copy = NULL;
18091809
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+
18101817 copy->cp_clp = cstate->clp;
18111818 if (nfsd4_ssc_is_inter(copy)) {
18121819 trace_nfsd_copy_inter(copy);
@@ -2003,11 +2010,16 @@ nfsd4_offload_status(struct svc_rqst *rqstp, · 190 unmodified lines
20032010 struct nfsd4_copy *copy;
20042011 struct nfs4_client *clp = cstate->clp;
20052012
2013+ os->completed = false;
20062014 spin_lock(&clp->async_lock);
20072015 copy = find_async_copy_locked(clp, &os->stateid);
2008− if (copy)
2016+ if (copy) {
20092017 os->count = copy->cp_res.wr_bytes_written;
2010− else
2018+ if (test_bit(NFSD4_COPY_F_COMPLETED, &copy->cp_flags)) {
2019+ os->completed = true;
2020+ os->status = copy->nfserr;
2021+ }
2022+ } else
20112023 status = nfserr_bad_stateid;
20122024 spin_unlock(&clp->async_lock);
20132025
@@ -2154,6 +2166,29 @@ nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, · 140 unmodified lines
21542166 return status == nfserr_same ? nfs_ok : status;
21552167 }
21562168
2169+static __be32
2170+nfsd4_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+
21572192 #ifdef CONFIG_NFSD_PNFS
21582193 static const struct nfsd4_layout_ops *
21592194 nfsd4_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
30823117 * sizeof(__be32);
30833118 }
30843119
3120+static 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+
30853132 #ifdef CONFIG_NFSD_PNFS
30863133 static u32 nfsd4_getdeviceinfo_rsize(const struct svc_rqst *rqstp,
30873134 const struct nfsd4_op *op)
@@ -3470,6 +3517,12 @@ static const struct nfsd4_operation nfsd4_ops[] = { · 382 unmodified lines
34703517 .op_get_currentstateid = nfsd4_get_freestateid,
34713518 .op_rsize_bop = nfsd4_only_status_rsize,
34723519 },
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+ },
34733526 #ifdef CONFIG_NFSD_PNFS
34743527 [OP_GETDEVICEINFO] = {
34753528 .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
541541 }
542542
543543 static struct nfs4_openowner *
544−find_openstateowner_str_locked(unsigned int hashval, struct nfsd4_open *open,
544+find_openstateowner_str(unsigned int hashval, struct nfsd4_open *open,
545545 struct nfs4_client *clp)
546546 {
547547 struct nfs4_stateowner *so;
@@ -558,18 +558,6 @@ find_openstateowner_str_locked(unsigned int hashval, struct nfsd4_open *open, · 10 unmodified lines
558558 return NULL;
559559 }
560560
561−static struct nfs4_openowner *
562−find_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−
573561 static inline u32
574562 opaque_hashval(const void *ptr, int nbytes)
575563 {
@@ -1409,11 +1397,16 @@ static void · 833 unmodified lines
14091397 recalculate_deny_mode(struct nfs4_file *fp)
14101398 {
14111399 struct nfs4_ol_stateid *stp;
1400+ u32 old_deny;
14121401
14131402 spin_lock(&fp->fi_lock);
1403+ old_deny = fp->fi_share_deny;
14141404 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) {
14161406 fp->fi_share_deny |= bmap_to_share_mode(stp->st_deny_bmap);
1407+ if (fp->fi_share_deny == old_deny)
1408+ break;
1409+ }
14171410 spin_unlock(&fp->fi_lock);
14181411 }
14191412
@@ -2245,6 +2238,10 @@ static struct nfs4_client *alloc_client(struct xdr_netobj name, · 825 unmodified lines
22452238 GFP_KERNEL);
22462239 if (!clp->cl_ownerstr_hashtbl)
22472240 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+
22482245 for (i = 0; i < OWNER_HASH_SIZE; i++)
22492246 INIT_LIST_HEAD(&clp->cl_ownerstr_hashtbl[i]);
22502247 INIT_LIST_HEAD(&clp->cl_sessions);
@@ -2267,6 +2264,8 @@ static struct nfs4_client *alloc_client(struct xdr_netobj name, · 16 unmodified lines
22672264 spin_lock_init(&clp->cl_lock);
22682265 rpc_init_wait_queue(&clp->cl_cb_waitq, "Backchannel slot table");
22692266 return clp;
2267+err_no_callback_wq:
2268+ kfree(clp->cl_ownerstr_hashtbl);
22702269 err_no_hashtbl:
22712270 kfree(clp->cl_name.data);
22722271 err_no_name:
@@ -2280,6 +2279,7 @@ static void __free_client(struct kref *k) · 7 unmodified lines
22802279 struct nfs4_client *clp = container_of(c, struct nfs4_client, cl_nfsdfs);
22812280
22822281 free_svc_cred(&clp->cl_cred);
2282+ destroy_workqueue(clp->cl_callback_wq);
22832283 kfree(clp->cl_ownerstr_hashtbl);
22842284 kfree(clp->cl_name.data);
22852285 kfree(clp->cl_nii_domain.data);
@@ -2352,7 +2352,11 @@ unhash_client(struct nfs4_client *clp) · 66 unmodified lines
23522352
23532353 static __be32 mark_client_expired_locked(struct nfs4_client *clp)
23542354 {
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)
23562360 return nfserr_jukebox;
23572361 unhash_client_locked(clp);
23582362 return nfs_ok;
@@ -3641,12 +3645,8 @@ out_nolock: · 1282 unmodified lines
36413645 return status;
36423646 }
36433647
3644−static __be32
3645−check_slot_seqid(u32 seqid, u32 slot_seqid, int slot_inuse)
3648+static __be32 check_slot_seqid(u32 seqid, u32 slot_seqid, bool slot_inuse)
36463649 {
3647− dprintk("%s enter. seqid %d slot_seqid %d\n", __func__, seqid,
3648− slot_seqid);
3649−
36503650 /* The slot is in use, and no response has been sent. */
36513651 if (slot_inuse) {
36523652 if (seqid == slot_seqid)
@@ -3823,10 +3823,13 @@ nfsd4_create_session(struct svc_rqst *rqstp, · 170 unmodified lines
38233823 }
38243824
38253825 /* RFC 8881 Section 18.36.4 Phase 2: Sequence ID processing. */
3826− if (conf)
3826+ if (conf) {
38273827 cs_slot = &conf->cl_cs_slot;
3828− else
3828+ trace_nfsd_slot_seqid_conf(conf, cr_ses);
3829+ } else {
38293830 cs_slot = &unconf->cl_cs_slot;
3831+ trace_nfsd_slot_seqid_unconf(unconf, cr_ses);
3832+ }
38303833 status = check_slot_seqid(cr_ses->seqid, cs_slot->sl_seqid, 0);
38313834 switch (status) {
38323835 case nfs_ok:
@@ -4221,6 +4224,7 @@ nfsd4_sequence(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, · 388 unmodified lines
42214224 * sr_highest_slotid and the sr_target_slot id to maxslots */
42224225 seq->maxslots = session->se_fchannel.maxreqs;
42234226
4227+ trace_nfsd_slot_seqid_sequence(clp, seq, slot);
42244228 status = check_slot_seqid(seq->seqid, slot->sl_seqid,
42254229 slot->sl_flags & NFSD4_SLOT_INUSE);
42264230 if (status == nfserr_replay_cache) {
@@ -4662,21 +4666,32 @@ nfsd4_init_leases_net(struct nfsd_net *nn) · 435 unmodified lines
46624666 atomic_set(&nn->nfsd_courtesy_clients, 0);
46634667 }
46644668
4669+enum rp_lock {
4670+ RP_UNLOCKED,
4671+ RP_LOCKED,
4672+ RP_UNHASHED,
4673+};
4674+
46654675 static void init_nfs4_replay(struct nfs4_replay *rp)
46664676 {
46674677 rp->rp_status = nfserr_serverfault;
46684678 rp->rp_buflen = 0;
46694679 rp->rp_buf = rp->rp_ibuf;
4670− mutex_init(&rp->rp_mutex);
4680+ atomic_set(&rp->rp_locked, RP_UNLOCKED);
46714681 }
46724682
4673−static void nfsd4_cstate_assign_replay(struct nfsd4_compound_state *cstate,
4674− struct nfs4_stateowner *so)
4683+static int nfsd4_cstate_assign_replay(struct nfsd4_compound_state *cstate,
4684+ struct nfs4_stateowner *so)
46754685 {
46764686 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;
46784692 cstate->replay_owner = nfs4_get_stateowner(so);
46794693 }
4694+ return 0;
46804695 }
46814696
46824697 void 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
46854700
46864701 if (so != NULL) {
46874702 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);
46894705 nfs4_put_stateowner(so);
46904706 }
46914707 }
@@ -4866,34 +4882,46 @@ nfsd4_find_and_lock_existing_open(struct nfs4_file *fp, struct nfsd4_open *open) · 174 unmodified lines
48664882 }
48674883
48684884 static struct nfs4_openowner *
4869−alloc_init_open_stateowner(unsigned int strhashval, struct nfsd4_open *open,
4870− struct nfsd4_compound_state *cstate)
4885+find_or_alloc_open_stateowner(unsigned int strhashval, struct nfsd4_open *open,
4886+ struct nfsd4_compound_state *cstate)
48714887 {
48724888 struct nfs4_client *clp = cstate->clp;
4873− struct nfs4_openowner *oo, *ret;
4889+ struct nfs4_openowner *oo, *new = NULL;
48744890
4875− oo = alloc_stateowner(openowner_slab, &open->op_owner, clp);
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);
4891+retry:
48874892 spin_lock(&clp->cl_lock);
4888− ret = find_openstateowner_str_locked(strhashval, open, clp);
4889− if (ret == NULL) {
4890− hash_openowner(oo, clp, strhashval);
4891− ret = oo;
4892− } else
4893− nfs4_free_stateowner(&oo->oo_owner);
4894−
4893+ oo = find_openstateowner_str(strhashval, open, clp);
4894+ if (!oo && new) {
4895+ hash_openowner(new, clp, strhashval);
4896+ spin_unlock(&clp->cl_lock);
4897+ return new;
4898+ }
48954899 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;
48974925 }
48984926
48994927 static struct nfs4_ol_stateid *
@@ -4969,7 +4997,11 @@ move_to_close_lru(struct nfs4_ol_stateid *s, struct net *net) · 69 unmodified lines
49694997 * Wait for the refcount to drop to 2. Since it has been unhashed,
49704998 * there should be no danger of the refcount going back up again at
49714999 * this point.
5000+ * Some threads with a reference might be waiting for rp_locked,
5001+ * so tell them to stop waiting.
49725002 */
5003+ atomic_set(&oo->oo_owner.so_replay.rp_locked, RP_UNHASHED);
5004+ wake_up_var(&oo->oo_owner.so_replay.rp_locked);
49735005 wait_event(close_wq, refcount_read(&s->st_stid.sc_count) == 2);
49745006
49755007 release_all_access(s);
@@ -5342,27 +5374,19 @@ nfsd4_process_open1(struct nfsd4_compound_state *cstate, · 366 unmodified lines
53425374 clp = cstate->clp;
53435375
53445376 strhashval = ownerstr_hashval(&open->op_owner);
5345− oo = find_openstateowner_str(strhashval, open, clp);
5377+retry:
5378+ oo = find_or_alloc_open_stateowner(strhashval, open, cstate);
53465379 open->op_openowner = oo;
5347− if (!oo) {
5348− goto new_owner;
5349− }
5350− if (!(oo->oo_flags & NFS4_OO_CONFIRMED)) {
5351− /* Replace unconfirmed owners without checking for replay. */
5352− release_openowner(oo);
5353− open->op_openowner = NULL;
5354− goto new_owner;
5380+ if (!oo)
5381+ return nfserr_jukebox;
5382+ if (nfsd4_cstate_assign_replay(cstate, &oo->oo_owner) == -EAGAIN) {
5383+ nfs4_put_stateowner(&oo->oo_owner);
5384+ goto retry;
53555385 }
53565386 status = nfsd4_check_seqid(cstate, &oo->oo_owner, open->op_seqid);
53575387 if (status)
53585388 return status;
5359− goto alloc_stateid;
5360−new_owner:
5361− oo = alloc_init_open_stateowner(strhashval, open, cstate);
5362− if (oo == NULL)
5363− return nfserr_jukebox;
5364− open->op_openowner = oo;
5365−alloc_stateid:
5389+
53665390 open->op_stp = nfs4_alloc_open_stateid(clp);
53675391 if (!open->op_stp)
53685392 return nfserr_jukebox;
@@ -6133,12 +6157,8 @@ out: · 764 unmodified lines
61336157 void nfsd4_cleanup_open_state(struct nfsd4_compound_state *cstate,
61346158 struct nfsd4_open *open)
61356159 {
6136− if (open->op_openowner) {
6137− struct nfs4_stateowner *so = &open->op_openowner->oo_owner;
6138−
6139− nfsd4_cstate_assign_replay(cstate, so);
6140− nfs4_put_stateowner(so);
6141− }
6160+ if (open->op_openowner)
6161+ nfs4_put_stateowner(&open->op_openowner->oo_owner);
61426162 if (open->op_file)
61436163 kmem_cache_free(file_slab, open->op_file);
61446164 if (open->op_stp)
@@ -7202,12 +7222,16 @@ nfs4_preprocess_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid, · 1057 unmodified lines
72027222 trace_nfsd_preprocess(seqid, stateid);
72037223
72047224 *stpp = NULL;
7225+retry:
72057226 status = nfsd4_lookup_stateid(cstate, stateid,
72067227 typemask, statusmask, &s, nn);
72077228 if (status)
72087229 return status;
72097230 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+ }
72117235
72127236 status = nfs4_seqid_op_checks(cstate, stateid, seqid, stp);
72137237 if (!status)
@@ -7349,7 +7373,7 @@ out: · 135 unmodified lines
73497373 return status;
73507374 }
73517375
7352−static void nfsd4_close_open_stateid(struct nfs4_ol_stateid *s)
7376+static bool nfsd4_close_open_stateid(struct nfs4_ol_stateid *s)
73537377 {
73547378 struct nfs4_client *clp = s->st_stid.sc_client;
73557379 bool unhashed;
@@ -7366,11 +7390,11 @@ static void nfsd4_close_open_stateid(struct nfs4_ol_stateid *s) · 10 unmodified lines
73667390 list_for_each_entry(stp, &reaplist, st_locks)
73677391 nfs4_free_cpntf_statelist(clp->net, &stp->st_stid);
73687392 free_ol_stateid_reaplist(&reaplist);
7393+ return false;
73697394 } else {
73707395 spin_unlock(&clp->cl_lock);
73717396 free_ol_stateid_reaplist(&reaplist);
7372− if (unhashed)
7373− move_to_close_lru(s, clp->net);
7397+ return unhashed;
73747398 }
73757399 }
73767400
@@ -7386,6 +7410,7 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, · 9 unmodified lines
73867410 struct nfs4_ol_stateid *stp;
73877411 struct net *net = SVC_NET(rqstp);
73887412 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
7413+ bool need_move_to_close_list;
73897414
73907415 dprintk("NFSD: nfsd4_close on file %pd\n",
73917416 cstate->current_fh.fh_dentry);
@@ -7410,8 +7435,10 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, · 18 unmodified lines
74107435 */
74117436 nfs4_inc_and_copy_stateid(&close->cl_stateid, &stp->st_stid);
74127437
7413− nfsd4_close_open_stateid(stp);
7438+ need_move_to_close_list = nfsd4_close_open_stateid(stp);
74147439 mutex_unlock(&stp->st_mutex);
7440+ if (need_move_to_close_list)
7441+ move_to_close_lru(stp, net);
74157442
74167443 /* v4.1+ suggests that we send a special stateid in here, since the
74177444 * clients should just ignore this anyway. Since this is not useful
@@ -8625,12 +8652,6 @@ nfs4_state_start(void) · 1207 unmodified lines
86258652 if (ret)
86268653 return ret;
86278654
8628− ret = nfsd4_create_callback_queue();
8629− if (ret) {
8630− rhltable_destroy(&nfs4_file_rhltable);
8631− return ret;
8632− }
8633−
86348655 set_max_delegations();
86358656 return 0;
86368657 }
@@ -8671,7 +8692,6 @@ nfs4_state_shutdown_net(struct net *net) · 34 unmodified lines
86718692 void
86728693 nfs4_state_shutdown(void)
86738694 {
8674− nfsd4_destroy_callback_queue();
86758695 rhltable_destroy(&nfs4_file_rhltable);
86768696 }
86778697
fs/nfsd/nfs4xdr.c+80−3
@@ -1732,6 +1732,35 @@ nfsd4_decode_free_stateid(struct nfsd4_compoundargs *argp, · 1731 unmodified lines
17321732 return nfsd4_decode_stateid4(argp, &free_stateid->fr_stateid);
17331733 }
17341734
1735+static __be32
1736+nfsd4_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+
17351764 #ifdef CONFIG_NFSD_PNFS
17361765 static __be32
17371766 nfsd4_decode_getdeviceinfo(struct nfsd4_compoundargs *argp,
@@ -2370,7 +2399,7 @@ static const nfsd4_dec nfsd4_dec_ops[] = { · 632 unmodified lines
23702399 [OP_CREATE_SESSION] = nfsd4_decode_create_session,
23712400 [OP_DESTROY_SESSION] = nfsd4_decode_destroy_session,
23722401 [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,
23742403 #ifdef CONFIG_NFSD_PNFS
23752404 [OP_GETDEVICEINFO] = nfsd4_decode_getdeviceinfo,
23762405 [OP_GETDEVICELIST] = nfsd4_decode_notsupp,
@@ -4963,6 +4992,49 @@ nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, __be32 nfserr, · 2586 unmodified lines
49634992 return nfs_ok;
49644993 }
49654994
4995+static __be32
4996+nfsd4_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+
49665038 #ifdef CONFIG_NFSD_PNFS
49675039 static __be32
49685040 nfsd4_encode_device_addr4(struct xdr_stream *xdr,
@@ -5199,7 +5271,12 @@ nfsd4_encode_offload_status(struct nfsd4_compoundres *resp, __be32 nfserr, · 230 unmodified lines
51995271 if (nfserr != nfs_ok)
52005272 return nfserr;
52015273 /* 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)
52035280 return nfserr_resource;
52045281 return nfs_ok;
52055282 }
@@ -5579,7 +5656,7 @@ static const nfsd4_enc nfsd4_enc_ops[] = { · 373 unmodified lines
55795656 [OP_CREATE_SESSION] = nfsd4_encode_create_session,
55805657 [OP_DESTROY_SESSION] = nfsd4_encode_noop,
55815658 [OP_FREE_STATEID] = nfsd4_encode_noop,
5582− [OP_GET_DIR_DELEGATION] = nfsd4_encode_noop,
5659+ [OP_GET_DIR_DELEGATION] = nfsd4_encode_get_dir_delegation,
55835660 #ifdef CONFIG_NFSD_PNFS
55845661 [OP_GETDEVICEINFO] = nfsd4_encode_getdeviceinfo,
55855662 [OP_GETDEVICELIST] = nfsd4_encode_noop,
fs/nfsd/nfsctl.c+521−5
@@ -15,6 +15,7 @@ · 14 unmodified lines
1515 #include <linux/sunrpc/addr.h>
1616 #include <linux/sunrpc/gss_api.h>
1717 #include <linux/sunrpc/rpc_pipe_fs.h>
18+#include <linux/sunrpc/svc.h>
1819 #include <linux/module.h>
1920 #include <linux/fsnotify.h>
2021
@@ -48,12 +49,10 @@ enum { · 27 unmodified lines
4849 NFSD_MaxBlkSize,
4950 NFSD_MaxConnections,
5051 NFSD_Filecache,
51−#ifdef CONFIG_NFSD_V4
5252 NFSD_Leasetime,
5353 NFSD_Gracetime,
5454 NFSD_RecoveryDir,
5555 NFSD_V4EndGrace,
56−#endif
5756 NFSD_MaxReserved
5857 };
5958
@@ -406,7 +405,9 @@ static ssize_t write_threads(struct file *file, char *buf, size_t size) · 346 unmodified lines
406405 if (newthreads < 0)
407406 return -EINVAL;
408407 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);
410411 if (rv < 0)
411412 return rv;
412413 } else
@@ -1360,7 +1361,9 @@ static int nfsd_fill_super(struct super_block *sb, struct fs_context *fc) · 947 unmodified lines
13601361 #ifdef CONFIG_NFSD_V4
13611362 [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},
13621363 [NFSD_Gracetime] = {"nfsv4gracetime", &transaction_ops, S_IWUSR|S_IRUSR},
1364+#ifdef CONFIG_NFSD_LEGACY_CLIENT_TRACKING
13631365 [NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR},
1366+#endif
13641367 [NFSD_V4EndGrace] = {"v4_end_grace", &transaction_ops, S_IWUSR|S_IRUGO},
13651368 #endif
13661369 /* last one */ {""}
@@ -1651,6 +1654,518 @@ int nfsd_nl_rpc_status_get_done(struct netlink_callback *cb) · 284 unmodified lines
16511654 return 0;
16521655 }
16531656
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+ */
1664+int 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+
1727+out_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+ */
1740+int 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+
1791+err_unlock:
1792+ mutex_unlock(&nfsd_mutex);
1793+err_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+ */
1806+int 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+ */
1876+int 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+
1941+err_nfsd_unlock:
1942+ mutex_unlock(&nfsd_mutex);
1943+err_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+ */
1956+int 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+
2093+out_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+ */
2106+int 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);
2154+out_unlock_mtx:
2155+ mutex_unlock(&nfsd_mutex);
2156+ genlmsg_end(skb, hdr);
2157+
2158+ return genlmsg_reply(skb, info);
2159+
2160+err_serv_unlock:
2161+ spin_unlock_bh(&serv->sv_lock);
2162+ mutex_unlock(&nfsd_mutex);
2163+err_free_msg:
2164+ nlmsg_free(skb);
2165+
2166+ return err;
2167+}
2168+
16542169 /**
16552170 * nfsd_net_init - Prepare the nfsd_net portion of a new net namespace
16562171 * @net: a freshly-created network namespace
@@ -1672,7 +2187,8 @@ static __net_init int nfsd_net_init(struct net *net) · 15 unmodified lines
16722187 retval = nfsd_idmap_init(net);
16732188 if (retval)
16742189 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);
16762192 if (retval)
16772193 goto out_repcache_error;
16782194 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
17042220 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
17052221
17062222 nfsd_proc_stat_shutdown(net);
1707− nfsd_stat_counters_destroy(nn);
2223+ percpu_counter_destroy_many(nn->counter, NFSD_STATS_COUNTERS_NUM);
17082224 nfsd_idmap_shutdown(net);
17092225 nfsd_export_shutdown(net);
17102226 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
103103 /*
104104 * Function prototypes.
105105 */
106−int nfsd_svc(int nrservs, struct net *net, const struct cred *cred);
106+int nfsd_svc(int nrservs, struct net *net, const struct cred *cred, const char *scope);
107107 int nfsd_dispatch(struct svc_rqst *rqstp);
108108
109109 int nfsd_nrthreads(struct net *);
@@ -230,7 +230,6 @@ void nfsd_lockd_shutdown(void); · 120 unmodified lines
230230 #define nfserr_nospc cpu_to_be32(NFSERR_NOSPC)
231231 #define nfserr_rofs cpu_to_be32(NFSERR_ROFS)
232232 #define nfserr_mlink cpu_to_be32(NFSERR_MLINK)
233−#define nfserr_opnotsupp cpu_to_be32(NFSERR_OPNOTSUPP)
234233 #define nfserr_nametoolong cpu_to_be32(NFSERR_NAMETOOLONG)
235234 #define nfserr_notempty cpu_to_be32(NFSERR_NOTEMPTY)
236235 #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
573573 _fh_update(fhp, exp, dentry);
574574 if (fhp->fh_handle.fh_fileid_type == FILEID_INVALID) {
575575 fh_put(fhp);
576− return nfserr_opnotsupp;
576+ return nfserr_stale;
577577 }
578578
579579 return 0;
@@ -599,7 +599,7 @@ fh_update(struct svc_fh *fhp) · 19 unmodified lines
599599
600600 _fh_update(fhp, fhp->fh_export, dentry);
601601 if (fhp->fh_handle.fh_fileid_type == FILEID_INVALID)
602− return nfserr_opnotsupp;
602+ return nfserr_stale;
603603 return 0;
604604 out_bad:
605605 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
133133 .pg_rpcbind_set = nfsd_rpcbind_set,
134134 };
135135
136−static bool
137−nfsd_support_version(int vers)
136+bool nfsd_support_version(int vers)
138137 {
139138 if (vers >= NFSD_MINVERS && vers < NFSD_NRVERS)
140139 return nfsd_version[vers] != NULL;
@@ -769,13 +768,14 @@ int nfsd_set_nrthreads(int n, int *nthreads, struct net *net) · 628 unmodified lines
769768 * this is the first time nrservs is nonzero.
770769 */
771770 int
772−nfsd_svc(int nrservs, struct net *net, const struct cred *cred)
771+nfsd_svc(int nrservs, struct net *net, const struct cred *cred, const char *scope)
773772 {
774773 int error;
775774 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
776775 struct svc_serv *serv;
777776
778− mutex_lock(&nfsd_mutex);
777+ lockdep_assert_held(&nfsd_mutex);
778+
779779 dprintk("nfsd: creating service\n");
780780
781781 nrservs = max(nrservs, 0);
@@ -785,7 +785,7 @@ nfsd_svc(int nrservs, struct net *net, const struct cred *cred) · 3 unmodified lines
785785 if (nrservs == 0 && nn->nfsd_serv == NULL)
786786 goto out;
787787
788− strscpy(nn->nfsd_name, utsname()->nodename,
788+ strscpy(nn->nfsd_name, scope ? scope : utsname()->nodename,
789789 sizeof(nn->nfsd_name));
790790
791791 error = nfsd_create_serv(net);
@@ -804,7 +804,6 @@ out_put: · 12 unmodified lines
804804 if (serv->sv_nrthreads == 0)
805805 nfsd_destroy_serv(net);
806806 out:
807− mutex_unlock(&nfsd_mutex);
808807 return error;
809808 }
810809
fs/nfsd/state.h+3−3
@@ -408,6 +408,8 @@ struct nfs4_client { · 407 unmodified lines
408408 1 << NFSD4_CLIENT_CB_KILL)
409409 #define NFSD4_CLIENT_CB_RECALL_ANY (6)
410410 unsigned long cl_flags;
411+
412+ struct workqueue_struct *cl_callback_wq;
411413 const struct cred *cl_cb_cred;
412414 struct rpc_clnt *cl_cb_client;
413415 u32 cl_cb_ident;
@@ -486,7 +488,7 @@ struct nfs4_replay { · 72 unmodified lines
486488 unsigned int rp_buflen;
487489 char *rp_buf;
488490 struct knfsd_fh rp_openfh;
489− struct mutex rp_mutex;
491+ atomic_t rp_locked;
490492 char rp_ibuf[NFSD4_REPLAY_ISIZE];
491493 };
492494
@@ -735,8 +737,6 @@ extern void nfsd4_change_callback(struct nfs4_client *clp, struct nfs4_cb_conn * · 242 unmodified lines
735737 extern void nfsd4_init_cb(struct nfsd4_callback *cb, struct nfs4_client *clp,
736738 const struct nfsd4_callback_ops *ops, enum nfsd4_cb_op op);
737739 extern bool nfsd4_run_cb(struct nfsd4_callback *cb);
738−extern int nfsd4_create_callback_queue(void);
739−extern void nfsd4_destroy_callback_queue(void);
740740 extern void nfsd4_shutdown_callback(struct nfs4_client *);
741741 extern void nfsd4_shutdown_copy(struct nfs4_client *clp);
742742 extern 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
7373
7474 DEFINE_PROC_SHOW_ATTRIBUTE(nfsd);
7575
76−int 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−
92−void 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−
100−void 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−
108−int nfsd_stat_counters_init(struct nfsd_net *nn)
109−{
110− return nfsd_percpu_counters_init(nn->counter, NFSD_STATS_COUNTERS_NUM);
111−}
112−
113−void nfsd_stat_counters_destroy(struct nfsd_net *nn)
114−{
115− nfsd_percpu_counters_destroy(nn->counter, NFSD_STATS_COUNTERS_NUM);
116−}
117−
11876 void nfsd_proc_stat_init(struct net *net)
11977 {
12078 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
fs/nfsd/stats.h+0−5
@@ -10,11 +10,6 @@ · 9 unmodified lines
1010 #include <uapi/linux/nfsd/stats.h>
1111 #include <linux/percpu_counter.h>
1212
13−int nfsd_percpu_counters_init(struct percpu_counter *counters, int num);
14−void nfsd_percpu_counters_reset(struct percpu_counter *counters, int num);
15−void nfsd_percpu_counters_destroy(struct percpu_counter *counters, int num);
16−int nfsd_stat_counters_init(struct nfsd_net *nn);
17−void nfsd_stat_counters_destroy(struct nfsd_net *nn);
1813 void nfsd_proc_stat_init(struct net *net);
1914 void nfsd_proc_stat_shutdown(struct net *net);
2015
fs/nfsd/trace.h+97−3
@@ -749,6 +749,76 @@ TRACE_EVENT_CONDITION(nfsd_seq4_status, · 748 unmodified lines
749749 )
750750 );
751751
752+DECLARE_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) \
782+DEFINE_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+
789+DEFINE_CS_SLOT_EVENT(slot_seqid_conf);
790+DEFINE_CS_SLOT_EVENT(slot_seqid_unconf);
791+
792+TRACE_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+
752822 DECLARE_EVENT_CLASS(nfsd_clientid_class,
753823 TP_PROTO(const clientid_t *clid),
754824 TP_ARGS(clid),
@@ -778,6 +848,30 @@ DEFINE_CLIENTID_EVENT(purged); · 23 unmodified lines
778848 DEFINE_CLIENTID_EVENT(renew);
779849 DEFINE_CLIENTID_EVENT(stale);
780850
851+TRACE_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+
781875 DECLARE_EVENT_CLASS(nfsd_net_class,
782876 TP_PROTO(const struct nfsd_net *nn),
783877 TP_ARGS(nn),
@@ -1534,7 +1628,7 @@ TRACE_EVENT(nfsd_cb_seq_status, · 750 unmodified lines
15341628 __entry->seq_status = cb->cb_seq_status;
15351629 ),
15361630 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",
15381632 __entry->task_id, __entry->client_id,
15391633 __entry->cl_boot, __entry->cl_id,
15401634 __entry->seqno, __entry->reserved,
@@ -1573,7 +1667,7 @@ TRACE_EVENT(nfsd_cb_free_slot, · 32 unmodified lines
15731667 __entry->slot_seqno = session->se_cb_seq_nr;
15741668 ),
15751669 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",
15771671 __entry->task_id, __entry->client_id,
15781672 __entry->cl_boot, __entry->cl_id,
15791673 __entry->seqno, __entry->reserved,
@@ -1978,7 +2072,7 @@ TRACE_EVENT(nfsd_ctl_time, · 398 unmodified lines
19782072 __entry->time = time;
19792073 __assign_str(name, name);
19802074 ),
1981− TP_printk("file=%s time=%d\n",
2075+ TP_printk("file=%s time=%d",
19822076 __get_str(name), __entry->time
19832077 )
19842078 );
fs/nfsd/vfs.c+1−1
@@ -1422,7 +1422,7 @@ nfsd_create_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, · 1421 unmodified lines
14221422 * Callers expect new file metadata to be committed even
14231423 * if the attributes have not changed.
14241424 */
1425− if (iap->ia_valid)
1425+ if (nfsd_attrs_valid(attrs))
14261426 status = nfsd_setattr(rqstp, resfhp, attrs, NULL);
14271427 else
14281428 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
6060 posix_acl_release(attrs->na_dpacl);
6161 }
6262
63+static 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+
6371 __be32 nfserrno (int errno);
6472 int nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp,
6573 struct svc_export **expp);
fs/nfsd/xdr4.h+23−1
@@ -518,6 +518,24 @@ struct nfsd4_free_stateid { · 517 unmodified lines
518518 stateid_t fr_stateid; /* request */
519519 };
520520
521+struct 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+
521539 /* also used for NVERIFY */
522540 struct nfsd4_verify {
523541 u32 ve_bmval[3]; /* request */
@@ -674,8 +692,10 @@ struct nfsd4_copy { · 150 unmodified lines
674692 #define NFSD4_COPY_F_INTRA (1)
675693 #define NFSD4_COPY_F_SYNCHRONOUS (2)
676694 #define NFSD4_COPY_F_COMMITTED (3)
695+#define NFSD4_COPY_F_COMPLETED (4)
677696
678697 /* response */
698+ __be32 nfserr;
679699 struct nfsd42_write_res cp_res;
680700 struct knfsd_fh fh;
681701
@@ -735,7 +755,8 @@ struct nfsd4_offload_status { · 53 unmodified lines
735755
736756 /* response */
737757 u64 count;
738− u32 status;
758+ __be32 status;
759+ bool completed;
739760 };
740761
741762 struct nfsd4_copy_notify {
@@ -797,6 +818,7 @@ struct nfsd4_op { · 55 unmodified lines
797818 struct nfsd4_reclaim_complete reclaim_complete;
798819 struct nfsd4_test_stateid test_stateid;
799820 struct nfsd4_free_stateid free_stateid;
821+ struct nfsd4_get_dir_delegation get_dir_delegation;
800822 struct nfsd4_getdeviceinfo getdeviceinfo;
801823 struct nfsd4_layoutget layoutget;
802824 struct nfsd4_layoutcommit layoutcommit;
include/linux/nfs4.h+6−0
@@ -701,6 +701,12 @@ enum state_protect_how4 { · 700 unmodified lines
701701 SP4_SSV = 2
702702 };
703703
704+/* GET_DIR_DELEGATION non-fatal status codes */
705+enum gddrnf4_status {
706+ GDD4_OK = 0,
707+ GDD4_UNAVAIL = 1
708+};
709+
704710 enum pnfs_layouttype {
705711 LAYOUT_NFSV4_1_FILES = 1,
706712 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
135135 void svc_unreg_xprt_class(struct svc_xprt_class *);
136136 void svc_xprt_init(struct net *, struct svc_xprt_class *, struct svc_xprt *,
137137 struct svc_serv *);
138+int 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);
138141 int svc_xprt_create(struct svc_serv *serv, const char *xprt_name,
139142 struct net *net, const int family,
140143 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
147150 void svc_xprt_close(struct svc_xprt *xprt);
148151 int svc_port_is_privileged(struct sockaddr *sin);
149152 int svc_print_xprts(char *buf, int maxlen);
153+struct svc_xprt *svc_find_listener(struct svc_serv *serv, const char *xcl_name,
154+ struct net *net, const struct sockaddr *sa);
150155 struct svc_xprt *svc_find_xprt(struct svc_serv *serv, const char *xcl_name,
151156 struct net *net, const sa_family_t af,
152157 const unsigned short port);
include/trace/misc/nfs.h+0−2
@@ -28,7 +28,6 @@ TRACE_DEFINE_ENUM(NFSERR_FBIG); · 27 unmodified lines
2828 TRACE_DEFINE_ENUM(NFSERR_NOSPC);
2929 TRACE_DEFINE_ENUM(NFSERR_ROFS);
3030 TRACE_DEFINE_ENUM(NFSERR_MLINK);
31−TRACE_DEFINE_ENUM(NFSERR_OPNOTSUPP);
3231 TRACE_DEFINE_ENUM(NFSERR_NAMETOOLONG);
3332 TRACE_DEFINE_ENUM(NFSERR_NOTEMPTY);
3433 TRACE_DEFINE_ENUM(NFSERR_DQUOT);
@@ -64,7 +63,6 @@ TRACE_DEFINE_ENUM(NFSERR_JUKEBOX); · 29 unmodified lines
6463 { NFSERR_NOSPC, "NOSPC" }, \
6564 { NFSERR_ROFS, "ROFS" }, \
6665 { NFSERR_MLINK, "MLINK" }, \
67− { NFSERR_OPNOTSUPP, "OPNOTSUPP" }, \
6866 { NFSERR_NAMETOOLONG, "NAMETOOLONG" }, \
6967 { NFSERR_NOTEMPTY, "NOTEMPTY" }, \
7068 { NFSERR_DQUOT, "DQUOT" }, \
include/uapi/linux/nfs.h+0−1
@@ -61,7 +61,6 @@ · 60 unmodified lines
6161 NFSERR_NOSPC = 28, /* v2 v3 v4 */
6262 NFSERR_ROFS = 30, /* v2 v3 v4 */
6363 NFSERR_MLINK = 31, /* v3 v4 */
64− NFSERR_OPNOTSUPP = 45, /* v2 v3 */
6564 NFSERR_NAMETOOLONG = 63, /* v2 v3 v4 */
6665 NFSERR_NOTEMPTY = 66, /* v2 v3 v4 */
6766 NFSERR_DQUOT = 69, /* v2 v3 v4 */
include/uapi/linux/nfsd_netlink.h+47−0
@@ -29,8 +29,55 @@ enum { · 28 unmodified lines
2929 NFSD_A_RPC_STATUS_MAX = (__NFSD_A_RPC_STATUS_MAX - 1)
3030 };
3131
32+enum {
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+
42+enum {
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+
51+enum {
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+
58+enum {
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+
66+enum {
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+
3273 enum {
3374 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,
3481
3582 __NFSD_CMD_MAX,
3683 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
10331033
10341034 static void gss_free_in_token_pages(struct gssp_in_token *in_token)
10351035 {
1036− u32 inlen;
10371036 int i;
10381037
10391038 i = 0;
1040− inlen = in_token->page_len;
1041− while (inlen) {
1042− if (in_token->pages[i])
1043− put_page(in_token->pages[i]);
1044− inlen -= inlen > PAGE_SIZE ? PAGE_SIZE : inlen;
1045− }
1046−
1039+ while (in_token->pages[i])
1040+ put_page(in_token->pages[i++]);
10471041 kfree(in_token->pages);
10481042 in_token->pages = NULL;
10491043 }
net/sunrpc/svc.c+0−2
@@ -1265,8 +1265,6 @@ svc_generic_init_request(struct svc_rqst *rqstp, · 1264 unmodified lines
12651265 if (rqstp->rq_proc >= versp->vs_nproc)
12661266 goto err_bad_proc;
12671267 rqstp->rq_procinfo = procp = &versp->vs_proc[rqstp->rq_proc];
1268− if (!procp)
1269− goto err_bad_proc;
12701268
12711269 /* Initialize storage for argp and resp */
12721270 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
4646
4747 /* SMP locking strategy:
4848 *
49− * svc_pool->sp_lock protects most of the fields of that pool.
5049 * svc_serv->sv_lock protects sv_tempsocks, sv_permsocks, sv_tmpcnt.
5150 * when both need to be taken (rare), svc_serv->sv_lock is first.
5251 * 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
211210 }
212211 EXPORT_SYMBOL_GPL(svc_xprt_init);
213212
214−static 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−
259213 /**
260214 * svc_xprt_received - start next receiver thread
261215 * @xprt: controlling transport
@@ -294,9 +248,8 @@ void svc_add_new_perm_xprt(struct svc_serv *serv, struct svc_xprt *new) · 32 unmodified lines
294248 }
295249
296250 static int _svc_xprt_create(struct svc_serv *serv, const char *xprt_name,
297− struct net *net, const int family,
298− const unsigned short port, int flags,
299− const struct cred *cred)
251+ struct net *net, struct sockaddr *sap,
252+ size_t len, int flags, const struct cred *cred)
300253 {
301254 struct svc_xprt_class *xcl;
302255
@@ -312,8 +265,11 @@ static int _svc_xprt_create(struct svc_serv *serv, const char *xprt_name, · 9 unmodified lines
312265 goto err;
313266
314267 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);
316269 if (IS_ERR(newxprt)) {
270+ trace_svc_xprt_create_err(serv->sv_program->pg_name,
271+ xcl->xcl_name, sap, len,
272+ newxprt);
317273 module_put(xcl->xcl_owner);
318274 return PTR_ERR(newxprt);
319275 }
@@ -329,6 +285,48 @@ static int _svc_xprt_create(struct svc_serv *serv, const char *xprt_name, · 9 unmodified lines
329285 return -EPROTONOSUPPORT;
330286 }
331287
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+ */
299+int 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+}
328+EXPORT_SYMBOL_GPL(svc_xprt_create_from_sa);
329+
332330 /**
333331 * svc_xprt_create - Add a new listener to @serv
334332 * @serv: target RPC service
@@ -339,23 +337,41 @@ static int _svc_xprt_create(struct svc_serv *serv, const char *xprt_name, · 4 unmodified lines
339337 * @flags: SVC_SOCK flags
340338 * @cred: credential to bind to this transport
341339 *
342− * Return values:
343− * %0: New listener added successfully
344− * %-EPROTONOSUPPORT: Requested transport type not supported
340+ * Return local xprt port on success or %-EPROTONOSUPPORT on failure
345341 */
346342 int svc_xprt_create(struct svc_serv *serv, const char *xprt_name,
347343 struct net *net, const int family,
348344 const unsigned short port, int flags,
349345 const struct cred *cred)
350346 {
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;
352360
353− err = _svc_xprt_create(serv, xprt_name, net, family, port, flags, cred);
354− if (err == -EPROTONOSUPPORT) {
355− request_module("svc%s", xprt_name);
356− err = _svc_xprt_create(serv, xprt_name, net, family, port, flags, cred);
361+ switch (family) {
362+ case PF_INET:
363+ sap = (struct sockaddr *)&sin;
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;
357372 }
358− return err;
373+
374+ return svc_xprt_create_from_sa(serv, xprt_name, net, sap, flags, cred);
359375 }
360376 EXPORT_SYMBOL_GPL(svc_xprt_create);
361377
@@ -1259,6 +1275,40 @@ static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt) · 897 unmodified lines
12591275 return dr;
12601276 }
12611277
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+ */
1289+struct 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+}
1310+EXPORT_SYMBOL_GPL(svc_find_listener);
1311+
12621312 /**
12631313 * svc_find_xprt - find an RPC transport instance
12641314 * @serv: pointer to svc_serv to search