diff options
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/ext4.h | 2 | ||||
-rw-r--r-- | fs/ext4/inode.c | 27 | ||||
-rw-r--r-- | fs/ext4/mballoc.c | 32 | ||||
-rw-r--r-- | fs/ext4/migrate.c | 8 | ||||
-rw-r--r-- | fs/ext4/super.c | 11 |
5 files changed, 53 insertions, 27 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index aafc9eba1c25..b0c87dce66a3 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
@@ -868,7 +868,7 @@ static inline unsigned ext4_rec_len_from_disk(__le16 dlen) | |||
868 | { | 868 | { |
869 | unsigned len = le16_to_cpu(dlen); | 869 | unsigned len = le16_to_cpu(dlen); |
870 | 870 | ||
871 | if (len == EXT4_MAX_REC_LEN) | 871 | if (len == EXT4_MAX_REC_LEN || len == 0) |
872 | return 1 << 16; | 872 | return 1 << 16; |
873 | return len; | 873 | return len; |
874 | } | 874 | } |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 03ba20be1329..cbd2ca99d113 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -47,8 +47,10 @@ | |||
47 | static inline int ext4_begin_ordered_truncate(struct inode *inode, | 47 | static inline int ext4_begin_ordered_truncate(struct inode *inode, |
48 | loff_t new_size) | 48 | loff_t new_size) |
49 | { | 49 | { |
50 | return jbd2_journal_begin_ordered_truncate(&EXT4_I(inode)->jinode, | 50 | return jbd2_journal_begin_ordered_truncate( |
51 | new_size); | 51 | EXT4_SB(inode->i_sb)->s_journal, |
52 | &EXT4_I(inode)->jinode, | ||
53 | new_size); | ||
52 | } | 54 | } |
53 | 55 | ||
54 | static void ext4_invalidatepage(struct page *page, unsigned long offset); | 56 | static void ext4_invalidatepage(struct page *page, unsigned long offset); |
@@ -2437,6 +2439,7 @@ static int ext4_da_writepages(struct address_space *mapping, | |||
2437 | int no_nrwrite_index_update; | 2439 | int no_nrwrite_index_update; |
2438 | int pages_written = 0; | 2440 | int pages_written = 0; |
2439 | long pages_skipped; | 2441 | long pages_skipped; |
2442 | int range_cyclic, cycled = 1, io_done = 0; | ||
2440 | int needed_blocks, ret = 0, nr_to_writebump = 0; | 2443 | int needed_blocks, ret = 0, nr_to_writebump = 0; |
2441 | struct ext4_sb_info *sbi = EXT4_SB(mapping->host->i_sb); | 2444 | struct ext4_sb_info *sbi = EXT4_SB(mapping->host->i_sb); |
2442 | 2445 | ||
@@ -2488,9 +2491,15 @@ static int ext4_da_writepages(struct address_space *mapping, | |||
2488 | if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX) | 2491 | if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX) |
2489 | range_whole = 1; | 2492 | range_whole = 1; |
2490 | 2493 | ||
2491 | if (wbc->range_cyclic) | 2494 | range_cyclic = wbc->range_cyclic; |
2495 | if (wbc->range_cyclic) { | ||
2492 | index = mapping->writeback_index; | 2496 | index = mapping->writeback_index; |
2493 | else | 2497 | if (index) |
2498 | cycled = 0; | ||
2499 | wbc->range_start = index << PAGE_CACHE_SHIFT; | ||
2500 | wbc->range_end = LLONG_MAX; | ||
2501 | wbc->range_cyclic = 0; | ||
2502 | } else | ||
2494 | index = wbc->range_start >> PAGE_CACHE_SHIFT; | 2503 | index = wbc->range_start >> PAGE_CACHE_SHIFT; |
2495 | 2504 | ||
2496 | mpd.wbc = wbc; | 2505 | mpd.wbc = wbc; |
@@ -2504,6 +2513,7 @@ static int ext4_da_writepages(struct address_space *mapping, | |||
2504 | wbc->no_nrwrite_index_update = 1; | 2513 | wbc->no_nrwrite_index_update = 1; |
2505 | pages_skipped = wbc->pages_skipped; | 2514 | pages_skipped = wbc->pages_skipped; |
2506 | 2515 | ||
2516 | retry: | ||
2507 | while (!ret && wbc->nr_to_write > 0) { | 2517 | while (!ret && wbc->nr_to_write > 0) { |
2508 | 2518 | ||
2509 | /* | 2519 | /* |
@@ -2546,6 +2556,7 @@ static int ext4_da_writepages(struct address_space *mapping, | |||
2546 | pages_written += mpd.pages_written; | 2556 | pages_written += mpd.pages_written; |
2547 | wbc->pages_skipped = pages_skipped; | 2557 | wbc->pages_skipped = pages_skipped; |
2548 | ret = 0; | 2558 | ret = 0; |
2559 | io_done = 1; | ||
2549 | } else if (wbc->nr_to_write) | 2560 | } else if (wbc->nr_to_write) |
2550 | /* | 2561 | /* |
2551 | * There is no more writeout needed | 2562 | * There is no more writeout needed |
@@ -2554,6 +2565,13 @@ static int ext4_da_writepages(struct address_space *mapping, | |||
2554 | */ | 2565 | */ |
2555 | break; | 2566 | break; |
2556 | } | 2567 | } |
2568 | if (!io_done && !cycled) { | ||
2569 | cycled = 1; | ||
2570 | index = 0; | ||
2571 | wbc->range_start = index << PAGE_CACHE_SHIFT; | ||
2572 | wbc->range_end = mapping->writeback_index - 1; | ||
2573 | goto retry; | ||
2574 | } | ||
2557 | if (pages_skipped != wbc->pages_skipped) | 2575 | if (pages_skipped != wbc->pages_skipped) |
2558 | printk(KERN_EMERG "This should not happen leaving %s " | 2576 | printk(KERN_EMERG "This should not happen leaving %s " |
2559 | "with nr_to_write = %ld ret = %d\n", | 2577 | "with nr_to_write = %ld ret = %d\n", |
@@ -2561,6 +2579,7 @@ static int ext4_da_writepages(struct address_space *mapping, | |||
2561 | 2579 | ||
2562 | /* Update index */ | 2580 | /* Update index */ |
2563 | index += pages_written; | 2581 | index += pages_written; |
2582 | wbc->range_cyclic = range_cyclic; | ||
2564 | if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0)) | 2583 | if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0)) |
2565 | /* | 2584 | /* |
2566 | * set the writeback_index so that range_cyclic | 2585 | * set the writeback_index so that range_cyclic |
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index deba54f6cbed..4415beeb0b62 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
@@ -3693,6 +3693,8 @@ ext4_mb_new_inode_pa(struct ext4_allocation_context *ac) | |||
3693 | pa->pa_free = pa->pa_len; | 3693 | pa->pa_free = pa->pa_len; |
3694 | atomic_set(&pa->pa_count, 1); | 3694 | atomic_set(&pa->pa_count, 1); |
3695 | spin_lock_init(&pa->pa_lock); | 3695 | spin_lock_init(&pa->pa_lock); |
3696 | INIT_LIST_HEAD(&pa->pa_inode_list); | ||
3697 | INIT_LIST_HEAD(&pa->pa_group_list); | ||
3696 | pa->pa_deleted = 0; | 3698 | pa->pa_deleted = 0; |
3697 | pa->pa_linear = 0; | 3699 | pa->pa_linear = 0; |
3698 | 3700 | ||
@@ -3755,6 +3757,7 @@ ext4_mb_new_group_pa(struct ext4_allocation_context *ac) | |||
3755 | atomic_set(&pa->pa_count, 1); | 3757 | atomic_set(&pa->pa_count, 1); |
3756 | spin_lock_init(&pa->pa_lock); | 3758 | spin_lock_init(&pa->pa_lock); |
3757 | INIT_LIST_HEAD(&pa->pa_inode_list); | 3759 | INIT_LIST_HEAD(&pa->pa_inode_list); |
3760 | INIT_LIST_HEAD(&pa->pa_group_list); | ||
3758 | pa->pa_deleted = 0; | 3761 | pa->pa_deleted = 0; |
3759 | pa->pa_linear = 1; | 3762 | pa->pa_linear = 1; |
3760 | 3763 | ||
@@ -4476,23 +4479,26 @@ static int ext4_mb_release_context(struct ext4_allocation_context *ac) | |||
4476 | pa->pa_free -= ac->ac_b_ex.fe_len; | 4479 | pa->pa_free -= ac->ac_b_ex.fe_len; |
4477 | pa->pa_len -= ac->ac_b_ex.fe_len; | 4480 | pa->pa_len -= ac->ac_b_ex.fe_len; |
4478 | spin_unlock(&pa->pa_lock); | 4481 | spin_unlock(&pa->pa_lock); |
4479 | /* | ||
4480 | * We want to add the pa to the right bucket. | ||
4481 | * Remove it from the list and while adding | ||
4482 | * make sure the list to which we are adding | ||
4483 | * doesn't grow big. | ||
4484 | */ | ||
4485 | if (likely(pa->pa_free)) { | ||
4486 | spin_lock(pa->pa_obj_lock); | ||
4487 | list_del_rcu(&pa->pa_inode_list); | ||
4488 | spin_unlock(pa->pa_obj_lock); | ||
4489 | ext4_mb_add_n_trim(ac); | ||
4490 | } | ||
4491 | } | 4482 | } |
4492 | ext4_mb_put_pa(ac, ac->ac_sb, pa); | ||
4493 | } | 4483 | } |
4494 | if (ac->alloc_semp) | 4484 | if (ac->alloc_semp) |
4495 | up_read(ac->alloc_semp); | 4485 | up_read(ac->alloc_semp); |
4486 | if (pa) { | ||
4487 | /* | ||
4488 | * We want to add the pa to the right bucket. | ||
4489 | * Remove it from the list and while adding | ||
4490 | * make sure the list to which we are adding | ||
4491 | * doesn't grow big. We need to release | ||
4492 | * alloc_semp before calling ext4_mb_add_n_trim() | ||
4493 | */ | ||
4494 | if (pa->pa_linear && likely(pa->pa_free)) { | ||
4495 | spin_lock(pa->pa_obj_lock); | ||
4496 | list_del_rcu(&pa->pa_inode_list); | ||
4497 | spin_unlock(pa->pa_obj_lock); | ||
4498 | ext4_mb_add_n_trim(ac); | ||
4499 | } | ||
4500 | ext4_mb_put_pa(ac, ac->ac_sb, pa); | ||
4501 | } | ||
4496 | if (ac->ac_bitmap_page) | 4502 | if (ac->ac_bitmap_page) |
4497 | page_cache_release(ac->ac_bitmap_page); | 4503 | page_cache_release(ac->ac_bitmap_page); |
4498 | if (ac->ac_buddy_page) | 4504 | if (ac->ac_buddy_page) |
diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c index 734abca25e35..fe64d9f79852 100644 --- a/fs/ext4/migrate.c +++ b/fs/ext4/migrate.c | |||
@@ -481,7 +481,7 @@ int ext4_ext_migrate(struct inode *inode) | |||
481 | + 1); | 481 | + 1); |
482 | if (IS_ERR(handle)) { | 482 | if (IS_ERR(handle)) { |
483 | retval = PTR_ERR(handle); | 483 | retval = PTR_ERR(handle); |
484 | goto err_out; | 484 | return retval; |
485 | } | 485 | } |
486 | tmp_inode = ext4_new_inode(handle, | 486 | tmp_inode = ext4_new_inode(handle, |
487 | inode->i_sb->s_root->d_inode, | 487 | inode->i_sb->s_root->d_inode, |
@@ -489,8 +489,7 @@ int ext4_ext_migrate(struct inode *inode) | |||
489 | if (IS_ERR(tmp_inode)) { | 489 | if (IS_ERR(tmp_inode)) { |
490 | retval = -ENOMEM; | 490 | retval = -ENOMEM; |
491 | ext4_journal_stop(handle); | 491 | ext4_journal_stop(handle); |
492 | tmp_inode = NULL; | 492 | return retval; |
493 | goto err_out; | ||
494 | } | 493 | } |
495 | i_size_write(tmp_inode, i_size_read(inode)); | 494 | i_size_write(tmp_inode, i_size_read(inode)); |
496 | /* | 495 | /* |
@@ -618,8 +617,7 @@ err_out: | |||
618 | 617 | ||
619 | ext4_journal_stop(handle); | 618 | ext4_journal_stop(handle); |
620 | 619 | ||
621 | if (tmp_inode) | 620 | iput(tmp_inode); |
622 | iput(tmp_inode); | ||
623 | 621 | ||
624 | return retval; | 622 | return retval; |
625 | } | 623 | } |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index e5f06a5f045e..a5732c58f676 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -3046,14 +3046,17 @@ static void ext4_write_super(struct super_block *sb) | |||
3046 | static int ext4_sync_fs(struct super_block *sb, int wait) | 3046 | static int ext4_sync_fs(struct super_block *sb, int wait) |
3047 | { | 3047 | { |
3048 | int ret = 0; | 3048 | int ret = 0; |
3049 | tid_t target; | ||
3049 | 3050 | ||
3050 | trace_mark(ext4_sync_fs, "dev %s wait %d", sb->s_id, wait); | 3051 | trace_mark(ext4_sync_fs, "dev %s wait %d", sb->s_id, wait); |
3051 | sb->s_dirt = 0; | 3052 | sb->s_dirt = 0; |
3052 | if (EXT4_SB(sb)->s_journal) { | 3053 | if (EXT4_SB(sb)->s_journal) { |
3053 | if (wait) | 3054 | if (jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, |
3054 | ret = ext4_force_commit(sb); | 3055 | &target)) { |
3055 | else | 3056 | if (wait) |
3056 | jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, NULL); | 3057 | jbd2_log_wait_commit(EXT4_SB(sb)->s_journal, |
3058 | target); | ||
3059 | } | ||
3057 | } else { | 3060 | } else { |
3058 | ext4_commit_super(sb, EXT4_SB(sb)->s_es, wait); | 3061 | ext4_commit_super(sb, EXT4_SB(sb)->s_es, wait); |
3059 | } | 3062 | } |