hc
2024-05-10 9999e48639b3cecb08ffb37358bcba3b48161b29
kernel/fs/ocfs2/file.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /* -*- mode: c; c-basic-offset: 8; -*-
23 * vim: noexpandtab sw=8 ts=8 sts=0:
34 *
....@@ -6,21 +7,6 @@
67 * File open, close, extend, truncate
78 *
89 * Copyright (C) 2002, 2004 Oracle. All rights reserved.
9
- *
10
- * This program is free software; you can redistribute it and/or
11
- * modify it under the terms of the GNU General Public
12
- * License as published by the Free Software Foundation; either
13
- * version 2 of the License, or (at your option) any later version.
14
- *
15
- * This program is distributed in the hope that it will be useful,
16
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18
- * General Public License for more details.
19
- *
20
- * You should have received a copy of the GNU General Public
21
- * License along with this program; if not, write to the
22
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23
- * Boston, MA 021110-1307, USA.
2410 */
2511
2612 #include <linux/capability.h>
....@@ -208,7 +194,7 @@
208194 needs_barrier = true;
209195 err = jbd2_complete_transaction(journal, commit_tid);
210196 if (needs_barrier) {
211
- ret = blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL);
197
+ ret = blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL);
212198 if (!err)
213199 err = ret;
214200 }
....@@ -724,7 +710,9 @@
724710 * Thus, we need to explicitly order the zeroed pages.
725711 */
726712 static handle_t *ocfs2_zero_start_ordered_transaction(struct inode *inode,
727
- struct buffer_head *di_bh)
713
+ struct buffer_head *di_bh,
714
+ loff_t start_byte,
715
+ loff_t length)
728716 {
729717 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
730718 handle_t *handle = NULL;
....@@ -740,7 +728,7 @@
740728 goto out;
741729 }
742730
743
- ret = ocfs2_jbd2_file_inode(handle, inode);
731
+ ret = ocfs2_jbd2_inode_add_write(handle, inode, start_byte, length);
744732 if (ret < 0) {
745733 mlog_errno(ret);
746734 goto out;
....@@ -779,7 +767,9 @@
779767 BUG_ON(abs_to > (((u64)index + 1) << PAGE_SHIFT));
780768 BUG_ON(abs_from & (inode->i_blkbits - 1));
781769
782
- handle = ocfs2_zero_start_ordered_transaction(inode, di_bh);
770
+ handle = ocfs2_zero_start_ordered_transaction(inode, di_bh,
771
+ abs_from,
772
+ abs_to - abs_from);
783773 if (IS_ERR(handle)) {
784774 ret = PTR_ERR(handle);
785775 goto out;
....@@ -1244,6 +1234,7 @@
12441234 transfer_to[USRQUOTA] = dqget(sb, make_kqid_uid(attr->ia_uid));
12451235 if (IS_ERR(transfer_to[USRQUOTA])) {
12461236 status = PTR_ERR(transfer_to[USRQUOTA]);
1237
+ transfer_to[USRQUOTA] = NULL;
12471238 goto bail_unlock;
12481239 }
12491240 }
....@@ -1253,6 +1244,7 @@
12531244 transfer_to[GRPQUOTA] = dqget(sb, make_kqid_gid(attr->ia_gid));
12541245 if (IS_ERR(transfer_to[GRPQUOTA])) {
12551246 status = PTR_ERR(transfer_to[GRPQUOTA]);
1247
+ transfer_to[GRPQUOTA] = NULL;
12561248 goto bail_unlock;
12571249 }
12581250 }
....@@ -2002,7 +1994,7 @@
20021994 }
20031995 }
20041996
2005
- if (file && should_remove_suid(file->f_path.dentry)) {
1997
+ if (file && setattr_should_drop_suidgid(file_inode(file))) {
20061998 ret = __ocfs2_write_remove_suid(inode, di_bh);
20071999 if (ret) {
20082000 mlog_errno(ret);
....@@ -2111,14 +2103,20 @@
21112103 struct ocfs2_space_resv sr;
21122104 int change_size = 1;
21132105 int cmd = OCFS2_IOC_RESVSP64;
2106
+ int ret = 0;
21142107
21152108 if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))
21162109 return -EOPNOTSUPP;
21172110 if (!ocfs2_writes_unwritten_extents(osb))
21182111 return -EOPNOTSUPP;
21192112
2120
- if (mode & FALLOC_FL_KEEP_SIZE)
2113
+ if (mode & FALLOC_FL_KEEP_SIZE) {
21212114 change_size = 0;
2115
+ } else {
2116
+ ret = inode_newsize_ok(inode, offset + len);
2117
+ if (ret)
2118
+ return ret;
2119
+ }
21222120
21232121 if (mode & FALLOC_FL_PUNCH_HOLE)
21242122 cmd = OCFS2_IOC_UNRESVSP64;
....@@ -2247,7 +2245,6 @@
22472245 struct dentry *dentry = file->f_path.dentry;
22482246 struct inode *inode = d_inode(dentry);
22492247 struct buffer_head *di_bh = NULL;
2250
- loff_t end;
22512248 u32 cpos;
22522249 u32 clusters;
22532250
....@@ -2291,7 +2288,7 @@
22912288 * inode. There's also the dinode i_size state which
22922289 * can be lost via setattr during extending writes (we
22932290 * set inode->i_size at the end of a write. */
2294
- if (should_remove_suid(dentry)) {
2291
+ if (setattr_should_drop_suidgid(inode)) {
22952292 if (meta_level == 0) {
22962293 ocfs2_inode_unlock_for_extent_tree(inode,
22972294 &di_bh,
....@@ -2307,8 +2304,6 @@
23072304 goto out_unlock;
23082305 }
23092306 }
2310
-
2311
- end = pos + count;
23122307
23132308 ret = ocfs2_check_range_for_refcount(inode, pos, count);
23142309 if (ret == 1) {
....@@ -2645,24 +2640,79 @@
26452640 return offset;
26462641 }
26472642
2648
-static int ocfs2_file_clone_range(struct file *file_in,
2649
- loff_t pos_in,
2650
- struct file *file_out,
2651
- loff_t pos_out,
2652
- u64 len)
2643
+static loff_t ocfs2_remap_file_range(struct file *file_in, loff_t pos_in,
2644
+ struct file *file_out, loff_t pos_out,
2645
+ loff_t len, unsigned int remap_flags)
26532646 {
2654
- return ocfs2_reflink_remap_range(file_in, pos_in, file_out, pos_out,
2655
- len, false);
2656
-}
2647
+ struct inode *inode_in = file_inode(file_in);
2648
+ struct inode *inode_out = file_inode(file_out);
2649
+ struct ocfs2_super *osb = OCFS2_SB(inode_in->i_sb);
2650
+ struct buffer_head *in_bh = NULL, *out_bh = NULL;
2651
+ bool same_inode = (inode_in == inode_out);
2652
+ loff_t remapped = 0;
2653
+ ssize_t ret;
26572654
2658
-static int ocfs2_file_dedupe_range(struct file *file_in,
2659
- loff_t pos_in,
2660
- struct file *file_out,
2661
- loff_t pos_out,
2662
- u64 len)
2663
-{
2664
- return ocfs2_reflink_remap_range(file_in, pos_in, file_out, pos_out,
2665
- len, true);
2655
+ if (remap_flags & ~(REMAP_FILE_DEDUP | REMAP_FILE_ADVISORY))
2656
+ return -EINVAL;
2657
+ if (!ocfs2_refcount_tree(osb))
2658
+ return -EOPNOTSUPP;
2659
+ if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb))
2660
+ return -EROFS;
2661
+
2662
+ /* Lock both files against IO */
2663
+ ret = ocfs2_reflink_inodes_lock(inode_in, &in_bh, inode_out, &out_bh);
2664
+ if (ret)
2665
+ return ret;
2666
+
2667
+ /* Check file eligibility and prepare for block sharing. */
2668
+ ret = -EINVAL;
2669
+ if ((OCFS2_I(inode_in)->ip_flags & OCFS2_INODE_SYSTEM_FILE) ||
2670
+ (OCFS2_I(inode_out)->ip_flags & OCFS2_INODE_SYSTEM_FILE))
2671
+ goto out_unlock;
2672
+
2673
+ ret = generic_remap_file_range_prep(file_in, pos_in, file_out, pos_out,
2674
+ &len, remap_flags);
2675
+ if (ret < 0 || len == 0)
2676
+ goto out_unlock;
2677
+
2678
+ /* Lock out changes to the allocation maps and remap. */
2679
+ down_write(&OCFS2_I(inode_in)->ip_alloc_sem);
2680
+ if (!same_inode)
2681
+ down_write_nested(&OCFS2_I(inode_out)->ip_alloc_sem,
2682
+ SINGLE_DEPTH_NESTING);
2683
+
2684
+ /* Zap any page cache for the destination file's range. */
2685
+ truncate_inode_pages_range(&inode_out->i_data,
2686
+ round_down(pos_out, PAGE_SIZE),
2687
+ round_up(pos_out + len, PAGE_SIZE) - 1);
2688
+
2689
+ remapped = ocfs2_reflink_remap_blocks(inode_in, in_bh, pos_in,
2690
+ inode_out, out_bh, pos_out, len);
2691
+ up_write(&OCFS2_I(inode_in)->ip_alloc_sem);
2692
+ if (!same_inode)
2693
+ up_write(&OCFS2_I(inode_out)->ip_alloc_sem);
2694
+ if (remapped < 0) {
2695
+ ret = remapped;
2696
+ mlog_errno(ret);
2697
+ goto out_unlock;
2698
+ }
2699
+
2700
+ /*
2701
+ * Empty the extent map so that we may get the right extent
2702
+ * record from the disk.
2703
+ */
2704
+ ocfs2_extent_map_trunc(inode_in, 0);
2705
+ ocfs2_extent_map_trunc(inode_out, 0);
2706
+
2707
+ ret = ocfs2_reflink_update_dest(inode_out, out_bh, pos_out + len);
2708
+ if (ret) {
2709
+ mlog_errno(ret);
2710
+ goto out_unlock;
2711
+ }
2712
+
2713
+out_unlock:
2714
+ ocfs2_reflink_inodes_unlock(inode_in, in_bh, inode_out, out_bh);
2715
+ return remapped > 0 ? remapped : ret;
26662716 }
26672717
26682718 const struct inode_operations ocfs2_file_iops = {
....@@ -2704,8 +2754,7 @@
27042754 .splice_read = generic_file_splice_read,
27052755 .splice_write = iter_file_splice_write,
27062756 .fallocate = ocfs2_fallocate,
2707
- .clone_file_range = ocfs2_file_clone_range,
2708
- .dedupe_file_range = ocfs2_file_dedupe_range,
2757
+ .remap_file_range = ocfs2_remap_file_range,
27092758 };
27102759
27112760 const struct file_operations ocfs2_dops = {
....@@ -2751,8 +2800,7 @@
27512800 .splice_read = generic_file_splice_read,
27522801 .splice_write = iter_file_splice_write,
27532802 .fallocate = ocfs2_fallocate,
2754
- .clone_file_range = ocfs2_file_clone_range,
2755
- .dedupe_file_range = ocfs2_file_dedupe_range,
2803
+ .remap_file_range = ocfs2_remap_file_range,
27562804 };
27572805
27582806 const struct file_operations ocfs2_dops_no_plocks = {