Thread (18 messages) 18 messages, 6 authors, 2020-07-27

Re: [PATCH 2/2] zonefs: use zone-append for AIO as well

From: Johannes Thumshirn <hidden>
Date: 2020-07-22 14:32:32
Also in: linux-fsdevel

On 21/07/2020 15:02, Kanchan Joshi wrote:
On Mon, Jul 20, 2020 at 10:21:18PM +0900, Johannes Thumshirn wrote:
quoted
If we get an async I/O iocb with an O_APPEND or RWF_APPEND flag set,
submit it using REQ_OP_ZONE_APPEND to the block layer.

As an REQ_OP_ZONE_APPEND bio must not be split, this does come with an
additional constraint, namely the buffer submitted to zonefs must not be
bigger than the max zone append size of the underlying device. For
synchronous I/O we don't care about this constraint as we can return short
writes, for AIO we need to return an error on too big buffers.
I wonder what part of the patch implements that constraint on large
buffer and avoids short-write.
Existing code seems to trim iov_iter in the outset. 

        max = queue_max_zone_append_sectors(bdev_get_queue(bdev));
        max = ALIGN_DOWN(max << SECTOR_SHIFT, inode->i_sb->s_blocksize);
        iov_iter_truncate(from, max);
This actually needs a 'if (sync)' before the iov_iter_truncate() you're right.
This will prevent large-buffer seeing that error, and will lead to partial write.
quoted
On a successful completion, the position the data is written to is
returned via AIO's res2 field to the calling application.

Signed-off-by: Johannes Thumshirn <redacted>
---
fs/zonefs/super.c  | 143 +++++++++++++++++++++++++++++++++++++++------
fs/zonefs/zonefs.h |   3 +
2 files changed, 128 insertions(+), 18 deletions(-)
diff --git a/fs/zonefs/super.c b/fs/zonefs/super.c
index 5832e9f69268..f155a658675b 100644
--- a/fs/zonefs/super.c
+++ b/fs/zonefs/super.c
@@ -24,6 +24,8 @@
#include "zonefs.h"

+static struct bio_set zonefs_dio_bio_set;
+
static inline int zonefs_zone_mgmt(struct zonefs_inode_info *zi,
				   enum req_opf op)
{
@@ -700,16 +702,71 @@ static const struct iomap_dio_ops zonefs_write_dio_ops = {
	.end_io			= zonefs_file_write_dio_end_io,
};

+struct zonefs_dio {
+	struct kiocb		*iocb;
+	struct task_struct	*waiter;
+	int			error;
+	struct work_struct	work;
+	size_t			size;
+	u64			sector;
+	struct completion	completion;
+	struct bio		bio;
+};
How about this (will save 32 bytes) - 
+struct zonefs_dio {
+       struct kiocb            *iocb;
+       struct task_struct      *waiter;
+       int                     error;
+	union {
+       	struct work_struct      work;   //only for async IO
+       	struct completion       completion; //only for sync IO
+	};
+       size_t                  size;
+       u64                     sector;
+       struct bio              bio;
+};
And dio->error field is not required.
I see it being used at one place -
+       ret = zonefs_file_write_dio_end_io(iocb, dio->size,
+                                          dio->error, 0);
Here error-code can be picked from dio->bio.
Indeed, did that and also removed the unused completion from 
zonefs_dio and made a union of work and waiter.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help