Merge branch 'work.aio' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull aio iopriority support from Al Viro: "The rest of aio stuff for this cycle - Adam's aio ioprio series" * 'work.aio' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: fs: aio ioprio use ioprio_check_cap ret val fs: aio ioprio add explicit block layer dependence fs: iomap dio set bio prio from kiocb prio fs: blkdev set bio prio from kiocb prio fs: Add aio iopriority support fs: Convert kiocb rw_hint from enum to u16 block: add ioprio_check_cap function
This commit is contained in:
commit
4a189982e2
|
@ -61,15 +61,10 @@ int set_task_ioprio(struct task_struct *task, int ioprio)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(set_task_ioprio);
|
EXPORT_SYMBOL_GPL(set_task_ioprio);
|
||||||
|
|
||||||
SYSCALL_DEFINE3(ioprio_set, int, which, int, who, int, ioprio)
|
int ioprio_check_cap(int ioprio)
|
||||||
{
|
{
|
||||||
int class = IOPRIO_PRIO_CLASS(ioprio);
|
int class = IOPRIO_PRIO_CLASS(ioprio);
|
||||||
int data = IOPRIO_PRIO_DATA(ioprio);
|
int data = IOPRIO_PRIO_DATA(ioprio);
|
||||||
struct task_struct *p, *g;
|
|
||||||
struct user_struct *user;
|
|
||||||
struct pid *pgrp;
|
|
||||||
kuid_t uid;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
switch (class) {
|
switch (class) {
|
||||||
case IOPRIO_CLASS_RT:
|
case IOPRIO_CLASS_RT:
|
||||||
|
@ -92,6 +87,21 @@ SYSCALL_DEFINE3(ioprio_set, int, which, int, who, int, ioprio)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SYSCALL_DEFINE3(ioprio_set, int, which, int, who, int, ioprio)
|
||||||
|
{
|
||||||
|
struct task_struct *p, *g;
|
||||||
|
struct user_struct *user;
|
||||||
|
struct pid *pgrp;
|
||||||
|
kuid_t uid;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = ioprio_check_cap(ioprio);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
ret = -ESRCH;
|
ret = -ESRCH;
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
switch (which) {
|
switch (which) {
|
||||||
|
|
|
@ -76,6 +76,8 @@
|
||||||
#include <linux/miscdevice.h>
|
#include <linux/miscdevice.h>
|
||||||
#include <linux/falloc.h>
|
#include <linux/falloc.h>
|
||||||
#include <linux/uio.h>
|
#include <linux/uio.h>
|
||||||
|
#include <linux/ioprio.h>
|
||||||
|
|
||||||
#include "loop.h"
|
#include "loop.h"
|
||||||
|
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
|
@ -559,6 +561,7 @@ static int lo_rw_aio(struct loop_device *lo, struct loop_cmd *cmd,
|
||||||
cmd->iocb.ki_filp = file;
|
cmd->iocb.ki_filp = file;
|
||||||
cmd->iocb.ki_complete = lo_rw_aio_complete;
|
cmd->iocb.ki_complete = lo_rw_aio_complete;
|
||||||
cmd->iocb.ki_flags = IOCB_DIRECT;
|
cmd->iocb.ki_flags = IOCB_DIRECT;
|
||||||
|
cmd->iocb.ki_ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_NONE, 0);
|
||||||
if (cmd->css)
|
if (cmd->css)
|
||||||
kthread_associate_blkcg(cmd->css);
|
kthread_associate_blkcg(cmd->css);
|
||||||
|
|
||||||
|
|
18
fs/aio.c
18
fs/aio.c
|
@ -1434,7 +1434,23 @@ static int aio_prep_rw(struct kiocb *req, struct iocb *iocb)
|
||||||
req->ki_flags = iocb_flags(req->ki_filp);
|
req->ki_flags = iocb_flags(req->ki_filp);
|
||||||
if (iocb->aio_flags & IOCB_FLAG_RESFD)
|
if (iocb->aio_flags & IOCB_FLAG_RESFD)
|
||||||
req->ki_flags |= IOCB_EVENTFD;
|
req->ki_flags |= IOCB_EVENTFD;
|
||||||
req->ki_hint = file_write_hint(req->ki_filp);
|
req->ki_hint = ki_hint_validate(file_write_hint(req->ki_filp));
|
||||||
|
if (iocb->aio_flags & IOCB_FLAG_IOPRIO) {
|
||||||
|
/*
|
||||||
|
* If the IOCB_FLAG_IOPRIO flag of aio_flags is set, then
|
||||||
|
* aio_reqprio is interpreted as an I/O scheduling
|
||||||
|
* class and priority.
|
||||||
|
*/
|
||||||
|
ret = ioprio_check_cap(iocb->aio_reqprio);
|
||||||
|
if (ret) {
|
||||||
|
pr_debug("aio ioprio check cap error: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
req->ki_ioprio = iocb->aio_reqprio;
|
||||||
|
} else
|
||||||
|
req->ki_ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_NONE, 0);
|
||||||
|
|
||||||
ret = kiocb_set_rw_flags(req, iocb->aio_rw_flags);
|
ret = kiocb_set_rw_flags(req, iocb->aio_rw_flags);
|
||||||
if (unlikely(ret))
|
if (unlikely(ret))
|
||||||
fput(req->ki_filp);
|
fput(req->ki_filp);
|
||||||
|
|
|
@ -216,6 +216,7 @@ __blkdev_direct_IO_simple(struct kiocb *iocb, struct iov_iter *iter,
|
||||||
bio.bi_write_hint = iocb->ki_hint;
|
bio.bi_write_hint = iocb->ki_hint;
|
||||||
bio.bi_private = current;
|
bio.bi_private = current;
|
||||||
bio.bi_end_io = blkdev_bio_end_io_simple;
|
bio.bi_end_io = blkdev_bio_end_io_simple;
|
||||||
|
bio.bi_ioprio = iocb->ki_ioprio;
|
||||||
|
|
||||||
ret = bio_iov_iter_get_pages(&bio, iter);
|
ret = bio_iov_iter_get_pages(&bio, iter);
|
||||||
if (unlikely(ret))
|
if (unlikely(ret))
|
||||||
|
@ -355,6 +356,7 @@ __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, int nr_pages)
|
||||||
bio->bi_write_hint = iocb->ki_hint;
|
bio->bi_write_hint = iocb->ki_hint;
|
||||||
bio->bi_private = dio;
|
bio->bi_private = dio;
|
||||||
bio->bi_end_io = blkdev_bio_end_io;
|
bio->bi_end_io = blkdev_bio_end_io;
|
||||||
|
bio->bi_ioprio = iocb->ki_ioprio;
|
||||||
|
|
||||||
ret = bio_iov_iter_get_pages(bio, iter);
|
ret = bio_iov_iter_get_pages(bio, iter);
|
||||||
if (unlikely(ret)) {
|
if (unlikely(ret)) {
|
||||||
|
|
|
@ -1046,6 +1046,7 @@ iomap_dio_actor(struct inode *inode, loff_t pos, loff_t length,
|
||||||
bio_set_dev(bio, iomap->bdev);
|
bio_set_dev(bio, iomap->bdev);
|
||||||
bio->bi_iter.bi_sector = iomap_sector(iomap, pos);
|
bio->bi_iter.bi_sector = iomap_sector(iomap, pos);
|
||||||
bio->bi_write_hint = dio->iocb->ki_hint;
|
bio->bi_write_hint = dio->iocb->ki_hint;
|
||||||
|
bio->bi_ioprio = dio->iocb->ki_ioprio;
|
||||||
bio->bi_private = dio;
|
bio->bi_private = dio;
|
||||||
bio->bi_end_io = iomap_dio_bio_end_io;
|
bio->bi_end_io = iomap_dio_bio_end_io;
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include <linux/delayed_call.h>
|
#include <linux/delayed_call.h>
|
||||||
#include <linux/uuid.h>
|
#include <linux/uuid.h>
|
||||||
#include <linux/errseq.h>
|
#include <linux/errseq.h>
|
||||||
|
#include <linux/ioprio.h>
|
||||||
|
|
||||||
#include <asm/byteorder.h>
|
#include <asm/byteorder.h>
|
||||||
#include <uapi/linux/fs.h>
|
#include <uapi/linux/fs.h>
|
||||||
|
@ -299,7 +300,8 @@ struct kiocb {
|
||||||
void (*ki_complete)(struct kiocb *iocb, long ret, long ret2);
|
void (*ki_complete)(struct kiocb *iocb, long ret, long ret2);
|
||||||
void *private;
|
void *private;
|
||||||
int ki_flags;
|
int ki_flags;
|
||||||
enum rw_hint ki_hint;
|
u16 ki_hint;
|
||||||
|
u16 ki_ioprio; /* See linux/ioprio.h */
|
||||||
} __randomize_layout;
|
} __randomize_layout;
|
||||||
|
|
||||||
static inline bool is_sync_kiocb(struct kiocb *kiocb)
|
static inline bool is_sync_kiocb(struct kiocb *kiocb)
|
||||||
|
@ -1934,12 +1936,22 @@ static inline enum rw_hint file_write_hint(struct file *file)
|
||||||
|
|
||||||
static inline int iocb_flags(struct file *file);
|
static inline int iocb_flags(struct file *file);
|
||||||
|
|
||||||
|
static inline u16 ki_hint_validate(enum rw_hint hint)
|
||||||
|
{
|
||||||
|
typeof(((struct kiocb *)0)->ki_hint) max_hint = -1;
|
||||||
|
|
||||||
|
if (hint <= max_hint)
|
||||||
|
return hint;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void init_sync_kiocb(struct kiocb *kiocb, struct file *filp)
|
static inline void init_sync_kiocb(struct kiocb *kiocb, struct file *filp)
|
||||||
{
|
{
|
||||||
*kiocb = (struct kiocb) {
|
*kiocb = (struct kiocb) {
|
||||||
.ki_filp = filp,
|
.ki_filp = filp,
|
||||||
.ki_flags = iocb_flags(filp),
|
.ki_flags = iocb_flags(filp),
|
||||||
.ki_hint = file_write_hint(filp),
|
.ki_hint = ki_hint_validate(file_write_hint(filp)),
|
||||||
|
.ki_ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_NONE, 0),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,4 +77,13 @@ extern int ioprio_best(unsigned short aprio, unsigned short bprio);
|
||||||
|
|
||||||
extern int set_task_ioprio(struct task_struct *task, int ioprio);
|
extern int set_task_ioprio(struct task_struct *task, int ioprio);
|
||||||
|
|
||||||
|
#ifdef CONFIG_BLOCK
|
||||||
|
extern int ioprio_check_cap(int ioprio);
|
||||||
|
#else
|
||||||
|
static inline int ioprio_check_cap(int ioprio)
|
||||||
|
{
|
||||||
|
return -ENOTBLK;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_BLOCK */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -53,6 +53,7 @@ enum {
|
||||||
* is valid.
|
* is valid.
|
||||||
*/
|
*/
|
||||||
#define IOCB_FLAG_RESFD (1 << 0)
|
#define IOCB_FLAG_RESFD (1 << 0)
|
||||||
|
#define IOCB_FLAG_IOPRIO (1 << 1)
|
||||||
|
|
||||||
/* read() from /dev/aio returns these structures. */
|
/* read() from /dev/aio returns these structures. */
|
||||||
struct io_event {
|
struct io_event {
|
||||||
|
|
Loading…
Reference in New Issue