aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-12-10 18:13:13 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-10 18:13:13 -0500
commite20db597b6264de55ea6636fc79b1e4aaa89d129 (patch)
treefa650cb9cfad4b22598ae9867ca92baf57491a9d
parent3a5dc1fafb016560315fe45bb4ef8bde259dd1bc (diff)
parent388f0c776781fe64ce951701bfe712b2182a31f2 (diff)
Merge tag 'nfs-for-3.19-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client updates from Trond Myklebust: "Highlights include: Features: - NFSv4.2 client support for hole punching and preallocation. - Further RPC/RDMA client improvements. - Add more RPC transport debugging tracepoints. - Add RPC debugging tools in debugfs. Bugfixes: - Stable fix for layoutget error handling - Fix a change in COMMIT behaviour resulting from the recent io code updates" * tag 'nfs-for-3.19-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (28 commits) sunrpc: add a debugfs rpc_xprt directory with an info file in it sunrpc: add debugfs file for displaying client rpc_task queue nfs: Add DEALLOCATE support nfs: Add ALLOCATE support NFS: Clean up nfs4_init_callback() NFS: SETCLIENTID XDR buffer sizes are incorrect SUNRPC: serialize iostats updates xprtrdma: Display async errors xprtrdma: Enable pad optimization xprtrdma: Re-write rpcrdma_flush_cqs() xprtrdma: Refactor tasklet scheduling xprtrdma: unmap all FMRs during transport disconnect xprtrdma: Cap req_cqinit xprtrdma: Return an errno from rpcrdma_register_external() nfs: define nfs_inc_fscache_stats and using it as possible nfs: replace nfs_add_stats with nfs_inc_stats when add one NFS: Deletion of unnecessary checks before the function call "nfs_put_client" sunrpc: eliminate RPC_TRACEPOINTS sunrpc: eliminate RPC_DEBUG lockd: eliminate LOCKD_DEBUG ...
-rw-r--r--fs/lockd/svclock.c2
-rw-r--r--fs/nfs/blocklayout/blocklayout.c2
-rw-r--r--fs/nfs/callback_proc.c2
-rw-r--r--fs/nfs/filelayout/filelayoutdev.c3
-rw-r--r--fs/nfs/fscache.c24
-rw-r--r--fs/nfs/inode.c9
-rw-r--r--fs/nfs/iostat.h5
-rw-r--r--fs/nfs/nfs42.h2
-rw-r--r--fs/nfs/nfs42proc.c77
-rw-r--r--fs/nfs/nfs42xdr.c139
-rw-r--r--fs/nfs/nfs4_fs.h1
-rw-r--r--fs/nfs/nfs4client.c46
-rw-r--r--fs/nfs/nfs4file.c31
-rw-r--r--fs/nfs/nfs4proc.c12
-rw-r--r--fs/nfs/nfs4xdr.c12
-rw-r--r--fs/nfs/pagelist.c11
-rw-r--r--fs/nfs/read.c2
-rw-r--r--fs/nfs/write.c19
-rw-r--r--include/linux/lockd/debug.h6
-rw-r--r--include/linux/nfs4.h2
-rw-r--r--include/linux/nfs_fs.h4
-rw-r--r--include/linux/nfs_fs_sb.h2
-rw-r--r--include/linux/nfs_xdr.h14
-rw-r--r--include/linux/sunrpc/auth.h2
-rw-r--r--include/linux/sunrpc/clnt.h4
-rw-r--r--include/linux/sunrpc/debug.h64
-rw-r--r--include/linux/sunrpc/metrics.h3
-rw-r--r--include/linux/sunrpc/sched.h8
-rw-r--r--include/linux/sunrpc/xprt.h3
-rw-r--r--include/linux/sunrpc/xprtsock.h59
-rw-r--r--include/trace/events/sunrpc.h160
-rw-r--r--include/uapi/linux/nfsd/debug.h2
-rw-r--r--net/sunrpc/Kconfig1
-rw-r--r--net/sunrpc/Makefile1
-rw-r--r--net/sunrpc/auth.c4
-rw-r--r--net/sunrpc/auth_generic.c2
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c2
-rw-r--r--net/sunrpc/auth_gss/gss_generic_token.c2
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_crypto.c2
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_keys.c2
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_mech.c2
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_seal.c2
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_seqnum.c2
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_unseal.c2
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_wrap.c2
-rw-r--r--net/sunrpc/auth_gss/gss_mech_switch.c2
-rw-r--r--net/sunrpc/auth_gss/gss_rpc_xdr.h2
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c2
-rw-r--r--net/sunrpc/auth_null.c4
-rw-r--r--net/sunrpc/auth_unix.c2
-rw-r--r--net/sunrpc/backchannel_rqst.c2
-rw-r--r--net/sunrpc/clnt.c16
-rw-r--r--net/sunrpc/debugfs.c292
-rw-r--r--net/sunrpc/rpcb_clnt.c2
-rw-r--r--net/sunrpc/sched.c4
-rw-r--r--net/sunrpc/stats.c21
-rw-r--r--net/sunrpc/sunrpc_syms.c12
-rw-r--r--net/sunrpc/svc.c23
-rw-r--r--net/sunrpc/svc_xprt.c31
-rw-r--r--net/sunrpc/sysctl.c2
-rw-r--r--net/sunrpc/xprt.c19
-rw-r--r--net/sunrpc/xprtrdma/rpc_rdma.c4
-rw-r--r--net/sunrpc/xprtrdma/transport.c12
-rw-r--r--net/sunrpc/xprtrdma/verbs.c122
-rw-r--r--net/sunrpc/xprtrdma/xprt_rdma.h6
-rw-r--r--net/sunrpc/xprtsock.c77
66 files changed, 1171 insertions, 244 deletions
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index 13db95f54176..56598742dde4 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -53,7 +53,7 @@ static const struct rpc_call_ops nlmsvc_grant_ops;
53static LIST_HEAD(nlm_blocked); 53static LIST_HEAD(nlm_blocked);
54static DEFINE_SPINLOCK(nlm_blocked_lock); 54static DEFINE_SPINLOCK(nlm_blocked_lock);
55 55
56#ifdef LOCKD_DEBUG 56#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
57static const char *nlmdbg_cookie2a(const struct nlm_cookie *cookie) 57static const char *nlmdbg_cookie2a(const struct nlm_cookie *cookie)
58{ 58{
59 /* 59 /*
diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c
index 4f46f7a05289..77fec6a55f57 100644
--- a/fs/nfs/blocklayout/blocklayout.c
+++ b/fs/nfs/blocklayout/blocklayout.c
@@ -812,7 +812,7 @@ static u64 pnfs_num_cont_bytes(struct inode *inode, pgoff_t idx)
812 812
813 /* Optimize common case that writes from 0 to end of file */ 813 /* Optimize common case that writes from 0 to end of file */
814 end = DIV_ROUND_UP(i_size_read(inode), PAGE_CACHE_SIZE); 814 end = DIV_ROUND_UP(i_size_read(inode), PAGE_CACHE_SIZE);
815 if (end != NFS_I(inode)->npages) { 815 if (end != inode->i_mapping->nrpages) {
816 rcu_read_lock(); 816 rcu_read_lock();
817 end = page_cache_next_hole(mapping, idx + 1, ULONG_MAX); 817 end = page_cache_next_hole(mapping, idx + 1, ULONG_MAX);
818 rcu_read_unlock(); 818 rcu_read_unlock();
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
index 73466b934090..e36a9d78ea49 100644
--- a/fs/nfs/callback_proc.c
+++ b/fs/nfs/callback_proc.c
@@ -49,7 +49,7 @@ __be32 nfs4_callback_getattr(struct cb_getattrargs *args,
49 goto out_iput; 49 goto out_iput;
50 res->size = i_size_read(inode); 50 res->size = i_size_read(inode);
51 res->change_attr = delegation->change_attr; 51 res->change_attr = delegation->change_attr;
52 if (nfsi->npages != 0) 52 if (nfsi->nrequests != 0)
53 res->change_attr++; 53 res->change_attr++;
54 res->ctime = inode->i_ctime; 54 res->ctime = inode->i_ctime;
55 res->mtime = inode->i_mtime; 55 res->mtime = inode->i_mtime;
diff --git a/fs/nfs/filelayout/filelayoutdev.c b/fs/nfs/filelayout/filelayoutdev.c
index 9bb806a76d99..bfecac781f19 100644
--- a/fs/nfs/filelayout/filelayoutdev.c
+++ b/fs/nfs/filelayout/filelayoutdev.c
@@ -204,8 +204,7 @@ destroy_ds(struct nfs4_pnfs_ds *ds)
204 ifdebug(FACILITY) 204 ifdebug(FACILITY)
205 print_ds(ds); 205 print_ds(ds);
206 206
207 if (ds->ds_clp) 207 nfs_put_client(ds->ds_clp);
208 nfs_put_client(ds->ds_clp);
209 208
210 while (!list_empty(&ds->ds_addrs)) { 209 while (!list_empty(&ds->ds_addrs)) {
211 da = list_first_entry(&ds->ds_addrs, 210 da = list_first_entry(&ds->ds_addrs,
diff --git a/fs/nfs/fscache.c b/fs/nfs/fscache.c
index 3ef01f0ba0bc..d63bea8bbfbb 100644
--- a/fs/nfs/fscache.c
+++ b/fs/nfs/fscache.c
@@ -269,8 +269,8 @@ int nfs_fscache_release_page(struct page *page, gfp_t gfp)
269 if (!fscache_maybe_release_page(cookie, page, gfp)) 269 if (!fscache_maybe_release_page(cookie, page, gfp))
270 return 0; 270 return 0;
271 271
272 nfs_add_fscache_stats(page->mapping->host, 272 nfs_inc_fscache_stats(page->mapping->host,
273 NFSIOS_FSCACHE_PAGES_UNCACHED, 1); 273 NFSIOS_FSCACHE_PAGES_UNCACHED);
274 } 274 }
275 275
276 return 1; 276 return 1;
@@ -293,8 +293,8 @@ void __nfs_fscache_invalidate_page(struct page *page, struct inode *inode)
293 293
294 BUG_ON(!PageLocked(page)); 294 BUG_ON(!PageLocked(page));
295 fscache_uncache_page(cookie, page); 295 fscache_uncache_page(cookie, page);
296 nfs_add_fscache_stats(page->mapping->host, 296 nfs_inc_fscache_stats(page->mapping->host,
297 NFSIOS_FSCACHE_PAGES_UNCACHED, 1); 297 NFSIOS_FSCACHE_PAGES_UNCACHED);
298} 298}
299 299
300/* 300/*
@@ -343,19 +343,19 @@ int __nfs_readpage_from_fscache(struct nfs_open_context *ctx,
343 case 0: /* read BIO submitted (page in fscache) */ 343 case 0: /* read BIO submitted (page in fscache) */
344 dfprintk(FSCACHE, 344 dfprintk(FSCACHE,
345 "NFS: readpage_from_fscache: BIO submitted\n"); 345 "NFS: readpage_from_fscache: BIO submitted\n");
346 nfs_add_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_READ_OK, 1); 346 nfs_inc_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_READ_OK);
347 return ret; 347 return ret;
348 348
349 case -ENOBUFS: /* inode not in cache */ 349 case -ENOBUFS: /* inode not in cache */
350 case -ENODATA: /* page not in cache */ 350 case -ENODATA: /* page not in cache */
351 nfs_add_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_READ_FAIL, 1); 351 nfs_inc_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_READ_FAIL);
352 dfprintk(FSCACHE, 352 dfprintk(FSCACHE,
353 "NFS: readpage_from_fscache %d\n", ret); 353 "NFS: readpage_from_fscache %d\n", ret);
354 return 1; 354 return 1;
355 355
356 default: 356 default:
357 dfprintk(FSCACHE, "NFS: readpage_from_fscache %d\n", ret); 357 dfprintk(FSCACHE, "NFS: readpage_from_fscache %d\n", ret);
358 nfs_add_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_READ_FAIL, 1); 358 nfs_inc_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_READ_FAIL);
359 } 359 }
360 return ret; 360 return ret;
361} 361}
@@ -429,11 +429,11 @@ void __nfs_readpage_to_fscache(struct inode *inode, struct page *page, int sync)
429 429
430 if (ret != 0) { 430 if (ret != 0) {
431 fscache_uncache_page(nfs_i_fscache(inode), page); 431 fscache_uncache_page(nfs_i_fscache(inode), page);
432 nfs_add_fscache_stats(inode, 432 nfs_inc_fscache_stats(inode,
433 NFSIOS_FSCACHE_PAGES_WRITTEN_FAIL, 1); 433 NFSIOS_FSCACHE_PAGES_WRITTEN_FAIL);
434 nfs_add_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_UNCACHED, 1); 434 nfs_inc_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_UNCACHED);
435 } else { 435 } else {
436 nfs_add_fscache_stats(inode, 436 nfs_inc_fscache_stats(inode,
437 NFSIOS_FSCACHE_PAGES_WRITTEN_OK, 1); 437 NFSIOS_FSCACHE_PAGES_WRITTEN_OK);
438 } 438 }
439} 439}
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 00689a8a85e4..4bffe637ea32 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -192,6 +192,7 @@ void nfs_zap_caches(struct inode *inode)
192 nfs_zap_caches_locked(inode); 192 nfs_zap_caches_locked(inode);
193 spin_unlock(&inode->i_lock); 193 spin_unlock(&inode->i_lock);
194} 194}
195EXPORT_SYMBOL_GPL(nfs_zap_caches);
195 196
196void nfs_zap_mapping(struct inode *inode, struct address_space *mapping) 197void nfs_zap_mapping(struct inode *inode, struct address_space *mapping)
197{ 198{
@@ -1149,7 +1150,7 @@ static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr
1149 if ((fattr->valid & NFS_ATTR_FATTR_PRESIZE) 1150 if ((fattr->valid & NFS_ATTR_FATTR_PRESIZE)
1150 && (fattr->valid & NFS_ATTR_FATTR_SIZE) 1151 && (fattr->valid & NFS_ATTR_FATTR_SIZE)
1151 && i_size_read(inode) == nfs_size_to_loff_t(fattr->pre_size) 1152 && i_size_read(inode) == nfs_size_to_loff_t(fattr->pre_size)
1152 && nfsi->npages == 0) { 1153 && nfsi->nrequests == 0) {
1153 i_size_write(inode, nfs_size_to_loff_t(fattr->size)); 1154 i_size_write(inode, nfs_size_to_loff_t(fattr->size));
1154 ret |= NFS_INO_INVALID_ATTR; 1155 ret |= NFS_INO_INVALID_ATTR;
1155 } 1156 }
@@ -1192,7 +1193,7 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
1192 if (fattr->valid & NFS_ATTR_FATTR_SIZE) { 1193 if (fattr->valid & NFS_ATTR_FATTR_SIZE) {
1193 cur_size = i_size_read(inode); 1194 cur_size = i_size_read(inode);
1194 new_isize = nfs_size_to_loff_t(fattr->size); 1195 new_isize = nfs_size_to_loff_t(fattr->size);
1195 if (cur_size != new_isize && nfsi->npages == 0) 1196 if (cur_size != new_isize && nfsi->nrequests == 0)
1196 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE; 1197 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE;
1197 } 1198 }
1198 1199
@@ -1619,7 +1620,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1619 if (new_isize != cur_isize) { 1620 if (new_isize != cur_isize) {
1620 /* Do we perhaps have any outstanding writes, or has 1621 /* Do we perhaps have any outstanding writes, or has
1621 * the file grown beyond our last write? */ 1622 * the file grown beyond our last write? */
1622 if ((nfsi->npages == 0) || new_isize > cur_isize) { 1623 if ((nfsi->nrequests == 0) || new_isize > cur_isize) {
1623 i_size_write(inode, new_isize); 1624 i_size_write(inode, new_isize);
1624 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; 1625 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA;
1625 invalid &= ~NFS_INO_REVAL_PAGECACHE; 1626 invalid &= ~NFS_INO_REVAL_PAGECACHE;
@@ -1784,7 +1785,7 @@ static void init_once(void *foo)
1784 INIT_LIST_HEAD(&nfsi->access_cache_entry_lru); 1785 INIT_LIST_HEAD(&nfsi->access_cache_entry_lru);
1785 INIT_LIST_HEAD(&nfsi->access_cache_inode_lru); 1786 INIT_LIST_HEAD(&nfsi->access_cache_inode_lru);
1786 INIT_LIST_HEAD(&nfsi->commit_info.list); 1787 INIT_LIST_HEAD(&nfsi->commit_info.list);
1787 nfsi->npages = 0; 1788 nfsi->nrequests = 0;
1788 nfsi->commit_info.ncommit = 0; 1789 nfsi->commit_info.ncommit = 0;
1789 atomic_set(&nfsi->commit_info.rpcs_out, 0); 1790 atomic_set(&nfsi->commit_info.rpcs_out, 0);
1790 atomic_set(&nfsi->silly_count, 1); 1791 atomic_set(&nfsi->silly_count, 1);
diff --git a/fs/nfs/iostat.h b/fs/nfs/iostat.h
index c5832487c456..0cb806fbd4c4 100644
--- a/fs/nfs/iostat.h
+++ b/fs/nfs/iostat.h
@@ -55,6 +55,11 @@ static inline void nfs_add_fscache_stats(struct inode *inode,
55{ 55{
56 this_cpu_add(NFS_SERVER(inode)->io_stats->fscache[stat], addend); 56 this_cpu_add(NFS_SERVER(inode)->io_stats->fscache[stat], addend);
57} 57}
58static inline void nfs_inc_fscache_stats(struct inode *inode,
59 enum nfs_stat_fscachecounters stat)
60{
61 this_cpu_inc(NFS_SERVER(inode)->io_stats->fscache[stat]);
62}
58#endif 63#endif
59 64
60static inline struct nfs_iostats __percpu *nfs_alloc_iostats(void) 65static inline struct nfs_iostats __percpu *nfs_alloc_iostats(void)
diff --git a/fs/nfs/nfs42.h b/fs/nfs/nfs42.h
index d10333a197bf..7afb8947dfdf 100644
--- a/fs/nfs/nfs42.h
+++ b/fs/nfs/nfs42.h
@@ -6,6 +6,8 @@
6#define __LINUX_FS_NFS_NFS4_2_H 6#define __LINUX_FS_NFS_NFS4_2_H
7 7
8/* nfs4.2proc.c */ 8/* nfs4.2proc.c */
9int nfs42_proc_allocate(struct file *, loff_t, loff_t);
10int nfs42_proc_deallocate(struct file *, loff_t, loff_t);
9loff_t nfs42_proc_llseek(struct file *, loff_t, int); 11loff_t nfs42_proc_llseek(struct file *, loff_t, int);
10 12
11/* nfs4.2xdr.h */ 13/* nfs4.2xdr.h */
diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c
index 0886f1db5917..cb170722769c 100644
--- a/fs/nfs/nfs42proc.c
+++ b/fs/nfs/nfs42proc.c
@@ -32,6 +32,81 @@ static int nfs42_set_rw_stateid(nfs4_stateid *dst, struct file *file,
32 return ret; 32 return ret;
33} 33}
34 34
35static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
36 loff_t offset, loff_t len)
37{
38 struct inode *inode = file_inode(filep);
39 struct nfs42_falloc_args args = {
40 .falloc_fh = NFS_FH(inode),
41 .falloc_offset = offset,
42 .falloc_length = len,
43 };
44 struct nfs42_falloc_res res;
45 struct nfs_server *server = NFS_SERVER(inode);
46 int status;
47
48 msg->rpc_argp = &args;
49 msg->rpc_resp = &res;
50
51 status = nfs42_set_rw_stateid(&args.falloc_stateid, filep, FMODE_WRITE);
52 if (status)
53 return status;
54
55 return nfs4_call_sync(server->client, server, msg,
56 &args.seq_args, &res.seq_res, 0);
57}
58
59static int nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
60 loff_t offset, loff_t len)
61{
62 struct nfs_server *server = NFS_SERVER(file_inode(filep));
63 struct nfs4_exception exception = { };
64 int err;
65
66 do {
67 err = _nfs42_proc_fallocate(msg, filep, offset, len);
68 if (err == -ENOTSUPP)
69 return -EOPNOTSUPP;
70 err = nfs4_handle_exception(server, err, &exception);
71 } while (exception.retry);
72
73 return err;
74}
75
76int nfs42_proc_allocate(struct file *filep, loff_t offset, loff_t len)
77{
78 struct rpc_message msg = {
79 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_ALLOCATE],
80 };
81 struct inode *inode = file_inode(filep);
82 int err;
83
84 if (!nfs_server_capable(inode, NFS_CAP_ALLOCATE))
85 return -EOPNOTSUPP;
86
87 err = nfs42_proc_fallocate(&msg, filep, offset, len);
88 if (err == -EOPNOTSUPP)
89 NFS_SERVER(inode)->caps &= ~NFS_CAP_ALLOCATE;
90 return err;
91}
92
93int nfs42_proc_deallocate(struct file *filep, loff_t offset, loff_t len)
94{
95 struct rpc_message msg = {
96 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_DEALLOCATE],
97 };
98 struct inode *inode = file_inode(filep);
99 int err;
100
101 if (!nfs_server_capable(inode, NFS_CAP_DEALLOCATE))
102 return -EOPNOTSUPP;
103
104 err = nfs42_proc_fallocate(&msg, filep, offset, len);
105 if (err == -EOPNOTSUPP)
106 NFS_SERVER(inode)->caps &= ~NFS_CAP_DEALLOCATE;
107 return err;
108}
109
35loff_t nfs42_proc_llseek(struct file *filep, loff_t offset, int whence) 110loff_t nfs42_proc_llseek(struct file *filep, loff_t offset, int whence)
36{ 111{
37 struct inode *inode = file_inode(filep); 112 struct inode *inode = file_inode(filep);
@@ -50,7 +125,7 @@ loff_t nfs42_proc_llseek(struct file *filep, loff_t offset, int whence)
50 struct nfs_server *server = NFS_SERVER(inode); 125 struct nfs_server *server = NFS_SERVER(inode);
51 int status; 126 int status;
52 127
53 if (!(server->caps & NFS_CAP_SEEK)) 128 if (!nfs_server_capable(inode, NFS_CAP_SEEK))
54 return -ENOTSUPP; 129 return -ENOTSUPP;
55 130
56 status = nfs42_set_rw_stateid(&args.sa_stateid, filep, FMODE_READ); 131 status = nfs42_set_rw_stateid(&args.sa_stateid, filep, FMODE_READ);
diff --git a/fs/nfs/nfs42xdr.c b/fs/nfs/nfs42xdr.c
index c90469b604b8..038a7e1521fa 100644
--- a/fs/nfs/nfs42xdr.c
+++ b/fs/nfs/nfs42xdr.c
@@ -4,6 +4,15 @@
4#ifndef __LINUX_FS_NFS_NFS4_2XDR_H 4#ifndef __LINUX_FS_NFS_NFS4_2XDR_H
5#define __LINUX_FS_NFS_NFS4_2XDR_H 5#define __LINUX_FS_NFS_NFS4_2XDR_H
6 6
7#define encode_fallocate_maxsz (encode_stateid_maxsz + \
8 2 /* offset */ + \
9 2 /* length */)
10#define encode_allocate_maxsz (op_encode_hdr_maxsz + \
11 encode_fallocate_maxsz)
12#define decode_allocate_maxsz (op_decode_hdr_maxsz)
13#define encode_deallocate_maxsz (op_encode_hdr_maxsz + \
14 encode_fallocate_maxsz)
15#define decode_deallocate_maxsz (op_decode_hdr_maxsz)
7#define encode_seek_maxsz (op_encode_hdr_maxsz + \ 16#define encode_seek_maxsz (op_encode_hdr_maxsz + \
8 encode_stateid_maxsz + \ 17 encode_stateid_maxsz + \
9 2 /* offset */ + \ 18 2 /* offset */ + \
@@ -14,6 +23,18 @@
14 2 /* offset */ + \ 23 2 /* offset */ + \
15 2 /* length */) 24 2 /* length */)
16 25
26#define NFS4_enc_allocate_sz (compound_encode_hdr_maxsz + \
27 encode_putfh_maxsz + \
28 encode_allocate_maxsz)
29#define NFS4_dec_allocate_sz (compound_decode_hdr_maxsz + \
30 decode_putfh_maxsz + \
31 decode_allocate_maxsz)
32#define NFS4_enc_deallocate_sz (compound_encode_hdr_maxsz + \
33 encode_putfh_maxsz + \
34 encode_deallocate_maxsz)
35#define NFS4_dec_deallocate_sz (compound_decode_hdr_maxsz + \
36 decode_putfh_maxsz + \
37 decode_deallocate_maxsz)
17#define NFS4_enc_seek_sz (compound_encode_hdr_maxsz + \ 38#define NFS4_enc_seek_sz (compound_encode_hdr_maxsz + \
18 encode_putfh_maxsz + \ 39 encode_putfh_maxsz + \
19 encode_seek_maxsz) 40 encode_seek_maxsz)
@@ -22,6 +43,30 @@
22 decode_seek_maxsz) 43 decode_seek_maxsz)
23 44
24 45
46static void encode_fallocate(struct xdr_stream *xdr,
47 struct nfs42_falloc_args *args)
48{
49 encode_nfs4_stateid(xdr, &args->falloc_stateid);
50 encode_uint64(xdr, args->falloc_offset);
51 encode_uint64(xdr, args->falloc_length);
52}
53
54static void encode_allocate(struct xdr_stream *xdr,
55 struct nfs42_falloc_args *args,
56 struct compound_hdr *hdr)
57{
58 encode_op_hdr(xdr, OP_ALLOCATE, decode_allocate_maxsz, hdr);
59 encode_fallocate(xdr, args);
60}
61
62static void encode_deallocate(struct xdr_stream *xdr,
63 struct nfs42_falloc_args *args,
64 struct compound_hdr *hdr)
65{
66 encode_op_hdr(xdr, OP_DEALLOCATE, decode_deallocate_maxsz, hdr);
67 encode_fallocate(xdr, args);
68}
69
25static void encode_seek(struct xdr_stream *xdr, 70static void encode_seek(struct xdr_stream *xdr,
26 struct nfs42_seek_args *args, 71 struct nfs42_seek_args *args,
27 struct compound_hdr *hdr) 72 struct compound_hdr *hdr)
@@ -33,6 +78,42 @@ static void encode_seek(struct xdr_stream *xdr,
33} 78}
34 79
35/* 80/*
81 * Encode ALLOCATE request
82 */
83static void nfs4_xdr_enc_allocate(struct rpc_rqst *req,
84 struct xdr_stream *xdr,
85 struct nfs42_falloc_args *args)
86{
87 struct compound_hdr hdr = {
88 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
89 };
90
91 encode_compound_hdr(xdr, req, &hdr);
92 encode_sequence(xdr, &args->seq_args, &hdr);
93 encode_putfh(xdr, args->falloc_fh, &hdr);
94 encode_allocate(xdr, args, &hdr);
95 encode_nops(&hdr);
96}
97
98/*
99 * Encode DEALLOCATE request
100 */
101static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req,
102 struct xdr_stream *xdr,
103 struct nfs42_falloc_args *args)
104{
105 struct compound_hdr hdr = {
106 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
107 };
108
109 encode_compound_hdr(xdr, req, &hdr);
110 encode_sequence(xdr, &args->seq_args, &hdr);
111 encode_putfh(xdr, args->falloc_fh, &hdr);
112 encode_deallocate(xdr, args, &hdr);
113 encode_nops(&hdr);
114}
115
116/*
36 * Encode SEEK request 117 * Encode SEEK request
37 */ 118 */
38static void nfs4_xdr_enc_seek(struct rpc_rqst *req, 119static void nfs4_xdr_enc_seek(struct rpc_rqst *req,
@@ -50,6 +131,16 @@ static void nfs4_xdr_enc_seek(struct rpc_rqst *req,
50 encode_nops(&hdr); 131 encode_nops(&hdr);
51} 132}
52 133
134static int decode_allocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
135{
136 return decode_op_hdr(xdr, OP_ALLOCATE);
137}
138
139static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
140{
141 return decode_op_hdr(xdr, OP_DEALLOCATE);
142}
143
53static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res) 144static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res)
54{ 145{
55 int status; 146 int status;
@@ -73,6 +164,54 @@ out_overflow:
73} 164}
74 165
75/* 166/*
167 * Decode ALLOCATE request
168 */
169static int nfs4_xdr_dec_allocate(struct rpc_rqst *rqstp,
170 struct xdr_stream *xdr,
171 struct nfs42_falloc_res *res)
172{
173 struct compound_hdr hdr;
174 int status;
175
176 status = decode_compound_hdr(xdr, &hdr);
177 if (status)
178 goto out;
179 status = decode_sequence(xdr, &res->seq_res, rqstp);
180 if (status)
181 goto out;
182 status = decode_putfh(xdr);
183 if (status)
184 goto out;
185 status = decode_allocate(xdr, res);
186out:
187 return status;
188}
189
190/*
191 * Decode DEALLOCATE request
192 */
193static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp,
194 struct xdr_stream *xdr,
195 struct nfs42_falloc_res *res)
196{
197 struct compound_hdr hdr;
198 int status;
199
200 status = decode_compound_hdr(xdr, &hdr);
201 if (status)
202 goto out;
203 status = decode_sequence(xdr, &res->seq_res, rqstp);
204 if (status)
205 goto out;
206 status = decode_putfh(xdr);
207 if (status)
208 goto out;
209 status = decode_deallocate(xdr, res);
210out:
211 return status;
212}
213
214/*
76 * Decode SEEK request 215 * Decode SEEK request
77 */ 216 */
78static int nfs4_xdr_dec_seek(struct rpc_rqst *rqstp, 217static int nfs4_xdr_dec_seek(struct rpc_rqst *rqstp,
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index be6cac37ea10..a08178764cf9 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -226,6 +226,7 @@ int nfs4_replace_transport(struct nfs_server *server,
226 const struct nfs4_fs_locations *locations); 226 const struct nfs4_fs_locations *locations);
227 227
228/* nfs4proc.c */ 228/* nfs4proc.c */
229extern int nfs4_handle_exception(struct nfs_server *, int, struct nfs4_exception *);
229extern int nfs4_call_sync(struct rpc_clnt *, struct nfs_server *, 230extern int nfs4_call_sync(struct rpc_clnt *, struct nfs_server *,
230 struct rpc_message *, struct nfs4_sequence_args *, 231 struct rpc_message *, struct nfs4_sequence_args *,
231 struct nfs4_sequence_res *, int); 232 struct nfs4_sequence_res *, int);
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index ffdb28d86cf8..03311259b0c4 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -241,28 +241,25 @@ void nfs4_free_client(struct nfs_client *clp)
241 */ 241 */
242static int nfs4_init_callback(struct nfs_client *clp) 242static int nfs4_init_callback(struct nfs_client *clp)
243{ 243{
244 struct rpc_xprt *xprt;
244 int error; 245 int error;
245 246
246 if (clp->rpc_ops->version == 4) { 247 xprt = rcu_dereference_raw(clp->cl_rpcclient->cl_xprt);
247 struct rpc_xprt *xprt;
248 248
249 xprt = rcu_dereference_raw(clp->cl_rpcclient->cl_xprt); 249 if (nfs4_has_session(clp)) {
250 250 error = xprt_setup_backchannel(xprt, NFS41_BC_MIN_CALLBACKS);
251 if (nfs4_has_session(clp)) { 251 if (error < 0)
252 error = xprt_setup_backchannel(xprt,
253 NFS41_BC_MIN_CALLBACKS);
254 if (error < 0)
255 return error;
256 }
257
258 error = nfs_callback_up(clp->cl_mvops->minor_version, xprt);
259 if (error < 0) {
260 dprintk("%s: failed to start callback. Error = %d\n",
261 __func__, error);
262 return error; 252 return error;
263 }
264 __set_bit(NFS_CS_CALLBACK, &clp->cl_res_state);
265 } 253 }
254
255 error = nfs_callback_up(clp->cl_mvops->minor_version, xprt);
256 if (error < 0) {
257 dprintk("%s: failed to start callback. Error = %d\n",
258 __func__, error);
259 return error;
260 }
261 __set_bit(NFS_CS_CALLBACK, &clp->cl_res_state);
262
266 return 0; 263 return 0;
267} 264}
268 265
@@ -498,8 +495,7 @@ int nfs40_walk_client_list(struct nfs_client *new,
498 atomic_inc(&pos->cl_count); 495 atomic_inc(&pos->cl_count);
499 spin_unlock(&nn->nfs_client_lock); 496 spin_unlock(&nn->nfs_client_lock);
500 497
501 if (prev) 498 nfs_put_client(prev);
502 nfs_put_client(prev);
503 prev = pos; 499 prev = pos;
504 500
505 status = nfs_wait_client_init_complete(pos); 501 status = nfs_wait_client_init_complete(pos);
@@ -517,8 +513,7 @@ int nfs40_walk_client_list(struct nfs_client *new,
517 atomic_inc(&pos->cl_count); 513 atomic_inc(&pos->cl_count);
518 spin_unlock(&nn->nfs_client_lock); 514 spin_unlock(&nn->nfs_client_lock);
519 515
520 if (prev) 516 nfs_put_client(prev);
521 nfs_put_client(prev);
522 prev = pos; 517 prev = pos;
523 518
524 status = nfs4_proc_setclientid_confirm(pos, &clid, cred); 519 status = nfs4_proc_setclientid_confirm(pos, &clid, cred);
@@ -549,8 +544,7 @@ int nfs40_walk_client_list(struct nfs_client *new,
549 544
550 /* No match found. The server lost our clientid */ 545 /* No match found. The server lost our clientid */
551out: 546out:
552 if (prev) 547 nfs_put_client(prev);
553 nfs_put_client(prev);
554 dprintk("NFS: <-- %s status = %d\n", __func__, status); 548 dprintk("NFS: <-- %s status = %d\n", __func__, status);
555 return status; 549 return status;
556} 550}
@@ -641,8 +635,7 @@ int nfs41_walk_client_list(struct nfs_client *new,
641 atomic_inc(&pos->cl_count); 635 atomic_inc(&pos->cl_count);
642 spin_unlock(&nn->nfs_client_lock); 636 spin_unlock(&nn->nfs_client_lock);
643 637
644 if (prev) 638 nfs_put_client(prev);
645 nfs_put_client(prev);
646 prev = pos; 639 prev = pos;
647 640
648 status = nfs_wait_client_init_complete(pos); 641 status = nfs_wait_client_init_complete(pos);
@@ -675,8 +668,7 @@ int nfs41_walk_client_list(struct nfs_client *new,
675 /* No matching nfs_client found. */ 668 /* No matching nfs_client found. */
676 spin_unlock(&nn->nfs_client_lock); 669 spin_unlock(&nn->nfs_client_lock);
677 dprintk("NFS: <-- %s status = %d\n", __func__, status); 670 dprintk("NFS: <-- %s status = %d\n", __func__, status);
678 if (prev) 671 nfs_put_client(prev);
679 nfs_put_client(prev);
680 return status; 672 return status;
681} 673}
682#endif /* CONFIG_NFS_V4_1 */ 674#endif /* CONFIG_NFS_V4_1 */
diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c
index c51fb4db9bfe..8b46389c4c5b 100644
--- a/fs/nfs/nfs4file.c
+++ b/fs/nfs/nfs4file.c
@@ -3,6 +3,8 @@
3 * 3 *
4 * Copyright (C) 1992 Rick Sladkey 4 * Copyright (C) 1992 Rick Sladkey
5 */ 5 */
6#include <linux/fs.h>
7#include <linux/falloc.h>
6#include <linux/nfs_fs.h> 8#include <linux/nfs_fs.h>
7#include "internal.h" 9#include "internal.h"
8#include "fscache.h" 10#include "fscache.h"
@@ -134,6 +136,32 @@ static loff_t nfs4_file_llseek(struct file *filep, loff_t offset, int whence)
134 return nfs_file_llseek(filep, offset, whence); 136 return nfs_file_llseek(filep, offset, whence);
135 } 137 }
136} 138}
139
140static long nfs42_fallocate(struct file *filep, int mode, loff_t offset, loff_t len)
141{
142 struct inode *inode = file_inode(filep);
143 long ret;
144
145 if (!S_ISREG(inode->i_mode))
146 return -EOPNOTSUPP;
147
148 if ((mode != 0) && (mode != (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE)))
149 return -EOPNOTSUPP;
150
151 ret = inode_newsize_ok(inode, offset + len);
152 if (ret < 0)
153 return ret;
154
155 mutex_lock(&inode->i_mutex);
156 if (mode & FALLOC_FL_PUNCH_HOLE)
157 ret = nfs42_proc_deallocate(filep, offset, len);
158 else
159 ret = nfs42_proc_allocate(filep, offset, len);
160 mutex_unlock(&inode->i_mutex);
161
162 nfs_zap_caches(inode);
163 return ret;
164}
137#endif /* CONFIG_NFS_V4_2 */ 165#endif /* CONFIG_NFS_V4_2 */
138 166
139const struct file_operations nfs4_file_operations = { 167const struct file_operations nfs4_file_operations = {
@@ -155,6 +183,9 @@ const struct file_operations nfs4_file_operations = {
155 .flock = nfs_flock, 183 .flock = nfs_flock,
156 .splice_read = nfs_file_splice_read, 184 .splice_read = nfs_file_splice_read,
157 .splice_write = iter_file_splice_write, 185 .splice_write = iter_file_splice_write,
186#ifdef CONFIG_NFS_V4_2
187 .fallocate = nfs42_fallocate,
188#endif /* CONFIG_NFS_V4_2 */
158 .check_flags = nfs_check_flags, 189 .check_flags = nfs_check_flags,
159 .setlease = simple_nosetlease, 190 .setlease = simple_nosetlease,
160}; 191};
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 69dc20a743f9..e7f8d5ff2581 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -158,8 +158,6 @@ static int nfs4_map_errors(int err)
158 return -EACCES; 158 return -EACCES;
159 case -NFS4ERR_MINOR_VERS_MISMATCH: 159 case -NFS4ERR_MINOR_VERS_MISMATCH:
160 return -EPROTONOSUPPORT; 160 return -EPROTONOSUPPORT;
161 case -NFS4ERR_ACCESS:
162 return -EACCES;
163 case -NFS4ERR_FILE_OPEN: 161 case -NFS4ERR_FILE_OPEN:
164 return -EBUSY; 162 return -EBUSY;
165 default: 163 default:
@@ -344,7 +342,7 @@ static int nfs4_delay(struct rpc_clnt *clnt, long *timeout)
344/* This is the error handling routine for processes that are allowed 342/* This is the error handling routine for processes that are allowed
345 * to sleep. 343 * to sleep.
346 */ 344 */
347static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struct nfs4_exception *exception) 345int nfs4_handle_exception(struct nfs_server *server, int errorcode, struct nfs4_exception *exception)
348{ 346{
349 struct nfs_client *clp = server->nfs_client; 347 struct nfs_client *clp = server->nfs_client;
350 struct nfs4_state *state = exception->state; 348 struct nfs4_state *state = exception->state;
@@ -7704,6 +7702,9 @@ nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags)
7704 7702
7705 dprintk("--> %s\n", __func__); 7703 dprintk("--> %s\n", __func__);
7706 7704
7705 /* nfs4_layoutget_release calls pnfs_put_layout_hdr */
7706 pnfs_get_layout_hdr(NFS_I(inode)->layout);
7707
7707 lgp->args.layout.pages = nfs4_alloc_pages(max_pages, gfp_flags); 7708 lgp->args.layout.pages = nfs4_alloc_pages(max_pages, gfp_flags);
7708 if (!lgp->args.layout.pages) { 7709 if (!lgp->args.layout.pages) {
7709 nfs4_layoutget_release(lgp); 7710 nfs4_layoutget_release(lgp);
@@ -7716,9 +7717,6 @@ nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags)
7716 lgp->res.seq_res.sr_slot = NULL; 7717 lgp->res.seq_res.sr_slot = NULL;
7717 nfs4_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0); 7718 nfs4_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0);
7718 7719
7719 /* nfs4_layoutget_release calls pnfs_put_layout_hdr */
7720 pnfs_get_layout_hdr(NFS_I(inode)->layout);
7721
7722 task = rpc_run_task(&task_setup_data); 7720 task = rpc_run_task(&task_setup_data);
7723 if (IS_ERR(task)) 7721 if (IS_ERR(task))
7724 return ERR_CAST(task); 7722 return ERR_CAST(task);
@@ -8426,6 +8424,8 @@ static const struct nfs4_minor_version_ops nfs_v4_2_minor_ops = {
8426 | NFS_CAP_POSIX_LOCK 8424 | NFS_CAP_POSIX_LOCK
8427 | NFS_CAP_STATEID_NFSV41 8425 | NFS_CAP_STATEID_NFSV41
8428 | NFS_CAP_ATOMIC_OPEN_V1 8426 | NFS_CAP_ATOMIC_OPEN_V1
8427 | NFS_CAP_ALLOCATE
8428 | NFS_CAP_DEALLOCATE
8429 | NFS_CAP_SEEK, 8429 | NFS_CAP_SEEK,
8430 .init_client = nfs41_init_client, 8430 .init_client = nfs41_init_client,
8431 .shutdown_client = nfs41_shutdown_client, 8431 .shutdown_client = nfs41_shutdown_client,
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 206c08a60c7f..cb4376b78ed9 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -141,13 +141,15 @@ static int nfs4_stat_to_errno(int);
141 XDR_QUADLEN(NFS4_VERIFIER_SIZE) + \ 141 XDR_QUADLEN(NFS4_VERIFIER_SIZE) + \
142 XDR_QUADLEN(NFS4_SETCLIENTID_NAMELEN) + \ 142 XDR_QUADLEN(NFS4_SETCLIENTID_NAMELEN) + \
143 1 /* sc_prog */ + \ 143 1 /* sc_prog */ + \
144 XDR_QUADLEN(RPCBIND_MAXNETIDLEN) + \ 144 1 + XDR_QUADLEN(RPCBIND_MAXNETIDLEN) + \
145 XDR_QUADLEN(RPCBIND_MAXUADDRLEN) + \ 145 1 + XDR_QUADLEN(RPCBIND_MAXUADDRLEN) + \
146 1) /* sc_cb_ident */ 146 1) /* sc_cb_ident */
147#define decode_setclientid_maxsz \ 147#define decode_setclientid_maxsz \
148 (op_decode_hdr_maxsz + \ 148 (op_decode_hdr_maxsz + \
149 2 + \ 149 2 /* clientid */ + \
150 1024) /* large value for CLID_INUSE */ 150 XDR_QUADLEN(NFS4_VERIFIER_SIZE) + \
151 1 + XDR_QUADLEN(RPCBIND_MAXNETIDLEN) + \
152 1 + XDR_QUADLEN(RPCBIND_MAXUADDRLEN))
151#define encode_setclientid_confirm_maxsz \ 153#define encode_setclientid_confirm_maxsz \
152 (op_encode_hdr_maxsz + \ 154 (op_encode_hdr_maxsz + \
153 3 + (NFS4_VERIFIER_SIZE >> 2)) 155 3 + (NFS4_VERIFIER_SIZE >> 2))
@@ -7394,6 +7396,8 @@ struct rpc_procinfo nfs4_procedures[] = {
7394#endif /* CONFIG_NFS_V4_1 */ 7396#endif /* CONFIG_NFS_V4_1 */
7395#ifdef CONFIG_NFS_V4_2 7397#ifdef CONFIG_NFS_V4_2
7396 PROC(SEEK, enc_seek, dec_seek), 7398 PROC(SEEK, enc_seek, dec_seek),
7399 PROC(ALLOCATE, enc_allocate, dec_allocate),
7400 PROC(DEALLOCATE, enc_deallocate, dec_deallocate),
7397#endif /* CONFIG_NFS_V4_2 */ 7401#endif /* CONFIG_NFS_V4_2 */
7398}; 7402};
7399 7403
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index ed0db61f8543..2b5e769beb16 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -258,6 +258,7 @@ bool nfs_page_group_sync_on_bit(struct nfs_page *req, unsigned int bit)
258static inline void 258static inline void
259nfs_page_group_init(struct nfs_page *req, struct nfs_page *prev) 259nfs_page_group_init(struct nfs_page *req, struct nfs_page *prev)
260{ 260{
261 struct inode *inode;
261 WARN_ON_ONCE(prev == req); 262 WARN_ON_ONCE(prev == req);
262 263
263 if (!prev) { 264 if (!prev) {
@@ -276,12 +277,16 @@ nfs_page_group_init(struct nfs_page *req, struct nfs_page *prev)
276 * nfs_page_group_destroy is called */ 277 * nfs_page_group_destroy is called */
277 kref_get(&req->wb_head->wb_kref); 278 kref_get(&req->wb_head->wb_kref);
278 279
279 /* grab extra ref if head request has extra ref from 280 /* grab extra ref and bump the request count if head request
280 * the write/commit path to handle handoff between write 281 * has extra ref from the write/commit path to handle handoff
281 * and commit lists */ 282 * between write and commit lists. */
282 if (test_bit(PG_INODE_REF, &prev->wb_head->wb_flags)) { 283 if (test_bit(PG_INODE_REF, &prev->wb_head->wb_flags)) {
284 inode = page_file_mapping(req->wb_page)->host;
283 set_bit(PG_INODE_REF, &req->wb_flags); 285 set_bit(PG_INODE_REF, &req->wb_flags);
284 kref_get(&req->wb_kref); 286 kref_get(&req->wb_kref);
287 spin_lock(&inode->i_lock);
288 NFS_I(inode)->nrequests++;
289 spin_unlock(&inode->i_lock);
285 } 290 }
286 } 291 }
287} 292}
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index beff2769c5c5..c91a4799c562 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -269,7 +269,7 @@ int nfs_readpage(struct file *file, struct page *page)
269 dprintk("NFS: nfs_readpage (%p %ld@%lu)\n", 269 dprintk("NFS: nfs_readpage (%p %ld@%lu)\n",
270 page, PAGE_CACHE_SIZE, page_file_index(page)); 270 page, PAGE_CACHE_SIZE, page_file_index(page));
271 nfs_inc_stats(inode, NFSIOS_VFSREADPAGE); 271 nfs_inc_stats(inode, NFSIOS_VFSREADPAGE);
272 nfs_add_stats(inode, NFSIOS_READPAGES, 1); 272 nfs_inc_stats(inode, NFSIOS_READPAGES);
273 273
274 /* 274 /*
275 * Try to flush any pending writes to the file.. 275 * Try to flush any pending writes to the file..
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index f83b02dc9166..af3af685a9e3 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -575,7 +575,7 @@ static int nfs_do_writepage(struct page *page, struct writeback_control *wbc, st
575 int ret; 575 int ret;
576 576
577 nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGE); 577 nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGE);
578 nfs_add_stats(inode, NFSIOS_WRITEPAGES, 1); 578 nfs_inc_stats(inode, NFSIOS_WRITEPAGES);
579 579
580 nfs_pageio_cond_complete(pgio, page_file_index(page)); 580 nfs_pageio_cond_complete(pgio, page_file_index(page));
581 ret = nfs_page_async_flush(pgio, page, wbc->sync_mode == WB_SYNC_NONE); 581 ret = nfs_page_async_flush(pgio, page, wbc->sync_mode == WB_SYNC_NONE);
@@ -670,7 +670,8 @@ static void nfs_inode_add_request(struct inode *inode, struct nfs_page *req)
670 nfs_lock_request(req); 670 nfs_lock_request(req);
671 671
672 spin_lock(&inode->i_lock); 672 spin_lock(&inode->i_lock);
673 if (!nfsi->npages && NFS_PROTO(inode)->have_delegation(inode, FMODE_WRITE)) 673 if (!nfsi->nrequests &&
674 NFS_PROTO(inode)->have_delegation(inode, FMODE_WRITE))
674 inode->i_version++; 675 inode->i_version++;
675 /* 676 /*
676 * Swap-space should not get truncated. Hence no need to plug the race 677 * Swap-space should not get truncated. Hence no need to plug the race
@@ -681,9 +682,11 @@ static void nfs_inode_add_request(struct inode *inode, struct nfs_page *req)
681 SetPagePrivate(req->wb_page); 682 SetPagePrivate(req->wb_page);
682 set_page_private(req->wb_page, (unsigned long)req); 683 set_page_private(req->wb_page, (unsigned long)req);
683 } 684 }
684 nfsi->npages++; 685 nfsi->nrequests++;
685 /* this a head request for a page group - mark it as having an 686 /* this a head request for a page group - mark it as having an
686 * extra reference so sub groups can follow suit */ 687 * extra reference so sub groups can follow suit.
688 * This flag also informs pgio layer when to bump nrequests when
689 * adding subrequests. */
687 WARN_ON(test_and_set_bit(PG_INODE_REF, &req->wb_flags)); 690 WARN_ON(test_and_set_bit(PG_INODE_REF, &req->wb_flags));
688 kref_get(&req->wb_kref); 691 kref_get(&req->wb_kref);
689 spin_unlock(&inode->i_lock); 692 spin_unlock(&inode->i_lock);
@@ -709,7 +712,11 @@ static void nfs_inode_remove_request(struct nfs_page *req)
709 wake_up_page(head->wb_page, PG_private); 712 wake_up_page(head->wb_page, PG_private);
710 clear_bit(PG_MAPPED, &head->wb_flags); 713 clear_bit(PG_MAPPED, &head->wb_flags);
711 } 714 }
712 nfsi->npages--; 715 nfsi->nrequests--;
716 spin_unlock(&inode->i_lock);
717 } else {
718 spin_lock(&inode->i_lock);
719 nfsi->nrequests--;
713 spin_unlock(&inode->i_lock); 720 spin_unlock(&inode->i_lock);
714 } 721 }
715 722
@@ -1735,7 +1742,7 @@ static int nfs_commit_unstable_pages(struct inode *inode, struct writeback_contr
1735 /* Don't commit yet if this is a non-blocking flush and there 1742 /* Don't commit yet if this is a non-blocking flush and there
1736 * are a lot of outstanding writes for this mapping. 1743 * are a lot of outstanding writes for this mapping.
1737 */ 1744 */
1738 if (nfsi->commit_info.ncommit <= (nfsi->npages >> 1)) 1745 if (nfsi->commit_info.ncommit <= (nfsi->nrequests >> 1))
1739 goto out_mark_dirty; 1746 goto out_mark_dirty;
1740 1747
1741 /* don't wait for the COMMIT response */ 1748 /* don't wait for the COMMIT response */
diff --git a/include/linux/lockd/debug.h b/include/linux/lockd/debug.h
index 257d3779f2ab..0ca8109934e4 100644
--- a/include/linux/lockd/debug.h
+++ b/include/linux/lockd/debug.h
@@ -17,12 +17,8 @@
17 * Enable lockd debugging. 17 * Enable lockd debugging.
18 * Requires RPC_DEBUG. 18 * Requires RPC_DEBUG.
19 */ 19 */
20#ifdef RPC_DEBUG
21# define LOCKD_DEBUG 1
22#endif
23
24#undef ifdebug 20#undef ifdebug
25#if defined(RPC_DEBUG) && defined(LOCKD_DEBUG) 21#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
26# define ifdebug(flag) if (unlikely(nlm_debug & NLMDBG_##flag)) 22# define ifdebug(flag) if (unlikely(nlm_debug & NLMDBG_##flag))
27#else 23#else
28# define ifdebug(flag) if (0) 24# define ifdebug(flag) if (0)
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index 356acc2846fd..022b761dbf0a 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -490,6 +490,8 @@ enum {
490 490
491 /* nfs42 */ 491 /* nfs42 */
492 NFSPROC4_CLNT_SEEK, 492 NFSPROC4_CLNT_SEEK,
493 NFSPROC4_CLNT_ALLOCATE,
494 NFSPROC4_CLNT_DEALLOCATE,
493}; 495};
494 496
495/* nfs41 types */ 497/* nfs41 types */
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index c72d1ad41ad4..6d627b92df53 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -163,7 +163,7 @@ struct nfs_inode {
163 */ 163 */
164 __be32 cookieverf[2]; 164 __be32 cookieverf[2];
165 165
166 unsigned long npages; 166 unsigned long nrequests;
167 struct nfs_mds_commit_info commit_info; 167 struct nfs_mds_commit_info commit_info;
168 168
169 /* Open contexts for shared mmap writes */ 169 /* Open contexts for shared mmap writes */
@@ -520,7 +520,7 @@ extern void nfs_commit_free(struct nfs_commit_data *data);
520static inline int 520static inline int
521nfs_have_writebacks(struct inode *inode) 521nfs_have_writebacks(struct inode *inode)
522{ 522{
523 return NFS_I(inode)->npages != 0; 523 return NFS_I(inode)->nrequests != 0;
524} 524}
525 525
526/* 526/*
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index a32ba0d7a98f..1e37fbb78f7a 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -231,5 +231,7 @@ struct nfs_server {
231#define NFS_CAP_ATOMIC_OPEN_V1 (1U << 17) 231#define NFS_CAP_ATOMIC_OPEN_V1 (1U << 17)
232#define NFS_CAP_SECURITY_LABEL (1U << 18) 232#define NFS_CAP_SECURITY_LABEL (1U << 18)
233#define NFS_CAP_SEEK (1U << 19) 233#define NFS_CAP_SEEK (1U << 19)
234#define NFS_CAP_ALLOCATE (1U << 20)
235#define NFS_CAP_DEALLOCATE (1U << 21)
234 236
235#endif 237#endif
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 47ebb4fafd87..467c84efb596 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -1243,6 +1243,20 @@ nfs_free_pnfs_ds_cinfo(struct pnfs_ds_commit_info *cinfo)
1243#endif /* CONFIG_NFS_V4_1 */ 1243#endif /* CONFIG_NFS_V4_1 */
1244 1244
1245#ifdef CONFIG_NFS_V4_2 1245#ifdef CONFIG_NFS_V4_2
1246struct nfs42_falloc_args {
1247 struct nfs4_sequence_args seq_args;
1248
1249 struct nfs_fh *falloc_fh;
1250 nfs4_stateid falloc_stateid;
1251 u64 falloc_offset;
1252 u64 falloc_length;
1253};
1254
1255struct nfs42_falloc_res {
1256 struct nfs4_sequence_res seq_res;
1257 unsigned int status;
1258};
1259
1246struct nfs42_seek_args { 1260struct nfs42_seek_args {
1247 struct nfs4_sequence_args seq_args; 1261 struct nfs4_sequence_args seq_args;
1248 1262
diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h
index 8e030075fe79..a7cbb570cc5c 100644
--- a/include/linux/sunrpc/auth.h
+++ b/include/linux/sunrpc/auth.h
@@ -53,7 +53,7 @@ struct rpc_cred {
53 struct rcu_head cr_rcu; 53 struct rcu_head cr_rcu;
54 struct rpc_auth * cr_auth; 54 struct rpc_auth * cr_auth;
55 const struct rpc_credops *cr_ops; 55 const struct rpc_credops *cr_ops;
56#ifdef RPC_DEBUG 56#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
57 unsigned long cr_magic; /* 0x0f4aa4f0 */ 57 unsigned long cr_magic; /* 0x0f4aa4f0 */
58#endif 58#endif
59 unsigned long cr_expire; /* when to gc */ 59 unsigned long cr_expire; /* when to gc */
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index 70736b98c721..d86acc63b25f 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -63,6 +63,9 @@ struct rpc_clnt {
63 struct rpc_rtt cl_rtt_default; 63 struct rpc_rtt cl_rtt_default;
64 struct rpc_timeout cl_timeout_default; 64 struct rpc_timeout cl_timeout_default;
65 const struct rpc_program *cl_program; 65 const struct rpc_program *cl_program;
66#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
67 struct dentry *cl_debugfs; /* debugfs directory */
68#endif
66}; 69};
67 70
68/* 71/*
@@ -176,5 +179,6 @@ size_t rpc_peeraddr(struct rpc_clnt *, struct sockaddr *, size_t);
176const char *rpc_peeraddr2str(struct rpc_clnt *, enum rpc_display_format_t); 179const char *rpc_peeraddr2str(struct rpc_clnt *, enum rpc_display_format_t);
177int rpc_localaddr(struct rpc_clnt *, struct sockaddr *, size_t); 180int rpc_localaddr(struct rpc_clnt *, struct sockaddr *, size_t);
178 181
182const char *rpc_proc_name(const struct rpc_task *task);
179#endif /* __KERNEL__ */ 183#endif /* __KERNEL__ */
180#endif /* _LINUX_SUNRPC_CLNT_H */ 184#endif /* _LINUX_SUNRPC_CLNT_H */
diff --git a/include/linux/sunrpc/debug.h b/include/linux/sunrpc/debug.h
index 9385bd74c860..c57d8ea0716c 100644
--- a/include/linux/sunrpc/debug.h
+++ b/include/linux/sunrpc/debug.h
@@ -10,22 +10,10 @@
10 10
11#include <uapi/linux/sunrpc/debug.h> 11#include <uapi/linux/sunrpc/debug.h>
12 12
13
14/*
15 * Enable RPC debugging/profiling.
16 */
17#ifdef CONFIG_SUNRPC_DEBUG
18#define RPC_DEBUG
19#endif
20#ifdef CONFIG_TRACEPOINTS
21#define RPC_TRACEPOINTS
22#endif
23/* #define RPC_PROFILE */
24
25/* 13/*
26 * Debugging macros etc 14 * Debugging macros etc
27 */ 15 */
28#ifdef RPC_DEBUG 16#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
29extern unsigned int rpc_debug; 17extern unsigned int rpc_debug;
30extern unsigned int nfs_debug; 18extern unsigned int nfs_debug;
31extern unsigned int nfsd_debug; 19extern unsigned int nfsd_debug;
@@ -36,7 +24,7 @@ extern unsigned int nlm_debug;
36#define dprintk_rcu(args...) dfprintk_rcu(FACILITY, ## args) 24#define dprintk_rcu(args...) dfprintk_rcu(FACILITY, ## args)
37 25
38#undef ifdebug 26#undef ifdebug
39#ifdef RPC_DEBUG 27#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
40# define ifdebug(fac) if (unlikely(rpc_debug & RPCDBG_##fac)) 28# define ifdebug(fac) if (unlikely(rpc_debug & RPCDBG_##fac))
41 29
42# define dfprintk(fac, args...) \ 30# define dfprintk(fac, args...) \
@@ -65,9 +53,55 @@ extern unsigned int nlm_debug;
65/* 53/*
66 * Sysctl interface for RPC debugging 54 * Sysctl interface for RPC debugging
67 */ 55 */
68#ifdef RPC_DEBUG 56
57struct rpc_clnt;
58struct rpc_xprt;
59
60#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
69void rpc_register_sysctl(void); 61void rpc_register_sysctl(void);
70void rpc_unregister_sysctl(void); 62void rpc_unregister_sysctl(void);
63int sunrpc_debugfs_init(void);
64void sunrpc_debugfs_exit(void);
65int rpc_clnt_debugfs_register(struct rpc_clnt *);
66void rpc_clnt_debugfs_unregister(struct rpc_clnt *);
67int rpc_xprt_debugfs_register(struct rpc_xprt *);
68void rpc_xprt_debugfs_unregister(struct rpc_xprt *);
69#else
70static inline int
71sunrpc_debugfs_init(void)
72{
73 return 0;
74}
75
76static inline void
77sunrpc_debugfs_exit(void)
78{
79 return;
80}
81
82static inline int
83rpc_clnt_debugfs_register(struct rpc_clnt *clnt)
84{
85 return 0;
86}
87
88static inline void
89rpc_clnt_debugfs_unregister(struct rpc_clnt *clnt)
90{
91 return;
92}
93
94static inline int
95rpc_xprt_debugfs_register(struct rpc_xprt *xprt)
96{
97 return 0;
98}
99
100static inline void
101rpc_xprt_debugfs_unregister(struct rpc_xprt *xprt)
102{
103 return;
104}
71#endif 105#endif
72 106
73#endif /* _LINUX_SUNRPC_DEBUG_H_ */ 107#endif /* _LINUX_SUNRPC_DEBUG_H_ */
diff --git a/include/linux/sunrpc/metrics.h b/include/linux/sunrpc/metrics.h
index 1565bbe86d51..eecb5a71e6c0 100644
--- a/include/linux/sunrpc/metrics.h
+++ b/include/linux/sunrpc/metrics.h
@@ -27,10 +27,13 @@
27 27
28#include <linux/seq_file.h> 28#include <linux/seq_file.h>
29#include <linux/ktime.h> 29#include <linux/ktime.h>
30#include <linux/spinlock.h>
30 31
31#define RPC_IOSTATS_VERS "1.0" 32#define RPC_IOSTATS_VERS "1.0"
32 33
33struct rpc_iostats { 34struct rpc_iostats {
35 spinlock_t om_lock;
36
34 /* 37 /*
35 * These counters give an idea about how many request 38 * These counters give an idea about how many request
36 * transmissions are required, on average, to complete that 39 * transmissions are required, on average, to complete that
diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h
index 1a8959944c5f..5f1e6bd4c316 100644
--- a/include/linux/sunrpc/sched.h
+++ b/include/linux/sunrpc/sched.h
@@ -79,7 +79,7 @@ struct rpc_task {
79 unsigned short tk_flags; /* misc flags */ 79 unsigned short tk_flags; /* misc flags */
80 unsigned short tk_timeouts; /* maj timeouts */ 80 unsigned short tk_timeouts; /* maj timeouts */
81 81
82#if defined(RPC_DEBUG) || defined(RPC_TRACEPOINTS) 82#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || IS_ENABLED(CONFIG_TRACEPOINTS)
83 unsigned short tk_pid; /* debugging aid */ 83 unsigned short tk_pid; /* debugging aid */
84#endif 84#endif
85 unsigned char tk_priority : 2,/* Task priority */ 85 unsigned char tk_priority : 2,/* Task priority */
@@ -187,7 +187,7 @@ struct rpc_wait_queue {
187 unsigned char nr; /* # tasks remaining for cookie */ 187 unsigned char nr; /* # tasks remaining for cookie */
188 unsigned short qlen; /* total # tasks waiting in queue */ 188 unsigned short qlen; /* total # tasks waiting in queue */
189 struct rpc_timer timer_list; 189 struct rpc_timer timer_list;
190#if defined(RPC_DEBUG) || defined(RPC_TRACEPOINTS) 190#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || IS_ENABLED(CONFIG_TRACEPOINTS)
191 const char * name; 191 const char * name;
192#endif 192#endif
193}; 193};
@@ -237,7 +237,7 @@ void rpc_free(void *);
237int rpciod_up(void); 237int rpciod_up(void);
238void rpciod_down(void); 238void rpciod_down(void);
239int __rpc_wait_for_completion_task(struct rpc_task *task, wait_bit_action_f *); 239int __rpc_wait_for_completion_task(struct rpc_task *task, wait_bit_action_f *);
240#ifdef RPC_DEBUG 240#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
241struct net; 241struct net;
242void rpc_show_tasks(struct net *); 242void rpc_show_tasks(struct net *);
243#endif 243#endif
@@ -251,7 +251,7 @@ static inline int rpc_wait_for_completion_task(struct rpc_task *task)
251 return __rpc_wait_for_completion_task(task, NULL); 251 return __rpc_wait_for_completion_task(task, NULL);
252} 252}
253 253
254#if defined(RPC_DEBUG) || defined (RPC_TRACEPOINTS) 254#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || IS_ENABLED(CONFIG_TRACEPOINTS)
255static inline const char * rpc_qname(const struct rpc_wait_queue *q) 255static inline const char * rpc_qname(const struct rpc_wait_queue *q)
256{ 256{
257 return ((q && q->name) ? q->name : "unknown"); 257 return ((q && q->name) ? q->name : "unknown");
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index cf391eef2e6d..9d27ac45b909 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -239,6 +239,9 @@ struct rpc_xprt {
239 struct net *xprt_net; 239 struct net *xprt_net;
240 const char *servername; 240 const char *servername;
241 const char *address_strings[RPC_DISPLAY_MAX]; 241 const char *address_strings[RPC_DISPLAY_MAX];
242#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
243 struct dentry *debugfs; /* debugfs directory */
244#endif
242}; 245};
243 246
244#if defined(CONFIG_SUNRPC_BACKCHANNEL) 247#if defined(CONFIG_SUNRPC_BACKCHANNEL)
diff --git a/include/linux/sunrpc/xprtsock.h b/include/linux/sunrpc/xprtsock.h
index 1ad36cc25b2e..7591788e9fbf 100644
--- a/include/linux/sunrpc/xprtsock.h
+++ b/include/linux/sunrpc/xprtsock.h
@@ -17,6 +17,65 @@ void cleanup_socket_xprt(void);
17#define RPC_DEF_MIN_RESVPORT (665U) 17#define RPC_DEF_MIN_RESVPORT (665U)
18#define RPC_DEF_MAX_RESVPORT (1023U) 18#define RPC_DEF_MAX_RESVPORT (1023U)
19 19
20struct sock_xprt {
21 struct rpc_xprt xprt;
22
23 /*
24 * Network layer
25 */
26 struct socket * sock;
27 struct sock * inet;
28
29 /*
30 * State of TCP reply receive
31 */
32 __be32 tcp_fraghdr,
33 tcp_xid,
34 tcp_calldir;
35
36 u32 tcp_offset,
37 tcp_reclen;
38
39 unsigned long tcp_copied,
40 tcp_flags;
41
42 /*
43 * Connection of transports
44 */
45 struct delayed_work connect_worker;
46 struct sockaddr_storage srcaddr;
47 unsigned short srcport;
48
49 /*
50 * UDP socket buffer size parameters
51 */
52 size_t rcvsize,
53 sndsize;
54
55 /*
56 * Saved socket callback addresses
57 */
58 void (*old_data_ready)(struct sock *);
59 void (*old_state_change)(struct sock *);
60 void (*old_write_space)(struct sock *);
61 void (*old_error_report)(struct sock *);
62};
63
64/*
65 * TCP receive state flags
66 */
67#define TCP_RCV_LAST_FRAG (1UL << 0)
68#define TCP_RCV_COPY_FRAGHDR (1UL << 1)
69#define TCP_RCV_COPY_XID (1UL << 2)
70#define TCP_RCV_COPY_DATA (1UL << 3)
71#define TCP_RCV_READ_CALLDIR (1UL << 4)
72#define TCP_RCV_COPY_CALLDIR (1UL << 5)
73
74/*
75 * TCP RPC flags
76 */
77#define TCP_RPC_REPLY (1UL << 6)
78
20#endif /* __KERNEL__ */ 79#endif /* __KERNEL__ */
21 80
22#endif /* _LINUX_SUNRPC_XPRTSOCK_H */ 81#endif /* _LINUX_SUNRPC_XPRTSOCK_H */
diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h
index 1fef3e6e9436..171ca4ff6d99 100644
--- a/include/trace/events/sunrpc.h
+++ b/include/trace/events/sunrpc.h
@@ -6,6 +6,8 @@
6 6
7#include <linux/sunrpc/sched.h> 7#include <linux/sunrpc/sched.h>
8#include <linux/sunrpc/clnt.h> 8#include <linux/sunrpc/clnt.h>
9#include <linux/sunrpc/svc.h>
10#include <linux/sunrpc/xprtsock.h>
9#include <net/tcp_states.h> 11#include <net/tcp_states.h>
10#include <linux/net.h> 12#include <linux/net.h>
11#include <linux/tracepoint.h> 13#include <linux/tracepoint.h>
@@ -306,6 +308,164 @@ DEFINE_RPC_SOCKET_EVENT_DONE(rpc_socket_reset_connection);
306DEFINE_RPC_SOCKET_EVENT(rpc_socket_close); 308DEFINE_RPC_SOCKET_EVENT(rpc_socket_close);
307DEFINE_RPC_SOCKET_EVENT(rpc_socket_shutdown); 309DEFINE_RPC_SOCKET_EVENT(rpc_socket_shutdown);
308 310
311DECLARE_EVENT_CLASS(rpc_xprt_event,
312 TP_PROTO(struct rpc_xprt *xprt, __be32 xid, int status),
313
314 TP_ARGS(xprt, xid, status),
315
316 TP_STRUCT__entry(
317 __field(__be32, xid)
318 __field(int, status)
319 __string(addr, xprt->address_strings[RPC_DISPLAY_ADDR])
320 __string(port, xprt->address_strings[RPC_DISPLAY_PORT])
321 ),
322
323 TP_fast_assign(
324 __entry->xid = xid;
325 __entry->status = status;
326 __assign_str(addr, xprt->address_strings[RPC_DISPLAY_ADDR]);
327 __assign_str(port, xprt->address_strings[RPC_DISPLAY_PORT]);
328 ),
329
330 TP_printk("peer=[%s]:%s xid=0x%x status=%d", __get_str(addr),
331 __get_str(port), be32_to_cpu(__entry->xid),
332 __entry->status)
333);
334
335DEFINE_EVENT(rpc_xprt_event, xprt_lookup_rqst,
336 TP_PROTO(struct rpc_xprt *xprt, __be32 xid, int status),
337 TP_ARGS(xprt, xid, status));
338
339DEFINE_EVENT(rpc_xprt_event, xprt_transmit,
340 TP_PROTO(struct rpc_xprt *xprt, __be32 xid, int status),
341 TP_ARGS(xprt, xid, status));
342
343DEFINE_EVENT(rpc_xprt_event, xprt_complete_rqst,
344 TP_PROTO(struct rpc_xprt *xprt, __be32 xid, int status),
345 TP_ARGS(xprt, xid, status));
346
347TRACE_EVENT(xs_tcp_data_ready,
348 TP_PROTO(struct rpc_xprt *xprt, int err, unsigned int total),
349
350 TP_ARGS(xprt, err, total),
351
352 TP_STRUCT__entry(
353 __field(int, err)
354 __field(unsigned int, total)
355 __string(addr, xprt ? xprt->address_strings[RPC_DISPLAY_ADDR] :
356 "(null)")
357 __string(port, xprt ? xprt->address_strings[RPC_DISPLAY_PORT] :
358 "(null)")
359 ),
360
361 TP_fast_assign(
362 __entry->err = err;
363 __entry->total = total;
364 __assign_str(addr, xprt ?
365 xprt->address_strings[RPC_DISPLAY_ADDR] : "(null)");
366 __assign_str(port, xprt ?
367 xprt->address_strings[RPC_DISPLAY_PORT] : "(null)");
368 ),
369
370 TP_printk("peer=[%s]:%s err=%d total=%u", __get_str(addr),
371 __get_str(port), __entry->err, __entry->total)
372);
373
374#define rpc_show_sock_xprt_flags(flags) \
375 __print_flags(flags, "|", \
376 { TCP_RCV_LAST_FRAG, "TCP_RCV_LAST_FRAG" }, \
377 { TCP_RCV_COPY_FRAGHDR, "TCP_RCV_COPY_FRAGHDR" }, \
378 { TCP_RCV_COPY_XID, "TCP_RCV_COPY_XID" }, \
379 { TCP_RCV_COPY_DATA, "TCP_RCV_COPY_DATA" }, \
380 { TCP_RCV_READ_CALLDIR, "TCP_RCV_READ_CALLDIR" }, \
381 { TCP_RCV_COPY_CALLDIR, "TCP_RCV_COPY_CALLDIR" }, \
382 { TCP_RPC_REPLY, "TCP_RPC_REPLY" })
383
384TRACE_EVENT(xs_tcp_data_recv,
385 TP_PROTO(struct sock_xprt *xs),
386
387 TP_ARGS(xs),
388
389 TP_STRUCT__entry(
390 __string(addr, xs->xprt.address_strings[RPC_DISPLAY_ADDR])
391 __string(port, xs->xprt.address_strings[RPC_DISPLAY_PORT])
392 __field(__be32, xid)
393 __field(unsigned long, flags)
394 __field(unsigned long, copied)
395 __field(unsigned int, reclen)
396 __field(unsigned long, offset)
397 ),
398
399 TP_fast_assign(
400 __assign_str(addr, xs->xprt.address_strings[RPC_DISPLAY_ADDR]);
401 __assign_str(port, xs->xprt.address_strings[RPC_DISPLAY_PORT]);
402 __entry->xid = xs->tcp_xid;
403 __entry->flags = xs->tcp_flags;
404 __entry->copied = xs->tcp_copied;
405 __entry->reclen = xs->tcp_reclen;
406 __entry->offset = xs->tcp_offset;
407 ),
408
409 TP_printk("peer=[%s]:%s xid=0x%x flags=%s copied=%lu reclen=%u offset=%lu",
410 __get_str(addr), __get_str(port), be32_to_cpu(__entry->xid),
411 rpc_show_sock_xprt_flags(__entry->flags),
412 __entry->copied, __entry->reclen, __entry->offset)
413);
414
415TRACE_EVENT(svc_recv,
416 TP_PROTO(struct svc_rqst *rqst, int status),
417
418 TP_ARGS(rqst, status),
419
420 TP_STRUCT__entry(
421 __field(struct sockaddr *, addr)
422 __field(__be32, xid)
423 __field(int, status)
424 ),
425
426 TP_fast_assign(
427 __entry->addr = (struct sockaddr *)&rqst->rq_addr;
428 __entry->xid = status > 0 ? rqst->rq_xid : 0;
429 __entry->status = status;
430 ),
431
432 TP_printk("addr=%pIScp xid=0x%x status=%d", __entry->addr,
433 be32_to_cpu(__entry->xid), __entry->status)
434);
435
436DECLARE_EVENT_CLASS(svc_rqst_status,
437
438 TP_PROTO(struct svc_rqst *rqst, int status),
439
440 TP_ARGS(rqst, status),
441
442 TP_STRUCT__entry(
443 __field(struct sockaddr *, addr)
444 __field(__be32, xid)
445 __field(int, dropme)
446 __field(int, status)
447 ),
448
449 TP_fast_assign(
450 __entry->addr = (struct sockaddr *)&rqst->rq_addr;
451 __entry->xid = rqst->rq_xid;
452 __entry->dropme = (int)rqst->rq_dropme;
453 __entry->status = status;
454 ),
455
456 TP_printk("addr=%pIScp rq_xid=0x%x dropme=%d status=%d",
457 __entry->addr, be32_to_cpu(__entry->xid), __entry->dropme,
458 __entry->status)
459);
460
461DEFINE_EVENT(svc_rqst_status, svc_process,
462 TP_PROTO(struct svc_rqst *rqst, int status),
463 TP_ARGS(rqst, status));
464
465DEFINE_EVENT(svc_rqst_status, svc_send,
466 TP_PROTO(struct svc_rqst *rqst, int status),
467 TP_ARGS(rqst, status));
468
309#endif /* _TRACE_SUNRPC_H */ 469#endif /* _TRACE_SUNRPC_H */
310 470
311#include <trace/define_trace.h> 471#include <trace/define_trace.h>
diff --git a/include/uapi/linux/nfsd/debug.h b/include/uapi/linux/nfsd/debug.h
index a6f453c740b8..1fdc95bb2375 100644
--- a/include/uapi/linux/nfsd/debug.h
+++ b/include/uapi/linux/nfsd/debug.h
@@ -15,7 +15,7 @@
15 * Enable debugging for nfsd. 15 * Enable debugging for nfsd.
16 * Requires RPC_DEBUG. 16 * Requires RPC_DEBUG.
17 */ 17 */
18#ifdef RPC_DEBUG 18#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
19# define NFSD_DEBUG 1 19# define NFSD_DEBUG 1
20#endif 20#endif
21 21
diff --git a/net/sunrpc/Kconfig b/net/sunrpc/Kconfig
index 0754d0f466d2..fb78117b896c 100644
--- a/net/sunrpc/Kconfig
+++ b/net/sunrpc/Kconfig
@@ -35,6 +35,7 @@ config RPCSEC_GSS_KRB5
35config SUNRPC_DEBUG 35config SUNRPC_DEBUG
36 bool "RPC: Enable dprintk debugging" 36 bool "RPC: Enable dprintk debugging"
37 depends on SUNRPC && SYSCTL 37 depends on SUNRPC && SYSCTL
38 select DEBUG_FS
38 help 39 help
39 This option enables a sysctl-based debugging interface 40 This option enables a sysctl-based debugging interface
40 that is be used by the 'rpcdebug' utility to turn on or off 41 that is be used by the 'rpcdebug' utility to turn on or off
diff --git a/net/sunrpc/Makefile b/net/sunrpc/Makefile
index e5a7a1cac8f3..15e6f6c23c5d 100644
--- a/net/sunrpc/Makefile
+++ b/net/sunrpc/Makefile
@@ -14,6 +14,7 @@ sunrpc-y := clnt.o xprt.o socklib.o xprtsock.o sched.o \
14 addr.o rpcb_clnt.o timer.o xdr.o \ 14 addr.o rpcb_clnt.o timer.o xdr.o \
15 sunrpc_syms.o cache.o rpc_pipe.o \ 15 sunrpc_syms.o cache.o rpc_pipe.o \
16 svc_xprt.o 16 svc_xprt.o
17sunrpc-$(CONFIG_SUNRPC_DEBUG) += debugfs.o
17sunrpc-$(CONFIG_SUNRPC_BACKCHANNEL) += backchannel_rqst.o bc_svc.o 18sunrpc-$(CONFIG_SUNRPC_BACKCHANNEL) += backchannel_rqst.o bc_svc.o
18sunrpc-$(CONFIG_PROC_FS) += stats.o 19sunrpc-$(CONFIG_PROC_FS) += stats.o
19sunrpc-$(CONFIG_SYSCTL) += sysctl.o 20sunrpc-$(CONFIG_SYSCTL) += sysctl.o
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
index 383eb919ac0b..47f38be4155f 100644
--- a/net/sunrpc/auth.c
+++ b/net/sunrpc/auth.c
@@ -16,7 +16,7 @@
16#include <linux/sunrpc/gss_api.h> 16#include <linux/sunrpc/gss_api.h>
17#include <linux/spinlock.h> 17#include <linux/spinlock.h>
18 18
19#ifdef RPC_DEBUG 19#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
20# define RPCDBG_FACILITY RPCDBG_AUTH 20# define RPCDBG_FACILITY RPCDBG_AUTH
21#endif 21#endif
22 22
@@ -646,7 +646,7 @@ rpcauth_init_cred(struct rpc_cred *cred, const struct auth_cred *acred,
646 cred->cr_auth = auth; 646 cred->cr_auth = auth;
647 cred->cr_ops = ops; 647 cred->cr_ops = ops;
648 cred->cr_expire = jiffies; 648 cred->cr_expire = jiffies;
649#ifdef RPC_DEBUG 649#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
650 cred->cr_magic = RPCAUTH_CRED_MAGIC; 650 cred->cr_magic = RPCAUTH_CRED_MAGIC;
651#endif 651#endif
652 cred->cr_uid = acred->uid; 652 cred->cr_uid = acred->uid;
diff --git a/net/sunrpc/auth_generic.c b/net/sunrpc/auth_generic.c
index 6f6b829c9e8e..41248b1820c7 100644
--- a/net/sunrpc/auth_generic.c
+++ b/net/sunrpc/auth_generic.c
@@ -14,7 +14,7 @@
14#include <linux/sunrpc/debug.h> 14#include <linux/sunrpc/debug.h>
15#include <linux/sunrpc/sched.h> 15#include <linux/sunrpc/sched.h>
16 16
17#ifdef RPC_DEBUG 17#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
18# define RPCDBG_FACILITY RPCDBG_AUTH 18# define RPCDBG_FACILITY RPCDBG_AUTH
19#endif 19#endif
20 20
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index 53ed8d3f8897..dace13d7638e 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -66,7 +66,7 @@ static unsigned int gss_expired_cred_retry_delay = GSS_RETRY_EXPIRED;
66#define GSS_KEY_EXPIRE_TIMEO 240 66#define GSS_KEY_EXPIRE_TIMEO 240
67static unsigned int gss_key_expire_timeo = GSS_KEY_EXPIRE_TIMEO; 67static unsigned int gss_key_expire_timeo = GSS_KEY_EXPIRE_TIMEO;
68 68
69#ifdef RPC_DEBUG 69#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
70# define RPCDBG_FACILITY RPCDBG_AUTH 70# define RPCDBG_FACILITY RPCDBG_AUTH
71#endif 71#endif
72 72
diff --git a/net/sunrpc/auth_gss/gss_generic_token.c b/net/sunrpc/auth_gss/gss_generic_token.c
index c586e92bcf76..254defe446a7 100644
--- a/net/sunrpc/auth_gss/gss_generic_token.c
+++ b/net/sunrpc/auth_gss/gss_generic_token.c
@@ -38,7 +38,7 @@
38#include <linux/sunrpc/gss_asn1.h> 38#include <linux/sunrpc/gss_asn1.h>
39 39
40 40
41#ifdef RPC_DEBUG 41#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
42# define RPCDBG_FACILITY RPCDBG_AUTH 42# define RPCDBG_FACILITY RPCDBG_AUTH
43#endif 43#endif
44 44
diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c
index f5ed9f6ece06..b5408e8a37f2 100644
--- a/net/sunrpc/auth_gss/gss_krb5_crypto.c
+++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c
@@ -45,7 +45,7 @@
45#include <linux/sunrpc/gss_krb5.h> 45#include <linux/sunrpc/gss_krb5.h>
46#include <linux/sunrpc/xdr.h> 46#include <linux/sunrpc/xdr.h>
47 47
48#ifdef RPC_DEBUG 48#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
49# define RPCDBG_FACILITY RPCDBG_AUTH 49# define RPCDBG_FACILITY RPCDBG_AUTH
50#endif 50#endif
51 51
diff --git a/net/sunrpc/auth_gss/gss_krb5_keys.c b/net/sunrpc/auth_gss/gss_krb5_keys.c
index 24589bd2a4b6..234fa8d0fd9b 100644
--- a/net/sunrpc/auth_gss/gss_krb5_keys.c
+++ b/net/sunrpc/auth_gss/gss_krb5_keys.c
@@ -61,7 +61,7 @@
61#include <linux/sunrpc/xdr.h> 61#include <linux/sunrpc/xdr.h>
62#include <linux/lcm.h> 62#include <linux/lcm.h>
63 63
64#ifdef RPC_DEBUG 64#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
65# define RPCDBG_FACILITY RPCDBG_AUTH 65# define RPCDBG_FACILITY RPCDBG_AUTH
66#endif 66#endif
67 67
diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c
index 0d3c158ef8fa..28db442a0034 100644
--- a/net/sunrpc/auth_gss/gss_krb5_mech.c
+++ b/net/sunrpc/auth_gss/gss_krb5_mech.c
@@ -45,7 +45,7 @@
45#include <linux/crypto.h> 45#include <linux/crypto.h>
46#include <linux/sunrpc/gss_krb5_enctypes.h> 46#include <linux/sunrpc/gss_krb5_enctypes.h>
47 47
48#ifdef RPC_DEBUG 48#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
49# define RPCDBG_FACILITY RPCDBG_AUTH 49# define RPCDBG_FACILITY RPCDBG_AUTH
50#endif 50#endif
51 51
diff --git a/net/sunrpc/auth_gss/gss_krb5_seal.c b/net/sunrpc/auth_gss/gss_krb5_seal.c
index 42768e5c3994..1d74d653e6c0 100644
--- a/net/sunrpc/auth_gss/gss_krb5_seal.c
+++ b/net/sunrpc/auth_gss/gss_krb5_seal.c
@@ -64,7 +64,7 @@
64#include <linux/random.h> 64#include <linux/random.h>
65#include <linux/crypto.h> 65#include <linux/crypto.h>
66 66
67#ifdef RPC_DEBUG 67#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
68# define RPCDBG_FACILITY RPCDBG_AUTH 68# define RPCDBG_FACILITY RPCDBG_AUTH
69#endif 69#endif
70 70
diff --git a/net/sunrpc/auth_gss/gss_krb5_seqnum.c b/net/sunrpc/auth_gss/gss_krb5_seqnum.c
index 62ac90c62cb1..20d55c793eb6 100644
--- a/net/sunrpc/auth_gss/gss_krb5_seqnum.c
+++ b/net/sunrpc/auth_gss/gss_krb5_seqnum.c
@@ -35,7 +35,7 @@
35#include <linux/sunrpc/gss_krb5.h> 35#include <linux/sunrpc/gss_krb5.h>
36#include <linux/crypto.h> 36#include <linux/crypto.h>
37 37
38#ifdef RPC_DEBUG 38#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
39# define RPCDBG_FACILITY RPCDBG_AUTH 39# define RPCDBG_FACILITY RPCDBG_AUTH
40#endif 40#endif
41 41
diff --git a/net/sunrpc/auth_gss/gss_krb5_unseal.c b/net/sunrpc/auth_gss/gss_krb5_unseal.c
index 6c981ddc19f8..dcf9515d9aef 100644
--- a/net/sunrpc/auth_gss/gss_krb5_unseal.c
+++ b/net/sunrpc/auth_gss/gss_krb5_unseal.c
@@ -62,7 +62,7 @@
62#include <linux/sunrpc/gss_krb5.h> 62#include <linux/sunrpc/gss_krb5.h>
63#include <linux/crypto.h> 63#include <linux/crypto.h>
64 64
65#ifdef RPC_DEBUG 65#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
66# define RPCDBG_FACILITY RPCDBG_AUTH 66# define RPCDBG_FACILITY RPCDBG_AUTH
67#endif 67#endif
68 68
diff --git a/net/sunrpc/auth_gss/gss_krb5_wrap.c b/net/sunrpc/auth_gss/gss_krb5_wrap.c
index 4b614c604fe0..ca7e92a32f84 100644
--- a/net/sunrpc/auth_gss/gss_krb5_wrap.c
+++ b/net/sunrpc/auth_gss/gss_krb5_wrap.c
@@ -35,7 +35,7 @@
35#include <linux/pagemap.h> 35#include <linux/pagemap.h>
36#include <linux/crypto.h> 36#include <linux/crypto.h>
37 37
38#ifdef RPC_DEBUG 38#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
39# define RPCDBG_FACILITY RPCDBG_AUTH 39# define RPCDBG_FACILITY RPCDBG_AUTH
40#endif 40#endif
41 41
diff --git a/net/sunrpc/auth_gss/gss_mech_switch.c b/net/sunrpc/auth_gss/gss_mech_switch.c
index 92d5ab99fbf3..7063d856a598 100644
--- a/net/sunrpc/auth_gss/gss_mech_switch.c
+++ b/net/sunrpc/auth_gss/gss_mech_switch.c
@@ -46,7 +46,7 @@
46#include <linux/sunrpc/gss_api.h> 46#include <linux/sunrpc/gss_api.h>
47#include <linux/sunrpc/clnt.h> 47#include <linux/sunrpc/clnt.h>
48 48
49#ifdef RPC_DEBUG 49#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
50# define RPCDBG_FACILITY RPCDBG_AUTH 50# define RPCDBG_FACILITY RPCDBG_AUTH
51#endif 51#endif
52 52
diff --git a/net/sunrpc/auth_gss/gss_rpc_xdr.h b/net/sunrpc/auth_gss/gss_rpc_xdr.h
index 685a688f3d8a..9d88c6239f01 100644
--- a/net/sunrpc/auth_gss/gss_rpc_xdr.h
+++ b/net/sunrpc/auth_gss/gss_rpc_xdr.h
@@ -25,7 +25,7 @@
25#include <linux/sunrpc/clnt.h> 25#include <linux/sunrpc/clnt.h>
26#include <linux/sunrpc/xprtsock.h> 26#include <linux/sunrpc/xprtsock.h>
27 27
28#ifdef RPC_DEBUG 28#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
29# define RPCDBG_FACILITY RPCDBG_AUTH 29# define RPCDBG_FACILITY RPCDBG_AUTH
30#endif 30#endif
31 31
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index c548ab213f76..de856ddf5fed 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -51,7 +51,7 @@
51#include "gss_rpc_upcall.h" 51#include "gss_rpc_upcall.h"
52 52
53 53
54#ifdef RPC_DEBUG 54#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
55# define RPCDBG_FACILITY RPCDBG_AUTH 55# define RPCDBG_FACILITY RPCDBG_AUTH
56#endif 56#endif
57 57
diff --git a/net/sunrpc/auth_null.c b/net/sunrpc/auth_null.c
index 712c123e04e9..c2a2b584a056 100644
--- a/net/sunrpc/auth_null.c
+++ b/net/sunrpc/auth_null.c
@@ -10,7 +10,7 @@
10#include <linux/module.h> 10#include <linux/module.h>
11#include <linux/sunrpc/clnt.h> 11#include <linux/sunrpc/clnt.h>
12 12
13#ifdef RPC_DEBUG 13#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
14# define RPCDBG_FACILITY RPCDBG_AUTH 14# define RPCDBG_FACILITY RPCDBG_AUTH
15#endif 15#endif
16 16
@@ -138,7 +138,7 @@ struct rpc_cred null_cred = {
138 .cr_ops = &null_credops, 138 .cr_ops = &null_credops,
139 .cr_count = ATOMIC_INIT(1), 139 .cr_count = ATOMIC_INIT(1),
140 .cr_flags = 1UL << RPCAUTH_CRED_UPTODATE, 140 .cr_flags = 1UL << RPCAUTH_CRED_UPTODATE,
141#ifdef RPC_DEBUG 141#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
142 .cr_magic = RPCAUTH_CRED_MAGIC, 142 .cr_magic = RPCAUTH_CRED_MAGIC,
143#endif 143#endif
144}; 144};
diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c
index d5d692366294..4feda2d0a833 100644
--- a/net/sunrpc/auth_unix.c
+++ b/net/sunrpc/auth_unix.c
@@ -25,7 +25,7 @@ struct unx_cred {
25 25
26#define UNX_WRITESLACK (21 + (UNX_MAXNODENAME >> 2)) 26#define UNX_WRITESLACK (21 + (UNX_MAXNODENAME >> 2))
27 27
28#ifdef RPC_DEBUG 28#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
29# define RPCDBG_FACILITY RPCDBG_AUTH 29# define RPCDBG_FACILITY RPCDBG_AUTH
30#endif 30#endif
31 31
diff --git a/net/sunrpc/backchannel_rqst.c b/net/sunrpc/backchannel_rqst.c
index 9761a0da964d..651f49ab601f 100644
--- a/net/sunrpc/backchannel_rqst.c
+++ b/net/sunrpc/backchannel_rqst.c
@@ -27,7 +27,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27#include <linux/export.h> 27#include <linux/export.h>
28#include <linux/sunrpc/bc_xprt.h> 28#include <linux/sunrpc/bc_xprt.h>
29 29
30#ifdef RPC_DEBUG 30#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
31#define RPCDBG_FACILITY RPCDBG_TRANS 31#define RPCDBG_FACILITY RPCDBG_TRANS
32#endif 32#endif
33 33
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 9acd6ce88db7..05da12a33945 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -42,7 +42,7 @@
42#include "sunrpc.h" 42#include "sunrpc.h"
43#include "netns.h" 43#include "netns.h"
44 44
45#ifdef RPC_DEBUG 45#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
46# define RPCDBG_FACILITY RPCDBG_CALL 46# define RPCDBG_FACILITY RPCDBG_CALL
47#endif 47#endif
48 48
@@ -305,6 +305,10 @@ static int rpc_client_register(struct rpc_clnt *clnt,
305 struct super_block *pipefs_sb; 305 struct super_block *pipefs_sb;
306 int err; 306 int err;
307 307
308 err = rpc_clnt_debugfs_register(clnt);
309 if (err)
310 return err;
311
308 pipefs_sb = rpc_get_sb_net(net); 312 pipefs_sb = rpc_get_sb_net(net);
309 if (pipefs_sb) { 313 if (pipefs_sb) {
310 err = rpc_setup_pipedir(pipefs_sb, clnt); 314 err = rpc_setup_pipedir(pipefs_sb, clnt);
@@ -331,6 +335,7 @@ err_auth:
331out: 335out:
332 if (pipefs_sb) 336 if (pipefs_sb)
333 rpc_put_sb_net(net); 337 rpc_put_sb_net(net);
338 rpc_clnt_debugfs_unregister(clnt);
334 return err; 339 return err;
335} 340}
336 341
@@ -670,6 +675,7 @@ int rpc_switch_client_transport(struct rpc_clnt *clnt,
670 675
671 rpc_unregister_client(clnt); 676 rpc_unregister_client(clnt);
672 __rpc_clnt_remove_pipedir(clnt); 677 __rpc_clnt_remove_pipedir(clnt);
678 rpc_clnt_debugfs_unregister(clnt);
673 679
674 /* 680 /*
675 * A new transport was created. "clnt" therefore 681 * A new transport was created. "clnt" therefore
@@ -771,6 +777,7 @@ rpc_free_client(struct rpc_clnt *clnt)
771 rcu_dereference(clnt->cl_xprt)->servername); 777 rcu_dereference(clnt->cl_xprt)->servername);
772 if (clnt->cl_parent != clnt) 778 if (clnt->cl_parent != clnt)
773 parent = clnt->cl_parent; 779 parent = clnt->cl_parent;
780 rpc_clnt_debugfs_unregister(clnt);
774 rpc_clnt_remove_pipedir(clnt); 781 rpc_clnt_remove_pipedir(clnt);
775 rpc_unregister_client(clnt); 782 rpc_unregister_client(clnt);
776 rpc_free_iostats(clnt->cl_metrics); 783 rpc_free_iostats(clnt->cl_metrics);
@@ -1396,8 +1403,9 @@ rpc_restart_call(struct rpc_task *task)
1396} 1403}
1397EXPORT_SYMBOL_GPL(rpc_restart_call); 1404EXPORT_SYMBOL_GPL(rpc_restart_call);
1398 1405
1399#ifdef RPC_DEBUG 1406#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
1400static const char *rpc_proc_name(const struct rpc_task *task) 1407const char
1408*rpc_proc_name(const struct rpc_task *task)
1401{ 1409{
1402 const struct rpc_procinfo *proc = task->tk_msg.rpc_proc; 1410 const struct rpc_procinfo *proc = task->tk_msg.rpc_proc;
1403 1411
@@ -2421,7 +2429,7 @@ struct rpc_task *rpc_call_null(struct rpc_clnt *clnt, struct rpc_cred *cred, int
2421} 2429}
2422EXPORT_SYMBOL_GPL(rpc_call_null); 2430EXPORT_SYMBOL_GPL(rpc_call_null);
2423 2431
2424#ifdef RPC_DEBUG 2432#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
2425static void rpc_show_header(void) 2433static void rpc_show_header(void)
2426{ 2434{
2427 printk(KERN_INFO "-pid- flgs status -client- --rqstp- " 2435 printk(KERN_INFO "-pid- flgs status -client- --rqstp- "
diff --git a/net/sunrpc/debugfs.c b/net/sunrpc/debugfs.c
new file mode 100644
index 000000000000..e811f390f9f6
--- /dev/null
+++ b/net/sunrpc/debugfs.c
@@ -0,0 +1,292 @@
1/**
2 * debugfs interface for sunrpc
3 *
4 * (c) 2014 Jeff Layton <jlayton@primarydata.com>
5 */
6
7#include <linux/debugfs.h>
8#include <linux/sunrpc/sched.h>
9#include <linux/sunrpc/clnt.h>
10#include "netns.h"
11
12static struct dentry *topdir;
13static struct dentry *rpc_clnt_dir;
14static struct dentry *rpc_xprt_dir;
15
16struct rpc_clnt_iter {
17 struct rpc_clnt *clnt;
18 loff_t pos;
19};
20
21static int
22tasks_show(struct seq_file *f, void *v)
23{
24 u32 xid = 0;
25 struct rpc_task *task = v;
26 struct rpc_clnt *clnt = task->tk_client;
27 const char *rpc_waitq = "none";
28
29 if (RPC_IS_QUEUED(task))
30 rpc_waitq = rpc_qname(task->tk_waitqueue);
31
32 if (task->tk_rqstp)
33 xid = be32_to_cpu(task->tk_rqstp->rq_xid);
34
35 seq_printf(f, "%5u %04x %6d 0x%x 0x%x %8ld %ps %sv%u %s a:%ps q:%s\n",
36 task->tk_pid, task->tk_flags, task->tk_status,
37 clnt->cl_clid, xid, task->tk_timeout, task->tk_ops,
38 clnt->cl_program->name, clnt->cl_vers, rpc_proc_name(task),
39 task->tk_action, rpc_waitq);
40 return 0;
41}
42
43static void *
44tasks_start(struct seq_file *f, loff_t *ppos)
45 __acquires(&clnt->cl_lock)
46{
47 struct rpc_clnt_iter *iter = f->private;
48 loff_t pos = *ppos;
49 struct rpc_clnt *clnt = iter->clnt;
50 struct rpc_task *task;
51
52 iter->pos = pos + 1;
53 spin_lock(&clnt->cl_lock);
54 list_for_each_entry(task, &clnt->cl_tasks, tk_task)
55 if (pos-- == 0)
56 return task;
57 return NULL;
58}
59
60static void *
61tasks_next(struct seq_file *f, void *v, loff_t *pos)
62{
63 struct rpc_clnt_iter *iter = f->private;
64 struct rpc_clnt *clnt = iter->clnt;
65 struct rpc_task *task = v;
66 struct list_head *next = task->tk_task.next;
67
68 ++iter->pos;
69 ++*pos;
70
71 /* If there's another task on list, return it */
72 if (next == &clnt->cl_tasks)
73 return NULL;
74 return list_entry(next, struct rpc_task, tk_task);
75}
76
77static void
78tasks_stop(struct seq_file *f, void *v)
79 __releases(&clnt->cl_lock)
80{
81 struct rpc_clnt_iter *iter = f->private;
82 struct rpc_clnt *clnt = iter->clnt;
83
84 spin_unlock(&clnt->cl_lock);
85}
86
87static const struct seq_operations tasks_seq_operations = {
88 .start = tasks_start,
89 .next = tasks_next,
90 .stop = tasks_stop,
91 .show = tasks_show,
92};
93
94static int tasks_open(struct inode *inode, struct file *filp)
95{
96 int ret = seq_open_private(filp, &tasks_seq_operations,
97 sizeof(struct rpc_clnt_iter));
98
99 if (!ret) {
100 struct seq_file *seq = filp->private_data;
101 struct rpc_clnt_iter *iter = seq->private;
102
103 iter->clnt = inode->i_private;
104
105 if (!atomic_inc_not_zero(&iter->clnt->cl_count)) {
106 seq_release_private(inode, filp);
107 ret = -EINVAL;
108 }
109 }
110
111 return ret;
112}
113
114static int
115tasks_release(struct inode *inode, struct file *filp)
116{
117 struct seq_file *seq = filp->private_data;
118 struct rpc_clnt_iter *iter = seq->private;
119
120 rpc_release_client(iter->clnt);
121 return seq_release_private(inode, filp);
122}
123
124static const struct file_operations tasks_fops = {
125 .owner = THIS_MODULE,
126 .open = tasks_open,
127 .read = seq_read,
128 .llseek = seq_lseek,
129 .release = tasks_release,
130};
131
132int
133rpc_clnt_debugfs_register(struct rpc_clnt *clnt)
134{
135 int len, err;
136 char name[24]; /* enough for "../../rpc_xprt/ + 8 hex digits + NULL */
137
138 /* Already registered? */
139 if (clnt->cl_debugfs)
140 return 0;
141
142 len = snprintf(name, sizeof(name), "%x", clnt->cl_clid);
143 if (len >= sizeof(name))
144 return -EINVAL;
145
146 /* make the per-client dir */
147 clnt->cl_debugfs = debugfs_create_dir(name, rpc_clnt_dir);
148 if (!clnt->cl_debugfs)
149 return -ENOMEM;
150
151 /* make tasks file */
152 err = -ENOMEM;
153 if (!debugfs_create_file("tasks", S_IFREG | S_IRUSR, clnt->cl_debugfs,
154 clnt, &tasks_fops))
155 goto out_err;
156
157 err = -EINVAL;
158 rcu_read_lock();
159 len = snprintf(name, sizeof(name), "../../rpc_xprt/%s",
160 rcu_dereference(clnt->cl_xprt)->debugfs->d_name.name);
161 rcu_read_unlock();
162 if (len >= sizeof(name))
163 goto out_err;
164
165 err = -ENOMEM;
166 if (!debugfs_create_symlink("xprt", clnt->cl_debugfs, name))
167 goto out_err;
168
169 return 0;
170out_err:
171 debugfs_remove_recursive(clnt->cl_debugfs);
172 clnt->cl_debugfs = NULL;
173 return err;
174}
175
176void
177rpc_clnt_debugfs_unregister(struct rpc_clnt *clnt)
178{
179 debugfs_remove_recursive(clnt->cl_debugfs);
180 clnt->cl_debugfs = NULL;
181}
182
183static int
184xprt_info_show(struct seq_file *f, void *v)
185{
186 struct rpc_xprt *xprt = f->private;
187
188 seq_printf(f, "netid: %s\n", xprt->address_strings[RPC_DISPLAY_NETID]);
189 seq_printf(f, "addr: %s\n", xprt->address_strings[RPC_DISPLAY_ADDR]);
190 seq_printf(f, "port: %s\n", xprt->address_strings[RPC_DISPLAY_PORT]);
191 seq_printf(f, "state: 0x%lx\n", xprt->state);
192 return 0;
193}
194
195static int
196xprt_info_open(struct inode *inode, struct file *filp)
197{
198 int ret;
199 struct rpc_xprt *xprt = inode->i_private;
200
201 ret = single_open(filp, xprt_info_show, xprt);
202
203 if (!ret) {
204 if (!xprt_get(xprt)) {
205 single_release(inode, filp);
206 ret = -EINVAL;
207 }
208 }
209 return ret;
210}
211
212static int
213xprt_info_release(struct inode *inode, struct file *filp)
214{
215 struct rpc_xprt *xprt = inode->i_private;
216
217 xprt_put(xprt);
218 return single_release(inode, filp);
219}
220
221static const struct file_operations xprt_info_fops = {
222 .owner = THIS_MODULE,
223 .open = xprt_info_open,
224 .read = seq_read,
225 .llseek = seq_lseek,
226 .release = xprt_info_release,
227};
228
229int
230rpc_xprt_debugfs_register(struct rpc_xprt *xprt)
231{
232 int len, id;
233 static atomic_t cur_id;
234 char name[9]; /* 8 hex digits + NULL term */
235
236 id = (unsigned int)atomic_inc_return(&cur_id);
237
238 len = snprintf(name, sizeof(name), "%x", id);
239 if (len >= sizeof(name))
240 return -EINVAL;
241
242 /* make the per-client dir */
243 xprt->debugfs = debugfs_create_dir(name, rpc_xprt_dir);
244 if (!xprt->debugfs)
245 return -ENOMEM;
246
247 /* make tasks file */
248 if (!debugfs_create_file("info", S_IFREG | S_IRUSR, xprt->debugfs,
249 xprt, &xprt_info_fops)) {
250 debugfs_remove_recursive(xprt->debugfs);
251 xprt->debugfs = NULL;
252 return -ENOMEM;
253 }
254
255 return 0;
256}
257
258void
259rpc_xprt_debugfs_unregister(struct rpc_xprt *xprt)
260{
261 debugfs_remove_recursive(xprt->debugfs);
262 xprt->debugfs = NULL;
263}
264
265void __exit
266sunrpc_debugfs_exit(void)
267{
268 debugfs_remove_recursive(topdir);
269}
270
271int __init
272sunrpc_debugfs_init(void)
273{
274 topdir = debugfs_create_dir("sunrpc", NULL);
275 if (!topdir)
276 goto out;
277
278 rpc_clnt_dir = debugfs_create_dir("rpc_clnt", topdir);
279 if (!rpc_clnt_dir)
280 goto out_remove;
281
282 rpc_xprt_dir = debugfs_create_dir("rpc_xprt", topdir);
283 if (!rpc_xprt_dir)
284 goto out_remove;
285
286 return 0;
287out_remove:
288 debugfs_remove_recursive(topdir);
289 topdir = NULL;
290out:
291 return -ENOMEM;
292}
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 1891a1022c17..05202012bcfc 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -32,7 +32,7 @@
32 32
33#include "netns.h" 33#include "netns.h"
34 34
35#ifdef RPC_DEBUG 35#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
36# define RPCDBG_FACILITY RPCDBG_BIND 36# define RPCDBG_FACILITY RPCDBG_BIND
37#endif 37#endif
38 38
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index fe3441abdbe5..d20f2329eea3 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -24,7 +24,7 @@
24 24
25#include "sunrpc.h" 25#include "sunrpc.h"
26 26
27#ifdef RPC_DEBUG 27#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
28#define RPCDBG_FACILITY RPCDBG_SCHED 28#define RPCDBG_FACILITY RPCDBG_SCHED
29#endif 29#endif
30 30
@@ -258,7 +258,7 @@ static int rpc_wait_bit_killable(struct wait_bit_key *key)
258 return 0; 258 return 0;
259} 259}
260 260
261#if defined(RPC_DEBUG) || defined(RPC_TRACEPOINTS) 261#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || IS_ENABLED(CONFIG_TRACEPOINTS)
262static void rpc_task_set_debuginfo(struct rpc_task *task) 262static void rpc_task_set_debuginfo(struct rpc_task *task)
263{ 263{
264 static atomic_t rpc_pid; 264 static atomic_t rpc_pid;
diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c
index 54530490944e..9711a155bc50 100644
--- a/net/sunrpc/stats.c
+++ b/net/sunrpc/stats.c
@@ -116,7 +116,15 @@ EXPORT_SYMBOL_GPL(svc_seq_show);
116 */ 116 */
117struct rpc_iostats *rpc_alloc_iostats(struct rpc_clnt *clnt) 117struct rpc_iostats *rpc_alloc_iostats(struct rpc_clnt *clnt)
118{ 118{
119 return kcalloc(clnt->cl_maxproc, sizeof(struct rpc_iostats), GFP_KERNEL); 119 struct rpc_iostats *stats;
120 int i;
121
122 stats = kcalloc(clnt->cl_maxproc, sizeof(*stats), GFP_KERNEL);
123 if (stats) {
124 for (i = 0; i < clnt->cl_maxproc; i++)
125 spin_lock_init(&stats[i].om_lock);
126 }
127 return stats;
120} 128}
121EXPORT_SYMBOL_GPL(rpc_alloc_iostats); 129EXPORT_SYMBOL_GPL(rpc_alloc_iostats);
122 130
@@ -135,20 +143,21 @@ EXPORT_SYMBOL_GPL(rpc_free_iostats);
135 * rpc_count_iostats - tally up per-task stats 143 * rpc_count_iostats - tally up per-task stats
136 * @task: completed rpc_task 144 * @task: completed rpc_task
137 * @stats: array of stat structures 145 * @stats: array of stat structures
138 *
139 * Relies on the caller for serialization.
140 */ 146 */
141void rpc_count_iostats(const struct rpc_task *task, struct rpc_iostats *stats) 147void rpc_count_iostats(const struct rpc_task *task, struct rpc_iostats *stats)
142{ 148{
143 struct rpc_rqst *req = task->tk_rqstp; 149 struct rpc_rqst *req = task->tk_rqstp;
144 struct rpc_iostats *op_metrics; 150 struct rpc_iostats *op_metrics;
145 ktime_t delta; 151 ktime_t delta, now;
146 152
147 if (!stats || !req) 153 if (!stats || !req)
148 return; 154 return;
149 155
156 now = ktime_get();
150 op_metrics = &stats[task->tk_msg.rpc_proc->p_statidx]; 157 op_metrics = &stats[task->tk_msg.rpc_proc->p_statidx];
151 158
159 spin_lock(&op_metrics->om_lock);
160
152 op_metrics->om_ops++; 161 op_metrics->om_ops++;
153 op_metrics->om_ntrans += req->rq_ntrans; 162 op_metrics->om_ntrans += req->rq_ntrans;
154 op_metrics->om_timeouts += task->tk_timeouts; 163 op_metrics->om_timeouts += task->tk_timeouts;
@@ -161,8 +170,10 @@ void rpc_count_iostats(const struct rpc_task *task, struct rpc_iostats *stats)
161 170
162 op_metrics->om_rtt = ktime_add(op_metrics->om_rtt, req->rq_rtt); 171 op_metrics->om_rtt = ktime_add(op_metrics->om_rtt, req->rq_rtt);
163 172
164 delta = ktime_sub(ktime_get(), task->tk_start); 173 delta = ktime_sub(now, task->tk_start);
165 op_metrics->om_execute = ktime_add(op_metrics->om_execute, delta); 174 op_metrics->om_execute = ktime_add(op_metrics->om_execute, delta);
175
176 spin_unlock(&op_metrics->om_lock);
166} 177}
167EXPORT_SYMBOL_GPL(rpc_count_iostats); 178EXPORT_SYMBOL_GPL(rpc_count_iostats);
168 179
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index cd30120de9e4..e37fbed87956 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -97,13 +97,20 @@ init_sunrpc(void)
97 err = register_rpc_pipefs(); 97 err = register_rpc_pipefs();
98 if (err) 98 if (err)
99 goto out4; 99 goto out4;
100#ifdef RPC_DEBUG 100
101 err = sunrpc_debugfs_init();
102 if (err)
103 goto out5;
104
105#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
101 rpc_register_sysctl(); 106 rpc_register_sysctl();
102#endif 107#endif
103 svc_init_xprt_sock(); /* svc sock transport */ 108 svc_init_xprt_sock(); /* svc sock transport */
104 init_socket_xprt(); /* clnt sock transport */ 109 init_socket_xprt(); /* clnt sock transport */
105 return 0; 110 return 0;
106 111
112out5:
113 unregister_rpc_pipefs();
107out4: 114out4:
108 unregister_pernet_subsys(&sunrpc_net_ops); 115 unregister_pernet_subsys(&sunrpc_net_ops);
109out3: 116out3:
@@ -120,10 +127,11 @@ cleanup_sunrpc(void)
120 rpcauth_remove_module(); 127 rpcauth_remove_module();
121 cleanup_socket_xprt(); 128 cleanup_socket_xprt();
122 svc_cleanup_xprt_sock(); 129 svc_cleanup_xprt_sock();
130 sunrpc_debugfs_exit();
123 unregister_rpc_pipefs(); 131 unregister_rpc_pipefs();
124 rpc_destroy_mempool(); 132 rpc_destroy_mempool();
125 unregister_pernet_subsys(&sunrpc_net_ops); 133 unregister_pernet_subsys(&sunrpc_net_ops);
126#ifdef RPC_DEBUG 134#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
127 rpc_unregister_sysctl(); 135 rpc_unregister_sysctl();
128#endif 136#endif
129 rcu_barrier(); /* Wait for completion of call_rcu()'s */ 137 rcu_barrier(); /* Wait for completion of call_rcu()'s */
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index ca8a7958f4e6..2783fd80c229 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -28,6 +28,8 @@
28#include <linux/sunrpc/clnt.h> 28#include <linux/sunrpc/clnt.h>
29#include <linux/sunrpc/bc_xprt.h> 29#include <linux/sunrpc/bc_xprt.h>
30 30
31#include <trace/events/sunrpc.h>
32
31#define RPCDBG_FACILITY RPCDBG_SVCDSP 33#define RPCDBG_FACILITY RPCDBG_SVCDSP
32 34
33static void svc_unregister(const struct svc_serv *serv, struct net *net); 35static void svc_unregister(const struct svc_serv *serv, struct net *net);
@@ -1040,7 +1042,7 @@ static void svc_unregister(const struct svc_serv *serv, struct net *net)
1040/* 1042/*
1041 * dprintk the given error with the address of the client that caused it. 1043 * dprintk the given error with the address of the client that caused it.
1042 */ 1044 */
1043#ifdef RPC_DEBUG 1045#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
1044static __printf(2, 3) 1046static __printf(2, 3)
1045void svc_printk(struct svc_rqst *rqstp, const char *fmt, ...) 1047void svc_printk(struct svc_rqst *rqstp, const char *fmt, ...)
1046{ 1048{
@@ -1314,24 +1316,25 @@ svc_process(struct svc_rqst *rqstp)
1314 rqstp->rq_res.tail[0].iov_base = NULL; 1316 rqstp->rq_res.tail[0].iov_base = NULL;
1315 rqstp->rq_res.tail[0].iov_len = 0; 1317 rqstp->rq_res.tail[0].iov_len = 0;
1316 1318
1317 rqstp->rq_xid = svc_getu32(argv);
1318
1319 dir = svc_getnl(argv); 1319 dir = svc_getnl(argv);
1320 if (dir != 0) { 1320 if (dir != 0) {
1321 /* direction != CALL */ 1321 /* direction != CALL */
1322 svc_printk(rqstp, "bad direction %d, dropping request\n", dir); 1322 svc_printk(rqstp, "bad direction %d, dropping request\n", dir);
1323 serv->sv_stats->rpcbadfmt++; 1323 serv->sv_stats->rpcbadfmt++;
1324 svc_drop(rqstp); 1324 goto out_drop;
1325 return 0;
1326 } 1325 }
1327 1326
1328 /* Returns 1 for send, 0 for drop */ 1327 /* Returns 1 for send, 0 for drop */
1329 if (svc_process_common(rqstp, argv, resv)) 1328 if (likely(svc_process_common(rqstp, argv, resv))) {
1330 return svc_send(rqstp); 1329 int ret = svc_send(rqstp);
1331 else { 1330
1332 svc_drop(rqstp); 1331 trace_svc_process(rqstp, ret);
1333 return 0; 1332 return ret;
1334 } 1333 }
1334out_drop:
1335 trace_svc_process(rqstp, 0);
1336 svc_drop(rqstp);
1337 return 0;
1335} 1338}
1336 1339
1337#if defined(CONFIG_SUNRPC_BACKCHANNEL) 1340#if defined(CONFIG_SUNRPC_BACKCHANNEL)
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index c179ca2a5aa4..bbb3b044b877 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -15,6 +15,7 @@
15#include <linux/sunrpc/svcsock.h> 15#include <linux/sunrpc/svcsock.h>
16#include <linux/sunrpc/xprt.h> 16#include <linux/sunrpc/xprt.h>
17#include <linux/module.h> 17#include <linux/module.h>
18#include <trace/events/sunrpc.h>
18 19
19#define RPCDBG_FACILITY RPCDBG_SVCXPRT 20#define RPCDBG_FACILITY RPCDBG_SVCXPRT
20 21
@@ -773,35 +774,43 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
773 774
774 err = svc_alloc_arg(rqstp); 775 err = svc_alloc_arg(rqstp);
775 if (err) 776 if (err)
776 return err; 777 goto out;
777 778
778 try_to_freeze(); 779 try_to_freeze();
779 cond_resched(); 780 cond_resched();
781 err = -EINTR;
780 if (signalled() || kthread_should_stop()) 782 if (signalled() || kthread_should_stop())
781 return -EINTR; 783 goto out;
782 784
783 xprt = svc_get_next_xprt(rqstp, timeout); 785 xprt = svc_get_next_xprt(rqstp, timeout);
784 if (IS_ERR(xprt)) 786 if (IS_ERR(xprt)) {
785 return PTR_ERR(xprt); 787 err = PTR_ERR(xprt);
788 goto out;
789 }
786 790
787 len = svc_handle_xprt(rqstp, xprt); 791 len = svc_handle_xprt(rqstp, xprt);
788 792
789 /* No data, incomplete (TCP) read, or accept() */ 793 /* No data, incomplete (TCP) read, or accept() */
794 err = -EAGAIN;
790 if (len <= 0) 795 if (len <= 0)
791 goto out; 796 goto out_release;
792 797
793 clear_bit(XPT_OLD, &xprt->xpt_flags); 798 clear_bit(XPT_OLD, &xprt->xpt_flags);
794 799
795 rqstp->rq_secure = xprt->xpt_ops->xpo_secure_port(rqstp); 800 rqstp->rq_secure = xprt->xpt_ops->xpo_secure_port(rqstp);
796 rqstp->rq_chandle.defer = svc_defer; 801 rqstp->rq_chandle.defer = svc_defer;
802 rqstp->rq_xid = svc_getu32(&rqstp->rq_arg.head[0]);
797 803
798 if (serv->sv_stats) 804 if (serv->sv_stats)
799 serv->sv_stats->netcnt++; 805 serv->sv_stats->netcnt++;
806 trace_svc_recv(rqstp, len);
800 return len; 807 return len;
801out: 808out_release:
802 rqstp->rq_res.len = 0; 809 rqstp->rq_res.len = 0;
803 svc_xprt_release(rqstp); 810 svc_xprt_release(rqstp);
804 return -EAGAIN; 811out:
812 trace_svc_recv(rqstp, err);
813 return err;
805} 814}
806EXPORT_SYMBOL_GPL(svc_recv); 815EXPORT_SYMBOL_GPL(svc_recv);
807 816
@@ -821,12 +830,12 @@ EXPORT_SYMBOL_GPL(svc_drop);
821int svc_send(struct svc_rqst *rqstp) 830int svc_send(struct svc_rqst *rqstp)
822{ 831{
823 struct svc_xprt *xprt; 832 struct svc_xprt *xprt;
824 int len; 833 int len = -EFAULT;
825 struct xdr_buf *xb; 834 struct xdr_buf *xb;
826 835
827 xprt = rqstp->rq_xprt; 836 xprt = rqstp->rq_xprt;
828 if (!xprt) 837 if (!xprt)
829 return -EFAULT; 838 goto out;
830 839
831 /* release the receive skb before sending the reply */ 840 /* release the receive skb before sending the reply */
832 rqstp->rq_xprt->xpt_ops->xpo_release_rqst(rqstp); 841 rqstp->rq_xprt->xpt_ops->xpo_release_rqst(rqstp);
@@ -849,7 +858,9 @@ int svc_send(struct svc_rqst *rqstp)
849 svc_xprt_release(rqstp); 858 svc_xprt_release(rqstp);
850 859
851 if (len == -ECONNREFUSED || len == -ENOTCONN || len == -EAGAIN) 860 if (len == -ECONNREFUSED || len == -ENOTCONN || len == -EAGAIN)
852 return 0; 861 len = 0;
862out:
863 trace_svc_send(rqstp, len);
853 return len; 864 return len;
854} 865}
855 866
diff --git a/net/sunrpc/sysctl.c b/net/sunrpc/sysctl.c
index c99c58e2ee66..887f0183b4c6 100644
--- a/net/sunrpc/sysctl.c
+++ b/net/sunrpc/sysctl.c
@@ -37,7 +37,7 @@ EXPORT_SYMBOL_GPL(nfsd_debug);
37unsigned int nlm_debug; 37unsigned int nlm_debug;
38EXPORT_SYMBOL_GPL(nlm_debug); 38EXPORT_SYMBOL_GPL(nlm_debug);
39 39
40#ifdef RPC_DEBUG 40#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
41 41
42static struct ctl_table_header *sunrpc_table_header; 42static struct ctl_table_header *sunrpc_table_header;
43static struct ctl_table sunrpc_table[]; 43static struct ctl_table sunrpc_table[];
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 56e4e150e80e..ebbefad21a37 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -49,13 +49,15 @@
49#include <linux/sunrpc/metrics.h> 49#include <linux/sunrpc/metrics.h>
50#include <linux/sunrpc/bc_xprt.h> 50#include <linux/sunrpc/bc_xprt.h>
51 51
52#include <trace/events/sunrpc.h>
53
52#include "sunrpc.h" 54#include "sunrpc.h"
53 55
54/* 56/*
55 * Local variables 57 * Local variables
56 */ 58 */
57 59
58#ifdef RPC_DEBUG 60#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
59# define RPCDBG_FACILITY RPCDBG_XPRT 61# define RPCDBG_FACILITY RPCDBG_XPRT
60#endif 62#endif
61 63
@@ -772,11 +774,14 @@ struct rpc_rqst *xprt_lookup_rqst(struct rpc_xprt *xprt, __be32 xid)
772 struct rpc_rqst *entry; 774 struct rpc_rqst *entry;
773 775
774 list_for_each_entry(entry, &xprt->recv, rq_list) 776 list_for_each_entry(entry, &xprt->recv, rq_list)
775 if (entry->rq_xid == xid) 777 if (entry->rq_xid == xid) {
778 trace_xprt_lookup_rqst(xprt, xid, 0);
776 return entry; 779 return entry;
780 }
777 781
778 dprintk("RPC: xprt_lookup_rqst did not find xid %08x\n", 782 dprintk("RPC: xprt_lookup_rqst did not find xid %08x\n",
779 ntohl(xid)); 783 ntohl(xid));
784 trace_xprt_lookup_rqst(xprt, xid, -ENOENT);
780 xprt->stat.bad_xids++; 785 xprt->stat.bad_xids++;
781 return NULL; 786 return NULL;
782} 787}
@@ -810,6 +815,7 @@ void xprt_complete_rqst(struct rpc_task *task, int copied)
810 815
811 dprintk("RPC: %5u xid %08x complete (%d bytes received)\n", 816 dprintk("RPC: %5u xid %08x complete (%d bytes received)\n",
812 task->tk_pid, ntohl(req->rq_xid), copied); 817 task->tk_pid, ntohl(req->rq_xid), copied);
818 trace_xprt_complete_rqst(xprt, req->rq_xid, copied);
813 819
814 xprt->stat.recvs++; 820 xprt->stat.recvs++;
815 req->rq_rtt = ktime_sub(ktime_get(), req->rq_xtime); 821 req->rq_rtt = ktime_sub(ktime_get(), req->rq_xtime);
@@ -926,6 +932,7 @@ void xprt_transmit(struct rpc_task *task)
926 932
927 req->rq_xtime = ktime_get(); 933 req->rq_xtime = ktime_get();
928 status = xprt->ops->send_request(task); 934 status = xprt->ops->send_request(task);
935 trace_xprt_transmit(xprt, req->rq_xid, status);
929 if (status != 0) { 936 if (status != 0) {
930 task->tk_status = status; 937 task->tk_status = status;
931 return; 938 return;
@@ -1296,6 +1303,7 @@ static void xprt_init(struct rpc_xprt *xprt, struct net *net)
1296 */ 1303 */
1297struct rpc_xprt *xprt_create_transport(struct xprt_create *args) 1304struct rpc_xprt *xprt_create_transport(struct xprt_create *args)
1298{ 1305{
1306 int err;
1299 struct rpc_xprt *xprt; 1307 struct rpc_xprt *xprt;
1300 struct xprt_class *t; 1308 struct xprt_class *t;
1301 1309
@@ -1336,6 +1344,12 @@ found:
1336 return ERR_PTR(-ENOMEM); 1344 return ERR_PTR(-ENOMEM);
1337 } 1345 }
1338 1346
1347 err = rpc_xprt_debugfs_register(xprt);
1348 if (err) {
1349 xprt_destroy(xprt);
1350 return ERR_PTR(err);
1351 }
1352
1339 dprintk("RPC: created transport %p with %u slots\n", xprt, 1353 dprintk("RPC: created transport %p with %u slots\n", xprt,
1340 xprt->max_reqs); 1354 xprt->max_reqs);
1341out: 1355out:
@@ -1352,6 +1366,7 @@ static void xprt_destroy(struct rpc_xprt *xprt)
1352 dprintk("RPC: destroying transport %p\n", xprt); 1366 dprintk("RPC: destroying transport %p\n", xprt);
1353 del_timer_sync(&xprt->timer); 1367 del_timer_sync(&xprt->timer);
1354 1368
1369 rpc_xprt_debugfs_unregister(xprt);
1355 rpc_destroy_wait_queue(&xprt->binding); 1370 rpc_destroy_wait_queue(&xprt->binding);
1356 rpc_destroy_wait_queue(&xprt->pending); 1371 rpc_destroy_wait_queue(&xprt->pending);
1357 rpc_destroy_wait_queue(&xprt->sending); 1372 rpc_destroy_wait_queue(&xprt->sending);
diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c
index 6166c985fe24..df01d124936c 100644
--- a/net/sunrpc/xprtrdma/rpc_rdma.c
+++ b/net/sunrpc/xprtrdma/rpc_rdma.c
@@ -49,11 +49,11 @@
49 49
50#include <linux/highmem.h> 50#include <linux/highmem.h>
51 51
52#ifdef RPC_DEBUG 52#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
53# define RPCDBG_FACILITY RPCDBG_TRANS 53# define RPCDBG_FACILITY RPCDBG_TRANS
54#endif 54#endif
55 55
56#ifdef RPC_DEBUG 56#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
57static const char transfertypes[][12] = { 57static const char transfertypes[][12] = {
58 "pure inline", /* no chunks */ 58 "pure inline", /* no chunks */
59 " read chunk", /* some argument via rdma read */ 59 " read chunk", /* some argument via rdma read */
diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c
index 6a4615dd0261..bbd6155d3e34 100644
--- a/net/sunrpc/xprtrdma/transport.c
+++ b/net/sunrpc/xprtrdma/transport.c
@@ -55,7 +55,7 @@
55 55
56#include "xprt_rdma.h" 56#include "xprt_rdma.h"
57 57
58#ifdef RPC_DEBUG 58#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
59# define RPCDBG_FACILITY RPCDBG_TRANS 59# define RPCDBG_FACILITY RPCDBG_TRANS
60#endif 60#endif
61 61
@@ -73,9 +73,9 @@ static unsigned int xprt_rdma_max_inline_read = RPCRDMA_DEF_INLINE;
73static unsigned int xprt_rdma_max_inline_write = RPCRDMA_DEF_INLINE; 73static unsigned int xprt_rdma_max_inline_write = RPCRDMA_DEF_INLINE;
74static unsigned int xprt_rdma_inline_write_padding; 74static unsigned int xprt_rdma_inline_write_padding;
75static unsigned int xprt_rdma_memreg_strategy = RPCRDMA_FRMR; 75static unsigned int xprt_rdma_memreg_strategy = RPCRDMA_FRMR;
76 int xprt_rdma_pad_optimize = 0; 76 int xprt_rdma_pad_optimize = 1;
77 77
78#ifdef RPC_DEBUG 78#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
79 79
80static unsigned int min_slot_table_size = RPCRDMA_MIN_SLOT_TABLE; 80static unsigned int min_slot_table_size = RPCRDMA_MIN_SLOT_TABLE;
81static unsigned int max_slot_table_size = RPCRDMA_MAX_SLOT_TABLE; 81static unsigned int max_slot_table_size = RPCRDMA_MAX_SLOT_TABLE;
@@ -599,7 +599,7 @@ xprt_rdma_send_request(struct rpc_task *task)
599 599
600 if (req->rl_niovs == 0) 600 if (req->rl_niovs == 0)
601 rc = rpcrdma_marshal_req(rqst); 601 rc = rpcrdma_marshal_req(rqst);
602 else if (r_xprt->rx_ia.ri_memreg_strategy == RPCRDMA_FRMR) 602 else if (r_xprt->rx_ia.ri_memreg_strategy != RPCRDMA_ALLPHYSICAL)
603 rc = rpcrdma_marshal_chunks(rqst, 0); 603 rc = rpcrdma_marshal_chunks(rqst, 0);
604 if (rc < 0) 604 if (rc < 0)
605 goto failed_marshal; 605 goto failed_marshal;
@@ -705,7 +705,7 @@ static void __exit xprt_rdma_cleanup(void)
705 int rc; 705 int rc;
706 706
707 dprintk("RPCRDMA Module Removed, deregister RPC RDMA transport\n"); 707 dprintk("RPCRDMA Module Removed, deregister RPC RDMA transport\n");
708#ifdef RPC_DEBUG 708#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
709 if (sunrpc_table_header) { 709 if (sunrpc_table_header) {
710 unregister_sysctl_table(sunrpc_table_header); 710 unregister_sysctl_table(sunrpc_table_header);
711 sunrpc_table_header = NULL; 711 sunrpc_table_header = NULL;
@@ -736,7 +736,7 @@ static int __init xprt_rdma_init(void)
736 dprintk("\tPadding %d\n\tMemreg %d\n", 736 dprintk("\tPadding %d\n\tMemreg %d\n",
737 xprt_rdma_inline_write_padding, xprt_rdma_memreg_strategy); 737 xprt_rdma_inline_write_padding, xprt_rdma_memreg_strategy);
738 738
739#ifdef RPC_DEBUG 739#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
740 if (!sunrpc_table_header) 740 if (!sunrpc_table_header)
741 sunrpc_table_header = register_sysctl_table(sunrpc_table); 741 sunrpc_table_header = register_sysctl_table(sunrpc_table);
742#endif 742#endif
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c
index 61c41298b4ea..c98e40643910 100644
--- a/net/sunrpc/xprtrdma/verbs.c
+++ b/net/sunrpc/xprtrdma/verbs.c
@@ -57,11 +57,12 @@
57 * Globals/Macros 57 * Globals/Macros
58 */ 58 */
59 59
60#ifdef RPC_DEBUG 60#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
61# define RPCDBG_FACILITY RPCDBG_TRANS 61# define RPCDBG_FACILITY RPCDBG_TRANS
62#endif 62#endif
63 63
64static void rpcrdma_reset_frmrs(struct rpcrdma_ia *); 64static void rpcrdma_reset_frmrs(struct rpcrdma_ia *);
65static void rpcrdma_reset_fmrs(struct rpcrdma_ia *);
65 66
66/* 67/*
67 * internal functions 68 * internal functions
@@ -105,13 +106,51 @@ rpcrdma_run_tasklet(unsigned long data)
105 106
106static DECLARE_TASKLET(rpcrdma_tasklet_g, rpcrdma_run_tasklet, 0UL); 107static DECLARE_TASKLET(rpcrdma_tasklet_g, rpcrdma_run_tasklet, 0UL);
107 108
109static const char * const async_event[] = {
110 "CQ error",
111 "QP fatal error",
112 "QP request error",
113 "QP access error",
114 "communication established",
115 "send queue drained",
116 "path migration successful",
117 "path mig error",
118 "device fatal error",
119 "port active",
120 "port error",
121 "LID change",
122 "P_key change",
123 "SM change",
124 "SRQ error",
125 "SRQ limit reached",
126 "last WQE reached",
127 "client reregister",
128 "GID change",
129};
130
131#define ASYNC_MSG(status) \
132 ((status) < ARRAY_SIZE(async_event) ? \
133 async_event[(status)] : "unknown async error")
134
135static void
136rpcrdma_schedule_tasklet(struct list_head *sched_list)
137{
138 unsigned long flags;
139
140 spin_lock_irqsave(&rpcrdma_tk_lock_g, flags);
141 list_splice_tail(sched_list, &rpcrdma_tasklets_g);
142 spin_unlock_irqrestore(&rpcrdma_tk_lock_g, flags);
143 tasklet_schedule(&rpcrdma_tasklet_g);
144}
145
108static void 146static void
109rpcrdma_qp_async_error_upcall(struct ib_event *event, void *context) 147rpcrdma_qp_async_error_upcall(struct ib_event *event, void *context)
110{ 148{
111 struct rpcrdma_ep *ep = context; 149 struct rpcrdma_ep *ep = context;
112 150
113 dprintk("RPC: %s: QP error %X on device %s ep %p\n", 151 pr_err("RPC: %s: %s on device %s ep %p\n",
114 __func__, event->event, event->device->name, context); 152 __func__, ASYNC_MSG(event->event),
153 event->device->name, context);
115 if (ep->rep_connected == 1) { 154 if (ep->rep_connected == 1) {
116 ep->rep_connected = -EIO; 155 ep->rep_connected = -EIO;
117 ep->rep_func(ep); 156 ep->rep_func(ep);
@@ -124,8 +163,9 @@ rpcrdma_cq_async_error_upcall(struct ib_event *event, void *context)
124{ 163{
125 struct rpcrdma_ep *ep = context; 164 struct rpcrdma_ep *ep = context;
126 165
127 dprintk("RPC: %s: CQ error %X on device %s ep %p\n", 166 pr_err("RPC: %s: %s on device %s ep %p\n",
128 __func__, event->event, event->device->name, context); 167 __func__, ASYNC_MSG(event->event),
168 event->device->name, context);
129 if (ep->rep_connected == 1) { 169 if (ep->rep_connected == 1) {
130 ep->rep_connected = -EIO; 170 ep->rep_connected = -EIO;
131 ep->rep_func(ep); 171 ep->rep_func(ep);
@@ -243,7 +283,6 @@ rpcrdma_recvcq_poll(struct ib_cq *cq, struct rpcrdma_ep *ep)
243 struct list_head sched_list; 283 struct list_head sched_list;
244 struct ib_wc *wcs; 284 struct ib_wc *wcs;
245 int budget, count, rc; 285 int budget, count, rc;
246 unsigned long flags;
247 286
248 INIT_LIST_HEAD(&sched_list); 287 INIT_LIST_HEAD(&sched_list);
249 budget = RPCRDMA_WC_BUDGET / RPCRDMA_POLLSIZE; 288 budget = RPCRDMA_WC_BUDGET / RPCRDMA_POLLSIZE;
@@ -261,10 +300,7 @@ rpcrdma_recvcq_poll(struct ib_cq *cq, struct rpcrdma_ep *ep)
261 rc = 0; 300 rc = 0;
262 301
263out_schedule: 302out_schedule:
264 spin_lock_irqsave(&rpcrdma_tk_lock_g, flags); 303 rpcrdma_schedule_tasklet(&sched_list);
265 list_splice_tail(&sched_list, &rpcrdma_tasklets_g);
266 spin_unlock_irqrestore(&rpcrdma_tk_lock_g, flags);
267 tasklet_schedule(&rpcrdma_tasklet_g);
268 return rc; 304 return rc;
269} 305}
270 306
@@ -309,11 +345,18 @@ rpcrdma_recvcq_upcall(struct ib_cq *cq, void *cq_context)
309static void 345static void
310rpcrdma_flush_cqs(struct rpcrdma_ep *ep) 346rpcrdma_flush_cqs(struct rpcrdma_ep *ep)
311{ 347{
312 rpcrdma_recvcq_upcall(ep->rep_attr.recv_cq, ep); 348 struct ib_wc wc;
313 rpcrdma_sendcq_upcall(ep->rep_attr.send_cq, ep); 349 LIST_HEAD(sched_list);
350
351 while (ib_poll_cq(ep->rep_attr.recv_cq, 1, &wc) > 0)
352 rpcrdma_recvcq_process_wc(&wc, &sched_list);
353 if (!list_empty(&sched_list))
354 rpcrdma_schedule_tasklet(&sched_list);
355 while (ib_poll_cq(ep->rep_attr.send_cq, 1, &wc) > 0)
356 rpcrdma_sendcq_process_wc(&wc);
314} 357}
315 358
316#ifdef RPC_DEBUG 359#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
317static const char * const conn[] = { 360static const char * const conn[] = {
318 "address resolved", 361 "address resolved",
319 "address error", 362 "address error",
@@ -344,7 +387,7 @@ rpcrdma_conn_upcall(struct rdma_cm_id *id, struct rdma_cm_event *event)
344 struct rpcrdma_xprt *xprt = id->context; 387 struct rpcrdma_xprt *xprt = id->context;
345 struct rpcrdma_ia *ia = &xprt->rx_ia; 388 struct rpcrdma_ia *ia = &xprt->rx_ia;
346 struct rpcrdma_ep *ep = &xprt->rx_ep; 389 struct rpcrdma_ep *ep = &xprt->rx_ep;
347#ifdef RPC_DEBUG 390#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
348 struct sockaddr_in *addr = (struct sockaddr_in *) &ep->rep_remote_addr; 391 struct sockaddr_in *addr = (struct sockaddr_in *) &ep->rep_remote_addr;
349#endif 392#endif
350 struct ib_qp_attr attr; 393 struct ib_qp_attr attr;
@@ -408,7 +451,7 @@ connected:
408 break; 451 break;
409 } 452 }
410 453
411#ifdef RPC_DEBUG 454#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
412 if (connstate == 1) { 455 if (connstate == 1) {
413 int ird = attr.max_dest_rd_atomic; 456 int ird = attr.max_dest_rd_atomic;
414 int tird = ep->rep_remote_cma.responder_resources; 457 int tird = ep->rep_remote_cma.responder_resources;
@@ -733,7 +776,9 @@ rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia,
733 776
734 /* set trigger for requesting send completion */ 777 /* set trigger for requesting send completion */
735 ep->rep_cqinit = ep->rep_attr.cap.max_send_wr/2 - 1; 778 ep->rep_cqinit = ep->rep_attr.cap.max_send_wr/2 - 1;
736 if (ep->rep_cqinit <= 2) 779 if (ep->rep_cqinit > RPCRDMA_MAX_UNSIGNALED_SENDS)
780 ep->rep_cqinit = RPCRDMA_MAX_UNSIGNALED_SENDS;
781 else if (ep->rep_cqinit <= 2)
737 ep->rep_cqinit = 0; 782 ep->rep_cqinit = 0;
738 INIT_CQCOUNT(ep); 783 INIT_CQCOUNT(ep);
739 ep->rep_ia = ia; 784 ep->rep_ia = ia;
@@ -866,8 +911,19 @@ retry:
866 rpcrdma_ep_disconnect(ep, ia); 911 rpcrdma_ep_disconnect(ep, ia);
867 rpcrdma_flush_cqs(ep); 912 rpcrdma_flush_cqs(ep);
868 913
869 if (ia->ri_memreg_strategy == RPCRDMA_FRMR) 914 switch (ia->ri_memreg_strategy) {
915 case RPCRDMA_FRMR:
870 rpcrdma_reset_frmrs(ia); 916 rpcrdma_reset_frmrs(ia);
917 break;
918 case RPCRDMA_MTHCAFMR:
919 rpcrdma_reset_fmrs(ia);
920 break;
921 case RPCRDMA_ALLPHYSICAL:
922 break;
923 default:
924 rc = -EIO;
925 goto out;
926 }
871 927
872 xprt = container_of(ia, struct rpcrdma_xprt, rx_ia); 928 xprt = container_of(ia, struct rpcrdma_xprt, rx_ia);
873 id = rpcrdma_create_id(xprt, ia, 929 id = rpcrdma_create_id(xprt, ia,
@@ -1287,6 +1343,34 @@ rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf)
1287 kfree(buf->rb_pool); 1343 kfree(buf->rb_pool);
1288} 1344}
1289 1345
1346/* After a disconnect, unmap all FMRs.
1347 *
1348 * This is invoked only in the transport connect worker in order
1349 * to serialize with rpcrdma_register_fmr_external().
1350 */
1351static void
1352rpcrdma_reset_fmrs(struct rpcrdma_ia *ia)
1353{
1354 struct rpcrdma_xprt *r_xprt =
1355 container_of(ia, struct rpcrdma_xprt, rx_ia);
1356 struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
1357 struct list_head *pos;
1358 struct rpcrdma_mw *r;
1359 LIST_HEAD(l);
1360 int rc;
1361
1362 list_for_each(pos, &buf->rb_all) {
1363 r = list_entry(pos, struct rpcrdma_mw, mw_all);
1364
1365 INIT_LIST_HEAD(&l);
1366 list_add(&r->r.fmr->list, &l);
1367 rc = ib_unmap_fmr(&l);
1368 if (rc)
1369 dprintk("RPC: %s: ib_unmap_fmr failed %i\n",
1370 __func__, rc);
1371 }
1372}
1373
1290/* After a disconnect, a flushed FAST_REG_MR can leave an FRMR in 1374/* After a disconnect, a flushed FAST_REG_MR can leave an FRMR in
1291 * an unusable state. Find FRMRs in this state and dereg / reg 1375 * an unusable state. Find FRMRs in this state and dereg / reg
1292 * each. FRMRs that are VALID and attached to an rpcrdma_req are 1376 * each. FRMRs that are VALID and attached to an rpcrdma_req are
@@ -1918,10 +2002,10 @@ rpcrdma_register_external(struct rpcrdma_mr_seg *seg,
1918 break; 2002 break;
1919 2003
1920 default: 2004 default:
1921 return -1; 2005 return -EIO;
1922 } 2006 }
1923 if (rc) 2007 if (rc)
1924 return -1; 2008 return rc;
1925 2009
1926 return nsegs; 2010 return nsegs;
1927} 2011}
diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h
index ac7fc9a31342..b799041b75bf 100644
--- a/net/sunrpc/xprtrdma/xprt_rdma.h
+++ b/net/sunrpc/xprtrdma/xprt_rdma.h
@@ -97,6 +97,12 @@ struct rpcrdma_ep {
97 struct ib_wc rep_recv_wcs[RPCRDMA_POLLSIZE]; 97 struct ib_wc rep_recv_wcs[RPCRDMA_POLLSIZE];
98}; 98};
99 99
100/*
101 * Force a signaled SEND Work Request every so often,
102 * in case the provider needs to do some housekeeping.
103 */
104#define RPCRDMA_MAX_UNSIGNALED_SENDS (32)
105
100#define INIT_CQCOUNT(ep) atomic_set(&(ep)->rep_cqcount, (ep)->rep_cqinit) 106#define INIT_CQCOUNT(ep) atomic_set(&(ep)->rep_cqcount, (ep)->rep_cqinit)
101#define DECR_CQCOUNT(ep) atomic_sub_return(1, &(ep)->rep_cqcount) 107#define DECR_CQCOUNT(ep) atomic_sub_return(1, &(ep)->rep_cqcount)
102 108
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 3b305ab17afe..87ce7e8bb8dc 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -75,7 +75,7 @@ static unsigned int xs_tcp_fin_timeout __read_mostly = XS_TCP_LINGER_TO;
75 * someone else's file names! 75 * someone else's file names!
76 */ 76 */
77 77
78#ifdef RPC_DEBUG 78#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
79 79
80static unsigned int min_slot_table_size = RPC_MIN_SLOT_TABLE; 80static unsigned int min_slot_table_size = RPC_MIN_SLOT_TABLE;
81static unsigned int max_slot_table_size = RPC_MAX_SLOT_TABLE; 81static unsigned int max_slot_table_size = RPC_MAX_SLOT_TABLE;
@@ -186,7 +186,7 @@ static struct ctl_table sunrpc_table[] = {
186 */ 186 */
187#define XS_IDLE_DISC_TO (5U * 60 * HZ) 187#define XS_IDLE_DISC_TO (5U * 60 * HZ)
188 188
189#ifdef RPC_DEBUG 189#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
190# undef RPC_DEBUG_DATA 190# undef RPC_DEBUG_DATA
191# define RPCDBG_FACILITY RPCDBG_TRANS 191# define RPCDBG_FACILITY RPCDBG_TRANS
192#endif 192#endif
@@ -216,65 +216,6 @@ static inline void xs_pktdump(char *msg, u32 *packet, unsigned int count)
216} 216}
217#endif 217#endif
218 218
219struct sock_xprt {
220 struct rpc_xprt xprt;
221
222 /*
223 * Network layer
224 */
225 struct socket * sock;
226 struct sock * inet;
227
228 /*
229 * State of TCP reply receive
230 */
231 __be32 tcp_fraghdr,
232 tcp_xid,
233 tcp_calldir;
234
235 u32 tcp_offset,
236 tcp_reclen;
237
238 unsigned long tcp_copied,
239 tcp_flags;
240
241 /*
242 * Connection of transports
243 */
244 struct delayed_work connect_worker;
245 struct sockaddr_storage srcaddr;
246 unsigned short srcport;
247
248 /*
249 * UDP socket buffer size parameters
250 */
251 size_t rcvsize,
252 sndsize;
253
254 /*
255 * Saved socket callback addresses
256 */
257 void (*old_data_ready)(struct sock *);
258 void (*old_state_change)(struct sock *);
259 void (*old_write_space)(struct sock *);
260 void (*old_error_report)(struct sock *);
261};
262
263/*
264 * TCP receive state flags
265 */
266#define TCP_RCV_LAST_FRAG (1UL << 0)
267#define TCP_RCV_COPY_FRAGHDR (1UL << 1)
268#define TCP_RCV_COPY_XID (1UL << 2)
269#define TCP_RCV_COPY_DATA (1UL << 3)
270#define TCP_RCV_READ_CALLDIR (1UL << 4)
271#define TCP_RCV_COPY_CALLDIR (1UL << 5)
272
273/*
274 * TCP RPC flags
275 */
276#define TCP_RPC_REPLY (1UL << 6)
277
278static inline struct rpc_xprt *xprt_from_sock(struct sock *sk) 219static inline struct rpc_xprt *xprt_from_sock(struct sock *sk)
279{ 220{
280 return (struct rpc_xprt *) sk->sk_user_data; 221 return (struct rpc_xprt *) sk->sk_user_data;
@@ -1415,6 +1356,7 @@ static int xs_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb, uns
1415 1356
1416 dprintk("RPC: xs_tcp_data_recv started\n"); 1357 dprintk("RPC: xs_tcp_data_recv started\n");
1417 do { 1358 do {
1359 trace_xs_tcp_data_recv(transport);
1418 /* Read in a new fragment marker if necessary */ 1360 /* Read in a new fragment marker if necessary */
1419 /* Can we ever really expect to get completely empty fragments? */ 1361 /* Can we ever really expect to get completely empty fragments? */
1420 if (transport->tcp_flags & TCP_RCV_COPY_FRAGHDR) { 1362 if (transport->tcp_flags & TCP_RCV_COPY_FRAGHDR) {
@@ -1439,6 +1381,7 @@ static int xs_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb, uns
1439 /* Skip over any trailing bytes on short reads */ 1381 /* Skip over any trailing bytes on short reads */
1440 xs_tcp_read_discard(transport, &desc); 1382 xs_tcp_read_discard(transport, &desc);
1441 } while (desc.count); 1383 } while (desc.count);
1384 trace_xs_tcp_data_recv(transport);
1442 dprintk("RPC: xs_tcp_data_recv done\n"); 1385 dprintk("RPC: xs_tcp_data_recv done\n");
1443 return len - desc.count; 1386 return len - desc.count;
1444} 1387}
@@ -1454,12 +1397,15 @@ static void xs_tcp_data_ready(struct sock *sk)
1454 struct rpc_xprt *xprt; 1397 struct rpc_xprt *xprt;
1455 read_descriptor_t rd_desc; 1398 read_descriptor_t rd_desc;
1456 int read; 1399 int read;
1400 unsigned long total = 0;
1457 1401
1458 dprintk("RPC: xs_tcp_data_ready...\n"); 1402 dprintk("RPC: xs_tcp_data_ready...\n");
1459 1403
1460 read_lock_bh(&sk->sk_callback_lock); 1404 read_lock_bh(&sk->sk_callback_lock);
1461 if (!(xprt = xprt_from_sock(sk))) 1405 if (!(xprt = xprt_from_sock(sk))) {
1406 read = 0;
1462 goto out; 1407 goto out;
1408 }
1463 /* Any data means we had a useful conversation, so 1409 /* Any data means we had a useful conversation, so
1464 * the we don't need to delay the next reconnect 1410 * the we don't need to delay the next reconnect
1465 */ 1411 */
@@ -1471,8 +1417,11 @@ static void xs_tcp_data_ready(struct sock *sk)
1471 do { 1417 do {
1472 rd_desc.count = 65536; 1418 rd_desc.count = 65536;
1473 read = tcp_read_sock(sk, &rd_desc, xs_tcp_data_recv); 1419 read = tcp_read_sock(sk, &rd_desc, xs_tcp_data_recv);
1420 if (read > 0)
1421 total += read;
1474 } while (read > 0); 1422 } while (read > 0);
1475out: 1423out:
1424 trace_xs_tcp_data_ready(xprt, read, total);
1476 read_unlock_bh(&sk->sk_callback_lock); 1425 read_unlock_bh(&sk->sk_callback_lock);
1477} 1426}
1478 1427
@@ -3042,7 +2991,7 @@ static struct xprt_class xs_bc_tcp_transport = {
3042 */ 2991 */
3043int init_socket_xprt(void) 2992int init_socket_xprt(void)
3044{ 2993{
3045#ifdef RPC_DEBUG 2994#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
3046 if (!sunrpc_table_header) 2995 if (!sunrpc_table_header)
3047 sunrpc_table_header = register_sysctl_table(sunrpc_table); 2996 sunrpc_table_header = register_sysctl_table(sunrpc_table);
3048#endif 2997#endif
@@ -3061,7 +3010,7 @@ int init_socket_xprt(void)
3061 */ 3010 */
3062void cleanup_socket_xprt(void) 3011void cleanup_socket_xprt(void)
3063{ 3012{
3064#ifdef RPC_DEBUG 3013#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
3065 if (sunrpc_table_header) { 3014 if (sunrpc_table_header) {
3066 unregister_sysctl_table(sunrpc_table_header); 3015 unregister_sysctl_table(sunrpc_table_header);
3067 sunrpc_table_header = NULL; 3016 sunrpc_table_header = NULL;