aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2018-10-29 19:45:48 -0400
committerDave Chinner <david@fromorbit.com>2018-10-29 19:45:48 -0400
commit65f098e91ffbb64d7ca2ed93b6ab2428a2e34452 (patch)
tree011f141cf436f7136d18e7de82371be23da49f27
parent900611a1bd06ef4a79980e58babc61ef056c81ab (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.c68
-rw-r--r--fs/ocfs2/refcounttree.c113
-rw-r--r--fs/ocfs2/refcounttree.h24
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
2600out_unlock:
2601 ocfs2_reflink_inodes_unlock(inode_in, in_bh, inode_out, out_bh);
2602 return remapped > 0 ? remapped : ret;
2539} 2603}
2540 2604
2541const struct inode_operations ocfs2_file_iops = { 2605const 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. */
4471static int ocfs2_reflink_update_dest(struct inode *dest, 4471int 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. */
4624static loff_t ocfs2_reflink_remap_blocks(struct inode *s_inode, 4624loff_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. */
4723static int ocfs2_reflink_inodes_lock(struct inode *s_inode, 4723int 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. */
4811static void ocfs2_reflink_inodes_unlock(struct inode *s_inode, 4811void 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. */
4828loff_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
4899out_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);
118loff_t ocfs2_reflink_remap_range(struct file *file_in, 118loff_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);
125int ocfs2_reflink_inodes_lock(struct inode *s_inode,
126 struct buffer_head **bh1,
127 struct inode *t_inode,
128 struct buffer_head **bh2);
129void 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);
133int 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 */