aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4')
-rw-r--r--fs/ext4/inode.c73
1 files changed, 25 insertions, 48 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 55961ff4efc2..a08ec795995f 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -2704,7 +2704,7 @@ static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate);
2704static int ext4_writepage(struct page *page, 2704static int ext4_writepage(struct page *page,
2705 struct writeback_control *wbc) 2705 struct writeback_control *wbc)
2706{ 2706{
2707 int ret = 0; 2707 int ret = 0, commit_write = 0;
2708 loff_t size; 2708 loff_t size;
2709 unsigned int len; 2709 unsigned int len;
2710 struct buffer_head *page_bufs = NULL; 2710 struct buffer_head *page_bufs = NULL;
@@ -2717,60 +2717,37 @@ static int ext4_writepage(struct page *page,
2717 else 2717 else
2718 len = PAGE_CACHE_SIZE; 2718 len = PAGE_CACHE_SIZE;
2719 2719
2720 if (page_has_buffers(page)) { 2720 /*
2721 page_bufs = page_buffers(page); 2721 * If the page does not have buffers (for whatever reason),
2722 if (walk_page_buffers(NULL, page_bufs, 0, len, NULL, 2722 * try to create them using block_prepare_write. If this
2723 ext4_bh_delay_or_unwritten)) { 2723 * fails, redirty the page and move on.
2724 /* 2724 */
2725 * We don't want to do block allocation 2725 if (!page_buffers(page)) {
2726 * So redirty the page and return 2726 if (block_prepare_write(page, 0, len,
2727 * We may reach here when we do a journal commit 2727 noalloc_get_block_write)) {
2728 * via journal_submit_inode_data_buffers. 2728 redirty_page:
2729 * If we don't have mapping block we just ignore
2730 * them. We can also reach here via shrink_page_list
2731 */
2732 redirty_page_for_writepage(wbc, page); 2729 redirty_page_for_writepage(wbc, page);
2733 unlock_page(page); 2730 unlock_page(page);
2734 return 0; 2731 return 0;
2735 } 2732 }
2736 } else { 2733 commit_write = 1;
2734 }
2735 page_bufs = page_buffers(page);
2736 if (walk_page_buffers(NULL, page_bufs, 0, len, NULL,
2737 ext4_bh_delay_or_unwritten)) {
2737 /* 2738 /*
2738 * The test for page_has_buffers() is subtle: 2739 * We don't want to do block allocation So redirty the
2739 * We know the page is dirty but it lost buffers. That means 2740 * page and return We may reach here when we do a
2740 * that at some moment in time after write_begin()/write_end() 2741 * journal commit via
2741 * has been called all buffers have been clean and thus they 2742 * journal_submit_inode_data_buffers. If we don't
2742 * must have been written at least once. So they are all 2743 * have mapping block we just ignore them. We can also
2743 * mapped and we can happily proceed with mapping them 2744 * reach here via shrink_page_list
2744 * and writing the page.
2745 *
2746 * Try to initialize the buffer_heads and check whether
2747 * all are mapped and non delay. We don't want to
2748 * do block allocation here.
2749 */ 2745 */
2750 ret = block_prepare_write(page, 0, len, 2746 goto redirty_page;
2751 noalloc_get_block_write); 2747 }
2752 if (!ret) { 2748 if (commit_write)
2753 page_bufs = page_buffers(page);
2754 /* check whether all are mapped and non delay */
2755 if (walk_page_buffers(NULL, page_bufs, 0, len, NULL,
2756 ext4_bh_delay_or_unwritten)) {
2757 redirty_page_for_writepage(wbc, page);
2758 unlock_page(page);
2759 return 0;
2760 }
2761 } else {
2762 /*
2763 * We can't do block allocation here
2764 * so just redity the page and unlock
2765 * and return
2766 */
2767 redirty_page_for_writepage(wbc, page);
2768 unlock_page(page);
2769 return 0;
2770 }
2771 /* now mark the buffer_heads as dirty and uptodate */ 2749 /* now mark the buffer_heads as dirty and uptodate */
2772 block_commit_write(page, 0, len); 2750 block_commit_write(page, 0, len);
2773 }
2774 2751
2775 if (PageChecked(page) && ext4_should_journal_data(inode)) { 2752 if (PageChecked(page) && ext4_should_journal_data(inode)) {
2776 /* 2753 /*
@@ -2781,7 +2758,7 @@ static int ext4_writepage(struct page *page,
2781 return __ext4_journalled_writepage(page, len); 2758 return __ext4_journalled_writepage(page, len);
2782 } 2759 }
2783 2760
2784 if (page_bufs && buffer_uninit(page_bufs)) { 2761 if (buffer_uninit(page_bufs)) {
2785 ext4_set_bh_endio(page_bufs, inode); 2762 ext4_set_bh_endio(page_bufs, inode);
2786 ret = block_write_full_page_endio(page, noalloc_get_block_write, 2763 ret = block_write_full_page_endio(page, noalloc_get_block_write,
2787 wbc, ext4_end_io_buffer_write); 2764 wbc, ext4_end_io_buffer_write);