aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/filesystems/ext4.txt10
-rw-r--r--fs/ext4/ext4.h8
-rw-r--r--fs/ext4/inode.c11
-rw-r--r--fs/ext4/ioctl.c197
-rw-r--r--fs/ext4/move_extent.c48
5 files changed, 248 insertions, 26 deletions
diff --git a/Documentation/filesystems/ext4.txt b/Documentation/filesystems/ext4.txt
index 34ea4f1fa6ea..5dd957d8b25b 100644
--- a/Documentation/filesystems/ext4.txt
+++ b/Documentation/filesystems/ext4.txt
@@ -587,6 +587,16 @@ Table of Ext4 specific ioctls
587 bitmaps and inode table, the userspace tool thus 587 bitmaps and inode table, the userspace tool thus
588 just passes the new number of blocks. 588 just passes the new number of blocks.
589 589
590EXT4_IOC_SWAP_BOOT Swap i_blocks and associated attributes
591 (like i_blocks, i_size, i_flags, ...) from
592 the specified inode with inode
593 EXT4_BOOT_LOADER_INO (#5). This is typically
594 used to store a boot loader in a secure part of
595 the filesystem, where it can't be changed by a
596 normal user by accident.
597 The data blocks of the previous boot loader
598 will be associated with the given inode.
599
590.............................................................................. 600..............................................................................
591 601
592References 602References
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index a0637e5057ae..d91871570982 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -616,6 +616,7 @@ enum {
616#define EXT4_IOC_ALLOC_DA_BLKS _IO('f', 12) 616#define EXT4_IOC_ALLOC_DA_BLKS _IO('f', 12)
617#define EXT4_IOC_MOVE_EXT _IOWR('f', 15, struct move_extent) 617#define EXT4_IOC_MOVE_EXT _IOWR('f', 15, struct move_extent)
618#define EXT4_IOC_RESIZE_FS _IOW('f', 16, __u64) 618#define EXT4_IOC_RESIZE_FS _IOW('f', 16, __u64)
619#define EXT4_IOC_SWAP_BOOT _IO('f', 17)
619 620
620#if defined(__KERNEL__) && defined(CONFIG_COMPAT) 621#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
621/* 622/*
@@ -1341,6 +1342,7 @@ static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino)
1341 return ino == EXT4_ROOT_INO || 1342 return ino == EXT4_ROOT_INO ||
1342 ino == EXT4_USR_QUOTA_INO || 1343 ino == EXT4_USR_QUOTA_INO ||
1343 ino == EXT4_GRP_QUOTA_INO || 1344 ino == EXT4_GRP_QUOTA_INO ||
1345 ino == EXT4_BOOT_LOADER_INO ||
1344 ino == EXT4_JOURNAL_INO || 1346 ino == EXT4_JOURNAL_INO ||
1345 ino == EXT4_RESIZE_INO || 1347 ino == EXT4_RESIZE_INO ||
1346 (ino >= EXT4_FIRST_INO(sb) && 1348 (ino >= EXT4_FIRST_INO(sb) &&
@@ -2624,6 +2626,12 @@ extern int ext4_ind_migrate(struct inode *inode);
2624 2626
2625 2627
2626/* move_extent.c */ 2628/* move_extent.c */
2629extern void ext4_double_down_write_data_sem(struct inode *first,
2630 struct inode *second);
2631extern void ext4_double_up_write_data_sem(struct inode *orig_inode,
2632 struct inode *donor_inode);
2633void ext4_inode_double_lock(struct inode *inode1, struct inode *inode2);
2634void ext4_inode_double_unlock(struct inode *inode1, struct inode *inode2);
2627extern int ext4_move_extents(struct file *o_filp, struct file *d_filp, 2635extern int ext4_move_extents(struct file *o_filp, struct file *d_filp,
2628 __u64 start_orig, __u64 start_donor, 2636 __u64 start_orig, __u64 start_donor,
2629 __u64 len, __u64 *moved_len); 2637 __u64 len, __u64 *moved_len);
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 769c656ea3b1..a29bfc2142ef 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -4191,8 +4191,9 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
4191 * NeilBrown 1999oct15 4191 * NeilBrown 1999oct15
4192 */ 4192 */
4193 if (inode->i_nlink == 0) { 4193 if (inode->i_nlink == 0) {
4194 if (inode->i_mode == 0 || 4194 if ((inode->i_mode == 0 ||
4195 !(EXT4_SB(inode->i_sb)->s_mount_state & EXT4_ORPHAN_FS)) { 4195 !(EXT4_SB(inode->i_sb)->s_mount_state & EXT4_ORPHAN_FS)) &&
4196 ino != EXT4_BOOT_LOADER_INO) {
4196 /* this inode is deleted */ 4197 /* this inode is deleted */
4197 ret = -ESTALE; 4198 ret = -ESTALE;
4198 goto bad_inode; 4199 goto bad_inode;
@@ -4200,7 +4201,9 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
4200 /* The only unlinked inodes we let through here have 4201 /* The only unlinked inodes we let through here have
4201 * valid i_mode and are being read by the orphan 4202 * valid i_mode and are being read by the orphan
4202 * recovery code: that's fine, we're about to complete 4203 * recovery code: that's fine, we're about to complete
4203 * the process of deleting those. */ 4204 * the process of deleting those.
4205 * OR it is the EXT4_BOOT_LOADER_INO which is
4206 * not initialized on a new filesystem. */
4204 } 4207 }
4205 ei->i_flags = le32_to_cpu(raw_inode->i_flags); 4208 ei->i_flags = le32_to_cpu(raw_inode->i_flags);
4206 inode->i_blocks = ext4_inode_blocks(raw_inode, ei); 4209 inode->i_blocks = ext4_inode_blocks(raw_inode, ei);
@@ -4320,6 +4323,8 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
4320 else 4323 else
4321 init_special_inode(inode, inode->i_mode, 4324 init_special_inode(inode, inode->i_mode,
4322 new_decode_dev(le32_to_cpu(raw_inode->i_block[1]))); 4325 new_decode_dev(le32_to_cpu(raw_inode->i_block[1])));
4326 } else if (ino == EXT4_BOOT_LOADER_INO) {
4327 make_bad_inode(inode);
4323 } else { 4328 } else {
4324 ret = -EIO; 4329 ret = -EIO;
4325 EXT4_ERROR_INODE(inode, "bogus i_mode (%o)", inode->i_mode); 4330 EXT4_ERROR_INODE(inode, "bogus i_mode (%o)", inode->i_mode);
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
index a07b7bc0856a..cbc3acea6bcf 100644
--- a/fs/ext4/ioctl.c
+++ b/fs/ext4/ioctl.c
@@ -17,9 +17,201 @@
17#include <asm/uaccess.h> 17#include <asm/uaccess.h>
18#include "ext4_jbd2.h" 18#include "ext4_jbd2.h"
19#include "ext4.h" 19#include "ext4.h"
20#include "ext4_extents.h"
20 21
21#define MAX_32_NUM ((((unsigned long long) 1) << 32) - 1) 22#define MAX_32_NUM ((((unsigned long long) 1) << 32) - 1)
22 23
24/**
25 * Swap memory between @a and @b for @len bytes.
26 *
27 * @a: pointer to first memory area
28 * @b: pointer to second memory area
29 * @len: number of bytes to swap
30 *
31 */
32static void memswap(void *a, void *b, size_t len)
33{
34 unsigned char *ap, *bp;
35 unsigned char tmp;
36
37 ap = (unsigned char *)a;
38 bp = (unsigned char *)b;
39 while (len-- > 0) {
40 tmp = *ap;
41 *ap = *bp;
42 *bp = tmp;
43 ap++;
44 bp++;
45 }
46}
47
48/**
49 * Swap i_data and associated attributes between @inode1 and @inode2.
50 * This function is used for the primary swap between inode1 and inode2
51 * and also to revert this primary swap in case of errors.
52 *
53 * Therefore you have to make sure, that calling this method twice
54 * will revert all changes.
55 *
56 * @inode1: pointer to first inode
57 * @inode2: pointer to second inode
58 */
59static void swap_inode_data(struct inode *inode1, struct inode *inode2)
60{
61 loff_t isize;
62 struct ext4_inode_info *ei1;
63 struct ext4_inode_info *ei2;
64
65 ei1 = EXT4_I(inode1);
66 ei2 = EXT4_I(inode2);
67
68 memswap(&inode1->i_flags, &inode2->i_flags, sizeof(inode1->i_flags));
69 memswap(&inode1->i_version, &inode2->i_version,
70 sizeof(inode1->i_version));
71 memswap(&inode1->i_blocks, &inode2->i_blocks,
72 sizeof(inode1->i_blocks));
73 memswap(&inode1->i_bytes, &inode2->i_bytes, sizeof(inode1->i_bytes));
74 memswap(&inode1->i_atime, &inode2->i_atime, sizeof(inode1->i_atime));
75 memswap(&inode1->i_mtime, &inode2->i_mtime, sizeof(inode1->i_mtime));
76
77 memswap(ei1->i_data, ei2->i_data, sizeof(ei1->i_data));
78 memswap(&ei1->i_flags, &ei2->i_flags, sizeof(ei1->i_flags));
79 memswap(&ei1->i_disksize, &ei2->i_disksize, sizeof(ei1->i_disksize));
80 memswap(&ei1->i_es_tree, &ei2->i_es_tree, sizeof(ei1->i_es_tree));
81 memswap(&ei1->i_es_lru_nr, &ei2->i_es_lru_nr, sizeof(ei1->i_es_lru_nr));
82
83 isize = i_size_read(inode1);
84 i_size_write(inode1, i_size_read(inode2));
85 i_size_write(inode2, isize);
86}
87
88/**
89 * Swap the information from the given @inode and the inode
90 * EXT4_BOOT_LOADER_INO. It will basically swap i_data and all other
91 * important fields of the inodes.
92 *
93 * @sb: the super block of the filesystem
94 * @inode: the inode to swap with EXT4_BOOT_LOADER_INO
95 *
96 */
97static long swap_inode_boot_loader(struct super_block *sb,
98 struct inode *inode)
99{
100 handle_t *handle;
101 int err;
102 struct inode *inode_bl;
103 struct ext4_inode_info *ei;
104 struct ext4_inode_info *ei_bl;
105 struct ext4_sb_info *sbi;
106
107 if (inode->i_nlink != 1 || !S_ISREG(inode->i_mode)) {
108 err = -EINVAL;
109 goto swap_boot_out;
110 }
111
112 if (!inode_owner_or_capable(inode) || !capable(CAP_SYS_ADMIN)) {
113 err = -EPERM;
114 goto swap_boot_out;
115 }
116
117 sbi = EXT4_SB(sb);
118 ei = EXT4_I(inode);
119
120 inode_bl = ext4_iget(sb, EXT4_BOOT_LOADER_INO);
121 if (IS_ERR(inode_bl)) {
122 err = PTR_ERR(inode_bl);
123 goto swap_boot_out;
124 }
125 ei_bl = EXT4_I(inode_bl);
126
127 filemap_flush(inode->i_mapping);
128 filemap_flush(inode_bl->i_mapping);
129
130 /* Protect orig inodes against a truncate and make sure,
131 * that only 1 swap_inode_boot_loader is running. */
132 ext4_inode_double_lock(inode, inode_bl);
133
134 truncate_inode_pages(&inode->i_data, 0);
135 truncate_inode_pages(&inode_bl->i_data, 0);
136
137 /* Wait for all existing dio workers */
138 ext4_inode_block_unlocked_dio(inode);
139 ext4_inode_block_unlocked_dio(inode_bl);
140 inode_dio_wait(inode);
141 inode_dio_wait(inode_bl);
142
143 handle = ext4_journal_start(inode_bl, EXT4_HT_MOVE_EXTENTS, 2);
144 if (IS_ERR(handle)) {
145 err = -EINVAL;
146 goto swap_boot_out;
147 }
148
149 /* Protect extent tree against block allocations via delalloc */
150 ext4_double_down_write_data_sem(inode, inode_bl);
151
152 if (inode_bl->i_nlink == 0) {
153 /* this inode has never been used as a BOOT_LOADER */
154 set_nlink(inode_bl, 1);
155 i_uid_write(inode_bl, 0);
156 i_gid_write(inode_bl, 0);
157 inode_bl->i_flags = 0;
158 ei_bl->i_flags = 0;
159 inode_bl->i_version = 1;
160 i_size_write(inode_bl, 0);
161 inode_bl->i_mode = S_IFREG;
162 if (EXT4_HAS_INCOMPAT_FEATURE(sb,
163 EXT4_FEATURE_INCOMPAT_EXTENTS)) {
164 ext4_set_inode_flag(inode_bl, EXT4_INODE_EXTENTS);
165 ext4_ext_tree_init(handle, inode_bl);
166 } else
167 memset(ei_bl->i_data, 0, sizeof(ei_bl->i_data));
168 }
169
170 swap_inode_data(inode, inode_bl);
171
172 inode->i_ctime = inode_bl->i_ctime = ext4_current_time(inode);
173
174 spin_lock(&sbi->s_next_gen_lock);
175 inode->i_generation = sbi->s_next_generation++;
176 inode_bl->i_generation = sbi->s_next_generation++;
177 spin_unlock(&sbi->s_next_gen_lock);
178
179 ext4_discard_preallocations(inode);
180
181 err = ext4_mark_inode_dirty(handle, inode);
182 if (err < 0) {
183 ext4_warning(inode->i_sb,
184 "couldn't mark inode #%lu dirty (err %d)",
185 inode->i_ino, err);
186 /* Revert all changes: */
187 swap_inode_data(inode, inode_bl);
188 } else {
189 err = ext4_mark_inode_dirty(handle, inode_bl);
190 if (err < 0) {
191 ext4_warning(inode_bl->i_sb,
192 "couldn't mark inode #%lu dirty (err %d)",
193 inode_bl->i_ino, err);
194 /* Revert all changes: */
195 swap_inode_data(inode, inode_bl);
196 ext4_mark_inode_dirty(handle, inode);
197 }
198 }
199
200 ext4_journal_stop(handle);
201
202 ext4_double_up_write_data_sem(inode, inode_bl);
203
204 ext4_inode_resume_unlocked_dio(inode);
205 ext4_inode_resume_unlocked_dio(inode_bl);
206
207 ext4_inode_double_unlock(inode, inode_bl);
208
209 iput(inode_bl);
210
211swap_boot_out:
212 return err;
213}
214
23long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 215long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
24{ 216{
25 struct inode *inode = file_inode(filp); 217 struct inode *inode = file_inode(filp);
@@ -353,6 +545,11 @@ group_add_out:
353 return err; 545 return err;
354 } 546 }
355 547
548 case EXT4_IOC_SWAP_BOOT:
549 if (!(filp->f_mode & FMODE_WRITE))
550 return -EBADF;
551 return swap_inode_boot_loader(sb, inode);
552
356 case EXT4_IOC_RESIZE_FS: { 553 case EXT4_IOC_RESIZE_FS: {
357 ext4_fsblk_t n_blocks_count; 554 ext4_fsblk_t n_blocks_count;
358 struct super_block *sb = inode->i_sb; 555 struct super_block *sb = inode->i_sb;
diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
index 33e1c086858b..a2e696e16331 100644
--- a/fs/ext4/move_extent.c
+++ b/fs/ext4/move_extent.c
@@ -144,12 +144,13 @@ mext_next_extent(struct inode *inode, struct ext4_ext_path *path,
144} 144}
145 145
146/** 146/**
147 * double_down_write_data_sem - Acquire two inodes' write lock of i_data_sem 147 * ext4_double_down_write_data_sem - Acquire two inodes' write lock
148 * of i_data_sem
148 * 149 *
149 * Acquire write lock of i_data_sem of the two inodes 150 * Acquire write lock of i_data_sem of the two inodes
150 */ 151 */
151static void 152void
152double_down_write_data_sem(struct inode *first, struct inode *second) 153ext4_double_down_write_data_sem(struct inode *first, struct inode *second)
153{ 154{
154 if (first < second) { 155 if (first < second) {
155 down_write(&EXT4_I(first)->i_data_sem); 156 down_write(&EXT4_I(first)->i_data_sem);
@@ -162,14 +163,15 @@ double_down_write_data_sem(struct inode *first, struct inode *second)
162} 163}
163 164
164/** 165/**
165 * double_up_write_data_sem - Release two inodes' write lock of i_data_sem 166 * ext4_double_up_write_data_sem - Release two inodes' write lock of i_data_sem
166 * 167 *
167 * @orig_inode: original inode structure to be released its lock first 168 * @orig_inode: original inode structure to be released its lock first
168 * @donor_inode: donor inode structure to be released its lock second 169 * @donor_inode: donor inode structure to be released its lock second
169 * Release write lock of i_data_sem of two inodes (orig and donor). 170 * Release write lock of i_data_sem of two inodes (orig and donor).
170 */ 171 */
171static void 172void
172double_up_write_data_sem(struct inode *orig_inode, struct inode *donor_inode) 173ext4_double_up_write_data_sem(struct inode *orig_inode,
174 struct inode *donor_inode)
173{ 175{
174 up_write(&EXT4_I(orig_inode)->i_data_sem); 176 up_write(&EXT4_I(orig_inode)->i_data_sem);
175 up_write(&EXT4_I(donor_inode)->i_data_sem); 177 up_write(&EXT4_I(donor_inode)->i_data_sem);
@@ -976,7 +978,7 @@ again:
976 * necessary, just swap data blocks between orig and donor. 978 * necessary, just swap data blocks between orig and donor.
977 */ 979 */
978 if (uninit) { 980 if (uninit) {
979 double_down_write_data_sem(orig_inode, donor_inode); 981 ext4_double_down_write_data_sem(orig_inode, donor_inode);
980 /* If any of extents in range became initialized we have to 982 /* If any of extents in range became initialized we have to
981 * fallback to data copying */ 983 * fallback to data copying */
982 uninit = mext_check_coverage(orig_inode, orig_blk_offset, 984 uninit = mext_check_coverage(orig_inode, orig_blk_offset,
@@ -990,7 +992,7 @@ again:
990 goto drop_data_sem; 992 goto drop_data_sem;
991 993
992 if (!uninit) { 994 if (!uninit) {
993 double_up_write_data_sem(orig_inode, donor_inode); 995 ext4_double_up_write_data_sem(orig_inode, donor_inode);
994 goto data_copy; 996 goto data_copy;
995 } 997 }
996 if ((page_has_private(pagep[0]) && 998 if ((page_has_private(pagep[0]) &&
@@ -1004,7 +1006,7 @@ again:
1004 donor_inode, orig_blk_offset, 1006 donor_inode, orig_blk_offset,
1005 block_len_in_page, err); 1007 block_len_in_page, err);
1006 drop_data_sem: 1008 drop_data_sem:
1007 double_up_write_data_sem(orig_inode, donor_inode); 1009 ext4_double_up_write_data_sem(orig_inode, donor_inode);
1008 goto unlock_pages; 1010 goto unlock_pages;
1009 } 1011 }
1010data_copy: 1012data_copy:
@@ -1065,11 +1067,11 @@ repair_branches:
1065 * Extents are swapped already, but we are not able to copy data. 1067 * Extents are swapped already, but we are not able to copy data.
1066 * Try to swap extents to it's original places 1068 * Try to swap extents to it's original places
1067 */ 1069 */
1068 double_down_write_data_sem(orig_inode, donor_inode); 1070 ext4_double_down_write_data_sem(orig_inode, donor_inode);
1069 replaced_count = mext_replace_branches(handle, donor_inode, orig_inode, 1071 replaced_count = mext_replace_branches(handle, donor_inode, orig_inode,
1070 orig_blk_offset, 1072 orig_blk_offset,
1071 block_len_in_page, &err2); 1073 block_len_in_page, &err2);
1072 double_up_write_data_sem(orig_inode, donor_inode); 1074 ext4_double_up_write_data_sem(orig_inode, donor_inode);
1073 if (replaced_count != block_len_in_page) { 1075 if (replaced_count != block_len_in_page) {
1074 EXT4_ERROR_INODE_BLOCK(orig_inode, (sector_t)(orig_blk_offset), 1076 EXT4_ERROR_INODE_BLOCK(orig_inode, (sector_t)(orig_blk_offset),
1075 "Unable to copy data block," 1077 "Unable to copy data block,"
@@ -1209,15 +1211,15 @@ mext_check_arguments(struct inode *orig_inode,
1209} 1211}
1210 1212
1211/** 1213/**
1212 * mext_inode_double_lock - Lock i_mutex on both @inode1 and @inode2 1214 * ext4_inode_double_lock - Lock i_mutex on both @inode1 and @inode2
1213 * 1215 *
1214 * @inode1: the inode structure 1216 * @inode1: the inode structure
1215 * @inode2: the inode structure 1217 * @inode2: the inode structure
1216 * 1218 *
1217 * Lock two inodes' i_mutex 1219 * Lock two inodes' i_mutex
1218 */ 1220 */
1219static void 1221void
1220mext_inode_double_lock(struct inode *inode1, struct inode *inode2) 1222ext4_inode_double_lock(struct inode *inode1, struct inode *inode2)
1221{ 1223{
1222 BUG_ON(inode1 == inode2); 1224 BUG_ON(inode1 == inode2);
1223 if (inode1 < inode2) { 1225 if (inode1 < inode2) {
@@ -1230,15 +1232,15 @@ mext_inode_double_lock(struct inode *inode1, struct inode *inode2)
1230} 1232}
1231 1233
1232/** 1234/**
1233 * mext_inode_double_unlock - Release i_mutex on both @inode1 and @inode2 1235 * ext4_inode_double_unlock - Release i_mutex on both @inode1 and @inode2
1234 * 1236 *
1235 * @inode1: the inode that is released first 1237 * @inode1: the inode that is released first
1236 * @inode2: the inode that is released second 1238 * @inode2: the inode that is released second
1237 * 1239 *
1238 */ 1240 */
1239 1241
1240static void 1242void
1241mext_inode_double_unlock(struct inode *inode1, struct inode *inode2) 1243ext4_inode_double_unlock(struct inode *inode1, struct inode *inode2)
1242{ 1244{
1243 mutex_unlock(&inode1->i_mutex); 1245 mutex_unlock(&inode1->i_mutex);
1244 mutex_unlock(&inode2->i_mutex); 1246 mutex_unlock(&inode2->i_mutex);
@@ -1333,7 +1335,7 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
1333 return -EINVAL; 1335 return -EINVAL;
1334 } 1336 }
1335 /* Protect orig and donor inodes against a truncate */ 1337 /* Protect orig and donor inodes against a truncate */
1336 mext_inode_double_lock(orig_inode, donor_inode); 1338 ext4_inode_double_lock(orig_inode, donor_inode);
1337 1339
1338 /* Wait for all existing dio workers */ 1340 /* Wait for all existing dio workers */
1339 ext4_inode_block_unlocked_dio(orig_inode); 1341 ext4_inode_block_unlocked_dio(orig_inode);
@@ -1342,7 +1344,7 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
1342 inode_dio_wait(donor_inode); 1344 inode_dio_wait(donor_inode);
1343 1345
1344 /* Protect extent tree against block allocations via delalloc */ 1346 /* Protect extent tree against block allocations via delalloc */
1345 double_down_write_data_sem(orig_inode, donor_inode); 1347 ext4_double_down_write_data_sem(orig_inode, donor_inode);
1346 /* Check the filesystem environment whether move_extent can be done */ 1348 /* Check the filesystem environment whether move_extent can be done */
1347 ret = mext_check_arguments(orig_inode, donor_inode, orig_start, 1349 ret = mext_check_arguments(orig_inode, donor_inode, orig_start,
1348 donor_start, &len); 1350 donor_start, &len);
@@ -1466,7 +1468,7 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
1466 * b. racing with ->readpage, ->write_begin, and ext4_get_block 1468 * b. racing with ->readpage, ->write_begin, and ext4_get_block
1467 * in move_extent_per_page 1469 * in move_extent_per_page
1468 */ 1470 */
1469 double_up_write_data_sem(orig_inode, donor_inode); 1471 ext4_double_up_write_data_sem(orig_inode, donor_inode);
1470 1472
1471 while (orig_page_offset <= seq_end_page) { 1473 while (orig_page_offset <= seq_end_page) {
1472 1474
@@ -1500,7 +1502,7 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
1500 block_len_in_page = rest_blocks; 1502 block_len_in_page = rest_blocks;
1501 } 1503 }
1502 1504
1503 double_down_write_data_sem(orig_inode, donor_inode); 1505 ext4_double_down_write_data_sem(orig_inode, donor_inode);
1504 if (ret < 0) 1506 if (ret < 0)
1505 break; 1507 break;
1506 1508
@@ -1538,10 +1540,10 @@ out:
1538 ext4_ext_drop_refs(holecheck_path); 1540 ext4_ext_drop_refs(holecheck_path);
1539 kfree(holecheck_path); 1541 kfree(holecheck_path);
1540 } 1542 }
1541 double_up_write_data_sem(orig_inode, donor_inode); 1543 ext4_double_up_write_data_sem(orig_inode, donor_inode);
1542 ext4_inode_resume_unlocked_dio(orig_inode); 1544 ext4_inode_resume_unlocked_dio(orig_inode);
1543 ext4_inode_resume_unlocked_dio(donor_inode); 1545 ext4_inode_resume_unlocked_dio(donor_inode);
1544 mext_inode_double_unlock(orig_inode, donor_inode); 1546 ext4_inode_double_unlock(orig_inode, donor_inode);
1545 1547
1546 return ret; 1548 return ret;
1547} 1549}