All of lore.kernel.org
 help / color / mirror / Atom feed
From: Theodore Ts'o <tytso@mit.edu>
To: stable@kernel.org
Cc: "Jayson R. King" <dev@jaysonking.com>,
	Ext4 Developers List <linux-ext4@vger.kernel.org>,
	"Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>,
	Theodore Ts'o <tytso@mit.edu>
Subject: [PATCH 2.6.27.y 01/11] ext4: invalidate pages if delalloc block allocation fails.
Date: Mon, 15 Mar 2010 20:25:55 -0400	[thread overview]
Message-ID: <1268699165-17461-2-git-send-email-tytso@mit.edu> (raw)
In-Reply-To: <1268699165-17461-1-git-send-email-tytso@mit.edu>

From: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>

commit c4a0c46ec92c194c873232b88debce4e1a448483 upstream.

We are a bit agressive in invalidating all the pages. But
it is ok because we really don't know why the block allocation
failed and it is better to come of the writeback path
so that user can look for more info.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Jayson R. King <dev@jaysonking.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
---
 fs/ext4/inode.c |   85 +++++++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 73 insertions(+), 12 deletions(-)

diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index aeebfc2..ebd83cd 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1821,6 +1821,39 @@ static inline void __unmap_underlying_blocks(struct inode *inode,
 		unmap_underlying_metadata(bdev, bh->b_blocknr + i);
 }
 
+static void ext4_da_block_invalidatepages(struct mpage_da_data *mpd,
+					sector_t logical, long blk_cnt)
+{
+	int nr_pages, i;
+	pgoff_t index, end;
+	struct pagevec pvec;
+	struct inode *inode = mpd->inode;
+	struct address_space *mapping = inode->i_mapping;
+
+	index = logical >> (PAGE_CACHE_SHIFT - inode->i_blkbits);
+	end   = (logical + blk_cnt - 1) >>
+				(PAGE_CACHE_SHIFT - inode->i_blkbits);
+	while (index <= end) {
+		nr_pages = pagevec_lookup(&pvec, mapping, index, PAGEVEC_SIZE);
+		if (nr_pages == 0)
+			break;
+		for (i = 0; i < nr_pages; i++) {
+			struct page *page = pvec.pages[i];
+			index = page->index;
+			if (index > end)
+				break;
+			index++;
+
+			BUG_ON(!PageLocked(page));
+			BUG_ON(PageWriteback(page));
+			block_invalidatepage(page, 0);
+			ClearPageUptodate(page);
+			unlock_page(page);
+		}
+	}
+	return;
+}
+
 /*
  * mpage_da_map_blocks - go through given space
  *
@@ -1830,7 +1863,7 @@ static inline void __unmap_underlying_blocks(struct inode *inode,
  * The function skips space we know is already mapped to disk blocks.
  *
  */
-static void mpage_da_map_blocks(struct mpage_da_data *mpd)
+static int  mpage_da_map_blocks(struct mpage_da_data *mpd)
 {
 	int err = 0;
 	struct buffer_head *lbh = &mpd->lbh;
@@ -1841,7 +1874,7 @@ static void mpage_da_map_blocks(struct mpage_da_data *mpd)
 	 * We consider only non-mapped and non-allocated blocks
 	 */
 	if (buffer_mapped(lbh) && !buffer_delay(lbh))
-		return;
+		return 0;
 
 	new.b_state = lbh->b_state;
 	new.b_blocknr = 0;
@@ -1852,10 +1885,38 @@ static void mpage_da_map_blocks(struct mpage_da_data *mpd)
 	 * to write simply return
 	 */
 	if (!new.b_size)
-		return;
+		return 0;
 	err = mpd->get_block(mpd->inode, next, &new, 1);
-	if (err)
-		return;
+	if (err) {
+
+		/* If get block returns with error
+		 * we simply return. Later writepage
+		 * will redirty the page and writepages
+		 * will find the dirty page again
+		 */
+		if (err == -EAGAIN)
+			return 0;
+		/*
+		 * get block failure will cause us
+		 * to loop in writepages. Because
+		 * a_ops->writepage won't be able to
+		 * make progress. The page will be redirtied
+		 * by writepage and writepages will again
+		 * try to write the same.
+		 */
+		printk(KERN_EMERG "%s block allocation failed for inode %lu "
+				  "at logical offset %llu with max blocks "
+				  "%zd with error %d\n",
+				  __func__, mpd->inode->i_ino,
+				  (unsigned long long)next,
+				  lbh->b_size >> mpd->inode->i_blkbits, err);
+		printk(KERN_EMERG "This should not happen.!! "
+					"Data will be lost\n");
+		/* invlaidate all the pages */
+		ext4_da_block_invalidatepages(mpd, next,
+				lbh->b_size >> mpd->inode->i_blkbits);
+		return err;
+	}
 	BUG_ON(new.b_size == 0);
 
 	if (buffer_new(&new))
@@ -1868,7 +1929,7 @@ static void mpage_da_map_blocks(struct mpage_da_data *mpd)
 	if (buffer_delay(lbh) || buffer_unwritten(lbh))
 		mpage_put_bnr_to_bhs(mpd, next, &new);
 
-	return;
+	return 0;
 }
 
 #define BH_FLAGS ((1 << BH_Uptodate) | (1 << BH_Mapped) | \
@@ -1937,8 +1998,8 @@ flush_it:
 	 * We couldn't merge the block to our extent, so we
 	 * need to flush current  extent and start new one
 	 */
-	mpage_da_map_blocks(mpd);
-	mpage_da_submit_io(mpd);
+	if (mpage_da_map_blocks(mpd) == 0)
+		mpage_da_submit_io(mpd);
 	mpd->io_done = 1;
 	return;
 }
@@ -1980,8 +2041,8 @@ static int __mpage_da_writepage(struct page *page,
 		 * and start IO on them using writepage()
 		 */
 		if (mpd->next_page != mpd->first_page) {
-			mpage_da_map_blocks(mpd);
-			mpage_da_submit_io(mpd);
+			if (mpage_da_map_blocks(mpd) == 0)
+				mpage_da_submit_io(mpd);
 			/*
 			 * skip rest of the page in the page_vec
 			 */
@@ -2102,8 +2163,8 @@ static int mpage_da_writepages(struct address_space *mapping,
 	 * Handle last extent of pages
 	 */
 	if (!mpd.io_done && mpd.next_page != mpd.first_page) {
-		mpage_da_map_blocks(&mpd);
-		mpage_da_submit_io(&mpd);
+		if (mpage_da_map_blocks(&mpd) == 0)
+			mpage_da_submit_io(&mpd);
 	}
 
 	wbc->nr_to_write = to_write - mpd.pages_written;
-- 
1.6.6.1.1.g974db.dirty


  reply	other threads:[~2010-03-16  0:26 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-03-16  0:25 [PATCH 2.6.27.y 00/11] *** SUBJECT HERE *** Theodore Ts'o
2010-03-16  0:25 ` Theodore Ts'o [this message]
2010-04-19 17:26   ` patch ext4-invalidate-pages-if-delalloc-block-allocation-fails.patch added to 2.6.27-stable tree gregkh
2010-03-16  0:25 ` [PATCH 2.6.27.y 02/11] percpu counter: clean up percpu_counter_sum_and_set() Theodore Ts'o
2010-04-19 17:27   ` patch percpu-counter-clean-up-percpu_counter_sum_and_set.patch added to 2.6.27-stable tree gregkh
2010-03-16  0:25 ` [PATCH 2.6.27.y 03/11] ext4: Make sure all the block allocation paths reserve blocks Theodore Ts'o
2010-04-19 17:26   ` patch ext4-make-sure-all-the-block-allocation-paths-reserve-blocks.patch added to 2.6.27-stable tree gregkh
2010-03-16  0:25 ` [PATCH 2.6.27.y 04/11] ext4: Add percpu dirty block accounting Theodore Ts'o
2010-03-16 18:48   ` Andreas Dilger
2010-03-17  0:51     ` tytso
2010-04-19 17:26   ` patch ext4-add-percpu-dirty-block-accounting.patch added to 2.6.27-stable tree gregkh
2010-03-16  0:25 ` [PATCH 2.6.27.y 05/11] ext4: Retry block reservation Theodore Ts'o
2010-04-19 17:27   ` patch ext4-retry-block-reservation.patch added to 2.6.27-stable tree gregkh
2010-03-16  0:26 ` [PATCH 2.6.27.y 06/11] ext4: Retry block allocation if we have free blocks left Theodore Ts'o
2010-04-19 17:26   ` patch ext4-retry-block-allocation-if-we-have-free-blocks-left.patch added to 2.6.27-stable tree gregkh
2010-03-16  0:26 ` [PATCH 2.6.27.y 07/11] ext4: Use tag dirty lookup during mpage_da_submit_io Theodore Ts'o
2010-04-19 17:27   ` patch ext4-use-tag-dirty-lookup-during-mpage_da_submit_io.patch added to 2.6.27-stable tree gregkh
2010-03-16  0:26 ` [PATCH 2.6.27.y 08/11] vfs: Remove the range_cont writeback mode Theodore Ts'o
2010-04-19 17:27   ` patch vfs-remove-the-range_cont-writeback-mode.patch added to 2.6.27-stable tree gregkh
2010-03-16  0:26 ` [PATCH 2.6.27.y 09/11] vfs: Add no_nrwrite_index_update writeback control flag Theodore Ts'o
2010-04-19 17:27   ` patch vfs-add-no_nrwrite_index_update-writeback-control-flag.patch added to 2.6.27-stable tree gregkh
2010-03-16  0:26 ` [PATCH 2.6.27.y 10/11] ext4: Fix file fragmentation during large file write Theodore Ts'o
2010-04-19 17:26   ` patch ext4-fix-file-fragmentation-during-large-file-write.patch added to 2.6.27-stable tree gregkh
2010-03-16  0:26 ` [PATCH 2.6.27.y 11/11] ext4: Implement range_cyclic in ext4_da_writepages instead of write_cache_pages Theodore Ts'o
2010-04-19 17:26   ` patch ext4-implement-range_cyclic-in-ext4_da_writepages-instead-of-write_cache_pages.patch added to 2.6.27-stable tree gregkh
2010-03-17  3:10 ` [PATCH 2.6.27.y 00/11] *** SUBJECT HERE *** Jayson R. King

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1268699165-17461-2-git-send-email-tytso@mit.edu \
    --to=tytso@mit.edu \
    --cc=aneesh.kumar@linux.vnet.ibm.com \
    --cc=dev@jaysonking.com \
    --cc=linux-ext4@vger.kernel.org \
    --cc=stable@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.