Skip to content

Commit 29ac8e8

Browse files
committed
ocfs2: implement the VFS clone_range, copy_range, and dedupe_range features
Connect the new VFS clone_range, copy_range, and dedupe_range features to the existing reflink capability of ocfs2. Compared to the existing ocfs2 reflink ioctl We have to do things a little differently to support the VFS semantics (we can clone subranges of a file but we don't clone xattrs), but the VFS ioctls are more broadly supported. Signed-off-by: Darrick J. Wong <[email protected]> --- v2: Convert inline data files to extents files before reflinking, and fix i_blocks so that stat(2) output is correct. v3: Make zero-length dedupe consistent with btrfs behavior. v4: Use VFS double-inode lock routines and remove MAX_DEDUPE_LEN.
1 parent 86e5943 commit 29ac8e8

File tree

4 files changed

+474
-3
lines changed

4 files changed

+474
-3
lines changed

fs/ocfs2/file.c

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1667,9 +1667,9 @@ static void ocfs2_calc_trunc_pos(struct inode *inode,
16671667
*done = ret;
16681668
}
16691669

1670-
static int ocfs2_remove_inode_range(struct inode *inode,
1671-
struct buffer_head *di_bh, u64 byte_start,
1672-
u64 byte_len)
1670+
int ocfs2_remove_inode_range(struct inode *inode,
1671+
struct buffer_head *di_bh, u64 byte_start,
1672+
u64 byte_len)
16731673
{
16741674
int ret = 0, flags = 0, done = 0, i;
16751675
u32 trunc_start, trunc_len, trunc_end, trunc_cpos, phys_cpos;
@@ -2439,6 +2439,31 @@ static loff_t ocfs2_file_llseek(struct file *file, loff_t offset, int whence)
24392439
return offset;
24402440
}
24412441

2442+
static int ocfs2_file_clone_range(struct file *file_in,
2443+
loff_t pos_in,
2444+
struct file *file_out,
2445+
loff_t pos_out,
2446+
u64 len)
2447+
{
2448+
return ocfs2_reflink_remap_range(file_in, pos_in, file_out, pos_out,
2449+
len, false);
2450+
}
2451+
2452+
static ssize_t ocfs2_file_dedupe_range(struct file *src_file,
2453+
u64 loff,
2454+
u64 len,
2455+
struct file *dst_file,
2456+
u64 dst_loff)
2457+
{
2458+
int error;
2459+
2460+
error = ocfs2_reflink_remap_range(src_file, loff, dst_file, dst_loff,
2461+
len, true);
2462+
if (error)
2463+
return error;
2464+
return len;
2465+
}
2466+
24422467
const struct inode_operations ocfs2_file_iops = {
24432468
.setattr = ocfs2_setattr,
24442469
.getattr = ocfs2_getattr,
@@ -2478,6 +2503,8 @@ const struct file_operations ocfs2_fops = {
24782503
.splice_read = generic_file_splice_read,
24792504
.splice_write = iter_file_splice_write,
24802505
.fallocate = ocfs2_fallocate,
2506+
.clone_file_range = ocfs2_file_clone_range,
2507+
.dedupe_file_range = ocfs2_file_dedupe_range,
24812508
};
24822509

24832510
const struct file_operations ocfs2_dops = {
@@ -2523,6 +2550,8 @@ const struct file_operations ocfs2_fops_no_plocks = {
25232550
.splice_read = generic_file_splice_read,
25242551
.splice_write = iter_file_splice_write,
25252552
.fallocate = ocfs2_fallocate,
2553+
.clone_file_range = ocfs2_file_clone_range,
2554+
.dedupe_file_range = ocfs2_file_dedupe_range,
25262555
};
25272556

25282557
const struct file_operations ocfs2_dops_no_plocks = {

fs/ocfs2/file.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,7 @@ int ocfs2_change_file_space(struct file *file, unsigned int cmd,
8282

8383
int ocfs2_check_range_for_refcount(struct inode *inode, loff_t pos,
8484
size_t count);
85+
int ocfs2_remove_inode_range(struct inode *inode,
86+
struct buffer_head *di_bh, u64 byte_start,
87+
u64 byte_len);
8588
#endif /* OCFS2_FILE_H */

0 commit comments

Comments
 (0)