Skip to content

Commit 1275101

Browse files
olgakorn1Olga Kornievskaia
authored andcommitted
NFS based on file size issue sync copy or fallback to generic copy offload
For small file sizes, it make sense to issue a synchronous copy (and save an RPC callback operation). Also, for the inter copy offload, copy len must be larger than the cost of doing a mount between the destination and source server (14RPCs are sent during 4.x mount). Signed-off-by: Olga Kornievskaia <[email protected]>
1 parent 0e65a32 commit 1275101

File tree

3 files changed

+18
-4
lines changed

3 files changed

+18
-4
lines changed

fs/nfs/nfs42.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
#ifdef CONFIG_NFS_V4_2
1717
int nfs42_proc_allocate(struct file *, loff_t, loff_t);
1818
ssize_t nfs42_proc_copy(struct file *, loff_t, struct file *, loff_t, size_t,
19-
struct nl4_server *, nfs4_stateid *);
19+
struct nl4_server *, nfs4_stateid *, bool);
2020
int nfs42_proc_deallocate(struct file *, loff_t, loff_t);
2121
loff_t nfs42_proc_llseek(struct file *, loff_t, int);
2222
int nfs42_proc_layoutstats_generic(struct nfs_server *,

fs/nfs/nfs42proc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ static ssize_t _nfs42_proc_copy(struct file *src,
357357
ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src,
358358
struct file *dst, loff_t pos_dst, size_t count,
359359
struct nl4_server *nss,
360-
nfs4_stateid *cnr_stateid)
360+
nfs4_stateid *cnr_stateid, bool sync)
361361
{
362362
struct nfs_server *server = NFS_SERVER(file_inode(dst));
363363
struct nfs_lock_context *src_lock;
@@ -368,7 +368,7 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src,
368368
.dst_fh = NFS_FH(file_inode(dst)),
369369
.dst_pos = pos_dst,
370370
.count = count,
371-
.sync = false,
371+
.sync = sync,
372372
};
373373
struct nfs42_copy_res res;
374374
struct nfs4_exception src_exception = {

fs/nfs/nfs4file.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ static ssize_t __nfs4_copy_file_range(struct file *file_in, loff_t pos_in,
138138
struct nl4_server *nss = NULL;
139139
nfs4_stateid *cnrs = NULL;
140140
ssize_t ret;
141+
bool sync = false;
141142

142143
/* Only offload copy if superblock is the same */
143144
if (file_inode(file_in)->i_sb != file_inode(file_out)->i_sb)
@@ -146,8 +147,21 @@ static ssize_t __nfs4_copy_file_range(struct file *file_in, loff_t pos_in,
146147
return -EOPNOTSUPP;
147148
if (file_inode(file_in) == file_inode(file_out))
148149
return -EOPNOTSUPP;
150+
/* if the copy size if smaller than 2 RPC payloads, make it
151+
* synchronous
152+
*/
153+
if (count <= 2 * NFS_SERVER(file_inode(file_in))->rsize)
154+
sync = true;
149155
retry:
150156
if (!nfs42_files_from_same_server(file_in, file_out)) {
157+
/* for inter copy, if copy size if smaller than 12 RPC
158+
* payloads, fallback to traditional copy. There are
159+
* 14 RPCs during an NFSv4.x mount between source/dest
160+
* servers.
161+
*/
162+
if (sync ||
163+
count <= 14 * NFS_SERVER(file_inode(file_in))->rsize)
164+
return -EOPNOTSUPP;
151165
cn_resp = kzalloc(sizeof(struct nfs42_copy_notify_res),
152166
GFP_NOFS);
153167
if (unlikely(cn_resp == NULL))
@@ -162,7 +176,7 @@ static ssize_t __nfs4_copy_file_range(struct file *file_in, loff_t pos_in,
162176
cnrs = &cn_resp->cnr_stateid;
163177
}
164178
ret = nfs42_proc_copy(file_in, pos_in, file_out, pos_out, count,
165-
nss, cnrs);
179+
nss, cnrs, sync);
166180
out:
167181
kfree(cn_resp);
168182
if (ret == -EAGAIN)

0 commit comments

Comments
 (0)