Skip to content

Commit

Permalink
aio: Kill aio_rw_vect_retry()
Browse files Browse the repository at this point in the history
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: Kent Overstreet <[email protected]>
Cc: Zach Brown <[email protected]>
Cc: Felipe Balbi <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Cc: Mark Fasheh <[email protected]>
Cc: Joel Becker <[email protected]>
Cc: Rusty Russell <[email protected]>
Cc: Jens Axboe <[email protected]>
Cc: Asai Thambi S P <[email protected]>
Cc: Selvan Mani <[email protected]>
Cc: Sam Bradshaw <[email protected]>
Cc: Jeff Moyer <[email protected]>
Cc: Al Viro <[email protected]>
Cc: Benjamin LaHaise <[email protected]>
Signed-off-by: Benjamin LaHaise <[email protected]>
Kent Overstreet authored and bcrl committed Jul 30, 2013
1 parent 5ffac12 commit 73a7075
Showing 11 changed files with 28 additions and 90 deletions.
2 changes: 1 addition & 1 deletion drivers/staging/android/logger.c
Original file line number Diff line number Diff line change
@@ -481,7 +481,7 @@ static ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov,
header.sec = now.tv_sec;
header.nsec = now.tv_nsec;
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);

/* null writes succeed, return zero */
6 changes: 3 additions & 3 deletions drivers/usb/gadget/inode.c
Original file line number Diff line number Diff line change
@@ -708,11 +708,11 @@ ep_aio_read(struct kiocb *iocb, const struct iovec *iov,
if (unlikely(usb_endpoint_dir_in(&epdata->desc)))
return -EINVAL;

buf = kmalloc(iocb->ki_left, GFP_KERNEL);
buf = kmalloc(iocb->ki_nbytes, GFP_KERNEL);
if (unlikely(!buf))
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
@@ -727,7 +727,7 @@ ep_aio_write(struct kiocb *iocb, const struct iovec *iov,
if (unlikely(!usb_endpoint_dir_in(&epdata->desc)))
return -EINVAL;

buf = kmalloc(iocb->ki_left, GFP_KERNEL);
buf = kmalloc(iocb->ki_nbytes, GFP_KERNEL);
if (unlikely(!buf))
return -ENOMEM;

91 changes: 18 additions & 73 deletions fs/aio.c
Original file line number Diff line number Diff line change
@@ -707,7 +707,7 @@ static inline struct kiocb *aio_get_req(struct kioctx *ctx)
if (unlikely(!req))
goto out_put;

atomic_set(&req->ki_users, 2);
atomic_set(&req->ki_users, 1);
req->ki_ctx = ctx;
return req;
out_put:
@@ -1051,75 +1051,9 @@ SYSCALL_DEFINE1(io_destroy, aio_context_t, ctx)
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 *,
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)
{
ssize_t ret;
@@ -1204,9 +1138,22 @@ static ssize_t aio_run_iocb(struct kiocb *req, bool compat)
return 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;

case IOCB_CMD_FDSYNC:
@@ -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_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;

ret = aio_run_iocb(req, compat);
if (ret)
goto out_put_req;

aio_put_req(req); /* drop extra ref to req */
return 0;
out_put_req:
put_reqs_available(ctx, 1);
aio_put_req(req); /* drop extra ref to req */
aio_put_req(req); /* drop i/o ref to req */
aio_put_req(req);
return ret;
}

2 changes: 1 addition & 1 deletion fs/block_dev.c
Original file line number Diff line number Diff line change
@@ -1542,7 +1542,7 @@ static ssize_t blkdev_aio_read(struct kiocb *iocb, const struct iovec *iov,
return 0;

size -= pos;
if (size < iocb->ki_left)
if (size < iocb->ki_nbytes)
nr_segs = iov_shorten((struct iovec *)iov, nr_segs, size);
return generic_file_aio_read(iocb, iov, nr_segs, pos);
}
1 change: 0 additions & 1 deletion fs/nfs/direct.c
Original file line number Diff line number Diff line change
@@ -130,7 +130,6 @@ ssize_t nfs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, loff_

return -EINVAL;
#else
VM_BUG_ON(iocb->ki_left != PAGE_SIZE);
VM_BUG_ON(iocb->ki_nbytes != PAGE_SIZE);

if (rw == READ || rw == KERNEL_READ)
6 changes: 3 additions & 3 deletions fs/ocfs2/file.c
Original file line number Diff line number Diff line change
@@ -2245,7 +2245,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
file->f_path.dentry->d_name.name,
(unsigned int)nr_segs);

if (iocb->ki_left == 0)
if (iocb->ki_nbytes == 0)
return 0;

appending = file->f_flags & O_APPEND ? 1 : 0;
@@ -2296,15 +2296,15 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,

can_do_direct = direct_io;
ret = ocfs2_prepare_inode_for_write(file, ppos,
iocb->ki_left, appending,
iocb->ki_nbytes, appending,
&can_do_direct, &has_refcount);
if (ret < 0) {
mlog_errno(ret);
goto out;
}

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);

/*
3 changes: 0 additions & 3 deletions fs/read_write.c
Original file line number Diff line number Diff line change
@@ -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);
kiocb.ki_pos = *ppos;
kiocb.ki_left = len;
kiocb.ki_nbytes = len;

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

init_sync_kiocb(&kiocb, filp);
kiocb.ki_pos = *ppos;
kiocb.ki_left = len;
kiocb.ki_nbytes = len;

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,

init_sync_kiocb(&kiocb, filp);
kiocb.ki_pos = *ppos;
kiocb.ki_left = len;
kiocb.ki_nbytes = len;

ret = fn(&kiocb, iov, nr_segs, kiocb.ki_pos);
2 changes: 1 addition & 1 deletion fs/udf/file.c
Original file line number Diff line number Diff line change
@@ -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 inode *inode = file_inode(file);
int err, pos;
size_t count = iocb->ki_left;
size_t count = iocb->ki_nbytes;
struct udf_inode_info *iinfo = UDF_I(inode);

down_write(&iinfo->i_data_sem);
2 changes: 0 additions & 2 deletions include/linux/aio.h
Original file line number Diff line number Diff line change
@@ -50,11 +50,9 @@ struct kiocb {
unsigned short ki_opcode;
size_t ki_nbytes; /* copy of iocb->aio_nbytes */
char __user *ki_buf; /* remaining iocb->aio_buf */
size_t ki_left; /* remaining bytes */
struct iovec ki_inline_vec; /* inline vector */
struct iovec *ki_iovec;
unsigned long ki_nr_segs;
unsigned long ki_cur_seg;

struct list_head ki_list; /* the aio core uses this
* for cancellation */
1 change: 0 additions & 1 deletion mm/page_io.c
Original file line number Diff line number Diff line change
@@ -266,7 +266,6 @@ int __swap_writepage(struct page *page, struct writeback_control *wbc,

init_sync_kiocb(&kiocb, swap_file);
kiocb.ki_pos = page_file_offset(page);
kiocb.ki_left = PAGE_SIZE;
kiocb.ki_nbytes = PAGE_SIZE;

set_page_writeback(page);
2 changes: 1 addition & 1 deletion net/socket.c
Original file line number Diff line number Diff line change
@@ -931,7 +931,7 @@ static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
if (pos != 0)
return -ESPIPE;

if (iocb->ki_left == 0) /* Match SYS5 behaviour */
if (iocb->ki_nbytes == 0) /* Match SYS5 behaviour */
return 0;


0 comments on commit 73a7075

Please sign in to comment.