summaryrefslogtreecommitdiffstats
path: root/fs/aio.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/aio.c')
-rw-r--r--fs/aio.c28
1 files changed, 19 insertions, 9 deletions
diff --git a/fs/aio.c b/fs/aio.c
index 8a37dbbf3437..b74c567383bc 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -317,7 +317,7 @@ out:
/* wait_on_sync_kiocb:
* Waits on the given sync kiocb to complete.
*/
-ssize_t fastcall wait_on_sync_kiocb(struct kiocb *iocb)
+ssize_t wait_on_sync_kiocb(struct kiocb *iocb)
{
while (iocb->ki_users) {
set_current_state(TASK_UNINTERRUPTIBLE);
@@ -336,7 +336,7 @@ ssize_t fastcall wait_on_sync_kiocb(struct kiocb *iocb)
* go away, they will call put_ioctx and release any pinned memory
* associated with the request (held via struct page * references).
*/
-void fastcall exit_aio(struct mm_struct *mm)
+void exit_aio(struct mm_struct *mm)
{
struct kioctx *ctx = mm->ioctx_list;
mm->ioctx_list = NULL;
@@ -365,7 +365,7 @@ void fastcall exit_aio(struct mm_struct *mm)
* Called when the last user of an aio context has gone away,
* and the struct needs to be freed.
*/
-void fastcall __put_ioctx(struct kioctx *ctx)
+void __put_ioctx(struct kioctx *ctx)
{
unsigned nr_events = ctx->max_reqs;
@@ -397,8 +397,7 @@ void fastcall __put_ioctx(struct kioctx *ctx)
* This prevents races between the aio code path referencing the
* req (after submitting it) and aio_complete() freeing the req.
*/
-static struct kiocb *__aio_get_req(struct kioctx *ctx);
-static struct kiocb fastcall *__aio_get_req(struct kioctx *ctx)
+static struct kiocb *__aio_get_req(struct kioctx *ctx)
{
struct kiocb *req = NULL;
struct aio_ring *ring;
@@ -533,7 +532,7 @@ static int __aio_put_req(struct kioctx *ctx, struct kiocb *req)
* Returns true if this put was the last user of the kiocb,
* false if the request is still in use.
*/
-int fastcall aio_put_req(struct kiocb *req)
+int aio_put_req(struct kiocb *req)
{
struct kioctx *ctx = req->ki_ctx;
int ret;
@@ -893,7 +892,7 @@ static void try_queue_kicked_iocb(struct kiocb *iocb)
* The retry is usually executed by aio workqueue
* threads (See aio_kick_handler).
*/
-void fastcall kick_iocb(struct kiocb *iocb)
+void kick_iocb(struct kiocb *iocb)
{
/* sync iocbs are easy: they can only ever be executing from a
* single context. */
@@ -912,7 +911,7 @@ EXPORT_SYMBOL(kick_iocb);
* Returns true if this is the last user of the request. The
* only other user of the request can be the cancellation code.
*/
-int fastcall aio_complete(struct kiocb *iocb, long res, long res2)
+int aio_complete(struct kiocb *iocb, long res, long res2)
{
struct kioctx *ctx = iocb->ki_ctx;
struct aio_ring_info *info;
@@ -1330,6 +1329,10 @@ static ssize_t aio_rw_vect_retry(struct kiocb *iocb)
opcode = IOCB_CMD_PWRITEV;
}
+ /* This matches the pread()/pwrite() logic */
+ if (iocb->ki_pos < 0)
+ return -EINVAL;
+
do {
ret = rw_op(iocb, &iocb->ki_iovec[iocb->ki_cur_seg],
iocb->ki_nr_segs - iocb->ki_cur_seg,
@@ -1348,6 +1351,13 @@ static ssize_t aio_rw_vect_retry(struct kiocb *iocb)
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 (opcode == IOCB_CMD_PWRITEV
+ && ret < 0 && ret != -EIOCBQUEUED && ret != -EIOCBRETRY
+ && iocb->ki_nbytes - iocb->ki_left)
+ ret = iocb->ki_nbytes - iocb->ki_left;
+
return ret;
}
@@ -1523,7 +1533,7 @@ static int aio_wake_function(wait_queue_t *wait, unsigned mode,
return 1;
}
-int fastcall io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
+int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
struct iocb *iocb)
{
struct kiocb *req;