ext4: fix unwritten counter leakage

ext4_set_io_unwritten_flag() will increment i_unwritten counter, so
once we mark end_io with EXT4_END_IO_UNWRITTEN we have to revert it back
on error path.

 - add missed error checks to prevent counter leakage
 - ext4_end_io_nolock() will clear EXT4_END_IO_UNWRITTEN flag to signal
   that conversion finished.
 - add BUG_ON to ext4_free_end_io() to prevent similar leakage in future.

Visible effect of this bug is that unaligned aio_stress may deadlock

Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c
index de77e31..9970022 100644
--- a/fs/ext4/page-io.c
+++ b/fs/ext4/page-io.c
@@ -71,6 +71,8 @@
 	int i;
 
 	BUG_ON(!io);
+	BUG_ON(io->flag & EXT4_IO_END_UNWRITTEN);
+
 	if (io->page)
 		put_page(io->page);
 	for (i = 0; i < io->num_io_pages; i++)
@@ -94,6 +96,8 @@
 	ssize_t size = io->size;
 	int ret = 0;
 
+	BUG_ON(!(io->flag & EXT4_IO_END_UNWRITTEN));
+
 	ext4_debug("ext4_end_io_nolock: io 0x%p from inode %lu,list->next 0x%p,"
 		   "list->prev 0x%p\n",
 		   io, inode->i_ino, io->list.next, io->list.prev);
@@ -106,7 +110,7 @@
 			 "(inode %lu, offset %llu, size %zd, error %d)",
 			 inode->i_ino, offset, size, ret);
 	}
-
+	io->flag &= ~EXT4_IO_END_UNWRITTEN;
 	if (io->iocb)
 		aio_complete(io->iocb, io->result, 0);