[AIO] introduce async sendmsg and recvmsg Introduce thread based async sendmsg and recvmsg functionality to allow socket using applications to pass flags like MSG_WAITALL into the network stack. Signed-off-by: Benjamin LaHaise diff -purN --exclude=description 862_net_vfsmsg/fs/aio.c 867_async_msg/fs/aio.c --- 862_net_vfsmsg/fs/aio.c 2005-08-17 13:46:58.000000000 -0400 +++ 867_async_msg/fs/aio.c 2005-08-17 13:47:02.000000000 -0400 @@ -30,6 +30,8 @@ #include #include #include +#include +#include #include #include @@ -1537,6 +1539,36 @@ static int aio_thread_write_fn(void *arg return 0; } +static int aio_thread_recvmsg_fn(void *arg) +{ + struct kiocb *iocb = arg; + long ret; + + set_fs(USER_DS); + use_mm(iocb->ki_ctx->mm); + ret = vfs_recvmsg(iocb->ki_filp->private_data, + (void __user *)iocb->ki_buf, iocb->ki_pos); + unuse_mm(iocb->ki_ctx->mm); + aio_complete(iocb, ret, 0); + + return 0; +} + +static int aio_thread_sendmsg_fn(void *arg) +{ + struct kiocb *iocb = arg; + long ret; + + set_fs(USER_DS); + use_mm(iocb->ki_ctx->mm); + ret = vfs_sendmsg(iocb->ki_filp->private_data, + (void __user *)iocb->ki_buf, iocb->ki_pos); + unuse_mm(iocb->ki_ctx->mm); + aio_complete(iocb, ret, 0); + + return 0; +} + static int aio_thread_rw_v_fn(void *arg) { struct kiocb *iocb = arg; @@ -1627,6 +1659,16 @@ static ssize_t aio_thread_fdsync(struct return aio_kernel_thread(iocb, aio_thread_fdsync_fn); } +static ssize_t aio_thread_sendmsg(struct kiocb *iocb) +{ + return aio_kernel_thread(iocb, aio_thread_sendmsg); +} + +static ssize_t aio_thread_recvmsg(struct kiocb *iocb) +{ + return aio_kernel_thread(iocb, aio_thread_recvmsg); +} + static ssize_t aio_fdsync(struct kiocb *iocb) { struct file *file = iocb->ki_filp; @@ -1747,6 +1789,18 @@ static ssize_t aio_setup_iocb(struct kio else if (file->f_op->fsync) kiocb->ki_retry = aio_thread_fsync; break; + case IOCB_CMD_SENDMSG: + ret = -EINVAL; + if (kiocb->ki_nbytes != sizeof(struct msghdr)) + break; + kiocb->ki_retry = aio_thread_thread_sendmsg; + break; + case IOCB_CMD_RECVMSG: + ret = -EINVAL; + if (kiocb->ki_nbytes != sizeof(struct msghdr)) + break; + kiocb->ki_retry = aio_thread_thread_recvmsg; + break; default: dprintk("EINVAL: io_submit: no operation provided\n"); ret = -EINVAL; diff -purN --exclude=description 862_net_vfsmsg/include/linux/aio_abi.h 867_async_msg/include/linux/aio_abi.h --- 862_net_vfsmsg/include/linux/aio_abi.h 2005-08-09 19:13:07.000000000 -0400 +++ 867_async_msg/include/linux/aio_abi.h 2005-08-16 15:56:32.000000000 -0400 @@ -43,6 +43,14 @@ enum { IOCB_CMD_NOOP = 6, IOCB_CMD_PREADV = 7, IOCB_CMD_PWRITEV = 8, + + /* For these network operations: + * aio_buf points to struct msghdr *, + * aio_nbytes is sizeof(struct msghdr) + * aio_offset is the flags value. + */ + IOCB_CMD_SENDMSG = 9, + IOCB_CMD_RECVMSG = 10, }; /* read() from /dev/aio returns these structures. */