hc
2024-05-10 9999e48639b3cecb08ffb37358bcba3b48161b29
kernel/fs/ocfs2/refcounttree.c
....@@ -1,18 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /* -*- mode: c; c-basic-offset: 8; -*-
23 * vim: noexpandtab sw=8 ts=8 sts=0:
34 *
45 * refcounttree.c
56 *
67 * Copyright (C) 2009 Oracle. All rights reserved.
7
- *
8
- * This program is free software; you can redistribute it and/or
9
- * modify it under the terms of the GNU General Public
10
- * License version 2 as published by the Free Software Foundation.
11
- *
12
- * This program is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
- * General Public License for more details.
168 */
179
1810 #include <linux/sort.h>
....@@ -162,6 +154,7 @@
162154 }
163155
164156 static void ocfs2_refcount_cache_lock(struct ocfs2_caching_info *ci)
157
+__acquires(&rf->rf_lock)
165158 {
166159 struct ocfs2_refcount_tree *rf = cache_info_to_refcount(ci);
167160
....@@ -169,6 +162,7 @@
169162 }
170163
171164 static void ocfs2_refcount_cache_unlock(struct ocfs2_caching_info *ci)
165
+__releases(&rf->rf_lock)
172166 {
173167 struct ocfs2_refcount_tree *rf = cache_info_to_refcount(ci);
174168
....@@ -1069,7 +1063,7 @@
10691063 struct buffer_head **ret_bh)
10701064 {
10711065 int ret = 0, i, found;
1072
- u32 low_cpos, uninitialized_var(cpos_end);
1066
+ u32 low_cpos, cpos_end;
10731067 struct ocfs2_extent_list *el;
10741068 struct ocfs2_extent_rec *rec = NULL;
10751069 struct ocfs2_extent_block *eb = NULL;
....@@ -4135,7 +4129,6 @@
41354129 struct buffer_head *ref_root_bh = NULL;
41364130 struct ocfs2_cached_dealloc_ctxt dealloc;
41374131 struct ocfs2_super *osb = OCFS2_SB(s_inode->i_sb);
4138
- struct ocfs2_refcount_block *rb;
41394132 struct ocfs2_dinode *di = (struct ocfs2_dinode *)s_bh->b_data;
41404133 struct ocfs2_refcount_tree *ref_tree;
41414134
....@@ -4162,7 +4155,6 @@
41624155 mlog_errno(ret);
41634156 goto out;
41644157 }
4165
- rb = (struct ocfs2_refcount_block *)ref_root_bh->b_data;
41664158
41674159 ret = ocfs2_duplicate_extent_list(s_inode, t_inode, t_bh,
41684160 &ref_tree->rf_ci, ref_root_bh,
....@@ -4468,9 +4460,9 @@
44684460 }
44694461
44704462 /* Update destination inode size, if necessary. */
4471
-static int ocfs2_reflink_update_dest(struct inode *dest,
4472
- struct buffer_head *d_bh,
4473
- loff_t newlen)
4463
+int ocfs2_reflink_update_dest(struct inode *dest,
4464
+ struct buffer_head *d_bh,
4465
+ loff_t newlen)
44744466 {
44754467 handle_t *handle;
44764468 int ret;
....@@ -4507,14 +4499,14 @@
45074499 }
45084500
45094501 /* Remap the range pos_in:len in s_inode to pos_out:len in t_inode. */
4510
-static int ocfs2_reflink_remap_extent(struct inode *s_inode,
4511
- struct buffer_head *s_bh,
4512
- loff_t pos_in,
4513
- struct inode *t_inode,
4514
- struct buffer_head *t_bh,
4515
- loff_t pos_out,
4516
- loff_t len,
4517
- struct ocfs2_cached_dealloc_ctxt *dealloc)
4502
+static loff_t ocfs2_reflink_remap_extent(struct inode *s_inode,
4503
+ struct buffer_head *s_bh,
4504
+ loff_t pos_in,
4505
+ struct inode *t_inode,
4506
+ struct buffer_head *t_bh,
4507
+ loff_t pos_out,
4508
+ loff_t len,
4509
+ struct ocfs2_cached_dealloc_ctxt *dealloc)
45184510 {
45194511 struct ocfs2_extent_tree s_et;
45204512 struct ocfs2_extent_tree t_et;
....@@ -4522,8 +4514,9 @@
45224514 struct buffer_head *ref_root_bh = NULL;
45234515 struct ocfs2_refcount_tree *ref_tree;
45244516 struct ocfs2_super *osb;
4517
+ loff_t remapped_bytes = 0;
45254518 loff_t pstart, plen;
4526
- u32 p_cluster, num_clusters, slast, spos, tpos;
4519
+ u32 p_cluster, num_clusters, slast, spos, tpos, remapped_clus = 0;
45274520 unsigned int ext_flags;
45284521 int ret = 0;
45294522
....@@ -4605,30 +4598,34 @@
46054598 next_loop:
46064599 spos += num_clusters;
46074600 tpos += num_clusters;
4601
+ remapped_clus += num_clusters;
46084602 }
46094603
4610
-out:
4611
- return ret;
4604
+ goto out;
46124605 out_unlock_refcount:
46134606 ocfs2_unlock_refcount_tree(osb, ref_tree, 1);
46144607 brelse(ref_root_bh);
4615
- return ret;
4608
+out:
4609
+ remapped_bytes = ocfs2_clusters_to_bytes(t_inode->i_sb, remapped_clus);
4610
+ remapped_bytes = min_t(loff_t, len, remapped_bytes);
4611
+
4612
+ return remapped_bytes > 0 ? remapped_bytes : ret;
46164613 }
46174614
46184615 /* Set up refcount tree and remap s_inode to t_inode. */
4619
-static int ocfs2_reflink_remap_blocks(struct inode *s_inode,
4620
- struct buffer_head *s_bh,
4621
- loff_t pos_in,
4622
- struct inode *t_inode,
4623
- struct buffer_head *t_bh,
4624
- loff_t pos_out,
4625
- loff_t len)
4616
+loff_t ocfs2_reflink_remap_blocks(struct inode *s_inode,
4617
+ struct buffer_head *s_bh,
4618
+ loff_t pos_in,
4619
+ struct inode *t_inode,
4620
+ struct buffer_head *t_bh,
4621
+ loff_t pos_out,
4622
+ loff_t len)
46264623 {
46274624 struct ocfs2_cached_dealloc_ctxt dealloc;
46284625 struct ocfs2_super *osb;
46294626 struct ocfs2_dinode *dis;
46304627 struct ocfs2_dinode *dit;
4631
- int ret;
4628
+ loff_t ret;
46324629
46334630 osb = OCFS2_SB(s_inode->i_sb);
46344631 dis = (struct ocfs2_dinode *)s_bh->b_data;
....@@ -4700,7 +4697,7 @@
47004697 /* Actually remap extents now. */
47014698 ret = ocfs2_reflink_remap_extent(s_inode, s_bh, pos_in, t_inode, t_bh,
47024699 pos_out, len, &dealloc);
4703
- if (ret) {
4700
+ if (ret < 0) {
47044701 mlog_errno(ret);
47054702 goto out;
47064703 }
....@@ -4715,10 +4712,10 @@
47154712 }
47164713
47174714 /* Lock an inode and grab a bh pointing to the inode. */
4718
-static int ocfs2_reflink_inodes_lock(struct inode *s_inode,
4719
- struct buffer_head **bh_s,
4720
- struct inode *t_inode,
4721
- struct buffer_head **bh_t)
4715
+int ocfs2_reflink_inodes_lock(struct inode *s_inode,
4716
+ struct buffer_head **bh_s,
4717
+ struct inode *t_inode,
4718
+ struct buffer_head **bh_t)
47224719 {
47234720 struct inode *inode1 = s_inode;
47244721 struct inode *inode2 = t_inode;
....@@ -4809,10 +4806,10 @@
48094806 }
48104807
48114808 /* Unlock both inodes and release buffers. */
4812
-static void ocfs2_reflink_inodes_unlock(struct inode *s_inode,
4813
- struct buffer_head *s_bh,
4814
- struct inode *t_inode,
4815
- struct buffer_head *t_bh)
4809
+void ocfs2_reflink_inodes_unlock(struct inode *s_inode,
4810
+ struct buffer_head *s_bh,
4811
+ struct inode *t_inode,
4812
+ struct buffer_head *t_bh)
48164813 {
48174814 ocfs2_inode_unlock(s_inode, 1);
48184815 ocfs2_rw_unlock(s_inode, 1);
....@@ -4823,83 +4820,4 @@
48234820 brelse(t_bh);
48244821 }
48254822 unlock_two_nondirectories(s_inode, t_inode);
4826
-}
4827
-
4828
-/* Link a range of blocks from one file to another. */
4829
-int ocfs2_reflink_remap_range(struct file *file_in,
4830
- loff_t pos_in,
4831
- struct file *file_out,
4832
- loff_t pos_out,
4833
- u64 len,
4834
- bool is_dedupe)
4835
-{
4836
- struct inode *inode_in = file_inode(file_in);
4837
- struct inode *inode_out = file_inode(file_out);
4838
- struct ocfs2_super *osb = OCFS2_SB(inode_in->i_sb);
4839
- struct buffer_head *in_bh = NULL, *out_bh = NULL;
4840
- bool same_inode = (inode_in == inode_out);
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 = vfs_clone_file_prep_inodes(inode_in, pos_in, inode_out, pos_out,
4860
- &len, is_dedupe);
4861
- if (ret <= 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
- ret = ocfs2_reflink_remap_blocks(inode_in, in_bh, pos_in, inode_out,
4871
- out_bh, pos_out, len);
4872
-
4873
- /* Zap any page cache for the destination file's range. */
4874
- if (!ret)
4875
- truncate_inode_pages_range(&inode_out->i_data, pos_out,
4876
- PAGE_ALIGN(pos_out + len) - 1);
4877
-
4878
- up_write(&OCFS2_I(inode_in)->ip_alloc_sem);
4879
- if (!same_inode)
4880
- up_write(&OCFS2_I(inode_out)->ip_alloc_sem);
4881
- if (ret) {
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
- ocfs2_reflink_inodes_unlock(inode_in, in_bh, inode_out, out_bh);
4900
- return 0;
4901
-
4902
-out_unlock:
4903
- ocfs2_reflink_inodes_unlock(inode_in, in_bh, inode_out, out_bh);
4904
- return ret;
49054823 }