Skip to content

Commit 64bf5ff

Browse files
Dave Chinnerdjwong
Dave Chinner
authored andcommitted
vfs: no fallback for ->copy_file_range
Now that we have generic_copy_file_range(), remove it as a fallback case when offloads fail. This puts the responsibility for executing fallbacks on the filesystems that implement ->copy_file_range and allows us to add operational validity checks to generic_copy_file_range(). Rework vfs_copy_file_range() to call a new do_copy_file_range() helper to execute the copying callout, and move calls to generic_file_copy_range() into filesystem methods where they currently return failures. [Amir] overlayfs is not responsible of executing the fallback. It is the responsibility of the underlying filesystem. Signed-off-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Amir Goldstein <amir73il@gmail.com> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
1 parent f16acc9 commit 64bf5ff

File tree

5 files changed

+73
-18
lines changed

5 files changed

+73
-18
lines changed

fs/ceph/file.c

+18-3
Original file line numberDiff line numberDiff line change
@@ -1889,9 +1889,9 @@ static int is_file_size_ok(struct inode *src_inode, struct inode *dst_inode,
18891889
return 0;
18901890
}
18911891

1892-
static ssize_t ceph_copy_file_range(struct file *src_file, loff_t src_off,
1893-
struct file *dst_file, loff_t dst_off,
1894-
size_t len, unsigned int flags)
1892+
static ssize_t __ceph_copy_file_range(struct file *src_file, loff_t src_off,
1893+
struct file *dst_file, loff_t dst_off,
1894+
size_t len, unsigned int flags)
18951895
{
18961896
struct inode *src_inode = file_inode(src_file);
18971897
struct inode *dst_inode = file_inode(dst_file);
@@ -2100,6 +2100,21 @@ static ssize_t ceph_copy_file_range(struct file *src_file, loff_t src_off,
21002100
return ret;
21012101
}
21022102

2103+
static ssize_t ceph_copy_file_range(struct file *src_file, loff_t src_off,
2104+
struct file *dst_file, loff_t dst_off,
2105+
size_t len, unsigned int flags)
2106+
{
2107+
ssize_t ret;
2108+
2109+
ret = __ceph_copy_file_range(src_file, src_off, dst_file, dst_off,
2110+
len, flags);
2111+
2112+
if (ret == -EOPNOTSUPP)
2113+
ret = generic_copy_file_range(src_file, src_off, dst_file,
2114+
dst_off, len, flags);
2115+
return ret;
2116+
}
2117+
21032118
const struct file_operations ceph_file_fops = {
21042119
.open = ceph_open,
21052120
.release = ceph_release,

fs/cifs/cifsfs.c

+4
Original file line numberDiff line numberDiff line change
@@ -1148,6 +1148,10 @@ static ssize_t cifs_copy_file_range(struct file *src_file, loff_t off,
11481148
rc = cifs_file_copychunk_range(xid, src_file, off, dst_file, destoff,
11491149
len, flags);
11501150
free_xid(xid);
1151+
1152+
if (rc == -EOPNOTSUPP)
1153+
rc = generic_copy_file_range(src_file, off, dst_file,
1154+
destoff, len, flags);
11511155
return rc;
11521156
}
11531157

fs/fuse/file.c

+18-3
Original file line numberDiff line numberDiff line change
@@ -3112,9 +3112,9 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
31123112
return err;
31133113
}
31143114

3115-
static ssize_t fuse_copy_file_range(struct file *file_in, loff_t pos_in,
3116-
struct file *file_out, loff_t pos_out,
3117-
size_t len, unsigned int flags)
3115+
static ssize_t __fuse_copy_file_range(struct file *file_in, loff_t pos_in,
3116+
struct file *file_out, loff_t pos_out,
3117+
size_t len, unsigned int flags)
31183118
{
31193119
struct fuse_file *ff_in = file_in->private_data;
31203120
struct fuse_file *ff_out = file_out->private_data;
@@ -3194,6 +3194,21 @@ static ssize_t fuse_copy_file_range(struct file *file_in, loff_t pos_in,
31943194
return err;
31953195
}
31963196

3197+
static ssize_t fuse_copy_file_range(struct file *src_file, loff_t src_off,
3198+
struct file *dst_file, loff_t dst_off,
3199+
size_t len, unsigned int flags)
3200+
{
3201+
ssize_t ret;
3202+
3203+
ret = __fuse_copy_file_range(src_file, src_off, dst_file, dst_off,
3204+
len, flags);
3205+
3206+
if (ret == -EOPNOTSUPP)
3207+
ret = generic_copy_file_range(src_file, src_off, dst_file,
3208+
dst_off, len, flags);
3209+
return ret;
3210+
}
3211+
31973212
static const struct file_operations fuse_file_operations = {
31983213
.llseek = fuse_file_llseek,
31993214
.read_iter = fuse_file_read_iter,

fs/nfs/nfs4file.c

+17-3
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,9 @@ nfs4_file_flush(struct file *file, fl_owner_t id)
129129
}
130130

131131
#ifdef CONFIG_NFS_V4_2
132-
static ssize_t nfs4_copy_file_range(struct file *file_in, loff_t pos_in,
133-
struct file *file_out, loff_t pos_out,
134-
size_t count, unsigned int flags)
132+
static ssize_t __nfs4_copy_file_range(struct file *file_in, loff_t pos_in,
133+
struct file *file_out, loff_t pos_out,
134+
size_t count, unsigned int flags)
135135
{
136136
if (!nfs_server_capable(file_inode(file_out), NFS_CAP_COPY))
137137
return -EOPNOTSUPP;
@@ -140,6 +140,20 @@ static ssize_t nfs4_copy_file_range(struct file *file_in, loff_t pos_in,
140140
return nfs42_proc_copy(file_in, pos_in, file_out, pos_out, count);
141141
}
142142

143+
static ssize_t nfs4_copy_file_range(struct file *file_in, loff_t pos_in,
144+
struct file *file_out, loff_t pos_out,
145+
size_t count, unsigned int flags)
146+
{
147+
ssize_t ret;
148+
149+
ret = __nfs4_copy_file_range(file_in, pos_in, file_out, pos_out, count,
150+
flags);
151+
if (ret == -EOPNOTSUPP)
152+
ret = generic_copy_file_range(file_in, pos_in, file_out,
153+
pos_out, count, flags);
154+
return ret;
155+
}
156+
143157
static loff_t nfs4_file_llseek(struct file *filep, loff_t offset, int whence)
144158
{
145159
loff_t ret;

fs/read_write.c

+16-9
Original file line numberDiff line numberDiff line change
@@ -1595,6 +1595,19 @@ ssize_t generic_copy_file_range(struct file *file_in, loff_t pos_in,
15951595
}
15961596
EXPORT_SYMBOL(generic_copy_file_range);
15971597

1598+
static ssize_t do_copy_file_range(struct file *file_in, loff_t pos_in,
1599+
struct file *file_out, loff_t pos_out,
1600+
size_t len, unsigned int flags)
1601+
{
1602+
if (file_out->f_op->copy_file_range)
1603+
return file_out->f_op->copy_file_range(file_in, pos_in,
1604+
file_out, pos_out,
1605+
len, flags);
1606+
1607+
return generic_copy_file_range(file_in, pos_in, file_out, pos_out, len,
1608+
flags);
1609+
}
1610+
15981611
/*
15991612
* copy_file_range() differs from regular file read and write in that it
16001613
* specifically allows return partial success. When it does so is up to
@@ -1655,15 +1668,9 @@ ssize_t vfs_copy_file_range(struct file *file_in, loff_t pos_in,
16551668
}
16561669
}
16571670

1658-
if (file_out->f_op->copy_file_range) {
1659-
ret = file_out->f_op->copy_file_range(file_in, pos_in, file_out,
1660-
pos_out, len, flags);
1661-
if (ret != -EOPNOTSUPP)
1662-
goto done;
1663-
}
1664-
1665-
ret = generic_copy_file_range(file_in, pos_in, file_out, pos_out, len,
1666-
flags);
1671+
ret = do_copy_file_range(file_in, pos_in, file_out, pos_out, len,
1672+
flags);
1673+
WARN_ON_ONCE(ret == -EOPNOTSUPP);
16671674
done:
16681675
if (ret > 0) {
16691676
fsnotify_access(file_in);

0 commit comments

Comments
 (0)