All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] aio: Support read/write with non-iter file-ops
@ 2019-07-18 23:10 Bjorn Andersson
  2019-07-18 23:17 ` Al Viro
  0 siblings, 1 reply; 6+ messages in thread
From: Bjorn Andersson @ 2019-07-18 23:10 UTC (permalink / raw)
  To: Alexander Viro, Benjamin LaHaise; +Cc: linux-fsdevel, linux-aio, linux-kernel

Implement a wrapper for aio_read()/write() to allow async IO on files
not implementing the iter version of read/write, such as sysfs. This
mimics how readv/writev uses non-iter ops in do_loop_readv_writev().

Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
 fs/aio.c | 52 +++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 45 insertions(+), 7 deletions(-)

diff --git a/fs/aio.c b/fs/aio.c
index f9f441b59966..0137a1a9bef1 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -1514,12 +1514,44 @@ static inline void aio_rw_done(struct kiocb *req, ssize_t ret)
 	}
 }
 
+static ssize_t aio_iter_readv_writev(struct file *file, struct kiocb *req,
+				     struct iov_iter *iter, int type)
+{
+	ssize_t ret = 0;
+	ssize_t nr;
+
+	while (iov_iter_count(iter)) {
+		struct iovec iovec = iov_iter_iovec(iter);
+
+		if (type == READ) {
+			nr = file->f_op->read(file, iovec.iov_base,
+					      iovec.iov_len, &req->ki_pos);
+		} else {
+			nr = file->f_op->write(file, iovec.iov_base,
+					       iovec.iov_len, &req->ki_pos);
+		}
+
+		if (nr < 0) {
+			ret = nr;
+			break;
+		}
+
+		ret += nr;
+		if (nr != iovec.iov_len)
+			break;
+		iov_iter_advance(iter, nr);
+	}
+
+	return ret;
+}
+
 static int aio_read(struct kiocb *req, const struct iocb *iocb,
 			bool vectored, bool compat)
 {
 	struct iovec inline_vecs[UIO_FASTIOV], *iovec = inline_vecs;
 	struct iov_iter iter;
 	struct file *file;
+	ssize_t count;
 	int ret;
 
 	ret = aio_prep_rw(req, iocb);
@@ -1529,15 +1561,18 @@ static int aio_read(struct kiocb *req, const struct iocb *iocb,
 	if (unlikely(!(file->f_mode & FMODE_READ)))
 		return -EBADF;
 	ret = -EINVAL;
-	if (unlikely(!file->f_op->read_iter))
-		return -EINVAL;
 
 	ret = aio_setup_rw(READ, iocb, &iovec, vectored, compat, &iter);
 	if (ret < 0)
 		return ret;
 	ret = rw_verify_area(READ, file, &req->ki_pos, iov_iter_count(&iter));
-	if (!ret)
-		aio_rw_done(req, call_read_iter(file, req, &iter));
+	if (!ret) {
+		if (likely(file->f_op->read_iter))
+			count = call_read_iter(file, req, &iter);
+		else
+			count = aio_iter_readv_writev(file, req, &iter, READ);
+		aio_rw_done(req, count);
+	}
 	kfree(iovec);
 	return ret;
 }
@@ -1548,6 +1583,7 @@ static int aio_write(struct kiocb *req, const struct iocb *iocb,
 	struct iovec inline_vecs[UIO_FASTIOV], *iovec = inline_vecs;
 	struct iov_iter iter;
 	struct file *file;
+	ssize_t count;
 	int ret;
 
 	ret = aio_prep_rw(req, iocb);
@@ -1557,8 +1593,6 @@ static int aio_write(struct kiocb *req, const struct iocb *iocb,
 
 	if (unlikely(!(file->f_mode & FMODE_WRITE)))
 		return -EBADF;
-	if (unlikely(!file->f_op->write_iter))
-		return -EINVAL;
 
 	ret = aio_setup_rw(WRITE, iocb, &iovec, vectored, compat, &iter);
 	if (ret < 0)
@@ -1577,7 +1611,11 @@ static int aio_write(struct kiocb *req, const struct iocb *iocb,
 			__sb_writers_release(file_inode(file)->i_sb, SB_FREEZE_WRITE);
 		}
 		req->ki_flags |= IOCB_WRITE;
-		aio_rw_done(req, call_write_iter(file, req, &iter));
+		if (likely(file->f_op->write_iter))
+			count = call_write_iter(file, req, &iter);
+		else
+			count = aio_iter_readv_writev(file, req, &iter, WRITE);
+		aio_rw_done(req, count);
 	}
 	kfree(iovec);
 	return ret;
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH] aio: Support read/write with non-iter file-ops
  2019-07-18 23:10 [PATCH] aio: Support read/write with non-iter file-ops Bjorn Andersson
@ 2019-07-18 23:17 ` Al Viro
  2019-07-18 23:43   ` Bjorn Andersson
  0 siblings, 1 reply; 6+ messages in thread
From: Al Viro @ 2019-07-18 23:17 UTC (permalink / raw)
  To: Bjorn Andersson; +Cc: Benjamin LaHaise, linux-fsdevel, linux-aio, linux-kernel

On Thu, Jul 18, 2019 at 04:10:54PM -0700, Bjorn Andersson wrote:
> Implement a wrapper for aio_read()/write() to allow async IO on files
> not implementing the iter version of read/write, such as sysfs. This
> mimics how readv/writev uses non-iter ops in do_loop_readv_writev().

IDGI.  How would that IO manage to be async?  And what's the point
using aio in such situations in the first place?

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] aio: Support read/write with non-iter file-ops
  2019-07-18 23:17 ` Al Viro
@ 2019-07-18 23:43   ` Bjorn Andersson
  2019-07-18 23:56     ` Benjamin LaHaise
  2019-07-19  0:07     ` Al Viro
  0 siblings, 2 replies; 6+ messages in thread
From: Bjorn Andersson @ 2019-07-18 23:43 UTC (permalink / raw)
  To: Al Viro; +Cc: Benjamin LaHaise, linux-fsdevel, linux-aio, linux-kernel

On Thu 18 Jul 16:17 PDT 2019, Al Viro wrote:

> On Thu, Jul 18, 2019 at 04:10:54PM -0700, Bjorn Andersson wrote:
> > Implement a wrapper for aio_read()/write() to allow async IO on files
> > not implementing the iter version of read/write, such as sysfs. This
> > mimics how readv/writev uses non-iter ops in do_loop_readv_writev().
> 
> IDGI.  How would that IO manage to be async?  And what's the point
> using aio in such situations in the first place?

The point is that an application using aio to submit io operations on a
set of files, can use the same mechanism to read/write files that
happens to be implemented by driver only implementing read/write (not
read_iter/write_iter) in the registered file_operations struct, such as
kernfs.

In this particular case I have a sysfs file that is accessing hardware
and hence will block for a while and using this patch I can io_submit()
a write and handle the completion of this in my normal event loop.


Each individual io operation will be just as synchronous as the current
iter-based mechanism - for the drivers that implement that.

Regards,
Bjorn

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] aio: Support read/write with non-iter file-ops
  2019-07-18 23:43   ` Bjorn Andersson
@ 2019-07-18 23:56     ` Benjamin LaHaise
  2019-07-19  0:36       ` Bjorn Andersson
  2019-07-19  0:07     ` Al Viro
  1 sibling, 1 reply; 6+ messages in thread
From: Benjamin LaHaise @ 2019-07-18 23:56 UTC (permalink / raw)
  To: Bjorn Andersson; +Cc: Al Viro, linux-fsdevel, linux-aio, linux-kernel

On Thu, Jul 18, 2019 at 04:43:52PM -0700, Bjorn Andersson wrote:
> On Thu 18 Jul 16:17 PDT 2019, Al Viro wrote:
> 
> > On Thu, Jul 18, 2019 at 04:10:54PM -0700, Bjorn Andersson wrote:
> > > Implement a wrapper for aio_read()/write() to allow async IO on files
> > > not implementing the iter version of read/write, such as sysfs. This
> > > mimics how readv/writev uses non-iter ops in do_loop_readv_writev().
> > 
> > IDGI.  How would that IO manage to be async?  And what's the point
> > using aio in such situations in the first place?
> 
> The point is that an application using aio to submit io operations on a
> set of files, can use the same mechanism to read/write files that
> happens to be implemented by driver only implementing read/write (not
> read_iter/write_iter) in the registered file_operations struct, such as
> kernfs.
> 
> In this particular case I have a sysfs file that is accessing hardware
> and hence will block for a while and using this patch I can io_submit()
> a write and handle the completion of this in my normal event loop.
> 
> 
> Each individual io operation will be just as synchronous as the current
> iter-based mechanism - for the drivers that implement that.

Just adding the fops is not enough.  I have patches floating around at
Solace that add thread based fallbacks for files that don't have an aio
read / write implementation, but I'm not working on that code any more.
The thread based methods were quite useful in applications that had a need
for using other kernel infrastructure in their main event loops.

		-ben

> Regards,
> Bjorn
> 

-- 
"Thought is the essence of where you are now."

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] aio: Support read/write with non-iter file-ops
  2019-07-18 23:43   ` Bjorn Andersson
  2019-07-18 23:56     ` Benjamin LaHaise
@ 2019-07-19  0:07     ` Al Viro
  1 sibling, 0 replies; 6+ messages in thread
From: Al Viro @ 2019-07-19  0:07 UTC (permalink / raw)
  To: Bjorn Andersson; +Cc: Benjamin LaHaise, linux-fsdevel, linux-aio, linux-kernel

On Thu, Jul 18, 2019 at 04:43:52PM -0700, Bjorn Andersson wrote:
> On Thu 18 Jul 16:17 PDT 2019, Al Viro wrote:
> 
> > On Thu, Jul 18, 2019 at 04:10:54PM -0700, Bjorn Andersson wrote:
> > > Implement a wrapper for aio_read()/write() to allow async IO on files
> > > not implementing the iter version of read/write, such as sysfs. This
> > > mimics how readv/writev uses non-iter ops in do_loop_readv_writev().
> > 
> > IDGI.  How would that IO manage to be async?  And what's the point
> > using aio in such situations in the first place?
> 
> The point is that an application using aio to submit io operations on a
> set of files,

... for no reason whatsoever, I take it?

> can use the same mechanism to read/write files that
> happens to be implemented by driver only implementing read/write (not
> read_iter/write_iter) in the registered file_operations struct, such as
> kernfs.

... except that it still has to support the kernels that don't have
your patch, so the fallback in userland is *not* going away.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] aio: Support read/write with non-iter file-ops
  2019-07-18 23:56     ` Benjamin LaHaise
@ 2019-07-19  0:36       ` Bjorn Andersson
  0 siblings, 0 replies; 6+ messages in thread
From: Bjorn Andersson @ 2019-07-19  0:36 UTC (permalink / raw)
  To: Benjamin LaHaise; +Cc: Al Viro, linux-fsdevel, linux-aio, linux-kernel

On Thu 18 Jul 16:56 PDT 2019, Benjamin LaHaise wrote:

> On Thu, Jul 18, 2019 at 04:43:52PM -0700, Bjorn Andersson wrote:
> > On Thu 18 Jul 16:17 PDT 2019, Al Viro wrote:
> > 
> > > On Thu, Jul 18, 2019 at 04:10:54PM -0700, Bjorn Andersson wrote:
> > > > Implement a wrapper for aio_read()/write() to allow async IO on files
> > > > not implementing the iter version of read/write, such as sysfs. This
> > > > mimics how readv/writev uses non-iter ops in do_loop_readv_writev().
> > > 
> > > IDGI.  How would that IO manage to be async?  And what's the point
> > > using aio in such situations in the first place?
> > 
> > The point is that an application using aio to submit io operations on a
> > set of files, can use the same mechanism to read/write files that
> > happens to be implemented by driver only implementing read/write (not
> > read_iter/write_iter) in the registered file_operations struct, such as
> > kernfs.
> > 
> > In this particular case I have a sysfs file that is accessing hardware
> > and hence will block for a while and using this patch I can io_submit()
> > a write and handle the completion of this in my normal event loop.
> > 
> > 
> > Each individual io operation will be just as synchronous as the current
> > iter-based mechanism - for the drivers that implement that.
> 
> Just adding the fops is not enough.  I have patches floating around at
> Solace that add thread based fallbacks for files that don't have an aio
> read / write implementation, but I'm not working on that code any more.

My bad. Took another look and now I see the bigger picture of how this
is currently implemented and why just adding the fops would defeat the
purpose of the api.

Sorry for the noise.

> The thread based methods were quite useful in applications that had a need
> for using other kernel infrastructure in their main event loops.
> 

Yes indeed.

Regards,
Bjorn

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2019-07-19  0:37 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-18 23:10 [PATCH] aio: Support read/write with non-iter file-ops Bjorn Andersson
2019-07-18 23:17 ` Al Viro
2019-07-18 23:43   ` Bjorn Andersson
2019-07-18 23:56     ` Benjamin LaHaise
2019-07-19  0:36       ` Bjorn Andersson
2019-07-19  0:07     ` Al Viro

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.