From: Goldwyn Rodrigues <[email protected]>

RWF_* flags is used for preadv2/pwritev2 calls. Port to use
it for aio operations as well. For this, aio_rw_flags is
introduced in struct iocb (using aio_reserved1) which will
carry these flags.

This is a precursor to the nowait AIO calls.

Note, the only place RWF_HIPRI comes in effect is dio_await_one().
All the rest of the locations, aio code return -EIOCBQUEUED before the
checks for RWF_HIPRI.

Signed-off-by: Goldwyn Rodrigues <[email protected]>
---
 fs/aio.c                     | 15 ++++++++++++++-
 include/uapi/linux/aio_abi.h |  2 +-
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/fs/aio.c b/fs/aio.c
index f52d925ee259..7cd1443ad1c8 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -1541,11 +1541,17 @@ static int io_submit_one(struct kioctx *ctx, struct 
iocb __user *user_iocb,
        ssize_t ret;
 
        /* enforce forwards compatibility on users */
-       if (unlikely(iocb->aio_reserved1 || iocb->aio_reserved2)) {
+       if (unlikely(iocb->aio_reserved2)) {
                pr_debug("EINVAL: reserve field set\n");
                return -EINVAL;
        }
 
+       if (unlikely(iocb->aio_rw_flags & ~(RWF_HIPRI | RWF_DSYNC | RWF_SYNC))) 
{
+               pr_debug("EINVAL: aio_rw_flags set with incompatible flags\n");
+               return -EINVAL;
+       }
+
+
        /* prevent overflows */
        if (unlikely(
            (iocb->aio_buf != (unsigned long)iocb->aio_buf) ||
@@ -1586,6 +1592,13 @@ static int io_submit_one(struct kioctx *ctx, struct iocb 
__user *user_iocb,
                req->common.ki_flags |= IOCB_EVENTFD;
        }
 
+       if (iocb->aio_rw_flags & RWF_HIPRI)
+               req->common.ki_flags |= IOCB_HIPRI;
+       if (iocb->aio_rw_flags & RWF_DSYNC)
+               req->common.ki_flags |= IOCB_DSYNC;
+       if (iocb->aio_rw_flags & RWF_SYNC)
+               req->common.ki_flags |= (IOCB_DSYNC | IOCB_SYNC);
+
        ret = put_user(KIOCB_KEY, &user_iocb->aio_key);
        if (unlikely(ret)) {
                pr_debug("EFAULT: aio_key\n");
diff --git a/include/uapi/linux/aio_abi.h b/include/uapi/linux/aio_abi.h
index bb2554f7fbd1..a2d4a8ac94ca 100644
--- a/include/uapi/linux/aio_abi.h
+++ b/include/uapi/linux/aio_abi.h
@@ -79,7 +79,7 @@ struct io_event {
 struct iocb {
        /* these are internal to the kernel/libc. */
        __u64   aio_data;       /* data to be returned in event's data */
-       __u32   PADDED(aio_key, aio_reserved1);
+       __u32   PADDED(aio_key, aio_rw_flags);
                                /* the kernel sets aio_key to the req # */
 
        /* common fields */
-- 
2.12.0

Reply via email to