f2fs: preallocate blocks for buffered aio writes

This patch preallocates data blocks for buffered aio writes.
With this patch, we can avoid redundant locking and unlocking of node pages
given consecutive aio request.

[For 3.10]
 - Add preallocationg for generic_splice_write(sendfile) for xfstests/249, 285

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>

 Conflicts:
	fs/f2fs/data.c
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 57072f7..15d9580 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -1897,6 +1897,7 @@
 {
 	struct file *file = iocb->ki_filp;
 	struct inode *inode = file_inode(file);
+	size_t count;
 	ssize_t ret;
 
 	if (f2fs_encrypted_inode(inode) &&
@@ -1904,11 +1905,19 @@
 				f2fs_get_encryption_info(inode))
 		return -EACCES;
 
+	ret = generic_segment_checks(iov, &nr_segs, &count, VERIFY_READ);
+	if (ret)
+		return ret;
+
 	inode_lock(inode);
-	ret = f2fs_preallocate_blocks(iocb, iov_length(iov, nr_segs));
-	if (!ret)
-		ret = __generic_file_aio_write(iocb, iov, nr_segs,
-							&iocb->ki_pos);
+	ret = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode));
+	if (!ret) {
+		ret = f2fs_preallocate_blocks(inode, pos, count,
+				iocb->ki_filp->f_flags & O_DIRECT);
+		if (!ret)
+			ret = __generic_file_aio_write(iocb, iov, nr_segs,
+								&iocb->ki_pos);
+	}
 	inode_unlock(inode);
 
 	if (ret > 0 || ret == -EIOCBQUEUED) {
@@ -1954,6 +1963,23 @@
 }
 #endif
 
+static ssize_t f2fs_file_splice_write(struct pipe_inode_info *pipe,
+			struct file *out,
+			  loff_t *ppos, size_t len, unsigned int flags)
+{
+	struct address_space *mapping = out->f_mapping;
+	struct inode *inode = mapping->host;
+	int ret;
+
+	ret = generic_write_checks(out, ppos, &len, S_ISBLK(inode->i_mode));
+	if (ret)
+		return ret;
+	ret = f2fs_preallocate_blocks(inode, *ppos, len, false);
+	if (ret)
+		return ret;
+	return generic_file_splice_write(pipe, out, ppos, len, flags);
+}
+
 const struct file_operations f2fs_file_operations = {
 	.llseek		= f2fs_llseek,
 	.read		= do_sync_read,
@@ -1970,5 +1996,5 @@
 	.compat_ioctl	= f2fs_compat_ioctl,
 #endif
 	.splice_read	= generic_file_splice_read,
-	.splice_write	= generic_file_splice_write,
+	.splice_write	= f2fs_file_splice_write,
 };