diff options
author | Adam Manzanares <adam.manzanares@wdc.com> | 2018-05-22 13:52:19 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2018-05-31 10:50:55 -0400 |
commit | d9a08a9e616beeccdbd0e7262b7225ffdfa49e92 (patch) | |
tree | f2f7985aa07ccee2337631273f4b906389649477 | |
parent | fc28724d67c90ff48b976e0687caf79993160bed (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.c | 3 | ||||
-rw-r--r-- | fs/aio.c | 16 | ||||
-rw-r--r-- | include/linux/fs.h | 3 | ||||
-rw-r--r-- | include/uapi/linux/aio_abi.h | 1 |
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 | ||
@@ -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 | ||
305 | static inline bool is_sync_kiocb(struct kiocb *kiocb) | 307 | static 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. */ |
58 | struct io_event { | 59 | struct io_event { |