.. | .. |
---|
32 | 32 | newext.ee_block = cpu_to_le32(lb->first_block); |
---|
33 | 33 | newext.ee_len = cpu_to_le16(lb->last_block - lb->first_block + 1); |
---|
34 | 34 | 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 */ |
---|
36 | 36 | down_write(&EXT4_I(inode)->i_data_sem); |
---|
37 | 37 | path = ext4_find_extent(inode, lb->first_block, NULL, 0); |
---|
38 | 38 | if (IS_ERR(path)) { |
---|
.. | .. |
---|
43 | 43 | |
---|
44 | 44 | /* |
---|
45 | 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 |
---|
| 46 | + * Since we are doing this in loop we may accumulate extra |
---|
| 47 | + * credit. But below we try to not accumulate too much |
---|
48 | 48 | * of them by restarting the journal. |
---|
49 | 49 | */ |
---|
50 | 50 | needed = ext4_ext_calc_credits_for_single_extent(inode, |
---|
51 | 51 | lb->last_block - lb->first_block + 1, path); |
---|
52 | 52 | |
---|
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; |
---|
76 | 56 | retval = ext4_ext_insert_extent(handle, inode, &path, &newext, 0); |
---|
77 | 57 | err_out: |
---|
78 | 58 | up_write((&EXT4_I(inode)->i_data_sem)); |
---|
.. | .. |
---|
196 | 176 | |
---|
197 | 177 | } |
---|
198 | 178 | |
---|
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 | | - |
---|
219 | 179 | static int free_dind_blocks(handle_t *handle, |
---|
220 | 180 | struct inode *inode, __le32 i_data) |
---|
221 | 181 | { |
---|
222 | 182 | int i; |
---|
223 | 183 | __le32 *tmp_idata; |
---|
224 | 184 | struct buffer_head *bh; |
---|
| 185 | + struct super_block *sb = inode->i_sb; |
---|
225 | 186 | unsigned long max_entries = inode->i_sb->s_blocksize >> 2; |
---|
| 187 | + int err; |
---|
226 | 188 | |
---|
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); |
---|
228 | 190 | if (IS_ERR(bh)) |
---|
229 | 191 | return PTR_ERR(bh); |
---|
230 | 192 | |
---|
231 | 193 | tmp_idata = (__le32 *)bh->b_data; |
---|
232 | 194 | for (i = 0; i < max_entries; i++) { |
---|
233 | 195 | 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 | + } |
---|
235 | 203 | ext4_free_blocks(handle, inode, NULL, |
---|
236 | 204 | le32_to_cpu(tmp_idata[i]), 1, |
---|
237 | 205 | EXT4_FREE_BLOCKS_METADATA | |
---|
.. | .. |
---|
239 | 207 | } |
---|
240 | 208 | } |
---|
241 | 209 | 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; |
---|
243 | 214 | ext4_free_blocks(handle, inode, NULL, le32_to_cpu(i_data), 1, |
---|
244 | 215 | EXT4_FREE_BLOCKS_METADATA | |
---|
245 | 216 | EXT4_FREE_BLOCKS_FORGET); |
---|
.. | .. |
---|
270 | 241 | } |
---|
271 | 242 | } |
---|
272 | 243 | 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; |
---|
274 | 248 | ext4_free_blocks(handle, inode, NULL, le32_to_cpu(i_data), 1, |
---|
275 | 249 | EXT4_FREE_BLOCKS_METADATA | |
---|
276 | 250 | EXT4_FREE_BLOCKS_FORGET); |
---|
.. | .. |
---|
283 | 257 | |
---|
284 | 258 | /* ei->i_data[EXT4_IND_BLOCK] */ |
---|
285 | 259 | 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; |
---|
287 | 265 | ext4_free_blocks(handle, inode, NULL, |
---|
288 | 266 | le32_to_cpu(i_data[0]), 1, |
---|
289 | 267 | EXT4_FREE_BLOCKS_METADATA | |
---|
.. | .. |
---|
309 | 287 | static int ext4_ext_swap_inode_data(handle_t *handle, struct inode *inode, |
---|
310 | 288 | struct inode *tmp_inode) |
---|
311 | 289 | { |
---|
312 | | - int retval; |
---|
| 290 | + int retval, retval2 = 0; |
---|
313 | 291 | __le32 i_data[3]; |
---|
314 | 292 | struct ext4_inode_info *ei = EXT4_I(inode); |
---|
315 | 293 | struct ext4_inode_info *tmp_ei = EXT4_I(tmp_inode); |
---|
.. | .. |
---|
318 | 296 | * One credit accounted for writing the |
---|
319 | 297 | * i_data field of the original inode |
---|
320 | 298 | */ |
---|
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; |
---|
327 | 302 | |
---|
328 | 303 | i_data[0] = ei->i_data[EXT4_IND_BLOCK]; |
---|
329 | 304 | i_data[1] = ei->i_data[EXT4_DIND_BLOCK]; |
---|
.. | .. |
---|
367 | 342 | * i_blocks when freeing the indirect meta-data blocks |
---|
368 | 343 | */ |
---|
369 | 344 | 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; |
---|
371 | 348 | |
---|
372 | 349 | err_out: |
---|
373 | 350 | return retval; |
---|
.. | .. |
---|
391 | 368 | ix = EXT_FIRST_INDEX(eh); |
---|
392 | 369 | for (i = 0; i < le16_to_cpu(eh->eh_entries); i++, ix++) { |
---|
393 | 370 | retval = free_ext_idx(handle, inode, ix); |
---|
394 | | - if (retval) |
---|
395 | | - break; |
---|
| 371 | + if (retval) { |
---|
| 372 | + put_bh(bh); |
---|
| 373 | + return retval; |
---|
| 374 | + } |
---|
396 | 375 | } |
---|
397 | 376 | } |
---|
398 | 377 | 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; |
---|
400 | 382 | ext4_free_blocks(handle, inode, NULL, block, 1, |
---|
401 | 383 | EXT4_FREE_BLOCKS_METADATA | EXT4_FREE_BLOCKS_FORGET); |
---|
402 | | - return retval; |
---|
| 384 | + return 0; |
---|
403 | 385 | } |
---|
404 | 386 | |
---|
405 | 387 | /* |
---|
.. | .. |
---|
435 | 417 | struct inode *tmp_inode = NULL; |
---|
436 | 418 | struct migrate_struct lb; |
---|
437 | 419 | unsigned long max_entries; |
---|
438 | | - __u32 goal; |
---|
| 420 | + __u32 goal, tmp_csum_seed; |
---|
439 | 421 | uid_t owner[2]; |
---|
440 | 422 | |
---|
441 | 423 | /* |
---|
.. | .. |
---|
443 | 425 | * already is extent-based, error out. |
---|
444 | 426 | */ |
---|
445 | 427 | 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)) |
---|
447 | 430 | return -EINVAL; |
---|
448 | 431 | |
---|
449 | 432 | if (S_ISLNK(inode->i_mode) && inode->i_blocks == 0) |
---|
.. | .. |
---|
483 | 466 | * the migration. |
---|
484 | 467 | */ |
---|
485 | 468 | ei = EXT4_I(inode); |
---|
| 469 | + tmp_csum_seed = EXT4_I(tmp_inode)->i_csum_seed; |
---|
486 | 470 | EXT4_I(tmp_inode)->i_csum_seed = ei->i_csum_seed; |
---|
487 | 471 | i_size_write(tmp_inode, i_size_read(inode)); |
---|
488 | 472 | /* |
---|
.. | .. |
---|
537 | 521 | if (i_data[EXT4_IND_BLOCK]) { |
---|
538 | 522 | retval = update_ind_extent_range(handle, tmp_inode, |
---|
539 | 523 | le32_to_cpu(i_data[EXT4_IND_BLOCK]), &lb); |
---|
540 | | - if (retval) |
---|
541 | | - goto err_out; |
---|
| 524 | + if (retval) |
---|
| 525 | + goto err_out; |
---|
542 | 526 | } else |
---|
543 | 527 | lb.curr_block += max_entries; |
---|
544 | 528 | if (i_data[EXT4_DIND_BLOCK]) { |
---|
545 | 529 | retval = update_dind_extent_range(handle, tmp_inode, |
---|
546 | 530 | le32_to_cpu(i_data[EXT4_DIND_BLOCK]), &lb); |
---|
547 | | - if (retval) |
---|
548 | | - goto err_out; |
---|
| 531 | + if (retval) |
---|
| 532 | + goto err_out; |
---|
549 | 533 | } else |
---|
550 | 534 | lb.curr_block += max_entries * max_entries; |
---|
551 | 535 | if (i_data[EXT4_TIND_BLOCK]) { |
---|
552 | 536 | retval = update_tind_extent_range(handle, tmp_inode, |
---|
553 | 537 | le32_to_cpu(i_data[EXT4_TIND_BLOCK]), &lb); |
---|
554 | | - if (retval) |
---|
555 | | - goto err_out; |
---|
| 538 | + if (retval) |
---|
| 539 | + goto err_out; |
---|
556 | 540 | } |
---|
557 | 541 | /* |
---|
558 | 542 | * Build the last extent |
---|
.. | .. |
---|
576 | 560 | } |
---|
577 | 561 | |
---|
578 | 562 | /* 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; |
---|
582 | 566 | /* |
---|
583 | 567 | * Mark the tmp_inode as of size zero |
---|
584 | 568 | */ |
---|
.. | .. |
---|
593 | 577 | * the inode is not visible to user space. |
---|
594 | 578 | */ |
---|
595 | 579 | tmp_inode->i_blocks = 0; |
---|
| 580 | + EXT4_I(tmp_inode)->i_csum_seed = tmp_csum_seed; |
---|
596 | 581 | |
---|
597 | 582 | /* Reset the extent details */ |
---|
598 | 583 | ext4_ext_tree_init(handle, tmp_inode); |
---|
| 584 | +out_stop: |
---|
599 | 585 | ext4_journal_stop(handle); |
---|
600 | 586 | out_tmp_inode: |
---|
601 | 587 | unlock_new_inode(tmp_inode); |
---|
.. | .. |
---|
619 | 605 | ext4_lblk_t start, end; |
---|
620 | 606 | ext4_fsblk_t blk; |
---|
621 | 607 | handle_t *handle; |
---|
622 | | - int ret; |
---|
| 608 | + int ret, ret2 = 0; |
---|
623 | 609 | |
---|
624 | 610 | if (!ext4_has_feature_extents(inode->i_sb) || |
---|
625 | 611 | (!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) |
---|
.. | .. |
---|
673 | 659 | memset(ei->i_data, 0, sizeof(ei->i_data)); |
---|
674 | 660 | for (i = start; i <= end; i++) |
---|
675 | 661 | 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; |
---|
677 | 665 | errout: |
---|
678 | 666 | ext4_journal_stop(handle); |
---|
679 | 667 | up_write(&EXT4_I(inode)->i_data_sem); |
---|