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; |
