diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-10 18:13:13 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-10 18:13:13 -0500 |
commit | e20db597b6264de55ea6636fc79b1e4aaa89d129 (patch) | |
tree | fa650cb9cfad4b22598ae9867ca92baf57491a9d | |
parent | 3a5dc1fafb016560315fe45bb4ef8bde259dd1bc (diff) | |
parent | 388f0c776781fe64ce951701bfe712b2182a31f2 (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
...
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; | |||
53 | static LIST_HEAD(nlm_blocked); | 53 | static LIST_HEAD(nlm_blocked); |
54 | static DEFINE_SPINLOCK(nlm_blocked_lock); | 54 | static DEFINE_SPINLOCK(nlm_blocked_lock); |
55 | 55 | ||
56 | #ifdef LOCKD_DEBUG | 56 | #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) |
57 | static const char *nlmdbg_cookie2a(const struct nlm_cookie *cookie) | 57 | static 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 | } |
195 | EXPORT_SYMBOL_GPL(nfs_zap_caches); | ||
195 | 196 | ||
196 | void nfs_zap_mapping(struct inode *inode, struct address_space *mapping) | 197 | void 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 | } |
58 | static 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 | ||
60 | static inline struct nfs_iostats __percpu *nfs_alloc_iostats(void) | 65 | static 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 */ |
9 | int nfs42_proc_allocate(struct file *, loff_t, loff_t); | ||
10 | int nfs42_proc_deallocate(struct file *, loff_t, loff_t); | ||
9 | loff_t nfs42_proc_llseek(struct file *, loff_t, int); | 11 | loff_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 | ||
35 | static 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 | |||
59 | static 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 | |||
76 | int 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 | |||
93 | int 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 | |||
35 | loff_t nfs42_proc_llseek(struct file *filep, loff_t offset, int whence) | 110 | loff_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 | ||
46 | static 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 | |||
54 | static 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 | |||
62 | static 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 | |||
25 | static void encode_seek(struct xdr_stream *xdr, | 70 | static 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 | */ | ||
83 | static 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 | */ | ||
101 | static 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 | */ |
38 | static void nfs4_xdr_enc_seek(struct rpc_rqst *req, | 119 | static 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 | ||
134 | static int decode_allocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res) | ||
135 | { | ||
136 | return decode_op_hdr(xdr, OP_ALLOCATE); | ||
137 | } | ||
138 | |||
139 | static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res) | ||
140 | { | ||
141 | return decode_op_hdr(xdr, OP_DEALLOCATE); | ||
142 | } | ||
143 | |||
53 | static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res) | 144 | static 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 | */ | ||
169 | static 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); | ||
186 | out: | ||
187 | return status; | ||
188 | } | ||
189 | |||
190 | /* | ||
191 | * Decode DEALLOCATE request | ||
192 | */ | ||
193 | static 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); | ||
210 | out: | ||
211 | return status; | ||
212 | } | ||
213 | |||
214 | /* | ||
76 | * Decode SEEK request | 215 | * Decode SEEK request |
77 | */ | 216 | */ |
78 | static int nfs4_xdr_dec_seek(struct rpc_rqst *rqstp, | 217 | static 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 */ |
229 | extern int nfs4_handle_exception(struct nfs_server *, int, struct nfs4_exception *); | ||
229 | extern int nfs4_call_sync(struct rpc_clnt *, struct nfs_server *, | 230 | extern 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 | */ |
242 | static int nfs4_init_callback(struct nfs_client *clp) | 242 | static 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 */ |
551 | out: | 546 | out: |
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 | |||
140 | static 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 | ||
139 | const struct file_operations nfs4_file_operations = { | 167 | const 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 | */ |
347 | static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struct nfs4_exception *exception) | 345 | int 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) | |||
258 | static inline void | 258 | static inline void |
259 | nfs_page_group_init(struct nfs_page *req, struct nfs_page *prev) | 259 | nfs_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); | |||
520 | static inline int | 520 | static inline int |
521 | nfs_have_writebacks(struct inode *inode) | 521 | nfs_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 |
1246 | struct 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 | |||
1255 | struct nfs42_falloc_res { | ||
1256 | struct nfs4_sequence_res seq_res; | ||
1257 | unsigned int status; | ||
1258 | }; | ||
1259 | |||
1246 | struct nfs42_seek_args { | 1260 | struct 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); | |||
176 | const char *rpc_peeraddr2str(struct rpc_clnt *, enum rpc_display_format_t); | 179 | const char *rpc_peeraddr2str(struct rpc_clnt *, enum rpc_display_format_t); |
177 | int rpc_localaddr(struct rpc_clnt *, struct sockaddr *, size_t); | 180 | int rpc_localaddr(struct rpc_clnt *, struct sockaddr *, size_t); |
178 | 181 | ||
182 | const 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) |
29 | extern unsigned int rpc_debug; | 17 | extern unsigned int rpc_debug; |
30 | extern unsigned int nfs_debug; | 18 | extern unsigned int nfs_debug; |
31 | extern unsigned int nfsd_debug; | 19 | extern 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 | |
57 | struct rpc_clnt; | ||
58 | struct rpc_xprt; | ||
59 | |||
60 | #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) | ||
69 | void rpc_register_sysctl(void); | 61 | void rpc_register_sysctl(void); |
70 | void rpc_unregister_sysctl(void); | 62 | void rpc_unregister_sysctl(void); |
63 | int sunrpc_debugfs_init(void); | ||
64 | void sunrpc_debugfs_exit(void); | ||
65 | int rpc_clnt_debugfs_register(struct rpc_clnt *); | ||
66 | void rpc_clnt_debugfs_unregister(struct rpc_clnt *); | ||
67 | int rpc_xprt_debugfs_register(struct rpc_xprt *); | ||
68 | void rpc_xprt_debugfs_unregister(struct rpc_xprt *); | ||
69 | #else | ||
70 | static inline int | ||
71 | sunrpc_debugfs_init(void) | ||
72 | { | ||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | static inline void | ||
77 | sunrpc_debugfs_exit(void) | ||
78 | { | ||
79 | return; | ||
80 | } | ||
81 | |||
82 | static inline int | ||
83 | rpc_clnt_debugfs_register(struct rpc_clnt *clnt) | ||
84 | { | ||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | static inline void | ||
89 | rpc_clnt_debugfs_unregister(struct rpc_clnt *clnt) | ||
90 | { | ||
91 | return; | ||
92 | } | ||
93 | |||
94 | static inline int | ||
95 | rpc_xprt_debugfs_register(struct rpc_xprt *xprt) | ||
96 | { | ||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | static inline void | ||
101 | rpc_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 | ||
33 | struct rpc_iostats { | 34 | struct 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 *); | |||
237 | int rpciod_up(void); | 237 | int rpciod_up(void); |
238 | void rpciod_down(void); | 238 | void rpciod_down(void); |
239 | int __rpc_wait_for_completion_task(struct rpc_task *task, wait_bit_action_f *); | 239 | int __rpc_wait_for_completion_task(struct rpc_task *task, wait_bit_action_f *); |
240 | #ifdef RPC_DEBUG | 240 | #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) |
241 | struct net; | 241 | struct net; |
242 | void rpc_show_tasks(struct net *); | 242 | void 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) |
255 | static inline const char * rpc_qname(const struct rpc_wait_queue *q) | 255 | static 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 | ||
20 | struct 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); | |||
306 | DEFINE_RPC_SOCKET_EVENT(rpc_socket_close); | 308 | DEFINE_RPC_SOCKET_EVENT(rpc_socket_close); |
307 | DEFINE_RPC_SOCKET_EVENT(rpc_socket_shutdown); | 309 | DEFINE_RPC_SOCKET_EVENT(rpc_socket_shutdown); |
308 | 310 | ||
311 | DECLARE_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 | |||
335 | DEFINE_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 | |||
339 | DEFINE_EVENT(rpc_xprt_event, xprt_transmit, | ||
340 | TP_PROTO(struct rpc_xprt *xprt, __be32 xid, int status), | ||
341 | TP_ARGS(xprt, xid, status)); | ||
342 | |||
343 | DEFINE_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 | |||
347 | TRACE_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 | |||
384 | TRACE_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 | |||
415 | TRACE_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 | |||
436 | DECLARE_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 | |||
461 | DEFINE_EVENT(svc_rqst_status, svc_process, | ||
462 | TP_PROTO(struct svc_rqst *rqst, int status), | ||
463 | TP_ARGS(rqst, status)); | ||
464 | |||
465 | DEFINE_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 | |||
35 | config SUNRPC_DEBUG | 35 | config 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 |
17 | sunrpc-$(CONFIG_SUNRPC_DEBUG) += debugfs.o | ||
17 | sunrpc-$(CONFIG_SUNRPC_BACKCHANNEL) += backchannel_rqst.o bc_svc.o | 18 | sunrpc-$(CONFIG_SUNRPC_BACKCHANNEL) += backchannel_rqst.o bc_svc.o |
18 | sunrpc-$(CONFIG_PROC_FS) += stats.o | 19 | sunrpc-$(CONFIG_PROC_FS) += stats.o |
19 | sunrpc-$(CONFIG_SYSCTL) += sysctl.o | 20 | sunrpc-$(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 |
67 | static unsigned int gss_key_expire_timeo = GSS_KEY_EXPIRE_TIMEO; | 67 | static 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: | |||
331 | out: | 335 | out: |
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 | } |
1397 | EXPORT_SYMBOL_GPL(rpc_restart_call); | 1404 | EXPORT_SYMBOL_GPL(rpc_restart_call); |
1398 | 1405 | ||
1399 | #ifdef RPC_DEBUG | 1406 | #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) |
1400 | static const char *rpc_proc_name(const struct rpc_task *task) | 1407 | const 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 | } |
2422 | EXPORT_SYMBOL_GPL(rpc_call_null); | 2430 | EXPORT_SYMBOL_GPL(rpc_call_null); |
2423 | 2431 | ||
2424 | #ifdef RPC_DEBUG | 2432 | #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) |
2425 | static void rpc_show_header(void) | 2433 | static 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 | |||
12 | static struct dentry *topdir; | ||
13 | static struct dentry *rpc_clnt_dir; | ||
14 | static struct dentry *rpc_xprt_dir; | ||
15 | |||
16 | struct rpc_clnt_iter { | ||
17 | struct rpc_clnt *clnt; | ||
18 | loff_t pos; | ||
19 | }; | ||
20 | |||
21 | static int | ||
22 | tasks_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 | |||
43 | static void * | ||
44 | tasks_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 | |||
60 | static void * | ||
61 | tasks_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 | |||
77 | static void | ||
78 | tasks_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 | |||
87 | static 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 | |||
94 | static 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 | |||
114 | static int | ||
115 | tasks_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 | |||
124 | static 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 | |||
132 | int | ||
133 | rpc_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; | ||
170 | out_err: | ||
171 | debugfs_remove_recursive(clnt->cl_debugfs); | ||
172 | clnt->cl_debugfs = NULL; | ||
173 | return err; | ||
174 | } | ||
175 | |||
176 | void | ||
177 | rpc_clnt_debugfs_unregister(struct rpc_clnt *clnt) | ||
178 | { | ||
179 | debugfs_remove_recursive(clnt->cl_debugfs); | ||
180 | clnt->cl_debugfs = NULL; | ||
181 | } | ||
182 | |||
183 | static int | ||
184 | xprt_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 | |||
195 | static int | ||
196 | xprt_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 | |||
212 | static int | ||
213 | xprt_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 | |||
221 | static 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 | |||
229 | int | ||
230 | rpc_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 | |||
258 | void | ||
259 | rpc_xprt_debugfs_unregister(struct rpc_xprt *xprt) | ||
260 | { | ||
261 | debugfs_remove_recursive(xprt->debugfs); | ||
262 | xprt->debugfs = NULL; | ||
263 | } | ||
264 | |||
265 | void __exit | ||
266 | sunrpc_debugfs_exit(void) | ||
267 | { | ||
268 | debugfs_remove_recursive(topdir); | ||
269 | } | ||
270 | |||
271 | int __init | ||
272 | sunrpc_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; | ||
287 | out_remove: | ||
288 | debugfs_remove_recursive(topdir); | ||
289 | topdir = NULL; | ||
290 | out: | ||
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) |
262 | static void rpc_task_set_debuginfo(struct rpc_task *task) | 262 | static 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 | */ |
117 | struct rpc_iostats *rpc_alloc_iostats(struct rpc_clnt *clnt) | 117 | struct 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 | } |
121 | EXPORT_SYMBOL_GPL(rpc_alloc_iostats); | 129 | EXPORT_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 | */ |
141 | void rpc_count_iostats(const struct rpc_task *task, struct rpc_iostats *stats) | 147 | void 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 | } |
167 | EXPORT_SYMBOL_GPL(rpc_count_iostats); | 178 | EXPORT_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 | ||
112 | out5: | ||
113 | unregister_rpc_pipefs(); | ||
107 | out4: | 114 | out4: |
108 | unregister_pernet_subsys(&sunrpc_net_ops); | 115 | unregister_pernet_subsys(&sunrpc_net_ops); |
109 | out3: | 116 | out3: |
@@ -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 | ||
33 | static void svc_unregister(const struct svc_serv *serv, struct net *net); | 35 | static 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) |
1044 | static __printf(2, 3) | 1046 | static __printf(2, 3) |
1045 | void svc_printk(struct svc_rqst *rqstp, const char *fmt, ...) | 1047 | void 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 | } |
1334 | out_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; |
801 | out: | 808 | out_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; | 811 | out: |
812 | trace_svc_recv(rqstp, err); | ||
813 | return err; | ||
805 | } | 814 | } |
806 | EXPORT_SYMBOL_GPL(svc_recv); | 815 | EXPORT_SYMBOL_GPL(svc_recv); |
807 | 816 | ||
@@ -821,12 +830,12 @@ EXPORT_SYMBOL_GPL(svc_drop); | |||
821 | int svc_send(struct svc_rqst *rqstp) | 830 | int 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; |
862 | out: | ||
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); | |||
37 | unsigned int nlm_debug; | 37 | unsigned int nlm_debug; |
38 | EXPORT_SYMBOL_GPL(nlm_debug); | 38 | EXPORT_SYMBOL_GPL(nlm_debug); |
39 | 39 | ||
40 | #ifdef RPC_DEBUG | 40 | #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) |
41 | 41 | ||
42 | static struct ctl_table_header *sunrpc_table_header; | 42 | static struct ctl_table_header *sunrpc_table_header; |
43 | static struct ctl_table sunrpc_table[]; | 43 | static 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 | */ |
1297 | struct rpc_xprt *xprt_create_transport(struct xprt_create *args) | 1304 | struct 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); |
1341 | out: | 1355 | out: |
@@ -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) |
57 | static const char transfertypes[][12] = { | 57 | static 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; | |||
73 | static unsigned int xprt_rdma_max_inline_write = RPCRDMA_DEF_INLINE; | 73 | static unsigned int xprt_rdma_max_inline_write = RPCRDMA_DEF_INLINE; |
74 | static unsigned int xprt_rdma_inline_write_padding; | 74 | static unsigned int xprt_rdma_inline_write_padding; |
75 | static unsigned int xprt_rdma_memreg_strategy = RPCRDMA_FRMR; | 75 | static 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 | ||
80 | static unsigned int min_slot_table_size = RPCRDMA_MIN_SLOT_TABLE; | 80 | static unsigned int min_slot_table_size = RPCRDMA_MIN_SLOT_TABLE; |
81 | static unsigned int max_slot_table_size = RPCRDMA_MAX_SLOT_TABLE; | 81 | static 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 | ||
64 | static void rpcrdma_reset_frmrs(struct rpcrdma_ia *); | 64 | static void rpcrdma_reset_frmrs(struct rpcrdma_ia *); |
65 | static 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 | ||
106 | static DECLARE_TASKLET(rpcrdma_tasklet_g, rpcrdma_run_tasklet, 0UL); | 107 | static DECLARE_TASKLET(rpcrdma_tasklet_g, rpcrdma_run_tasklet, 0UL); |
107 | 108 | ||
109 | static 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 | |||
135 | static void | ||
136 | rpcrdma_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 | |||
108 | static void | 146 | static void |
109 | rpcrdma_qp_async_error_upcall(struct ib_event *event, void *context) | 147 | rpcrdma_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 | ||
263 | out_schedule: | 302 | out_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) | |||
309 | static void | 345 | static void |
310 | rpcrdma_flush_cqs(struct rpcrdma_ep *ep) | 346 | rpcrdma_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) |
317 | static const char * const conn[] = { | 360 | static 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 | */ | ||
1351 | static void | ||
1352 | rpcrdma_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 | ||
80 | static unsigned int min_slot_table_size = RPC_MIN_SLOT_TABLE; | 80 | static unsigned int min_slot_table_size = RPC_MIN_SLOT_TABLE; |
81 | static unsigned int max_slot_table_size = RPC_MAX_SLOT_TABLE; | 81 | static 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 | ||
219 | struct 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 | |||
278 | static inline struct rpc_xprt *xprt_from_sock(struct sock *sk) | 219 | static 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); |
1475 | out: | 1423 | out: |
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 | */ |
3043 | int init_socket_xprt(void) | 2992 | int 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 | */ |
3062 | void cleanup_socket_xprt(void) | 3011 | void 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; |