History

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

Pull nfsd updates from Chuck Lever: "The big ticket item for this release is that support for RPC-with-TLS [RFC 9289] has been added to the Linux NFS server. The goal is to provide a simple-to-deploy, low-overhead in-transit confidentiality and peer authentication mechanism. It can supplement NFS Kerberos and it can protect the use of legacy non-cryptographic user authentication flavors such as AUTH_SYS. The TLS Record protocol is handled entirely by kTLS, meaning it can use either software encryption or offload encryption to smart NICs. Aside from that, work continues on improving NFSD's open file cache. Among the many clean-ups in that area is a patch to convert the rhashtable to use the list-hashing version of that data structure" * tag 'nfsd-6.4' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux: (31 commits) NFSD: Handle new xprtsec= export option SUNRPC: Support TLS handshake in the server-side TCP socket code NFSD: Clean up xattr memory allocation flags NFSD: Fix problem of COMMIT and NFS4ERR_DELAY in infinite loop SUNRPC: Clear rq_xid when receiving a new RPC Call SUNRPC: Recognize control messages in server-side TCP socket code SUNRPC: Be even lazier about releasing pages SUNRPC: Convert svc_xprt_release() to the release_pages() API SUNRPC: Relocate svc_free_res_pages() nfsd: simplify the delayed disposal list code SUNRPC: Ignore return value of ->xpo_sendto SUNRPC: Ensure server-side sockets have a sock->file NFSD: Watch for rq_pages bounds checking errors in nfsd_splice_actor() sunrpc: simplify two-level sysctl registration for svcrdma_parm_table SUNRPC: return proper error from get_expiry() lockd: add some client-side tracepoints nfs: move nfs_fhandle_hash to common include file lockd: server should unlock lock if client rejects the grant lockd: fix races in client GRANTED_MSG wait logic lockd: move struct nlm_wait to lockd.h ...

Linus Torvalds committed 3 years ago

Commit 4e1c80a2 parents 0127f25 9280c5731 files · +802 −442Browse files

Unified · Split

31 files
  1. fs/lockd/Makefile +4 −2
  2. fs/lockd/clntlock.c +25 −33
  3. fs/lockd/clntproc.c +32 −10
  4. fs/lockd/host.c +1 −0
  5. fs/lockd/svclock.c +17 −4
  6. fs/lockd/trace.c +3 −0
  7. fs/lockd/trace.h +106 −0
  8. fs/nfs/export.c +6 −3
  9. fs/nfs/internal.h +0 −15
  10. fs/nfsd/export.c +54 −10
  11. fs/nfsd/export.h +1 −0
  12. fs/nfsd/filecache.c +185 −245
  13. fs/nfsd/filecache.h +5 −4
  14. fs/nfsd/nfs4idmap.c +4 −4
  15. fs/nfsd/vfs.c +7 −6
  16. include/linux/exportfs.h +1 −0
  17. include/linux/lockd/lockd.h +15 −14
  18. include/linux/nfs.h +20 −0
  19. include/linux/sunrpc/cache.h +8 −7
  20. include/linux/sunrpc/svc.h +3 −13
  21. include/linux/sunrpc/svc_xprt.h +4 −1
  22. include/linux/sunrpc/svcsock.h +3 −1
  23. include/net/tls.h +2 −0
  24. include/trace/events/sunrpc.h +40 −1
  25. include/uapi/linux/nfsd/export.h +13 −0
  26. net/sunrpc/auth_gss/svcauth_gss.c +6 −6
  27. net/sunrpc/svc.c +42 −7
  28. net/sunrpc/svc_xprt.c +16 −17
  29. net/sunrpc/svcauth_unix.c +15 −8
  30. net/sunrpc/svcsock.c +162 −12
  31. net/sunrpc/xprtrdma/svc_rdma.c +2 −19
fs/lockd/Makefile+4−2
@@ -3,10 +3,12 @@ · 2 unmodified lines
33 # Makefile for the linux lock manager stuff
44 #
55
6+ccflags-y += -I$(src) # needed for trace events
7+
68 obj-$(CONFIG_LOCKD) += lockd.o
79
8−lockd-objs-y := clntlock.o clntproc.o clntxdr.o host.o svc.o svclock.o \
9− svcshare.o svcproc.o svcsubs.o mon.o xdr.o
10+lockd-objs-y += clntlock.o clntproc.o clntxdr.o host.o svc.o svclock.o \
11+ svcshare.o svcproc.o svcsubs.o mon.o trace.o xdr.o
1012 lockd-objs-$(CONFIG_LOCKD_V4) += clnt4xdr.o xdr4.o svc4proc.o
1113 lockd-objs-$(CONFIG_PROC_FS) += procfs.o
1214 lockd-objs := $(lockd-objs-y)
fs/lockd/clntlock.c+25−33
@@ -14,9 +14,12 @@ · 13 unmodified lines
1414 #include <linux/nfs_fs.h>
1515 #include <linux/sunrpc/addr.h>
1616 #include <linux/sunrpc/svc.h>
17+#include <linux/sunrpc/svc_xprt.h>
1718 #include <linux/lockd/lockd.h>
1819 #include <linux/kthread.h>
1920
21+#include "trace.h"
22+
2023 #define NLMDBG_FACILITY NLMDBG_CLIENT
2124
2225 /*
@@ -29,18 +32,6 @@ static int reclaimer(void *ptr); · 6 unmodified lines
2932 * client perspective.
3033 */
3134
32−/*
33− * This is the representation of a blocked client lock.
34− */
35−struct nlm_wait {
36− struct list_head b_list; /* linked list */
37− wait_queue_head_t b_wait; /* where to wait on */
38− struct nlm_host * b_host;
39− struct file_lock * b_lock; /* local file lock */
40− unsigned short b_reclaim; /* got to reclaim lock */
41− __be32 b_status; /* grant callback status */
42−};
43−
4435 static LIST_HEAD(nlm_blocked);
4536 static DEFINE_SPINLOCK(nlm_blocked_lock);
4637
@@ -94,41 +85,42 @@ void nlmclnt_done(struct nlm_host *host) · 47 unmodified lines
9485 }
9586 EXPORT_SYMBOL_GPL(nlmclnt_done);
9687
88+void nlmclnt_prepare_block(struct nlm_wait *block, struct nlm_host *host, struct file_lock *fl)
89+{
90+ block->b_host = host;
91+ block->b_lock = fl;
92+ init_waitqueue_head(&block->b_wait);
93+ block->b_status = nlm_lck_blocked;
94+}
95+
9796 /*
9897 * Queue up a lock for blocking so that the GRANTED request can see it
9998 */
100−struct nlm_wait *nlmclnt_prepare_block(struct nlm_host *host, struct file_lock *fl)
99+void nlmclnt_queue_block(struct nlm_wait *block)
101100 {
102− struct nlm_wait *block;
103−
104− block = kmalloc(sizeof(*block), GFP_KERNEL);
105− if (block != NULL) {
106− block->b_host = host;
107− block->b_lock = fl;
108− init_waitqueue_head(&block->b_wait);
109− block->b_status = nlm_lck_blocked;
110−
111− spin_lock(&nlm_blocked_lock);
112− list_add(&block->b_list, &nlm_blocked);
113− spin_unlock(&nlm_blocked_lock);
114− }
115− return block;
101+ spin_lock(&nlm_blocked_lock);
102+ list_add(&block->b_list, &nlm_blocked);
103+ spin_unlock(&nlm_blocked_lock);
116104 }
117105
118−void nlmclnt_finish_block(struct nlm_wait *block)
106+/*
107+ * Dequeue the block and return its final status
108+ */
109+__be32 nlmclnt_dequeue_block(struct nlm_wait *block)
119110 {
120− if (block == NULL)
121− return;
111+ __be32 status;
112+
122113 spin_lock(&nlm_blocked_lock);
123114 list_del(&block->b_list);
115+ status = block->b_status;
124116 spin_unlock(&nlm_blocked_lock);
125− kfree(block);
117+ return status;
126118 }
127119
128120 /*
129121 * Block on a lock
130122 */
131−int nlmclnt_block(struct nlm_wait *block, struct nlm_rqst *req, long timeout)
123+int nlmclnt_wait(struct nlm_wait *block, struct nlm_rqst *req, long timeout)
132124 {
133125 long ret;
134126
@@ -154,7 +146,6 @@ int nlmclnt_block(struct nlm_wait *block, struct nlm_rqst *req, long timeout) · 19 unmodified lines
154146 /* Reset the lock status after a server reboot so we resend */
155147 if (block->b_status == nlm_lck_denied_grace_period)
156148 block->b_status = nlm_lck_blocked;
157− req->a_res.status = block->b_status;
158149 return 0;
159150 }
160151
@@ -198,6 +189,7 @@ __be32 nlmclnt_grant(const struct sockaddr *addr, const struct nlm_lock *lock) · 37 unmodified lines
198189 res = nlm_granted;
199190 }
200191 spin_unlock(&nlm_blocked_lock);
192+ trace_nlmclnt_grant(lock, addr, svc_addr_len(addr), res);
201193 return res;
202194 }
203195
fs/lockd/clntproc.c+32−10
@@ -20,6 +20,8 @@ · 19 unmodified lines
2020 #include <linux/sunrpc/svc.h>
2121 #include <linux/lockd/lockd.h>
2222
23+#include "trace.h"
24+
2325 #define NLMDBG_FACILITY NLMDBG_CLIENT
2426 #define NLMCLNT_GRACE_WAIT (5*HZ)
2527 #define NLMCLNT_POLL_TIMEOUT (30*HZ)
@@ -451,6 +453,9 @@ nlmclnt_test(struct nlm_rqst *req, struct file_lock *fl) · 425 unmodified lines
451453 status = nlm_stat_to_errno(req->a_res.status);
452454 }
453455 out:
456+ trace_nlmclnt_test(&req->a_args.lock,
457+ (const struct sockaddr *)&req->a_host->h_addr,
458+ req->a_host->h_addrlen, req->a_res.status);
454459 nlmclnt_release_call(req);
455460 return status;
456461 }
@@ -516,9 +521,10 @@ nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl) · 59 unmodified lines
516521 const struct cred *cred = nfs_file_cred(fl->fl_file);
517522 struct nlm_host *host = req->a_host;
518523 struct nlm_res *resp = &req->a_res;
519− struct nlm_wait *block = NULL;
524+ struct nlm_wait block;
520525 unsigned char fl_flags = fl->fl_flags;
521526 unsigned char fl_type;
527+ __be32 b_status;
522528 int status = -ENOLCK;
523529
524530 if (nsm_monitor(host) < 0)
@@ -531,31 +537,41 @@ nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl) · 6 unmodified lines
531537 if (status < 0)
532538 goto out;
533539
534− block = nlmclnt_prepare_block(host, fl);
540+ nlmclnt_prepare_block(&block, host, fl);
535541 again:
536542 /*
537543 * Initialise resp->status to a valid non-zero value,
538544 * since 0 == nlm_lck_granted
539545 */
540546 resp->status = nlm_lck_blocked;
541− for(;;) {
547+
548+ /*
549+ * A GRANTED callback can come at any time -- even before the reply
550+ * to the LOCK request arrives, so we queue the wait before
551+ * requesting the lock.
552+ */
553+ nlmclnt_queue_block(&block);
554+ for (;;) {
542555 /* Reboot protection */
543556 fl->fl_u.nfs_fl.state = host->h_state;
544557 status = nlmclnt_call(cred, req, NLMPROC_LOCK);
545558 if (status < 0)
546559 break;
547560 /* Did a reclaimer thread notify us of a server reboot? */
548− if (resp->status == nlm_lck_denied_grace_period)
561+ if (resp->status == nlm_lck_denied_grace_period)
549562 continue;
550563 if (resp->status != nlm_lck_blocked)
551564 break;
552565 /* Wait on an NLM blocking lock */
553− status = nlmclnt_block(block, req, NLMCLNT_POLL_TIMEOUT);
566+ status = nlmclnt_wait(&block, req, NLMCLNT_POLL_TIMEOUT);
554567 if (status < 0)
555568 break;
556− if (resp->status != nlm_lck_blocked)
569+ if (block.b_status != nlm_lck_blocked)
557570 break;
558571 }
572+ b_status = nlmclnt_dequeue_block(&block);
573+ if (resp->status == nlm_lck_blocked)
574+ resp->status = b_status;
559575
560576 /* if we were interrupted while blocking, then cancel the lock request
561577 * and exit
@@ -564,7 +580,7 @@ again: · 2 unmodified lines
564580 if (!req->a_args.block)
565581 goto out_unlock;
566582 if (nlmclnt_cancel(host, req->a_args.block, fl) == 0)
567− goto out_unblock;
583+ goto out;
568584 }
569585
570586 if (resp->status == nlm_granted) {
@@ -593,16 +609,19 @@ again: · 22 unmodified lines
593609 status = -ENOLCK;
594610 else
595611 status = nlm_stat_to_errno(resp->status);
596−out_unblock:
597− nlmclnt_finish_block(block);
598612 out:
613+ trace_nlmclnt_lock(&req->a_args.lock,
614+ (const struct sockaddr *)&req->a_host->h_addr,
615+ req->a_host->h_addrlen, req->a_res.status);
599616 nlmclnt_release_call(req);
600617 return status;
601618 out_unlock:
602619 /* Fatal error: ensure that we remove the lock altogether */
620+ trace_nlmclnt_lock(&req->a_args.lock,
621+ (const struct sockaddr *)&req->a_host->h_addr,
622+ req->a_host->h_addrlen, req->a_res.status);
603623 dprintk("lockd: lock attempt ended in fatal error.\n"
604624 " Attempting to unlock.\n");
605− nlmclnt_finish_block(block);
606625 fl_type = fl->fl_type;
607626 fl->fl_type = F_UNLCK;
608627 down_read(&host->h_rwsem);
@@ -696,6 +715,9 @@ nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl) · 87 unmodified lines
696715 /* What to do now? I'm out of my depth... */
697716 status = -ENOLCK;
698717 out:
718+ trace_nlmclnt_unlock(&req->a_args.lock,
719+ (const struct sockaddr *)&req->a_host->h_addr,
720+ req->a_host->h_addrlen, req->a_res.status);
699721 nlmclnt_release_call(req);
700722 return status;
701723 }
fs/lockd/host.c+1−0
@@ -629,6 +629,7 @@ nlm_shutdown_hosts_net(struct net *net) · 628 unmodified lines
629629 rpc_shutdown_client(host->h_rpcclnt);
630630 host->h_rpcclnt = NULL;
631631 }
632+ nlmsvc_free_host_resources(host);
632633 }
633634
634635 /* Then, perform a garbage collection pass */
fs/lockd/svclock.c+17−4
@@ -954,19 +954,32 @@ void · 953 unmodified lines
954954 nlmsvc_grant_reply(struct nlm_cookie *cookie, __be32 status)
955955 {
956956 struct nlm_block *block;
957+ struct file_lock *fl;
958+ int error;
957959
958960 dprintk("grant_reply: looking for cookie %x, s=%d \n",
959961 *(unsigned int *)(cookie->data), status);
960962 if (!(block = nlmsvc_find_block(cookie)))
961963 return;
962964
963− if (status == nlm_lck_denied_grace_period) {
965+ switch (status) {
966+ case nlm_lck_denied_grace_period:
964967 /* Try again in a couple of seconds */
965968 nlmsvc_insert_block(block, 10 * HZ);
966− } else {
969+ break;
970+ case nlm_lck_denied:
971+ /* Client doesn't want it, just unlock it */
972+ nlmsvc_unlink_block(block);
973+ fl = &block->b_call->a_args.lock.fl;
974+ fl->fl_type = F_UNLCK;
975+ error = vfs_lock_file(fl->fl_file, F_SETLK, fl, NULL);
976+ if (error)
977+ pr_warn("lockd: unable to unlock lock rejected by client!\n");
978+ break;
979+ default:
967980 /*
968− * Lock is now held by client, or has been rejected.
969− * In both cases, the block should be removed.
981+ * Either it was accepted or the status makes no sense
982+ * just unlink it either way.
970983 */
971984 nlmsvc_unlink_block(block);
972985 }
fs/lockd/trace.c+3−0
@@ -0,0 +1,3 @@
1+// SPDX-License-Identifier: GPL-2.0
2+#define CREATE_TRACE_POINTS
3+#include "trace.h"
fs/lockd/trace.h+106−0
@@ -0,0 +1,106 @@
1+/* SPDX-License-Identifier: GPL-2.0 */
2+#undef TRACE_SYSTEM
3+#define TRACE_SYSTEM lockd
4+
5+#if !defined(_TRACE_LOCKD_H) || defined(TRACE_HEADER_MULTI_READ)
6+#define _TRACE_LOCKD_H
7+
8+#include <linux/tracepoint.h>
9+#include <linux/crc32.h>
10+#include <linux/nfs.h>
11+#include <linux/lockd/lockd.h>
12+
13+#ifdef CONFIG_LOCKD_V4
14+#define NLM_STATUS_LIST \
15+ nlm_status_code(LCK_GRANTED) \
16+ nlm_status_code(LCK_DENIED) \
17+ nlm_status_code(LCK_DENIED_NOLOCKS) \
18+ nlm_status_code(LCK_BLOCKED) \
19+ nlm_status_code(LCK_DENIED_GRACE_PERIOD) \
20+ nlm_status_code(DEADLCK) \
21+ nlm_status_code(ROFS) \
22+ nlm_status_code(STALE_FH) \
23+ nlm_status_code(FBIG) \
24+ nlm_status_code_end(FAILED)
25+#else
26+#define NLM_STATUS_LIST \
27+ nlm_status_code(LCK_GRANTED) \
28+ nlm_status_code(LCK_DENIED) \
29+ nlm_status_code(LCK_DENIED_NOLOCKS) \
30+ nlm_status_code(LCK_BLOCKED) \
31+ nlm_status_code_end(LCK_DENIED_GRACE_PERIOD)
32+#endif
33+
34+#undef nlm_status_code
35+#undef nlm_status_code_end
36+#define nlm_status_code(x) TRACE_DEFINE_ENUM(NLM_##x);
37+#define nlm_status_code_end(x) TRACE_DEFINE_ENUM(NLM_##x);
38+
39+NLM_STATUS_LIST
40+
41+#undef nlm_status_code
42+#undef nlm_status_code_end
43+#define nlm_status_code(x) { NLM_##x, #x },
44+#define nlm_status_code_end(x) { NLM_##x, #x }
45+
46+#define show_nlm_status(x) __print_symbolic(x, NLM_STATUS_LIST)
47+
48+DECLARE_EVENT_CLASS(nlmclnt_lock_event,
49+ TP_PROTO(
50+ const struct nlm_lock *lock,
51+ const struct sockaddr *addr,
52+ unsigned int addrlen,
53+ __be32 status
54+ ),
55+
56+ TP_ARGS(lock, addr, addrlen, status),
57+
58+ TP_STRUCT__entry(
59+ __field(u32, oh)
60+ __field(u32, svid)
61+ __field(u32, fh)
62+ __field(unsigned long, status)
63+ __field(u64, start)
64+ __field(u64, len)
65+ __sockaddr(addr, addrlen)
66+ ),
67+
68+ TP_fast_assign(
69+ __entry->oh = ~crc32_le(0xffffffff, lock->oh.data, lock->oh.len);
70+ __entry->svid = lock->svid;
71+ __entry->fh = nfs_fhandle_hash(&lock->fh);
72+ __entry->start = lock->lock_start;
73+ __entry->len = lock->lock_len;
74+ __entry->status = be32_to_cpu(status);
75+ __assign_sockaddr(addr, addr, addrlen);
76+ ),
77+
78+ TP_printk(
79+ "addr=%pISpc oh=0x%08x svid=0x%08x fh=0x%08x start=%llu len=%llu status=%s",
80+ __get_sockaddr(addr), __entry->oh, __entry->svid,
81+ __entry->fh, __entry->start, __entry->len,
82+ show_nlm_status(__entry->status)
83+ )
84+);
85+
86+#define DEFINE_NLMCLNT_EVENT(name) \
87+ DEFINE_EVENT(nlmclnt_lock_event, name, \
88+ TP_PROTO( \
89+ const struct nlm_lock *lock, \
90+ const struct sockaddr *addr, \
91+ unsigned int addrlen, \
92+ __be32 status \
93+ ), \
94+ TP_ARGS(lock, addr, addrlen, status))
95+
96+DEFINE_NLMCLNT_EVENT(nlmclnt_test);
97+DEFINE_NLMCLNT_EVENT(nlmclnt_lock);
98+DEFINE_NLMCLNT_EVENT(nlmclnt_unlock);
99+DEFINE_NLMCLNT_EVENT(nlmclnt_grant);
100+
101+#endif /* _TRACE_LOCKD_H */
102+
103+#undef TRACE_INCLUDE_PATH
104+#define TRACE_INCLUDE_PATH .
105+#define TRACE_INCLUDE_FILE trace
106+#include <trace/define_trace.h>
fs/nfs/export.c+6−3
@@ -149,7 +149,10 @@ const struct export_operations nfs_export_ops = { · 148 unmodified lines
149149 .encode_fh = nfs_encode_fh,
150150 .fh_to_dentry = nfs_fh_to_dentry,
151151 .get_parent = nfs_get_parent,
152− .flags = EXPORT_OP_NOWCC|EXPORT_OP_NOSUBTREECHK|
153− EXPORT_OP_CLOSE_BEFORE_UNLINK|EXPORT_OP_REMOTE_FS|
154− EXPORT_OP_NOATOMIC_ATTR,
152+ .flags = EXPORT_OP_NOWCC |
153+ EXPORT_OP_NOSUBTREECHK |
154+ EXPORT_OP_CLOSE_BEFORE_UNLINK |
155+ EXPORT_OP_REMOTE_FS |
156+ EXPORT_OP_NOATOMIC_ATTR |
157+ EXPORT_OP_FLUSH_ON_CLOSE,
155158 };
fs/nfs/internal.h+0−15
@@ -855,27 +855,12 @@ u64 nfs_timespec_to_change_attr(const struct timespec64 *ts) · 854 unmodified lines
855855 }
856856
857857 #ifdef CONFIG_CRC32
858−/**
859− * nfs_fhandle_hash - calculate the crc32 hash for the filehandle
860− * @fh - pointer to filehandle
861− *
862− * returns a crc32 hash for the filehandle that is compatible with
863− * the one displayed by "wireshark".
864− */
865−static inline u32 nfs_fhandle_hash(const struct nfs_fh *fh)
866−{
867− return ~crc32_le(0xFFFFFFFF, &fh->data[0], fh->size);
868−}
869858 static inline u32 nfs_stateid_hash(const nfs4_stateid *stateid)
870859 {
871860 return ~crc32_le(0xFFFFFFFF, &stateid->other[0],
872861 NFS4_STATEID_OTHER_SIZE);
873862 }
874863 #else
875−static inline u32 nfs_fhandle_hash(const struct nfs_fh *fh)
876−{
877− return 0;
878−}
879864 static inline u32 nfs_stateid_hash(nfs4_stateid *stateid)
880865 {
881866 return 0;
fs/nfsd/export.c+54−10
@@ -123,11 +123,11 @@ static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen) · 122 unmodified lines
123123
124124 /* OK, we seem to have a valid key */
125125 key.h.flags = 0;
126− key.h.expiry_time = get_expiry(&mesg);
127− if (key.h.expiry_time == 0)
126+ err = get_expiry(&mesg, &key.h.expiry_time);
127+ if (err)
128128 goto out;
129129
130− key.ek_client = dom;
130+ key.ek_client = dom;
131131 key.ek_fsidtype = fsidtype;
132132 memcpy(key.ek_fsid, buf, len);
133133
@@ -439,7 +439,6 @@ static int check_export(struct path *path, int *flags, unsigned char *uuid) · 305 unmodified lines
439439 return -EINVAL;
440440 }
441441 return 0;
442−
443442 }
444443
445444 #ifdef CONFIG_NFSD_V4
@@ -546,6 +545,29 @@ static inline int · 100 unmodified lines
546545 secinfo_parse(char **mesg, char *buf, struct svc_export *exp) { return 0; }
547546 #endif
548547
548+static int xprtsec_parse(char **mesg, char *buf, struct svc_export *exp)
549+{
550+ unsigned int i, mode, listsize;
551+ int err;
552+
553+ err = get_uint(mesg, &listsize);
554+ if (err)
555+ return err;
556+ if (listsize > NFSEXP_XPRTSEC_NUM)
557+ return -EINVAL;
558+
559+ exp->ex_xprtsec_modes = 0;
560+ for (i = 0; i < listsize; i++) {
561+ err = get_uint(mesg, &mode);
562+ if (err)
563+ return err;
564+ if (mode > NFSEXP_XPRTSEC_MTLS)
565+ return -EINVAL;
566+ exp->ex_xprtsec_modes |= mode;
567+ }
568+ return 0;
569+}
570+
549571 static inline int
550572 nfsd_uuid_parse(char **mesg, char *buf, unsigned char **puuid)
551573 {
@@ -608,11 +630,11 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) · 56 unmodified lines
608630 exp.ex_client = dom;
609631 exp.cd = cd;
610632 exp.ex_devid_map = NULL;
633+ exp.ex_xprtsec_modes = NFSEXP_XPRTSEC_ALL;
611634
612635 /* expiry */
613− err = -EINVAL;
614− exp.h.expiry_time = get_expiry(&mesg);
615− if (exp.h.expiry_time == 0)
636+ err = get_expiry(&mesg, &exp.h.expiry_time);
637+ if (err)
616638 goto out3;
617639
618640 /* flags */
@@ -624,7 +646,7 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) · 5 unmodified lines
624646 if (err || an_int < 0)
625647 goto out3;
626648 exp.ex_flags= an_int;
627−
649+
628650 /* anon uid */
629651 err = get_int(&mesg, &an_int);
630652 if (err)
@@ -650,6 +672,8 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) · 19 unmodified lines
650672 err = nfsd_uuid_parse(&mesg, buf, &exp.ex_uuid);
651673 else if (strcmp(buf, "secinfo") == 0)
652674 err = secinfo_parse(&mesg, buf, &exp);
675+ else if (strcmp(buf, "xprtsec") == 0)
676+ err = xprtsec_parse(&mesg, buf, &exp);
653677 else
654678 /* quietly ignore unknown words and anything
655679 * following. Newer user-space can try to set
@@ -663,6 +687,7 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) · 7 unmodified lines
663687 err = check_export(&exp.ex_path, &exp.ex_flags, exp.ex_uuid);
664688 if (err)
665689 goto out4;
690+
666691 /*
667692 * No point caching this if it would immediately expire.
668693 * Also, this protects exportfs's dummy export from the
@@ -824,6 +849,7 @@ static void export_update(struct cache_head *cnew, struct cache_head *citem) · 155 unmodified lines
824849 for (i = 0; i < MAX_SECINFO_LIST; i++) {
825850 new->ex_flavors[i] = item->ex_flavors[i];
826851 }
852+ new->ex_xprtsec_modes = item->ex_xprtsec_modes;
827853 }
828854
829855 static struct cache_head *svc_export_alloc(void)
@@ -1035,9 +1061,26 @@ static struct svc_export *exp_find(struct cache_detail *cd, · 205 unmodified lines
10351061
10361062 __be32 check_nfsd_access(struct svc_export *exp, struct svc_rqst *rqstp)
10371063 {
1038− struct exp_flavor_info *f;
1039− struct exp_flavor_info *end = exp->ex_flavors + exp->ex_nflavors;
1064+ struct exp_flavor_info *f, *end = exp->ex_flavors + exp->ex_nflavors;
1065+ struct svc_xprt *xprt = rqstp->rq_xprt;
1066+
1067+ if (exp->ex_xprtsec_modes & NFSEXP_XPRTSEC_NONE) {
1068+ if (!test_bit(XPT_TLS_SESSION, &xprt->xpt_flags))
1069+ goto ok;
1070+ }
1071+ if (exp->ex_xprtsec_modes & NFSEXP_XPRTSEC_TLS) {
1072+ if (test_bit(XPT_TLS_SESSION, &xprt->xpt_flags) &&
1073+ !test_bit(XPT_PEER_AUTH, &xprt->xpt_flags))
1074+ goto ok;
1075+ }
1076+ if (exp->ex_xprtsec_modes & NFSEXP_XPRTSEC_MTLS) {
1077+ if (test_bit(XPT_TLS_SESSION, &xprt->xpt_flags) &&
1078+ test_bit(XPT_PEER_AUTH, &xprt->xpt_flags))
1079+ goto ok;
1080+ }
1081+ goto denied;
10401082
1083+ok:
10411084 /* legacy gss-only clients are always OK: */
10421085 if (exp->ex_client == rqstp->rq_gssclient)
10431086 return 0;
@@ -1062,6 +1105,7 @@ __be32 check_nfsd_access(struct svc_export *exp, struct svc_rqst *rqstp) · 18 unmodified lines
10621105 if (nfsd4_spo_must_allow(rqstp))
10631106 return 0;
10641107
1108+denied:
10651109 return rqstp->rq_vers < 4 ? nfserr_acces : nfserr_wrongsec;
10661110 }
10671111
fs/nfsd/export.h+1−0
@@ -77,6 +77,7 @@ struct svc_export { · 76 unmodified lines
7777 struct cache_detail *cd;
7878 struct rcu_head ex_rcu;
7979 struct export_stats ex_stats;
80+ unsigned long ex_xprtsec_modes;
8081 };
8182
8283 /* an "export key" (expkey) maps a filehandlefragement to an
fs/nfsd/filecache.c+185−245
@@ -74,70 +74,9 @@ static struct list_lru nfsd_file_lru; · 73 unmodified lines
7474 static unsigned long nfsd_file_flags;
7575 static struct fsnotify_group *nfsd_file_fsnotify_group;
7676 static struct delayed_work nfsd_filecache_laundrette;
77−static struct rhashtable nfsd_file_rhash_tbl
77+static struct rhltable nfsd_file_rhltable
7878 ____cacheline_aligned_in_smp;
7979
80−enum nfsd_file_lookup_type {
81− NFSD_FILE_KEY_INODE,
82− NFSD_FILE_KEY_FULL,
83−};
84−
85−struct nfsd_file_lookup_key {
86− struct inode *inode;
87− struct net *net;
88− const struct cred *cred;
89− unsigned char need;
90− bool gc;
91− enum nfsd_file_lookup_type type;
92−};
93−
94−/*
95− * The returned hash value is based solely on the address of an in-code
96− * inode, a pointer to a slab-allocated object. The entropy in such a
97− * pointer is concentrated in its middle bits.
98− */
99−static u32 nfsd_file_inode_hash(const struct inode *inode, u32 seed)
100−{
101− unsigned long ptr = (unsigned long)inode;
102− u32 k;
103−
104− k = ptr >> L1_CACHE_SHIFT;
105− k &= 0x00ffffff;
106− return jhash2(&k, 1, seed);
107−}
108−
109−/**
110− * nfsd_file_key_hashfn - Compute the hash value of a lookup key
111− * @data: key on which to compute the hash value
112− * @len: rhash table's key_len parameter (unused)
113− * @seed: rhash table's random seed of the day
114− *
115− * Return value:
116− * Computed 32-bit hash value
117− */
118−static u32 nfsd_file_key_hashfn(const void *data, u32 len, u32 seed)
119−{
120− const struct nfsd_file_lookup_key *key = data;
121−
122− return nfsd_file_inode_hash(key->inode, seed);
123−}
124−
125−/**
126− * nfsd_file_obj_hashfn - Compute the hash value of an nfsd_file
127− * @data: object on which to compute the hash value
128− * @len: rhash table's key_len parameter (unused)
129− * @seed: rhash table's random seed of the day
130− *
131− * Return value:
132− * Computed 32-bit hash value
133− */
134−static u32 nfsd_file_obj_hashfn(const void *data, u32 len, u32 seed)
135−{
136− const struct nfsd_file *nf = data;
137−
138− return nfsd_file_inode_hash(nf->nf_inode, seed);
139−}
140−
14180 static bool
14281 nfsd_match_cred(const struct cred *c1, const struct cred *c2)
14382 {
@@ -158,53 +97,16 @@ nfsd_match_cred(const struct cred *c1, const struct cred *c2) · 14 unmodified lines
15897 return true;
15998 }
16099
161−/**
162− * nfsd_file_obj_cmpfn - Match a cache item against search criteria
163− * @arg: search criteria
164− * @ptr: cache item to check
165− *
166− * Return values:
167− * %0 - Item matches search criteria
168− * %1 - Item does not match search criteria
169− */
170−static int nfsd_file_obj_cmpfn(struct rhashtable_compare_arg *arg,
171− const void *ptr)
172−{
173− const struct nfsd_file_lookup_key *key = arg->key;
174− const struct nfsd_file *nf = ptr;
175−
176− switch (key->type) {
177− case NFSD_FILE_KEY_INODE:
178− if (nf->nf_inode != key->inode)
179− return 1;
180− break;
181− case NFSD_FILE_KEY_FULL:
182− if (nf->nf_inode != key->inode)
183− return 1;
184− if (nf->nf_may != key->need)
185− return 1;
186− if (nf->nf_net != key->net)
187− return 1;
188− if (!nfsd_match_cred(nf->nf_cred, key->cred))
189− return 1;
190− if (!!test_bit(NFSD_FILE_GC, &nf->nf_flags) != key->gc)
191− return 1;
192− if (test_bit(NFSD_FILE_HASHED, &nf->nf_flags) == 0)
193− return 1;
194− break;
195− }
196− return 0;
197−}
198−
199100 static const struct rhashtable_params nfsd_file_rhash_params = {
200101 .key_len = sizeof_field(struct nfsd_file, nf_inode),
201102 .key_offset = offsetof(struct nfsd_file, nf_inode),
202− .head_offset = offsetof(struct nfsd_file, nf_rhash),
203− .hashfn = nfsd_file_key_hashfn,
204− .obj_hashfn = nfsd_file_obj_hashfn,
205− .obj_cmpfn = nfsd_file_obj_cmpfn,
206− /* Reduce resizing churn on light workloads */
207− .min_size = 512, /* buckets */
103+ .head_offset = offsetof(struct nfsd_file, nf_rlist),
104+
105+ /*
106+ * Start with a single page hash table to reduce resizing churn
107+ * on light workloads.
108+ */
109+ .min_size = 256,
208110 .automatic_shrinking = true,
209111 };
210112
@@ -307,27 +209,27 @@ nfsd_file_mark_find_or_create(struct nfsd_file *nf, struct inode *inode) · 96 unmodified lines
307209 }
308210
309211 static struct nfsd_file *
310−nfsd_file_alloc(struct nfsd_file_lookup_key *key, unsigned int may)
212+nfsd_file_alloc(struct net *net, struct inode *inode, unsigned char need,
213+ bool want_gc)
311214 {
312215 struct nfsd_file *nf;
313216
314217 nf = kmem_cache_alloc(nfsd_file_slab, GFP_KERNEL);
315− if (nf) {
316− INIT_LIST_HEAD(&nf->nf_lru);
317− nf->nf_birthtime = ktime_get();
318− nf->nf_file = NULL;
319− nf->nf_cred = get_current_cred();
320− nf->nf_net = key->net;
321− nf->nf_flags = 0;
322− __set_bit(NFSD_FILE_HASHED, &nf->nf_flags);
323− __set_bit(NFSD_FILE_PENDING, &nf->nf_flags);
324− if (key->gc)
325− __set_bit(NFSD_FILE_GC, &nf->nf_flags);
326− nf->nf_inode = key->inode;
327− refcount_set(&nf->nf_ref, 1);
328− nf->nf_may = key->need;
329− nf->nf_mark = NULL;
330− }
218+ if (unlikely(!nf))
219+ return NULL;
220+
221+ INIT_LIST_HEAD(&nf->nf_lru);
222+ nf->nf_birthtime = ktime_get();
223+ nf->nf_file = NULL;
224+ nf->nf_cred = get_current_cred();
225+ nf->nf_net = net;
226+ nf->nf_flags = want_gc ?
227+ BIT(NFSD_FILE_HASHED) | BIT(NFSD_FILE_PENDING) | BIT(NFSD_FILE_GC) :
228+ BIT(NFSD_FILE_HASHED) | BIT(NFSD_FILE_PENDING);
229+ nf->nf_inode = inode;
230+ refcount_set(&nf->nf_ref, 1);
231+ nf->nf_may = need;
232+ nf->nf_mark = NULL;
331233 return nf;
332234 }
333235
@@ -352,8 +254,8 @@ static void · 18 unmodified lines
352254 nfsd_file_hash_remove(struct nfsd_file *nf)
353255 {
354256 trace_nfsd_file_unhash(nf);
355− rhashtable_remove_fast(&nfsd_file_rhash_tbl, &nf->nf_rhash,
356− nfsd_file_rhash_params);
257+ rhltable_remove(&nfsd_file_rhltable, &nf->nf_rlist,
258+ nfsd_file_rhash_params);
357259 }
358260
359261 static bool
@@ -380,10 +282,8 @@ nfsd_file_free(struct nfsd_file *nf) · 20 unmodified lines
380282 if (nf->nf_mark)
381283 nfsd_file_mark_put(nf->nf_mark);
382284 if (nf->nf_file) {
383− get_file(nf->nf_file);
384− filp_close(nf->nf_file, NULL);
385285 nfsd_file_check_write_error(nf);
386− fput(nf->nf_file);
286+ filp_close(nf->nf_file, NULL);
387287 }
388288
389289 /*
@@ -402,13 +302,23 @@ nfsd_file_check_writeback(struct nfsd_file *nf) · 12 unmodified lines
402302 struct file *file = nf->nf_file;
403303 struct address_space *mapping;
404304
405− if (!file || !(file->f_mode & FMODE_WRITE))
305+ /* File not open for write? */
306+ if (!(file->f_mode & FMODE_WRITE))
307+ return false;
308+
309+ /*
310+ * Some filesystems (e.g. NFS) flush all dirty data on close.
311+ * On others, there is no need to wait for writeback.
312+ */
313+ if (!(file_inode(file)->i_sb->s_export_op->flags & EXPORT_OP_FLUSH_ON_CLOSE))
406314 return false;
315+
407316 mapping = file->f_mapping;
408317 return mapping_tagged(mapping, PAGECACHE_TAG_DIRTY) ||
409318 mapping_tagged(mapping, PAGECACHE_TAG_WRITEBACK);
410319 }
411320
321+
412322 static bool nfsd_file_lru_add(struct nfsd_file *nf)
413323 {
414324 set_bit(NFSD_FILE_REFERENCED, &nf->nf_flags);
@@ -492,49 +402,26 @@ nfsd_file_dispose_list(struct list_head *dispose) · 77 unmodified lines
492402 }
493403 }
494404
495−static void
496−nfsd_file_list_remove_disposal(struct list_head *dst,
497− struct nfsd_fcache_disposal *l)
498−{
499− spin_lock(&l->lock);
500− list_splice_init(&l->freeme, dst);
501− spin_unlock(&l->lock);
502−}
503−
504−static void
505−nfsd_file_list_add_disposal(struct list_head *files, struct net *net)
506−{
507− struct nfsd_net *nn = net_generic(net, nfsd_net_id);
508− struct nfsd_fcache_disposal *l = nn->fcache_disposal;
509−
510− spin_lock(&l->lock);
511− list_splice_tail_init(files, &l->freeme);
512− spin_unlock(&l->lock);
513− queue_work(nfsd_filecache_wq, &l->work);
514−}
515−
516−static void
517−nfsd_file_list_add_pernet(struct list_head *dst, struct list_head *src,
518− struct net *net)
519−{
520− struct nfsd_file *nf, *tmp;
521−
522− list_for_each_entry_safe(nf, tmp, src, nf_lru) {
523− if (nf->nf_net == net)
524− list_move_tail(&nf->nf_lru, dst);
525− }
526−}
527−
405+/**
406+ * nfsd_file_dispose_list_delayed - move list of dead files to net's freeme list
407+ * @dispose: list of nfsd_files to be disposed
408+ *
409+ * Transfers each file to the "freeme" list for its nfsd_net, to eventually
410+ * be disposed of by the per-net garbage collector.
411+ */
528412 static void
529413 nfsd_file_dispose_list_delayed(struct list_head *dispose)
530414 {
531− LIST_HEAD(list);
532− struct nfsd_file *nf;
533−
534415 while(!list_empty(dispose)) {
535− nf = list_first_entry(dispose, struct nfsd_file, nf_lru);
536− nfsd_file_list_add_pernet(&list, dispose, nf->nf_net);
537− nfsd_file_list_add_disposal(&list, nf->nf_net);
416+ struct nfsd_file *nf = list_first_entry(dispose,
417+ struct nfsd_file, nf_lru);
418+ struct nfsd_net *nn = net_generic(nf->nf_net, nfsd_net_id);
419+ struct nfsd_fcache_disposal *l = nn->fcache_disposal;
420+
421+ spin_lock(&l->lock);
422+ list_move_tail(&nf->nf_lru, &l->freeme);
423+ spin_unlock(&l->lock);
424+ queue_work(nfsd_filecache_wq, &l->work);
538425 }
539426 }
540427
@@ -678,8 +565,8 @@ nfsd_file_cond_queue(struct nfsd_file *nf, struct list_head *dispose) · 137 unmodified lines
678565 * @inode: inode on which to close out nfsd_files
679566 * @dispose: list on which to gather nfsd_files to close out
680567 *
681− * An nfsd_file represents a struct file being held open on behalf of nfsd. An
682− * open file however can block other activity (such as leases), or cause
568+ * An nfsd_file represents a struct file being held open on behalf of nfsd.
569+ * An open file however can block other activity (such as leases), or cause
683570 * undesirable behavior (e.g. spurious silly-renames when reexporting NFS).
684571 *
685572 * This function is intended to find open nfsd_files when this sort of
@@ -692,20 +579,17 @@ nfsd_file_cond_queue(struct nfsd_file *nf, struct list_head *dispose) · 6 unmodified lines
692579 static void
693580 nfsd_file_queue_for_close(struct inode *inode, struct list_head *dispose)
694581 {
695− struct nfsd_file_lookup_key key = {
696− .type = NFSD_FILE_KEY_INODE,
697− .inode = inode,
698− };
582+ struct rhlist_head *tmp, *list;
699583 struct nfsd_file *nf;
700584
701585 rcu_read_lock();
702− do {
703− nf = rhashtable_lookup(&nfsd_file_rhash_tbl, &key,
704− nfsd_file_rhash_params);
705− if (!nf)
706− break;
586+ list = rhltable_lookup(&nfsd_file_rhltable, &inode,
587+ nfsd_file_rhash_params);
588+ rhl_for_each_entry_rcu(nf, tmp, list, nf_rlist) {
589+ if (!test_bit(NFSD_FILE_GC, &nf->nf_flags))
590+ continue;
707591 nfsd_file_cond_queue(nf, dispose);
708− } while (1);
592+ }
709593 rcu_read_unlock();
710594 }
711595
@@ -758,8 +642,8 @@ nfsd_file_close_inode_sync(struct inode *inode) · 46 unmodified lines
758642 * nfsd_file_delayed_close - close unused nfsd_files
759643 * @work: dummy
760644 *
761− * Walk the LRU list and destroy any entries that have not been used since
762− * the last scan.
645+ * Scrape the freeme list for this nfsd_net, and then dispose of them
646+ * all.
763647 */
764648 static void
765649 nfsd_file_delayed_close(struct work_struct *work)
@@ -768,7 +652,10 @@ nfsd_file_delayed_close(struct work_struct *work) · 2 unmodified lines
768652 struct nfsd_fcache_disposal *l = container_of(work,
769653 struct nfsd_fcache_disposal, work);
770654
771− nfsd_file_list_remove_disposal(&head, l);
655+ spin_lock(&l->lock);
656+ list_splice_init(&l->freeme, &head);
657+ spin_unlock(&l->lock);
658+
772659 nfsd_file_dispose_list(&head);
773660 }
774661
@@ -829,7 +716,7 @@ nfsd_file_cache_init(void) · 54 unmodified lines
829716 if (test_and_set_bit(NFSD_FILE_CACHE_UP, &nfsd_file_flags) == 1)
830717 return 0;
831718
832− ret = rhashtable_init(&nfsd_file_rhash_tbl, &nfsd_file_rhash_params);
719+ ret = rhltable_init(&nfsd_file_rhltable, &nfsd_file_rhash_params);
833720 if (ret)
834721 return ret;
835722
@@ -897,7 +784,7 @@ out_err: · 61 unmodified lines
897784 nfsd_file_mark_slab = NULL;
898785 destroy_workqueue(nfsd_filecache_wq);
899786 nfsd_filecache_wq = NULL;
900− rhashtable_destroy(&nfsd_file_rhash_tbl);
787+ rhltable_destroy(&nfsd_file_rhltable);
901788 goto out;
902789 }
903790
@@ -906,7 +793,8 @@ out_err: · 2 unmodified lines
906793 * @net: net-namespace to shut down the cache (may be NULL)
907794 *
908795 * Walk the nfsd_file cache and close out any that match @net. If @net is NULL,
909− * then close out everything. Called when an nfsd instance is being shut down.
796+ * then close out everything. Called when an nfsd instance is being shut down,
797+ * and when the exports table is flushed.
910798 */
911799 static void
912800 __nfsd_file_cache_purge(struct net *net)
@@ -915,7 +803,7 @@ __nfsd_file_cache_purge(struct net *net) · 2 unmodified lines
915803 struct nfsd_file *nf;
916804 LIST_HEAD(dispose);
917805
918− rhashtable_walk_enter(&nfsd_file_rhash_tbl, &iter);
806+ rhltable_walk_enter(&nfsd_file_rhltable, &iter);
919807 do {
920808 rhashtable_walk_start(&iter);
921809
@@ -1021,7 +909,7 @@ nfsd_file_cache_shutdown(void) · 99 unmodified lines
1021909 nfsd_file_mark_slab = NULL;
1022910 destroy_workqueue(nfsd_filecache_wq);
1023911 nfsd_filecache_wq = NULL;
1024− rhashtable_destroy(&nfsd_file_rhash_tbl);
912+ rhltable_destroy(&nfsd_file_rhltable);
1025913
1026914 for_each_possible_cpu(i) {
1027915 per_cpu(nfsd_file_cache_hits, i) = 0;
@@ -1032,6 +920,35 @@ nfsd_file_cache_shutdown(void) · 4 unmodified lines
1032920 }
1033921 }
1034922
923+static struct nfsd_file *
924+nfsd_file_lookup_locked(const struct net *net, const struct cred *cred,
925+ struct inode *inode, unsigned char need,
926+ bool want_gc)
927+{
928+ struct rhlist_head *tmp, *list;
929+ struct nfsd_file *nf;
930+
931+ list = rhltable_lookup(&nfsd_file_rhltable, &inode,
932+ nfsd_file_rhash_params);
933+ rhl_for_each_entry_rcu(nf, tmp, list, nf_rlist) {
934+ if (nf->nf_may != need)
935+ continue;
936+ if (nf->nf_net != net)
937+ continue;
938+ if (!nfsd_match_cred(nf->nf_cred, cred))
939+ continue;
940+ if (test_bit(NFSD_FILE_GC, &nf->nf_flags) != want_gc)
941+ continue;
942+ if (test_bit(NFSD_FILE_HASHED, &nf->nf_flags) == 0)
943+ continue;
944+
945+ if (!nfsd_file_get(nf))
946+ continue;
947+ return nf;
948+ }
949+ return NULL;
950+}
951+
1035952 /**
1036953 * nfsd_file_is_cached - are there any cached open files for this inode?
1037954 * @inode: inode to check
@@ -1046,15 +963,20 @@ nfsd_file_cache_shutdown(void) · 8 unmodified lines
1046963 bool
1047964 nfsd_file_is_cached(struct inode *inode)
1048965 {
1049− struct nfsd_file_lookup_key key = {
1050− .type = NFSD_FILE_KEY_INODE,
1051− .inode = inode,
1052− };
966+ struct rhlist_head *tmp, *list;
967+ struct nfsd_file *nf;
1053968 bool ret = false;
1054969
1055− if (rhashtable_lookup_fast(&nfsd_file_rhash_tbl, &key,
1056− nfsd_file_rhash_params) != NULL)
1057− ret = true;
970+ rcu_read_lock();
971+ list = rhltable_lookup(&nfsd_file_rhltable, &inode,
972+ nfsd_file_rhash_params);
973+ rhl_for_each_entry_rcu(nf, tmp, list, nf_rlist)
974+ if (test_bit(NFSD_FILE_GC, &nf->nf_flags)) {
975+ ret = true;
976+ break;
977+ }
978+ rcu_read_unlock();
979+
1058980 trace_nfsd_file_is_cached(inode, (int)ret);
1059981 return ret;
1060982 }
@@ -1064,14 +986,12 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, · 3 unmodified lines
1064986 unsigned int may_flags, struct file *file,
1065987 struct nfsd_file **pnf, bool want_gc)
1066988 {
1067− struct nfsd_file_lookup_key key = {
1068− .type = NFSD_FILE_KEY_FULL,
1069− .need = may_flags & NFSD_FILE_MAY_MASK,
1070− .net = SVC_NET(rqstp),
1071− .gc = want_gc,
1072− };
989+ unsigned char need = may_flags & NFSD_FILE_MAY_MASK;
990+ struct net *net = SVC_NET(rqstp);
991+ struct nfsd_file *new, *nf;
992+ const struct cred *cred;
1073993 bool open_retry = true;
1074− struct nfsd_file *nf;
994+ struct inode *inode;
1075995 __be32 status;
1076996 int ret;
1077997
@@ -1079,80 +999,88 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, · 1 unmodified line
1079999 may_flags|NFSD_MAY_OWNER_OVERRIDE);
10801000 if (status != nfs_ok)
10811001 return status;
1082− key.inode = d_inode(fhp->fh_dentry);
1083− key.cred = get_current_cred();
1002+ inode = d_inode(fhp->fh_dentry);
1003+ cred = get_current_cred();
10841004
10851005 retry:
10861006 rcu_read_lock();
1087− nf = rhashtable_lookup(&nfsd_file_rhash_tbl, &key,
1088− nfsd_file_rhash_params);
1089− nf = nfsd_file_get(nf);
1007+ nf = nfsd_file_lookup_locked(net, cred, inode, need, want_gc);
10901008 rcu_read_unlock();
10911009
10921010 if (nf) {
1011+ /*
1012+ * If the nf is on the LRU then it holds an extra reference
1013+ * that must be put if it's removed. It had better not be
1014+ * the last one however, since we should hold another.
1015+ */
10931016 if (nfsd_file_lru_remove(nf))
10941017 WARN_ON_ONCE(refcount_dec_and_test(&nf->nf_ref));
10951018 goto wait_for_construction;
10961019 }
10971020
1098− nf = nfsd_file_alloc(&key, may_flags);
1099− if (!nf) {
1021+ new = nfsd_file_alloc(net, inode, need, want_gc);
1022+ if (!new) {
11001023 status = nfserr_jukebox;
1101− goto out_status;
1024+ goto out;
11021025 }
11031026
1104− ret = rhashtable_lookup_insert_key(&nfsd_file_rhash_tbl,
1105− &key, &nf->nf_rhash,
1106− nfsd_file_rhash_params);
1027+ rcu_read_lock();
1028+ spin_lock(&inode->i_lock);
1029+ nf = nfsd_file_lookup_locked(net, cred, inode, need, want_gc);
1030+ if (unlikely(nf)) {
1031+ spin_unlock(&inode->i_lock);
1032+ rcu_read_unlock();
1033+ nfsd_file_slab_free(&new->nf_rcu);
1034+ goto wait_for_construction;
1035+ }
1036+ nf = new;
1037+ ret = rhltable_insert(&nfsd_file_rhltable, &nf->nf_rlist,
1038+ nfsd_file_rhash_params);
1039+ spin_unlock(&inode->i_lock);
1040+ rcu_read_unlock();
11071041 if (likely(ret == 0))
11081042 goto open_file;
11091043
1110− nfsd_file_slab_free(&nf->nf_rcu);
1111− nf = NULL;
11121044 if (ret == -EEXIST)
11131045 goto retry;
1114− trace_nfsd_file_insert_err(rqstp, key.inode, may_flags, ret);
1046+ trace_nfsd_file_insert_err(rqstp, inode, may_flags, ret);
11151047 status = nfserr_jukebox;
1116− goto out_status;
1048+ goto construction_err;
11171049
11181050 wait_for_construction:
11191051 wait_on_bit(&nf->nf_flags, NFSD_FILE_PENDING, TASK_UNINTERRUPTIBLE);
11201052
11211053 /* Did construction of this file fail? */
11221054 if (!test_bit(NFSD_FILE_HASHED, &nf->nf_flags)) {
1123− trace_nfsd_file_cons_err(rqstp, key.inode, may_flags, nf);
1055+ trace_nfsd_file_cons_err(rqstp, inode, may_flags, nf);
11241056 if (!open_retry) {
11251057 status = nfserr_jukebox;
1126− goto out;
1058+ goto construction_err;
11271059 }
11281060 open_retry = false;
1129− if (refcount_dec_and_test(&nf->nf_ref))
1130− nfsd_file_free(nf);
11311061 goto retry;
11321062 }
1133−
11341063 this_cpu_inc(nfsd_file_cache_hits);
11351064
11361065 status = nfserrno(nfsd_open_break_lease(file_inode(nf->nf_file), may_flags));
1066+ if (status != nfs_ok) {
1067+ nfsd_file_put(nf);
1068+ nf = NULL;
1069+ }
1070+
11371071 out:
11381072 if (status == nfs_ok) {
11391073 this_cpu_inc(nfsd_file_acquisitions);
11401074 nfsd_file_check_write_error(nf);
11411075 *pnf = nf;
1142− } else {
1143− if (refcount_dec_and_test(&nf->nf_ref))
1144− nfsd_file_free(nf);
1145− nf = NULL;
11461076 }
1147−
1148−out_status:
1149− put_cred(key.cred);
1150− trace_nfsd_file_acquire(rqstp, key.inode, may_flags, nf, status);
1077+ put_cred(cred);
1078+ trace_nfsd_file_acquire(rqstp, inode, may_flags, nf, status);
11511079 return status;
11521080
11531081 open_file:
11541082 trace_nfsd_file_alloc(nf);
1155− nf->nf_mark = nfsd_file_mark_find_or_create(nf, key.inode);
1083+ nf->nf_mark = nfsd_file_mark_find_or_create(nf, inode);
11561084 if (nf->nf_mark) {
11571085 if (file) {
11581086 get_file(file);
@@ -1170,13 +1098,16 @@ open_file: · 11 unmodified lines
11701098 * If construction failed, or we raced with a call to unlink()
11711099 * then unhash.
11721100 */
1173− if (status == nfs_ok && key.inode->i_nlink == 0)
1174− status = nfserr_jukebox;
1175− if (status != nfs_ok)
1101+ if (status != nfs_ok || inode->i_nlink == 0)
11761102 nfsd_file_unhash(nf);
1177− clear_bit_unlock(NFSD_FILE_PENDING, &nf->nf_flags);
1178− smp_mb__after_atomic();
1179− wake_up_bit(&nf->nf_flags, NFSD_FILE_PENDING);
1103+ clear_and_wake_up_bit(NFSD_FILE_PENDING, &nf->nf_flags);
1104+ if (status == nfs_ok)
1105+ goto out;
1106+
1107+construction_err:
1108+ if (refcount_dec_and_test(&nf->nf_ref))
1109+ nfsd_file_free(nf);
1110+ nf = NULL;
11801111 goto out;
11811112 }
11821113
@@ -1192,8 +1123,11 @@ open_file: · 9 unmodified lines
11921123 * seconds after the final nfsd_file_put() in case the caller
11931124 * wants to re-use it.
11941125 *
1195− * Returns nfs_ok and sets @pnf on success; otherwise an nfsstat in
1196− * network byte order is returned.
1126+ * Return values:
1127+ * %nfs_ok - @pnf points to an nfsd_file with its reference
1128+ * count boosted.
1129+ *
1130+ * On error, an nfsstat value in network byte order is returned.
11971131 */
11981132 __be32
11991133 nfsd_file_acquire_gc(struct svc_rqst *rqstp, struct svc_fh *fhp,
@@ -1213,8 +1147,11 @@ nfsd_file_acquire_gc(struct svc_rqst *rqstp, struct svc_fh *fhp, · 13 unmodified lines
12131147 * but not garbage-collected. The object is unhashed after the
12141148 * final nfsd_file_put().
12151149 *
1216− * Returns nfs_ok and sets @pnf on success; otherwise an nfsstat in
1217− * network byte order is returned.
1150+ * Return values:
1151+ * %nfs_ok - @pnf points to an nfsd_file with its reference
1152+ * count boosted.
1153+ *
1154+ * On error, an nfsstat value in network byte order is returned.
12181155 */
12191156 __be32
12201157 nfsd_file_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp,
@@ -1235,8 +1172,11 @@ nfsd_file_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, · 14 unmodified lines
12351172 * and @file is non-NULL, use it to instantiate a new nfsd_file instead of
12361173 * opening a new one.
12371174 *
1238− * Returns nfs_ok and sets @pnf on success; otherwise an nfsstat in
1239− * network byte order is returned.
1175+ * Return values:
1176+ * %nfs_ok - @pnf points to an nfsd_file with its reference
1177+ * count boosted.
1178+ *
1179+ * On error, an nfsstat value in network byte order is returned.
12401180 */
12411181 __be32
12421182 nfsd_file_acquire_opened(struct svc_rqst *rqstp, struct svc_fh *fhp,
@@ -1267,7 +1207,7 @@ int nfsd_file_cache_stats_show(struct seq_file *m, void *v) · 24 unmodified lines
12671207 lru = list_lru_count(&nfsd_file_lru);
12681208
12691209 rcu_read_lock();
1270− ht = &nfsd_file_rhash_tbl;
1210+ ht = &nfsd_file_rhltable.ht;
12711211 count = atomic_read(&ht->nelems);
12721212 tbl = rht_dereference_rcu(ht->tbl, ht);
12731213 buckets = tbl->size;
@@ -1283,7 +1223,7 @@ int nfsd_file_cache_stats_show(struct seq_file *m, void *v) · 9 unmodified lines
12831223 evictions += per_cpu(nfsd_file_evictions, i);
12841224 }
12851225
1286− seq_printf(m, "total entries: %u\n", count);
1226+ seq_printf(m, "total inodes: %u\n", count);
12871227 seq_printf(m, "hash buckets: %u\n", buckets);
12881228 seq_printf(m, "lru entries: %lu\n", lru);
12891229 seq_printf(m, "cache hits: %lu\n", hits);
fs/nfsd/filecache.h+5−4
@@ -29,9 +29,8 @@ struct nfsd_file_mark { · 28 unmodified lines
2929 * never be dereferenced, only used for comparison.
3030 */
3131 struct nfsd_file {
32− struct rhash_head nf_rhash;
33− struct list_head nf_lru;
34− struct rcu_head nf_rcu;
32+ struct rhlist_head nf_rlist;
33+ void *nf_inode;
3534 struct file *nf_file;
3635 const struct cred *nf_cred;
3736 struct net *nf_net;
@@ -40,10 +39,12 @@ struct nfsd_file { · 2 unmodified lines
4039 #define NFSD_FILE_REFERENCED (2)
4140 #define NFSD_FILE_GC (3)
4241 unsigned long nf_flags;
43− struct inode *nf_inode; /* don't deref */
4442 refcount_t nf_ref;
4543 unsigned char nf_may;
44+
4645 struct nfsd_file_mark *nf_mark;
46+ struct list_head nf_lru;
47+ struct rcu_head nf_rcu;
4748 ktime_t nf_birthtime;
4849 };
4950
fs/nfsd/nfs4idmap.c+4−4
@@ -240,8 +240,8 @@ idtoname_parse(struct cache_detail *cd, char *buf, int buflen) · 239 unmodified lines
240240 goto out;
241241
242242 /* expiry */
243− ent.h.expiry_time = get_expiry(&buf);
244− if (ent.h.expiry_time == 0)
243+ error = get_expiry(&buf, &ent.h.expiry_time);
244+ if (error)
245245 goto out;
246246
247247 error = -ENOMEM;
@@ -408,8 +408,8 @@ nametoid_parse(struct cache_detail *cd, char *buf, int buflen) · 160 unmodified lines
408408 memcpy(ent.name, buf1, sizeof(ent.name));
409409
410410 /* expiry */
411− ent.h.expiry_time = get_expiry(&buf);
412− if (ent.h.expiry_time == 0)
411+ error = get_expiry(&buf, &ent.h.expiry_time);
412+ if (error)
413413 goto out;
414414
415415 /* ID */
fs/nfsd/vfs.c+7−6
@@ -930,6 +930,9 @@ nfsd_open_verified(struct svc_rqst *rqstp, struct svc_fh *fhp, int may_flags, · 929 unmodified lines
930930 * Grab and keep cached pages associated with a file in the svc_rqst
931931 * so that they can be passed to the network sendmsg/sendpage routines
932932 * directly. They will be released after the sending has completed.
933+ *
934+ * Return values: Number of bytes consumed, or -EIO if there are no
935+ * remaining pages in rqstp->rq_pages.
933936 */
934937 static int
935938 nfsd_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
@@ -948,7 +951,8 @@ nfsd_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf, · 12 unmodified lines
948951 */
949952 if (page == *(rqstp->rq_next_page - 1))
950953 continue;
951− svc_rqst_replace_page(rqstp, page);
954+ if (unlikely(!svc_rqst_replace_page(rqstp, page)))
955+ return -EIO;
952956 }
953957 if (rqstp->rq_res.page_len == 0) // first call
954958 rqstp->rq_res.page_base = offset % PAGE_SIZE;
@@ -2164,7 +2168,7 @@ nfsd_getxattr(struct svc_rqst *rqstp, struct svc_fh *fhp, char *name, · 1209 unmodified lines
21642168 goto out;
21652169 }
21662170
2167− buf = kvmalloc(len, GFP_KERNEL | GFP_NOFS);
2171+ buf = kvmalloc(len, GFP_KERNEL);
21682172 if (buf == NULL) {
21692173 err = nfserr_jukebox;
21702174 goto out;
@@ -2227,10 +2231,7 @@ nfsd_listxattr(struct svc_rqst *rqstp, struct svc_fh *fhp, char **bufp, · 56 unmodified lines
22272231 goto out;
22282232 }
22292233
2230− /*
2231− * We're holding i_rwsem - use GFP_NOFS.
2232− */
2233− buf = kvmalloc(len, GFP_KERNEL | GFP_NOFS);
2234+ buf = kvmalloc(len, GFP_KERNEL);
22342235 if (buf == NULL) {
22352236 err = nfserr_jukebox;
22362237 goto out;
include/linux/exportfs.h+1−0
@@ -220,6 +220,7 @@ struct export_operations { · 219 unmodified lines
220220 #define EXPORT_OP_NOATOMIC_ATTR (0x10) /* Filesystem cannot supply
221221 atomic attribute updates
222222 */
223+#define EXPORT_OP_FLUSH_ON_CLOSE (0x20) /* fs flushes file data on close */
223224 unsigned long flags;
224225 };
225226
include/linux/lockd/lockd.h+15−14
@@ -99,21 +99,11 @@ struct nsm_handle { · 98 unmodified lines
9999 /*
100100 * Rigorous type checking on sockaddr type conversions
101101 */
102−static inline struct sockaddr_in *nlm_addr_in(const struct nlm_host *host)
103−{
104− return (struct sockaddr_in *)&host->h_addr;
105−}
106−
107102 static inline struct sockaddr *nlm_addr(const struct nlm_host *host)
108103 {
109104 return (struct sockaddr *)&host->h_addr;
110105 }
111106
112−static inline struct sockaddr_in *nlm_srcaddr_in(const struct nlm_host *host)
113−{
114− return (struct sockaddr_in *)&host->h_srcaddr;
115−}
116−
117107 static inline struct sockaddr *nlm_srcaddr(const struct nlm_host *host)
118108 {
119109 return (struct sockaddr *)&host->h_srcaddr;
@@ -131,7 +121,16 @@ struct nlm_lockowner { · 11 unmodified lines
131121 uint32_t pid;
132122 };
133123
134−struct nlm_wait;
124+/*
125+ * This is the representation of a blocked client lock.
126+ */
127+struct nlm_wait {
128+ struct list_head b_list; /* linked list */
129+ wait_queue_head_t b_wait; /* where to wait on */
130+ struct nlm_host *b_host;
131+ struct file_lock *b_lock; /* local file lock */
132+ __be32 b_status; /* grant callback status */
133+};
135134
136135 /*
137136 * Memory chunk for NLM client RPC request.
@@ -212,9 +211,11 @@ struct nlm_rqst * nlm_alloc_call(struct nlm_host *host); · 74 unmodified lines
212211 int nlm_async_call(struct nlm_rqst *, u32, const struct rpc_call_ops *);
213212 int nlm_async_reply(struct nlm_rqst *, u32, const struct rpc_call_ops *);
214213 void nlmclnt_release_call(struct nlm_rqst *);
215−struct nlm_wait * nlmclnt_prepare_block(struct nlm_host *host, struct file_lock *fl);
216−void nlmclnt_finish_block(struct nlm_wait *block);
217−int nlmclnt_block(struct nlm_wait *block, struct nlm_rqst *req, long timeout);
214+void nlmclnt_prepare_block(struct nlm_wait *block, struct nlm_host *host,
215+ struct file_lock *fl);
216+void nlmclnt_queue_block(struct nlm_wait *block);
217+__be32 nlmclnt_dequeue_block(struct nlm_wait *block);
218+int nlmclnt_wait(struct nlm_wait *block, struct nlm_rqst *req, long timeout);
218219 __be32 nlmclnt_grant(const struct sockaddr *addr,
219220 const struct nlm_lock *lock);
220221 void nlmclnt_recovery(struct nlm_host *);
include/linux/nfs.h+20−0
@@ -10,6 +10,7 @@ · 9 unmodified lines
1010
1111 #include <linux/sunrpc/msg_prot.h>
1212 #include <linux/string.h>
13+#include <linux/crc32.h>
1314 #include <uapi/linux/nfs.h>
1415
1516 /*
@@ -44,4 +45,23 @@ enum nfs3_stable_how { · 28 unmodified lines
4445 /* used by direct.c to mark verf as invalid */
4546 NFS_INVALID_STABLE_HOW = -1
4647 };
48+
49+#ifdef CONFIG_CRC32
50+/**
51+ * nfs_fhandle_hash - calculate the crc32 hash for the filehandle
52+ * @fh - pointer to filehandle
53+ *
54+ * returns a crc32 hash for the filehandle that is compatible with
55+ * the one displayed by "wireshark".
56+ */
57+static inline u32 nfs_fhandle_hash(const struct nfs_fh *fh)
58+{
59+ return ~crc32_le(0xFFFFFFFF, &fh->data[0], fh->size);
60+}
61+#else /* CONFIG_CRC32 */
62+static inline u32 nfs_fhandle_hash(const struct nfs_fh *fh)
63+{
64+ return 0;
65+}
66+#endif /* CONFIG_CRC32 */
4767 #endif /* _LINUX_NFS_H */
include/linux/sunrpc/cache.h+8−7
@@ -300,17 +300,18 @@ static inline int get_time(char **bpp, time64_t *time) · 299 unmodified lines
300300 return 0;
301301 }
302302
303−static inline time64_t get_expiry(char **bpp)
303+static inline int get_expiry(char **bpp, time64_t *rvp)
304304 {
305− time64_t rv;
305+ int error;
306306 struct timespec64 boot;
307307
308− if (get_time(bpp, &rv))
309− return 0;
310− if (rv < 0)
311− return 0;
308+ error = get_time(bpp, rvp);
309+ if (error)
310+ return error;
311+
312312 getboottime64(&boot);
313− return rv - boot.tv_sec;
313+ (*rvp) -= boot.tv_sec;
314+ return 0;
314315 }
315316
316317 #endif /* _LINUX_SUNRPC_CACHE_H_ */
include/linux/sunrpc/svc.h+3−13
@@ -309,17 +309,6 @@ static inline struct sockaddr *svc_daddr(const struct svc_rqst *rqst) · 308 unmodified lines
309309 return (struct sockaddr *) &rqst->rq_daddr;
310310 }
311311
312−static inline void svc_free_res_pages(struct svc_rqst *rqstp)
313−{
314− while (rqstp->rq_next_page != rqstp->rq_respages) {
315− struct page **pp = --rqstp->rq_next_page;
316− if (*pp) {
317− put_page(*pp);
318− *pp = NULL;
319− }
320− }
321−}
322−
323312 struct svc_deferred_req {
324313 u32 prot; /* protocol (UDP or TCP) */
325314 struct svc_xprt *xprt;
@@ -422,15 +411,16 @@ struct svc_serv *svc_create(struct svc_program *, unsigned int, · 96 unmodified lines
422411 int (*threadfn)(void *data));
423412 struct svc_rqst *svc_rqst_alloc(struct svc_serv *serv,
424413 struct svc_pool *pool, int node);
425−void svc_rqst_replace_page(struct svc_rqst *rqstp,
414+bool svc_rqst_replace_page(struct svc_rqst *rqstp,
426415 struct page *page);
416+void svc_rqst_release_pages(struct svc_rqst *rqstp);
427417 void svc_rqst_free(struct svc_rqst *);
428418 void svc_exit_thread(struct svc_rqst *);
429419 struct svc_serv * svc_create_pooled(struct svc_program *, unsigned int,
430420 int (*threadfn)(void *data));
431421 int svc_set_num_threads(struct svc_serv *, struct svc_pool *, int);
432422 int svc_pool_stats_open(struct svc_serv *serv, struct file *file);
433−int svc_process(struct svc_rqst *);
423+void svc_process(struct svc_rqst *rqstp);
434424 int bc_svc_process(struct svc_serv *, struct rpc_rqst *,
435425 struct svc_rqst *);
436426 int svc_register(const struct svc_serv *, struct net *, const int,
include/linux/sunrpc/svc_xprt.h+4−1
@@ -27,7 +27,7 @@ struct svc_xprt_ops { · 26 unmodified lines
2727 void (*xpo_detach)(struct svc_xprt *);
2828 void (*xpo_free)(struct svc_xprt *);
2929 void (*xpo_kill_temp_xprt)(struct svc_xprt *);
30− void (*xpo_start_tls)(struct svc_xprt *);
30+ void (*xpo_handshake)(struct svc_xprt *xprt);
3131 };
3232
3333 struct svc_xprt_class {
@@ -70,6 +70,9 @@ struct svc_xprt { · 36 unmodified lines
7070 #define XPT_LOCAL 12 /* connection from loopback interface */
7171 #define XPT_KILL_TEMP 13 /* call xpo_kill_temp_xprt before closing */
7272 #define XPT_CONG_CTRL 14 /* has congestion control */
73+#define XPT_HANDSHAKE 15 /* xprt requests a handshake */
74+#define XPT_TLS_SESSION 16 /* transport-layer security established */
75+#define XPT_PEER_AUTH 17 /* peer has been authenticated */
7376
7477 struct svc_serv *xpt_server; /* service for transport */
7578 atomic_t xpt_reserved; /* space on outq that is rsvd */
include/linux/sunrpc/svcsock.h+3−1
@@ -38,6 +38,8 @@ struct svc_sock { · 37 unmodified lines
3838 /* Number of queued send requests */
3939 atomic_t sk_sendqlen;
4040
41+ struct completion sk_handshake_done;
42+
4143 struct page * sk_pages[RPCSVC_MAXPAGES]; /* received data */
4244 };
4345
@@ -56,7 +58,7 @@ static inline u32 svc_sock_final_rec(struct svc_sock *svsk) · 12 unmodified lines
5658 */
5759 void svc_close_net(struct svc_serv *, struct net *);
5860 int svc_recv(struct svc_rqst *, long);
59−int svc_send(struct svc_rqst *);
61+void svc_send(struct svc_rqst *rqstp);
6062 void svc_drop(struct svc_rqst *);
6163 void svc_sock_update_bufs(struct svc_serv *serv);
6264 bool svc_alien_sock(struct net *net, int fd);
include/net/tls.h+2−0
@@ -69,6 +69,8 @@ extern const struct tls_cipher_size_desc tls_cipher_size_desc[]; · 68 unmodified lines
6969
7070 #define TLS_CRYPTO_INFO_READY(info) ((info)->cipher_type)
7171
72+#define TLS_RECORD_TYPE_ALERT 0x15
73+#define TLS_RECORD_TYPE_HANDSHAKE 0x16
7274 #define TLS_RECORD_TYPE_DATA 0x17
7375
7476 #define TLS_AAD_SPACE_SIZE 13
include/trace/events/sunrpc.h+40−1
@@ -1790,6 +1790,31 @@ DEFINE_EVENT(svc_rqst_status, svc_send, · 1789 unmodified lines
17901790 TP_PROTO(const struct svc_rqst *rqst, int status),
17911791 TP_ARGS(rqst, status));
17921792
1793+TRACE_EVENT(svc_replace_page_err,
1794+ TP_PROTO(const struct svc_rqst *rqst),
1795+
1796+ TP_ARGS(rqst),
1797+ TP_STRUCT__entry(
1798+ SVC_RQST_ENDPOINT_FIELDS(rqst)
1799+
1800+ __field(const void *, begin)
1801+ __field(const void *, respages)
1802+ __field(const void *, nextpage)
1803+ ),
1804+
1805+ TP_fast_assign(
1806+ SVC_RQST_ENDPOINT_ASSIGNMENTS(rqst);
1807+
1808+ __entry->begin = rqst->rq_pages;
1809+ __entry->respages = rqst->rq_respages;
1810+ __entry->nextpage = rqst->rq_next_page;
1811+ ),
1812+
1813+ TP_printk(SVC_RQST_ENDPOINT_FORMAT " begin=%p respages=%p nextpage=%p",
1814+ SVC_RQST_ENDPOINT_VARARGS,
1815+ __entry->begin, __entry->respages, __entry->nextpage)
1816+);
1817+
17931818 TRACE_EVENT(svc_stats_latency,
17941819 TP_PROTO(
17951820 const struct svc_rqst *rqst
@@ -1832,7 +1857,10 @@ TRACE_EVENT(svc_stats_latency, · 36 unmodified lines
18321857 { BIT(XPT_CACHE_AUTH), "CACHE_AUTH" }, \
18331858 { BIT(XPT_LOCAL), "LOCAL" }, \
18341859 { BIT(XPT_KILL_TEMP), "KILL_TEMP" }, \
1835− { BIT(XPT_CONG_CTRL), "CONG_CTRL" })
1860+ { BIT(XPT_CONG_CTRL), "CONG_CTRL" }, \
1861+ { BIT(XPT_HANDSHAKE), "HANDSHAKE" }, \
1862+ { BIT(XPT_TLS_SESSION), "TLS_SESSION" }, \
1863+ { BIT(XPT_PEER_AUTH), "PEER_AUTH" })
18361864
18371865 TRACE_EVENT(svc_xprt_create_err,
18381866 TP_PROTO(
@@ -1965,6 +1993,17 @@ DEFINE_SVC_XPRT_EVENT(close); · 126 unmodified lines
19651993 DEFINE_SVC_XPRT_EVENT(detach);
19661994 DEFINE_SVC_XPRT_EVENT(free);
19671995
1996+#define DEFINE_SVC_TLS_EVENT(name) \
1997+ DEFINE_EVENT(svc_xprt_event, svc_tls_##name, \
1998+ TP_PROTO(const struct svc_xprt *xprt), \
1999+ TP_ARGS(xprt))
2000+
2001+DEFINE_SVC_TLS_EVENT(start);
2002+DEFINE_SVC_TLS_EVENT(upcall);
2003+DEFINE_SVC_TLS_EVENT(unavailable);
2004+DEFINE_SVC_TLS_EVENT(not_started);
2005+DEFINE_SVC_TLS_EVENT(timed_out);
2006+
19682007 TRACE_EVENT(svc_xprt_accept,
19692008 TP_PROTO(
19702009 const struct svc_xprt *xprt,
include/uapi/linux/nfsd/export.h+13−0
@@ -62,5 +62,18 @@ · 61 unmodified lines
6262 | NFSEXP_ALLSQUASH \
6363 | NFSEXP_INSECURE_PORT)
6464
65+/*
66+ * Transport layer security policies that are permitted to access
67+ * an export
68+ */
69+#define NFSEXP_XPRTSEC_NONE 0x0001
70+#define NFSEXP_XPRTSEC_TLS 0x0002
71+#define NFSEXP_XPRTSEC_MTLS 0x0004
72+
73+#define NFSEXP_XPRTSEC_NUM (3)
74+
75+#define NFSEXP_XPRTSEC_ALL (NFSEXP_XPRTSEC_NONE | \
76+ NFSEXP_XPRTSEC_TLS | \
77+ NFSEXP_XPRTSEC_MTLS)
6578
6679 #endif /* _UAPINFSD_EXPORT_H */
net/sunrpc/auth_gss/svcauth_gss.c+6−6
@@ -257,11 +257,11 @@ static int rsi_parse(struct cache_detail *cd, · 256 unmodified lines
257257
258258 rsii.h.flags = 0;
259259 /* expiry */
260− expiry = get_expiry(&mesg);
261− status = -EINVAL;
262− if (expiry == 0)
260+ status = get_expiry(&mesg, &expiry);
261+ if (status)
263262 goto out;
264263
264+ status = -EINVAL;
265265 /* major/minor */
266266 len = qword_get(&mesg, buf, mlen);
267267 if (len <= 0)
@@ -483,11 +483,11 @@ static int rsc_parse(struct cache_detail *cd, · 215 unmodified lines
483483
484484 rsci.h.flags = 0;
485485 /* expiry */
486− expiry = get_expiry(&mesg);
487− status = -EINVAL;
488− if (expiry == 0)
486+ status = get_expiry(&mesg, &expiry);
487+ if (status)
489488 goto out;
490489
490+ status = -EINVAL;
491491 rscp = rsc_lookup(cd, &rsci);
492492 if (!rscp)
493493 goto out;
net/sunrpc/svc.c+42−7
@@ -649,6 +649,8 @@ svc_rqst_alloc(struct svc_serv *serv, struct svc_pool *pool, int node) · 648 unmodified lines
649649 if (!rqstp)
650650 return rqstp;
651651
652+ pagevec_init(&rqstp->rq_pvec);
653+
652654 __set_bit(RQ_BUSY, &rqstp->rq_flags);
653655 rqstp->rq_server = serv;
654656 rqstp->rq_pool = pool;
@@ -842,9 +844,21 @@ EXPORT_SYMBOL_GPL(svc_set_num_threads); · 187 unmodified lines
842844 *
843845 * When replacing a page in rq_pages, batch the release of the
844846 * replaced pages to avoid hammering the page allocator.
847+ *
848+ * Return values:
849+ * %true: page replaced
850+ * %false: array bounds checking failed
845851 */
846−void svc_rqst_replace_page(struct svc_rqst *rqstp, struct page *page)
852+bool svc_rqst_replace_page(struct svc_rqst *rqstp, struct page *page)
847853 {
854+ struct page **begin = rqstp->rq_pages;
855+ struct page **end = &rqstp->rq_pages[RPCSVC_MAXPAGES];
856+
857+ if (unlikely(rqstp->rq_next_page < begin || rqstp->rq_next_page > end)) {
858+ trace_svc_replace_page_err(rqstp);
859+ return false;
860+ }
861+
848862 if (*rqstp->rq_next_page) {
849863 if (!pagevec_space(&rqstp->rq_pvec))
850864 __pagevec_release(&rqstp->rq_pvec);
@@ -853,9 +867,28 @@ void svc_rqst_replace_page(struct svc_rqst *rqstp, struct page *page) · 2 unmodified lines
853867
854868 get_page(page);
855869 *(rqstp->rq_next_page++) = page;
870+ return true;
856871 }
857872 EXPORT_SYMBOL_GPL(svc_rqst_replace_page);
858873
874+/**
875+ * svc_rqst_release_pages - Release Reply buffer pages
876+ * @rqstp: RPC transaction context
877+ *
878+ * Release response pages that might still be in flight after
879+ * svc_send, and any spliced filesystem-owned pages.
880+ */
881+void svc_rqst_release_pages(struct svc_rqst *rqstp)
882+{
883+ int i, count = rqstp->rq_next_page - rqstp->rq_respages;
884+
885+ if (count) {
886+ release_pages(rqstp->rq_respages, count);
887+ for (i = 0; i < count; i++)
888+ rqstp->rq_respages[i] = NULL;
889+ }
890+}
891+
859892 /*
860893 * Called from a server thread as it's exiting. Caller must hold the "service
861894 * mutex" for the service.
@@ -863,6 +896,7 @@ EXPORT_SYMBOL_GPL(svc_rqst_replace_page); · 1 unmodified line
863896 void
864897 svc_rqst_free(struct svc_rqst *rqstp)
865898 {
899+ pagevec_release(&rqstp->rq_pvec);
866900 svc_release_buffer(rqstp);
867901 if (rqstp->rq_scratch_page)
868902 put_page(rqstp->rq_scratch_page);
@@ -1431,11 +1465,12 @@ err_system_err: · 562 unmodified lines
14311465 goto sendit;
14321466 }
14331467
1434−/*
1435− * Process the RPC request.
1468+/**
1469+ * svc_process - Execute one RPC transaction
1470+ * @rqstp: RPC transaction context
1471+ *
14361472 */
1437−int
1438−svc_process(struct svc_rqst *rqstp)
1473+void svc_process(struct svc_rqst *rqstp)
14391474 {
14401475 struct kvec *resv = &rqstp->rq_res.head[0];
14411476 __be32 *p;
@@ -1471,7 +1506,8 @@ svc_process(struct svc_rqst *rqstp) · 29 unmodified lines
14711506
14721507 if (!svc_process_common(rqstp))
14731508 goto out_drop;
1474− return svc_send(rqstp);
1509+ svc_send(rqstp);
1510+ return;
14751511
14761512 out_baddir:
14771513 svc_printk(rqstp, "bad direction 0x%08x, dropping request\n",
@@ -1479,7 +1515,6 @@ out_baddir: · 1 unmodified line
14791515 rqstp->rq_server->sv_stats->rpcbadfmt++;
14801516 out_drop:
14811517 svc_drop(rqstp);
1482− return 0;
14831518 }
14841519 EXPORT_SYMBOL_GPL(svc_process);
14851520
net/sunrpc/svc_xprt.c+16−17
@@ -427,7 +427,7 @@ static bool svc_xprt_ready(struct svc_xprt *xprt) · 426 unmodified lines
427427
428428 if (xpt_flags & BIT(XPT_BUSY))
429429 return false;
430− if (xpt_flags & (BIT(XPT_CONN) | BIT(XPT_CLOSE)))
430+ if (xpt_flags & (BIT(XPT_CONN) | BIT(XPT_CLOSE) | BIT(XPT_HANDSHAKE)))
431431 return true;
432432 if (xpt_flags & (BIT(XPT_DATA) | BIT(XPT_DEFERRED))) {
433433 if (xprt->xpt_ops->xpo_has_wspace(xprt) &&
@@ -541,8 +541,7 @@ static void svc_xprt_release(struct svc_rqst *rqstp) · 107 unmodified lines
541541 kfree(rqstp->rq_deferred);
542542 rqstp->rq_deferred = NULL;
543543
544− pagevec_release(&rqstp->rq_pvec);
545− svc_free_res_pages(rqstp);
544+ svc_rqst_release_pages(rqstp);
546545 rqstp->rq_res.page_len = 0;
547546 rqstp->rq_res.page_base = 0;
548547
@@ -667,8 +666,6 @@ static int svc_alloc_arg(struct svc_rqst *rqstp) · 118 unmodified lines
667666 struct xdr_buf *arg = &rqstp->rq_arg;
668667 unsigned long pages, filled, ret;
669668
670− pagevec_init(&rqstp->rq_pvec);
671−
672669 pages = (serv->sv_max_mesg + 2 * PAGE_SIZE) >> PAGE_SHIFT;
673670 if (pages > RPCSVC_MAXPAGES) {
674671 pr_warn_once("svc: warning: pages=%lu > RPCSVC_MAXPAGES=%lu\n",
@@ -704,6 +701,8 @@ static int svc_alloc_arg(struct svc_rqst *rqstp) · 29 unmodified lines
704701 arg->page_len = (pages-2)*PAGE_SIZE;
705702 arg->len = (pages-1)*PAGE_SIZE;
706703 arg->tail[0].iov_len = 0;
704+
705+ rqstp->rq_xid = xdr_zero;
707706 return 0;
708707 }
709708
@@ -829,6 +828,9 @@ static int svc_handle_xprt(struct svc_rqst *rqstp, struct svc_xprt *xprt) · 119 unmodified lines
829828 module_put(xprt->xpt_class->xcl_owner);
830829 }
831830 svc_xprt_received(xprt);
831+ } else if (test_bit(XPT_HANDSHAKE, &xprt->xpt_flags)) {
832+ xprt->xpt_ops->xpo_handshake(xprt);
833+ svc_xprt_received(xprt);
832834 } else if (svc_xprt_reserve_slot(rqstp, xprt)) {
833835 /* XPT_DATA|XPT_DEFERRED case: */
834836 dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n",
@@ -909,18 +911,20 @@ void svc_drop(struct svc_rqst *rqstp) · 74 unmodified lines
909911 }
910912 EXPORT_SYMBOL_GPL(svc_drop);
911913
912−/*
913− * Return reply to client.
914+/**
915+ * svc_send - Return reply to client
916+ * @rqstp: RPC transaction context
917+ *
914918 */
915−int svc_send(struct svc_rqst *rqstp)
919+void svc_send(struct svc_rqst *rqstp)
916920 {
917921 struct svc_xprt *xprt;
918− int len = -EFAULT;
919922 struct xdr_buf *xb;
923+ int status;
920924
921925 xprt = rqstp->rq_xprt;
922926 if (!xprt)
923− goto out;
927+ return;
924928
925929 /* calculate over-all length */
926930 xb = &rqstp->rq_res;
@@ -930,15 +934,10 @@ int svc_send(struct svc_rqst *rqstp) · 3 unmodified lines
930934 trace_svc_xdr_sendto(rqstp->rq_xid, xb);
931935 trace_svc_stats_latency(rqstp);
932936
933− len = xprt->xpt_ops->xpo_sendto(rqstp);
937+ status = xprt->xpt_ops->xpo_sendto(rqstp);
934938
935− trace_svc_send(rqstp, len);
939+ trace_svc_send(rqstp, status);
936940 svc_xprt_release(rqstp);
937−
938− if (len == -ECONNREFUSED || len == -ENOTCONN || len == -EAGAIN)
939− len = 0;
940−out:
941− return len;
942941 }
943942
944943 /*
net/sunrpc/svcauth_unix.c+15−8
@@ -17,8 +17,9 @@ · 16 unmodified lines
1717 #include <net/ipv6.h>
1818 #include <linux/kernel.h>
1919 #include <linux/user_namespace.h>
20−#define RPCDBG_FACILITY RPCDBG_AUTH
20+#include <trace/events/sunrpc.h>
2121
22+#define RPCDBG_FACILITY RPCDBG_AUTH
2223
2324 #include "netns.h"
2425
@@ -225,9 +226,9 @@ static int ip_map_parse(struct cache_detail *cd, · 200 unmodified lines
225226 return -EINVAL;
226227 }
227228
228− expiry = get_expiry(&mesg);
229− if (expiry ==0)
230− return -EINVAL;
229+ err = get_expiry(&mesg, &expiry);
230+ if (err)
231+ return err;
231232
232233 /* domainname, or empty for NEGATIVE */
233234 len = qword_get(&mesg, buf, mlen);
@@ -506,9 +507,9 @@ static int unix_gid_parse(struct cache_detail *cd, · 272 unmodified lines
506507 uid = make_kuid(current_user_ns(), id);
507508 ug.uid = uid;
508509
509− expiry = get_expiry(&mesg);
510− if (expiry == 0)
511− return -EINVAL;
510+ err = get_expiry(&mesg, &expiry);
511+ if (err)
512+ return err;
512513
513514 rv = get_int(&mesg, &gids);
514515 if (rv || gids < 0 || gids > 8192)
@@ -832,6 +833,7 @@ svcauth_tls_accept(struct svc_rqst *rqstp) · 317 unmodified lines
832833 {
833834 struct xdr_stream *xdr = &rqstp->rq_arg_stream;
834835 struct svc_cred *cred = &rqstp->rq_cred;
836+ struct svc_xprt *xprt = rqstp->rq_xprt;
835837 u32 flavor, len;
836838 void *body;
837839 __be32 *p;
@@ -865,14 +867,19 @@ svcauth_tls_accept(struct svc_rqst *rqstp) · 27 unmodified lines
865867 if (cred->cr_group_info == NULL)
866868 return SVC_CLOSE;
867869
868− if (rqstp->rq_xprt->xpt_ops->xpo_start_tls) {
870+ if (xprt->xpt_ops->xpo_handshake) {
869871 p = xdr_reserve_space(&rqstp->rq_res_stream, XDR_UNIT * 2 + 8);
870872 if (!p)
871873 return SVC_CLOSE;
874+ trace_svc_tls_start(xprt);
872875 *p++ = rpc_auth_null;
873876 *p++ = cpu_to_be32(8);
874877 memcpy(p, "STARTTLS", 8);
878+
879+ set_bit(XPT_HANDSHAKE, &xprt->xpt_flags);
880+ svc_xprt_enqueue(xprt);
875881 } else {
882+ trace_svc_tls_unavailable(xprt);
876883 if (xdr_stream_encode_opaque_auth(&rqstp->rq_res_stream,
877884 RPC_AUTH_NULL, NULL, 0) < 0)
878885 return SVC_CLOSE;
net/sunrpc/svcsock.c+162−12
@@ -43,9 +43,12 @@ · 42 unmodified lines
4343 #include <net/udp.h>
4444 #include <net/tcp.h>
4545 #include <net/tcp_states.h>
46+#include <net/tls.h>
47+#include <net/handshake.h>
4648 #include <linux/uaccess.h>
4749 #include <linux/highmem.h>
4850 #include <asm/ioctls.h>
51+#include <linux/key.h>
4952
5053 #include <linux/sunrpc/types.h>
5154 #include <linux/sunrpc/clnt.h>
@@ -63,6 +66,12 @@ · 11 unmodified lines
6366
6467 #define RPCDBG_FACILITY RPCDBG_SVCXPRT
6568
69+/* To-do: to avoid tying up an nfsd thread while waiting for a
70+ * handshake request, the request could instead be deferred.
71+ */
72+enum {
73+ SVC_HANDSHAKE_TO = 5U * HZ
74+};
6675
6776 static struct svc_sock *svc_setup_socket(struct svc_serv *, struct socket *,
6877 int flags);
@@ -216,6 +225,49 @@ static int svc_one_sock_name(struct svc_sock *svsk, char *buf, int remaining) · 147 unmodified lines
216225 return len;
217226 }
218227
228+static int
229+svc_tcp_sock_process_cmsg(struct svc_sock *svsk, struct msghdr *msg,
230+ struct cmsghdr *cmsg, int ret)
231+{
232+ if (cmsg->cmsg_level == SOL_TLS &&
233+ cmsg->cmsg_type == TLS_GET_RECORD_TYPE) {
234+ u8 content_type = *((u8 *)CMSG_DATA(cmsg));
235+
236+ switch (content_type) {
237+ case TLS_RECORD_TYPE_DATA:
238+ /* TLS sets EOR at the end of each application data
239+ * record, even though there might be more frames
240+ * waiting to be decrypted.
241+ */
242+ msg->msg_flags &= ~MSG_EOR;
243+ break;
244+ case TLS_RECORD_TYPE_ALERT:
245+ ret = -ENOTCONN;
246+ break;
247+ default:
248+ ret = -EAGAIN;
249+ }
250+ }
251+ return ret;
252+}
253+
254+static int
255+svc_tcp_sock_recv_cmsg(struct svc_sock *svsk, struct msghdr *msg)
256+{
257+ union {
258+ struct cmsghdr cmsg;
259+ u8 buf[CMSG_SPACE(sizeof(u8))];
260+ } u;
261+ int ret;
262+
263+ msg->msg_control = &u;
264+ msg->msg_controllen = sizeof(u);
265+ ret = sock_recvmsg(svsk->sk_sock, msg, MSG_DONTWAIT);
266+ if (unlikely(msg->msg_controllen != sizeof(u)))
267+ ret = svc_tcp_sock_process_cmsg(svsk, msg, &u.cmsg, ret);
268+ return ret;
269+}
270+
219271 #if ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE
220272 static void svc_flush_bvec(const struct bio_vec *bvec, size_t size, size_t seek)
221273 {
@@ -263,7 +315,7 @@ static ssize_t svc_tcp_read_msg(struct svc_rqst *rqstp, size_t buflen, · 41 unmodified lines
263315 iov_iter_advance(&msg.msg_iter, seek);
264316 buflen -= seek;
265317 }
266− len = sock_recvmsg(svsk->sk_sock, &msg, MSG_DONTWAIT);
318+ len = svc_tcp_sock_recv_cmsg(svsk, &msg);
267319 if (len > 0)
268320 svc_flush_bvec(bvec, len, seek);
269321
@@ -315,6 +367,8 @@ static void svc_data_ready(struct sock *sk) · 45 unmodified lines
315367 rmb();
316368 svsk->sk_odata(sk);
317369 trace_svcsock_data_ready(&svsk->sk_xprt, 0);
370+ if (test_bit(XPT_HANDSHAKE, &svsk->sk_xprt.xpt_flags))
371+ return;
318372 if (!test_and_set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags))
319373 svc_xprt_enqueue(&svsk->sk_xprt);
320374 }
@@ -352,6 +406,88 @@ static void svc_tcp_kill_temp_xprt(struct svc_xprt *xprt) · 31 unmodified lines
352406 sock_no_linger(svsk->sk_sock->sk);
353407 }
354408
409+/**
410+ * svc_tcp_handshake_done - Handshake completion handler
411+ * @data: address of xprt to wake
412+ * @status: status of handshake
413+ * @peerid: serial number of key containing the remote peer's identity
414+ *
415+ * If a security policy is specified as an export option, we don't
416+ * have a specific export here to check. So we set a "TLS session
417+ * is present" flag on the xprt and let an upper layer enforce local
418+ * security policy.
419+ */
420+static void svc_tcp_handshake_done(void *data, int status, key_serial_t peerid)
421+{
422+ struct svc_xprt *xprt = data;
423+ struct svc_sock *svsk = container_of(xprt, struct svc_sock, sk_xprt);
424+
425+ if (!status) {
426+ if (peerid != TLS_NO_PEERID)
427+ set_bit(XPT_PEER_AUTH, &xprt->xpt_flags);
428+ set_bit(XPT_TLS_SESSION, &xprt->xpt_flags);
429+ }
430+ clear_bit(XPT_HANDSHAKE, &xprt->xpt_flags);
431+ complete_all(&svsk->sk_handshake_done);
432+}
433+
434+/**
435+ * svc_tcp_handshake - Perform a transport-layer security handshake
436+ * @xprt: connected transport endpoint
437+ *
438+ */
439+static void svc_tcp_handshake(struct svc_xprt *xprt)
440+{
441+ struct svc_sock *svsk = container_of(xprt, struct svc_sock, sk_xprt);
442+ struct sock *sk = svsk->sk_sock->sk;
443+ struct tls_handshake_args args = {
444+ .ta_sock = svsk->sk_sock,
445+ .ta_done = svc_tcp_handshake_done,
446+ .ta_data = xprt,
447+ };
448+ int ret;
449+
450+ trace_svc_tls_upcall(xprt);
451+
452+ clear_bit(XPT_TLS_SESSION, &xprt->xpt_flags);
453+ init_completion(&svsk->sk_handshake_done);
454+
455+ ret = tls_server_hello_x509(&args, GFP_KERNEL);
456+ if (ret) {
457+ trace_svc_tls_not_started(xprt);
458+ goto out_failed;
459+ }
460+
461+ ret = wait_for_completion_interruptible_timeout(&svsk->sk_handshake_done,
462+ SVC_HANDSHAKE_TO);
463+ if (ret <= 0) {
464+ if (tls_handshake_cancel(sk)) {
465+ trace_svc_tls_timed_out(xprt);
466+ goto out_close;
467+ }
468+ }
469+
470+ if (!test_bit(XPT_TLS_SESSION, &xprt->xpt_flags)) {
471+ trace_svc_tls_unavailable(xprt);
472+ goto out_close;
473+ }
474+
475+ /* Mark the transport ready in case the remote sent RPC
476+ * traffic before the kernel received the handshake
477+ * completion downcall.
478+ */
479+ set_bit(XPT_DATA, &xprt->xpt_flags);
480+ svc_xprt_enqueue(xprt);
481+ return;
482+
483+out_close:
484+ set_bit(XPT_CLOSE, &xprt->xpt_flags);
485+out_failed:
486+ clear_bit(XPT_HANDSHAKE, &xprt->xpt_flags);
487+ set_bit(XPT_DATA, &xprt->xpt_flags);
488+ svc_xprt_enqueue(xprt);
489+}
490+
355491 /*
356492 * See net/ipv6/ip_sockglue.c : ip_cmsg_recv_pktinfo
357493 */
@@ -877,7 +1013,7 @@ static ssize_t svc_tcp_read_marker(struct svc_sock *svsk, · 519 unmodified lines
8771013 iov.iov_base = ((char *)&svsk->sk_marker) + svsk->sk_tcplen;
8781014 iov.iov_len = want;
8791015 iov_iter_kvec(&msg.msg_iter, ITER_DEST, &iov, 1, want);
880− len = sock_recvmsg(svsk->sk_sock, &msg, MSG_DONTWAIT);
1016+ len = svc_tcp_sock_recv_cmsg(svsk, &msg);
8811017 if (len < 0)
8821018 return len;
8831019 svsk->sk_tcplen += len;
@@ -1213,6 +1349,7 @@ static const struct svc_xprt_ops svc_tcp_ops = { · 329 unmodified lines
12131349 .xpo_has_wspace = svc_tcp_has_wspace,
12141350 .xpo_accept = svc_tcp_accept,
12151351 .xpo_kill_temp_xprt = svc_tcp_kill_temp_xprt,
1352+ .xpo_handshake = svc_tcp_handshake,
12161353 };
12171354
12181355 static struct svc_xprt_class svc_tcp_class = {
@@ -1293,26 +1430,37 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv, · 74 unmodified lines
12931430 struct socket *sock,
12941431 int flags)
12951432 {
1433+ struct file *filp = NULL;
12961434 struct svc_sock *svsk;
12971435 struct sock *inet;
12981436 int pmap_register = !(flags & SVC_SOCK_ANONYMOUS);
1299− int err = 0;
13001437
13011438 svsk = kzalloc(sizeof(*svsk), GFP_KERNEL);
13021439 if (!svsk)
13031440 return ERR_PTR(-ENOMEM);
13041441
1442+ if (!sock->file) {
1443+ filp = sock_alloc_file(sock, O_NONBLOCK, NULL);
1444+ if (IS_ERR(filp)) {
1445+ kfree(svsk);
1446+ return ERR_CAST(filp);
1447+ }
1448+ }
1449+
13051450 inet = sock->sk;
13061451
1307− /* Register socket with portmapper */
1308− if (pmap_register)
1452+ if (pmap_register) {
1453+ int err;
1454+
13091455 err = svc_register(serv, sock_net(sock->sk), inet->sk_family,
13101456 inet->sk_protocol,
13111457 ntohs(inet_sk(inet)->inet_sport));
1312−
1313− if (err < 0) {
1314− kfree(svsk);
1315− return ERR_PTR(err);
1458+ if (err < 0) {
1459+ if (filp)
1460+ fput(filp);
1461+ kfree(svsk);
1462+ return ERR_PTR(err);
1463+ }
13161464 }
13171465
13181466 svsk->sk_sock = sock;
@@ -1525,10 +1673,12 @@ static void svc_tcp_sock_detach(struct svc_xprt *xprt) · 206 unmodified lines
15251673 static void svc_sock_free(struct svc_xprt *xprt)
15261674 {
15271675 struct svc_sock *svsk = container_of(xprt, struct svc_sock, sk_xprt);
1676+ struct socket *sock = svsk->sk_sock;
15281677
1529− if (svsk->sk_sock->file)
1530− sockfd_put(svsk->sk_sock);
1678+ tls_handshake_cancel(sock->sk);
1679+ if (sock->file)
1680+ sockfd_put(sock);
15311681 else
1532− sock_release(svsk->sk_sock);
1682+ sock_release(sock);
15331683 kfree(svsk);
15341684 }
net/sunrpc/xprtrdma/svc_rdma.c+2−19
@@ -212,24 +212,6 @@ static struct ctl_table svcrdma_parm_table[] = { · 211 unmodified lines
212212 { },
213213 };
214214
215−static struct ctl_table svcrdma_table[] = {
216− {
217− .procname = "svc_rdma",
218− .mode = 0555,
219− .child = svcrdma_parm_table
220− },
221− { },
222−};
223−
224−static struct ctl_table svcrdma_root_table[] = {
225− {
226− .procname = "sunrpc",
227− .mode = 0555,
228− .child = svcrdma_table
229− },
230− { },
231−};
232−
233215 static void svc_rdma_proc_cleanup(void)
234216 {
235217 if (!svcrdma_table_header)
@@ -263,7 +245,8 @@ static int svc_rdma_proc_init(void) · 27 unmodified lines
263245 if (rc)
264246 goto out_err;
265247
266− svcrdma_table_header = register_sysctl_table(svcrdma_root_table);
248+ svcrdma_table_header = register_sysctl("sunrpc/svc_rdma",
249+ svcrdma_parm_table);
267250 return 0;
268251
269252 out_err: