diff options
author | Darrick J. Wong <darrick.wong@oracle.com> | 2016-11-09 17:13:11 -0500 |
---|---|---|
committer | Darrick J. Wong <darrick.wong@oracle.com> | 2016-12-10 15:39:45 -0500 |
commit | 29ac8e856cb3694e004037de595dec4ec53d42f2 (patch) | |
tree | 006df64270ecc128a4b837215c7ef78bd259ff51 /fs/ocfs2/file.c | |
parent | 86e59436d406d833a5da4a94aefb3c3be6b26053 (diff) |
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 <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.
Diffstat (limited to 'fs/ocfs2/file.c')
-rw-r--r-- | fs/ocfs2/file.c | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index d261f3a91870..c4889655d32b 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -1667,9 +1667,9 @@ static void ocfs2_calc_trunc_pos(struct inode *inode, | |||
1667 | *done = ret; | 1667 | *done = ret; |
1668 | } | 1668 | } |
1669 | 1669 | ||
1670 | static int ocfs2_remove_inode_range(struct inode *inode, | 1670 | int ocfs2_remove_inode_range(struct inode *inode, |
1671 | struct buffer_head *di_bh, u64 byte_start, | 1671 | struct buffer_head *di_bh, u64 byte_start, |
1672 | u64 byte_len) | 1672 | u64 byte_len) |
1673 | { | 1673 | { |
1674 | int ret = 0, flags = 0, done = 0, i; | 1674 | int ret = 0, flags = 0, done = 0, i; |
1675 | u32 trunc_start, trunc_len, trunc_end, trunc_cpos, phys_cpos; | 1675 | u32 trunc_start, trunc_len, trunc_end, trunc_cpos, phys_cpos; |
@@ -2439,6 +2439,31 @@ out: | |||
2439 | return offset; | 2439 | return offset; |
2440 | } | 2440 | } |
2441 | 2441 | ||
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 | |||
2442 | const struct inode_operations ocfs2_file_iops = { | 2467 | const struct inode_operations ocfs2_file_iops = { |
2443 | .setattr = ocfs2_setattr, | 2468 | .setattr = ocfs2_setattr, |
2444 | .getattr = ocfs2_getattr, | 2469 | .getattr = ocfs2_getattr, |
@@ -2478,6 +2503,8 @@ const struct file_operations ocfs2_fops = { | |||
2478 | .splice_read = generic_file_splice_read, | 2503 | .splice_read = generic_file_splice_read, |
2479 | .splice_write = iter_file_splice_write, | 2504 | .splice_write = iter_file_splice_write, |
2480 | .fallocate = ocfs2_fallocate, | 2505 | .fallocate = ocfs2_fallocate, |
2506 | .clone_file_range = ocfs2_file_clone_range, | ||
2507 | .dedupe_file_range = ocfs2_file_dedupe_range, | ||
2481 | }; | 2508 | }; |
2482 | 2509 | ||
2483 | const struct file_operations ocfs2_dops = { | 2510 | const struct file_operations ocfs2_dops = { |
@@ -2523,6 +2550,8 @@ const struct file_operations ocfs2_fops_no_plocks = { | |||
2523 | .splice_read = generic_file_splice_read, | 2550 | .splice_read = generic_file_splice_read, |
2524 | .splice_write = iter_file_splice_write, | 2551 | .splice_write = iter_file_splice_write, |
2525 | .fallocate = ocfs2_fallocate, | 2552 | .fallocate = ocfs2_fallocate, |
2553 | .clone_file_range = ocfs2_file_clone_range, | ||
2554 | .dedupe_file_range = ocfs2_file_dedupe_range, | ||
2526 | }; | 2555 | }; |
2527 | 2556 | ||
2528 | const struct file_operations ocfs2_dops_no_plocks = { | 2557 | const struct file_operations ocfs2_dops_no_plocks = { |