android_kernel_samsung_msm8976/fs/ext4
Theodore Ts'o f7ad6d2e92 ext4: handle writeback of inodes which are being freed
The following BUG can occur when an inode which is getting freed when
it still has dirty pages outstanding, and it gets deleted (in this
because it was the target of a rename).  In ordered mode, we need to
make sure the data pages are written just in case we crash before the
rename (or unlink) is committed.  If the inode is being freed then
when we try to igrab the inode, we end up tripping the BUG_ON at
fs/ext4/page-io.c:146.

To solve this problem, we need to keep track of the number of io
callbacks which are pending, and avoid destroying the inode until they
have all been completed.  That way we don't have to bump the inode
count to keep the inode from being destroyed; an approach which
doesn't work because the count could have already been dropped down to
zero before the inode writeback has started (at which point we're not
allowed to bump the count back up to 1, since it's already started
getting freed).

Thanks to Dave Chinner for suggesting this approach, which is also
used by XFS.

  kernel BUG at /scratch_space/linux-2.6/fs/ext4/page-io.c:146!
  Call Trace:
   [<ffffffff811075b1>] ext4_bio_write_page+0x172/0x307
   [<ffffffff811033a7>] mpage_da_submit_io+0x2f9/0x37b
   [<ffffffff811068d7>] mpage_da_map_and_submit+0x2cc/0x2e2
   [<ffffffff811069b3>] mpage_add_bh_to_extent+0xc6/0xd5
   [<ffffffff81106c66>] write_cache_pages_da+0x2a4/0x3ac
   [<ffffffff81107044>] ext4_da_writepages+0x2d6/0x44d
   [<ffffffff81087910>] do_writepages+0x1c/0x25
   [<ffffffff810810a4>] __filemap_fdatawrite_range+0x4b/0x4d
   [<ffffffff810815f5>] filemap_fdatawrite_range+0xe/0x10
   [<ffffffff81122a2e>] jbd2_journal_begin_ordered_truncate+0x7b/0xa2
   [<ffffffff8110615d>] ext4_evict_inode+0x57/0x24c
   [<ffffffff810c14a3>] evict+0x22/0x92
   [<ffffffff810c1a3d>] iput+0x212/0x249
   [<ffffffff810bdf16>] dentry_iput+0xa1/0xb9
   [<ffffffff810bdf6b>] d_kill+0x3d/0x5d
   [<ffffffff810be613>] dput+0x13a/0x147
   [<ffffffff810b990d>] sys_renameat+0x1b5/0x258
   [<ffffffff81145f71>] ? _atomic_dec_and_lock+0x2d/0x4c
   [<ffffffff810b2950>] ? cp_new_stat+0xde/0xea
   [<ffffffff810b29c1>] ? sys_newlstat+0x2d/0x38
   [<ffffffff810b99c6>] sys_rename+0x16/0x18
   [<ffffffff81002a2b>] system_call_fastpath+0x16/0x1b

Reported-by: Nick Bowler <nbowler@elliptictech.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Tested-by: Nick Bowler <nbowler@elliptictech.com>
2010-11-08 13:43:33 -05:00
..
acl.c ext4: update ctime when changing the file's permission by setfacl 2010-06-15 12:19:59 -04:00
acl.h
balloc.c ext4: rename mark_bitmap_end() to ext4_mark_bitmap_end() 2010-10-27 21:30:15 -04:00
bitmap.c
block_validity.c ext4: rename {exit,init}_ext4_*() to ext4_{exit,init}_*() 2010-10-27 21:30:14 -04:00
dir.c ext4: improve llseek error handling for overly large seek offsets 2010-10-27 21:30:06 -04:00
ext4.h ext4: handle writeback of inodes which are being freed 2010-11-08 13:43:33 -05:00
ext4_extents.h ext4: rename {ext,idx}_pblock and inline small extent functions 2010-10-27 21:30:14 -04:00
ext4_jbd2.c ext4: Pass line numbers to ext4_error() and friends 2010-07-27 11:56:40 -04:00
ext4_jbd2.h ext4: Pass line numbers to ext4_error() and friends 2010-07-27 11:56:40 -04:00
extents.c Merge branch 'next' into upstream-merge 2010-10-27 23:44:47 -04:00
file.c ext4: improve llseek error handling for overly large seek offsets 2010-10-27 21:30:06 -04:00
fsync.c Merge branch 'next' into upstream-merge 2010-10-27 23:44:47 -04:00
hash.c
ialloc.c Merge branch 'next' into upstream-merge 2010-10-27 23:44:47 -04:00
inode.c ext4: BUG_ON fix: check if page has buffers before calling page_buffers() 2010-10-28 17:33:57 -04:00
ioctl.c ext4: Drop whitespace at end of lines 2010-05-17 07:00:00 -04:00
Kconfig ext4: Don't ask about supporting ext2/3 in ext4 if ext4 is not configured 2009-12-21 10:54:09 -05:00
Makefile ext4: use bio layer instead of buffer layer in mpage_da_submit_io 2010-10-27 21:30:10 -04:00
mballoc.c Merge branch 'next' into upstream-merge 2010-10-27 23:44:47 -04:00
mballoc.h ext4: consolidate in_range() definitions 2010-03-03 23:55:01 -05:00
migrate.c ext4: rename {ext,idx}_pblock and inline small extent functions 2010-10-27 21:30:14 -04:00
move_extent.c ext4: rename {ext,idx}_pblock and inline small extent functions 2010-10-27 21:30:14 -04:00
namei.c Merge branch 'next' into upstream-merge 2010-10-27 23:44:47 -04:00
page-io.c ext4: handle writeback of inodes which are being freed 2010-11-08 13:43:33 -05:00
resize.c Merge branch 'next' into upstream-merge 2010-10-27 23:44:47 -04:00
super.c ext4: handle writeback of inodes which are being freed 2010-11-08 13:43:33 -05:00
symlink.c ext4: symlink must be handled via filesystem specific operation 2010-05-16 02:00:00 -04:00
xattr.c ext4: rename {exit,init}_ext4_*() to ext4_{exit,init}_*() 2010-10-27 21:30:14 -04:00
xattr.h ext4: fix compile with CONFIG_EXT4_FS_XATTR disabled 2010-10-28 09:29:17 -07:00
xattr_security.c ext4: constify xattr_handler 2010-05-21 18:31:19 -04:00
xattr_trusted.c ext4: constify xattr_handler 2010-05-21 18:31:19 -04:00
xattr_user.c ext4: constify xattr_handler 2010-05-21 18:31:19 -04:00