ext4: Rewrite ext4_page_mkwrite() to use generic helpers

Rewrite ext4_page_mkwrite() to use __block_page_mkwrite() helper. This
removes the need of using i_alloc_sem to avoid races with truncate which
seems to be the wrong locking order according to lock ordering documented in
mm/rmap.c. Also calling ext4_da_write_begin() as used by the old code seems to
be problematic because we can decide to flush delay-allocated blocks which
will acquire s_umount semaphore - again creating unpleasant lock dependency
if not directly a deadlock.

Also add a check for frozen filesystem so that we don't busyloop in page fault
when the filesystem is frozen.

Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
(cherry picked from commit 9ea7df534ed2a18157434a496a12cf073ca00c52)
ext4: remove unnecessary ext4_get_group_info in ext4_mb_load_buddy

ext4_mb_load_buddy() calls ext4_get_group_info() for setting both
"grp" and "e4b->bd_info", but it could do "e4b->bd_info = grp".

Reported-by:  Andreas Dilger <adilger@whamcloud.com>
Signed-off-by: Tao Ma <boyu.mt@taobao.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
(cherry picked from commit 529da704ad1ead755d9e40721f29446cb278e099)
ext4: don't increment s_mb_buddies_generated in ext4_mb_release

In ext4_mb_release, we use s_mb_buddies_generated++.  Although
the output is OK, but I don't think we need this extra ++.

Signed-off-by: Tao Ma <boyu.mt@taobao.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
(cherry picked from commit ced156e464e49b6b4153ede9aaa04d9a4ad24e0c)
ext4: remove ac_repeats from ext4_allocation_context

ac_repeats isn't referenced in the mballoc code. So remove it.

Signed-off-by: Tao Ma <boyu.mt@taobao.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
(cherry picked from commit 6a0fe49308dcac10ab510b3c45e00eb8d5ef440e)
ext4: remove unused argument in ext4_ext_next_leaf_block

The argument "inode" in function ext4_ext_next_allocated_block looks useless,
so clean it.

Signed-off-by: Robin Dong <sanbai@taobao.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
(cherry picked from commit 5718789da5b94bd4148cb7ea0f457089c26bc1c3)

Conflicts:

	fs/ext4/extents.c
ext4: correct the debug message in ext4_ext_insert_extent

The debug message in ext4_ext_insert_extent before moving extent
is incorrect (the "from xx to xx").

Signed-off-by: Robin Dong <sanbai@taobao.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
(cherry picked from commit 0737964bc98202776f4d10bc8e108f45b3115037)
ext4: correct comment for ext4_ext_check_cache

The comment for ext4_ext_check_cache has a litte mistake.

Signed-off-by: Robin Dong <sanbai@taobao.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
(cherry picked from commit b7ca1e8ec53259359db5313f923a0a20fa04bdb6)
ext4: fix data corruption in inodes with journalled data

When journalling data for an inode (either because it is a symlink or
because the filesystem is mounted in data=journal mode), ext4_evict_inode()
can discard unwritten data by calling truncate_inode_pages(). This is
because we don't mark the buffer / page dirty when journalling data but only
add the buffer to the running transaction and thus mm does not know there
are still unwritten data.

Fix the problem by carefully tracking transaction containing inode's data,
committing this transaction, and writing uncheckpointed buffers when inode
should be reaped.

Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
(cherry picked from commit 2d859db3e4a82a365572592d57624a5f996ed0ec)
ext4: prevent parallel resizers by atomic bit ops

Before this patch, parallel resizers are allowed and protected by a
mutex lock, actually, there is no need to support parallel resizer, so
this patch prevents parallel resizers by atmoic bit ops, like
lock_page() and unlock_page() do.

To do this, the patch removed the mutex lock s_resize_lock from struct
ext4_sb_info and added a unsigned long field named s_resize_flags
which inidicates if there is a resizer.

Signed-off-by: Yongqiang Yang <xiaoqiangnk@gmail.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
(cherry picked from commit 8f82f840ec6ab873f520364d443ff6fa1b3f8e22)
ext4: prevent a fs with errors from being resized

A filesystem with errors is not allowed to being resized, otherwise,
it is easy to destroy the filesystem.

Signed-off-by: Yongqiang Yang <xiaoqiangnk@gmail.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
(cherry picked from commit ce723c31b58f54fb865036805475ee7a8c5dc173)
ext4: rename ext4_add_groupblocks() to ext4_group_add_blocks()

Signed-off-by: Yongqiang Yang <xiaoqiangnk@gmail.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
(cherry picked from commit 0529155e8a4bcb77dfc9ceaea19c6501487e452b)
ext4: let ext4_group_add_blocks() return an error code

This patch lets ext4_group_add_blocks() return an error code if it
fails, so that upper functions can handle error correctly.

Signed-off-by: Yongqiang Yang <xiaoqiangnk@gmail.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
(cherry picked from commit cc7365dfe48cb2191f1572bf69e30d3e58716313)
ext4: let ext4_group_add_blocks() handle 0 blocks quickly

If ext4_group_add_blocks() is called with 0 block, make it return 0
without doing any extra work.

Signed-off-by: Yongqiang Yang <xiaoqiangnk@gmail.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
(cherry picked from commit 4740b830ed5720ade6c780dbf3fdfe9089b3552d)
ext4: fix a typo in ext4_group_extend()

Signed-off-by: Yongqiang Yang <xiaoqiangnk@gmail.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
(cherry picked from commit 2b79b09d13e35577151bd13ba08809911baccd1c)
ext4: let setup_new_group_blocks() set multiple bits at a time

Rename mb_set_bits() to ext4_set_bits() and make it a global function
so that setup_new_group_blocks() can use it.

Signed-off-by: Yongqiang Yang <xiaoqiangnk@gmail.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
(cherry picked from commit c3e94d1df9bdd9e2c4ba7e8f534f7925f1756f97)
ext4: simplify journal handling in setup_new_group_blocks()

This patch simplifies journal handling in setup_new_group_blocks().

In previous code, block bitmap is modified everywhere in
setup_new_group_blocks(), ext4_get_write_access() in
extend_or_restart_transaction() is used to guarantee that the block
bitmap stays in the new handle, this makes things complicated.

The previous commit changed things so that the modifications on the
block bitmap are batched and done by ext4_set_bits() at the end of the
for loop.  This allows us to simplify things.

Signed-off-by: Yongqiang Yang <xiaoqiangnk@gmail.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
(cherry picked from commit 6d40bc5a7e8fc71795d131e835f38f161ed7e1b1)
ext4: remove lock_buffer in bclean() and setup_new_group_blocks()

There is no need to lock the buffers since no one else should be
touching these buffers besides the file system.

Signed-off-by: Yongqiang Yang <xiaoqiangnk@gmail.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
(cherry picked from commit e6075e984d100c12bb79267639c3f661d9788a67)
ext4: simplify parameters of add_new_gdb()

add_new_gdb() only needs the block group number; there is no need to
pass a pointer to struct ext4_new_group_data to add_new_gdb().
Instead of filling in a pointer the struct buffer_head in
add_new_gdb(), it's simpler to have the caller fetch it from the
s_group_desc[] array.

[Fixed error path to handle the case where struct buffer_head *primary
 hasn't been set yet. -- Ted]

Signed-off-by: Yongqiang Yang <xiaoqiangnk@gmail.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
(cherry picked from commit 2f919710143cb2025157c3c193ee22de86f3ed73)
ext4: simplify parameters of reserve_backup_gdb()

The reserve_backup_gdb() function only needs the block group number;
there's no need to pass a pointer to struct ext4_new_group_data to it.

Signed-off-by: Yongqiang Yang <xiaoqiangnk@gmail.com>
(cherry picked from commit 668f4dc5593327fadc95b33189c375f7178ef88e)
ext4: add action of moving index in ext4_ext_rm_idx for Punch Hole

The old function ext4_ext_rm_idx is used only for truncate case
because it just remove last index in extent-index-block. When punching
hole, it usually needed to remove "middle" index, therefore we must
move indexes which after it forward.

(I create a file with 1 depth extent tree and punch hole in the middle
of it, the last index in index-block strangly gone, so I find out this
bug)

Signed-off-by: Robin Dong <sanbai@taobao.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
(cherry picked from commit 0e1147b001793593624e80b3c0a1790822b6baca)