diff options
author | Darrick J. Wong <darrick.wong@oracle.com> | 2018-10-29 19:45:48 -0400 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2018-10-29 19:45:48 -0400 |
commit | 65f098e91ffbb64d7ca2ed93b6ab2428a2e34452 (patch) | |
tree | 011f141cf436f7136d18e7de82371be23da49f27 | |
parent | 900611a1bd06ef4a79980e58babc61ef056c81ab (diff) |
ocfs2: remove ocfs2_reflink_remap_range
Since ocfs2_remap_file_range is a thin shell around
ocfs2_remap_remap_range, move everything from the latter into the
former.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
-rw-r--r-- | fs/ocfs2/file.c | 68 | ||||
-rw-r--r-- | fs/ocfs2/refcounttree.c | 113 | ||||
-rw-r--r-- | fs/ocfs2/refcounttree.h | 24 |
3 files changed, 102 insertions, 103 deletions
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 8125c5ccf821..fe570824b991 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -2531,11 +2531,75 @@ static loff_t ocfs2_remap_file_range(struct file *file_in, loff_t pos_in, | |||
2531 | struct file *file_out, loff_t pos_out, | 2531 | struct file *file_out, loff_t pos_out, |
2532 | loff_t len, unsigned int remap_flags) | 2532 | loff_t len, unsigned int remap_flags) |
2533 | { | 2533 | { |
2534 | struct inode *inode_in = file_inode(file_in); | ||
2535 | struct inode *inode_out = file_inode(file_out); | ||
2536 | struct ocfs2_super *osb = OCFS2_SB(inode_in->i_sb); | ||
2537 | struct buffer_head *in_bh = NULL, *out_bh = NULL; | ||
2538 | bool same_inode = (inode_in == inode_out); | ||
2539 | loff_t remapped = 0; | ||
2540 | ssize_t ret; | ||
2541 | |||
2534 | if (remap_flags & ~(REMAP_FILE_DEDUP | REMAP_FILE_ADVISORY)) | 2542 | if (remap_flags & ~(REMAP_FILE_DEDUP | REMAP_FILE_ADVISORY)) |
2535 | return -EINVAL; | 2543 | return -EINVAL; |
2544 | if (!ocfs2_refcount_tree(osb)) | ||
2545 | return -EOPNOTSUPP; | ||
2546 | if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb)) | ||
2547 | return -EROFS; | ||
2536 | 2548 | ||
2537 | return ocfs2_reflink_remap_range(file_in, pos_in, file_out, pos_out, | 2549 | /* Lock both files against IO */ |
2538 | len, remap_flags); | 2550 | ret = ocfs2_reflink_inodes_lock(inode_in, &in_bh, inode_out, &out_bh); |
2551 | if (ret) | ||
2552 | return ret; | ||
2553 | |||
2554 | /* Check file eligibility and prepare for block sharing. */ | ||
2555 | ret = -EINVAL; | ||
2556 | if ((OCFS2_I(inode_in)->ip_flags & OCFS2_INODE_SYSTEM_FILE) || | ||
2557 | (OCFS2_I(inode_out)->ip_flags & OCFS2_INODE_SYSTEM_FILE)) | ||
2558 | goto out_unlock; | ||
2559 | |||
2560 | ret = generic_remap_file_range_prep(file_in, pos_in, file_out, pos_out, | ||
2561 | &len, remap_flags); | ||
2562 | if (ret < 0 || len == 0) | ||
2563 | goto out_unlock; | ||
2564 | |||
2565 | /* Lock out changes to the allocation maps and remap. */ | ||
2566 | down_write(&OCFS2_I(inode_in)->ip_alloc_sem); | ||
2567 | if (!same_inode) | ||
2568 | down_write_nested(&OCFS2_I(inode_out)->ip_alloc_sem, | ||
2569 | SINGLE_DEPTH_NESTING); | ||
2570 | |||
2571 | /* Zap any page cache for the destination file's range. */ | ||
2572 | truncate_inode_pages_range(&inode_out->i_data, | ||
2573 | round_down(pos_out, PAGE_SIZE), | ||
2574 | round_up(pos_out + len, PAGE_SIZE) - 1); | ||
2575 | |||
2576 | remapped = ocfs2_reflink_remap_blocks(inode_in, in_bh, pos_in, | ||
2577 | inode_out, out_bh, pos_out, len); | ||
2578 | up_write(&OCFS2_I(inode_in)->ip_alloc_sem); | ||
2579 | if (!same_inode) | ||
2580 | up_write(&OCFS2_I(inode_out)->ip_alloc_sem); | ||
2581 | if (remapped < 0) { | ||
2582 | ret = remapped; | ||
2583 | mlog_errno(ret); | ||
2584 | goto out_unlock; | ||
2585 | } | ||
2586 | |||
2587 | /* | ||
2588 | * Empty the extent map so that we may get the right extent | ||
2589 | * record from the disk. | ||
2590 | */ | ||
2591 | ocfs2_extent_map_trunc(inode_in, 0); | ||
2592 | ocfs2_extent_map_trunc(inode_out, 0); | ||
2593 | |||
2594 | ret = ocfs2_reflink_update_dest(inode_out, out_bh, pos_out + len); | ||
2595 | if (ret) { | ||
2596 | mlog_errno(ret); | ||
2597 | goto out_unlock; | ||
2598 | } | ||
2599 | |||
2600 | out_unlock: | ||
2601 | ocfs2_reflink_inodes_unlock(inode_in, in_bh, inode_out, out_bh); | ||
2602 | return remapped > 0 ? remapped : ret; | ||
2539 | } | 2603 | } |
2540 | 2604 | ||
2541 | const struct inode_operations ocfs2_file_iops = { | 2605 | const struct inode_operations ocfs2_file_iops = { |
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c index c7409578657b..dc66b80585ec 100644 --- a/fs/ocfs2/refcounttree.c +++ b/fs/ocfs2/refcounttree.c | |||
@@ -4468,9 +4468,9 @@ out: | |||
4468 | } | 4468 | } |
4469 | 4469 | ||
4470 | /* Update destination inode size, if necessary. */ | 4470 | /* Update destination inode size, if necessary. */ |
4471 | static int ocfs2_reflink_update_dest(struct inode *dest, | 4471 | int ocfs2_reflink_update_dest(struct inode *dest, |
4472 | struct buffer_head *d_bh, | 4472 | struct buffer_head *d_bh, |
4473 | loff_t newlen) | 4473 | loff_t newlen) |
4474 | { | 4474 | { |
4475 | handle_t *handle; | 4475 | handle_t *handle; |
4476 | int ret; | 4476 | int ret; |
@@ -4621,13 +4621,13 @@ out: | |||
4621 | } | 4621 | } |
4622 | 4622 | ||
4623 | /* Set up refcount tree and remap s_inode to t_inode. */ | 4623 | /* Set up refcount tree and remap s_inode to t_inode. */ |
4624 | static loff_t ocfs2_reflink_remap_blocks(struct inode *s_inode, | 4624 | loff_t ocfs2_reflink_remap_blocks(struct inode *s_inode, |
4625 | struct buffer_head *s_bh, | 4625 | struct buffer_head *s_bh, |
4626 | loff_t pos_in, | 4626 | loff_t pos_in, |
4627 | struct inode *t_inode, | 4627 | struct inode *t_inode, |
4628 | struct buffer_head *t_bh, | 4628 | struct buffer_head *t_bh, |
4629 | loff_t pos_out, | 4629 | loff_t pos_out, |
4630 | loff_t len) | 4630 | loff_t len) |
4631 | { | 4631 | { |
4632 | struct ocfs2_cached_dealloc_ctxt dealloc; | 4632 | struct ocfs2_cached_dealloc_ctxt dealloc; |
4633 | struct ocfs2_super *osb; | 4633 | struct ocfs2_super *osb; |
@@ -4720,10 +4720,10 @@ out: | |||
4720 | } | 4720 | } |
4721 | 4721 | ||
4722 | /* Lock an inode and grab a bh pointing to the inode. */ | 4722 | /* Lock an inode and grab a bh pointing to the inode. */ |
4723 | static int ocfs2_reflink_inodes_lock(struct inode *s_inode, | 4723 | int ocfs2_reflink_inodes_lock(struct inode *s_inode, |
4724 | struct buffer_head **bh1, | 4724 | struct buffer_head **bh1, |
4725 | struct inode *t_inode, | 4725 | struct inode *t_inode, |
4726 | struct buffer_head **bh2) | 4726 | struct buffer_head **bh2) |
4727 | { | 4727 | { |
4728 | struct inode *inode1; | 4728 | struct inode *inode1; |
4729 | struct inode *inode2; | 4729 | struct inode *inode2; |
@@ -4808,10 +4808,10 @@ out_i1: | |||
4808 | } | 4808 | } |
4809 | 4809 | ||
4810 | /* Unlock both inodes and release buffers. */ | 4810 | /* Unlock both inodes and release buffers. */ |
4811 | static void ocfs2_reflink_inodes_unlock(struct inode *s_inode, | 4811 | void ocfs2_reflink_inodes_unlock(struct inode *s_inode, |
4812 | struct buffer_head *s_bh, | 4812 | struct buffer_head *s_bh, |
4813 | struct inode *t_inode, | 4813 | struct inode *t_inode, |
4814 | struct buffer_head *t_bh) | 4814 | struct buffer_head *t_bh) |
4815 | { | 4815 | { |
4816 | ocfs2_inode_unlock(s_inode, 1); | 4816 | ocfs2_inode_unlock(s_inode, 1); |
4817 | ocfs2_rw_unlock(s_inode, 1); | 4817 | ocfs2_rw_unlock(s_inode, 1); |
@@ -4823,80 +4823,3 @@ static void ocfs2_reflink_inodes_unlock(struct inode *s_inode, | |||
4823 | } | 4823 | } |
4824 | unlock_two_nondirectories(s_inode, t_inode); | 4824 | unlock_two_nondirectories(s_inode, t_inode); |
4825 | } | 4825 | } |
4826 | |||
4827 | /* Link a range of blocks from one file to another. */ | ||
4828 | loff_t ocfs2_reflink_remap_range(struct file *file_in, | ||
4829 | loff_t pos_in, | ||
4830 | struct file *file_out, | ||
4831 | loff_t pos_out, | ||
4832 | loff_t len, | ||
4833 | unsigned int remap_flags) | ||
4834 | { | ||
4835 | struct inode *inode_in = file_inode(file_in); | ||
4836 | struct inode *inode_out = file_inode(file_out); | ||
4837 | struct ocfs2_super *osb = OCFS2_SB(inode_in->i_sb); | ||
4838 | struct buffer_head *in_bh = NULL, *out_bh = NULL; | ||
4839 | bool same_inode = (inode_in == inode_out); | ||
4840 | loff_t remapped = 0; | ||
4841 | ssize_t ret; | ||
4842 | |||
4843 | if (!ocfs2_refcount_tree(osb)) | ||
4844 | return -EOPNOTSUPP; | ||
4845 | if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb)) | ||
4846 | return -EROFS; | ||
4847 | |||
4848 | /* Lock both files against IO */ | ||
4849 | ret = ocfs2_reflink_inodes_lock(inode_in, &in_bh, inode_out, &out_bh); | ||
4850 | if (ret) | ||
4851 | return ret; | ||
4852 | |||
4853 | /* Check file eligibility and prepare for block sharing. */ | ||
4854 | ret = -EINVAL; | ||
4855 | if ((OCFS2_I(inode_in)->ip_flags & OCFS2_INODE_SYSTEM_FILE) || | ||
4856 | (OCFS2_I(inode_out)->ip_flags & OCFS2_INODE_SYSTEM_FILE)) | ||
4857 | goto out_unlock; | ||
4858 | |||
4859 | ret = generic_remap_file_range_prep(file_in, pos_in, file_out, pos_out, | ||
4860 | &len, remap_flags); | ||
4861 | if (ret < 0 || len == 0) | ||
4862 | goto out_unlock; | ||
4863 | |||
4864 | /* Lock out changes to the allocation maps and remap. */ | ||
4865 | down_write(&OCFS2_I(inode_in)->ip_alloc_sem); | ||
4866 | if (!same_inode) | ||
4867 | down_write_nested(&OCFS2_I(inode_out)->ip_alloc_sem, | ||
4868 | SINGLE_DEPTH_NESTING); | ||
4869 | |||
4870 | /* Zap any page cache for the destination file's range. */ | ||
4871 | truncate_inode_pages_range(&inode_out->i_data, | ||
4872 | round_down(pos_out, PAGE_SIZE), | ||
4873 | round_up(pos_out + len, PAGE_SIZE) - 1); | ||
4874 | |||
4875 | remapped = ocfs2_reflink_remap_blocks(inode_in, in_bh, pos_in, | ||
4876 | inode_out, out_bh, pos_out, len); | ||
4877 | up_write(&OCFS2_I(inode_in)->ip_alloc_sem); | ||
4878 | if (!same_inode) | ||
4879 | up_write(&OCFS2_I(inode_out)->ip_alloc_sem); | ||
4880 | if (remapped < 0) { | ||
4881 | ret = remapped; | ||
4882 | mlog_errno(ret); | ||
4883 | goto out_unlock; | ||
4884 | } | ||
4885 | |||
4886 | /* | ||
4887 | * Empty the extent map so that we may get the right extent | ||
4888 | * record from the disk. | ||
4889 | */ | ||
4890 | ocfs2_extent_map_trunc(inode_in, 0); | ||
4891 | ocfs2_extent_map_trunc(inode_out, 0); | ||
4892 | |||
4893 | ret = ocfs2_reflink_update_dest(inode_out, out_bh, pos_out + len); | ||
4894 | if (ret) { | ||
4895 | mlog_errno(ret); | ||
4896 | goto out_unlock; | ||
4897 | } | ||
4898 | |||
4899 | out_unlock: | ||
4900 | ocfs2_reflink_inodes_unlock(inode_in, in_bh, inode_out, out_bh); | ||
4901 | return remapped > 0 ? remapped : ret; | ||
4902 | } | ||
diff --git a/fs/ocfs2/refcounttree.h b/fs/ocfs2/refcounttree.h index 9e64daba395d..e9e862be4a1e 100644 --- a/fs/ocfs2/refcounttree.h +++ b/fs/ocfs2/refcounttree.h | |||
@@ -115,11 +115,23 @@ int ocfs2_reflink_ioctl(struct inode *inode, | |||
115 | const char __user *oldname, | 115 | const char __user *oldname, |
116 | const char __user *newname, | 116 | const char __user *newname, |
117 | bool preserve); | 117 | bool preserve); |
118 | loff_t ocfs2_reflink_remap_range(struct file *file_in, | 118 | loff_t ocfs2_reflink_remap_blocks(struct inode *s_inode, |
119 | loff_t pos_in, | 119 | struct buffer_head *s_bh, |
120 | struct file *file_out, | 120 | loff_t pos_in, |
121 | loff_t pos_out, | 121 | struct inode *t_inode, |
122 | loff_t len, | 122 | struct buffer_head *t_bh, |
123 | unsigned int remap_flags); | 123 | loff_t pos_out, |
124 | loff_t len); | ||
125 | int ocfs2_reflink_inodes_lock(struct inode *s_inode, | ||
126 | struct buffer_head **bh1, | ||
127 | struct inode *t_inode, | ||
128 | struct buffer_head **bh2); | ||
129 | void ocfs2_reflink_inodes_unlock(struct inode *s_inode, | ||
130 | struct buffer_head *s_bh, | ||
131 | struct inode *t_inode, | ||
132 | struct buffer_head *t_bh); | ||
133 | int ocfs2_reflink_update_dest(struct inode *dest, | ||
134 | struct buffer_head *d_bh, | ||
135 | loff_t newlen); | ||
124 | 136 | ||
125 | #endif /* OCFS2_REFCOUNTTREE_H */ | 137 | #endif /* OCFS2_REFCOUNTTREE_H */ |