[AIO] add thread based fallback for aio_{read,write}v Add thread based fallbacks for aio readv and writev operations. Signed-off-by: Benjamin LaHaise diff -purN --exclude=description 83_fix_refcounting/fs/aio.c 85_vectored_fallback/fs/aio.c --- 83_fix_refcounting/fs/aio.c 2005-08-17 13:46:57.000000000 -0400 +++ 85_vectored_fallback/fs/aio.c 2005-08-17 13:46:58.000000000 -0400 @@ -1537,6 +1537,30 @@ static int aio_thread_write_fn(void *arg return 0; } +static int aio_thread_rw_v_fn(void *arg) +{ + struct kiocb *iocb = arg; + long ret; + + set_fs(USER_DS); + use_mm(iocb->ki_ctx->mm); + + if (iocb->ki_opcode == IOCB_CMD_PREADV) + ret = vfs_readv(iocb->ki_filp, + &iocb->ki_iovec[iocb->ki_cur_seg], + iocb->ki_nr_segs - iocb->ki_cur_seg, + &iocb->ki_pos); + else + ret = vfs_writev(iocb->ki_filp, + &iocb->ki_iovec[iocb->ki_cur_seg], + iocb->ki_nr_segs - iocb->ki_cur_seg, + &iocb->ki_pos); + unuse_mm(iocb->ki_ctx->mm); + aio_complete(iocb, ret, 0); + + return 0; +} + static int aio_thread_fsync_fn(void *arg) { struct kiocb *iocb = arg; @@ -1578,11 +1602,21 @@ static ssize_t aio_thread_pread(struct k return aio_kernel_thread(iocb, aio_thread_read_fn); } +static ssize_t aio_thread_preadv(struct kiocb *iocb) +{ + return aio_kernel_thread(iocb, aio_thread_rw_v_fn); +} + static ssize_t aio_thread_pwrite(struct kiocb *iocb) { return aio_kernel_thread(iocb, aio_thread_write_fn); } +static ssize_t aio_thread_pwritev(struct kiocb *iocb) +{ + return aio_kernel_thread(iocb, aio_thread_rw_v_fn); +} + static ssize_t aio_thread_fsync(struct kiocb *iocb) { return aio_kernel_thread(iocb, aio_thread_fsync_fn); @@ -1683,6 +1717,8 @@ static ssize_t aio_setup_iocb(struct kio ret = EINVAL; if (file->f_op->aio_readv) kiocb->ki_retry = aio_rw_vect_retry; + else if (file->f_op->readv || file->f_op->read) + kiocb->ki_retry = aio_thread_preadv; break; case IOCB_CMD_PWRITEV: ret = -EBADF; @@ -1694,6 +1730,8 @@ static ssize_t aio_setup_iocb(struct kio ret = EINVAL; if (file->f_op->aio_writev) kiocb->ki_retry = aio_rw_vect_retry; + else if (file->f_op->writev || file->f_op->write) + kiocb->ki_retry = aio_thread_pwritev; break; case IOCB_CMD_FDSYNC: ret = -EINVAL;