Commit 73a7075e authored by Kent Overstreet's avatar Kent Overstreet Committed by Benjamin LaHaise

aio: Kill aio_rw_vect_retry()

This code doesn't serve any purpose anymore, since the aio retry
infrastructure has been removed.

This change should be safe because aio_read/write are also used for
synchronous IO, and called from do_sync_read()/do_sync_write() - and
there's no looping done in the sync case (the read and write syscalls).
Signed-off-by: default avatarKent Overstreet <koverstreet@google.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>
Cc: Jeff Moyer <jmoyer@redhat.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Benjamin LaHaise <bcrl@kvack.org>
Signed-off-by: default avatarBenjamin LaHaise <bcrl@kvack.org>
parent 5ffac122
...@@ -481,7 +481,7 @@ static ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov, ...@@ -481,7 +481,7 @@ static ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov,
header.sec = now.tv_sec; header.sec = now.tv_sec;
header.nsec = now.tv_nsec; header.nsec = now.tv_nsec;
header.euid = current_euid(); header.euid = current_euid();
header.len = min_t(size_t, iocb->ki_left, LOGGER_ENTRY_MAX_PAYLOAD); header.len = min_t(size_t, iocb->ki_nbytes, LOGGER_ENTRY_MAX_PAYLOAD);
header.hdr_size = sizeof(struct logger_entry); header.hdr_size = sizeof(struct logger_entry);
/* null writes succeed, return zero */ /* null writes succeed, return zero */
......
...@@ -708,11 +708,11 @@ ep_aio_read(struct kiocb *iocb, const struct iovec *iov, ...@@ -708,11 +708,11 @@ ep_aio_read(struct kiocb *iocb, const struct iovec *iov,
if (unlikely(usb_endpoint_dir_in(&epdata->desc))) if (unlikely(usb_endpoint_dir_in(&epdata->desc)))
return -EINVAL; return -EINVAL;
buf = kmalloc(iocb->ki_left, GFP_KERNEL); buf = kmalloc(iocb->ki_nbytes, GFP_KERNEL);
if (unlikely(!buf)) if (unlikely(!buf))
return -ENOMEM; return -ENOMEM;
return ep_aio_rwtail(iocb, buf, iocb->ki_left, epdata, iov, nr_segs); return ep_aio_rwtail(iocb, buf, iocb->ki_nbytes, epdata, iov, nr_segs);
} }
static ssize_t static ssize_t
...@@ -727,7 +727,7 @@ ep_aio_write(struct kiocb *iocb, const struct iovec *iov, ...@@ -727,7 +727,7 @@ ep_aio_write(struct kiocb *iocb, const struct iovec *iov,
if (unlikely(!usb_endpoint_dir_in(&epdata->desc))) if (unlikely(!usb_endpoint_dir_in(&epdata->desc)))
return -EINVAL; return -EINVAL;
buf = kmalloc(iocb->ki_left, GFP_KERNEL); buf = kmalloc(iocb->ki_nbytes, GFP_KERNEL);
if (unlikely(!buf)) if (unlikely(!buf))
return -ENOMEM; return -ENOMEM;
......
...@@ -707,7 +707,7 @@ static inline struct kiocb *aio_get_req(struct kioctx *ctx) ...@@ -707,7 +707,7 @@ static inline struct kiocb *aio_get_req(struct kioctx *ctx)
if (unlikely(!req)) if (unlikely(!req))
goto out_put; goto out_put;
atomic_set(&req->ki_users, 2); atomic_set(&req->ki_users, 1);
req->ki_ctx = ctx; req->ki_ctx = ctx;
return req; return req;
out_put: out_put:
...@@ -1051,75 +1051,9 @@ SYSCALL_DEFINE1(io_destroy, aio_context_t, ctx) ...@@ -1051,75 +1051,9 @@ SYSCALL_DEFINE1(io_destroy, aio_context_t, ctx)
return -EINVAL; return -EINVAL;
} }
static void aio_advance_iovec(struct kiocb *iocb, ssize_t ret)
{
struct iovec *iov = &iocb->ki_iovec[iocb->ki_cur_seg];
BUG_ON(ret <= 0);
while (iocb->ki_cur_seg < iocb->ki_nr_segs && ret > 0) {
ssize_t this = min((ssize_t)iov->iov_len, ret);
iov->iov_base += this;
iov->iov_len -= this;
iocb->ki_left -= this;
ret -= this;
if (iov->iov_len == 0) {
iocb->ki_cur_seg++;
iov++;
}
}
/* the caller should not have done more io than what fit in
* the remaining iovecs */
BUG_ON(ret > 0 && iocb->ki_left == 0);
}
typedef ssize_t (aio_rw_op)(struct kiocb *, const struct iovec *, typedef ssize_t (aio_rw_op)(struct kiocb *, const struct iovec *,
unsigned long, loff_t); unsigned long, loff_t);
static ssize_t aio_rw_vect_retry(struct kiocb *iocb, int rw, aio_rw_op *rw_op)
{
struct file *file = iocb->ki_filp;
struct address_space *mapping = file->f_mapping;
struct inode *inode = mapping->host;
ssize_t ret = 0;
/* This matches the pread()/pwrite() logic */
if (iocb->ki_pos < 0)
return -EINVAL;
if (rw == WRITE)
file_start_write(file);
do {
ret = rw_op(iocb, &iocb->ki_iovec[iocb->ki_cur_seg],
iocb->ki_nr_segs - iocb->ki_cur_seg,
iocb->ki_pos);
if (ret > 0)
aio_advance_iovec(iocb, ret);
/* retry all partial writes. retry partial reads as long as its a
* regular file. */
} while (ret > 0 && iocb->ki_left > 0 &&
(rw == WRITE ||
(!S_ISFIFO(inode->i_mode) && !S_ISSOCK(inode->i_mode))));
if (rw == WRITE)
file_end_write(file);
/* This means we must have transferred all that we could */
/* No need to retry anymore */
if ((ret == 0) || (iocb->ki_left == 0))
ret = iocb->ki_nbytes - iocb->ki_left;
/* If we managed to write some out we return that, rather than
* the eventual error. */
if (rw == WRITE
&& ret < 0 && ret != -EIOCBQUEUED
&& iocb->ki_nbytes - iocb->ki_left)
ret = iocb->ki_nbytes - iocb->ki_left;
return ret;
}
static ssize_t aio_setup_vectored_rw(int rw, struct kiocb *kiocb, bool compat) static ssize_t aio_setup_vectored_rw(int rw, struct kiocb *kiocb, bool compat)
{ {
ssize_t ret; ssize_t ret;
...@@ -1204,9 +1138,22 @@ static ssize_t aio_run_iocb(struct kiocb *req, bool compat) ...@@ -1204,9 +1138,22 @@ static ssize_t aio_run_iocb(struct kiocb *req, bool compat)
return ret; return ret;
req->ki_nbytes = ret; req->ki_nbytes = ret;
req->ki_left = ret;
ret = aio_rw_vect_retry(req, rw, rw_op); /* XXX: move/kill - rw_verify_area()? */
/* This matches the pread()/pwrite() logic */
if (req->ki_pos < 0) {
ret = -EINVAL;
break;
}
if (rw == WRITE)
file_start_write(file);
ret = rw_op(req, req->ki_iovec,
req->ki_nr_segs, req->ki_pos);
if (rw == WRITE)
file_end_write(file);
break; break;
case IOCB_CMD_FDSYNC: case IOCB_CMD_FDSYNC:
...@@ -1301,19 +1248,17 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, ...@@ -1301,19 +1248,17 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
req->ki_pos = iocb->aio_offset; req->ki_pos = iocb->aio_offset;
req->ki_buf = (char __user *)(unsigned long)iocb->aio_buf; req->ki_buf = (char __user *)(unsigned long)iocb->aio_buf;
req->ki_left = req->ki_nbytes = iocb->aio_nbytes; req->ki_nbytes = iocb->aio_nbytes;
req->ki_opcode = iocb->aio_lio_opcode; req->ki_opcode = iocb->aio_lio_opcode;
ret = aio_run_iocb(req, compat); ret = aio_run_iocb(req, compat);
if (ret) if (ret)
goto out_put_req; goto out_put_req;
aio_put_req(req); /* drop extra ref to req */
return 0; return 0;
out_put_req: out_put_req:
put_reqs_available(ctx, 1); put_reqs_available(ctx, 1);
aio_put_req(req); /* drop extra ref to req */ aio_put_req(req);
aio_put_req(req); /* drop i/o ref to req */
return ret; return ret;
} }
......
...@@ -1542,7 +1542,7 @@ static ssize_t blkdev_aio_read(struct kiocb *iocb, const struct iovec *iov, ...@@ -1542,7 +1542,7 @@ static ssize_t blkdev_aio_read(struct kiocb *iocb, const struct iovec *iov,
return 0; return 0;
size -= pos; size -= pos;
if (size < iocb->ki_left) if (size < iocb->ki_nbytes)
nr_segs = iov_shorten((struct iovec *)iov, nr_segs, size); nr_segs = iov_shorten((struct iovec *)iov, nr_segs, size);
return generic_file_aio_read(iocb, iov, nr_segs, pos); return generic_file_aio_read(iocb, iov, nr_segs, pos);
} }
......
...@@ -130,7 +130,6 @@ ssize_t nfs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, loff_ ...@@ -130,7 +130,6 @@ ssize_t nfs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, loff_
return -EINVAL; return -EINVAL;
#else #else
VM_BUG_ON(iocb->ki_left != PAGE_SIZE);
VM_BUG_ON(iocb->ki_nbytes != PAGE_SIZE); VM_BUG_ON(iocb->ki_nbytes != PAGE_SIZE);
if (rw == READ || rw == KERNEL_READ) if (rw == READ || rw == KERNEL_READ)
......
...@@ -2245,7 +2245,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, ...@@ -2245,7 +2245,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
file->f_path.dentry->d_name.name, file->f_path.dentry->d_name.name,
(unsigned int)nr_segs); (unsigned int)nr_segs);
if (iocb->ki_left == 0) if (iocb->ki_nbytes == 0)
return 0; return 0;
appending = file->f_flags & O_APPEND ? 1 : 0; appending = file->f_flags & O_APPEND ? 1 : 0;
...@@ -2296,7 +2296,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, ...@@ -2296,7 +2296,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
can_do_direct = direct_io; can_do_direct = direct_io;
ret = ocfs2_prepare_inode_for_write(file, ppos, ret = ocfs2_prepare_inode_for_write(file, ppos,
iocb->ki_left, appending, iocb->ki_nbytes, appending,
&can_do_direct, &has_refcount); &can_do_direct, &has_refcount);
if (ret < 0) { if (ret < 0) {
mlog_errno(ret); mlog_errno(ret);
...@@ -2304,7 +2304,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, ...@@ -2304,7 +2304,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
} }
if (direct_io && !is_sync_kiocb(iocb)) if (direct_io && !is_sync_kiocb(iocb))
unaligned_dio = ocfs2_is_io_unaligned(inode, iocb->ki_left, unaligned_dio = ocfs2_is_io_unaligned(inode, iocb->ki_nbytes,
*ppos); *ppos);
/* /*
......
...@@ -367,7 +367,6 @@ ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *pp ...@@ -367,7 +367,6 @@ ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *pp
init_sync_kiocb(&kiocb, filp); init_sync_kiocb(&kiocb, filp);
kiocb.ki_pos = *ppos; kiocb.ki_pos = *ppos;
kiocb.ki_left = len;
kiocb.ki_nbytes = len; kiocb.ki_nbytes = len;
ret = filp->f_op->aio_read(&kiocb, &iov, 1, kiocb.ki_pos); ret = filp->f_op->aio_read(&kiocb, &iov, 1, kiocb.ki_pos);
...@@ -417,7 +416,6 @@ ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, lof ...@@ -417,7 +416,6 @@ ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, lof
init_sync_kiocb(&kiocb, filp); init_sync_kiocb(&kiocb, filp);
kiocb.ki_pos = *ppos; kiocb.ki_pos = *ppos;
kiocb.ki_left = len;
kiocb.ki_nbytes = len; kiocb.ki_nbytes = len;
ret = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos); ret = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos);
...@@ -599,7 +597,6 @@ static ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov, ...@@ -599,7 +597,6 @@ static ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov,
init_sync_kiocb(&kiocb, filp); init_sync_kiocb(&kiocb, filp);
kiocb.ki_pos = *ppos; kiocb.ki_pos = *ppos;
kiocb.ki_left = len;
kiocb.ki_nbytes = len; kiocb.ki_nbytes = len;
ret = fn(&kiocb, iov, nr_segs, kiocb.ki_pos); ret = fn(&kiocb, iov, nr_segs, kiocb.ki_pos);
......
...@@ -141,7 +141,7 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, ...@@ -141,7 +141,7 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
struct file *file = iocb->ki_filp; struct file *file = iocb->ki_filp;
struct inode *inode = file_inode(file); struct inode *inode = file_inode(file);
int err, pos; int err, pos;
size_t count = iocb->ki_left; size_t count = iocb->ki_nbytes;
struct udf_inode_info *iinfo = UDF_I(inode); struct udf_inode_info *iinfo = UDF_I(inode);
down_write(&iinfo->i_data_sem); down_write(&iinfo->i_data_sem);
......
...@@ -50,11 +50,9 @@ struct kiocb { ...@@ -50,11 +50,9 @@ struct kiocb {
unsigned short ki_opcode; unsigned short ki_opcode;
size_t ki_nbytes; /* copy of iocb->aio_nbytes */ size_t ki_nbytes; /* copy of iocb->aio_nbytes */
char __user *ki_buf; /* remaining iocb->aio_buf */ char __user *ki_buf; /* remaining iocb->aio_buf */
size_t ki_left; /* remaining bytes */
struct iovec ki_inline_vec; /* inline vector */ struct iovec ki_inline_vec; /* inline vector */
struct iovec *ki_iovec; struct iovec *ki_iovec;
unsigned long ki_nr_segs; unsigned long ki_nr_segs;
unsigned long ki_cur_seg;
struct list_head ki_list; /* the aio core uses this struct list_head ki_list; /* the aio core uses this
* for cancellation */ * for cancellation */
......
...@@ -266,7 +266,6 @@ int __swap_writepage(struct page *page, struct writeback_control *wbc, ...@@ -266,7 +266,6 @@ int __swap_writepage(struct page *page, struct writeback_control *wbc,
init_sync_kiocb(&kiocb, swap_file); init_sync_kiocb(&kiocb, swap_file);
kiocb.ki_pos = page_file_offset(page); kiocb.ki_pos = page_file_offset(page);
kiocb.ki_left = PAGE_SIZE;
kiocb.ki_nbytes = PAGE_SIZE; kiocb.ki_nbytes = PAGE_SIZE;
set_page_writeback(page); set_page_writeback(page);
......
...@@ -931,7 +931,7 @@ static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov, ...@@ -931,7 +931,7 @@ static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
if (pos != 0) if (pos != 0)
return -ESPIPE; return -ESPIPE;
if (iocb->ki_left == 0) /* Match SYS5 behaviour */ if (iocb->ki_nbytes == 0) /* Match SYS5 behaviour */
return 0; return 0;
......
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