linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Christoph Hellwig <hch@infradead.org>
To: linux-fsdevel@vger.kernel.org
Cc: Jan Kara <jack@suse.cz>, Jeff Moyer <jmoyer@redhat.com>,
	"Darrick J. Wong" <darrick.wong@oracle.com>
Subject: [PATCH 2/2] [PATCH 2/2] direct-io: handle handle O_(D)SYNC AIO
Date: Fri, 23 Nov 2012 02:55:04 -0500	[thread overview]
Message-ID: <20121123075916.375908616@bombadil.infradead.org> (raw)
In-Reply-To: 20121123075502.307482760@bombadil.infradead.org

[-- Attachment #1: directio-handle-aio-O_SYNC --]
[-- Type: text/plain, Size: 4934 bytes --]

Call generic_write_sync from the deferred I/O completion handler if
O_DSYNC is set for a write request.  Also make sure various callers
don't call generic_write_sync if the direct I/O code returns
-EIOCBQUEUED.

Note: this currently breaks ext4 due to it's convoluted unwritten
extent conversion code.  I've tried to understand it and as far
as I can see it's a workaround for the fact that ext4 marks page
writeback as completed before converting unwritten extents.
Ext4 should follow xfs on this and only mark writeback as completed
when it really is and at that point can remove the big hairy mess to
force unwritten extent conversions from fsync, truncate and a few other
places.

Based on an earlier patch from Jan Kara <jack@suse.cz> with updates from
Jeff Moyer <jmoyer@redhat.com> and Darrick J. Wong <darrick.wong@oracle.com>.

Signed-off-by: Christoph Hellwig <hch@lst.de>

---
 fs/block_dev.c  |    2 +-
 fs/btrfs/file.c |    2 +-
 fs/cifs/file.c  |    2 +-
 fs/direct-io.c  |   22 +++++++++++++++++++++-
 fs/ext4/file.c  |    2 +-
 mm/filemap.c    |    2 +-
 6 files changed, 26 insertions(+), 6 deletions(-)

Index: linux-2.6/fs/block_dev.c
===================================================================
--- linux-2.6.orig/fs/block_dev.c	2012-11-21 21:19:34.075136013 +0100
+++ linux-2.6/fs/block_dev.c	2012-11-21 21:23:51.227142598 +0100
@@ -1631,7 +1631,7 @@ ssize_t blkdev_aio_write(struct kiocb *i
 	percpu_down_read(&bdev->bd_block_size_semaphore);
 
 	ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos);
-	if (ret > 0 || ret == -EIOCBQUEUED) {
+	if (ret > 0) {
 		ssize_t err;
 
 		err = generic_write_sync(file, pos, ret);
Index: linux-2.6/fs/btrfs/file.c
===================================================================
--- linux-2.6.orig/fs/btrfs/file.c	2012-11-21 21:19:34.075136013 +0100
+++ linux-2.6/fs/btrfs/file.c	2012-11-21 21:23:51.231142597 +0100
@@ -1495,7 +1495,7 @@ static ssize_t btrfs_file_aio_write(stru
 	 * one running right now.
 	 */
 	BTRFS_I(inode)->last_trans = root->fs_info->generation + 1;
-	if (num_written > 0 || num_written == -EIOCBQUEUED) {
+	if (num_written > 0) {
 		err = generic_write_sync(file, pos, num_written);
 		if (err < 0 && num_written > 0)
 			num_written = err;
Index: linux-2.6/fs/cifs/file.c
===================================================================
--- linux-2.6.orig/fs/cifs/file.c	2012-11-21 21:19:34.075136013 +0100
+++ linux-2.6/fs/cifs/file.c	2012-11-21 21:23:51.231142597 +0100
@@ -2464,7 +2464,7 @@ cifs_writev(struct kiocb *iocb, const st
 		mutex_unlock(&inode->i_mutex);
 	}
 
-	if (rc > 0 || rc == -EIOCBQUEUED) {
+	if (rc > 0) {
 		ssize_t err;
 
 		err = generic_write_sync(file, pos, rc);
Index: linux-2.6/fs/ext4/file.c
===================================================================
--- linux-2.6.orig/fs/ext4/file.c	2012-11-21 21:19:34.075136013 +0100
+++ linux-2.6/fs/ext4/file.c	2012-11-21 21:23:51.231142597 +0100
@@ -155,7 +155,7 @@ ext4_file_dio_write(struct kiocb *iocb,
 	ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos);
 	mutex_unlock(&inode->i_mutex);
 
-	if (ret > 0 || ret == -EIOCBQUEUED) {
+	if (ret > 0) {
 		ssize_t err;
 
 		err = generic_write_sync(file, pos, ret);
Index: linux-2.6/mm/filemap.c
===================================================================
--- linux-2.6.orig/mm/filemap.c	2012-11-21 21:19:34.075136013 +0100
+++ linux-2.6/mm/filemap.c	2012-11-21 21:23:51.235142597 +0100
@@ -2532,7 +2532,7 @@ ssize_t generic_file_aio_write(struct ki
 	ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos);
 	mutex_unlock(&inode->i_mutex);
 
-	if (ret > 0 || ret == -EIOCBQUEUED) {
+	if (ret > 0) {
 		ssize_t err;
 
 		err = generic_write_sync(file, pos, ret);
Index: linux-2.6/fs/direct-io.c
===================================================================
--- linux-2.6.orig/fs/direct-io.c	2012-11-21 21:22:57.875141232 +0100
+++ linux-2.6/fs/direct-io.c	2012-11-21 21:23:51.235142597 +0100
@@ -264,8 +264,19 @@ static ssize_t dio_complete(struct dio *
 	if (dio->result && dio->end_io)
 		dio->end_io(dio->iocb, offset, transferred, dio->private);
 
-	if (is_async)
+	if (is_async) {
+		if (dio->rw & WRITE) {
+			int err;
+
+			err = generic_write_sync(dio->iocb->ki_filp, offset,
+						 transferred);
+			if (err < 0 && ret > 0)
+				ret = err;
+		}
+
 		aio_complete(dio->iocb, ret, 0);
+	}
+
 	inode_dio_done(dio->inode);
 
 	kmem_cache_free(dio_cache, dio);
@@ -1163,6 +1174,15 @@ do_blockdev_direct_IO(int rw, struct kio
 	dio->is_async = !is_sync_kiocb(iocb) && !((rw & WRITE) &&
 		(end > i_size_read(inode)));
 
+	/*
+	 * For AIO O_(D)SYNC writes we need to defer completions to a workqueue
+	 * so that we can call ->fsync.
+	 */
+	if (dio->is_async && (rw & WRITE) &&
+	    ((iocb->ki_filp->f_flags & O_DSYNC) ||
+	     IS_SYNC(iocb->ki_filp->f_mapping->host)))
+		dio->defer_completion = true;
+
 	retval = 0;
 
 	dio->inode = inode;


  parent reply	other threads:[~2012-11-23  7:59 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-11-23  7:55 [PATCH 0/2] handle O_(D)SYNC for AIO Christoph Hellwig
2012-11-23  7:55 ` [PATCH 1/2] [PATCH 1/2] direct-io: implement generic deferred AIO completions Christoph Hellwig
2012-11-27 16:17   ` Jeff Moyer
2012-12-06 19:05   ` Jan Kara
2012-12-08 12:02     ` Christoph Hellwig
2012-12-20 11:15       ` Jan Kara
2012-11-23  7:55 ` Christoph Hellwig [this message]
2012-11-27 16:19   ` [PATCH 2/2] [PATCH 2/2] direct-io: handle handle O_(D)SYNC AIO Jeff Moyer
2012-11-28  0:26     ` Darrick J. Wong
2012-11-28  0:30       ` Christoph Hellwig
2012-11-28  8:02         ` [RFC PATCH] ext4: Convert unwritten extents during end_io processing Darrick J. Wong
2012-11-28 14:34           ` Christoph Hellwig
2012-11-29 19:47             ` Darrick J. Wong
2012-12-05 13:08     ` [PATCH 2/2] [PATCH 2/2] direct-io: handle handle O_(D)SYNC AIO Jan Kara

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20121123075916.375908616@bombadil.infradead.org \
    --to=hch@infradead.org \
    --cc=darrick.wong@oracle.com \
    --cc=jack@suse.cz \
    --cc=jmoyer@redhat.com \
    --cc=linux-fsdevel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).