aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/inode.c')
-rw-r--r--fs/ext4/inode.c70
1 files changed, 59 insertions, 11 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index a08ec795995f..97a0c35219ae 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -60,7 +60,12 @@ static inline int ext4_begin_ordered_truncate(struct inode *inode,
60} 60}
61 61
62static void ext4_invalidatepage(struct page *page, unsigned long offset); 62static void ext4_invalidatepage(struct page *page, unsigned long offset);
63static int ext4_writepage(struct page *page, struct writeback_control *wbc); 63static int noalloc_get_block_write(struct inode *inode, sector_t iblock,
64 struct buffer_head *bh_result, int create);
65static int ext4_set_bh_endio(struct buffer_head *bh, struct inode *inode);
66static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate);
67static int __ext4_journalled_writepage(struct page *page, unsigned int len);
68static int ext4_bh_delay_or_unwritten(handle_t *handle, struct buffer_head *bh);
64 69
65/* 70/*
66 * Test whether an inode is a fast symlink. 71 * Test whether an inode is a fast symlink.
@@ -2000,12 +2005,15 @@ static void ext4_da_page_release_reservation(struct page *page,
2000 */ 2005 */
2001static int mpage_da_submit_io(struct mpage_da_data *mpd) 2006static int mpage_da_submit_io(struct mpage_da_data *mpd)
2002{ 2007{
2003 long pages_skipped;
2004 struct pagevec pvec; 2008 struct pagevec pvec;
2005 unsigned long index, end; 2009 unsigned long index, end;
2006 int ret = 0, err, nr_pages, i; 2010 int ret = 0, err, nr_pages, i;
2007 struct inode *inode = mpd->inode; 2011 struct inode *inode = mpd->inode;
2008 struct address_space *mapping = inode->i_mapping; 2012 struct address_space *mapping = inode->i_mapping;
2013 loff_t size = i_size_read(inode);
2014 unsigned int len;
2015 struct buffer_head *page_bufs = NULL;
2016 int journal_data = ext4_should_journal_data(inode);
2009 2017
2010 BUG_ON(mpd->next_page <= mpd->first_page); 2018 BUG_ON(mpd->next_page <= mpd->first_page);
2011 /* 2019 /*
@@ -2023,28 +2031,69 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd)
2023 if (nr_pages == 0) 2031 if (nr_pages == 0)
2024 break; 2032 break;
2025 for (i = 0; i < nr_pages; i++) { 2033 for (i = 0; i < nr_pages; i++) {
2034 int commit_write = 0;
2026 struct page *page = pvec.pages[i]; 2035 struct page *page = pvec.pages[i];
2027 2036
2028 index = page->index; 2037 index = page->index;
2029 if (index > end) 2038 if (index > end)
2030 break; 2039 break;
2040
2041 if (index == size >> PAGE_CACHE_SHIFT)
2042 len = size & ~PAGE_CACHE_MASK;
2043 else
2044 len = PAGE_CACHE_SIZE;
2031 index++; 2045 index++;
2032 2046
2033 BUG_ON(!PageLocked(page)); 2047 BUG_ON(!PageLocked(page));
2034 BUG_ON(PageWriteback(page)); 2048 BUG_ON(PageWriteback(page));
2035 2049
2036 pages_skipped = mpd->wbc->pages_skipped; 2050 /*
2037 err = ext4_writepage(page, mpd->wbc); 2051 * If the page does not have buffers (for
2038 if (!err && (pages_skipped == mpd->wbc->pages_skipped)) 2052 * whatever reason), try to create them using
2053 * block_prepare_write. If this fails,
2054 * redirty the page and move on.
2055 */
2056 if (!page_has_buffers(page)) {
2057 if (block_prepare_write(page, 0, len,
2058 noalloc_get_block_write)) {
2059 redirty_page:
2060 redirty_page_for_writepage(mpd->wbc,
2061 page);
2062 unlock_page(page);
2063 continue;
2064 }
2065 commit_write = 1;
2066 }
2067 page_bufs = page_buffers(page);
2068 if (walk_page_buffers(NULL, page_bufs, 0, len, NULL,
2069 ext4_bh_delay_or_unwritten)) {
2039 /* 2070 /*
2040 * have successfully written the page 2071 * We couldn't do block allocation for
2041 * without skipping the same 2072 * some reason.
2042 */ 2073 */
2074 goto redirty_page;
2075 }
2076
2077 if (commit_write)
2078 /* mark the buffer_heads as dirty & uptodate */
2079 block_commit_write(page, 0, len);
2080
2081 if (journal_data && PageChecked(page))
2082 err = __ext4_journalled_writepage(page, len);
2083 else if (buffer_uninit(page_bufs)) {
2084 ext4_set_bh_endio(page_bufs, inode);
2085 err = block_write_full_page_endio(page,
2086 noalloc_get_block_write,
2087 mpd->wbc, ext4_end_io_buffer_write);
2088 } else
2089 err = block_write_full_page(page,
2090 noalloc_get_block_write, mpd->wbc);
2091
2092 if (!err)
2043 mpd->pages_written++; 2093 mpd->pages_written++;
2044 /* 2094 /*
2045 * In error case, we have to continue because 2095 * In error case, we have to continue because
2046 * remaining pages are still locked 2096 * remaining pages are still locked
2047 * XXX: unlock and re-dirty them?
2048 */ 2097 */
2049 if (ret == 0) 2098 if (ret == 0)
2050 ret = err; 2099 ret = err;
@@ -2627,6 +2676,7 @@ static int __ext4_journalled_writepage(struct page *page,
2627 int ret = 0; 2676 int ret = 0;
2628 int err; 2677 int err;
2629 2678
2679 ClearPageChecked(page);
2630 page_bufs = page_buffers(page); 2680 page_bufs = page_buffers(page);
2631 BUG_ON(!page_bufs); 2681 BUG_ON(!page_bufs);
2632 walk_page_buffers(handle, page_bufs, 0, len, NULL, bget_one); 2682 walk_page_buffers(handle, page_bufs, 0, len, NULL, bget_one);
@@ -2749,14 +2799,12 @@ static int ext4_writepage(struct page *page,
2749 /* now mark the buffer_heads as dirty and uptodate */ 2799 /* now mark the buffer_heads as dirty and uptodate */
2750 block_commit_write(page, 0, len); 2800 block_commit_write(page, 0, len);
2751 2801
2752 if (PageChecked(page) && ext4_should_journal_data(inode)) { 2802 if (PageChecked(page) && ext4_should_journal_data(inode))
2753 /* 2803 /*
2754 * It's mmapped pagecache. Add buffers and journal it. There 2804 * It's mmapped pagecache. Add buffers and journal it. There
2755 * doesn't seem much point in redirtying the page here. 2805 * doesn't seem much point in redirtying the page here.
2756 */ 2806 */
2757 ClearPageChecked(page);
2758 return __ext4_journalled_writepage(page, len); 2807 return __ext4_journalled_writepage(page, len);
2759 }
2760 2808
2761 if (buffer_uninit(page_bufs)) { 2809 if (buffer_uninit(page_bufs)) {
2762 ext4_set_bh_endio(page_bufs, inode); 2810 ext4_set_bh_endio(page_bufs, inode);