* [PATCH 1/2] NFSv3: Improve NFSv3 performance when server returns no post-op attributes
@ 2018-09-24 22:01 Trond Myklebust
2018-09-24 22:01 ` [PATCH 2/2] NFSv4: Save a few bytes in the nfs_pgio_args/res Trond Myklebust
2018-09-25 5:06 ` [PATCH 1/2] NFSv3: Improve NFSv3 performance when server returns no post-op attributes kbuild test robot
0 siblings, 2 replies; 3+ messages in thread
From: Trond Myklebust @ 2018-09-24 22:01 UTC (permalink / raw)
To: linux-nfs
From: Trond Myklebust <trond.myklebust@primarydata.com>
When the server fails to return post-op attributes, the client's
attempt to place read data directly in the page cache fails, and
so we have to do an extra copy in order to realign the data with
page borders.
This patch attempts to detect servers that don't return post-op
attributes on read (e.g. for pNFS) and adjusts the placement
calculation accordingly.
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
---
fs/nfs/nfs3proc.c | 5 +++++
fs/nfs/nfs3xdr.c | 7 ++++++-
include/linux/nfs_fs_sb.h | 3 +++
include/linux/nfs_xdr.h | 3 ++-
4 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index ec8a9efa268f..71bc16225b98 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -786,6 +786,7 @@ nfs3_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
static int nfs3_read_done(struct rpc_task *task, struct nfs_pgio_header *hdr)
{
struct inode *inode = hdr->inode;
+ struct nfs_server *server = NFS_SERVER(inode);
if (hdr->pgio_done_cb != NULL)
return hdr->pgio_done_cb(task, hdr);
@@ -793,6 +794,9 @@ static int nfs3_read_done(struct rpc_task *task, struct nfs_pgio_header *hdr)
if (nfs3_async_handle_jukebox(task, inode))
return -EAGAIN;
+ if (task->tk_status >= 0 && !server->read_hdrsize)
+ cmpxchg(&server->read_hdrsize, 0, hdr->res.replen);
+
nfs_invalidate_atime(inode);
nfs_refresh_inode(inode, &hdr->fattr);
return 0;
@@ -802,6 +806,7 @@ static void nfs3_proc_read_setup(struct nfs_pgio_header *hdr,
struct rpc_message *msg)
{
msg->rpc_proc = &nfs3_procedures[NFS3PROC_READ];
+ hdr->args.replen = NFS_SERVER(hdr->inode)->read_hdrsize;
}
static int nfs3_proc_pgio_rpc_prepare(struct rpc_task *task,
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c
index d8c4c10b15f7..91ae2667f9e4 100644
--- a/fs/nfs/nfs3xdr.c
+++ b/fs/nfs/nfs3xdr.c
@@ -983,10 +983,11 @@ static void nfs3_xdr_enc_read3args(struct rpc_rqst *req,
const void *data)
{
const struct nfs_pgio_args *args = data;
+ unsigned int replen = args->replen ? args->replen : NFS3_readres_sz;
encode_read3args(xdr, args);
prepare_reply_buffer(req, args->pages, args->pgbase,
- args->count, NFS3_readres_sz);
+ args->count, replen);
req->rq_rcv_buf.flags |= XDRBUF_READ;
}
@@ -1675,9 +1676,12 @@ static int nfs3_xdr_dec_read3res(struct rpc_rqst *req, struct xdr_stream *xdr,
void *data)
{
struct nfs_pgio_res *result = data;
+ struct nfs_server *server = result->server;
+ unsigned int replen, pos;
enum nfs_stat status;
int error;
+ pos = xdr_stream_pos(xdr);
error = decode_nfsstat3(xdr, &status);
if (unlikely(error))
goto out;
@@ -1687,6 +1691,7 @@ static int nfs3_xdr_dec_read3res(struct rpc_rqst *req, struct xdr_stream *xdr,
result->op_status = status;
if (status != NFS3_OK)
goto out_status;
+ result->replen = 3 + ((xdr_stream_pos(xdr) - pos) >> 2);
error = decode_read3resok(xdr, result);
out:
return error;
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index bf39d9c92201..0fc0b9135d46 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -228,6 +228,9 @@ struct nfs_server {
unsigned short mountd_port;
unsigned short mountd_protocol;
struct rpc_wait_queue uoc_rpcwaitq;
+
+ /* XDR related information */
+ unsigned int read_hdrsize;
};
/* Server capabilities */
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index bd1c889a9ed9..7f5535e5e852 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -608,6 +608,7 @@ struct nfs_pgio_args {
__u32 count;
unsigned int pgbase;
struct page ** pages;
+ unsigned int replen; /* used by read */
const u32 * bitmask; /* used by write */
enum nfs3_stable_how stable; /* used by write */
};
@@ -618,9 +619,9 @@ struct nfs_pgio_res {
__u32 count;
__u32 op_status;
int eof; /* used by read */
+ unsigned int replen; /* used by read */
struct nfs_writeverf * verf; /* used by write */
const struct nfs_server *server; /* used by write */
-
};
/*
--
2.17.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH 2/2] NFSv4: Save a few bytes in the nfs_pgio_args/res
2018-09-24 22:01 [PATCH 1/2] NFSv3: Improve NFSv3 performance when server returns no post-op attributes Trond Myklebust
@ 2018-09-24 22:01 ` Trond Myklebust
2018-09-25 5:06 ` [PATCH 1/2] NFSv3: Improve NFSv3 performance when server returns no post-op attributes kbuild test robot
1 sibling, 0 replies; 3+ messages in thread
From: Trond Myklebust @ 2018-09-24 22:01 UTC (permalink / raw)
To: linux-nfs
Save a few bytes by allowing the read/write specific fields of the
structures to share storage.
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
---
include/linux/nfs_xdr.h | 24 +++++++++++++++++-------
1 file changed, 17 insertions(+), 7 deletions(-)
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 7f5535e5e852..7981498239f6 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -608,9 +608,13 @@ struct nfs_pgio_args {
__u32 count;
unsigned int pgbase;
struct page ** pages;
- unsigned int replen; /* used by read */
- const u32 * bitmask; /* used by write */
- enum nfs3_stable_how stable; /* used by write */
+ union {
+ unsigned int replen; /* used by read */
+ struct {
+ const u32 * bitmask; /* used by write */
+ enum nfs3_stable_how stable; /* used by write */
+ };
+ };
};
struct nfs_pgio_res {
@@ -618,10 +622,16 @@ struct nfs_pgio_res {
struct nfs_fattr * fattr;
__u32 count;
__u32 op_status;
- int eof; /* used by read */
- unsigned int replen; /* used by read */
- struct nfs_writeverf * verf; /* used by write */
- const struct nfs_server *server; /* used by write */
+ union {
+ struct {
+ int eof; /* used by read */
+ unsigned int replen; /* used by read */
+ };
+ struct {
+ struct nfs_writeverf * verf; /* used by write */
+ const struct nfs_server *server; /* used by write */
+ };
+ };
};
/*
--
2.17.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH 1/2] NFSv3: Improve NFSv3 performance when server returns no post-op attributes
2018-09-24 22:01 [PATCH 1/2] NFSv3: Improve NFSv3 performance when server returns no post-op attributes Trond Myklebust
2018-09-24 22:01 ` [PATCH 2/2] NFSv4: Save a few bytes in the nfs_pgio_args/res Trond Myklebust
@ 2018-09-25 5:06 ` kbuild test robot
1 sibling, 0 replies; 3+ messages in thread
From: kbuild test robot @ 2018-09-25 5:06 UTC (permalink / raw)
To: Trond Myklebust; +Cc: kbuild-all, linux-nfs
[-- Attachment #1: Type: text/plain, Size: 2362 bytes --]
Hi Trond,
I love your patch! Perhaps something to improve:
[auto build test WARNING on nfs/linux-next]
[also build test WARNING on v4.19-rc5 next-20180924]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Trond-Myklebust/NFSv3-Improve-NFSv3-performance-when-server-returns-no-post-op-attributes/20180925-122432
base: git://git.linux-nfs.org/projects/trondmy/linux-nfs.git linux-next
config: i386-randconfig-x005-201838 (attached as .config)
compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
reproduce:
# save the attached .config to linux build tree
make ARCH=i386
All warnings (new ones prefixed by >>):
fs/nfs/nfs3xdr.c: In function 'nfs3_xdr_dec_read3res':
>> fs/nfs/nfs3xdr.c:1677:30: warning: initialization discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
struct nfs_server *server = result->server;
^~~~~~
fs/nfs/nfs3xdr.c:1678:15: warning: unused variable 'replen' [-Wunused-variable]
unsigned int replen, pos;
^~~~~~
fs/nfs/nfs3xdr.c:1677:21: warning: unused variable 'server' [-Wunused-variable]
struct nfs_server *server = result->server;
^~~~~~
vim +/const +1677 fs/nfs/nfs3xdr.c
1672
1673 static int nfs3_xdr_dec_read3res(struct rpc_rqst *req, struct xdr_stream *xdr,
1674 void *data)
1675 {
1676 struct nfs_pgio_res *result = data;
> 1677 struct nfs_server *server = result->server;
1678 unsigned int replen, pos;
1679 enum nfs_stat status;
1680 int error;
1681
1682 pos = xdr_stream_pos(xdr);
1683 error = decode_nfsstat3(xdr, &status);
1684 if (unlikely(error))
1685 goto out;
1686 error = decode_post_op_attr(xdr, result->fattr);
1687 if (unlikely(error))
1688 goto out;
1689 result->op_status = status;
1690 if (status != NFS3_OK)
1691 goto out_status;
1692 result->replen = 3 + ((xdr_stream_pos(xdr) - pos) >> 2);
1693 error = decode_read3resok(xdr, result);
1694 out:
1695 return error;
1696 out_status:
1697 return nfs3_stat_to_errno(status);
1698 }
1699
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 36102 bytes --]
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2018-09-25 11:14 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-24 22:01 [PATCH 1/2] NFSv3: Improve NFSv3 performance when server returns no post-op attributes Trond Myklebust
2018-09-24 22:01 ` [PATCH 2/2] NFSv4: Save a few bytes in the nfs_pgio_args/res Trond Myklebust
2018-09-25 5:06 ` [PATCH 1/2] NFSv3: Improve NFSv3 performance when server returns no post-op attributes kbuild test robot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).