aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Manzanares <adam.manzanares@wdc.com>2018-05-22 13:52:19 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2018-05-31 10:50:55 -0400
commitd9a08a9e616beeccdbd0e7262b7225ffdfa49e92 (patch)
treef2f7985aa07ccee2337631273f4b906389649477
parentfc28724d67c90ff48b976e0687caf79993160bed (diff)
fs: Add aio iopriority support
This is the per-I/O equivalent of the ioprio_set system call. When IOCB_FLAG_IOPRIO is set on the iocb aio_flags field, then we set the newly added kiocb ki_ioprio field to the value in the iocb aio_reqprio field. This patch depends on block: add ioprio_check_cap function. Signed-off-by: Adam Manzanares <adam.manzanares@wdc.com> Reviewed-by: Jeff Moyer <jmoyer@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--drivers/block/loop.c3
-rw-r--r--fs/aio.c16
-rw-r--r--include/linux/fs.h3
-rw-r--r--include/uapi/linux/aio_abi.h1
4 files changed, 23 insertions, 0 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 5d4e31655d96..dd98dfd97f5e 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -76,6 +76,8 @@
76#include <linux/miscdevice.h> 76#include <linux/miscdevice.h>
77#include <linux/falloc.h> 77#include <linux/falloc.h>
78#include <linux/uio.h> 78#include <linux/uio.h>
79#include <linux/ioprio.h>
80
79#include "loop.h" 81#include "loop.h"
80 82
81#include <linux/uaccess.h> 83#include <linux/uaccess.h>
@@ -559,6 +561,7 @@ static int lo_rw_aio(struct loop_device *lo, struct loop_cmd *cmd,
559 cmd->iocb.ki_filp = file; 561 cmd->iocb.ki_filp = file;
560 cmd->iocb.ki_complete = lo_rw_aio_complete; 562 cmd->iocb.ki_complete = lo_rw_aio_complete;
561 cmd->iocb.ki_flags = IOCB_DIRECT; 563 cmd->iocb.ki_flags = IOCB_DIRECT;
564 cmd->iocb.ki_ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_NONE, 0);
562 if (cmd->css) 565 if (cmd->css)
563 kthread_associate_blkcg(cmd->css); 566 kthread_associate_blkcg(cmd->css);
564 567
diff --git a/fs/aio.c b/fs/aio.c
index 33299ece7540..9527ededa669 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -1435,6 +1435,22 @@ static int aio_prep_rw(struct kiocb *req, struct iocb *iocb)
1435 if (iocb->aio_flags & IOCB_FLAG_RESFD) 1435 if (iocb->aio_flags & IOCB_FLAG_RESFD)
1436 req->ki_flags |= IOCB_EVENTFD; 1436 req->ki_flags |= IOCB_EVENTFD;
1437 req->ki_hint = ki_hint_validate(file_write_hint(req->ki_filp)); 1437 req->ki_hint = ki_hint_validate(file_write_hint(req->ki_filp));
1438 if (iocb->aio_flags & IOCB_FLAG_IOPRIO) {
1439 /*
1440 * If the IOCB_FLAG_IOPRIO flag of aio_flags is set, then
1441 * aio_reqprio is interpreted as an I/O scheduling
1442 * class and priority.
1443 */
1444 ret = ioprio_check_cap(iocb->aio_reqprio);
1445 if (ret) {
1446 pr_debug("aio ioprio check cap error\n");
1447 return -EINVAL;
1448 }
1449
1450 req->ki_ioprio = iocb->aio_reqprio;
1451 } else
1452 req->ki_ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_NONE, 0);
1453
1438 ret = kiocb_set_rw_flags(req, iocb->aio_rw_flags); 1454 ret = kiocb_set_rw_flags(req, iocb->aio_rw_flags);
1439 if (unlikely(ret)) 1455 if (unlikely(ret))
1440 fput(req->ki_filp); 1456 fput(req->ki_filp);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index b432fc3feb93..eef9334b26d1 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -36,6 +36,7 @@
36#include <linux/delayed_call.h> 36#include <linux/delayed_call.h>
37#include <linux/uuid.h> 37#include <linux/uuid.h>
38#include <linux/errseq.h> 38#include <linux/errseq.h>
39#include <linux/ioprio.h>
39 40
40#include <asm/byteorder.h> 41#include <asm/byteorder.h>
41#include <uapi/linux/fs.h> 42#include <uapi/linux/fs.h>
@@ -300,6 +301,7 @@ struct kiocb {
300 void *private; 301 void *private;
301 int ki_flags; 302 int ki_flags;
302 u16 ki_hint; 303 u16 ki_hint;
304 u16 ki_ioprio; /* See linux/ioprio.h */
303} __randomize_layout; 305} __randomize_layout;
304 306
305static inline bool is_sync_kiocb(struct kiocb *kiocb) 307static inline bool is_sync_kiocb(struct kiocb *kiocb)
@@ -1944,6 +1946,7 @@ static inline void init_sync_kiocb(struct kiocb *kiocb, struct file *filp)
1944 .ki_filp = filp, 1946 .ki_filp = filp,
1945 .ki_flags = iocb_flags(filp), 1947 .ki_flags = iocb_flags(filp),
1946 .ki_hint = ki_hint_validate(file_write_hint(filp)), 1948 .ki_hint = ki_hint_validate(file_write_hint(filp)),
1949 .ki_ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_NONE, 0),
1947 }; 1950 };
1948} 1951}
1949 1952
diff --git a/include/uapi/linux/aio_abi.h b/include/uapi/linux/aio_abi.h
index ed0185945bb2..75846164290e 100644
--- a/include/uapi/linux/aio_abi.h
+++ b/include/uapi/linux/aio_abi.h
@@ -53,6 +53,7 @@ enum {
53 * is valid. 53 * is valid.
54 */ 54 */
55#define IOCB_FLAG_RESFD (1 << 0) 55#define IOCB_FLAG_RESFD (1 << 0)
56#define IOCB_FLAG_IOPRIO (1 << 1)
56 57
57/* read() from /dev/aio returns these structures. */ 58/* read() from /dev/aio returns these structures. */
58struct io_event { 59struct io_event {