Patchwork [3.5.y.z,extended,stable] Patch "tmpfs: change final i_blocks BUG to WARNING" has been added to staging queue

mail settings
Submitter Herton Ronaldo Krzesinski
Date Dec. 7, 2012, 4:06 p.m.
Message ID <>
Download mbox | patch
Permalink /patch/204566/
State New
Headers show


Herton Ronaldo Krzesinski - Dec. 7, 2012, 4:06 p.m.
This is a note to let you know that I have just added a patch titled

    tmpfs: change final i_blocks BUG to WARNING

to the linux-3.5.y-queue branch of the 3.5.y.z extended stable tree 
which can be found at:;a=shortlog;h=refs/heads/linux-3.5.y-queue

If you, or anyone else, feels it should not be added to this tree, please 
reply to this email.

For more information about the 3.5.y.z tree, see



From 180a5fb26ef5d65d95619d5cee9087937d06f3d9 Mon Sep 17 00:00:00 2001
From: Hugh Dickins <>
Date: Fri, 16 Nov 2012 14:15:04 -0800
Subject: [PATCH] tmpfs: change final i_blocks BUG to WARNING

commit 0f3c42f522dc1ad7e27affc0a4aa8c790bce0a66 upstream.

Under a particular load on one machine, I have hit shmem_evict_inode()'s
BUG_ON(inode->i_blocks), enough times to narrow it down to a particular
race between swapout and eviction.

It comes from the "if (freed > 0)" asymmetry in shmem_recalc_inode(),
and the lack of coherent locking between mapping's nrpages and shmem's
swapped count.  There's a window in shmem_writepage(), between lowering
nrpages in shmem_delete_from_page_cache() and then raising swapped
count, when the freed count appears to be +1 when it should be 0, and
then the asymmetry stops it from being corrected with -1 before hitting
the BUG.

One answer is coherent locking: using tree_lock throughout, without
info->lock; reasonable, but the raw_spin_lock in percpu_counter_add() on
used_blocks makes that messier than expected.  Another answer may be a
further effort to eliminate the weird shmem_recalc_inode() altogether,
but previous attempts at that failed.

So far undecided, but for now change the BUG_ON to WARN_ON: in usual
circumstances it remains a useful consistency check.

Signed-off-by: Hugh Dickins <>
Signed-off-by: Andrew Morton <>
Signed-off-by: Linus Torvalds <>
[ herton: adjust context ]
Signed-off-by: Herton Ronaldo Krzesinski <>
 mm/shmem.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)



diff --git a/mm/shmem.c b/mm/shmem.c
index c7f7a77..8d0c102 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -654,7 +654,7 @@  static void shmem_evict_inode(struct inode *inode)
-	BUG_ON(inode->i_blocks);
+	WARN_ON(inode->i_blocks);