Commit 41003a7b authored by Zach Brown's avatar Zach Brown Committed by Linus Torvalds

aio: remove retry-based AIO

This removes the retry-based AIO infrastructure now that nothing in tree
is using it.

We want to remove retry-based AIO because it is fundemantally unsafe.
It retries IO submission from a kernel thread that has only assumed the
mm of the submitting task.  All other task_struct references in the IO
submission path will see the kernel thread, not the submitting task.
This design flaw means that nothing of any meaningful complexity can use
retry-based AIO.

This removes all the code and data associated with the retry machinery.
The most significant benefit of this is the removal of the locking
around the unused run list in the submission path.

[akpm@linux-foundation.org: coding-style fixes]
Signed-off-by: default avatarKent Overstreet <koverstreet@google.com>
Signed-off-by: default avatarZach Brown <zab@redhat.com>
Cc: Zach Brown <zab@redhat.com>
Cc: Felipe Balbi <balbi@ti.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Mark Fasheh <mfasheh@suse.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Asai Thambi S P <asamymuthupa@micron.com>
Cc: Selvan Mani <smani@micron.com>
Cc: Sam Bradshaw <sbradshaw@micron.com>
Acked-by: default avatarJeff Moyer <jmoyer@redhat.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Benjamin LaHaise <bcrl@kvack.org>
Reviewed-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent a80bf61e
This diff is collapsed.
...@@ -2322,7 +2322,7 @@ int ocfs2_inode_lock_full_nested(struct inode *inode, ...@@ -2322,7 +2322,7 @@ int ocfs2_inode_lock_full_nested(struct inode *inode,
status = __ocfs2_cluster_lock(osb, lockres, level, dlm_flags, status = __ocfs2_cluster_lock(osb, lockres, level, dlm_flags,
arg_flags, subclass, _RET_IP_); arg_flags, subclass, _RET_IP_);
if (status < 0) { if (status < 0) {
if (status != -EAGAIN && status != -EIOCBRETRY) if (status != -EAGAIN)
mlog_errno(status); mlog_errno(status);
goto bail; goto bail;
} }
......
...@@ -329,16 +329,6 @@ int rw_verify_area(int read_write, struct file *file, loff_t *ppos, size_t count ...@@ -329,16 +329,6 @@ int rw_verify_area(int read_write, struct file *file, loff_t *ppos, size_t count
return count > MAX_RW_COUNT ? MAX_RW_COUNT : count; return count > MAX_RW_COUNT ? MAX_RW_COUNT : count;
} }
static void wait_on_retry_sync_kiocb(struct kiocb *iocb)
{
set_current_state(TASK_UNINTERRUPTIBLE);
if (!kiocbIsKicked(iocb))
schedule();
else
kiocbClearKicked(iocb);
__set_current_state(TASK_RUNNING);
}
ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos) ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
{ {
struct iovec iov = { .iov_base = buf, .iov_len = len }; struct iovec iov = { .iov_base = buf, .iov_len = len };
...@@ -350,13 +340,7 @@ ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *pp ...@@ -350,13 +340,7 @@ ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *pp
kiocb.ki_left = len; kiocb.ki_left = len;
kiocb.ki_nbytes = len; kiocb.ki_nbytes = len;
for (;;) { ret = filp->f_op->aio_read(&kiocb, &iov, 1, kiocb.ki_pos);
ret = filp->f_op->aio_read(&kiocb, &iov, 1, kiocb.ki_pos);
if (ret != -EIOCBRETRY)
break;
wait_on_retry_sync_kiocb(&kiocb);
}
if (-EIOCBQUEUED == ret) if (-EIOCBQUEUED == ret)
ret = wait_on_sync_kiocb(&kiocb); ret = wait_on_sync_kiocb(&kiocb);
*ppos = kiocb.ki_pos; *ppos = kiocb.ki_pos;
...@@ -406,13 +390,7 @@ ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, lof ...@@ -406,13 +390,7 @@ ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, lof
kiocb.ki_left = len; kiocb.ki_left = len;
kiocb.ki_nbytes = len; kiocb.ki_nbytes = len;
for (;;) { ret = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos);
ret = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos);
if (ret != -EIOCBRETRY)
break;
wait_on_retry_sync_kiocb(&kiocb);
}
if (-EIOCBQUEUED == ret) if (-EIOCBQUEUED == ret)
ret = wait_on_sync_kiocb(&kiocb); ret = wait_on_sync_kiocb(&kiocb);
*ppos = kiocb.ki_pos; *ppos = kiocb.ki_pos;
...@@ -592,13 +570,7 @@ static ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov, ...@@ -592,13 +570,7 @@ static ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov,
kiocb.ki_left = len; kiocb.ki_left = len;
kiocb.ki_nbytes = len; kiocb.ki_nbytes = len;
for (;;) { ret = fn(&kiocb, iov, nr_segs, kiocb.ki_pos);
ret = fn(&kiocb, iov, nr_segs, kiocb.ki_pos);
if (ret != -EIOCBRETRY)
break;
wait_on_retry_sync_kiocb(&kiocb);
}
if (ret == -EIOCBQUEUED) if (ret == -EIOCBQUEUED)
ret = wait_on_sync_kiocb(&kiocb); ret = wait_on_sync_kiocb(&kiocb);
*ppos = kiocb.ki_pos; *ppos = kiocb.ki_pos;
......
...@@ -14,18 +14,12 @@ struct kioctx; ...@@ -14,18 +14,12 @@ struct kioctx;
#define KIOCB_SYNC_KEY (~0U) #define KIOCB_SYNC_KEY (~0U)
/* ki_flags bits */ /* ki_flags bits */
#define KIF_KICKED 1
#define KIF_CANCELLED 2 #define KIF_CANCELLED 2
#define kiocbTryKick(iocb) test_and_set_bit(KIF_KICKED, &(iocb)->ki_flags)
#define kiocbSetKicked(iocb) set_bit(KIF_KICKED, &(iocb)->ki_flags)
#define kiocbSetCancelled(iocb) set_bit(KIF_CANCELLED, &(iocb)->ki_flags) #define kiocbSetCancelled(iocb) set_bit(KIF_CANCELLED, &(iocb)->ki_flags)
#define kiocbClearKicked(iocb) clear_bit(KIF_KICKED, &(iocb)->ki_flags)
#define kiocbClearCancelled(iocb) clear_bit(KIF_CANCELLED, &(iocb)->ki_flags) #define kiocbClearCancelled(iocb) clear_bit(KIF_CANCELLED, &(iocb)->ki_flags)
#define kiocbIsKicked(iocb) test_bit(KIF_KICKED, &(iocb)->ki_flags)
#define kiocbIsCancelled(iocb) test_bit(KIF_CANCELLED, &(iocb)->ki_flags) #define kiocbIsCancelled(iocb) test_bit(KIF_CANCELLED, &(iocb)->ki_flags)
/* is there a better place to document function pointer methods? */ /* is there a better place to document function pointer methods? */
...@@ -52,18 +46,8 @@ struct kioctx; ...@@ -52,18 +46,8 @@ struct kioctx;
* not ask the method again -- ki_retry must ensure forward progress. * not ask the method again -- ki_retry must ensure forward progress.
* aio_complete() must be called once and only once in the future, multiple * aio_complete() must be called once and only once in the future, multiple
* calls may result in undefined behaviour. * calls may result in undefined behaviour.
*
* If ki_retry returns -EIOCBRETRY it has made a promise that kick_iocb()
* will be called on the kiocb pointer in the future. This may happen
* through generic helpers that associate kiocb->ki_wait with a wait
* queue head that ki_retry uses via current->io_wait. It can also happen
* with custom tracking and manual calls to kick_iocb(), though that is
* discouraged. In either case, kick_iocb() must be called once and only
* once. ki_retry must ensure forward progress, the AIO core will wait
* indefinitely for kick_iocb() to be called.
*/ */
struct kiocb { struct kiocb {
struct list_head ki_run_list;
unsigned long ki_flags; unsigned long ki_flags;
int ki_users; int ki_users;
unsigned ki_key; /* id of this request */ unsigned ki_key; /* id of this request */
...@@ -160,7 +144,6 @@ static inline unsigned aio_ring_avail(struct aio_ring_info *info, ...@@ -160,7 +144,6 @@ static inline unsigned aio_ring_avail(struct aio_ring_info *info,
struct kioctx { struct kioctx {
atomic_t users; atomic_t users;
int dead; int dead;
struct mm_struct *mm;
/* This needs improving */ /* This needs improving */
unsigned long user_id; unsigned long user_id;
...@@ -172,15 +155,12 @@ struct kioctx { ...@@ -172,15 +155,12 @@ struct kioctx {
int reqs_active; int reqs_active;
struct list_head active_reqs; /* used for cancellation */ struct list_head active_reqs; /* used for cancellation */
struct list_head run_list; /* used for kicked reqs */
/* sys_io_setup currently limits this to an unsigned int */ /* sys_io_setup currently limits this to an unsigned int */
unsigned max_reqs; unsigned max_reqs;
struct aio_ring_info ring_info; struct aio_ring_info ring_info;
struct delayed_work wq;
struct rcu_head rcu_head; struct rcu_head rcu_head;
}; };
...@@ -188,7 +168,6 @@ struct kioctx { ...@@ -188,7 +168,6 @@ struct kioctx {
#ifdef CONFIG_AIO #ifdef CONFIG_AIO
extern ssize_t wait_on_sync_kiocb(struct kiocb *iocb); extern ssize_t wait_on_sync_kiocb(struct kiocb *iocb);
extern int aio_put_req(struct kiocb *iocb); extern int aio_put_req(struct kiocb *iocb);
extern void kick_iocb(struct kiocb *iocb);
extern int aio_complete(struct kiocb *iocb, long res, long res2); extern int aio_complete(struct kiocb *iocb, long res, long res2);
struct mm_struct; struct mm_struct;
extern void exit_aio(struct mm_struct *mm); extern void exit_aio(struct mm_struct *mm);
...@@ -197,7 +176,6 @@ extern long do_io_submit(aio_context_t ctx_id, long nr, ...@@ -197,7 +176,6 @@ extern long do_io_submit(aio_context_t ctx_id, long nr,
#else #else
static inline ssize_t wait_on_sync_kiocb(struct kiocb *iocb) { return 0; } static inline ssize_t wait_on_sync_kiocb(struct kiocb *iocb) { return 0; }
static inline int aio_put_req(struct kiocb *iocb) { return 0; } static inline int aio_put_req(struct kiocb *iocb) { return 0; }
static inline void kick_iocb(struct kiocb *iocb) { }
static inline int aio_complete(struct kiocb *iocb, long res, long res2) { return 0; } static inline int aio_complete(struct kiocb *iocb, long res, long res2) { return 0; }
struct mm_struct; struct mm_struct;
static inline void exit_aio(struct mm_struct *mm) { } static inline void exit_aio(struct mm_struct *mm) { }
......
...@@ -28,6 +28,5 @@ ...@@ -28,6 +28,5 @@
#define EBADTYPE 527 /* Type not supported by server */ #define EBADTYPE 527 /* Type not supported by server */
#define EJUKEBOX 528 /* Request initiated, but will not complete before timeout */ #define EJUKEBOX 528 /* Request initiated, but will not complete before timeout */
#define EIOCBQUEUED 529 /* iocb queued, will get completion event */ #define EIOCBQUEUED 529 /* iocb queued, will get completion event */
#define EIOCBRETRY 530 /* iocb queued, will trigger a retry */
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment