Skip to content

Commit

Permalink
ocfs2: implement the VFS clone_range, copy_range, and dedupe_range fe…
Browse files Browse the repository at this point in the history
…atures

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 <darrick.wong@oracle.com>
---
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.
  • Loading branch information
Darrick J. Wong committed Dec 10, 2016
1 parent 86e5943 commit 29ac8e8
Show file tree
Hide file tree
Showing 4 changed files with 474 additions and 3 deletions.
35 changes: 32 additions & 3 deletions fs/ocfs2/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -1667,9 +1667,9 @@ static void ocfs2_calc_trunc_pos(struct inode *inode,
*done = ret;
}

static int ocfs2_remove_inode_range(struct inode *inode,
struct buffer_head *di_bh, u64 byte_start,
u64 byte_len)
int ocfs2_remove_inode_range(struct inode *inode,
struct buffer_head *di_bh, u64 byte_start,
u64 byte_len)
{
int ret = 0, flags = 0, done = 0, i;
u32 trunc_start, trunc_len, trunc_end, trunc_cpos, phys_cpos;
Expand Down Expand Up @@ -2439,6 +2439,31 @@ static loff_t ocfs2_file_llseek(struct file *file, loff_t offset, int whence)
return offset;
}

static int ocfs2_file_clone_range(struct file *file_in,
loff_t pos_in,
struct file *file_out,
loff_t pos_out,
u64 len)
{
return ocfs2_reflink_remap_range(file_in, pos_in, file_out, pos_out,
len, false);
}

static ssize_t ocfs2_file_dedupe_range(struct file *src_file,
u64 loff,
u64 len,
struct file *dst_file,
u64 dst_loff)
{
int error;

error = ocfs2_reflink_remap_range(src_file, loff, dst_file, dst_loff,
len, true);
if (error)
return error;
return len;
}

const struct inode_operations ocfs2_file_iops = {
.setattr = ocfs2_setattr,
.getattr = ocfs2_getattr,
Expand Down Expand Up @@ -2478,6 +2503,8 @@ const struct file_operations ocfs2_fops = {
.splice_read = generic_file_splice_read,
.splice_write = iter_file_splice_write,
.fallocate = ocfs2_fallocate,
.clone_file_range = ocfs2_file_clone_range,
.dedupe_file_range = ocfs2_file_dedupe_range,
};

const struct file_operations ocfs2_dops = {
Expand Down Expand Up @@ -2523,6 +2550,8 @@ const struct file_operations ocfs2_fops_no_plocks = {
.splice_read = generic_file_splice_read,
.splice_write = iter_file_splice_write,
.fallocate = ocfs2_fallocate,
.clone_file_range = ocfs2_file_clone_range,
.dedupe_file_range = ocfs2_file_dedupe_range,
};

const struct file_operations ocfs2_dops_no_plocks = {
Expand Down
3 changes: 3 additions & 0 deletions fs/ocfs2/file.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,7 @@ int ocfs2_change_file_space(struct file *file, unsigned int cmd,

int ocfs2_check_range_for_refcount(struct inode *inode, loff_t pos,
size_t count);
int ocfs2_remove_inode_range(struct inode *inode,
struct buffer_head *di_bh, u64 byte_start,
u64 byte_len);
#endif /* OCFS2_FILE_H */
Loading

0 comments on commit 29ac8e8

Please sign in to comment.