hc
2024-05-10 23fa18eaa71266feff7ba8d83022d9e1cc83c65a
kernel/fs/ext4/migrate.c
....@@ -32,7 +32,7 @@
3232 newext.ee_block = cpu_to_le32(lb->first_block);
3333 newext.ee_len = cpu_to_le16(lb->last_block - lb->first_block + 1);
3434 ext4_ext_store_pblock(&newext, lb->first_pblock);
35
- /* Locking only for convinience since we are operating on temp inode */
35
+ /* Locking only for convenience since we are operating on temp inode */
3636 down_write(&EXT4_I(inode)->i_data_sem);
3737 path = ext4_find_extent(inode, lb->first_block, NULL, 0);
3838 if (IS_ERR(path)) {
....@@ -43,36 +43,16 @@
4343
4444 /*
4545 * 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
46
+ * Since we are doing this in loop we may accumulate extra
47
+ * credit. But below we try to not accumulate too much
4848 * of them by restarting the journal.
4949 */
5050 needed = ext4_ext_calc_credits_for_single_extent(inode,
5151 lb->last_block - lb->first_block + 1, path);
5252
53
- /*
54
- * Make sure the credit we accumalated is not really high
55
- */
56
- if (needed && ext4_handle_has_enough_credits(handle,
57
- EXT4_RESERVE_TRANS_BLOCKS)) {
58
- up_write((&EXT4_I(inode)->i_data_sem));
59
- retval = ext4_journal_restart(handle, needed);
60
- down_write((&EXT4_I(inode)->i_data_sem));
61
- if (retval)
62
- goto err_out;
63
- } else if (needed) {
64
- retval = ext4_journal_extend(handle, needed);
65
- if (retval) {
66
- /*
67
- * IF not able to extend the journal restart the journal
68
- */
69
- up_write((&EXT4_I(inode)->i_data_sem));
70
- retval = ext4_journal_restart(handle, needed);
71
- down_write((&EXT4_I(inode)->i_data_sem));
72
- if (retval)
73
- goto err_out;
74
- }
75
- }
53
+ retval = ext4_datasem_ensure_credits(handle, inode, needed, needed, 0);
54
+ if (retval < 0)
55
+ goto err_out;
7656 retval = ext4_ext_insert_extent(handle, inode, &path, &newext, 0);
7757 err_out:
7858 up_write((&EXT4_I(inode)->i_data_sem));
....@@ -196,42 +176,30 @@
196176
197177 }
198178
199
-static int extend_credit_for_blkdel(handle_t *handle, struct inode *inode)
200
-{
201
- int retval = 0, needed;
202
-
203
- if (ext4_handle_has_enough_credits(handle, EXT4_RESERVE_TRANS_BLOCKS+1))
204
- return 0;
205
- /*
206
- * We are freeing a blocks. During this we touch
207
- * superblock, group descriptor and block bitmap.
208
- * So allocate a credit of 3. We may update
209
- * quota (user and group).
210
- */
211
- needed = 3 + EXT4_MAXQUOTAS_TRANS_BLOCKS(inode->i_sb);
212
-
213
- if (ext4_journal_extend(handle, needed) != 0)
214
- retval = ext4_journal_restart(handle, needed);
215
-
216
- return retval;
217
-}
218
-
219179 static int free_dind_blocks(handle_t *handle,
220180 struct inode *inode, __le32 i_data)
221181 {
222182 int i;
223183 __le32 *tmp_idata;
224184 struct buffer_head *bh;
185
+ struct super_block *sb = inode->i_sb;
225186 unsigned long max_entries = inode->i_sb->s_blocksize >> 2;
187
+ int err;
226188
227
- bh = ext4_sb_bread(inode->i_sb, le32_to_cpu(i_data), 0);
189
+ bh = ext4_sb_bread(sb, le32_to_cpu(i_data), 0);
228190 if (IS_ERR(bh))
229191 return PTR_ERR(bh);
230192
231193 tmp_idata = (__le32 *)bh->b_data;
232194 for (i = 0; i < max_entries; i++) {
233195 if (tmp_idata[i]) {
234
- extend_credit_for_blkdel(handle, inode);
196
+ err = ext4_journal_ensure_credits(handle,
197
+ EXT4_RESERVE_TRANS_BLOCKS,
198
+ ext4_free_metadata_revoke_credits(sb, 1));
199
+ if (err < 0) {
200
+ put_bh(bh);
201
+ return err;
202
+ }
235203 ext4_free_blocks(handle, inode, NULL,
236204 le32_to_cpu(tmp_idata[i]), 1,
237205 EXT4_FREE_BLOCKS_METADATA |
....@@ -239,7 +207,10 @@
239207 }
240208 }
241209 put_bh(bh);
242
- extend_credit_for_blkdel(handle, inode);
210
+ err = ext4_journal_ensure_credits(handle, EXT4_RESERVE_TRANS_BLOCKS,
211
+ ext4_free_metadata_revoke_credits(sb, 1));
212
+ if (err < 0)
213
+ return err;
243214 ext4_free_blocks(handle, inode, NULL, le32_to_cpu(i_data), 1,
244215 EXT4_FREE_BLOCKS_METADATA |
245216 EXT4_FREE_BLOCKS_FORGET);
....@@ -270,7 +241,10 @@
270241 }
271242 }
272243 put_bh(bh);
273
- extend_credit_for_blkdel(handle, inode);
244
+ retval = ext4_journal_ensure_credits(handle, EXT4_RESERVE_TRANS_BLOCKS,
245
+ ext4_free_metadata_revoke_credits(inode->i_sb, 1));
246
+ if (retval < 0)
247
+ return retval;
274248 ext4_free_blocks(handle, inode, NULL, le32_to_cpu(i_data), 1,
275249 EXT4_FREE_BLOCKS_METADATA |
276250 EXT4_FREE_BLOCKS_FORGET);
....@@ -283,7 +257,11 @@
283257
284258 /* ei->i_data[EXT4_IND_BLOCK] */
285259 if (i_data[0]) {
286
- extend_credit_for_blkdel(handle, inode);
260
+ retval = ext4_journal_ensure_credits(handle,
261
+ EXT4_RESERVE_TRANS_BLOCKS,
262
+ ext4_free_metadata_revoke_credits(inode->i_sb, 1));
263
+ if (retval < 0)
264
+ return retval;
287265 ext4_free_blocks(handle, inode, NULL,
288266 le32_to_cpu(i_data[0]), 1,
289267 EXT4_FREE_BLOCKS_METADATA |
....@@ -309,7 +287,7 @@
309287 static int ext4_ext_swap_inode_data(handle_t *handle, struct inode *inode,
310288 struct inode *tmp_inode)
311289 {
312
- int retval;
290
+ int retval, retval2 = 0;
313291 __le32 i_data[3];
314292 struct ext4_inode_info *ei = EXT4_I(inode);
315293 struct ext4_inode_info *tmp_ei = EXT4_I(tmp_inode);
....@@ -318,12 +296,9 @@
318296 * One credit accounted for writing the
319297 * i_data field of the original inode
320298 */
321
- retval = ext4_journal_extend(handle, 1);
322
- if (retval) {
323
- retval = ext4_journal_restart(handle, 1);
324
- if (retval)
325
- goto err_out;
326
- }
299
+ retval = ext4_journal_ensure_credits(handle, 1, 0);
300
+ if (retval < 0)
301
+ goto err_out;
327302
328303 i_data[0] = ei->i_data[EXT4_IND_BLOCK];
329304 i_data[1] = ei->i_data[EXT4_DIND_BLOCK];
....@@ -367,7 +342,9 @@
367342 * i_blocks when freeing the indirect meta-data blocks
368343 */
369344 retval = free_ind_block(handle, inode, i_data);
370
- ext4_mark_inode_dirty(handle, inode);
345
+ retval2 = ext4_mark_inode_dirty(handle, inode);
346
+ if (unlikely(retval2 && !retval))
347
+ retval = retval2;
371348
372349 err_out:
373350 return retval;
....@@ -391,15 +368,20 @@
391368 ix = EXT_FIRST_INDEX(eh);
392369 for (i = 0; i < le16_to_cpu(eh->eh_entries); i++, ix++) {
393370 retval = free_ext_idx(handle, inode, ix);
394
- if (retval)
395
- break;
371
+ if (retval) {
372
+ put_bh(bh);
373
+ return retval;
374
+ }
396375 }
397376 }
398377 put_bh(bh);
399
- extend_credit_for_blkdel(handle, inode);
378
+ retval = ext4_journal_ensure_credits(handle, EXT4_RESERVE_TRANS_BLOCKS,
379
+ ext4_free_metadata_revoke_credits(inode->i_sb, 1));
380
+ if (retval < 0)
381
+ return retval;
400382 ext4_free_blocks(handle, inode, NULL, block, 1,
401383 EXT4_FREE_BLOCKS_METADATA | EXT4_FREE_BLOCKS_FORGET);
402
- return retval;
384
+ return 0;
403385 }
404386
405387 /*
....@@ -435,7 +417,7 @@
435417 struct inode *tmp_inode = NULL;
436418 struct migrate_struct lb;
437419 unsigned long max_entries;
438
- __u32 goal;
420
+ __u32 goal, tmp_csum_seed;
439421 uid_t owner[2];
440422
441423 /*
....@@ -443,7 +425,8 @@
443425 * already is extent-based, error out.
444426 */
445427 if (!ext4_has_feature_extents(inode->i_sb) ||
446
- (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
428
+ ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS) ||
429
+ ext4_has_inline_data(inode))
447430 return -EINVAL;
448431
449432 if (S_ISLNK(inode->i_mode) && inode->i_blocks == 0)
....@@ -483,6 +466,7 @@
483466 * the migration.
484467 */
485468 ei = EXT4_I(inode);
469
+ tmp_csum_seed = EXT4_I(tmp_inode)->i_csum_seed;
486470 EXT4_I(tmp_inode)->i_csum_seed = ei->i_csum_seed;
487471 i_size_write(tmp_inode, i_size_read(inode));
488472 /*
....@@ -537,22 +521,22 @@
537521 if (i_data[EXT4_IND_BLOCK]) {
538522 retval = update_ind_extent_range(handle, tmp_inode,
539523 le32_to_cpu(i_data[EXT4_IND_BLOCK]), &lb);
540
- if (retval)
541
- goto err_out;
524
+ if (retval)
525
+ goto err_out;
542526 } else
543527 lb.curr_block += max_entries;
544528 if (i_data[EXT4_DIND_BLOCK]) {
545529 retval = update_dind_extent_range(handle, tmp_inode,
546530 le32_to_cpu(i_data[EXT4_DIND_BLOCK]), &lb);
547
- if (retval)
548
- goto err_out;
531
+ if (retval)
532
+ goto err_out;
549533 } else
550534 lb.curr_block += max_entries * max_entries;
551535 if (i_data[EXT4_TIND_BLOCK]) {
552536 retval = update_tind_extent_range(handle, tmp_inode,
553537 le32_to_cpu(i_data[EXT4_TIND_BLOCK]), &lb);
554
- if (retval)
555
- goto err_out;
538
+ if (retval)
539
+ goto err_out;
556540 }
557541 /*
558542 * Build the last extent
....@@ -576,9 +560,9 @@
576560 }
577561
578562 /* We mark the tmp_inode dirty via ext4_ext_tree_init. */
579
- if (ext4_journal_extend(handle, 1) != 0)
580
- ext4_journal_restart(handle, 1);
581
-
563
+ retval = ext4_journal_ensure_credits(handle, 1, 0);
564
+ if (retval < 0)
565
+ goto out_stop;
582566 /*
583567 * Mark the tmp_inode as of size zero
584568 */
....@@ -593,9 +577,11 @@
593577 * the inode is not visible to user space.
594578 */
595579 tmp_inode->i_blocks = 0;
580
+ EXT4_I(tmp_inode)->i_csum_seed = tmp_csum_seed;
596581
597582 /* Reset the extent details */
598583 ext4_ext_tree_init(handle, tmp_inode);
584
+out_stop:
599585 ext4_journal_stop(handle);
600586 out_tmp_inode:
601587 unlock_new_inode(tmp_inode);
....@@ -619,7 +605,7 @@
619605 ext4_lblk_t start, end;
620606 ext4_fsblk_t blk;
621607 handle_t *handle;
622
- int ret;
608
+ int ret, ret2 = 0;
623609
624610 if (!ext4_has_feature_extents(inode->i_sb) ||
625611 (!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
....@@ -673,7 +659,9 @@
673659 memset(ei->i_data, 0, sizeof(ei->i_data));
674660 for (i = start; i <= end; i++)
675661 ei->i_data[i] = cpu_to_le32(blk++);
676
- ext4_mark_inode_dirty(handle, inode);
662
+ ret2 = ext4_mark_inode_dirty(handle, inode);
663
+ if (unlikely(ret2 && !ret))
664
+ ret = ret2;
677665 errout:
678666 ext4_journal_stop(handle);
679667 up_write(&EXT4_I(inode)->i_data_sem);