mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-27 00:51:35 +00:00
NFS client updates for Linux 3.19
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 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJUhRVTAAoJEGcL54qWCgDyfeUP/RoFo3ImTMbGxfcPJqoELjcO lZbQ+27pOE/whFDkWgiOVTwlgGct5a0WRo7GCZmpYJA4q1kmSv4ngTb3nMTCUztt xMJ0mBr0BqttVs+ouKiVPm3cejQXedEhttwWcloIXS8lNenlpL29Zlrx2NHdU8UU 13+souocj0dwIyTYYS/4Lm9KpuCYnpDBpP5ShvQjVaMe/GxJo6GyZu70c7FgwGNz Nh9onzZV3mz1elhfizlV38aVA7KWVXtLWIqOFIKlT2fa4nWB8Hc07miR5UeOK0/h r+icnF2qCQe83MbjOxYNxIKB6uiA/4xwVc90X4AQ7F0RX8XPWHIQWG5tlkC9jrCQ 3RGzYshWDc9Ud2mXtLMyVQxHVVYlFAe1WtdP8ZWb1oxDInmhrarnWeNyECz9xGKu VzIDZzeq9G8slJXATWGRfPsYr+Ihpzcen4QQw58cakUBcqEJrYEhlEOfLovM71k3 /S/jSHBAbQqiw4LPMw87bA5A6+ZKcVSsNE0XCtNnhmqFpLc1kKRrl5vaN+QMk5tJ v4/zR0fPqH7SGAJWYs4brdfahyejEo0TwgpDs7KHmu1W9zQ0LCVTaYnQuUmQjta6 WyYwIy3TTibdfR191O0E3NOW82Q/k/NBD6ySvabN9HqQ9eSk6+rzrWAslXCbYohb BJfzcQfDdx+lsyhjeTx9 =wOP3 -----END PGP SIGNATURE----- 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 ...
This commit is contained in:
commit
e20db597b6
66 changed files with 1171 additions and 244 deletions
|
@ -53,7 +53,7 @@ static const struct rpc_call_ops nlmsvc_grant_ops;
|
||||||
static LIST_HEAD(nlm_blocked);
|
static LIST_HEAD(nlm_blocked);
|
||||||
static DEFINE_SPINLOCK(nlm_blocked_lock);
|
static DEFINE_SPINLOCK(nlm_blocked_lock);
|
||||||
|
|
||||||
#ifdef LOCKD_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
static const char *nlmdbg_cookie2a(const struct nlm_cookie *cookie)
|
static const char *nlmdbg_cookie2a(const struct nlm_cookie *cookie)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -812,7 +812,7 @@ static u64 pnfs_num_cont_bytes(struct inode *inode, pgoff_t idx)
|
||||||
|
|
||||||
/* Optimize common case that writes from 0 to end of file */
|
/* Optimize common case that writes from 0 to end of file */
|
||||||
end = DIV_ROUND_UP(i_size_read(inode), PAGE_CACHE_SIZE);
|
end = DIV_ROUND_UP(i_size_read(inode), PAGE_CACHE_SIZE);
|
||||||
if (end != NFS_I(inode)->npages) {
|
if (end != inode->i_mapping->nrpages) {
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
end = page_cache_next_hole(mapping, idx + 1, ULONG_MAX);
|
end = page_cache_next_hole(mapping, idx + 1, ULONG_MAX);
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
|
|
@ -49,7 +49,7 @@ __be32 nfs4_callback_getattr(struct cb_getattrargs *args,
|
||||||
goto out_iput;
|
goto out_iput;
|
||||||
res->size = i_size_read(inode);
|
res->size = i_size_read(inode);
|
||||||
res->change_attr = delegation->change_attr;
|
res->change_attr = delegation->change_attr;
|
||||||
if (nfsi->npages != 0)
|
if (nfsi->nrequests != 0)
|
||||||
res->change_attr++;
|
res->change_attr++;
|
||||||
res->ctime = inode->i_ctime;
|
res->ctime = inode->i_ctime;
|
||||||
res->mtime = inode->i_mtime;
|
res->mtime = inode->i_mtime;
|
||||||
|
|
|
@ -204,8 +204,7 @@ destroy_ds(struct nfs4_pnfs_ds *ds)
|
||||||
ifdebug(FACILITY)
|
ifdebug(FACILITY)
|
||||||
print_ds(ds);
|
print_ds(ds);
|
||||||
|
|
||||||
if (ds->ds_clp)
|
nfs_put_client(ds->ds_clp);
|
||||||
nfs_put_client(ds->ds_clp);
|
|
||||||
|
|
||||||
while (!list_empty(&ds->ds_addrs)) {
|
while (!list_empty(&ds->ds_addrs)) {
|
||||||
da = list_first_entry(&ds->ds_addrs,
|
da = list_first_entry(&ds->ds_addrs,
|
||||||
|
|
|
@ -269,8 +269,8 @@ int nfs_fscache_release_page(struct page *page, gfp_t gfp)
|
||||||
if (!fscache_maybe_release_page(cookie, page, gfp))
|
if (!fscache_maybe_release_page(cookie, page, gfp))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
nfs_add_fscache_stats(page->mapping->host,
|
nfs_inc_fscache_stats(page->mapping->host,
|
||||||
NFSIOS_FSCACHE_PAGES_UNCACHED, 1);
|
NFSIOS_FSCACHE_PAGES_UNCACHED);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -293,8 +293,8 @@ void __nfs_fscache_invalidate_page(struct page *page, struct inode *inode)
|
||||||
|
|
||||||
BUG_ON(!PageLocked(page));
|
BUG_ON(!PageLocked(page));
|
||||||
fscache_uncache_page(cookie, page);
|
fscache_uncache_page(cookie, page);
|
||||||
nfs_add_fscache_stats(page->mapping->host,
|
nfs_inc_fscache_stats(page->mapping->host,
|
||||||
NFSIOS_FSCACHE_PAGES_UNCACHED, 1);
|
NFSIOS_FSCACHE_PAGES_UNCACHED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -343,19 +343,19 @@ int __nfs_readpage_from_fscache(struct nfs_open_context *ctx,
|
||||||
case 0: /* read BIO submitted (page in fscache) */
|
case 0: /* read BIO submitted (page in fscache) */
|
||||||
dfprintk(FSCACHE,
|
dfprintk(FSCACHE,
|
||||||
"NFS: readpage_from_fscache: BIO submitted\n");
|
"NFS: readpage_from_fscache: BIO submitted\n");
|
||||||
nfs_add_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_READ_OK, 1);
|
nfs_inc_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_READ_OK);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
case -ENOBUFS: /* inode not in cache */
|
case -ENOBUFS: /* inode not in cache */
|
||||||
case -ENODATA: /* page not in cache */
|
case -ENODATA: /* page not in cache */
|
||||||
nfs_add_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_READ_FAIL, 1);
|
nfs_inc_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_READ_FAIL);
|
||||||
dfprintk(FSCACHE,
|
dfprintk(FSCACHE,
|
||||||
"NFS: readpage_from_fscache %d\n", ret);
|
"NFS: readpage_from_fscache %d\n", ret);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
dfprintk(FSCACHE, "NFS: readpage_from_fscache %d\n", ret);
|
dfprintk(FSCACHE, "NFS: readpage_from_fscache %d\n", ret);
|
||||||
nfs_add_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_READ_FAIL, 1);
|
nfs_inc_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_READ_FAIL);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -429,11 +429,11 @@ void __nfs_readpage_to_fscache(struct inode *inode, struct page *page, int sync)
|
||||||
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
fscache_uncache_page(nfs_i_fscache(inode), page);
|
fscache_uncache_page(nfs_i_fscache(inode), page);
|
||||||
nfs_add_fscache_stats(inode,
|
nfs_inc_fscache_stats(inode,
|
||||||
NFSIOS_FSCACHE_PAGES_WRITTEN_FAIL, 1);
|
NFSIOS_FSCACHE_PAGES_WRITTEN_FAIL);
|
||||||
nfs_add_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_UNCACHED, 1);
|
nfs_inc_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_UNCACHED);
|
||||||
} else {
|
} else {
|
||||||
nfs_add_fscache_stats(inode,
|
nfs_inc_fscache_stats(inode,
|
||||||
NFSIOS_FSCACHE_PAGES_WRITTEN_OK, 1);
|
NFSIOS_FSCACHE_PAGES_WRITTEN_OK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -192,6 +192,7 @@ void nfs_zap_caches(struct inode *inode)
|
||||||
nfs_zap_caches_locked(inode);
|
nfs_zap_caches_locked(inode);
|
||||||
spin_unlock(&inode->i_lock);
|
spin_unlock(&inode->i_lock);
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(nfs_zap_caches);
|
||||||
|
|
||||||
void nfs_zap_mapping(struct inode *inode, struct address_space *mapping)
|
void nfs_zap_mapping(struct inode *inode, struct address_space *mapping)
|
||||||
{
|
{
|
||||||
|
@ -1149,7 +1150,7 @@ static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr
|
||||||
if ((fattr->valid & NFS_ATTR_FATTR_PRESIZE)
|
if ((fattr->valid & NFS_ATTR_FATTR_PRESIZE)
|
||||||
&& (fattr->valid & NFS_ATTR_FATTR_SIZE)
|
&& (fattr->valid & NFS_ATTR_FATTR_SIZE)
|
||||||
&& i_size_read(inode) == nfs_size_to_loff_t(fattr->pre_size)
|
&& i_size_read(inode) == nfs_size_to_loff_t(fattr->pre_size)
|
||||||
&& nfsi->npages == 0) {
|
&& nfsi->nrequests == 0) {
|
||||||
i_size_write(inode, nfs_size_to_loff_t(fattr->size));
|
i_size_write(inode, nfs_size_to_loff_t(fattr->size));
|
||||||
ret |= NFS_INO_INVALID_ATTR;
|
ret |= NFS_INO_INVALID_ATTR;
|
||||||
}
|
}
|
||||||
|
@ -1192,7 +1193,7 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
|
||||||
if (fattr->valid & NFS_ATTR_FATTR_SIZE) {
|
if (fattr->valid & NFS_ATTR_FATTR_SIZE) {
|
||||||
cur_size = i_size_read(inode);
|
cur_size = i_size_read(inode);
|
||||||
new_isize = nfs_size_to_loff_t(fattr->size);
|
new_isize = nfs_size_to_loff_t(fattr->size);
|
||||||
if (cur_size != new_isize && nfsi->npages == 0)
|
if (cur_size != new_isize && nfsi->nrequests == 0)
|
||||||
invalid |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE;
|
invalid |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1619,7 +1620,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
|
||||||
if (new_isize != cur_isize) {
|
if (new_isize != cur_isize) {
|
||||||
/* Do we perhaps have any outstanding writes, or has
|
/* Do we perhaps have any outstanding writes, or has
|
||||||
* the file grown beyond our last write? */
|
* the file grown beyond our last write? */
|
||||||
if ((nfsi->npages == 0) || new_isize > cur_isize) {
|
if ((nfsi->nrequests == 0) || new_isize > cur_isize) {
|
||||||
i_size_write(inode, new_isize);
|
i_size_write(inode, new_isize);
|
||||||
invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA;
|
invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA;
|
||||||
invalid &= ~NFS_INO_REVAL_PAGECACHE;
|
invalid &= ~NFS_INO_REVAL_PAGECACHE;
|
||||||
|
@ -1784,7 +1785,7 @@ static void init_once(void *foo)
|
||||||
INIT_LIST_HEAD(&nfsi->access_cache_entry_lru);
|
INIT_LIST_HEAD(&nfsi->access_cache_entry_lru);
|
||||||
INIT_LIST_HEAD(&nfsi->access_cache_inode_lru);
|
INIT_LIST_HEAD(&nfsi->access_cache_inode_lru);
|
||||||
INIT_LIST_HEAD(&nfsi->commit_info.list);
|
INIT_LIST_HEAD(&nfsi->commit_info.list);
|
||||||
nfsi->npages = 0;
|
nfsi->nrequests = 0;
|
||||||
nfsi->commit_info.ncommit = 0;
|
nfsi->commit_info.ncommit = 0;
|
||||||
atomic_set(&nfsi->commit_info.rpcs_out, 0);
|
atomic_set(&nfsi->commit_info.rpcs_out, 0);
|
||||||
atomic_set(&nfsi->silly_count, 1);
|
atomic_set(&nfsi->silly_count, 1);
|
||||||
|
|
|
@ -55,6 +55,11 @@ static inline void nfs_add_fscache_stats(struct inode *inode,
|
||||||
{
|
{
|
||||||
this_cpu_add(NFS_SERVER(inode)->io_stats->fscache[stat], addend);
|
this_cpu_add(NFS_SERVER(inode)->io_stats->fscache[stat], addend);
|
||||||
}
|
}
|
||||||
|
static inline void nfs_inc_fscache_stats(struct inode *inode,
|
||||||
|
enum nfs_stat_fscachecounters stat)
|
||||||
|
{
|
||||||
|
this_cpu_inc(NFS_SERVER(inode)->io_stats->fscache[stat]);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline struct nfs_iostats __percpu *nfs_alloc_iostats(void)
|
static inline struct nfs_iostats __percpu *nfs_alloc_iostats(void)
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
#define __LINUX_FS_NFS_NFS4_2_H
|
#define __LINUX_FS_NFS_NFS4_2_H
|
||||||
|
|
||||||
/* nfs4.2proc.c */
|
/* nfs4.2proc.c */
|
||||||
|
int nfs42_proc_allocate(struct file *, loff_t, loff_t);
|
||||||
|
int nfs42_proc_deallocate(struct file *, loff_t, loff_t);
|
||||||
loff_t nfs42_proc_llseek(struct file *, loff_t, int);
|
loff_t nfs42_proc_llseek(struct file *, loff_t, int);
|
||||||
|
|
||||||
/* nfs4.2xdr.h */
|
/* nfs4.2xdr.h */
|
||||||
|
|
|
@ -32,6 +32,81 @@ static int nfs42_set_rw_stateid(nfs4_stateid *dst, struct file *file,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
|
||||||
|
loff_t offset, loff_t len)
|
||||||
|
{
|
||||||
|
struct inode *inode = file_inode(filep);
|
||||||
|
struct nfs42_falloc_args args = {
|
||||||
|
.falloc_fh = NFS_FH(inode),
|
||||||
|
.falloc_offset = offset,
|
||||||
|
.falloc_length = len,
|
||||||
|
};
|
||||||
|
struct nfs42_falloc_res res;
|
||||||
|
struct nfs_server *server = NFS_SERVER(inode);
|
||||||
|
int status;
|
||||||
|
|
||||||
|
msg->rpc_argp = &args;
|
||||||
|
msg->rpc_resp = &res;
|
||||||
|
|
||||||
|
status = nfs42_set_rw_stateid(&args.falloc_stateid, filep, FMODE_WRITE);
|
||||||
|
if (status)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
return nfs4_call_sync(server->client, server, msg,
|
||||||
|
&args.seq_args, &res.seq_res, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
|
||||||
|
loff_t offset, loff_t len)
|
||||||
|
{
|
||||||
|
struct nfs_server *server = NFS_SERVER(file_inode(filep));
|
||||||
|
struct nfs4_exception exception = { };
|
||||||
|
int err;
|
||||||
|
|
||||||
|
do {
|
||||||
|
err = _nfs42_proc_fallocate(msg, filep, offset, len);
|
||||||
|
if (err == -ENOTSUPP)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
err = nfs4_handle_exception(server, err, &exception);
|
||||||
|
} while (exception.retry);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nfs42_proc_allocate(struct file *filep, loff_t offset, loff_t len)
|
||||||
|
{
|
||||||
|
struct rpc_message msg = {
|
||||||
|
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_ALLOCATE],
|
||||||
|
};
|
||||||
|
struct inode *inode = file_inode(filep);
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (!nfs_server_capable(inode, NFS_CAP_ALLOCATE))
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
err = nfs42_proc_fallocate(&msg, filep, offset, len);
|
||||||
|
if (err == -EOPNOTSUPP)
|
||||||
|
NFS_SERVER(inode)->caps &= ~NFS_CAP_ALLOCATE;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nfs42_proc_deallocate(struct file *filep, loff_t offset, loff_t len)
|
||||||
|
{
|
||||||
|
struct rpc_message msg = {
|
||||||
|
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_DEALLOCATE],
|
||||||
|
};
|
||||||
|
struct inode *inode = file_inode(filep);
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (!nfs_server_capable(inode, NFS_CAP_DEALLOCATE))
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
err = nfs42_proc_fallocate(&msg, filep, offset, len);
|
||||||
|
if (err == -EOPNOTSUPP)
|
||||||
|
NFS_SERVER(inode)->caps &= ~NFS_CAP_DEALLOCATE;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
loff_t nfs42_proc_llseek(struct file *filep, loff_t offset, int whence)
|
loff_t nfs42_proc_llseek(struct file *filep, loff_t offset, int whence)
|
||||||
{
|
{
|
||||||
struct inode *inode = file_inode(filep);
|
struct inode *inode = file_inode(filep);
|
||||||
|
@ -50,7 +125,7 @@ loff_t nfs42_proc_llseek(struct file *filep, loff_t offset, int whence)
|
||||||
struct nfs_server *server = NFS_SERVER(inode);
|
struct nfs_server *server = NFS_SERVER(inode);
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
if (!(server->caps & NFS_CAP_SEEK))
|
if (!nfs_server_capable(inode, NFS_CAP_SEEK))
|
||||||
return -ENOTSUPP;
|
return -ENOTSUPP;
|
||||||
|
|
||||||
status = nfs42_set_rw_stateid(&args.sa_stateid, filep, FMODE_READ);
|
status = nfs42_set_rw_stateid(&args.sa_stateid, filep, FMODE_READ);
|
||||||
|
|
|
@ -4,6 +4,15 @@
|
||||||
#ifndef __LINUX_FS_NFS_NFS4_2XDR_H
|
#ifndef __LINUX_FS_NFS_NFS4_2XDR_H
|
||||||
#define __LINUX_FS_NFS_NFS4_2XDR_H
|
#define __LINUX_FS_NFS_NFS4_2XDR_H
|
||||||
|
|
||||||
|
#define encode_fallocate_maxsz (encode_stateid_maxsz + \
|
||||||
|
2 /* offset */ + \
|
||||||
|
2 /* length */)
|
||||||
|
#define encode_allocate_maxsz (op_encode_hdr_maxsz + \
|
||||||
|
encode_fallocate_maxsz)
|
||||||
|
#define decode_allocate_maxsz (op_decode_hdr_maxsz)
|
||||||
|
#define encode_deallocate_maxsz (op_encode_hdr_maxsz + \
|
||||||
|
encode_fallocate_maxsz)
|
||||||
|
#define decode_deallocate_maxsz (op_decode_hdr_maxsz)
|
||||||
#define encode_seek_maxsz (op_encode_hdr_maxsz + \
|
#define encode_seek_maxsz (op_encode_hdr_maxsz + \
|
||||||
encode_stateid_maxsz + \
|
encode_stateid_maxsz + \
|
||||||
2 /* offset */ + \
|
2 /* offset */ + \
|
||||||
|
@ -14,6 +23,18 @@
|
||||||
2 /* offset */ + \
|
2 /* offset */ + \
|
||||||
2 /* length */)
|
2 /* length */)
|
||||||
|
|
||||||
|
#define NFS4_enc_allocate_sz (compound_encode_hdr_maxsz + \
|
||||||
|
encode_putfh_maxsz + \
|
||||||
|
encode_allocate_maxsz)
|
||||||
|
#define NFS4_dec_allocate_sz (compound_decode_hdr_maxsz + \
|
||||||
|
decode_putfh_maxsz + \
|
||||||
|
decode_allocate_maxsz)
|
||||||
|
#define NFS4_enc_deallocate_sz (compound_encode_hdr_maxsz + \
|
||||||
|
encode_putfh_maxsz + \
|
||||||
|
encode_deallocate_maxsz)
|
||||||
|
#define NFS4_dec_deallocate_sz (compound_decode_hdr_maxsz + \
|
||||||
|
decode_putfh_maxsz + \
|
||||||
|
decode_deallocate_maxsz)
|
||||||
#define NFS4_enc_seek_sz (compound_encode_hdr_maxsz + \
|
#define NFS4_enc_seek_sz (compound_encode_hdr_maxsz + \
|
||||||
encode_putfh_maxsz + \
|
encode_putfh_maxsz + \
|
||||||
encode_seek_maxsz)
|
encode_seek_maxsz)
|
||||||
|
@ -22,6 +43,30 @@
|
||||||
decode_seek_maxsz)
|
decode_seek_maxsz)
|
||||||
|
|
||||||
|
|
||||||
|
static void encode_fallocate(struct xdr_stream *xdr,
|
||||||
|
struct nfs42_falloc_args *args)
|
||||||
|
{
|
||||||
|
encode_nfs4_stateid(xdr, &args->falloc_stateid);
|
||||||
|
encode_uint64(xdr, args->falloc_offset);
|
||||||
|
encode_uint64(xdr, args->falloc_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void encode_allocate(struct xdr_stream *xdr,
|
||||||
|
struct nfs42_falloc_args *args,
|
||||||
|
struct compound_hdr *hdr)
|
||||||
|
{
|
||||||
|
encode_op_hdr(xdr, OP_ALLOCATE, decode_allocate_maxsz, hdr);
|
||||||
|
encode_fallocate(xdr, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void encode_deallocate(struct xdr_stream *xdr,
|
||||||
|
struct nfs42_falloc_args *args,
|
||||||
|
struct compound_hdr *hdr)
|
||||||
|
{
|
||||||
|
encode_op_hdr(xdr, OP_DEALLOCATE, decode_deallocate_maxsz, hdr);
|
||||||
|
encode_fallocate(xdr, args);
|
||||||
|
}
|
||||||
|
|
||||||
static void encode_seek(struct xdr_stream *xdr,
|
static void encode_seek(struct xdr_stream *xdr,
|
||||||
struct nfs42_seek_args *args,
|
struct nfs42_seek_args *args,
|
||||||
struct compound_hdr *hdr)
|
struct compound_hdr *hdr)
|
||||||
|
@ -32,6 +77,42 @@ static void encode_seek(struct xdr_stream *xdr,
|
||||||
encode_uint32(xdr, args->sa_what);
|
encode_uint32(xdr, args->sa_what);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Encode ALLOCATE request
|
||||||
|
*/
|
||||||
|
static void nfs4_xdr_enc_allocate(struct rpc_rqst *req,
|
||||||
|
struct xdr_stream *xdr,
|
||||||
|
struct nfs42_falloc_args *args)
|
||||||
|
{
|
||||||
|
struct compound_hdr hdr = {
|
||||||
|
.minorversion = nfs4_xdr_minorversion(&args->seq_args),
|
||||||
|
};
|
||||||
|
|
||||||
|
encode_compound_hdr(xdr, req, &hdr);
|
||||||
|
encode_sequence(xdr, &args->seq_args, &hdr);
|
||||||
|
encode_putfh(xdr, args->falloc_fh, &hdr);
|
||||||
|
encode_allocate(xdr, args, &hdr);
|
||||||
|
encode_nops(&hdr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Encode DEALLOCATE request
|
||||||
|
*/
|
||||||
|
static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req,
|
||||||
|
struct xdr_stream *xdr,
|
||||||
|
struct nfs42_falloc_args *args)
|
||||||
|
{
|
||||||
|
struct compound_hdr hdr = {
|
||||||
|
.minorversion = nfs4_xdr_minorversion(&args->seq_args),
|
||||||
|
};
|
||||||
|
|
||||||
|
encode_compound_hdr(xdr, req, &hdr);
|
||||||
|
encode_sequence(xdr, &args->seq_args, &hdr);
|
||||||
|
encode_putfh(xdr, args->falloc_fh, &hdr);
|
||||||
|
encode_deallocate(xdr, args, &hdr);
|
||||||
|
encode_nops(&hdr);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Encode SEEK request
|
* Encode SEEK request
|
||||||
*/
|
*/
|
||||||
|
@ -50,6 +131,16 @@ static void nfs4_xdr_enc_seek(struct rpc_rqst *req,
|
||||||
encode_nops(&hdr);
|
encode_nops(&hdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int decode_allocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
|
||||||
|
{
|
||||||
|
return decode_op_hdr(xdr, OP_ALLOCATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
|
||||||
|
{
|
||||||
|
return decode_op_hdr(xdr, OP_DEALLOCATE);
|
||||||
|
}
|
||||||
|
|
||||||
static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res)
|
static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
|
@ -72,6 +163,54 @@ out_overflow:
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Decode ALLOCATE request
|
||||||
|
*/
|
||||||
|
static int nfs4_xdr_dec_allocate(struct rpc_rqst *rqstp,
|
||||||
|
struct xdr_stream *xdr,
|
||||||
|
struct nfs42_falloc_res *res)
|
||||||
|
{
|
||||||
|
struct compound_hdr hdr;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
status = decode_compound_hdr(xdr, &hdr);
|
||||||
|
if (status)
|
||||||
|
goto out;
|
||||||
|
status = decode_sequence(xdr, &res->seq_res, rqstp);
|
||||||
|
if (status)
|
||||||
|
goto out;
|
||||||
|
status = decode_putfh(xdr);
|
||||||
|
if (status)
|
||||||
|
goto out;
|
||||||
|
status = decode_allocate(xdr, res);
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Decode DEALLOCATE request
|
||||||
|
*/
|
||||||
|
static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp,
|
||||||
|
struct xdr_stream *xdr,
|
||||||
|
struct nfs42_falloc_res *res)
|
||||||
|
{
|
||||||
|
struct compound_hdr hdr;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
status = decode_compound_hdr(xdr, &hdr);
|
||||||
|
if (status)
|
||||||
|
goto out;
|
||||||
|
status = decode_sequence(xdr, &res->seq_res, rqstp);
|
||||||
|
if (status)
|
||||||
|
goto out;
|
||||||
|
status = decode_putfh(xdr);
|
||||||
|
if (status)
|
||||||
|
goto out;
|
||||||
|
status = decode_deallocate(xdr, res);
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Decode SEEK request
|
* Decode SEEK request
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -226,6 +226,7 @@ int nfs4_replace_transport(struct nfs_server *server,
|
||||||
const struct nfs4_fs_locations *locations);
|
const struct nfs4_fs_locations *locations);
|
||||||
|
|
||||||
/* nfs4proc.c */
|
/* nfs4proc.c */
|
||||||
|
extern int nfs4_handle_exception(struct nfs_server *, int, struct nfs4_exception *);
|
||||||
extern int nfs4_call_sync(struct rpc_clnt *, struct nfs_server *,
|
extern int nfs4_call_sync(struct rpc_clnt *, struct nfs_server *,
|
||||||
struct rpc_message *, struct nfs4_sequence_args *,
|
struct rpc_message *, struct nfs4_sequence_args *,
|
||||||
struct nfs4_sequence_res *, int);
|
struct nfs4_sequence_res *, int);
|
||||||
|
|
|
@ -241,28 +241,25 @@ void nfs4_free_client(struct nfs_client *clp)
|
||||||
*/
|
*/
|
||||||
static int nfs4_init_callback(struct nfs_client *clp)
|
static int nfs4_init_callback(struct nfs_client *clp)
|
||||||
{
|
{
|
||||||
|
struct rpc_xprt *xprt;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (clp->rpc_ops->version == 4) {
|
xprt = rcu_dereference_raw(clp->cl_rpcclient->cl_xprt);
|
||||||
struct rpc_xprt *xprt;
|
|
||||||
|
|
||||||
xprt = rcu_dereference_raw(clp->cl_rpcclient->cl_xprt);
|
if (nfs4_has_session(clp)) {
|
||||||
|
error = xprt_setup_backchannel(xprt, NFS41_BC_MIN_CALLBACKS);
|
||||||
if (nfs4_has_session(clp)) {
|
if (error < 0)
|
||||||
error = xprt_setup_backchannel(xprt,
|
|
||||||
NFS41_BC_MIN_CALLBACKS);
|
|
||||||
if (error < 0)
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
error = nfs_callback_up(clp->cl_mvops->minor_version, xprt);
|
|
||||||
if (error < 0) {
|
|
||||||
dprintk("%s: failed to start callback. Error = %d\n",
|
|
||||||
__func__, error);
|
|
||||||
return error;
|
return error;
|
||||||
}
|
|
||||||
__set_bit(NFS_CS_CALLBACK, &clp->cl_res_state);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
error = nfs_callback_up(clp->cl_mvops->minor_version, xprt);
|
||||||
|
if (error < 0) {
|
||||||
|
dprintk("%s: failed to start callback. Error = %d\n",
|
||||||
|
__func__, error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
__set_bit(NFS_CS_CALLBACK, &clp->cl_res_state);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -498,8 +495,7 @@ int nfs40_walk_client_list(struct nfs_client *new,
|
||||||
atomic_inc(&pos->cl_count);
|
atomic_inc(&pos->cl_count);
|
||||||
spin_unlock(&nn->nfs_client_lock);
|
spin_unlock(&nn->nfs_client_lock);
|
||||||
|
|
||||||
if (prev)
|
nfs_put_client(prev);
|
||||||
nfs_put_client(prev);
|
|
||||||
prev = pos;
|
prev = pos;
|
||||||
|
|
||||||
status = nfs_wait_client_init_complete(pos);
|
status = nfs_wait_client_init_complete(pos);
|
||||||
|
@ -517,8 +513,7 @@ int nfs40_walk_client_list(struct nfs_client *new,
|
||||||
atomic_inc(&pos->cl_count);
|
atomic_inc(&pos->cl_count);
|
||||||
spin_unlock(&nn->nfs_client_lock);
|
spin_unlock(&nn->nfs_client_lock);
|
||||||
|
|
||||||
if (prev)
|
nfs_put_client(prev);
|
||||||
nfs_put_client(prev);
|
|
||||||
prev = pos;
|
prev = pos;
|
||||||
|
|
||||||
status = nfs4_proc_setclientid_confirm(pos, &clid, cred);
|
status = nfs4_proc_setclientid_confirm(pos, &clid, cred);
|
||||||
|
@ -549,8 +544,7 @@ int nfs40_walk_client_list(struct nfs_client *new,
|
||||||
|
|
||||||
/* No match found. The server lost our clientid */
|
/* No match found. The server lost our clientid */
|
||||||
out:
|
out:
|
||||||
if (prev)
|
nfs_put_client(prev);
|
||||||
nfs_put_client(prev);
|
|
||||||
dprintk("NFS: <-- %s status = %d\n", __func__, status);
|
dprintk("NFS: <-- %s status = %d\n", __func__, status);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -641,8 +635,7 @@ int nfs41_walk_client_list(struct nfs_client *new,
|
||||||
atomic_inc(&pos->cl_count);
|
atomic_inc(&pos->cl_count);
|
||||||
spin_unlock(&nn->nfs_client_lock);
|
spin_unlock(&nn->nfs_client_lock);
|
||||||
|
|
||||||
if (prev)
|
nfs_put_client(prev);
|
||||||
nfs_put_client(prev);
|
|
||||||
prev = pos;
|
prev = pos;
|
||||||
|
|
||||||
status = nfs_wait_client_init_complete(pos);
|
status = nfs_wait_client_init_complete(pos);
|
||||||
|
@ -675,8 +668,7 @@ int nfs41_walk_client_list(struct nfs_client *new,
|
||||||
/* No matching nfs_client found. */
|
/* No matching nfs_client found. */
|
||||||
spin_unlock(&nn->nfs_client_lock);
|
spin_unlock(&nn->nfs_client_lock);
|
||||||
dprintk("NFS: <-- %s status = %d\n", __func__, status);
|
dprintk("NFS: <-- %s status = %d\n", __func__, status);
|
||||||
if (prev)
|
nfs_put_client(prev);
|
||||||
nfs_put_client(prev);
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_NFS_V4_1 */
|
#endif /* CONFIG_NFS_V4_1 */
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
*
|
*
|
||||||
* Copyright (C) 1992 Rick Sladkey
|
* Copyright (C) 1992 Rick Sladkey
|
||||||
*/
|
*/
|
||||||
|
#include <linux/fs.h>
|
||||||
|
#include <linux/falloc.h>
|
||||||
#include <linux/nfs_fs.h>
|
#include <linux/nfs_fs.h>
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "fscache.h"
|
#include "fscache.h"
|
||||||
|
@ -134,6 +136,32 @@ static loff_t nfs4_file_llseek(struct file *filep, loff_t offset, int whence)
|
||||||
return nfs_file_llseek(filep, offset, whence);
|
return nfs_file_llseek(filep, offset, whence);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static long nfs42_fallocate(struct file *filep, int mode, loff_t offset, loff_t len)
|
||||||
|
{
|
||||||
|
struct inode *inode = file_inode(filep);
|
||||||
|
long ret;
|
||||||
|
|
||||||
|
if (!S_ISREG(inode->i_mode))
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
if ((mode != 0) && (mode != (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE)))
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
ret = inode_newsize_ok(inode, offset + len);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
mutex_lock(&inode->i_mutex);
|
||||||
|
if (mode & FALLOC_FL_PUNCH_HOLE)
|
||||||
|
ret = nfs42_proc_deallocate(filep, offset, len);
|
||||||
|
else
|
||||||
|
ret = nfs42_proc_allocate(filep, offset, len);
|
||||||
|
mutex_unlock(&inode->i_mutex);
|
||||||
|
|
||||||
|
nfs_zap_caches(inode);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
#endif /* CONFIG_NFS_V4_2 */
|
#endif /* CONFIG_NFS_V4_2 */
|
||||||
|
|
||||||
const struct file_operations nfs4_file_operations = {
|
const struct file_operations nfs4_file_operations = {
|
||||||
|
@ -155,6 +183,9 @@ const struct file_operations nfs4_file_operations = {
|
||||||
.flock = nfs_flock,
|
.flock = nfs_flock,
|
||||||
.splice_read = nfs_file_splice_read,
|
.splice_read = nfs_file_splice_read,
|
||||||
.splice_write = iter_file_splice_write,
|
.splice_write = iter_file_splice_write,
|
||||||
|
#ifdef CONFIG_NFS_V4_2
|
||||||
|
.fallocate = nfs42_fallocate,
|
||||||
|
#endif /* CONFIG_NFS_V4_2 */
|
||||||
.check_flags = nfs_check_flags,
|
.check_flags = nfs_check_flags,
|
||||||
.setlease = simple_nosetlease,
|
.setlease = simple_nosetlease,
|
||||||
};
|
};
|
||||||
|
|
|
@ -158,8 +158,6 @@ static int nfs4_map_errors(int err)
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
case -NFS4ERR_MINOR_VERS_MISMATCH:
|
case -NFS4ERR_MINOR_VERS_MISMATCH:
|
||||||
return -EPROTONOSUPPORT;
|
return -EPROTONOSUPPORT;
|
||||||
case -NFS4ERR_ACCESS:
|
|
||||||
return -EACCES;
|
|
||||||
case -NFS4ERR_FILE_OPEN:
|
case -NFS4ERR_FILE_OPEN:
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
default:
|
default:
|
||||||
|
@ -344,7 +342,7 @@ static int nfs4_delay(struct rpc_clnt *clnt, long *timeout)
|
||||||
/* This is the error handling routine for processes that are allowed
|
/* This is the error handling routine for processes that are allowed
|
||||||
* to sleep.
|
* to sleep.
|
||||||
*/
|
*/
|
||||||
static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struct nfs4_exception *exception)
|
int nfs4_handle_exception(struct nfs_server *server, int errorcode, struct nfs4_exception *exception)
|
||||||
{
|
{
|
||||||
struct nfs_client *clp = server->nfs_client;
|
struct nfs_client *clp = server->nfs_client;
|
||||||
struct nfs4_state *state = exception->state;
|
struct nfs4_state *state = exception->state;
|
||||||
|
@ -7704,6 +7702,9 @@ nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags)
|
||||||
|
|
||||||
dprintk("--> %s\n", __func__);
|
dprintk("--> %s\n", __func__);
|
||||||
|
|
||||||
|
/* nfs4_layoutget_release calls pnfs_put_layout_hdr */
|
||||||
|
pnfs_get_layout_hdr(NFS_I(inode)->layout);
|
||||||
|
|
||||||
lgp->args.layout.pages = nfs4_alloc_pages(max_pages, gfp_flags);
|
lgp->args.layout.pages = nfs4_alloc_pages(max_pages, gfp_flags);
|
||||||
if (!lgp->args.layout.pages) {
|
if (!lgp->args.layout.pages) {
|
||||||
nfs4_layoutget_release(lgp);
|
nfs4_layoutget_release(lgp);
|
||||||
|
@ -7716,9 +7717,6 @@ nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags)
|
||||||
lgp->res.seq_res.sr_slot = NULL;
|
lgp->res.seq_res.sr_slot = NULL;
|
||||||
nfs4_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0);
|
nfs4_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0);
|
||||||
|
|
||||||
/* nfs4_layoutget_release calls pnfs_put_layout_hdr */
|
|
||||||
pnfs_get_layout_hdr(NFS_I(inode)->layout);
|
|
||||||
|
|
||||||
task = rpc_run_task(&task_setup_data);
|
task = rpc_run_task(&task_setup_data);
|
||||||
if (IS_ERR(task))
|
if (IS_ERR(task))
|
||||||
return ERR_CAST(task);
|
return ERR_CAST(task);
|
||||||
|
@ -8426,6 +8424,8 @@ static const struct nfs4_minor_version_ops nfs_v4_2_minor_ops = {
|
||||||
| NFS_CAP_POSIX_LOCK
|
| NFS_CAP_POSIX_LOCK
|
||||||
| NFS_CAP_STATEID_NFSV41
|
| NFS_CAP_STATEID_NFSV41
|
||||||
| NFS_CAP_ATOMIC_OPEN_V1
|
| NFS_CAP_ATOMIC_OPEN_V1
|
||||||
|
| NFS_CAP_ALLOCATE
|
||||||
|
| NFS_CAP_DEALLOCATE
|
||||||
| NFS_CAP_SEEK,
|
| NFS_CAP_SEEK,
|
||||||
.init_client = nfs41_init_client,
|
.init_client = nfs41_init_client,
|
||||||
.shutdown_client = nfs41_shutdown_client,
|
.shutdown_client = nfs41_shutdown_client,
|
||||||
|
|
|
@ -141,13 +141,15 @@ static int nfs4_stat_to_errno(int);
|
||||||
XDR_QUADLEN(NFS4_VERIFIER_SIZE) + \
|
XDR_QUADLEN(NFS4_VERIFIER_SIZE) + \
|
||||||
XDR_QUADLEN(NFS4_SETCLIENTID_NAMELEN) + \
|
XDR_QUADLEN(NFS4_SETCLIENTID_NAMELEN) + \
|
||||||
1 /* sc_prog */ + \
|
1 /* sc_prog */ + \
|
||||||
XDR_QUADLEN(RPCBIND_MAXNETIDLEN) + \
|
1 + XDR_QUADLEN(RPCBIND_MAXNETIDLEN) + \
|
||||||
XDR_QUADLEN(RPCBIND_MAXUADDRLEN) + \
|
1 + XDR_QUADLEN(RPCBIND_MAXUADDRLEN) + \
|
||||||
1) /* sc_cb_ident */
|
1) /* sc_cb_ident */
|
||||||
#define decode_setclientid_maxsz \
|
#define decode_setclientid_maxsz \
|
||||||
(op_decode_hdr_maxsz + \
|
(op_decode_hdr_maxsz + \
|
||||||
2 + \
|
2 /* clientid */ + \
|
||||||
1024) /* large value for CLID_INUSE */
|
XDR_QUADLEN(NFS4_VERIFIER_SIZE) + \
|
||||||
|
1 + XDR_QUADLEN(RPCBIND_MAXNETIDLEN) + \
|
||||||
|
1 + XDR_QUADLEN(RPCBIND_MAXUADDRLEN))
|
||||||
#define encode_setclientid_confirm_maxsz \
|
#define encode_setclientid_confirm_maxsz \
|
||||||
(op_encode_hdr_maxsz + \
|
(op_encode_hdr_maxsz + \
|
||||||
3 + (NFS4_VERIFIER_SIZE >> 2))
|
3 + (NFS4_VERIFIER_SIZE >> 2))
|
||||||
|
@ -7394,6 +7396,8 @@ struct rpc_procinfo nfs4_procedures[] = {
|
||||||
#endif /* CONFIG_NFS_V4_1 */
|
#endif /* CONFIG_NFS_V4_1 */
|
||||||
#ifdef CONFIG_NFS_V4_2
|
#ifdef CONFIG_NFS_V4_2
|
||||||
PROC(SEEK, enc_seek, dec_seek),
|
PROC(SEEK, enc_seek, dec_seek),
|
||||||
|
PROC(ALLOCATE, enc_allocate, dec_allocate),
|
||||||
|
PROC(DEALLOCATE, enc_deallocate, dec_deallocate),
|
||||||
#endif /* CONFIG_NFS_V4_2 */
|
#endif /* CONFIG_NFS_V4_2 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -258,6 +258,7 @@ bool nfs_page_group_sync_on_bit(struct nfs_page *req, unsigned int bit)
|
||||||
static inline void
|
static inline void
|
||||||
nfs_page_group_init(struct nfs_page *req, struct nfs_page *prev)
|
nfs_page_group_init(struct nfs_page *req, struct nfs_page *prev)
|
||||||
{
|
{
|
||||||
|
struct inode *inode;
|
||||||
WARN_ON_ONCE(prev == req);
|
WARN_ON_ONCE(prev == req);
|
||||||
|
|
||||||
if (!prev) {
|
if (!prev) {
|
||||||
|
@ -276,12 +277,16 @@ nfs_page_group_init(struct nfs_page *req, struct nfs_page *prev)
|
||||||
* nfs_page_group_destroy is called */
|
* nfs_page_group_destroy is called */
|
||||||
kref_get(&req->wb_head->wb_kref);
|
kref_get(&req->wb_head->wb_kref);
|
||||||
|
|
||||||
/* grab extra ref if head request has extra ref from
|
/* grab extra ref and bump the request count if head request
|
||||||
* the write/commit path to handle handoff between write
|
* has extra ref from the write/commit path to handle handoff
|
||||||
* and commit lists */
|
* between write and commit lists. */
|
||||||
if (test_bit(PG_INODE_REF, &prev->wb_head->wb_flags)) {
|
if (test_bit(PG_INODE_REF, &prev->wb_head->wb_flags)) {
|
||||||
|
inode = page_file_mapping(req->wb_page)->host;
|
||||||
set_bit(PG_INODE_REF, &req->wb_flags);
|
set_bit(PG_INODE_REF, &req->wb_flags);
|
||||||
kref_get(&req->wb_kref);
|
kref_get(&req->wb_kref);
|
||||||
|
spin_lock(&inode->i_lock);
|
||||||
|
NFS_I(inode)->nrequests++;
|
||||||
|
spin_unlock(&inode->i_lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -269,7 +269,7 @@ int nfs_readpage(struct file *file, struct page *page)
|
||||||
dprintk("NFS: nfs_readpage (%p %ld@%lu)\n",
|
dprintk("NFS: nfs_readpage (%p %ld@%lu)\n",
|
||||||
page, PAGE_CACHE_SIZE, page_file_index(page));
|
page, PAGE_CACHE_SIZE, page_file_index(page));
|
||||||
nfs_inc_stats(inode, NFSIOS_VFSREADPAGE);
|
nfs_inc_stats(inode, NFSIOS_VFSREADPAGE);
|
||||||
nfs_add_stats(inode, NFSIOS_READPAGES, 1);
|
nfs_inc_stats(inode, NFSIOS_READPAGES);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Try to flush any pending writes to the file..
|
* Try to flush any pending writes to the file..
|
||||||
|
|
|
@ -575,7 +575,7 @@ static int nfs_do_writepage(struct page *page, struct writeback_control *wbc, st
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGE);
|
nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGE);
|
||||||
nfs_add_stats(inode, NFSIOS_WRITEPAGES, 1);
|
nfs_inc_stats(inode, NFSIOS_WRITEPAGES);
|
||||||
|
|
||||||
nfs_pageio_cond_complete(pgio, page_file_index(page));
|
nfs_pageio_cond_complete(pgio, page_file_index(page));
|
||||||
ret = nfs_page_async_flush(pgio, page, wbc->sync_mode == WB_SYNC_NONE);
|
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)
|
||||||
nfs_lock_request(req);
|
nfs_lock_request(req);
|
||||||
|
|
||||||
spin_lock(&inode->i_lock);
|
spin_lock(&inode->i_lock);
|
||||||
if (!nfsi->npages && NFS_PROTO(inode)->have_delegation(inode, FMODE_WRITE))
|
if (!nfsi->nrequests &&
|
||||||
|
NFS_PROTO(inode)->have_delegation(inode, FMODE_WRITE))
|
||||||
inode->i_version++;
|
inode->i_version++;
|
||||||
/*
|
/*
|
||||||
* Swap-space should not get truncated. Hence no need to plug the race
|
* 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)
|
||||||
SetPagePrivate(req->wb_page);
|
SetPagePrivate(req->wb_page);
|
||||||
set_page_private(req->wb_page, (unsigned long)req);
|
set_page_private(req->wb_page, (unsigned long)req);
|
||||||
}
|
}
|
||||||
nfsi->npages++;
|
nfsi->nrequests++;
|
||||||
/* this a head request for a page group - mark it as having an
|
/* this a head request for a page group - mark it as having an
|
||||||
* extra reference so sub groups can follow suit */
|
* extra reference so sub groups can follow suit.
|
||||||
|
* This flag also informs pgio layer when to bump nrequests when
|
||||||
|
* adding subrequests. */
|
||||||
WARN_ON(test_and_set_bit(PG_INODE_REF, &req->wb_flags));
|
WARN_ON(test_and_set_bit(PG_INODE_REF, &req->wb_flags));
|
||||||
kref_get(&req->wb_kref);
|
kref_get(&req->wb_kref);
|
||||||
spin_unlock(&inode->i_lock);
|
spin_unlock(&inode->i_lock);
|
||||||
|
@ -709,7 +712,11 @@ static void nfs_inode_remove_request(struct nfs_page *req)
|
||||||
wake_up_page(head->wb_page, PG_private);
|
wake_up_page(head->wb_page, PG_private);
|
||||||
clear_bit(PG_MAPPED, &head->wb_flags);
|
clear_bit(PG_MAPPED, &head->wb_flags);
|
||||||
}
|
}
|
||||||
nfsi->npages--;
|
nfsi->nrequests--;
|
||||||
|
spin_unlock(&inode->i_lock);
|
||||||
|
} else {
|
||||||
|
spin_lock(&inode->i_lock);
|
||||||
|
nfsi->nrequests--;
|
||||||
spin_unlock(&inode->i_lock);
|
spin_unlock(&inode->i_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1735,7 +1742,7 @@ static int nfs_commit_unstable_pages(struct inode *inode, struct writeback_contr
|
||||||
/* Don't commit yet if this is a non-blocking flush and there
|
/* Don't commit yet if this is a non-blocking flush and there
|
||||||
* are a lot of outstanding writes for this mapping.
|
* are a lot of outstanding writes for this mapping.
|
||||||
*/
|
*/
|
||||||
if (nfsi->commit_info.ncommit <= (nfsi->npages >> 1))
|
if (nfsi->commit_info.ncommit <= (nfsi->nrequests >> 1))
|
||||||
goto out_mark_dirty;
|
goto out_mark_dirty;
|
||||||
|
|
||||||
/* don't wait for the COMMIT response */
|
/* don't wait for the COMMIT response */
|
||||||
|
|
|
@ -17,12 +17,8 @@
|
||||||
* Enable lockd debugging.
|
* Enable lockd debugging.
|
||||||
* Requires RPC_DEBUG.
|
* Requires RPC_DEBUG.
|
||||||
*/
|
*/
|
||||||
#ifdef RPC_DEBUG
|
|
||||||
# define LOCKD_DEBUG 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#undef ifdebug
|
#undef ifdebug
|
||||||
#if defined(RPC_DEBUG) && defined(LOCKD_DEBUG)
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
# define ifdebug(flag) if (unlikely(nlm_debug & NLMDBG_##flag))
|
# define ifdebug(flag) if (unlikely(nlm_debug & NLMDBG_##flag))
|
||||||
#else
|
#else
|
||||||
# define ifdebug(flag) if (0)
|
# define ifdebug(flag) if (0)
|
||||||
|
|
|
@ -490,6 +490,8 @@ enum {
|
||||||
|
|
||||||
/* nfs42 */
|
/* nfs42 */
|
||||||
NFSPROC4_CLNT_SEEK,
|
NFSPROC4_CLNT_SEEK,
|
||||||
|
NFSPROC4_CLNT_ALLOCATE,
|
||||||
|
NFSPROC4_CLNT_DEALLOCATE,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* nfs41 types */
|
/* nfs41 types */
|
||||||
|
|
|
@ -163,7 +163,7 @@ struct nfs_inode {
|
||||||
*/
|
*/
|
||||||
__be32 cookieverf[2];
|
__be32 cookieverf[2];
|
||||||
|
|
||||||
unsigned long npages;
|
unsigned long nrequests;
|
||||||
struct nfs_mds_commit_info commit_info;
|
struct nfs_mds_commit_info commit_info;
|
||||||
|
|
||||||
/* Open contexts for shared mmap writes */
|
/* Open contexts for shared mmap writes */
|
||||||
|
@ -520,7 +520,7 @@ extern void nfs_commit_free(struct nfs_commit_data *data);
|
||||||
static inline int
|
static inline int
|
||||||
nfs_have_writebacks(struct inode *inode)
|
nfs_have_writebacks(struct inode *inode)
|
||||||
{
|
{
|
||||||
return NFS_I(inode)->npages != 0;
|
return NFS_I(inode)->nrequests != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -231,5 +231,7 @@ struct nfs_server {
|
||||||
#define NFS_CAP_ATOMIC_OPEN_V1 (1U << 17)
|
#define NFS_CAP_ATOMIC_OPEN_V1 (1U << 17)
|
||||||
#define NFS_CAP_SECURITY_LABEL (1U << 18)
|
#define NFS_CAP_SECURITY_LABEL (1U << 18)
|
||||||
#define NFS_CAP_SEEK (1U << 19)
|
#define NFS_CAP_SEEK (1U << 19)
|
||||||
|
#define NFS_CAP_ALLOCATE (1U << 20)
|
||||||
|
#define NFS_CAP_DEALLOCATE (1U << 21)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1243,6 +1243,20 @@ nfs_free_pnfs_ds_cinfo(struct pnfs_ds_commit_info *cinfo)
|
||||||
#endif /* CONFIG_NFS_V4_1 */
|
#endif /* CONFIG_NFS_V4_1 */
|
||||||
|
|
||||||
#ifdef CONFIG_NFS_V4_2
|
#ifdef CONFIG_NFS_V4_2
|
||||||
|
struct nfs42_falloc_args {
|
||||||
|
struct nfs4_sequence_args seq_args;
|
||||||
|
|
||||||
|
struct nfs_fh *falloc_fh;
|
||||||
|
nfs4_stateid falloc_stateid;
|
||||||
|
u64 falloc_offset;
|
||||||
|
u64 falloc_length;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct nfs42_falloc_res {
|
||||||
|
struct nfs4_sequence_res seq_res;
|
||||||
|
unsigned int status;
|
||||||
|
};
|
||||||
|
|
||||||
struct nfs42_seek_args {
|
struct nfs42_seek_args {
|
||||||
struct nfs4_sequence_args seq_args;
|
struct nfs4_sequence_args seq_args;
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ struct rpc_cred {
|
||||||
struct rcu_head cr_rcu;
|
struct rcu_head cr_rcu;
|
||||||
struct rpc_auth * cr_auth;
|
struct rpc_auth * cr_auth;
|
||||||
const struct rpc_credops *cr_ops;
|
const struct rpc_credops *cr_ops;
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
unsigned long cr_magic; /* 0x0f4aa4f0 */
|
unsigned long cr_magic; /* 0x0f4aa4f0 */
|
||||||
#endif
|
#endif
|
||||||
unsigned long cr_expire; /* when to gc */
|
unsigned long cr_expire; /* when to gc */
|
||||||
|
|
|
@ -63,6 +63,9 @@ struct rpc_clnt {
|
||||||
struct rpc_rtt cl_rtt_default;
|
struct rpc_rtt cl_rtt_default;
|
||||||
struct rpc_timeout cl_timeout_default;
|
struct rpc_timeout cl_timeout_default;
|
||||||
const struct rpc_program *cl_program;
|
const struct rpc_program *cl_program;
|
||||||
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
|
struct dentry *cl_debugfs; /* debugfs directory */
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -176,5 +179,6 @@ size_t rpc_peeraddr(struct rpc_clnt *, struct sockaddr *, size_t);
|
||||||
const char *rpc_peeraddr2str(struct rpc_clnt *, enum rpc_display_format_t);
|
const char *rpc_peeraddr2str(struct rpc_clnt *, enum rpc_display_format_t);
|
||||||
int rpc_localaddr(struct rpc_clnt *, struct sockaddr *, size_t);
|
int rpc_localaddr(struct rpc_clnt *, struct sockaddr *, size_t);
|
||||||
|
|
||||||
|
const char *rpc_proc_name(const struct rpc_task *task);
|
||||||
#endif /* __KERNEL__ */
|
#endif /* __KERNEL__ */
|
||||||
#endif /* _LINUX_SUNRPC_CLNT_H */
|
#endif /* _LINUX_SUNRPC_CLNT_H */
|
||||||
|
|
|
@ -10,22 +10,10 @@
|
||||||
|
|
||||||
#include <uapi/linux/sunrpc/debug.h>
|
#include <uapi/linux/sunrpc/debug.h>
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Enable RPC debugging/profiling.
|
|
||||||
*/
|
|
||||||
#ifdef CONFIG_SUNRPC_DEBUG
|
|
||||||
#define RPC_DEBUG
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_TRACEPOINTS
|
|
||||||
#define RPC_TRACEPOINTS
|
|
||||||
#endif
|
|
||||||
/* #define RPC_PROFILE */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Debugging macros etc
|
* Debugging macros etc
|
||||||
*/
|
*/
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
extern unsigned int rpc_debug;
|
extern unsigned int rpc_debug;
|
||||||
extern unsigned int nfs_debug;
|
extern unsigned int nfs_debug;
|
||||||
extern unsigned int nfsd_debug;
|
extern unsigned int nfsd_debug;
|
||||||
|
@ -36,7 +24,7 @@ extern unsigned int nlm_debug;
|
||||||
#define dprintk_rcu(args...) dfprintk_rcu(FACILITY, ## args)
|
#define dprintk_rcu(args...) dfprintk_rcu(FACILITY, ## args)
|
||||||
|
|
||||||
#undef ifdebug
|
#undef ifdebug
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
# define ifdebug(fac) if (unlikely(rpc_debug & RPCDBG_##fac))
|
# define ifdebug(fac) if (unlikely(rpc_debug & RPCDBG_##fac))
|
||||||
|
|
||||||
# define dfprintk(fac, args...) \
|
# define dfprintk(fac, args...) \
|
||||||
|
@ -65,9 +53,55 @@ extern unsigned int nlm_debug;
|
||||||
/*
|
/*
|
||||||
* Sysctl interface for RPC debugging
|
* Sysctl interface for RPC debugging
|
||||||
*/
|
*/
|
||||||
#ifdef RPC_DEBUG
|
|
||||||
|
struct rpc_clnt;
|
||||||
|
struct rpc_xprt;
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
void rpc_register_sysctl(void);
|
void rpc_register_sysctl(void);
|
||||||
void rpc_unregister_sysctl(void);
|
void rpc_unregister_sysctl(void);
|
||||||
|
int sunrpc_debugfs_init(void);
|
||||||
|
void sunrpc_debugfs_exit(void);
|
||||||
|
int rpc_clnt_debugfs_register(struct rpc_clnt *);
|
||||||
|
void rpc_clnt_debugfs_unregister(struct rpc_clnt *);
|
||||||
|
int rpc_xprt_debugfs_register(struct rpc_xprt *);
|
||||||
|
void rpc_xprt_debugfs_unregister(struct rpc_xprt *);
|
||||||
|
#else
|
||||||
|
static inline int
|
||||||
|
sunrpc_debugfs_init(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
sunrpc_debugfs_exit(void)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
rpc_clnt_debugfs_register(struct rpc_clnt *clnt)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
rpc_clnt_debugfs_unregister(struct rpc_clnt *clnt)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
rpc_xprt_debugfs_register(struct rpc_xprt *xprt)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
rpc_xprt_debugfs_unregister(struct rpc_xprt *xprt)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _LINUX_SUNRPC_DEBUG_H_ */
|
#endif /* _LINUX_SUNRPC_DEBUG_H_ */
|
||||||
|
|
|
@ -27,10 +27,13 @@
|
||||||
|
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
#include <linux/ktime.h>
|
#include <linux/ktime.h>
|
||||||
|
#include <linux/spinlock.h>
|
||||||
|
|
||||||
#define RPC_IOSTATS_VERS "1.0"
|
#define RPC_IOSTATS_VERS "1.0"
|
||||||
|
|
||||||
struct rpc_iostats {
|
struct rpc_iostats {
|
||||||
|
spinlock_t om_lock;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These counters give an idea about how many request
|
* These counters give an idea about how many request
|
||||||
* transmissions are required, on average, to complete that
|
* transmissions are required, on average, to complete that
|
||||||
|
|
|
@ -79,7 +79,7 @@ struct rpc_task {
|
||||||
unsigned short tk_flags; /* misc flags */
|
unsigned short tk_flags; /* misc flags */
|
||||||
unsigned short tk_timeouts; /* maj timeouts */
|
unsigned short tk_timeouts; /* maj timeouts */
|
||||||
|
|
||||||
#if defined(RPC_DEBUG) || defined(RPC_TRACEPOINTS)
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || IS_ENABLED(CONFIG_TRACEPOINTS)
|
||||||
unsigned short tk_pid; /* debugging aid */
|
unsigned short tk_pid; /* debugging aid */
|
||||||
#endif
|
#endif
|
||||||
unsigned char tk_priority : 2,/* Task priority */
|
unsigned char tk_priority : 2,/* Task priority */
|
||||||
|
@ -187,7 +187,7 @@ struct rpc_wait_queue {
|
||||||
unsigned char nr; /* # tasks remaining for cookie */
|
unsigned char nr; /* # tasks remaining for cookie */
|
||||||
unsigned short qlen; /* total # tasks waiting in queue */
|
unsigned short qlen; /* total # tasks waiting in queue */
|
||||||
struct rpc_timer timer_list;
|
struct rpc_timer timer_list;
|
||||||
#if defined(RPC_DEBUG) || defined(RPC_TRACEPOINTS)
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || IS_ENABLED(CONFIG_TRACEPOINTS)
|
||||||
const char * name;
|
const char * name;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
@ -237,7 +237,7 @@ void rpc_free(void *);
|
||||||
int rpciod_up(void);
|
int rpciod_up(void);
|
||||||
void rpciod_down(void);
|
void rpciod_down(void);
|
||||||
int __rpc_wait_for_completion_task(struct rpc_task *task, wait_bit_action_f *);
|
int __rpc_wait_for_completion_task(struct rpc_task *task, wait_bit_action_f *);
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
struct net;
|
struct net;
|
||||||
void rpc_show_tasks(struct net *);
|
void rpc_show_tasks(struct net *);
|
||||||
#endif
|
#endif
|
||||||
|
@ -251,7 +251,7 @@ static inline int rpc_wait_for_completion_task(struct rpc_task *task)
|
||||||
return __rpc_wait_for_completion_task(task, NULL);
|
return __rpc_wait_for_completion_task(task, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(RPC_DEBUG) || defined (RPC_TRACEPOINTS)
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || IS_ENABLED(CONFIG_TRACEPOINTS)
|
||||||
static inline const char * rpc_qname(const struct rpc_wait_queue *q)
|
static inline const char * rpc_qname(const struct rpc_wait_queue *q)
|
||||||
{
|
{
|
||||||
return ((q && q->name) ? q->name : "unknown");
|
return ((q && q->name) ? q->name : "unknown");
|
||||||
|
|
|
@ -239,6 +239,9 @@ struct rpc_xprt {
|
||||||
struct net *xprt_net;
|
struct net *xprt_net;
|
||||||
const char *servername;
|
const char *servername;
|
||||||
const char *address_strings[RPC_DISPLAY_MAX];
|
const char *address_strings[RPC_DISPLAY_MAX];
|
||||||
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
|
struct dentry *debugfs; /* debugfs directory */
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(CONFIG_SUNRPC_BACKCHANNEL)
|
#if defined(CONFIG_SUNRPC_BACKCHANNEL)
|
||||||
|
|
|
@ -17,6 +17,65 @@ void cleanup_socket_xprt(void);
|
||||||
#define RPC_DEF_MIN_RESVPORT (665U)
|
#define RPC_DEF_MIN_RESVPORT (665U)
|
||||||
#define RPC_DEF_MAX_RESVPORT (1023U)
|
#define RPC_DEF_MAX_RESVPORT (1023U)
|
||||||
|
|
||||||
|
struct sock_xprt {
|
||||||
|
struct rpc_xprt xprt;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Network layer
|
||||||
|
*/
|
||||||
|
struct socket * sock;
|
||||||
|
struct sock * inet;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* State of TCP reply receive
|
||||||
|
*/
|
||||||
|
__be32 tcp_fraghdr,
|
||||||
|
tcp_xid,
|
||||||
|
tcp_calldir;
|
||||||
|
|
||||||
|
u32 tcp_offset,
|
||||||
|
tcp_reclen;
|
||||||
|
|
||||||
|
unsigned long tcp_copied,
|
||||||
|
tcp_flags;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Connection of transports
|
||||||
|
*/
|
||||||
|
struct delayed_work connect_worker;
|
||||||
|
struct sockaddr_storage srcaddr;
|
||||||
|
unsigned short srcport;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* UDP socket buffer size parameters
|
||||||
|
*/
|
||||||
|
size_t rcvsize,
|
||||||
|
sndsize;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Saved socket callback addresses
|
||||||
|
*/
|
||||||
|
void (*old_data_ready)(struct sock *);
|
||||||
|
void (*old_state_change)(struct sock *);
|
||||||
|
void (*old_write_space)(struct sock *);
|
||||||
|
void (*old_error_report)(struct sock *);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TCP receive state flags
|
||||||
|
*/
|
||||||
|
#define TCP_RCV_LAST_FRAG (1UL << 0)
|
||||||
|
#define TCP_RCV_COPY_FRAGHDR (1UL << 1)
|
||||||
|
#define TCP_RCV_COPY_XID (1UL << 2)
|
||||||
|
#define TCP_RCV_COPY_DATA (1UL << 3)
|
||||||
|
#define TCP_RCV_READ_CALLDIR (1UL << 4)
|
||||||
|
#define TCP_RCV_COPY_CALLDIR (1UL << 5)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TCP RPC flags
|
||||||
|
*/
|
||||||
|
#define TCP_RPC_REPLY (1UL << 6)
|
||||||
|
|
||||||
#endif /* __KERNEL__ */
|
#endif /* __KERNEL__ */
|
||||||
|
|
||||||
#endif /* _LINUX_SUNRPC_XPRTSOCK_H */
|
#endif /* _LINUX_SUNRPC_XPRTSOCK_H */
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
#include <linux/sunrpc/sched.h>
|
#include <linux/sunrpc/sched.h>
|
||||||
#include <linux/sunrpc/clnt.h>
|
#include <linux/sunrpc/clnt.h>
|
||||||
|
#include <linux/sunrpc/svc.h>
|
||||||
|
#include <linux/sunrpc/xprtsock.h>
|
||||||
#include <net/tcp_states.h>
|
#include <net/tcp_states.h>
|
||||||
#include <linux/net.h>
|
#include <linux/net.h>
|
||||||
#include <linux/tracepoint.h>
|
#include <linux/tracepoint.h>
|
||||||
|
@ -306,6 +308,164 @@ DEFINE_RPC_SOCKET_EVENT_DONE(rpc_socket_reset_connection);
|
||||||
DEFINE_RPC_SOCKET_EVENT(rpc_socket_close);
|
DEFINE_RPC_SOCKET_EVENT(rpc_socket_close);
|
||||||
DEFINE_RPC_SOCKET_EVENT(rpc_socket_shutdown);
|
DEFINE_RPC_SOCKET_EVENT(rpc_socket_shutdown);
|
||||||
|
|
||||||
|
DECLARE_EVENT_CLASS(rpc_xprt_event,
|
||||||
|
TP_PROTO(struct rpc_xprt *xprt, __be32 xid, int status),
|
||||||
|
|
||||||
|
TP_ARGS(xprt, xid, status),
|
||||||
|
|
||||||
|
TP_STRUCT__entry(
|
||||||
|
__field(__be32, xid)
|
||||||
|
__field(int, status)
|
||||||
|
__string(addr, xprt->address_strings[RPC_DISPLAY_ADDR])
|
||||||
|
__string(port, xprt->address_strings[RPC_DISPLAY_PORT])
|
||||||
|
),
|
||||||
|
|
||||||
|
TP_fast_assign(
|
||||||
|
__entry->xid = xid;
|
||||||
|
__entry->status = status;
|
||||||
|
__assign_str(addr, xprt->address_strings[RPC_DISPLAY_ADDR]);
|
||||||
|
__assign_str(port, xprt->address_strings[RPC_DISPLAY_PORT]);
|
||||||
|
),
|
||||||
|
|
||||||
|
TP_printk("peer=[%s]:%s xid=0x%x status=%d", __get_str(addr),
|
||||||
|
__get_str(port), be32_to_cpu(__entry->xid),
|
||||||
|
__entry->status)
|
||||||
|
);
|
||||||
|
|
||||||
|
DEFINE_EVENT(rpc_xprt_event, xprt_lookup_rqst,
|
||||||
|
TP_PROTO(struct rpc_xprt *xprt, __be32 xid, int status),
|
||||||
|
TP_ARGS(xprt, xid, status));
|
||||||
|
|
||||||
|
DEFINE_EVENT(rpc_xprt_event, xprt_transmit,
|
||||||
|
TP_PROTO(struct rpc_xprt *xprt, __be32 xid, int status),
|
||||||
|
TP_ARGS(xprt, xid, status));
|
||||||
|
|
||||||
|
DEFINE_EVENT(rpc_xprt_event, xprt_complete_rqst,
|
||||||
|
TP_PROTO(struct rpc_xprt *xprt, __be32 xid, int status),
|
||||||
|
TP_ARGS(xprt, xid, status));
|
||||||
|
|
||||||
|
TRACE_EVENT(xs_tcp_data_ready,
|
||||||
|
TP_PROTO(struct rpc_xprt *xprt, int err, unsigned int total),
|
||||||
|
|
||||||
|
TP_ARGS(xprt, err, total),
|
||||||
|
|
||||||
|
TP_STRUCT__entry(
|
||||||
|
__field(int, err)
|
||||||
|
__field(unsigned int, total)
|
||||||
|
__string(addr, xprt ? xprt->address_strings[RPC_DISPLAY_ADDR] :
|
||||||
|
"(null)")
|
||||||
|
__string(port, xprt ? xprt->address_strings[RPC_DISPLAY_PORT] :
|
||||||
|
"(null)")
|
||||||
|
),
|
||||||
|
|
||||||
|
TP_fast_assign(
|
||||||
|
__entry->err = err;
|
||||||
|
__entry->total = total;
|
||||||
|
__assign_str(addr, xprt ?
|
||||||
|
xprt->address_strings[RPC_DISPLAY_ADDR] : "(null)");
|
||||||
|
__assign_str(port, xprt ?
|
||||||
|
xprt->address_strings[RPC_DISPLAY_PORT] : "(null)");
|
||||||
|
),
|
||||||
|
|
||||||
|
TP_printk("peer=[%s]:%s err=%d total=%u", __get_str(addr),
|
||||||
|
__get_str(port), __entry->err, __entry->total)
|
||||||
|
);
|
||||||
|
|
||||||
|
#define rpc_show_sock_xprt_flags(flags) \
|
||||||
|
__print_flags(flags, "|", \
|
||||||
|
{ TCP_RCV_LAST_FRAG, "TCP_RCV_LAST_FRAG" }, \
|
||||||
|
{ TCP_RCV_COPY_FRAGHDR, "TCP_RCV_COPY_FRAGHDR" }, \
|
||||||
|
{ TCP_RCV_COPY_XID, "TCP_RCV_COPY_XID" }, \
|
||||||
|
{ TCP_RCV_COPY_DATA, "TCP_RCV_COPY_DATA" }, \
|
||||||
|
{ TCP_RCV_READ_CALLDIR, "TCP_RCV_READ_CALLDIR" }, \
|
||||||
|
{ TCP_RCV_COPY_CALLDIR, "TCP_RCV_COPY_CALLDIR" }, \
|
||||||
|
{ TCP_RPC_REPLY, "TCP_RPC_REPLY" })
|
||||||
|
|
||||||
|
TRACE_EVENT(xs_tcp_data_recv,
|
||||||
|
TP_PROTO(struct sock_xprt *xs),
|
||||||
|
|
||||||
|
TP_ARGS(xs),
|
||||||
|
|
||||||
|
TP_STRUCT__entry(
|
||||||
|
__string(addr, xs->xprt.address_strings[RPC_DISPLAY_ADDR])
|
||||||
|
__string(port, xs->xprt.address_strings[RPC_DISPLAY_PORT])
|
||||||
|
__field(__be32, xid)
|
||||||
|
__field(unsigned long, flags)
|
||||||
|
__field(unsigned long, copied)
|
||||||
|
__field(unsigned int, reclen)
|
||||||
|
__field(unsigned long, offset)
|
||||||
|
),
|
||||||
|
|
||||||
|
TP_fast_assign(
|
||||||
|
__assign_str(addr, xs->xprt.address_strings[RPC_DISPLAY_ADDR]);
|
||||||
|
__assign_str(port, xs->xprt.address_strings[RPC_DISPLAY_PORT]);
|
||||||
|
__entry->xid = xs->tcp_xid;
|
||||||
|
__entry->flags = xs->tcp_flags;
|
||||||
|
__entry->copied = xs->tcp_copied;
|
||||||
|
__entry->reclen = xs->tcp_reclen;
|
||||||
|
__entry->offset = xs->tcp_offset;
|
||||||
|
),
|
||||||
|
|
||||||
|
TP_printk("peer=[%s]:%s xid=0x%x flags=%s copied=%lu reclen=%u offset=%lu",
|
||||||
|
__get_str(addr), __get_str(port), be32_to_cpu(__entry->xid),
|
||||||
|
rpc_show_sock_xprt_flags(__entry->flags),
|
||||||
|
__entry->copied, __entry->reclen, __entry->offset)
|
||||||
|
);
|
||||||
|
|
||||||
|
TRACE_EVENT(svc_recv,
|
||||||
|
TP_PROTO(struct svc_rqst *rqst, int status),
|
||||||
|
|
||||||
|
TP_ARGS(rqst, status),
|
||||||
|
|
||||||
|
TP_STRUCT__entry(
|
||||||
|
__field(struct sockaddr *, addr)
|
||||||
|
__field(__be32, xid)
|
||||||
|
__field(int, status)
|
||||||
|
),
|
||||||
|
|
||||||
|
TP_fast_assign(
|
||||||
|
__entry->addr = (struct sockaddr *)&rqst->rq_addr;
|
||||||
|
__entry->xid = status > 0 ? rqst->rq_xid : 0;
|
||||||
|
__entry->status = status;
|
||||||
|
),
|
||||||
|
|
||||||
|
TP_printk("addr=%pIScp xid=0x%x status=%d", __entry->addr,
|
||||||
|
be32_to_cpu(__entry->xid), __entry->status)
|
||||||
|
);
|
||||||
|
|
||||||
|
DECLARE_EVENT_CLASS(svc_rqst_status,
|
||||||
|
|
||||||
|
TP_PROTO(struct svc_rqst *rqst, int status),
|
||||||
|
|
||||||
|
TP_ARGS(rqst, status),
|
||||||
|
|
||||||
|
TP_STRUCT__entry(
|
||||||
|
__field(struct sockaddr *, addr)
|
||||||
|
__field(__be32, xid)
|
||||||
|
__field(int, dropme)
|
||||||
|
__field(int, status)
|
||||||
|
),
|
||||||
|
|
||||||
|
TP_fast_assign(
|
||||||
|
__entry->addr = (struct sockaddr *)&rqst->rq_addr;
|
||||||
|
__entry->xid = rqst->rq_xid;
|
||||||
|
__entry->dropme = (int)rqst->rq_dropme;
|
||||||
|
__entry->status = status;
|
||||||
|
),
|
||||||
|
|
||||||
|
TP_printk("addr=%pIScp rq_xid=0x%x dropme=%d status=%d",
|
||||||
|
__entry->addr, be32_to_cpu(__entry->xid), __entry->dropme,
|
||||||
|
__entry->status)
|
||||||
|
);
|
||||||
|
|
||||||
|
DEFINE_EVENT(svc_rqst_status, svc_process,
|
||||||
|
TP_PROTO(struct svc_rqst *rqst, int status),
|
||||||
|
TP_ARGS(rqst, status));
|
||||||
|
|
||||||
|
DEFINE_EVENT(svc_rqst_status, svc_send,
|
||||||
|
TP_PROTO(struct svc_rqst *rqst, int status),
|
||||||
|
TP_ARGS(rqst, status));
|
||||||
|
|
||||||
#endif /* _TRACE_SUNRPC_H */
|
#endif /* _TRACE_SUNRPC_H */
|
||||||
|
|
||||||
#include <trace/define_trace.h>
|
#include <trace/define_trace.h>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
* Enable debugging for nfsd.
|
* Enable debugging for nfsd.
|
||||||
* Requires RPC_DEBUG.
|
* Requires RPC_DEBUG.
|
||||||
*/
|
*/
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
# define NFSD_DEBUG 1
|
# define NFSD_DEBUG 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ config RPCSEC_GSS_KRB5
|
||||||
config SUNRPC_DEBUG
|
config SUNRPC_DEBUG
|
||||||
bool "RPC: Enable dprintk debugging"
|
bool "RPC: Enable dprintk debugging"
|
||||||
depends on SUNRPC && SYSCTL
|
depends on SUNRPC && SYSCTL
|
||||||
|
select DEBUG_FS
|
||||||
help
|
help
|
||||||
This option enables a sysctl-based debugging interface
|
This option enables a sysctl-based debugging interface
|
||||||
that is be used by the 'rpcdebug' utility to turn on or off
|
that is be used by the 'rpcdebug' utility to turn on or off
|
||||||
|
|
|
@ -14,6 +14,7 @@ sunrpc-y := clnt.o xprt.o socklib.o xprtsock.o sched.o \
|
||||||
addr.o rpcb_clnt.o timer.o xdr.o \
|
addr.o rpcb_clnt.o timer.o xdr.o \
|
||||||
sunrpc_syms.o cache.o rpc_pipe.o \
|
sunrpc_syms.o cache.o rpc_pipe.o \
|
||||||
svc_xprt.o
|
svc_xprt.o
|
||||||
|
sunrpc-$(CONFIG_SUNRPC_DEBUG) += debugfs.o
|
||||||
sunrpc-$(CONFIG_SUNRPC_BACKCHANNEL) += backchannel_rqst.o bc_svc.o
|
sunrpc-$(CONFIG_SUNRPC_BACKCHANNEL) += backchannel_rqst.o bc_svc.o
|
||||||
sunrpc-$(CONFIG_PROC_FS) += stats.o
|
sunrpc-$(CONFIG_PROC_FS) += stats.o
|
||||||
sunrpc-$(CONFIG_SYSCTL) += sysctl.o
|
sunrpc-$(CONFIG_SYSCTL) += sysctl.o
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
#include <linux/sunrpc/gss_api.h>
|
#include <linux/sunrpc/gss_api.h>
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
|
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
# define RPCDBG_FACILITY RPCDBG_AUTH
|
# define RPCDBG_FACILITY RPCDBG_AUTH
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -646,7 +646,7 @@ rpcauth_init_cred(struct rpc_cred *cred, const struct auth_cred *acred,
|
||||||
cred->cr_auth = auth;
|
cred->cr_auth = auth;
|
||||||
cred->cr_ops = ops;
|
cred->cr_ops = ops;
|
||||||
cred->cr_expire = jiffies;
|
cred->cr_expire = jiffies;
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
cred->cr_magic = RPCAUTH_CRED_MAGIC;
|
cred->cr_magic = RPCAUTH_CRED_MAGIC;
|
||||||
#endif
|
#endif
|
||||||
cred->cr_uid = acred->uid;
|
cred->cr_uid = acred->uid;
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#include <linux/sunrpc/debug.h>
|
#include <linux/sunrpc/debug.h>
|
||||||
#include <linux/sunrpc/sched.h>
|
#include <linux/sunrpc/sched.h>
|
||||||
|
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
# define RPCDBG_FACILITY RPCDBG_AUTH
|
# define RPCDBG_FACILITY RPCDBG_AUTH
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,7 @@ static unsigned int gss_expired_cred_retry_delay = GSS_RETRY_EXPIRED;
|
||||||
#define GSS_KEY_EXPIRE_TIMEO 240
|
#define GSS_KEY_EXPIRE_TIMEO 240
|
||||||
static unsigned int gss_key_expire_timeo = GSS_KEY_EXPIRE_TIMEO;
|
static unsigned int gss_key_expire_timeo = GSS_KEY_EXPIRE_TIMEO;
|
||||||
|
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
# define RPCDBG_FACILITY RPCDBG_AUTH
|
# define RPCDBG_FACILITY RPCDBG_AUTH
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
#include <linux/sunrpc/gss_asn1.h>
|
#include <linux/sunrpc/gss_asn1.h>
|
||||||
|
|
||||||
|
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
# define RPCDBG_FACILITY RPCDBG_AUTH
|
# define RPCDBG_FACILITY RPCDBG_AUTH
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
#include <linux/sunrpc/gss_krb5.h>
|
#include <linux/sunrpc/gss_krb5.h>
|
||||||
#include <linux/sunrpc/xdr.h>
|
#include <linux/sunrpc/xdr.h>
|
||||||
|
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
# define RPCDBG_FACILITY RPCDBG_AUTH
|
# define RPCDBG_FACILITY RPCDBG_AUTH
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@
|
||||||
#include <linux/sunrpc/xdr.h>
|
#include <linux/sunrpc/xdr.h>
|
||||||
#include <linux/lcm.h>
|
#include <linux/lcm.h>
|
||||||
|
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
# define RPCDBG_FACILITY RPCDBG_AUTH
|
# define RPCDBG_FACILITY RPCDBG_AUTH
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
#include <linux/crypto.h>
|
#include <linux/crypto.h>
|
||||||
#include <linux/sunrpc/gss_krb5_enctypes.h>
|
#include <linux/sunrpc/gss_krb5_enctypes.h>
|
||||||
|
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
# define RPCDBG_FACILITY RPCDBG_AUTH
|
# define RPCDBG_FACILITY RPCDBG_AUTH
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@
|
||||||
#include <linux/random.h>
|
#include <linux/random.h>
|
||||||
#include <linux/crypto.h>
|
#include <linux/crypto.h>
|
||||||
|
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
# define RPCDBG_FACILITY RPCDBG_AUTH
|
# define RPCDBG_FACILITY RPCDBG_AUTH
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
#include <linux/sunrpc/gss_krb5.h>
|
#include <linux/sunrpc/gss_krb5.h>
|
||||||
#include <linux/crypto.h>
|
#include <linux/crypto.h>
|
||||||
|
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
# define RPCDBG_FACILITY RPCDBG_AUTH
|
# define RPCDBG_FACILITY RPCDBG_AUTH
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@
|
||||||
#include <linux/sunrpc/gss_krb5.h>
|
#include <linux/sunrpc/gss_krb5.h>
|
||||||
#include <linux/crypto.h>
|
#include <linux/crypto.h>
|
||||||
|
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
# define RPCDBG_FACILITY RPCDBG_AUTH
|
# define RPCDBG_FACILITY RPCDBG_AUTH
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
#include <linux/pagemap.h>
|
#include <linux/pagemap.h>
|
||||||
#include <linux/crypto.h>
|
#include <linux/crypto.h>
|
||||||
|
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
# define RPCDBG_FACILITY RPCDBG_AUTH
|
# define RPCDBG_FACILITY RPCDBG_AUTH
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@
|
||||||
#include <linux/sunrpc/gss_api.h>
|
#include <linux/sunrpc/gss_api.h>
|
||||||
#include <linux/sunrpc/clnt.h>
|
#include <linux/sunrpc/clnt.h>
|
||||||
|
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
# define RPCDBG_FACILITY RPCDBG_AUTH
|
# define RPCDBG_FACILITY RPCDBG_AUTH
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#include <linux/sunrpc/clnt.h>
|
#include <linux/sunrpc/clnt.h>
|
||||||
#include <linux/sunrpc/xprtsock.h>
|
#include <linux/sunrpc/xprtsock.h>
|
||||||
|
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
# define RPCDBG_FACILITY RPCDBG_AUTH
|
# define RPCDBG_FACILITY RPCDBG_AUTH
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
#include "gss_rpc_upcall.h"
|
#include "gss_rpc_upcall.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
# define RPCDBG_FACILITY RPCDBG_AUTH
|
# define RPCDBG_FACILITY RPCDBG_AUTH
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/sunrpc/clnt.h>
|
#include <linux/sunrpc/clnt.h>
|
||||||
|
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
# define RPCDBG_FACILITY RPCDBG_AUTH
|
# define RPCDBG_FACILITY RPCDBG_AUTH
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -138,7 +138,7 @@ struct rpc_cred null_cred = {
|
||||||
.cr_ops = &null_credops,
|
.cr_ops = &null_credops,
|
||||||
.cr_count = ATOMIC_INIT(1),
|
.cr_count = ATOMIC_INIT(1),
|
||||||
.cr_flags = 1UL << RPCAUTH_CRED_UPTODATE,
|
.cr_flags = 1UL << RPCAUTH_CRED_UPTODATE,
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
.cr_magic = RPCAUTH_CRED_MAGIC,
|
.cr_magic = RPCAUTH_CRED_MAGIC,
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
|
@ -25,7 +25,7 @@ struct unx_cred {
|
||||||
|
|
||||||
#define UNX_WRITESLACK (21 + (UNX_MAXNODENAME >> 2))
|
#define UNX_WRITESLACK (21 + (UNX_MAXNODENAME >> 2))
|
||||||
|
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
# define RPCDBG_FACILITY RPCDBG_AUTH
|
# define RPCDBG_FACILITY RPCDBG_AUTH
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
#include <linux/sunrpc/bc_xprt.h>
|
#include <linux/sunrpc/bc_xprt.h>
|
||||||
|
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
#define RPCDBG_FACILITY RPCDBG_TRANS
|
#define RPCDBG_FACILITY RPCDBG_TRANS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
#include "sunrpc.h"
|
#include "sunrpc.h"
|
||||||
#include "netns.h"
|
#include "netns.h"
|
||||||
|
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
# define RPCDBG_FACILITY RPCDBG_CALL
|
# define RPCDBG_FACILITY RPCDBG_CALL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -305,6 +305,10 @@ static int rpc_client_register(struct rpc_clnt *clnt,
|
||||||
struct super_block *pipefs_sb;
|
struct super_block *pipefs_sb;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
err = rpc_clnt_debugfs_register(clnt);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
pipefs_sb = rpc_get_sb_net(net);
|
pipefs_sb = rpc_get_sb_net(net);
|
||||||
if (pipefs_sb) {
|
if (pipefs_sb) {
|
||||||
err = rpc_setup_pipedir(pipefs_sb, clnt);
|
err = rpc_setup_pipedir(pipefs_sb, clnt);
|
||||||
|
@ -331,6 +335,7 @@ err_auth:
|
||||||
out:
|
out:
|
||||||
if (pipefs_sb)
|
if (pipefs_sb)
|
||||||
rpc_put_sb_net(net);
|
rpc_put_sb_net(net);
|
||||||
|
rpc_clnt_debugfs_unregister(clnt);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -670,6 +675,7 @@ int rpc_switch_client_transport(struct rpc_clnt *clnt,
|
||||||
|
|
||||||
rpc_unregister_client(clnt);
|
rpc_unregister_client(clnt);
|
||||||
__rpc_clnt_remove_pipedir(clnt);
|
__rpc_clnt_remove_pipedir(clnt);
|
||||||
|
rpc_clnt_debugfs_unregister(clnt);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A new transport was created. "clnt" therefore
|
* A new transport was created. "clnt" therefore
|
||||||
|
@ -771,6 +777,7 @@ rpc_free_client(struct rpc_clnt *clnt)
|
||||||
rcu_dereference(clnt->cl_xprt)->servername);
|
rcu_dereference(clnt->cl_xprt)->servername);
|
||||||
if (clnt->cl_parent != clnt)
|
if (clnt->cl_parent != clnt)
|
||||||
parent = clnt->cl_parent;
|
parent = clnt->cl_parent;
|
||||||
|
rpc_clnt_debugfs_unregister(clnt);
|
||||||
rpc_clnt_remove_pipedir(clnt);
|
rpc_clnt_remove_pipedir(clnt);
|
||||||
rpc_unregister_client(clnt);
|
rpc_unregister_client(clnt);
|
||||||
rpc_free_iostats(clnt->cl_metrics);
|
rpc_free_iostats(clnt->cl_metrics);
|
||||||
|
@ -1396,8 +1403,9 @@ rpc_restart_call(struct rpc_task *task)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(rpc_restart_call);
|
EXPORT_SYMBOL_GPL(rpc_restart_call);
|
||||||
|
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
static const char *rpc_proc_name(const struct rpc_task *task)
|
const char
|
||||||
|
*rpc_proc_name(const struct rpc_task *task)
|
||||||
{
|
{
|
||||||
const struct rpc_procinfo *proc = task->tk_msg.rpc_proc;
|
const struct rpc_procinfo *proc = task->tk_msg.rpc_proc;
|
||||||
|
|
||||||
|
@ -2421,7 +2429,7 @@ struct rpc_task *rpc_call_null(struct rpc_clnt *clnt, struct rpc_cred *cred, int
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(rpc_call_null);
|
EXPORT_SYMBOL_GPL(rpc_call_null);
|
||||||
|
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
static void rpc_show_header(void)
|
static void rpc_show_header(void)
|
||||||
{
|
{
|
||||||
printk(KERN_INFO "-pid- flgs status -client- --rqstp- "
|
printk(KERN_INFO "-pid- flgs status -client- --rqstp- "
|
||||||
|
|
292
net/sunrpc/debugfs.c
Normal file
292
net/sunrpc/debugfs.c
Normal file
|
@ -0,0 +1,292 @@
|
||||||
|
/**
|
||||||
|
* debugfs interface for sunrpc
|
||||||
|
*
|
||||||
|
* (c) 2014 Jeff Layton <jlayton@primarydata.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/debugfs.h>
|
||||||
|
#include <linux/sunrpc/sched.h>
|
||||||
|
#include <linux/sunrpc/clnt.h>
|
||||||
|
#include "netns.h"
|
||||||
|
|
||||||
|
static struct dentry *topdir;
|
||||||
|
static struct dentry *rpc_clnt_dir;
|
||||||
|
static struct dentry *rpc_xprt_dir;
|
||||||
|
|
||||||
|
struct rpc_clnt_iter {
|
||||||
|
struct rpc_clnt *clnt;
|
||||||
|
loff_t pos;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
tasks_show(struct seq_file *f, void *v)
|
||||||
|
{
|
||||||
|
u32 xid = 0;
|
||||||
|
struct rpc_task *task = v;
|
||||||
|
struct rpc_clnt *clnt = task->tk_client;
|
||||||
|
const char *rpc_waitq = "none";
|
||||||
|
|
||||||
|
if (RPC_IS_QUEUED(task))
|
||||||
|
rpc_waitq = rpc_qname(task->tk_waitqueue);
|
||||||
|
|
||||||
|
if (task->tk_rqstp)
|
||||||
|
xid = be32_to_cpu(task->tk_rqstp->rq_xid);
|
||||||
|
|
||||||
|
seq_printf(f, "%5u %04x %6d 0x%x 0x%x %8ld %ps %sv%u %s a:%ps q:%s\n",
|
||||||
|
task->tk_pid, task->tk_flags, task->tk_status,
|
||||||
|
clnt->cl_clid, xid, task->tk_timeout, task->tk_ops,
|
||||||
|
clnt->cl_program->name, clnt->cl_vers, rpc_proc_name(task),
|
||||||
|
task->tk_action, rpc_waitq);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
tasks_start(struct seq_file *f, loff_t *ppos)
|
||||||
|
__acquires(&clnt->cl_lock)
|
||||||
|
{
|
||||||
|
struct rpc_clnt_iter *iter = f->private;
|
||||||
|
loff_t pos = *ppos;
|
||||||
|
struct rpc_clnt *clnt = iter->clnt;
|
||||||
|
struct rpc_task *task;
|
||||||
|
|
||||||
|
iter->pos = pos + 1;
|
||||||
|
spin_lock(&clnt->cl_lock);
|
||||||
|
list_for_each_entry(task, &clnt->cl_tasks, tk_task)
|
||||||
|
if (pos-- == 0)
|
||||||
|
return task;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
tasks_next(struct seq_file *f, void *v, loff_t *pos)
|
||||||
|
{
|
||||||
|
struct rpc_clnt_iter *iter = f->private;
|
||||||
|
struct rpc_clnt *clnt = iter->clnt;
|
||||||
|
struct rpc_task *task = v;
|
||||||
|
struct list_head *next = task->tk_task.next;
|
||||||
|
|
||||||
|
++iter->pos;
|
||||||
|
++*pos;
|
||||||
|
|
||||||
|
/* If there's another task on list, return it */
|
||||||
|
if (next == &clnt->cl_tasks)
|
||||||
|
return NULL;
|
||||||
|
return list_entry(next, struct rpc_task, tk_task);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tasks_stop(struct seq_file *f, void *v)
|
||||||
|
__releases(&clnt->cl_lock)
|
||||||
|
{
|
||||||
|
struct rpc_clnt_iter *iter = f->private;
|
||||||
|
struct rpc_clnt *clnt = iter->clnt;
|
||||||
|
|
||||||
|
spin_unlock(&clnt->cl_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct seq_operations tasks_seq_operations = {
|
||||||
|
.start = tasks_start,
|
||||||
|
.next = tasks_next,
|
||||||
|
.stop = tasks_stop,
|
||||||
|
.show = tasks_show,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int tasks_open(struct inode *inode, struct file *filp)
|
||||||
|
{
|
||||||
|
int ret = seq_open_private(filp, &tasks_seq_operations,
|
||||||
|
sizeof(struct rpc_clnt_iter));
|
||||||
|
|
||||||
|
if (!ret) {
|
||||||
|
struct seq_file *seq = filp->private_data;
|
||||||
|
struct rpc_clnt_iter *iter = seq->private;
|
||||||
|
|
||||||
|
iter->clnt = inode->i_private;
|
||||||
|
|
||||||
|
if (!atomic_inc_not_zero(&iter->clnt->cl_count)) {
|
||||||
|
seq_release_private(inode, filp);
|
||||||
|
ret = -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
tasks_release(struct inode *inode, struct file *filp)
|
||||||
|
{
|
||||||
|
struct seq_file *seq = filp->private_data;
|
||||||
|
struct rpc_clnt_iter *iter = seq->private;
|
||||||
|
|
||||||
|
rpc_release_client(iter->clnt);
|
||||||
|
return seq_release_private(inode, filp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct file_operations tasks_fops = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.open = tasks_open,
|
||||||
|
.read = seq_read,
|
||||||
|
.llseek = seq_lseek,
|
||||||
|
.release = tasks_release,
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
rpc_clnt_debugfs_register(struct rpc_clnt *clnt)
|
||||||
|
{
|
||||||
|
int len, err;
|
||||||
|
char name[24]; /* enough for "../../rpc_xprt/ + 8 hex digits + NULL */
|
||||||
|
|
||||||
|
/* Already registered? */
|
||||||
|
if (clnt->cl_debugfs)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
len = snprintf(name, sizeof(name), "%x", clnt->cl_clid);
|
||||||
|
if (len >= sizeof(name))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* make the per-client dir */
|
||||||
|
clnt->cl_debugfs = debugfs_create_dir(name, rpc_clnt_dir);
|
||||||
|
if (!clnt->cl_debugfs)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
/* make tasks file */
|
||||||
|
err = -ENOMEM;
|
||||||
|
if (!debugfs_create_file("tasks", S_IFREG | S_IRUSR, clnt->cl_debugfs,
|
||||||
|
clnt, &tasks_fops))
|
||||||
|
goto out_err;
|
||||||
|
|
||||||
|
err = -EINVAL;
|
||||||
|
rcu_read_lock();
|
||||||
|
len = snprintf(name, sizeof(name), "../../rpc_xprt/%s",
|
||||||
|
rcu_dereference(clnt->cl_xprt)->debugfs->d_name.name);
|
||||||
|
rcu_read_unlock();
|
||||||
|
if (len >= sizeof(name))
|
||||||
|
goto out_err;
|
||||||
|
|
||||||
|
err = -ENOMEM;
|
||||||
|
if (!debugfs_create_symlink("xprt", clnt->cl_debugfs, name))
|
||||||
|
goto out_err;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
out_err:
|
||||||
|
debugfs_remove_recursive(clnt->cl_debugfs);
|
||||||
|
clnt->cl_debugfs = NULL;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rpc_clnt_debugfs_unregister(struct rpc_clnt *clnt)
|
||||||
|
{
|
||||||
|
debugfs_remove_recursive(clnt->cl_debugfs);
|
||||||
|
clnt->cl_debugfs = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
xprt_info_show(struct seq_file *f, void *v)
|
||||||
|
{
|
||||||
|
struct rpc_xprt *xprt = f->private;
|
||||||
|
|
||||||
|
seq_printf(f, "netid: %s\n", xprt->address_strings[RPC_DISPLAY_NETID]);
|
||||||
|
seq_printf(f, "addr: %s\n", xprt->address_strings[RPC_DISPLAY_ADDR]);
|
||||||
|
seq_printf(f, "port: %s\n", xprt->address_strings[RPC_DISPLAY_PORT]);
|
||||||
|
seq_printf(f, "state: 0x%lx\n", xprt->state);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
xprt_info_open(struct inode *inode, struct file *filp)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct rpc_xprt *xprt = inode->i_private;
|
||||||
|
|
||||||
|
ret = single_open(filp, xprt_info_show, xprt);
|
||||||
|
|
||||||
|
if (!ret) {
|
||||||
|
if (!xprt_get(xprt)) {
|
||||||
|
single_release(inode, filp);
|
||||||
|
ret = -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
xprt_info_release(struct inode *inode, struct file *filp)
|
||||||
|
{
|
||||||
|
struct rpc_xprt *xprt = inode->i_private;
|
||||||
|
|
||||||
|
xprt_put(xprt);
|
||||||
|
return single_release(inode, filp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct file_operations xprt_info_fops = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.open = xprt_info_open,
|
||||||
|
.read = seq_read,
|
||||||
|
.llseek = seq_lseek,
|
||||||
|
.release = xprt_info_release,
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
rpc_xprt_debugfs_register(struct rpc_xprt *xprt)
|
||||||
|
{
|
||||||
|
int len, id;
|
||||||
|
static atomic_t cur_id;
|
||||||
|
char name[9]; /* 8 hex digits + NULL term */
|
||||||
|
|
||||||
|
id = (unsigned int)atomic_inc_return(&cur_id);
|
||||||
|
|
||||||
|
len = snprintf(name, sizeof(name), "%x", id);
|
||||||
|
if (len >= sizeof(name))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* make the per-client dir */
|
||||||
|
xprt->debugfs = debugfs_create_dir(name, rpc_xprt_dir);
|
||||||
|
if (!xprt->debugfs)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
/* make tasks file */
|
||||||
|
if (!debugfs_create_file("info", S_IFREG | S_IRUSR, xprt->debugfs,
|
||||||
|
xprt, &xprt_info_fops)) {
|
||||||
|
debugfs_remove_recursive(xprt->debugfs);
|
||||||
|
xprt->debugfs = NULL;
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rpc_xprt_debugfs_unregister(struct rpc_xprt *xprt)
|
||||||
|
{
|
||||||
|
debugfs_remove_recursive(xprt->debugfs);
|
||||||
|
xprt->debugfs = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __exit
|
||||||
|
sunrpc_debugfs_exit(void)
|
||||||
|
{
|
||||||
|
debugfs_remove_recursive(topdir);
|
||||||
|
}
|
||||||
|
|
||||||
|
int __init
|
||||||
|
sunrpc_debugfs_init(void)
|
||||||
|
{
|
||||||
|
topdir = debugfs_create_dir("sunrpc", NULL);
|
||||||
|
if (!topdir)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
rpc_clnt_dir = debugfs_create_dir("rpc_clnt", topdir);
|
||||||
|
if (!rpc_clnt_dir)
|
||||||
|
goto out_remove;
|
||||||
|
|
||||||
|
rpc_xprt_dir = debugfs_create_dir("rpc_xprt", topdir);
|
||||||
|
if (!rpc_xprt_dir)
|
||||||
|
goto out_remove;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
out_remove:
|
||||||
|
debugfs_remove_recursive(topdir);
|
||||||
|
topdir = NULL;
|
||||||
|
out:
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
|
@ -32,7 +32,7 @@
|
||||||
|
|
||||||
#include "netns.h"
|
#include "netns.h"
|
||||||
|
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
# define RPCDBG_FACILITY RPCDBG_BIND
|
# define RPCDBG_FACILITY RPCDBG_BIND
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
#include "sunrpc.h"
|
#include "sunrpc.h"
|
||||||
|
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
#define RPCDBG_FACILITY RPCDBG_SCHED
|
#define RPCDBG_FACILITY RPCDBG_SCHED
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -258,7 +258,7 @@ static int rpc_wait_bit_killable(struct wait_bit_key *key)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(RPC_DEBUG) || defined(RPC_TRACEPOINTS)
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || IS_ENABLED(CONFIG_TRACEPOINTS)
|
||||||
static void rpc_task_set_debuginfo(struct rpc_task *task)
|
static void rpc_task_set_debuginfo(struct rpc_task *task)
|
||||||
{
|
{
|
||||||
static atomic_t rpc_pid;
|
static atomic_t rpc_pid;
|
||||||
|
|
|
@ -116,7 +116,15 @@ EXPORT_SYMBOL_GPL(svc_seq_show);
|
||||||
*/
|
*/
|
||||||
struct rpc_iostats *rpc_alloc_iostats(struct rpc_clnt *clnt)
|
struct rpc_iostats *rpc_alloc_iostats(struct rpc_clnt *clnt)
|
||||||
{
|
{
|
||||||
return kcalloc(clnt->cl_maxproc, sizeof(struct rpc_iostats), GFP_KERNEL);
|
struct rpc_iostats *stats;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
stats = kcalloc(clnt->cl_maxproc, sizeof(*stats), GFP_KERNEL);
|
||||||
|
if (stats) {
|
||||||
|
for (i = 0; i < clnt->cl_maxproc; i++)
|
||||||
|
spin_lock_init(&stats[i].om_lock);
|
||||||
|
}
|
||||||
|
return stats;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(rpc_alloc_iostats);
|
EXPORT_SYMBOL_GPL(rpc_alloc_iostats);
|
||||||
|
|
||||||
|
@ -135,20 +143,21 @@ EXPORT_SYMBOL_GPL(rpc_free_iostats);
|
||||||
* rpc_count_iostats - tally up per-task stats
|
* rpc_count_iostats - tally up per-task stats
|
||||||
* @task: completed rpc_task
|
* @task: completed rpc_task
|
||||||
* @stats: array of stat structures
|
* @stats: array of stat structures
|
||||||
*
|
|
||||||
* Relies on the caller for serialization.
|
|
||||||
*/
|
*/
|
||||||
void rpc_count_iostats(const struct rpc_task *task, struct rpc_iostats *stats)
|
void rpc_count_iostats(const struct rpc_task *task, struct rpc_iostats *stats)
|
||||||
{
|
{
|
||||||
struct rpc_rqst *req = task->tk_rqstp;
|
struct rpc_rqst *req = task->tk_rqstp;
|
||||||
struct rpc_iostats *op_metrics;
|
struct rpc_iostats *op_metrics;
|
||||||
ktime_t delta;
|
ktime_t delta, now;
|
||||||
|
|
||||||
if (!stats || !req)
|
if (!stats || !req)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
now = ktime_get();
|
||||||
op_metrics = &stats[task->tk_msg.rpc_proc->p_statidx];
|
op_metrics = &stats[task->tk_msg.rpc_proc->p_statidx];
|
||||||
|
|
||||||
|
spin_lock(&op_metrics->om_lock);
|
||||||
|
|
||||||
op_metrics->om_ops++;
|
op_metrics->om_ops++;
|
||||||
op_metrics->om_ntrans += req->rq_ntrans;
|
op_metrics->om_ntrans += req->rq_ntrans;
|
||||||
op_metrics->om_timeouts += task->tk_timeouts;
|
op_metrics->om_timeouts += task->tk_timeouts;
|
||||||
|
@ -161,8 +170,10 @@ void rpc_count_iostats(const struct rpc_task *task, struct rpc_iostats *stats)
|
||||||
|
|
||||||
op_metrics->om_rtt = ktime_add(op_metrics->om_rtt, req->rq_rtt);
|
op_metrics->om_rtt = ktime_add(op_metrics->om_rtt, req->rq_rtt);
|
||||||
|
|
||||||
delta = ktime_sub(ktime_get(), task->tk_start);
|
delta = ktime_sub(now, task->tk_start);
|
||||||
op_metrics->om_execute = ktime_add(op_metrics->om_execute, delta);
|
op_metrics->om_execute = ktime_add(op_metrics->om_execute, delta);
|
||||||
|
|
||||||
|
spin_unlock(&op_metrics->om_lock);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(rpc_count_iostats);
|
EXPORT_SYMBOL_GPL(rpc_count_iostats);
|
||||||
|
|
||||||
|
|
|
@ -97,13 +97,20 @@ init_sunrpc(void)
|
||||||
err = register_rpc_pipefs();
|
err = register_rpc_pipefs();
|
||||||
if (err)
|
if (err)
|
||||||
goto out4;
|
goto out4;
|
||||||
#ifdef RPC_DEBUG
|
|
||||||
|
err = sunrpc_debugfs_init();
|
||||||
|
if (err)
|
||||||
|
goto out5;
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
rpc_register_sysctl();
|
rpc_register_sysctl();
|
||||||
#endif
|
#endif
|
||||||
svc_init_xprt_sock(); /* svc sock transport */
|
svc_init_xprt_sock(); /* svc sock transport */
|
||||||
init_socket_xprt(); /* clnt sock transport */
|
init_socket_xprt(); /* clnt sock transport */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
out5:
|
||||||
|
unregister_rpc_pipefs();
|
||||||
out4:
|
out4:
|
||||||
unregister_pernet_subsys(&sunrpc_net_ops);
|
unregister_pernet_subsys(&sunrpc_net_ops);
|
||||||
out3:
|
out3:
|
||||||
|
@ -120,10 +127,11 @@ cleanup_sunrpc(void)
|
||||||
rpcauth_remove_module();
|
rpcauth_remove_module();
|
||||||
cleanup_socket_xprt();
|
cleanup_socket_xprt();
|
||||||
svc_cleanup_xprt_sock();
|
svc_cleanup_xprt_sock();
|
||||||
|
sunrpc_debugfs_exit();
|
||||||
unregister_rpc_pipefs();
|
unregister_rpc_pipefs();
|
||||||
rpc_destroy_mempool();
|
rpc_destroy_mempool();
|
||||||
unregister_pernet_subsys(&sunrpc_net_ops);
|
unregister_pernet_subsys(&sunrpc_net_ops);
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
rpc_unregister_sysctl();
|
rpc_unregister_sysctl();
|
||||||
#endif
|
#endif
|
||||||
rcu_barrier(); /* Wait for completion of call_rcu()'s */
|
rcu_barrier(); /* Wait for completion of call_rcu()'s */
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
#include <linux/sunrpc/clnt.h>
|
#include <linux/sunrpc/clnt.h>
|
||||||
#include <linux/sunrpc/bc_xprt.h>
|
#include <linux/sunrpc/bc_xprt.h>
|
||||||
|
|
||||||
|
#include <trace/events/sunrpc.h>
|
||||||
|
|
||||||
#define RPCDBG_FACILITY RPCDBG_SVCDSP
|
#define RPCDBG_FACILITY RPCDBG_SVCDSP
|
||||||
|
|
||||||
static void svc_unregister(const struct svc_serv *serv, struct net *net);
|
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)
|
||||||
/*
|
/*
|
||||||
* dprintk the given error with the address of the client that caused it.
|
* dprintk the given error with the address of the client that caused it.
|
||||||
*/
|
*/
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
static __printf(2, 3)
|
static __printf(2, 3)
|
||||||
void svc_printk(struct svc_rqst *rqstp, const char *fmt, ...)
|
void svc_printk(struct svc_rqst *rqstp, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
|
@ -1314,24 +1316,25 @@ svc_process(struct svc_rqst *rqstp)
|
||||||
rqstp->rq_res.tail[0].iov_base = NULL;
|
rqstp->rq_res.tail[0].iov_base = NULL;
|
||||||
rqstp->rq_res.tail[0].iov_len = 0;
|
rqstp->rq_res.tail[0].iov_len = 0;
|
||||||
|
|
||||||
rqstp->rq_xid = svc_getu32(argv);
|
|
||||||
|
|
||||||
dir = svc_getnl(argv);
|
dir = svc_getnl(argv);
|
||||||
if (dir != 0) {
|
if (dir != 0) {
|
||||||
/* direction != CALL */
|
/* direction != CALL */
|
||||||
svc_printk(rqstp, "bad direction %d, dropping request\n", dir);
|
svc_printk(rqstp, "bad direction %d, dropping request\n", dir);
|
||||||
serv->sv_stats->rpcbadfmt++;
|
serv->sv_stats->rpcbadfmt++;
|
||||||
svc_drop(rqstp);
|
goto out_drop;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns 1 for send, 0 for drop */
|
/* Returns 1 for send, 0 for drop */
|
||||||
if (svc_process_common(rqstp, argv, resv))
|
if (likely(svc_process_common(rqstp, argv, resv))) {
|
||||||
return svc_send(rqstp);
|
int ret = svc_send(rqstp);
|
||||||
else {
|
|
||||||
svc_drop(rqstp);
|
trace_svc_process(rqstp, ret);
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
out_drop:
|
||||||
|
trace_svc_process(rqstp, 0);
|
||||||
|
svc_drop(rqstp);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_SUNRPC_BACKCHANNEL)
|
#if defined(CONFIG_SUNRPC_BACKCHANNEL)
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <linux/sunrpc/svcsock.h>
|
#include <linux/sunrpc/svcsock.h>
|
||||||
#include <linux/sunrpc/xprt.h>
|
#include <linux/sunrpc/xprt.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <trace/events/sunrpc.h>
|
||||||
|
|
||||||
#define RPCDBG_FACILITY RPCDBG_SVCXPRT
|
#define RPCDBG_FACILITY RPCDBG_SVCXPRT
|
||||||
|
|
||||||
|
@ -773,35 +774,43 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
|
||||||
|
|
||||||
err = svc_alloc_arg(rqstp);
|
err = svc_alloc_arg(rqstp);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
goto out;
|
||||||
|
|
||||||
try_to_freeze();
|
try_to_freeze();
|
||||||
cond_resched();
|
cond_resched();
|
||||||
|
err = -EINTR;
|
||||||
if (signalled() || kthread_should_stop())
|
if (signalled() || kthread_should_stop())
|
||||||
return -EINTR;
|
goto out;
|
||||||
|
|
||||||
xprt = svc_get_next_xprt(rqstp, timeout);
|
xprt = svc_get_next_xprt(rqstp, timeout);
|
||||||
if (IS_ERR(xprt))
|
if (IS_ERR(xprt)) {
|
||||||
return PTR_ERR(xprt);
|
err = PTR_ERR(xprt);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
len = svc_handle_xprt(rqstp, xprt);
|
len = svc_handle_xprt(rqstp, xprt);
|
||||||
|
|
||||||
/* No data, incomplete (TCP) read, or accept() */
|
/* No data, incomplete (TCP) read, or accept() */
|
||||||
|
err = -EAGAIN;
|
||||||
if (len <= 0)
|
if (len <= 0)
|
||||||
goto out;
|
goto out_release;
|
||||||
|
|
||||||
clear_bit(XPT_OLD, &xprt->xpt_flags);
|
clear_bit(XPT_OLD, &xprt->xpt_flags);
|
||||||
|
|
||||||
rqstp->rq_secure = xprt->xpt_ops->xpo_secure_port(rqstp);
|
rqstp->rq_secure = xprt->xpt_ops->xpo_secure_port(rqstp);
|
||||||
rqstp->rq_chandle.defer = svc_defer;
|
rqstp->rq_chandle.defer = svc_defer;
|
||||||
|
rqstp->rq_xid = svc_getu32(&rqstp->rq_arg.head[0]);
|
||||||
|
|
||||||
if (serv->sv_stats)
|
if (serv->sv_stats)
|
||||||
serv->sv_stats->netcnt++;
|
serv->sv_stats->netcnt++;
|
||||||
|
trace_svc_recv(rqstp, len);
|
||||||
return len;
|
return len;
|
||||||
out:
|
out_release:
|
||||||
rqstp->rq_res.len = 0;
|
rqstp->rq_res.len = 0;
|
||||||
svc_xprt_release(rqstp);
|
svc_xprt_release(rqstp);
|
||||||
return -EAGAIN;
|
out:
|
||||||
|
trace_svc_recv(rqstp, err);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(svc_recv);
|
EXPORT_SYMBOL_GPL(svc_recv);
|
||||||
|
|
||||||
|
@ -821,12 +830,12 @@ EXPORT_SYMBOL_GPL(svc_drop);
|
||||||
int svc_send(struct svc_rqst *rqstp)
|
int svc_send(struct svc_rqst *rqstp)
|
||||||
{
|
{
|
||||||
struct svc_xprt *xprt;
|
struct svc_xprt *xprt;
|
||||||
int len;
|
int len = -EFAULT;
|
||||||
struct xdr_buf *xb;
|
struct xdr_buf *xb;
|
||||||
|
|
||||||
xprt = rqstp->rq_xprt;
|
xprt = rqstp->rq_xprt;
|
||||||
if (!xprt)
|
if (!xprt)
|
||||||
return -EFAULT;
|
goto out;
|
||||||
|
|
||||||
/* release the receive skb before sending the reply */
|
/* release the receive skb before sending the reply */
|
||||||
rqstp->rq_xprt->xpt_ops->xpo_release_rqst(rqstp);
|
rqstp->rq_xprt->xpt_ops->xpo_release_rqst(rqstp);
|
||||||
|
@ -849,7 +858,9 @@ int svc_send(struct svc_rqst *rqstp)
|
||||||
svc_xprt_release(rqstp);
|
svc_xprt_release(rqstp);
|
||||||
|
|
||||||
if (len == -ECONNREFUSED || len == -ENOTCONN || len == -EAGAIN)
|
if (len == -ECONNREFUSED || len == -ENOTCONN || len == -EAGAIN)
|
||||||
return 0;
|
len = 0;
|
||||||
|
out:
|
||||||
|
trace_svc_send(rqstp, len);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ EXPORT_SYMBOL_GPL(nfsd_debug);
|
||||||
unsigned int nlm_debug;
|
unsigned int nlm_debug;
|
||||||
EXPORT_SYMBOL_GPL(nlm_debug);
|
EXPORT_SYMBOL_GPL(nlm_debug);
|
||||||
|
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
|
|
||||||
static struct ctl_table_header *sunrpc_table_header;
|
static struct ctl_table_header *sunrpc_table_header;
|
||||||
static struct ctl_table sunrpc_table[];
|
static struct ctl_table sunrpc_table[];
|
||||||
|
|
|
@ -49,13 +49,15 @@
|
||||||
#include <linux/sunrpc/metrics.h>
|
#include <linux/sunrpc/metrics.h>
|
||||||
#include <linux/sunrpc/bc_xprt.h>
|
#include <linux/sunrpc/bc_xprt.h>
|
||||||
|
|
||||||
|
#include <trace/events/sunrpc.h>
|
||||||
|
|
||||||
#include "sunrpc.h"
|
#include "sunrpc.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Local variables
|
* Local variables
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
# define RPCDBG_FACILITY RPCDBG_XPRT
|
# define RPCDBG_FACILITY RPCDBG_XPRT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -772,11 +774,14 @@ struct rpc_rqst *xprt_lookup_rqst(struct rpc_xprt *xprt, __be32 xid)
|
||||||
struct rpc_rqst *entry;
|
struct rpc_rqst *entry;
|
||||||
|
|
||||||
list_for_each_entry(entry, &xprt->recv, rq_list)
|
list_for_each_entry(entry, &xprt->recv, rq_list)
|
||||||
if (entry->rq_xid == xid)
|
if (entry->rq_xid == xid) {
|
||||||
|
trace_xprt_lookup_rqst(xprt, xid, 0);
|
||||||
return entry;
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
dprintk("RPC: xprt_lookup_rqst did not find xid %08x\n",
|
dprintk("RPC: xprt_lookup_rqst did not find xid %08x\n",
|
||||||
ntohl(xid));
|
ntohl(xid));
|
||||||
|
trace_xprt_lookup_rqst(xprt, xid, -ENOENT);
|
||||||
xprt->stat.bad_xids++;
|
xprt->stat.bad_xids++;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -810,6 +815,7 @@ void xprt_complete_rqst(struct rpc_task *task, int copied)
|
||||||
|
|
||||||
dprintk("RPC: %5u xid %08x complete (%d bytes received)\n",
|
dprintk("RPC: %5u xid %08x complete (%d bytes received)\n",
|
||||||
task->tk_pid, ntohl(req->rq_xid), copied);
|
task->tk_pid, ntohl(req->rq_xid), copied);
|
||||||
|
trace_xprt_complete_rqst(xprt, req->rq_xid, copied);
|
||||||
|
|
||||||
xprt->stat.recvs++;
|
xprt->stat.recvs++;
|
||||||
req->rq_rtt = ktime_sub(ktime_get(), req->rq_xtime);
|
req->rq_rtt = ktime_sub(ktime_get(), req->rq_xtime);
|
||||||
|
@ -926,6 +932,7 @@ void xprt_transmit(struct rpc_task *task)
|
||||||
|
|
||||||
req->rq_xtime = ktime_get();
|
req->rq_xtime = ktime_get();
|
||||||
status = xprt->ops->send_request(task);
|
status = xprt->ops->send_request(task);
|
||||||
|
trace_xprt_transmit(xprt, req->rq_xid, status);
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
task->tk_status = status;
|
task->tk_status = status;
|
||||||
return;
|
return;
|
||||||
|
@ -1296,6 +1303,7 @@ static void xprt_init(struct rpc_xprt *xprt, struct net *net)
|
||||||
*/
|
*/
|
||||||
struct rpc_xprt *xprt_create_transport(struct xprt_create *args)
|
struct rpc_xprt *xprt_create_transport(struct xprt_create *args)
|
||||||
{
|
{
|
||||||
|
int err;
|
||||||
struct rpc_xprt *xprt;
|
struct rpc_xprt *xprt;
|
||||||
struct xprt_class *t;
|
struct xprt_class *t;
|
||||||
|
|
||||||
|
@ -1336,6 +1344,12 @@ found:
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = rpc_xprt_debugfs_register(xprt);
|
||||||
|
if (err) {
|
||||||
|
xprt_destroy(xprt);
|
||||||
|
return ERR_PTR(err);
|
||||||
|
}
|
||||||
|
|
||||||
dprintk("RPC: created transport %p with %u slots\n", xprt,
|
dprintk("RPC: created transport %p with %u slots\n", xprt,
|
||||||
xprt->max_reqs);
|
xprt->max_reqs);
|
||||||
out:
|
out:
|
||||||
|
@ -1352,6 +1366,7 @@ static void xprt_destroy(struct rpc_xprt *xprt)
|
||||||
dprintk("RPC: destroying transport %p\n", xprt);
|
dprintk("RPC: destroying transport %p\n", xprt);
|
||||||
del_timer_sync(&xprt->timer);
|
del_timer_sync(&xprt->timer);
|
||||||
|
|
||||||
|
rpc_xprt_debugfs_unregister(xprt);
|
||||||
rpc_destroy_wait_queue(&xprt->binding);
|
rpc_destroy_wait_queue(&xprt->binding);
|
||||||
rpc_destroy_wait_queue(&xprt->pending);
|
rpc_destroy_wait_queue(&xprt->pending);
|
||||||
rpc_destroy_wait_queue(&xprt->sending);
|
rpc_destroy_wait_queue(&xprt->sending);
|
||||||
|
|
|
@ -49,11 +49,11 @@
|
||||||
|
|
||||||
#include <linux/highmem.h>
|
#include <linux/highmem.h>
|
||||||
|
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
# define RPCDBG_FACILITY RPCDBG_TRANS
|
# define RPCDBG_FACILITY RPCDBG_TRANS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
static const char transfertypes[][12] = {
|
static const char transfertypes[][12] = {
|
||||||
"pure inline", /* no chunks */
|
"pure inline", /* no chunks */
|
||||||
" read chunk", /* some argument via rdma read */
|
" read chunk", /* some argument via rdma read */
|
||||||
|
|
|
@ -55,7 +55,7 @@
|
||||||
|
|
||||||
#include "xprt_rdma.h"
|
#include "xprt_rdma.h"
|
||||||
|
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
# define RPCDBG_FACILITY RPCDBG_TRANS
|
# define RPCDBG_FACILITY RPCDBG_TRANS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -73,9 +73,9 @@ static unsigned int xprt_rdma_max_inline_read = RPCRDMA_DEF_INLINE;
|
||||||
static unsigned int xprt_rdma_max_inline_write = RPCRDMA_DEF_INLINE;
|
static unsigned int xprt_rdma_max_inline_write = RPCRDMA_DEF_INLINE;
|
||||||
static unsigned int xprt_rdma_inline_write_padding;
|
static unsigned int xprt_rdma_inline_write_padding;
|
||||||
static unsigned int xprt_rdma_memreg_strategy = RPCRDMA_FRMR;
|
static unsigned int xprt_rdma_memreg_strategy = RPCRDMA_FRMR;
|
||||||
int xprt_rdma_pad_optimize = 0;
|
int xprt_rdma_pad_optimize = 1;
|
||||||
|
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
|
|
||||||
static unsigned int min_slot_table_size = RPCRDMA_MIN_SLOT_TABLE;
|
static unsigned int min_slot_table_size = RPCRDMA_MIN_SLOT_TABLE;
|
||||||
static unsigned int max_slot_table_size = RPCRDMA_MAX_SLOT_TABLE;
|
static unsigned int max_slot_table_size = RPCRDMA_MAX_SLOT_TABLE;
|
||||||
|
@ -599,7 +599,7 @@ xprt_rdma_send_request(struct rpc_task *task)
|
||||||
|
|
||||||
if (req->rl_niovs == 0)
|
if (req->rl_niovs == 0)
|
||||||
rc = rpcrdma_marshal_req(rqst);
|
rc = rpcrdma_marshal_req(rqst);
|
||||||
else if (r_xprt->rx_ia.ri_memreg_strategy == RPCRDMA_FRMR)
|
else if (r_xprt->rx_ia.ri_memreg_strategy != RPCRDMA_ALLPHYSICAL)
|
||||||
rc = rpcrdma_marshal_chunks(rqst, 0);
|
rc = rpcrdma_marshal_chunks(rqst, 0);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
goto failed_marshal;
|
goto failed_marshal;
|
||||||
|
@ -705,7 +705,7 @@ static void __exit xprt_rdma_cleanup(void)
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
dprintk("RPCRDMA Module Removed, deregister RPC RDMA transport\n");
|
dprintk("RPCRDMA Module Removed, deregister RPC RDMA transport\n");
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
if (sunrpc_table_header) {
|
if (sunrpc_table_header) {
|
||||||
unregister_sysctl_table(sunrpc_table_header);
|
unregister_sysctl_table(sunrpc_table_header);
|
||||||
sunrpc_table_header = NULL;
|
sunrpc_table_header = NULL;
|
||||||
|
@ -736,7 +736,7 @@ static int __init xprt_rdma_init(void)
|
||||||
dprintk("\tPadding %d\n\tMemreg %d\n",
|
dprintk("\tPadding %d\n\tMemreg %d\n",
|
||||||
xprt_rdma_inline_write_padding, xprt_rdma_memreg_strategy);
|
xprt_rdma_inline_write_padding, xprt_rdma_memreg_strategy);
|
||||||
|
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
if (!sunrpc_table_header)
|
if (!sunrpc_table_header)
|
||||||
sunrpc_table_header = register_sysctl_table(sunrpc_table);
|
sunrpc_table_header = register_sysctl_table(sunrpc_table);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -57,11 +57,12 @@
|
||||||
* Globals/Macros
|
* Globals/Macros
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
# define RPCDBG_FACILITY RPCDBG_TRANS
|
# define RPCDBG_FACILITY RPCDBG_TRANS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void rpcrdma_reset_frmrs(struct rpcrdma_ia *);
|
static void rpcrdma_reset_frmrs(struct rpcrdma_ia *);
|
||||||
|
static void rpcrdma_reset_fmrs(struct rpcrdma_ia *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* internal functions
|
* internal functions
|
||||||
|
@ -105,13 +106,51 @@ rpcrdma_run_tasklet(unsigned long data)
|
||||||
|
|
||||||
static DECLARE_TASKLET(rpcrdma_tasklet_g, rpcrdma_run_tasklet, 0UL);
|
static DECLARE_TASKLET(rpcrdma_tasklet_g, rpcrdma_run_tasklet, 0UL);
|
||||||
|
|
||||||
|
static const char * const async_event[] = {
|
||||||
|
"CQ error",
|
||||||
|
"QP fatal error",
|
||||||
|
"QP request error",
|
||||||
|
"QP access error",
|
||||||
|
"communication established",
|
||||||
|
"send queue drained",
|
||||||
|
"path migration successful",
|
||||||
|
"path mig error",
|
||||||
|
"device fatal error",
|
||||||
|
"port active",
|
||||||
|
"port error",
|
||||||
|
"LID change",
|
||||||
|
"P_key change",
|
||||||
|
"SM change",
|
||||||
|
"SRQ error",
|
||||||
|
"SRQ limit reached",
|
||||||
|
"last WQE reached",
|
||||||
|
"client reregister",
|
||||||
|
"GID change",
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ASYNC_MSG(status) \
|
||||||
|
((status) < ARRAY_SIZE(async_event) ? \
|
||||||
|
async_event[(status)] : "unknown async error")
|
||||||
|
|
||||||
|
static void
|
||||||
|
rpcrdma_schedule_tasklet(struct list_head *sched_list)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&rpcrdma_tk_lock_g, flags);
|
||||||
|
list_splice_tail(sched_list, &rpcrdma_tasklets_g);
|
||||||
|
spin_unlock_irqrestore(&rpcrdma_tk_lock_g, flags);
|
||||||
|
tasklet_schedule(&rpcrdma_tasklet_g);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rpcrdma_qp_async_error_upcall(struct ib_event *event, void *context)
|
rpcrdma_qp_async_error_upcall(struct ib_event *event, void *context)
|
||||||
{
|
{
|
||||||
struct rpcrdma_ep *ep = context;
|
struct rpcrdma_ep *ep = context;
|
||||||
|
|
||||||
dprintk("RPC: %s: QP error %X on device %s ep %p\n",
|
pr_err("RPC: %s: %s on device %s ep %p\n",
|
||||||
__func__, event->event, event->device->name, context);
|
__func__, ASYNC_MSG(event->event),
|
||||||
|
event->device->name, context);
|
||||||
if (ep->rep_connected == 1) {
|
if (ep->rep_connected == 1) {
|
||||||
ep->rep_connected = -EIO;
|
ep->rep_connected = -EIO;
|
||||||
ep->rep_func(ep);
|
ep->rep_func(ep);
|
||||||
|
@ -124,8 +163,9 @@ rpcrdma_cq_async_error_upcall(struct ib_event *event, void *context)
|
||||||
{
|
{
|
||||||
struct rpcrdma_ep *ep = context;
|
struct rpcrdma_ep *ep = context;
|
||||||
|
|
||||||
dprintk("RPC: %s: CQ error %X on device %s ep %p\n",
|
pr_err("RPC: %s: %s on device %s ep %p\n",
|
||||||
__func__, event->event, event->device->name, context);
|
__func__, ASYNC_MSG(event->event),
|
||||||
|
event->device->name, context);
|
||||||
if (ep->rep_connected == 1) {
|
if (ep->rep_connected == 1) {
|
||||||
ep->rep_connected = -EIO;
|
ep->rep_connected = -EIO;
|
||||||
ep->rep_func(ep);
|
ep->rep_func(ep);
|
||||||
|
@ -243,7 +283,6 @@ rpcrdma_recvcq_poll(struct ib_cq *cq, struct rpcrdma_ep *ep)
|
||||||
struct list_head sched_list;
|
struct list_head sched_list;
|
||||||
struct ib_wc *wcs;
|
struct ib_wc *wcs;
|
||||||
int budget, count, rc;
|
int budget, count, rc;
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(&sched_list);
|
INIT_LIST_HEAD(&sched_list);
|
||||||
budget = RPCRDMA_WC_BUDGET / RPCRDMA_POLLSIZE;
|
budget = RPCRDMA_WC_BUDGET / RPCRDMA_POLLSIZE;
|
||||||
|
@ -261,10 +300,7 @@ rpcrdma_recvcq_poll(struct ib_cq *cq, struct rpcrdma_ep *ep)
|
||||||
rc = 0;
|
rc = 0;
|
||||||
|
|
||||||
out_schedule:
|
out_schedule:
|
||||||
spin_lock_irqsave(&rpcrdma_tk_lock_g, flags);
|
rpcrdma_schedule_tasklet(&sched_list);
|
||||||
list_splice_tail(&sched_list, &rpcrdma_tasklets_g);
|
|
||||||
spin_unlock_irqrestore(&rpcrdma_tk_lock_g, flags);
|
|
||||||
tasklet_schedule(&rpcrdma_tasklet_g);
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,11 +345,18 @@ rpcrdma_recvcq_upcall(struct ib_cq *cq, void *cq_context)
|
||||||
static void
|
static void
|
||||||
rpcrdma_flush_cqs(struct rpcrdma_ep *ep)
|
rpcrdma_flush_cqs(struct rpcrdma_ep *ep)
|
||||||
{
|
{
|
||||||
rpcrdma_recvcq_upcall(ep->rep_attr.recv_cq, ep);
|
struct ib_wc wc;
|
||||||
rpcrdma_sendcq_upcall(ep->rep_attr.send_cq, ep);
|
LIST_HEAD(sched_list);
|
||||||
|
|
||||||
|
while (ib_poll_cq(ep->rep_attr.recv_cq, 1, &wc) > 0)
|
||||||
|
rpcrdma_recvcq_process_wc(&wc, &sched_list);
|
||||||
|
if (!list_empty(&sched_list))
|
||||||
|
rpcrdma_schedule_tasklet(&sched_list);
|
||||||
|
while (ib_poll_cq(ep->rep_attr.send_cq, 1, &wc) > 0)
|
||||||
|
rpcrdma_sendcq_process_wc(&wc);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
static const char * const conn[] = {
|
static const char * const conn[] = {
|
||||||
"address resolved",
|
"address resolved",
|
||||||
"address error",
|
"address error",
|
||||||
|
@ -344,7 +387,7 @@ rpcrdma_conn_upcall(struct rdma_cm_id *id, struct rdma_cm_event *event)
|
||||||
struct rpcrdma_xprt *xprt = id->context;
|
struct rpcrdma_xprt *xprt = id->context;
|
||||||
struct rpcrdma_ia *ia = &xprt->rx_ia;
|
struct rpcrdma_ia *ia = &xprt->rx_ia;
|
||||||
struct rpcrdma_ep *ep = &xprt->rx_ep;
|
struct rpcrdma_ep *ep = &xprt->rx_ep;
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
struct sockaddr_in *addr = (struct sockaddr_in *) &ep->rep_remote_addr;
|
struct sockaddr_in *addr = (struct sockaddr_in *) &ep->rep_remote_addr;
|
||||||
#endif
|
#endif
|
||||||
struct ib_qp_attr attr;
|
struct ib_qp_attr attr;
|
||||||
|
@ -408,7 +451,7 @@ connected:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
if (connstate == 1) {
|
if (connstate == 1) {
|
||||||
int ird = attr.max_dest_rd_atomic;
|
int ird = attr.max_dest_rd_atomic;
|
||||||
int tird = ep->rep_remote_cma.responder_resources;
|
int tird = ep->rep_remote_cma.responder_resources;
|
||||||
|
@ -733,7 +776,9 @@ rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia,
|
||||||
|
|
||||||
/* set trigger for requesting send completion */
|
/* set trigger for requesting send completion */
|
||||||
ep->rep_cqinit = ep->rep_attr.cap.max_send_wr/2 - 1;
|
ep->rep_cqinit = ep->rep_attr.cap.max_send_wr/2 - 1;
|
||||||
if (ep->rep_cqinit <= 2)
|
if (ep->rep_cqinit > RPCRDMA_MAX_UNSIGNALED_SENDS)
|
||||||
|
ep->rep_cqinit = RPCRDMA_MAX_UNSIGNALED_SENDS;
|
||||||
|
else if (ep->rep_cqinit <= 2)
|
||||||
ep->rep_cqinit = 0;
|
ep->rep_cqinit = 0;
|
||||||
INIT_CQCOUNT(ep);
|
INIT_CQCOUNT(ep);
|
||||||
ep->rep_ia = ia;
|
ep->rep_ia = ia;
|
||||||
|
@ -866,8 +911,19 @@ retry:
|
||||||
rpcrdma_ep_disconnect(ep, ia);
|
rpcrdma_ep_disconnect(ep, ia);
|
||||||
rpcrdma_flush_cqs(ep);
|
rpcrdma_flush_cqs(ep);
|
||||||
|
|
||||||
if (ia->ri_memreg_strategy == RPCRDMA_FRMR)
|
switch (ia->ri_memreg_strategy) {
|
||||||
|
case RPCRDMA_FRMR:
|
||||||
rpcrdma_reset_frmrs(ia);
|
rpcrdma_reset_frmrs(ia);
|
||||||
|
break;
|
||||||
|
case RPCRDMA_MTHCAFMR:
|
||||||
|
rpcrdma_reset_fmrs(ia);
|
||||||
|
break;
|
||||||
|
case RPCRDMA_ALLPHYSICAL:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
rc = -EIO;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
xprt = container_of(ia, struct rpcrdma_xprt, rx_ia);
|
xprt = container_of(ia, struct rpcrdma_xprt, rx_ia);
|
||||||
id = rpcrdma_create_id(xprt, ia,
|
id = rpcrdma_create_id(xprt, ia,
|
||||||
|
@ -1287,6 +1343,34 @@ rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf)
|
||||||
kfree(buf->rb_pool);
|
kfree(buf->rb_pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* After a disconnect, unmap all FMRs.
|
||||||
|
*
|
||||||
|
* This is invoked only in the transport connect worker in order
|
||||||
|
* to serialize with rpcrdma_register_fmr_external().
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
rpcrdma_reset_fmrs(struct rpcrdma_ia *ia)
|
||||||
|
{
|
||||||
|
struct rpcrdma_xprt *r_xprt =
|
||||||
|
container_of(ia, struct rpcrdma_xprt, rx_ia);
|
||||||
|
struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
|
||||||
|
struct list_head *pos;
|
||||||
|
struct rpcrdma_mw *r;
|
||||||
|
LIST_HEAD(l);
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
list_for_each(pos, &buf->rb_all) {
|
||||||
|
r = list_entry(pos, struct rpcrdma_mw, mw_all);
|
||||||
|
|
||||||
|
INIT_LIST_HEAD(&l);
|
||||||
|
list_add(&r->r.fmr->list, &l);
|
||||||
|
rc = ib_unmap_fmr(&l);
|
||||||
|
if (rc)
|
||||||
|
dprintk("RPC: %s: ib_unmap_fmr failed %i\n",
|
||||||
|
__func__, rc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* After a disconnect, a flushed FAST_REG_MR can leave an FRMR in
|
/* After a disconnect, a flushed FAST_REG_MR can leave an FRMR in
|
||||||
* an unusable state. Find FRMRs in this state and dereg / reg
|
* an unusable state. Find FRMRs in this state and dereg / reg
|
||||||
* each. FRMRs that are VALID and attached to an rpcrdma_req are
|
* each. FRMRs that are VALID and attached to an rpcrdma_req are
|
||||||
|
@ -1918,10 +2002,10 @@ rpcrdma_register_external(struct rpcrdma_mr_seg *seg,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -EIO;
|
||||||
}
|
}
|
||||||
if (rc)
|
if (rc)
|
||||||
return -1;
|
return rc;
|
||||||
|
|
||||||
return nsegs;
|
return nsegs;
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,6 +97,12 @@ struct rpcrdma_ep {
|
||||||
struct ib_wc rep_recv_wcs[RPCRDMA_POLLSIZE];
|
struct ib_wc rep_recv_wcs[RPCRDMA_POLLSIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Force a signaled SEND Work Request every so often,
|
||||||
|
* in case the provider needs to do some housekeeping.
|
||||||
|
*/
|
||||||
|
#define RPCRDMA_MAX_UNSIGNALED_SENDS (32)
|
||||||
|
|
||||||
#define INIT_CQCOUNT(ep) atomic_set(&(ep)->rep_cqcount, (ep)->rep_cqinit)
|
#define INIT_CQCOUNT(ep) atomic_set(&(ep)->rep_cqcount, (ep)->rep_cqinit)
|
||||||
#define DECR_CQCOUNT(ep) atomic_sub_return(1, &(ep)->rep_cqcount)
|
#define DECR_CQCOUNT(ep) atomic_sub_return(1, &(ep)->rep_cqcount)
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ static unsigned int xs_tcp_fin_timeout __read_mostly = XS_TCP_LINGER_TO;
|
||||||
* someone else's file names!
|
* someone else's file names!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
|
|
||||||
static unsigned int min_slot_table_size = RPC_MIN_SLOT_TABLE;
|
static unsigned int min_slot_table_size = RPC_MIN_SLOT_TABLE;
|
||||||
static unsigned int max_slot_table_size = RPC_MAX_SLOT_TABLE;
|
static unsigned int max_slot_table_size = RPC_MAX_SLOT_TABLE;
|
||||||
|
@ -186,7 +186,7 @@ static struct ctl_table sunrpc_table[] = {
|
||||||
*/
|
*/
|
||||||
#define XS_IDLE_DISC_TO (5U * 60 * HZ)
|
#define XS_IDLE_DISC_TO (5U * 60 * HZ)
|
||||||
|
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
# undef RPC_DEBUG_DATA
|
# undef RPC_DEBUG_DATA
|
||||||
# define RPCDBG_FACILITY RPCDBG_TRANS
|
# define RPCDBG_FACILITY RPCDBG_TRANS
|
||||||
#endif
|
#endif
|
||||||
|
@ -216,65 +216,6 @@ static inline void xs_pktdump(char *msg, u32 *packet, unsigned int count)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct sock_xprt {
|
|
||||||
struct rpc_xprt xprt;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Network layer
|
|
||||||
*/
|
|
||||||
struct socket * sock;
|
|
||||||
struct sock * inet;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* State of TCP reply receive
|
|
||||||
*/
|
|
||||||
__be32 tcp_fraghdr,
|
|
||||||
tcp_xid,
|
|
||||||
tcp_calldir;
|
|
||||||
|
|
||||||
u32 tcp_offset,
|
|
||||||
tcp_reclen;
|
|
||||||
|
|
||||||
unsigned long tcp_copied,
|
|
||||||
tcp_flags;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Connection of transports
|
|
||||||
*/
|
|
||||||
struct delayed_work connect_worker;
|
|
||||||
struct sockaddr_storage srcaddr;
|
|
||||||
unsigned short srcport;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* UDP socket buffer size parameters
|
|
||||||
*/
|
|
||||||
size_t rcvsize,
|
|
||||||
sndsize;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Saved socket callback addresses
|
|
||||||
*/
|
|
||||||
void (*old_data_ready)(struct sock *);
|
|
||||||
void (*old_state_change)(struct sock *);
|
|
||||||
void (*old_write_space)(struct sock *);
|
|
||||||
void (*old_error_report)(struct sock *);
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* TCP receive state flags
|
|
||||||
*/
|
|
||||||
#define TCP_RCV_LAST_FRAG (1UL << 0)
|
|
||||||
#define TCP_RCV_COPY_FRAGHDR (1UL << 1)
|
|
||||||
#define TCP_RCV_COPY_XID (1UL << 2)
|
|
||||||
#define TCP_RCV_COPY_DATA (1UL << 3)
|
|
||||||
#define TCP_RCV_READ_CALLDIR (1UL << 4)
|
|
||||||
#define TCP_RCV_COPY_CALLDIR (1UL << 5)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* TCP RPC flags
|
|
||||||
*/
|
|
||||||
#define TCP_RPC_REPLY (1UL << 6)
|
|
||||||
|
|
||||||
static inline struct rpc_xprt *xprt_from_sock(struct sock *sk)
|
static inline struct rpc_xprt *xprt_from_sock(struct sock *sk)
|
||||||
{
|
{
|
||||||
return (struct rpc_xprt *) sk->sk_user_data;
|
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
|
||||||
|
|
||||||
dprintk("RPC: xs_tcp_data_recv started\n");
|
dprintk("RPC: xs_tcp_data_recv started\n");
|
||||||
do {
|
do {
|
||||||
|
trace_xs_tcp_data_recv(transport);
|
||||||
/* Read in a new fragment marker if necessary */
|
/* Read in a new fragment marker if necessary */
|
||||||
/* Can we ever really expect to get completely empty fragments? */
|
/* Can we ever really expect to get completely empty fragments? */
|
||||||
if (transport->tcp_flags & TCP_RCV_COPY_FRAGHDR) {
|
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
|
||||||
/* Skip over any trailing bytes on short reads */
|
/* Skip over any trailing bytes on short reads */
|
||||||
xs_tcp_read_discard(transport, &desc);
|
xs_tcp_read_discard(transport, &desc);
|
||||||
} while (desc.count);
|
} while (desc.count);
|
||||||
|
trace_xs_tcp_data_recv(transport);
|
||||||
dprintk("RPC: xs_tcp_data_recv done\n");
|
dprintk("RPC: xs_tcp_data_recv done\n");
|
||||||
return len - desc.count;
|
return len - desc.count;
|
||||||
}
|
}
|
||||||
|
@ -1454,12 +1397,15 @@ static void xs_tcp_data_ready(struct sock *sk)
|
||||||
struct rpc_xprt *xprt;
|
struct rpc_xprt *xprt;
|
||||||
read_descriptor_t rd_desc;
|
read_descriptor_t rd_desc;
|
||||||
int read;
|
int read;
|
||||||
|
unsigned long total = 0;
|
||||||
|
|
||||||
dprintk("RPC: xs_tcp_data_ready...\n");
|
dprintk("RPC: xs_tcp_data_ready...\n");
|
||||||
|
|
||||||
read_lock_bh(&sk->sk_callback_lock);
|
read_lock_bh(&sk->sk_callback_lock);
|
||||||
if (!(xprt = xprt_from_sock(sk)))
|
if (!(xprt = xprt_from_sock(sk))) {
|
||||||
|
read = 0;
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
/* Any data means we had a useful conversation, so
|
/* Any data means we had a useful conversation, so
|
||||||
* the we don't need to delay the next reconnect
|
* the we don't need to delay the next reconnect
|
||||||
*/
|
*/
|
||||||
|
@ -1471,8 +1417,11 @@ static void xs_tcp_data_ready(struct sock *sk)
|
||||||
do {
|
do {
|
||||||
rd_desc.count = 65536;
|
rd_desc.count = 65536;
|
||||||
read = tcp_read_sock(sk, &rd_desc, xs_tcp_data_recv);
|
read = tcp_read_sock(sk, &rd_desc, xs_tcp_data_recv);
|
||||||
|
if (read > 0)
|
||||||
|
total += read;
|
||||||
} while (read > 0);
|
} while (read > 0);
|
||||||
out:
|
out:
|
||||||
|
trace_xs_tcp_data_ready(xprt, read, total);
|
||||||
read_unlock_bh(&sk->sk_callback_lock);
|
read_unlock_bh(&sk->sk_callback_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3042,7 +2991,7 @@ static struct xprt_class xs_bc_tcp_transport = {
|
||||||
*/
|
*/
|
||||||
int init_socket_xprt(void)
|
int init_socket_xprt(void)
|
||||||
{
|
{
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
if (!sunrpc_table_header)
|
if (!sunrpc_table_header)
|
||||||
sunrpc_table_header = register_sysctl_table(sunrpc_table);
|
sunrpc_table_header = register_sysctl_table(sunrpc_table);
|
||||||
#endif
|
#endif
|
||||||
|
@ -3061,7 +3010,7 @@ int init_socket_xprt(void)
|
||||||
*/
|
*/
|
||||||
void cleanup_socket_xprt(void)
|
void cleanup_socket_xprt(void)
|
||||||
{
|
{
|
||||||
#ifdef RPC_DEBUG
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
if (sunrpc_table_header) {
|
if (sunrpc_table_header) {
|
||||||
unregister_sysctl_table(sunrpc_table_header);
|
unregister_sysctl_table(sunrpc_table_header);
|
||||||
sunrpc_table_header = NULL;
|
sunrpc_table_header = NULL;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue