Commit | Line | Data |
---|---|---|
f5166768 | 1 | // SPDX-License-Identifier: LGPL-2.1 |
c14c6fd5 AK |
2 | /* |
3 | * Copyright IBM Corporation, 2007 | |
4 | * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> | |
5 | * | |
c14c6fd5 AK |
6 | */ |
7 | ||
5a0e3ad6 | 8 | #include <linux/slab.h> |
3dcf5451 | 9 | #include "ext4_jbd2.h" |
4a092d73 | 10 | #include "ext4_extents.h" |
c14c6fd5 AK |
11 | |
12 | /* | |
13 | * The contiguous blocks details which can be | |
14 | * represented by a single extent | |
15 | */ | |
fba90ffe DM |
16 | struct migrate_struct { |
17 | ext4_lblk_t first_block, last_block, curr_block; | |
c14c6fd5 AK |
18 | ext4_fsblk_t first_pblock, last_pblock; |
19 | }; | |
20 | ||
21 | static int finish_range(handle_t *handle, struct inode *inode, | |
fba90ffe | 22 | struct migrate_struct *lb) |
c14c6fd5 AK |
23 | |
24 | { | |
25 | int retval = 0, needed; | |
26 | struct ext4_extent newext; | |
27 | struct ext4_ext_path *path; | |
28 | if (lb->first_pblock == 0) | |
29 | return 0; | |
30 | ||
31 | /* Add the extent to temp inode*/ | |
32 | newext.ee_block = cpu_to_le32(lb->first_block); | |
33 | newext.ee_len = cpu_to_le16(lb->last_block - lb->first_block + 1); | |
34 | ext4_ext_store_pblock(&newext, lb->first_pblock); | |
4b1f1660 DM |
35 | /* Locking only for convinience since we are operating on temp inode */ |
36 | down_write(&EXT4_I(inode)->i_data_sem); | |
ed8a1a76 | 37 | path = ext4_find_extent(inode, lb->first_block, NULL, 0); |
c14c6fd5 AK |
38 | if (IS_ERR(path)) { |
39 | retval = PTR_ERR(path); | |
b35905c1 | 40 | path = NULL; |
c14c6fd5 AK |
41 | goto err_out; |
42 | } | |
43 | ||
44 | /* | |
45 | * Calculate the credit needed to inserting this extent | |
46 | * Since we are doing this in loop we may accumalate extra | |
47 | * credit. But below we try to not accumalate too much | |
48 | * of them by restarting the journal. | |
49 | */ | |
ee12b630 MC |
50 | needed = ext4_ext_calc_credits_for_single_extent(inode, |
51 | lb->last_block - lb->first_block + 1, path); | |
c14c6fd5 | 52 | |
83448bdf | 53 | retval = ext4_datasem_ensure_credits(handle, inode, needed, needed, 0); |
a4130367 JK |
54 | if (retval < 0) |
55 | goto err_out; | |
dfe50809 | 56 | retval = ext4_ext_insert_extent(handle, inode, &path, &newext, 0); |
c14c6fd5 | 57 | err_out: |
4b1f1660 | 58 | up_write((&EXT4_I(inode)->i_data_sem)); |
b7ea89ad TT |
59 | ext4_ext_drop_refs(path); |
60 | kfree(path); | |
c14c6fd5 AK |
61 | lb->first_pblock = 0; |
62 | return retval; | |
63 | } | |
64 | ||
65 | static int update_extent_range(handle_t *handle, struct inode *inode, | |
fba90ffe | 66 | ext4_fsblk_t pblock, struct migrate_struct *lb) |
c14c6fd5 AK |
67 | { |
68 | int retval; | |
69 | /* | |
70 | * See if we can add on to the existing range (if it exists) | |
71 | */ | |
72 | if (lb->first_pblock && | |
73 | (lb->last_pblock+1 == pblock) && | |
fba90ffe | 74 | (lb->last_block+1 == lb->curr_block)) { |
c14c6fd5 | 75 | lb->last_pblock = pblock; |
fba90ffe DM |
76 | lb->last_block = lb->curr_block; |
77 | lb->curr_block++; | |
c14c6fd5 AK |
78 | return 0; |
79 | } | |
80 | /* | |
81 | * Start a new range. | |
82 | */ | |
83 | retval = finish_range(handle, inode, lb); | |
84 | lb->first_pblock = lb->last_pblock = pblock; | |
fba90ffe DM |
85 | lb->first_block = lb->last_block = lb->curr_block; |
86 | lb->curr_block++; | |
c14c6fd5 AK |
87 | return retval; |
88 | } | |
89 | ||
90 | static int update_ind_extent_range(handle_t *handle, struct inode *inode, | |
fba90ffe DM |
91 | ext4_fsblk_t pblock, |
92 | struct migrate_struct *lb) | |
c14c6fd5 AK |
93 | { |
94 | struct buffer_head *bh; | |
95 | __le32 *i_data; | |
96 | int i, retval = 0; | |
c14c6fd5 AK |
97 | unsigned long max_entries = inode->i_sb->s_blocksize >> 2; |
98 | ||
fb265c9c TT |
99 | bh = ext4_sb_bread(inode->i_sb, pblock, 0); |
100 | if (IS_ERR(bh)) | |
101 | return PTR_ERR(bh); | |
c14c6fd5 AK |
102 | |
103 | i_data = (__le32 *)bh->b_data; | |
fba90ffe | 104 | for (i = 0; i < max_entries; i++) { |
c14c6fd5 AK |
105 | if (i_data[i]) { |
106 | retval = update_extent_range(handle, inode, | |
fba90ffe | 107 | le32_to_cpu(i_data[i]), lb); |
c14c6fd5 AK |
108 | if (retval) |
109 | break; | |
fba90ffe DM |
110 | } else { |
111 | lb->curr_block++; | |
c14c6fd5 AK |
112 | } |
113 | } | |
c14c6fd5 AK |
114 | put_bh(bh); |
115 | return retval; | |
116 | ||
117 | } | |
118 | ||
119 | static int update_dind_extent_range(handle_t *handle, struct inode *inode, | |
fba90ffe DM |
120 | ext4_fsblk_t pblock, |
121 | struct migrate_struct *lb) | |
c14c6fd5 AK |
122 | { |
123 | struct buffer_head *bh; | |
124 | __le32 *i_data; | |
125 | int i, retval = 0; | |
c14c6fd5 AK |
126 | unsigned long max_entries = inode->i_sb->s_blocksize >> 2; |
127 | ||
fb265c9c TT |
128 | bh = ext4_sb_bread(inode->i_sb, pblock, 0); |
129 | if (IS_ERR(bh)) | |
130 | return PTR_ERR(bh); | |
c14c6fd5 AK |
131 | |
132 | i_data = (__le32 *)bh->b_data; | |
133 | for (i = 0; i < max_entries; i++) { | |
134 | if (i_data[i]) { | |
135 | retval = update_ind_extent_range(handle, inode, | |
fba90ffe | 136 | le32_to_cpu(i_data[i]), lb); |
c14c6fd5 AK |
137 | if (retval) |
138 | break; | |
139 | } else { | |
140 | /* Only update the file block number */ | |
fba90ffe | 141 | lb->curr_block += max_entries; |
c14c6fd5 AK |
142 | } |
143 | } | |
c14c6fd5 AK |
144 | put_bh(bh); |
145 | return retval; | |
146 | ||
147 | } | |
148 | ||
149 | static int update_tind_extent_range(handle_t *handle, struct inode *inode, | |
fba90ffe DM |
150 | ext4_fsblk_t pblock, |
151 | struct migrate_struct *lb) | |
c14c6fd5 AK |
152 | { |
153 | struct buffer_head *bh; | |
154 | __le32 *i_data; | |
155 | int i, retval = 0; | |
c14c6fd5 AK |
156 | unsigned long max_entries = inode->i_sb->s_blocksize >> 2; |
157 | ||
fb265c9c TT |
158 | bh = ext4_sb_bread(inode->i_sb, pblock, 0); |
159 | if (IS_ERR(bh)) | |
160 | return PTR_ERR(bh); | |
c14c6fd5 AK |
161 | |
162 | i_data = (__le32 *)bh->b_data; | |
163 | for (i = 0; i < max_entries; i++) { | |
164 | if (i_data[i]) { | |
165 | retval = update_dind_extent_range(handle, inode, | |
fba90ffe | 166 | le32_to_cpu(i_data[i]), lb); |
c14c6fd5 AK |
167 | if (retval) |
168 | break; | |
fba90ffe | 169 | } else { |
c14c6fd5 | 170 | /* Only update the file block number */ |
fba90ffe DM |
171 | lb->curr_block += max_entries * max_entries; |
172 | } | |
c14c6fd5 | 173 | } |
c14c6fd5 AK |
174 | put_bh(bh); |
175 | return retval; | |
176 | ||
177 | } | |
178 | ||
179 | static int free_dind_blocks(handle_t *handle, | |
180 | struct inode *inode, __le32 i_data) | |
181 | { | |
182 | int i; | |
183 | __le32 *tmp_idata; | |
184 | struct buffer_head *bh; | |
83448bdf | 185 | struct super_block *sb = inode->i_sb; |
c14c6fd5 | 186 | unsigned long max_entries = inode->i_sb->s_blocksize >> 2; |
a4130367 | 187 | int err; |
c14c6fd5 | 188 | |
83448bdf | 189 | bh = ext4_sb_bread(sb, le32_to_cpu(i_data), 0); |
fb265c9c TT |
190 | if (IS_ERR(bh)) |
191 | return PTR_ERR(bh); | |
c14c6fd5 AK |
192 | |
193 | tmp_idata = (__le32 *)bh->b_data; | |
194 | for (i = 0; i < max_entries; i++) { | |
8009f9fb | 195 | if (tmp_idata[i]) { |
a4130367 | 196 | err = ext4_journal_ensure_credits(handle, |
83448bdf JK |
197 | EXT4_RESERVE_TRANS_BLOCKS, |
198 | ext4_free_metadata_revoke_credits(sb, 1)); | |
a4130367 JK |
199 | if (err < 0) { |
200 | put_bh(bh); | |
201 | return err; | |
202 | } | |
7dc57615 | 203 | ext4_free_blocks(handle, inode, NULL, |
e6362609 TT |
204 | le32_to_cpu(tmp_idata[i]), 1, |
205 | EXT4_FREE_BLOCKS_METADATA | | |
206 | EXT4_FREE_BLOCKS_FORGET); | |
8009f9fb | 207 | } |
c14c6fd5 AK |
208 | } |
209 | put_bh(bh); | |
83448bdf JK |
210 | err = ext4_journal_ensure_credits(handle, EXT4_RESERVE_TRANS_BLOCKS, |
211 | ext4_free_metadata_revoke_credits(sb, 1)); | |
a4130367 JK |
212 | if (err < 0) |
213 | return err; | |
7dc57615 | 214 | ext4_free_blocks(handle, inode, NULL, le32_to_cpu(i_data), 1, |
e6362609 TT |
215 | EXT4_FREE_BLOCKS_METADATA | |
216 | EXT4_FREE_BLOCKS_FORGET); | |
c14c6fd5 AK |
217 | return 0; |
218 | } | |
219 | ||
220 | static int free_tind_blocks(handle_t *handle, | |
221 | struct inode *inode, __le32 i_data) | |
222 | { | |
223 | int i, retval = 0; | |
224 | __le32 *tmp_idata; | |
225 | struct buffer_head *bh; | |
226 | unsigned long max_entries = inode->i_sb->s_blocksize >> 2; | |
227 | ||
fb265c9c TT |
228 | bh = ext4_sb_bread(inode->i_sb, le32_to_cpu(i_data), 0); |
229 | if (IS_ERR(bh)) | |
230 | return PTR_ERR(bh); | |
c14c6fd5 AK |
231 | |
232 | tmp_idata = (__le32 *)bh->b_data; | |
233 | for (i = 0; i < max_entries; i++) { | |
234 | if (tmp_idata[i]) { | |
235 | retval = free_dind_blocks(handle, | |
236 | inode, tmp_idata[i]); | |
237 | if (retval) { | |
238 | put_bh(bh); | |
239 | return retval; | |
240 | } | |
241 | } | |
242 | } | |
243 | put_bh(bh); | |
83448bdf JK |
244 | retval = ext4_journal_ensure_credits(handle, EXT4_RESERVE_TRANS_BLOCKS, |
245 | ext4_free_metadata_revoke_credits(inode->i_sb, 1)); | |
a4130367 JK |
246 | if (retval < 0) |
247 | return retval; | |
7dc57615 | 248 | ext4_free_blocks(handle, inode, NULL, le32_to_cpu(i_data), 1, |
e6362609 TT |
249 | EXT4_FREE_BLOCKS_METADATA | |
250 | EXT4_FREE_BLOCKS_FORGET); | |
c14c6fd5 AK |
251 | return 0; |
252 | } | |
253 | ||
8009f9fb | 254 | static int free_ind_block(handle_t *handle, struct inode *inode, __le32 *i_data) |
c14c6fd5 AK |
255 | { |
256 | int retval; | |
c14c6fd5 | 257 | |
8009f9fb AK |
258 | /* ei->i_data[EXT4_IND_BLOCK] */ |
259 | if (i_data[0]) { | |
a4130367 | 260 | retval = ext4_journal_ensure_credits(handle, |
83448bdf JK |
261 | EXT4_RESERVE_TRANS_BLOCKS, |
262 | ext4_free_metadata_revoke_credits(inode->i_sb, 1)); | |
a4130367 JK |
263 | if (retval < 0) |
264 | return retval; | |
7dc57615 | 265 | ext4_free_blocks(handle, inode, NULL, |
e6362609 TT |
266 | le32_to_cpu(i_data[0]), 1, |
267 | EXT4_FREE_BLOCKS_METADATA | | |
268 | EXT4_FREE_BLOCKS_FORGET); | |
8009f9fb | 269 | } |
c14c6fd5 | 270 | |
8009f9fb AK |
271 | /* ei->i_data[EXT4_DIND_BLOCK] */ |
272 | if (i_data[1]) { | |
273 | retval = free_dind_blocks(handle, inode, i_data[1]); | |
c14c6fd5 AK |
274 | if (retval) |
275 | return retval; | |
276 | } | |
277 | ||
8009f9fb AK |
278 | /* ei->i_data[EXT4_TIND_BLOCK] */ |
279 | if (i_data[2]) { | |
280 | retval = free_tind_blocks(handle, inode, i_data[2]); | |
c14c6fd5 AK |
281 | if (retval) |
282 | return retval; | |
283 | } | |
284 | return 0; | |
285 | } | |
286 | ||
287 | static int ext4_ext_swap_inode_data(handle_t *handle, struct inode *inode, | |
267e4db9 | 288 | struct inode *tmp_inode) |
c14c6fd5 | 289 | { |
8009f9fb AK |
290 | int retval; |
291 | __le32 i_data[3]; | |
c14c6fd5 AK |
292 | struct ext4_inode_info *ei = EXT4_I(inode); |
293 | struct ext4_inode_info *tmp_ei = EXT4_I(tmp_inode); | |
294 | ||
c14c6fd5 AK |
295 | /* |
296 | * One credit accounted for writing the | |
297 | * i_data field of the original inode | |
298 | */ | |
83448bdf | 299 | retval = ext4_journal_ensure_credits(handle, 1, 0); |
a4130367 JK |
300 | if (retval < 0) |
301 | goto err_out; | |
c14c6fd5 | 302 | |
8009f9fb AK |
303 | i_data[0] = ei->i_data[EXT4_IND_BLOCK]; |
304 | i_data[1] = ei->i_data[EXT4_DIND_BLOCK]; | |
305 | i_data[2] = ei->i_data[EXT4_TIND_BLOCK]; | |
306 | ||
307 | down_write(&EXT4_I(inode)->i_data_sem); | |
267e4db9 | 308 | /* |
1b9c12f4 | 309 | * if EXT4_STATE_EXT_MIGRATE is cleared a block allocation |
267e4db9 AK |
310 | * happened after we started the migrate. We need to |
311 | * fail the migrate | |
312 | */ | |
19f5fb7a | 313 | if (!ext4_test_inode_state(inode, EXT4_STATE_EXT_MIGRATE)) { |
267e4db9 AK |
314 | retval = -EAGAIN; |
315 | up_write(&EXT4_I(inode)->i_data_sem); | |
316 | goto err_out; | |
317 | } else | |
19f5fb7a | 318 | ext4_clear_inode_state(inode, EXT4_STATE_EXT_MIGRATE); |
c14c6fd5 AK |
319 | /* |
320 | * We have the extent map build with the tmp inode. | |
321 | * Now copy the i_data across | |
322 | */ | |
74e4e6db | 323 | ext4_set_inode_flag(inode, EXT4_INODE_EXTENTS); |
c14c6fd5 AK |
324 | memcpy(ei->i_data, tmp_ei->i_data, sizeof(ei->i_data)); |
325 | ||
326 | /* | |
327 | * Update i_blocks with the new blocks that got | |
328 | * allocated while adding extents for extent index | |
329 | * blocks. | |
330 | * | |
331 | * While converting to extents we need not | |
b8a07463 | 332 | * update the original inode i_blocks for extent blocks |
c14c6fd5 AK |
333 | * via quota APIs. The quota update happened via tmp_inode already. |
334 | */ | |
335 | spin_lock(&inode->i_lock); | |
336 | inode->i_blocks += tmp_inode->i_blocks; | |
337 | spin_unlock(&inode->i_lock); | |
8009f9fb | 338 | up_write(&EXT4_I(inode)->i_data_sem); |
c14c6fd5 | 339 | |
8009f9fb AK |
340 | /* |
341 | * We mark the inode dirty after, because we decrement the | |
342 | * i_blocks when freeing the indirect meta-data blocks | |
343 | */ | |
344 | retval = free_ind_block(handle, inode, i_data); | |
c14c6fd5 | 345 | ext4_mark_inode_dirty(handle, inode); |
8009f9fb | 346 | |
c14c6fd5 AK |
347 | err_out: |
348 | return retval; | |
349 | } | |
350 | ||
351 | static int free_ext_idx(handle_t *handle, struct inode *inode, | |
352 | struct ext4_extent_idx *ix) | |
353 | { | |
354 | int i, retval = 0; | |
355 | ext4_fsblk_t block; | |
356 | struct buffer_head *bh; | |
357 | struct ext4_extent_header *eh; | |
358 | ||
bf89d16f | 359 | block = ext4_idx_pblock(ix); |
fb265c9c TT |
360 | bh = ext4_sb_bread(inode->i_sb, block, 0); |
361 | if (IS_ERR(bh)) | |
362 | return PTR_ERR(bh); | |
c14c6fd5 AK |
363 | |
364 | eh = (struct ext4_extent_header *)bh->b_data; | |
365 | if (eh->eh_depth != 0) { | |
366 | ix = EXT_FIRST_INDEX(eh); | |
367 | for (i = 0; i < le16_to_cpu(eh->eh_entries); i++, ix++) { | |
368 | retval = free_ext_idx(handle, inode, ix); | |
a4130367 JK |
369 | if (retval) { |
370 | put_bh(bh); | |
371 | return retval; | |
372 | } | |
c14c6fd5 AK |
373 | } |
374 | } | |
375 | put_bh(bh); | |
83448bdf JK |
376 | retval = ext4_journal_ensure_credits(handle, EXT4_RESERVE_TRANS_BLOCKS, |
377 | ext4_free_metadata_revoke_credits(inode->i_sb, 1)); | |
a4130367 JK |
378 | if (retval < 0) |
379 | return retval; | |
7dc57615 | 380 | ext4_free_blocks(handle, inode, NULL, block, 1, |
e6362609 | 381 | EXT4_FREE_BLOCKS_METADATA | EXT4_FREE_BLOCKS_FORGET); |
a4130367 | 382 | return 0; |
c14c6fd5 AK |
383 | } |
384 | ||
385 | /* | |
386 | * Free the extent meta data blocks only | |
387 | */ | |
388 | static int free_ext_block(handle_t *handle, struct inode *inode) | |
389 | { | |
390 | int i, retval = 0; | |
391 | struct ext4_inode_info *ei = EXT4_I(inode); | |
392 | struct ext4_extent_header *eh = (struct ext4_extent_header *)ei->i_data; | |
393 | struct ext4_extent_idx *ix; | |
394 | if (eh->eh_depth == 0) | |
395 | /* | |
396 | * No extra blocks allocated for extent meta data | |
397 | */ | |
398 | return 0; | |
399 | ix = EXT_FIRST_INDEX(eh); | |
400 | for (i = 0; i < le16_to_cpu(eh->eh_entries); i++, ix++) { | |
401 | retval = free_ext_idx(handle, inode, ix); | |
402 | if (retval) | |
403 | return retval; | |
404 | } | |
405 | return retval; | |
c14c6fd5 AK |
406 | } |
407 | ||
2a43a878 | 408 | int ext4_ext_migrate(struct inode *inode) |
c14c6fd5 | 409 | { |
cb85f4d2 | 410 | struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); |
c14c6fd5 AK |
411 | handle_t *handle; |
412 | int retval = 0, i; | |
413 | __le32 *i_data; | |
c14c6fd5 AK |
414 | struct ext4_inode_info *ei; |
415 | struct inode *tmp_inode = NULL; | |
fba90ffe | 416 | struct migrate_struct lb; |
c14c6fd5 | 417 | unsigned long max_entries; |
11013911 | 418 | __u32 goal; |
5cb81dab | 419 | uid_t owner[2]; |
c14c6fd5 | 420 | |
83982b6f TT |
421 | /* |
422 | * If the filesystem does not support extents, or the inode | |
423 | * already is extent-based, error out. | |
424 | */ | |
e2b911c5 | 425 | if (!ext4_has_feature_extents(inode->i_sb) || |
12e9b892 | 426 | (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) |
c14c6fd5 AK |
427 | return -EINVAL; |
428 | ||
b8356c46 VC |
429 | if (S_ISLNK(inode->i_mode) && inode->i_blocks == 0) |
430 | /* | |
431 | * don't migrate fast symlink | |
432 | */ | |
433 | return retval; | |
434 | ||
cb85f4d2 EB |
435 | percpu_down_write(&sbi->s_writepages_rwsem); |
436 | ||
4b217630 TT |
437 | /* |
438 | * Worst case we can touch the allocation bitmaps, a bgd | |
439 | * block, and a block to link in the orphan list. We do need | |
440 | * need to worry about credits for modifying the quota inode. | |
441 | */ | |
9924a92a | 442 | handle = ext4_journal_start(inode, EXT4_HT_MIGRATE, |
4b217630 TT |
443 | 4 + EXT4_MAXQUOTAS_TRANS_BLOCKS(inode->i_sb)); |
444 | ||
c14c6fd5 AK |
445 | if (IS_ERR(handle)) { |
446 | retval = PTR_ERR(handle); | |
cb85f4d2 | 447 | goto out_unlock; |
c14c6fd5 | 448 | } |
11013911 AD |
449 | goal = (((inode->i_ino - 1) / EXT4_INODES_PER_GROUP(inode->i_sb)) * |
450 | EXT4_INODES_PER_GROUP(inode->i_sb)) + 1; | |
08cefc7a EB |
451 | owner[0] = i_uid_read(inode); |
452 | owner[1] = i_gid_read(inode); | |
2b0143b5 | 453 | tmp_inode = ext4_new_inode(handle, d_inode(inode->i_sb->s_root), |
1b917ed8 | 454 | S_IFREG, NULL, goal, owner, 0); |
c14c6fd5 | 455 | if (IS_ERR(tmp_inode)) { |
a0cc910f | 456 | retval = PTR_ERR(tmp_inode); |
c14c6fd5 | 457 | ext4_journal_stop(handle); |
cb85f4d2 | 458 | goto out_unlock; |
c14c6fd5 AK |
459 | } |
460 | i_size_write(tmp_inode, i_size_read(inode)); | |
461 | /* | |
f39490bc DM |
462 | * Set the i_nlink to zero so it will be deleted later |
463 | * when we drop inode reference. | |
c14c6fd5 | 464 | */ |
6d6b77f1 | 465 | clear_nlink(tmp_inode); |
c14c6fd5 AK |
466 | |
467 | ext4_ext_tree_init(handle, tmp_inode); | |
468 | ext4_orphan_add(handle, tmp_inode); | |
469 | ext4_journal_stop(handle); | |
470 | ||
c14c6fd5 AK |
471 | /* |
472 | * start with one credit accounted for | |
473 | * superblock modification. | |
474 | * | |
25985edc | 475 | * For the tmp_inode we already have committed the |
70261f56 | 476 | * transaction that created the inode. Later as and |
c14c6fd5 AK |
477 | * when we add extents we extent the journal |
478 | */ | |
267e4db9 | 479 | /* |
1b9c12f4 TT |
480 | * Even though we take i_mutex we can still cause block |
481 | * allocation via mmap write to holes. If we have allocated | |
482 | * new blocks we fail migrate. New block allocation will | |
483 | * clear EXT4_STATE_EXT_MIGRATE flag. The flag is updated | |
484 | * with i_data_sem held to prevent racing with block | |
485 | * allocation. | |
267e4db9 | 486 | */ |
c8b459f4 | 487 | down_read(&EXT4_I(inode)->i_data_sem); |
19f5fb7a | 488 | ext4_set_inode_state(inode, EXT4_STATE_EXT_MIGRATE); |
267e4db9 AK |
489 | up_read((&EXT4_I(inode)->i_data_sem)); |
490 | ||
9924a92a | 491 | handle = ext4_journal_start(inode, EXT4_HT_MIGRATE, 1); |
f39490bc DM |
492 | if (IS_ERR(handle)) { |
493 | /* | |
494 | * It is impossible to update on-disk structures without | |
495 | * a handle, so just rollback in-core changes and live other | |
496 | * work to orphan_list_cleanup() | |
497 | */ | |
498 | ext4_orphan_del(NULL, tmp_inode); | |
499 | retval = PTR_ERR(handle); | |
cb85f4d2 | 500 | goto out_tmp_inode; |
f39490bc | 501 | } |
8009f9fb AK |
502 | |
503 | ei = EXT4_I(inode); | |
504 | i_data = ei->i_data; | |
505 | memset(&lb, 0, sizeof(lb)); | |
506 | ||
507 | /* 32 bit block address 4 bytes */ | |
508 | max_entries = inode->i_sb->s_blocksize >> 2; | |
fba90ffe | 509 | for (i = 0; i < EXT4_NDIR_BLOCKS; i++) { |
c14c6fd5 AK |
510 | if (i_data[i]) { |
511 | retval = update_extent_range(handle, tmp_inode, | |
fba90ffe | 512 | le32_to_cpu(i_data[i]), &lb); |
c14c6fd5 AK |
513 | if (retval) |
514 | goto err_out; | |
fba90ffe DM |
515 | } else |
516 | lb.curr_block++; | |
c14c6fd5 AK |
517 | } |
518 | if (i_data[EXT4_IND_BLOCK]) { | |
519 | retval = update_ind_extent_range(handle, tmp_inode, | |
fba90ffe | 520 | le32_to_cpu(i_data[EXT4_IND_BLOCK]), &lb); |
a92abd73 CIK |
521 | if (retval) |
522 | goto err_out; | |
c14c6fd5 | 523 | } else |
fba90ffe | 524 | lb.curr_block += max_entries; |
c14c6fd5 AK |
525 | if (i_data[EXT4_DIND_BLOCK]) { |
526 | retval = update_dind_extent_range(handle, tmp_inode, | |
fba90ffe | 527 | le32_to_cpu(i_data[EXT4_DIND_BLOCK]), &lb); |
a92abd73 CIK |
528 | if (retval) |
529 | goto err_out; | |
c14c6fd5 | 530 | } else |
fba90ffe | 531 | lb.curr_block += max_entries * max_entries; |
c14c6fd5 AK |
532 | if (i_data[EXT4_TIND_BLOCK]) { |
533 | retval = update_tind_extent_range(handle, tmp_inode, | |
fba90ffe | 534 | le32_to_cpu(i_data[EXT4_TIND_BLOCK]), &lb); |
a92abd73 CIK |
535 | if (retval) |
536 | goto err_out; | |
c14c6fd5 AK |
537 | } |
538 | /* | |
539 | * Build the last extent | |
540 | */ | |
541 | retval = finish_range(handle, tmp_inode, &lb); | |
542 | err_out: | |
c14c6fd5 AK |
543 | if (retval) |
544 | /* | |
545 | * Failure case delete the extent information with the | |
546 | * tmp_inode | |
547 | */ | |
548 | free_ext_block(handle, tmp_inode); | |
267e4db9 AK |
549 | else { |
550 | retval = ext4_ext_swap_inode_data(handle, inode, tmp_inode); | |
551 | if (retval) | |
552 | /* | |
553 | * if we fail to swap inode data free the extent | |
554 | * details of the tmp inode | |
555 | */ | |
556 | free_ext_block(handle, tmp_inode); | |
557 | } | |
8009f9fb AK |
558 | |
559 | /* We mark the tmp_inode dirty via ext4_ext_tree_init. */ | |
83448bdf | 560 | retval = ext4_journal_ensure_credits(handle, 1, 0); |
a4130367 JK |
561 | if (retval < 0) |
562 | goto out_stop; | |
c14c6fd5 AK |
563 | /* |
564 | * Mark the tmp_inode as of size zero | |
565 | */ | |
566 | i_size_write(tmp_inode, 0); | |
567 | ||
568 | /* | |
569 | * set the i_blocks count to zero | |
58d86a50 | 570 | * so that the ext4_evict_inode() does the |
c14c6fd5 AK |
571 | * right job |
572 | * | |
573 | * We don't need to take the i_lock because | |
574 | * the inode is not visible to user space. | |
575 | */ | |
576 | tmp_inode->i_blocks = 0; | |
577 | ||
578 | /* Reset the extent details */ | |
579 | ext4_ext_tree_init(handle, tmp_inode); | |
a4130367 | 580 | out_stop: |
c14c6fd5 | 581 | ext4_journal_stop(handle); |
cb85f4d2 | 582 | out_tmp_inode: |
a8526e84 | 583 | unlock_new_inode(tmp_inode); |
09054264 | 584 | iput(tmp_inode); |
cb85f4d2 EB |
585 | out_unlock: |
586 | percpu_up_write(&sbi->s_writepages_rwsem); | |
c14c6fd5 AK |
587 | return retval; |
588 | } | |
0d14b098 LC |
589 | |
590 | /* | |
591 | * Migrate a simple extent-based inode to use the i_blocks[] array | |
592 | */ | |
593 | int ext4_ind_migrate(struct inode *inode) | |
594 | { | |
595 | struct ext4_extent_header *eh; | |
cb85f4d2 EB |
596 | struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); |
597 | struct ext4_super_block *es = sbi->s_es; | |
0d14b098 LC |
598 | struct ext4_inode_info *ei = EXT4_I(inode); |
599 | struct ext4_extent *ex; | |
600 | unsigned int i, len; | |
8974fec7 | 601 | ext4_lblk_t start, end; |
0d14b098 LC |
602 | ext4_fsblk_t blk; |
603 | handle_t *handle; | |
604 | int ret; | |
605 | ||
e2b911c5 | 606 | if (!ext4_has_feature_extents(inode->i_sb) || |
0d14b098 LC |
607 | (!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) |
608 | return -EINVAL; | |
609 | ||
e2b911c5 | 610 | if (ext4_has_feature_bigalloc(inode->i_sb)) |
43e50f50 LC |
611 | return -EOPNOTSUPP; |
612 | ||
d6f123a9 EG |
613 | /* |
614 | * In order to get correct extent info, force all delayed allocation | |
615 | * blocks to be allocated, otherwise delayed allocation blocks may not | |
616 | * be reflected and bypass the checks on extent header. | |
617 | */ | |
618 | if (test_opt(inode->i_sb, DELALLOC)) | |
619 | ext4_alloc_da_blocks(inode); | |
620 | ||
cb85f4d2 EB |
621 | percpu_down_write(&sbi->s_writepages_rwsem); |
622 | ||
0d14b098 | 623 | handle = ext4_journal_start(inode, EXT4_HT_MIGRATE, 1); |
cb85f4d2 EB |
624 | if (IS_ERR(handle)) { |
625 | ret = PTR_ERR(handle); | |
626 | goto out_unlock; | |
627 | } | |
0d14b098 LC |
628 | |
629 | down_write(&EXT4_I(inode)->i_data_sem); | |
630 | ret = ext4_ext_check_inode(inode); | |
631 | if (ret) | |
632 | goto errout; | |
633 | ||
634 | eh = ext_inode_hdr(inode); | |
635 | ex = EXT_FIRST_EXTENT(eh); | |
636 | if (ext4_blocks_count(es) > EXT4_MAX_BLOCK_FILE_PHYS || | |
637 | eh->eh_depth != 0 || le16_to_cpu(eh->eh_entries) > 1) { | |
638 | ret = -EOPNOTSUPP; | |
639 | goto errout; | |
640 | } | |
641 | if (eh->eh_entries == 0) | |
8974fec7 | 642 | blk = len = start = end = 0; |
0d14b098 LC |
643 | else { |
644 | len = le16_to_cpu(ex->ee_len); | |
645 | blk = ext4_ext_pblock(ex); | |
8974fec7 EG |
646 | start = le32_to_cpu(ex->ee_block); |
647 | end = start + len - 1; | |
d6f123a9 | 648 | if (end >= EXT4_NDIR_BLOCKS) { |
0d14b098 LC |
649 | ret = -EOPNOTSUPP; |
650 | goto errout; | |
651 | } | |
652 | } | |
653 | ||
654 | ext4_clear_inode_flag(inode, EXT4_INODE_EXTENTS); | |
655 | memset(ei->i_data, 0, sizeof(ei->i_data)); | |
8974fec7 | 656 | for (i = start; i <= end; i++) |
0d14b098 LC |
657 | ei->i_data[i] = cpu_to_le32(blk++); |
658 | ext4_mark_inode_dirty(handle, inode); | |
659 | errout: | |
660 | ext4_journal_stop(handle); | |
661 | up_write(&EXT4_I(inode)->i_data_sem); | |
cb85f4d2 EB |
662 | out_unlock: |
663 | percpu_up_write(&sbi->s_writepages_rwsem); | |
0d14b098 LC |
664 | return ret; |
665 | } |