Merge branch 'iocb' into for-davem
trivial conflict in net/socket.c and non-trivial one in crypto - that one had evaded aio_complete() removal. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Коммит
237dae8890
|
@ -21,7 +21,7 @@
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
#include <linux/mount.h>
|
#include <linux/mount.h>
|
||||||
#include <linux/aio.h>
|
#include <linux/uio.h>
|
||||||
#include <asm/ebcdic.h>
|
#include <asm/ebcdic.h>
|
||||||
#include "hypfs.h"
|
#include "hypfs.h"
|
||||||
|
|
||||||
|
|
|
@ -106,7 +106,7 @@ static void skcipher_async_cb(struct crypto_async_request *req, int err)
|
||||||
atomic_dec(&ctx->inflight);
|
atomic_dec(&ctx->inflight);
|
||||||
skcipher_free_async_sgls(sreq);
|
skcipher_free_async_sgls(sreq);
|
||||||
kfree(req);
|
kfree(req);
|
||||||
aio_complete(iocb, err, err);
|
iocb->ki_complete(iocb, err, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int skcipher_sndbuf(struct sock *sk)
|
static inline int skcipher_sndbuf(struct sock *sk)
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
#include <linux/pfn.h>
|
#include <linux/pfn.h>
|
||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/aio.h>
|
#include <linux/uio.h>
|
||||||
|
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
#include <linux/types.h> /* size_t */
|
#include <linux/types.h> /* size_t */
|
||||||
#include <linux/proc_fs.h>
|
#include <linux/proc_fs.h>
|
||||||
#include <linux/fcntl.h> /* O_ACCMODE */
|
#include <linux/fcntl.h> /* O_ACCMODE */
|
||||||
#include <linux/aio.h>
|
|
||||||
#include <linux/pagemap.h>
|
#include <linux/pagemap.h>
|
||||||
#include <linux/hugetlb.h>
|
#include <linux/hugetlb.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
|
|
|
@ -40,7 +40,6 @@
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/highmem.h>
|
#include <linux/highmem.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/aio.h>
|
|
||||||
#include <linux/jiffies.h>
|
#include <linux/jiffies.h>
|
||||||
#include <linux/cpu.h>
|
#include <linux/cpu.h>
|
||||||
#include <asm/pgtable.h>
|
#include <asm/pgtable.h>
|
||||||
|
|
|
@ -39,7 +39,6 @@
|
||||||
#include <linux/vmalloc.h>
|
#include <linux/vmalloc.h>
|
||||||
#include <linux/highmem.h>
|
#include <linux/highmem.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/aio.h>
|
|
||||||
#include <linux/jiffies.h>
|
#include <linux/jiffies.h>
|
||||||
#include <asm/pgtable.h>
|
#include <asm/pgtable.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/fcntl.h>
|
#include <linux/fcntl.h>
|
||||||
#include <linux/aio.h>
|
|
||||||
#include <linux/ioctl.h>
|
#include <linux/ioctl.h>
|
||||||
#include <linux/cdev.h>
|
#include <linux/cdev.h>
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/fcntl.h>
|
#include <linux/fcntl.h>
|
||||||
#include <linux/aio.h>
|
|
||||||
#include <linux/poll.h>
|
#include <linux/poll.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/ioctl.h>
|
#include <linux/ioctl.h>
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/fcntl.h>
|
#include <linux/fcntl.h>
|
||||||
#include <linux/aio.h>
|
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <linux/poll.h>
|
#include <linux/poll.h>
|
||||||
#include <linux/ioctl.h>
|
#include <linux/ioctl.h>
|
||||||
|
|
|
@ -33,7 +33,6 @@ static int sg_version_num = 30536; /* 2 digits for each component */
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
#include <linux/aio.h>
|
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/mtio.h>
|
#include <linux/mtio.h>
|
||||||
#include <linux/ioctl.h>
|
#include <linux/ioctl.h>
|
||||||
|
@ -51,6 +50,7 @@ static int sg_version_num = 30536; /* 2 digits for each component */
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
#include <linux/atomic.h>
|
#include <linux/atomic.h>
|
||||||
#include <linux/ratelimit.h>
|
#include <linux/ratelimit.h>
|
||||||
|
#include <linux/uio.h>
|
||||||
|
|
||||||
#include "scsi.h"
|
#include "scsi.h"
|
||||||
#include <scsi/scsi_dbg.h>
|
#include <scsi/scsi_dbg.h>
|
||||||
|
|
|
@ -46,7 +46,6 @@
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/moduleparam.h>
|
#include <linux/moduleparam.h>
|
||||||
#include <linux/fcntl.h>
|
#include <linux/fcntl.h>
|
||||||
#include <linux/aio.h>
|
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
#include <linux/kthread.h>
|
#include <linux/kthread.h>
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
#include <linux/hid.h>
|
#include <linux/hid.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/uio.h>
|
||||||
#include <asm/unaligned.h>
|
#include <asm/unaligned.h>
|
||||||
|
|
||||||
#include <linux/usb/composite.h>
|
#include <linux/usb/composite.h>
|
||||||
|
@ -655,9 +656,10 @@ static void ffs_user_copy_worker(struct work_struct *work)
|
||||||
unuse_mm(io_data->mm);
|
unuse_mm(io_data->mm);
|
||||||
}
|
}
|
||||||
|
|
||||||
aio_complete(io_data->kiocb, ret, ret);
|
io_data->kiocb->ki_complete(io_data->kiocb, ret, ret);
|
||||||
|
|
||||||
if (io_data->ffs->ffs_eventfd && !io_data->kiocb->ki_eventfd)
|
if (io_data->ffs->ffs_eventfd &&
|
||||||
|
!(io_data->kiocb->ki_flags & IOCB_EVENTFD))
|
||||||
eventfd_signal(io_data->ffs->ffs_eventfd, 1);
|
eventfd_signal(io_data->ffs->ffs_eventfd, 1);
|
||||||
|
|
||||||
usb_ep_free_request(io_data->ep, io_data->req);
|
usb_ep_free_request(io_data->ep, io_data->req);
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <linux/poll.h>
|
#include <linux/poll.h>
|
||||||
#include <linux/mmu_context.h>
|
#include <linux/mmu_context.h>
|
||||||
#include <linux/aio.h>
|
#include <linux/aio.h>
|
||||||
|
#include <linux/uio.h>
|
||||||
|
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/moduleparam.h>
|
#include <linux/moduleparam.h>
|
||||||
|
@ -469,7 +470,7 @@ static void ep_user_copy_worker(struct work_struct *work)
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
|
|
||||||
/* completing the iocb can drop the ctx and mm, don't touch mm after */
|
/* completing the iocb can drop the ctx and mm, don't touch mm after */
|
||||||
aio_complete(iocb, ret, ret);
|
iocb->ki_complete(iocb, ret, ret);
|
||||||
|
|
||||||
kfree(priv->buf);
|
kfree(priv->buf);
|
||||||
kfree(priv->to_free);
|
kfree(priv->to_free);
|
||||||
|
@ -497,7 +498,8 @@ static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req)
|
||||||
kfree(priv);
|
kfree(priv);
|
||||||
iocb->private = NULL;
|
iocb->private = NULL;
|
||||||
/* aio_complete() reports bytes-transferred _and_ faults */
|
/* aio_complete() reports bytes-transferred _and_ faults */
|
||||||
aio_complete(iocb, req->actual ? req->actual : req->status,
|
|
||||||
|
iocb->ki_complete(iocb, req->actual ? req->actual : req->status,
|
||||||
req->status);
|
req->status);
|
||||||
} else {
|
} else {
|
||||||
/* ep_copy_to_user() won't report both; we hide some faults */
|
/* ep_copy_to_user() won't report both; we hide some faults */
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
#include <linux/pagemap.h>
|
#include <linux/pagemap.h>
|
||||||
#include <linux/idr.h>
|
#include <linux/idr.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/aio.h>
|
#include <linux/uio.h>
|
||||||
#include <net/9p/9p.h>
|
#include <net/9p/9p.h>
|
||||||
#include <net/9p/client.h>
|
#include <net/9p/client.h>
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
* affs regular file handling primitives
|
* affs regular file handling primitives
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/aio.h>
|
#include <linux/uio.h>
|
||||||
#include "affs.h"
|
#include "affs.h"
|
||||||
|
|
||||||
static struct buffer_head *affs_get_extblock_slow(struct inode *inode, u32 ext);
|
static struct buffer_head *affs_get_extblock_slow(struct inode *inode, u32 ext);
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
#include <linux/pagemap.h>
|
#include <linux/pagemap.h>
|
||||||
#include <linux/writeback.h>
|
#include <linux/writeback.h>
|
||||||
#include <linux/pagevec.h>
|
#include <linux/pagevec.h>
|
||||||
#include <linux/aio.h>
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
static int afs_write_back_from_locked_page(struct afs_writeback *wb,
|
static int afs_write_back_from_locked_page(struct afs_writeback *wb,
|
||||||
|
|
150
fs/aio.c
150
fs/aio.c
|
@ -151,6 +151,38 @@ struct kioctx {
|
||||||
unsigned id;
|
unsigned id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We use ki_cancel == KIOCB_CANCELLED to indicate that a kiocb has been either
|
||||||
|
* cancelled or completed (this makes a certain amount of sense because
|
||||||
|
* successful cancellation - io_cancel() - does deliver the completion to
|
||||||
|
* userspace).
|
||||||
|
*
|
||||||
|
* And since most things don't implement kiocb cancellation and we'd really like
|
||||||
|
* kiocb completion to be lockless when possible, we use ki_cancel to
|
||||||
|
* synchronize cancellation and completion - we only set it to KIOCB_CANCELLED
|
||||||
|
* with xchg() or cmpxchg(), see batch_complete_aio() and kiocb_cancel().
|
||||||
|
*/
|
||||||
|
#define KIOCB_CANCELLED ((void *) (~0ULL))
|
||||||
|
|
||||||
|
struct aio_kiocb {
|
||||||
|
struct kiocb common;
|
||||||
|
|
||||||
|
struct kioctx *ki_ctx;
|
||||||
|
kiocb_cancel_fn *ki_cancel;
|
||||||
|
|
||||||
|
struct iocb __user *ki_user_iocb; /* user's aiocb */
|
||||||
|
__u64 ki_user_data; /* user's data for completion */
|
||||||
|
|
||||||
|
struct list_head ki_list; /* the aio core uses this
|
||||||
|
* for cancellation */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the aio_resfd field of the userspace iocb is not zero,
|
||||||
|
* this is the underlying eventfd context to deliver events to.
|
||||||
|
*/
|
||||||
|
struct eventfd_ctx *ki_eventfd;
|
||||||
|
};
|
||||||
|
|
||||||
/*------ sysctl variables----*/
|
/*------ sysctl variables----*/
|
||||||
static DEFINE_SPINLOCK(aio_nr_lock);
|
static DEFINE_SPINLOCK(aio_nr_lock);
|
||||||
unsigned long aio_nr; /* current system wide number of aio requests */
|
unsigned long aio_nr; /* current system wide number of aio requests */
|
||||||
|
@ -220,7 +252,7 @@ static int __init aio_setup(void)
|
||||||
if (IS_ERR(aio_mnt))
|
if (IS_ERR(aio_mnt))
|
||||||
panic("Failed to create aio fs mount.");
|
panic("Failed to create aio fs mount.");
|
||||||
|
|
||||||
kiocb_cachep = KMEM_CACHE(kiocb, SLAB_HWCACHE_ALIGN|SLAB_PANIC);
|
kiocb_cachep = KMEM_CACHE(aio_kiocb, SLAB_HWCACHE_ALIGN|SLAB_PANIC);
|
||||||
kioctx_cachep = KMEM_CACHE(kioctx,SLAB_HWCACHE_ALIGN|SLAB_PANIC);
|
kioctx_cachep = KMEM_CACHE(kioctx,SLAB_HWCACHE_ALIGN|SLAB_PANIC);
|
||||||
|
|
||||||
pr_debug("sizeof(struct page) = %zu\n", sizeof(struct page));
|
pr_debug("sizeof(struct page) = %zu\n", sizeof(struct page));
|
||||||
|
@ -480,8 +512,9 @@ static int aio_setup_ring(struct kioctx *ctx)
|
||||||
#define AIO_EVENTS_FIRST_PAGE ((PAGE_SIZE - sizeof(struct aio_ring)) / sizeof(struct io_event))
|
#define AIO_EVENTS_FIRST_PAGE ((PAGE_SIZE - sizeof(struct aio_ring)) / sizeof(struct io_event))
|
||||||
#define AIO_EVENTS_OFFSET (AIO_EVENTS_PER_PAGE - AIO_EVENTS_FIRST_PAGE)
|
#define AIO_EVENTS_OFFSET (AIO_EVENTS_PER_PAGE - AIO_EVENTS_FIRST_PAGE)
|
||||||
|
|
||||||
void kiocb_set_cancel_fn(struct kiocb *req, kiocb_cancel_fn *cancel)
|
void kiocb_set_cancel_fn(struct kiocb *iocb, kiocb_cancel_fn *cancel)
|
||||||
{
|
{
|
||||||
|
struct aio_kiocb *req = container_of(iocb, struct aio_kiocb, common);
|
||||||
struct kioctx *ctx = req->ki_ctx;
|
struct kioctx *ctx = req->ki_ctx;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
|
@ -496,7 +529,7 @@ void kiocb_set_cancel_fn(struct kiocb *req, kiocb_cancel_fn *cancel)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(kiocb_set_cancel_fn);
|
EXPORT_SYMBOL(kiocb_set_cancel_fn);
|
||||||
|
|
||||||
static int kiocb_cancel(struct kiocb *kiocb)
|
static int kiocb_cancel(struct aio_kiocb *kiocb)
|
||||||
{
|
{
|
||||||
kiocb_cancel_fn *old, *cancel;
|
kiocb_cancel_fn *old, *cancel;
|
||||||
|
|
||||||
|
@ -514,7 +547,7 @@ static int kiocb_cancel(struct kiocb *kiocb)
|
||||||
cancel = cmpxchg(&kiocb->ki_cancel, old, KIOCB_CANCELLED);
|
cancel = cmpxchg(&kiocb->ki_cancel, old, KIOCB_CANCELLED);
|
||||||
} while (cancel != old);
|
} while (cancel != old);
|
||||||
|
|
||||||
return cancel(kiocb);
|
return cancel(&kiocb->common);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void free_ioctx(struct work_struct *work)
|
static void free_ioctx(struct work_struct *work)
|
||||||
|
@ -550,13 +583,13 @@ static void free_ioctx_reqs(struct percpu_ref *ref)
|
||||||
static void free_ioctx_users(struct percpu_ref *ref)
|
static void free_ioctx_users(struct percpu_ref *ref)
|
||||||
{
|
{
|
||||||
struct kioctx *ctx = container_of(ref, struct kioctx, users);
|
struct kioctx *ctx = container_of(ref, struct kioctx, users);
|
||||||
struct kiocb *req;
|
struct aio_kiocb *req;
|
||||||
|
|
||||||
spin_lock_irq(&ctx->ctx_lock);
|
spin_lock_irq(&ctx->ctx_lock);
|
||||||
|
|
||||||
while (!list_empty(&ctx->active_reqs)) {
|
while (!list_empty(&ctx->active_reqs)) {
|
||||||
req = list_first_entry(&ctx->active_reqs,
|
req = list_first_entry(&ctx->active_reqs,
|
||||||
struct kiocb, ki_list);
|
struct aio_kiocb, ki_list);
|
||||||
|
|
||||||
list_del_init(&req->ki_list);
|
list_del_init(&req->ki_list);
|
||||||
kiocb_cancel(req);
|
kiocb_cancel(req);
|
||||||
|
@ -778,22 +811,6 @@ static int kill_ioctx(struct mm_struct *mm, struct kioctx *ctx,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* wait_on_sync_kiocb:
|
|
||||||
* Waits on the given sync kiocb to complete.
|
|
||||||
*/
|
|
||||||
ssize_t wait_on_sync_kiocb(struct kiocb *req)
|
|
||||||
{
|
|
||||||
while (!req->ki_ctx) {
|
|
||||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
|
||||||
if (req->ki_ctx)
|
|
||||||
break;
|
|
||||||
io_schedule();
|
|
||||||
}
|
|
||||||
__set_current_state(TASK_RUNNING);
|
|
||||||
return req->ki_user_data;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(wait_on_sync_kiocb);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* exit_aio: called when the last user of mm goes away. At this point, there is
|
* exit_aio: called when the last user of mm goes away. At this point, there is
|
||||||
* no way for any new requests to be submited or any of the io_* syscalls to be
|
* no way for any new requests to be submited or any of the io_* syscalls to be
|
||||||
|
@ -948,9 +965,9 @@ static void user_refill_reqs_available(struct kioctx *ctx)
|
||||||
* Allocate a slot for an aio request.
|
* Allocate a slot for an aio request.
|
||||||
* Returns NULL if no requests are free.
|
* Returns NULL if no requests are free.
|
||||||
*/
|
*/
|
||||||
static inline struct kiocb *aio_get_req(struct kioctx *ctx)
|
static inline struct aio_kiocb *aio_get_req(struct kioctx *ctx)
|
||||||
{
|
{
|
||||||
struct kiocb *req;
|
struct aio_kiocb *req;
|
||||||
|
|
||||||
if (!get_reqs_available(ctx)) {
|
if (!get_reqs_available(ctx)) {
|
||||||
user_refill_reqs_available(ctx);
|
user_refill_reqs_available(ctx);
|
||||||
|
@ -971,10 +988,10 @@ out_put:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void kiocb_free(struct kiocb *req)
|
static void kiocb_free(struct aio_kiocb *req)
|
||||||
{
|
{
|
||||||
if (req->ki_filp)
|
if (req->common.ki_filp)
|
||||||
fput(req->ki_filp);
|
fput(req->common.ki_filp);
|
||||||
if (req->ki_eventfd != NULL)
|
if (req->ki_eventfd != NULL)
|
||||||
eventfd_ctx_put(req->ki_eventfd);
|
eventfd_ctx_put(req->ki_eventfd);
|
||||||
kmem_cache_free(kiocb_cachep, req);
|
kmem_cache_free(kiocb_cachep, req);
|
||||||
|
@ -1010,8 +1027,9 @@ out:
|
||||||
/* aio_complete
|
/* aio_complete
|
||||||
* Called when the io request on the given iocb is complete.
|
* Called when the io request on the given iocb is complete.
|
||||||
*/
|
*/
|
||||||
void aio_complete(struct kiocb *iocb, long res, long res2)
|
static void aio_complete(struct kiocb *kiocb, long res, long res2)
|
||||||
{
|
{
|
||||||
|
struct aio_kiocb *iocb = container_of(kiocb, struct aio_kiocb, common);
|
||||||
struct kioctx *ctx = iocb->ki_ctx;
|
struct kioctx *ctx = iocb->ki_ctx;
|
||||||
struct aio_ring *ring;
|
struct aio_ring *ring;
|
||||||
struct io_event *ev_page, *event;
|
struct io_event *ev_page, *event;
|
||||||
|
@ -1025,13 +1043,7 @@ void aio_complete(struct kiocb *iocb, long res, long res2)
|
||||||
* ref, no other paths have a way to get another ref
|
* ref, no other paths have a way to get another ref
|
||||||
* - the sync task helpfully left a reference to itself in the iocb
|
* - the sync task helpfully left a reference to itself in the iocb
|
||||||
*/
|
*/
|
||||||
if (is_sync_kiocb(iocb)) {
|
BUG_ON(is_sync_kiocb(kiocb));
|
||||||
iocb->ki_user_data = res;
|
|
||||||
smp_wmb();
|
|
||||||
iocb->ki_ctx = ERR_PTR(-EXDEV);
|
|
||||||
wake_up_process(iocb->ki_obj.tsk);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (iocb->ki_list.next) {
|
if (iocb->ki_list.next) {
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
@ -1057,7 +1069,7 @@ void aio_complete(struct kiocb *iocb, long res, long res2)
|
||||||
ev_page = kmap_atomic(ctx->ring_pages[pos / AIO_EVENTS_PER_PAGE]);
|
ev_page = kmap_atomic(ctx->ring_pages[pos / AIO_EVENTS_PER_PAGE]);
|
||||||
event = ev_page + pos % AIO_EVENTS_PER_PAGE;
|
event = ev_page + pos % AIO_EVENTS_PER_PAGE;
|
||||||
|
|
||||||
event->obj = (u64)(unsigned long)iocb->ki_obj.user;
|
event->obj = (u64)(unsigned long)iocb->ki_user_iocb;
|
||||||
event->data = iocb->ki_user_data;
|
event->data = iocb->ki_user_data;
|
||||||
event->res = res;
|
event->res = res;
|
||||||
event->res2 = res2;
|
event->res2 = res2;
|
||||||
|
@ -1066,7 +1078,7 @@ void aio_complete(struct kiocb *iocb, long res, long res2)
|
||||||
flush_dcache_page(ctx->ring_pages[pos / AIO_EVENTS_PER_PAGE]);
|
flush_dcache_page(ctx->ring_pages[pos / AIO_EVENTS_PER_PAGE]);
|
||||||
|
|
||||||
pr_debug("%p[%u]: %p: %p %Lx %lx %lx\n",
|
pr_debug("%p[%u]: %p: %p %Lx %lx %lx\n",
|
||||||
ctx, tail, iocb, iocb->ki_obj.user, iocb->ki_user_data,
|
ctx, tail, iocb, iocb->ki_user_iocb, iocb->ki_user_data,
|
||||||
res, res2);
|
res, res2);
|
||||||
|
|
||||||
/* after flagging the request as done, we
|
/* after flagging the request as done, we
|
||||||
|
@ -1113,7 +1125,6 @@ void aio_complete(struct kiocb *iocb, long res, long res2)
|
||||||
|
|
||||||
percpu_ref_put(&ctx->reqs);
|
percpu_ref_put(&ctx->reqs);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(aio_complete);
|
|
||||||
|
|
||||||
/* aio_read_events_ring
|
/* aio_read_events_ring
|
||||||
* Pull an event off of the ioctx's event ring. Returns the number of
|
* Pull an event off of the ioctx's event ring. Returns the number of
|
||||||
|
@ -1344,12 +1355,13 @@ typedef ssize_t (rw_iter_op)(struct kiocb *, struct iov_iter *);
|
||||||
static ssize_t aio_setup_vectored_rw(struct kiocb *kiocb,
|
static ssize_t aio_setup_vectored_rw(struct kiocb *kiocb,
|
||||||
int rw, char __user *buf,
|
int rw, char __user *buf,
|
||||||
unsigned long *nr_segs,
|
unsigned long *nr_segs,
|
||||||
|
size_t *len,
|
||||||
struct iovec **iovec,
|
struct iovec **iovec,
|
||||||
bool compat)
|
bool compat)
|
||||||
{
|
{
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
*nr_segs = kiocb->ki_nbytes;
|
*nr_segs = *len;
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_COMPAT
|
||||||
if (compat)
|
if (compat)
|
||||||
|
@ -1364,21 +1376,22 @@ static ssize_t aio_setup_vectored_rw(struct kiocb *kiocb,
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* ki_nbytes now reflect bytes instead of segs */
|
/* len now reflect bytes instead of segs */
|
||||||
kiocb->ki_nbytes = ret;
|
*len = ret;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t aio_setup_single_vector(struct kiocb *kiocb,
|
static ssize_t aio_setup_single_vector(struct kiocb *kiocb,
|
||||||
int rw, char __user *buf,
|
int rw, char __user *buf,
|
||||||
unsigned long *nr_segs,
|
unsigned long *nr_segs,
|
||||||
|
size_t len,
|
||||||
struct iovec *iovec)
|
struct iovec *iovec)
|
||||||
{
|
{
|
||||||
if (unlikely(!access_ok(!rw, buf, kiocb->ki_nbytes)))
|
if (unlikely(!access_ok(!rw, buf, len)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
iovec->iov_base = buf;
|
iovec->iov_base = buf;
|
||||||
iovec->iov_len = kiocb->ki_nbytes;
|
iovec->iov_len = len;
|
||||||
*nr_segs = 1;
|
*nr_segs = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1388,7 +1401,7 @@ static ssize_t aio_setup_single_vector(struct kiocb *kiocb,
|
||||||
* Performs the initial checks and io submission.
|
* Performs the initial checks and io submission.
|
||||||
*/
|
*/
|
||||||
static ssize_t aio_run_iocb(struct kiocb *req, unsigned opcode,
|
static ssize_t aio_run_iocb(struct kiocb *req, unsigned opcode,
|
||||||
char __user *buf, bool compat)
|
char __user *buf, size_t len, bool compat)
|
||||||
{
|
{
|
||||||
struct file *file = req->ki_filp;
|
struct file *file = req->ki_filp;
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
@ -1423,21 +1436,21 @@ rw_common:
|
||||||
if (!rw_op && !iter_op)
|
if (!rw_op && !iter_op)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
ret = (opcode == IOCB_CMD_PREADV ||
|
if (opcode == IOCB_CMD_PREADV || opcode == IOCB_CMD_PWRITEV)
|
||||||
opcode == IOCB_CMD_PWRITEV)
|
ret = aio_setup_vectored_rw(req, rw, buf, &nr_segs,
|
||||||
? aio_setup_vectored_rw(req, rw, buf, &nr_segs,
|
&len, &iovec, compat);
|
||||||
&iovec, compat)
|
else
|
||||||
: aio_setup_single_vector(req, rw, buf, &nr_segs,
|
ret = aio_setup_single_vector(req, rw, buf, &nr_segs,
|
||||||
iovec);
|
len, iovec);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
ret = rw_verify_area(rw, file, &req->ki_pos, req->ki_nbytes);
|
ret = rw_verify_area(rw, file, &req->ki_pos, len);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (iovec != inline_vecs)
|
if (iovec != inline_vecs)
|
||||||
kfree(iovec);
|
kfree(iovec);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
req->ki_nbytes = ret;
|
len = ret;
|
||||||
|
|
||||||
/* XXX: move/kill - rw_verify_area()? */
|
/* XXX: move/kill - rw_verify_area()? */
|
||||||
/* This matches the pread()/pwrite() logic */
|
/* This matches the pread()/pwrite() logic */
|
||||||
|
@ -1450,7 +1463,7 @@ rw_common:
|
||||||
file_start_write(file);
|
file_start_write(file);
|
||||||
|
|
||||||
if (iter_op) {
|
if (iter_op) {
|
||||||
iov_iter_init(&iter, rw, iovec, nr_segs, req->ki_nbytes);
|
iov_iter_init(&iter, rw, iovec, nr_segs, len);
|
||||||
ret = iter_op(req, &iter);
|
ret = iter_op(req, &iter);
|
||||||
} else {
|
} else {
|
||||||
ret = rw_op(req, iovec, nr_segs, req->ki_pos);
|
ret = rw_op(req, iovec, nr_segs, req->ki_pos);
|
||||||
|
@ -1500,7 +1513,7 @@ rw_common:
|
||||||
static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
|
static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
|
||||||
struct iocb *iocb, bool compat)
|
struct iocb *iocb, bool compat)
|
||||||
{
|
{
|
||||||
struct kiocb *req;
|
struct aio_kiocb *req;
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
/* enforce forwards compatibility on users */
|
/* enforce forwards compatibility on users */
|
||||||
|
@ -1523,11 +1536,14 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
|
||||||
if (unlikely(!req))
|
if (unlikely(!req))
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
|
|
||||||
req->ki_filp = fget(iocb->aio_fildes);
|
req->common.ki_filp = fget(iocb->aio_fildes);
|
||||||
if (unlikely(!req->ki_filp)) {
|
if (unlikely(!req->common.ki_filp)) {
|
||||||
ret = -EBADF;
|
ret = -EBADF;
|
||||||
goto out_put_req;
|
goto out_put_req;
|
||||||
}
|
}
|
||||||
|
req->common.ki_pos = iocb->aio_offset;
|
||||||
|
req->common.ki_complete = aio_complete;
|
||||||
|
req->common.ki_flags = 0;
|
||||||
|
|
||||||
if (iocb->aio_flags & IOCB_FLAG_RESFD) {
|
if (iocb->aio_flags & IOCB_FLAG_RESFD) {
|
||||||
/*
|
/*
|
||||||
|
@ -1542,6 +1558,8 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
|
||||||
req->ki_eventfd = NULL;
|
req->ki_eventfd = NULL;
|
||||||
goto out_put_req;
|
goto out_put_req;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
req->common.ki_flags |= IOCB_EVENTFD;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = put_user(KIOCB_KEY, &user_iocb->aio_key);
|
ret = put_user(KIOCB_KEY, &user_iocb->aio_key);
|
||||||
|
@ -1550,13 +1568,12 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
|
||||||
goto out_put_req;
|
goto out_put_req;
|
||||||
}
|
}
|
||||||
|
|
||||||
req->ki_obj.user = user_iocb;
|
req->ki_user_iocb = user_iocb;
|
||||||
req->ki_user_data = iocb->aio_data;
|
req->ki_user_data = iocb->aio_data;
|
||||||
req->ki_pos = iocb->aio_offset;
|
|
||||||
req->ki_nbytes = iocb->aio_nbytes;
|
|
||||||
|
|
||||||
ret = aio_run_iocb(req, iocb->aio_lio_opcode,
|
ret = aio_run_iocb(&req->common, iocb->aio_lio_opcode,
|
||||||
(char __user *)(unsigned long)iocb->aio_buf,
|
(char __user *)(unsigned long)iocb->aio_buf,
|
||||||
|
iocb->aio_nbytes,
|
||||||
compat);
|
compat);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_put_req;
|
goto out_put_req;
|
||||||
|
@ -1643,10 +1660,10 @@ SYSCALL_DEFINE3(io_submit, aio_context_t, ctx_id, long, nr,
|
||||||
/* lookup_kiocb
|
/* lookup_kiocb
|
||||||
* Finds a given iocb for cancellation.
|
* Finds a given iocb for cancellation.
|
||||||
*/
|
*/
|
||||||
static struct kiocb *lookup_kiocb(struct kioctx *ctx, struct iocb __user *iocb,
|
static struct aio_kiocb *
|
||||||
u32 key)
|
lookup_kiocb(struct kioctx *ctx, struct iocb __user *iocb, u32 key)
|
||||||
{
|
{
|
||||||
struct list_head *pos;
|
struct aio_kiocb *kiocb;
|
||||||
|
|
||||||
assert_spin_locked(&ctx->ctx_lock);
|
assert_spin_locked(&ctx->ctx_lock);
|
||||||
|
|
||||||
|
@ -1654,9 +1671,8 @@ static struct kiocb *lookup_kiocb(struct kioctx *ctx, struct iocb __user *iocb,
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* TODO: use a hash or array, this sucks. */
|
/* TODO: use a hash or array, this sucks. */
|
||||||
list_for_each(pos, &ctx->active_reqs) {
|
list_for_each_entry(kiocb, &ctx->active_reqs, ki_list) {
|
||||||
struct kiocb *kiocb = list_kiocb(pos);
|
if (kiocb->ki_user_iocb == iocb)
|
||||||
if (kiocb->ki_obj.user == iocb)
|
|
||||||
return kiocb;
|
return kiocb;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1676,7 +1692,7 @@ SYSCALL_DEFINE3(io_cancel, aio_context_t, ctx_id, struct iocb __user *, iocb,
|
||||||
struct io_event __user *, result)
|
struct io_event __user *, result)
|
||||||
{
|
{
|
||||||
struct kioctx *ctx;
|
struct kioctx *ctx;
|
||||||
struct kiocb *kiocb;
|
struct aio_kiocb *kiocb;
|
||||||
u32 key;
|
u32 key;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <linux/buffer_head.h>
|
#include <linux/buffer_head.h>
|
||||||
#include <linux/vfs.h>
|
#include <linux/vfs.h>
|
||||||
#include <linux/writeback.h>
|
#include <linux/writeback.h>
|
||||||
|
#include <linux/uio.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include "bfs.h"
|
#include "bfs.h"
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
#include <linux/namei.h>
|
#include <linux/namei.h>
|
||||||
#include <linux/log2.h>
|
#include <linux/log2.h>
|
||||||
#include <linux/cleancache.h>
|
#include <linux/cleancache.h>
|
||||||
#include <linux/aio.h>
|
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <linux/backing-dev.h>
|
#include <linux/backing-dev.h>
|
||||||
#include <linux/mpage.h>
|
#include <linux/mpage.h>
|
||||||
#include <linux/aio.h>
|
|
||||||
#include <linux/falloc.h>
|
#include <linux/falloc.h>
|
||||||
#include <linux/swap.h>
|
#include <linux/swap.h>
|
||||||
#include <linux/writeback.h>
|
#include <linux/writeback.h>
|
||||||
|
@ -32,6 +31,7 @@
|
||||||
#include <linux/compat.h>
|
#include <linux/compat.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/btrfs.h>
|
#include <linux/btrfs.h>
|
||||||
|
#include <linux/uio.h>
|
||||||
#include "ctree.h"
|
#include "ctree.h"
|
||||||
#include "disk-io.h"
|
#include "disk-io.h"
|
||||||
#include "transaction.h"
|
#include "transaction.h"
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
#include <linux/writeback.h>
|
#include <linux/writeback.h>
|
||||||
#include <linux/statfs.h>
|
#include <linux/statfs.h>
|
||||||
#include <linux/compat.h>
|
#include <linux/compat.h>
|
||||||
#include <linux/aio.h>
|
|
||||||
#include <linux/bit_spinlock.h>
|
#include <linux/bit_spinlock.h>
|
||||||
#include <linux/xattr.h>
|
#include <linux/xattr.h>
|
||||||
#include <linux/posix_acl.h>
|
#include <linux/posix_acl.h>
|
||||||
|
@ -43,6 +42,7 @@
|
||||||
#include <linux/btrfs.h>
|
#include <linux/btrfs.h>
|
||||||
#include <linux/blkdev.h>
|
#include <linux/blkdev.h>
|
||||||
#include <linux/posix_acl_xattr.h>
|
#include <linux/posix_acl_xattr.h>
|
||||||
|
#include <linux/uio.h>
|
||||||
#include "ctree.h"
|
#include "ctree.h"
|
||||||
#include "disk-io.h"
|
#include "disk-io.h"
|
||||||
#include "transaction.h"
|
#include "transaction.h"
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
#include <linux/mount.h>
|
#include <linux/mount.h>
|
||||||
#include <linux/namei.h>
|
#include <linux/namei.h>
|
||||||
#include <linux/writeback.h>
|
#include <linux/writeback.h>
|
||||||
#include <linux/aio.h>
|
|
||||||
#include <linux/falloc.h>
|
#include <linux/falloc.h>
|
||||||
|
|
||||||
#include "super.h"
|
#include "super.h"
|
||||||
|
@ -808,7 +807,7 @@ static ssize_t ceph_read_iter(struct kiocb *iocb, struct iov_iter *to)
|
||||||
{
|
{
|
||||||
struct file *filp = iocb->ki_filp;
|
struct file *filp = iocb->ki_filp;
|
||||||
struct ceph_file_info *fi = filp->private_data;
|
struct ceph_file_info *fi = filp->private_data;
|
||||||
size_t len = iocb->ki_nbytes;
|
size_t len = iov_iter_count(to);
|
||||||
struct inode *inode = file_inode(filp);
|
struct inode *inode = file_inode(filp);
|
||||||
struct ceph_inode_info *ci = ceph_inode(inode);
|
struct ceph_inode_info *ci = ceph_inode(inode);
|
||||||
struct page *pinned_page = NULL;
|
struct page *pinned_page = NULL;
|
||||||
|
|
|
@ -37,7 +37,6 @@
|
||||||
#include <linux/uio.h>
|
#include <linux/uio.h>
|
||||||
#include <linux/atomic.h>
|
#include <linux/atomic.h>
|
||||||
#include <linux/prefetch.h>
|
#include <linux/prefetch.h>
|
||||||
#include <linux/aio.h>
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* How many user pages to map in one call to get_user_pages(). This determines
|
* How many user pages to map in one call to get_user_pages(). This determines
|
||||||
|
@ -265,7 +264,7 @@ static ssize_t dio_complete(struct dio *dio, loff_t offset, ssize_t ret,
|
||||||
ret = err;
|
ret = err;
|
||||||
}
|
}
|
||||||
|
|
||||||
aio_complete(dio->iocb, ret, 0);
|
dio->iocb->ki_complete(dio->iocb, ret, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
kmem_cache_free(dio_cache, dio);
|
kmem_cache_free(dio_cache, dio);
|
||||||
|
@ -1056,7 +1055,7 @@ static inline int drop_refcount(struct dio *dio)
|
||||||
* operation. AIO can if it was a broken operation described above or
|
* operation. AIO can if it was a broken operation described above or
|
||||||
* in fact if all the bios race to complete before we get here. In
|
* in fact if all the bios race to complete before we get here. In
|
||||||
* that case dio_complete() translates the EIOCBQUEUED into the proper
|
* that case dio_complete() translates the EIOCBQUEUED into the proper
|
||||||
* return code that the caller will hand to aio_complete().
|
* return code that the caller will hand to ->complete().
|
||||||
*
|
*
|
||||||
* This is managed by the bio_lock instead of being an atomic_t so that
|
* This is managed by the bio_lock instead of being an atomic_t so that
|
||||||
* completion paths can drop their ref and use the remaining count to
|
* completion paths can drop their ref and use the remaining count to
|
||||||
|
|
|
@ -31,7 +31,6 @@
|
||||||
#include <linux/security.h>
|
#include <linux/security.h>
|
||||||
#include <linux/compat.h>
|
#include <linux/compat.h>
|
||||||
#include <linux/fs_stack.h>
|
#include <linux/fs_stack.h>
|
||||||
#include <linux/aio.h>
|
|
||||||
#include "ecryptfs_kernel.h"
|
#include "ecryptfs_kernel.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -52,12 +51,6 @@ static ssize_t ecryptfs_read_update_atime(struct kiocb *iocb,
|
||||||
struct file *file = iocb->ki_filp;
|
struct file *file = iocb->ki_filp;
|
||||||
|
|
||||||
rc = generic_file_read_iter(iocb, to);
|
rc = generic_file_read_iter(iocb, to);
|
||||||
/*
|
|
||||||
* Even though this is a async interface, we need to wait
|
|
||||||
* for IO to finish to update atime
|
|
||||||
*/
|
|
||||||
if (-EIOCBQUEUED == rc)
|
|
||||||
rc = wait_on_sync_kiocb(iocb);
|
|
||||||
if (rc >= 0) {
|
if (rc >= 0) {
|
||||||
path = ecryptfs_dentry_to_lower_path(file->f_path.dentry);
|
path = ecryptfs_dentry_to_lower_path(file->f_path.dentry);
|
||||||
touch_atime(path);
|
touch_atime(path);
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
#include <linux/mpage.h>
|
#include <linux/mpage.h>
|
||||||
#include <linux/fiemap.h>
|
#include <linux/fiemap.h>
|
||||||
#include <linux/namei.h>
|
#include <linux/namei.h>
|
||||||
#include <linux/aio.h>
|
#include <linux/uio.h>
|
||||||
#include "ext2.h"
|
#include "ext2.h"
|
||||||
#include "acl.h"
|
#include "acl.h"
|
||||||
#include "xattr.h"
|
#include "xattr.h"
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
#include <linux/writeback.h>
|
#include <linux/writeback.h>
|
||||||
#include <linux/mpage.h>
|
#include <linux/mpage.h>
|
||||||
#include <linux/namei.h>
|
#include <linux/namei.h>
|
||||||
#include <linux/aio.h>
|
#include <linux/uio.h>
|
||||||
#include "ext3.h"
|
#include "ext3.h"
|
||||||
#include "xattr.h"
|
#include "xattr.h"
|
||||||
#include "acl.h"
|
#include "acl.h"
|
||||||
|
|
|
@ -23,9 +23,9 @@
|
||||||
#include <linux/jbd2.h>
|
#include <linux/jbd2.h>
|
||||||
#include <linux/mount.h>
|
#include <linux/mount.h>
|
||||||
#include <linux/path.h>
|
#include <linux/path.h>
|
||||||
#include <linux/aio.h>
|
|
||||||
#include <linux/quotaops.h>
|
#include <linux/quotaops.h>
|
||||||
#include <linux/pagevec.h>
|
#include <linux/pagevec.h>
|
||||||
|
#include <linux/uio.h>
|
||||||
#include "ext4.h"
|
#include "ext4.h"
|
||||||
#include "ext4_jbd2.h"
|
#include "ext4_jbd2.h"
|
||||||
#include "xattr.h"
|
#include "xattr.h"
|
||||||
|
|
|
@ -20,9 +20,9 @@
|
||||||
* (sct@redhat.com), 1993, 1998
|
* (sct@redhat.com), 1993, 1998
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/aio.h>
|
|
||||||
#include "ext4_jbd2.h"
|
#include "ext4_jbd2.h"
|
||||||
#include "truncate.h"
|
#include "truncate.h"
|
||||||
|
#include <linux/uio.h>
|
||||||
|
|
||||||
#include <trace/events/ext4.h>
|
#include <trace/events/ext4.h>
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,6 @@
|
||||||
#include <linux/printk.h>
|
#include <linux/printk.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/ratelimit.h>
|
#include <linux/ratelimit.h>
|
||||||
#include <linux/aio.h>
|
|
||||||
#include <linux/bitops.h>
|
#include <linux/bitops.h>
|
||||||
|
|
||||||
#include "ext4_jbd2.h"
|
#include "ext4_jbd2.h"
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
#include <linux/pagevec.h>
|
#include <linux/pagevec.h>
|
||||||
#include <linux/mpage.h>
|
#include <linux/mpage.h>
|
||||||
#include <linux/namei.h>
|
#include <linux/namei.h>
|
||||||
#include <linux/aio.h>
|
|
||||||
#include <linux/uio.h>
|
#include <linux/uio.h>
|
||||||
#include <linux/bio.h>
|
#include <linux/bio.h>
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
|
|
|
@ -12,12 +12,12 @@
|
||||||
#include <linux/f2fs_fs.h>
|
#include <linux/f2fs_fs.h>
|
||||||
#include <linux/buffer_head.h>
|
#include <linux/buffer_head.h>
|
||||||
#include <linux/mpage.h>
|
#include <linux/mpage.h>
|
||||||
#include <linux/aio.h>
|
|
||||||
#include <linux/writeback.h>
|
#include <linux/writeback.h>
|
||||||
#include <linux/backing-dev.h>
|
#include <linux/backing-dev.h>
|
||||||
#include <linux/blkdev.h>
|
#include <linux/blkdev.h>
|
||||||
#include <linux/bio.h>
|
#include <linux/bio.h>
|
||||||
#include <linux/prefetch.h>
|
#include <linux/prefetch.h>
|
||||||
|
#include <linux/uio.h>
|
||||||
|
|
||||||
#include "f2fs.h"
|
#include "f2fs.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
#include <linux/mpage.h>
|
#include <linux/mpage.h>
|
||||||
#include <linux/buffer_head.h>
|
#include <linux/buffer_head.h>
|
||||||
#include <linux/mount.h>
|
#include <linux/mount.h>
|
||||||
#include <linux/aio.h>
|
|
||||||
#include <linux/vfs.h>
|
#include <linux/vfs.h>
|
||||||
#include <linux/parser.h>
|
#include <linux/parser.h>
|
||||||
#include <linux/uio.h>
|
#include <linux/uio.h>
|
||||||
|
|
|
@ -38,7 +38,6 @@
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/file.h>
|
#include <linux/file.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/aio.h>
|
|
||||||
#include <linux/kdev_t.h>
|
#include <linux/kdev_t.h>
|
||||||
#include <linux/kthread.h>
|
#include <linux/kthread.h>
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
|
@ -48,6 +47,7 @@
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/stat.h>
|
#include <linux/stat.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/uio.h>
|
||||||
|
|
||||||
#include "fuse_i.h"
|
#include "fuse_i.h"
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
#include <linux/pipe_fs_i.h>
|
#include <linux/pipe_fs_i.h>
|
||||||
#include <linux/swap.h>
|
#include <linux/swap.h>
|
||||||
#include <linux/splice.h>
|
#include <linux/splice.h>
|
||||||
#include <linux/aio.h>
|
|
||||||
|
|
||||||
MODULE_ALIAS_MISCDEV(FUSE_MINOR);
|
MODULE_ALIAS_MISCDEV(FUSE_MINOR);
|
||||||
MODULE_ALIAS("devname:fuse");
|
MODULE_ALIAS("devname:fuse");
|
||||||
|
|
|
@ -15,8 +15,8 @@
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/compat.h>
|
#include <linux/compat.h>
|
||||||
#include <linux/swap.h>
|
#include <linux/swap.h>
|
||||||
#include <linux/aio.h>
|
|
||||||
#include <linux/falloc.h>
|
#include <linux/falloc.h>
|
||||||
|
#include <linux/uio.h>
|
||||||
|
|
||||||
static const struct file_operations fuse_direct_io_file_operations;
|
static const struct file_operations fuse_direct_io_file_operations;
|
||||||
|
|
||||||
|
@ -528,6 +528,17 @@ static void fuse_release_user_pages(struct fuse_req *req, int write)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ssize_t fuse_get_res_by_io(struct fuse_io_priv *io)
|
||||||
|
{
|
||||||
|
if (io->err)
|
||||||
|
return io->err;
|
||||||
|
|
||||||
|
if (io->bytes >= 0 && io->write)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
return io->bytes < 0 ? io->size : io->bytes;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In case of short read, the caller sets 'pos' to the position of
|
* In case of short read, the caller sets 'pos' to the position of
|
||||||
* actual end of fuse request in IO request. Otherwise, if bytes_requested
|
* actual end of fuse request in IO request. Otherwise, if bytes_requested
|
||||||
|
@ -546,6 +557,7 @@ static void fuse_release_user_pages(struct fuse_req *req, int write)
|
||||||
*/
|
*/
|
||||||
static void fuse_aio_complete(struct fuse_io_priv *io, int err, ssize_t pos)
|
static void fuse_aio_complete(struct fuse_io_priv *io, int err, ssize_t pos)
|
||||||
{
|
{
|
||||||
|
bool is_sync = is_sync_kiocb(io->iocb);
|
||||||
int left;
|
int left;
|
||||||
|
|
||||||
spin_lock(&io->lock);
|
spin_lock(&io->lock);
|
||||||
|
@ -555,19 +567,14 @@ static void fuse_aio_complete(struct fuse_io_priv *io, int err, ssize_t pos)
|
||||||
io->bytes = pos;
|
io->bytes = pos;
|
||||||
|
|
||||||
left = --io->reqs;
|
left = --io->reqs;
|
||||||
|
if (!left && is_sync)
|
||||||
|
complete(io->done);
|
||||||
spin_unlock(&io->lock);
|
spin_unlock(&io->lock);
|
||||||
|
|
||||||
if (!left) {
|
if (!left && !is_sync) {
|
||||||
long res;
|
ssize_t res = fuse_get_res_by_io(io);
|
||||||
|
|
||||||
if (io->err)
|
if (res >= 0) {
|
||||||
res = io->err;
|
|
||||||
else if (io->bytes >= 0 && io->write)
|
|
||||||
res = -EIO;
|
|
||||||
else {
|
|
||||||
res = io->bytes < 0 ? io->size : io->bytes;
|
|
||||||
|
|
||||||
if (!is_sync_kiocb(io->iocb)) {
|
|
||||||
struct inode *inode = file_inode(io->iocb->ki_filp);
|
struct inode *inode = file_inode(io->iocb->ki_filp);
|
||||||
struct fuse_conn *fc = get_fuse_conn(inode);
|
struct fuse_conn *fc = get_fuse_conn(inode);
|
||||||
struct fuse_inode *fi = get_fuse_inode(inode);
|
struct fuse_inode *fi = get_fuse_inode(inode);
|
||||||
|
@ -576,9 +583,8 @@ static void fuse_aio_complete(struct fuse_io_priv *io, int err, ssize_t pos)
|
||||||
fi->attr_version = ++fc->attr_version;
|
fi->attr_version = ++fc->attr_version;
|
||||||
spin_unlock(&fc->lock);
|
spin_unlock(&fc->lock);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
aio_complete(io->iocb, res, 0);
|
io->iocb->ki_complete(io->iocb, res, 0);
|
||||||
kfree(io);
|
kfree(io);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2801,6 +2807,7 @@ static ssize_t
|
||||||
fuse_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter,
|
fuse_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter,
|
||||||
loff_t offset)
|
loff_t offset)
|
||||||
{
|
{
|
||||||
|
DECLARE_COMPLETION_ONSTACK(wait);
|
||||||
ssize_t ret = 0;
|
ssize_t ret = 0;
|
||||||
struct file *file = iocb->ki_filp;
|
struct file *file = iocb->ki_filp;
|
||||||
struct fuse_file *ff = file->private_data;
|
struct fuse_file *ff = file->private_data;
|
||||||
|
@ -2852,6 +2859,9 @@ fuse_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter,
|
||||||
if (!is_sync_kiocb(iocb) && (offset + count > i_size) && rw == WRITE)
|
if (!is_sync_kiocb(iocb) && (offset + count > i_size) && rw == WRITE)
|
||||||
io->async = false;
|
io->async = false;
|
||||||
|
|
||||||
|
if (io->async && is_sync_kiocb(iocb))
|
||||||
|
io->done = &wait;
|
||||||
|
|
||||||
if (rw == WRITE)
|
if (rw == WRITE)
|
||||||
ret = __fuse_direct_write(io, iter, &pos);
|
ret = __fuse_direct_write(io, iter, &pos);
|
||||||
else
|
else
|
||||||
|
@ -2864,11 +2874,12 @@ fuse_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter,
|
||||||
if (!is_sync_kiocb(iocb))
|
if (!is_sync_kiocb(iocb))
|
||||||
return -EIOCBQUEUED;
|
return -EIOCBQUEUED;
|
||||||
|
|
||||||
ret = wait_on_sync_kiocb(iocb);
|
wait_for_completion(&wait);
|
||||||
} else {
|
ret = fuse_get_res_by_io(io);
|
||||||
kfree(io);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kfree(io);
|
||||||
|
|
||||||
if (rw == WRITE) {
|
if (rw == WRITE) {
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
fuse_write_update_size(inode, pos);
|
fuse_write_update_size(inode, pos);
|
||||||
|
|
|
@ -263,6 +263,7 @@ struct fuse_io_priv {
|
||||||
int err;
|
int err;
|
||||||
struct kiocb *iocb;
|
struct kiocb *iocb;
|
||||||
struct file *file;
|
struct file *file;
|
||||||
|
struct completion *done;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include <linux/swap.h>
|
#include <linux/swap.h>
|
||||||
#include <linux/gfs2_ondisk.h>
|
#include <linux/gfs2_ondisk.h>
|
||||||
#include <linux/backing-dev.h>
|
#include <linux/backing-dev.h>
|
||||||
#include <linux/aio.h>
|
#include <linux/uio.h>
|
||||||
#include <trace/events/writeback.h>
|
#include <trace/events/writeback.h>
|
||||||
|
|
||||||
#include "gfs2.h"
|
#include "gfs2.h"
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <linux/dlm.h>
|
#include <linux/dlm.h>
|
||||||
#include <linux/dlm_plock.h>
|
#include <linux/dlm_plock.h>
|
||||||
#include <linux/aio.h>
|
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
|
|
||||||
#include "gfs2.h"
|
#include "gfs2.h"
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#include <linux/pagemap.h>
|
#include <linux/pagemap.h>
|
||||||
#include <linux/mpage.h>
|
#include <linux/mpage.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/aio.h>
|
#include <linux/uio.h>
|
||||||
|
|
||||||
#include "hfs_fs.h"
|
#include "hfs_fs.h"
|
||||||
#include "btree.h"
|
#include "btree.h"
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#include <linux/pagemap.h>
|
#include <linux/pagemap.h>
|
||||||
#include <linux/mpage.h>
|
#include <linux/mpage.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/aio.h>
|
#include <linux/uio.h>
|
||||||
|
|
||||||
#include "hfsplus_fs.h"
|
#include "hfsplus_fs.h"
|
||||||
#include "hfsplus_raw.h"
|
#include "hfsplus_raw.h"
|
||||||
|
|
|
@ -22,8 +22,8 @@
|
||||||
#include <linux/buffer_head.h>
|
#include <linux/buffer_head.h>
|
||||||
#include <linux/pagemap.h>
|
#include <linux/pagemap.h>
|
||||||
#include <linux/quotaops.h>
|
#include <linux/quotaops.h>
|
||||||
|
#include <linux/uio.h>
|
||||||
#include <linux/writeback.h>
|
#include <linux/writeback.h>
|
||||||
#include <linux/aio.h>
|
|
||||||
#include "jfs_incore.h"
|
#include "jfs_incore.h"
|
||||||
#include "jfs_inode.h"
|
#include "jfs_inode.h"
|
||||||
#include "jfs_filsys.h"
|
#include "jfs_filsys.h"
|
||||||
|
|
|
@ -265,7 +265,7 @@ ssize_t nfs_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, loff_t
|
||||||
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
#else
|
#else
|
||||||
VM_BUG_ON(iocb->ki_nbytes != PAGE_SIZE);
|
VM_BUG_ON(iov_iter_count(iter) != PAGE_SIZE);
|
||||||
|
|
||||||
if (rw == READ)
|
if (rw == READ)
|
||||||
return nfs_file_direct_read(iocb, iter, pos);
|
return nfs_file_direct_read(iocb, iter, pos);
|
||||||
|
@ -393,7 +393,7 @@ static void nfs_direct_complete(struct nfs_direct_req *dreq, bool write)
|
||||||
long res = (long) dreq->error;
|
long res = (long) dreq->error;
|
||||||
if (!res)
|
if (!res)
|
||||||
res = (long) dreq->count;
|
res = (long) dreq->count;
|
||||||
aio_complete(dreq->iocb, res, 0);
|
dreq->iocb->ki_complete(dreq->iocb, res, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
complete_all(&dreq->completion);
|
complete_all(&dreq->completion);
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
#include <linux/nfs_mount.h>
|
#include <linux/nfs_mount.h>
|
||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
#include <linux/pagemap.h>
|
#include <linux/pagemap.h>
|
||||||
#include <linux/aio.h>
|
|
||||||
#include <linux/gfp.h>
|
#include <linux/gfp.h>
|
||||||
#include <linux/swap.h>
|
#include <linux/swap.h>
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
#include <linux/mpage.h>
|
#include <linux/mpage.h>
|
||||||
#include <linux/pagemap.h>
|
#include <linux/pagemap.h>
|
||||||
#include <linux/writeback.h>
|
#include <linux/writeback.h>
|
||||||
#include <linux/aio.h>
|
#include <linux/uio.h>
|
||||||
#include "nilfs.h"
|
#include "nilfs.h"
|
||||||
#include "btnode.h"
|
#include "btnode.h"
|
||||||
#include "segment.h"
|
#include "segment.h"
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
#include <linux/swap.h>
|
#include <linux/swap.h>
|
||||||
#include <linux/uio.h>
|
#include <linux/uio.h>
|
||||||
#include <linux/writeback.h>
|
#include <linux/writeback.h>
|
||||||
#include <linux/aio.h>
|
|
||||||
|
|
||||||
#include <asm/page.h>
|
#include <asm/page.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
#include <linux/quotaops.h>
|
#include <linux/quotaops.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/log2.h>
|
#include <linux/log2.h>
|
||||||
#include <linux/aio.h>
|
|
||||||
|
|
||||||
#include "aops.h"
|
#include "aops.h"
|
||||||
#include "attrib.h"
|
#include "attrib.h"
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include <linux/mpage.h>
|
#include <linux/mpage.h>
|
||||||
#include <linux/quotaops.h>
|
#include <linux/quotaops.h>
|
||||||
#include <linux/blkdev.h>
|
#include <linux/blkdev.h>
|
||||||
|
#include <linux/uio.h>
|
||||||
|
|
||||||
#include <cluster/masklog.h>
|
#include <cluster/masklog.h>
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
#ifndef OCFS2_AOPS_H
|
#ifndef OCFS2_AOPS_H
|
||||||
#define OCFS2_AOPS_H
|
#define OCFS2_AOPS_H
|
||||||
|
|
||||||
#include <linux/aio.h>
|
#include <linux/fs.h>
|
||||||
|
|
||||||
handle_t *ocfs2_start_walk_page_trans(struct inode *inode,
|
handle_t *ocfs2_start_walk_page_trans(struct inode *inode,
|
||||||
struct page *page,
|
struct page *page,
|
||||||
|
|
|
@ -2280,7 +2280,7 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb,
|
||||||
file->f_path.dentry->d_name.name,
|
file->f_path.dentry->d_name.name,
|
||||||
(unsigned int)from->nr_segs); /* GRRRRR */
|
(unsigned int)from->nr_segs); /* GRRRRR */
|
||||||
|
|
||||||
if (iocb->ki_nbytes == 0)
|
if (count == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
appending = file->f_flags & O_APPEND ? 1 : 0;
|
appending = file->f_flags & O_APPEND ? 1 : 0;
|
||||||
|
@ -2330,8 +2330,7 @@ relock:
|
||||||
}
|
}
|
||||||
|
|
||||||
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, count, 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);
|
||||||
|
@ -2339,8 +2338,7 @@ relock:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (direct_io && !is_sync_kiocb(iocb))
|
if (direct_io && !is_sync_kiocb(iocb))
|
||||||
unaligned_dio = ocfs2_is_io_unaligned(inode, iocb->ki_nbytes,
|
unaligned_dio = ocfs2_is_io_unaligned(inode, count, *ppos);
|
||||||
*ppos);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We can't complete the direct I/O as requested, fall back to
|
* We can't complete the direct I/O as requested, fall back to
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include <linux/audit.h>
|
#include <linux/audit.h>
|
||||||
#include <linux/syscalls.h>
|
#include <linux/syscalls.h>
|
||||||
#include <linux/fcntl.h>
|
#include <linux/fcntl.h>
|
||||||
#include <linux/aio.h>
|
|
||||||
|
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <asm/ioctls.h>
|
#include <asm/ioctls.h>
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
#include <linux/fcntl.h>
|
#include <linux/fcntl.h>
|
||||||
#include <linux/file.h>
|
#include <linux/file.h>
|
||||||
#include <linux/uio.h>
|
#include <linux/uio.h>
|
||||||
#include <linux/aio.h>
|
|
||||||
#include <linux/fsnotify.h>
|
#include <linux/fsnotify.h>
|
||||||
#include <linux/security.h>
|
#include <linux/security.h>
|
||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
|
@ -343,13 +342,10 @@ ssize_t vfs_iter_read(struct file *file, struct iov_iter *iter, loff_t *ppos)
|
||||||
|
|
||||||
init_sync_kiocb(&kiocb, file);
|
init_sync_kiocb(&kiocb, file);
|
||||||
kiocb.ki_pos = *ppos;
|
kiocb.ki_pos = *ppos;
|
||||||
kiocb.ki_nbytes = iov_iter_count(iter);
|
|
||||||
|
|
||||||
iter->type |= READ;
|
iter->type |= READ;
|
||||||
ret = file->f_op->read_iter(&kiocb, iter);
|
ret = file->f_op->read_iter(&kiocb, iter);
|
||||||
if (ret == -EIOCBQUEUED)
|
BUG_ON(ret == -EIOCBQUEUED);
|
||||||
ret = wait_on_sync_kiocb(&kiocb);
|
|
||||||
|
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
*ppos = kiocb.ki_pos;
|
*ppos = kiocb.ki_pos;
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -366,13 +362,10 @@ ssize_t vfs_iter_write(struct file *file, struct iov_iter *iter, loff_t *ppos)
|
||||||
|
|
||||||
init_sync_kiocb(&kiocb, file);
|
init_sync_kiocb(&kiocb, file);
|
||||||
kiocb.ki_pos = *ppos;
|
kiocb.ki_pos = *ppos;
|
||||||
kiocb.ki_nbytes = iov_iter_count(iter);
|
|
||||||
|
|
||||||
iter->type |= WRITE;
|
iter->type |= WRITE;
|
||||||
ret = file->f_op->write_iter(&kiocb, iter);
|
ret = file->f_op->write_iter(&kiocb, iter);
|
||||||
if (ret == -EIOCBQUEUED)
|
BUG_ON(ret == -EIOCBQUEUED);
|
||||||
ret = wait_on_sync_kiocb(&kiocb);
|
|
||||||
|
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
*ppos = kiocb.ki_pos;
|
*ppos = kiocb.ki_pos;
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -426,11 +419,9 @@ 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_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);
|
||||||
if (-EIOCBQUEUED == ret)
|
BUG_ON(ret == -EIOCBQUEUED);
|
||||||
ret = wait_on_sync_kiocb(&kiocb);
|
|
||||||
*ppos = kiocb.ki_pos;
|
*ppos = kiocb.ki_pos;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -446,12 +437,10 @@ ssize_t new_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *p
|
||||||
|
|
||||||
init_sync_kiocb(&kiocb, filp);
|
init_sync_kiocb(&kiocb, filp);
|
||||||
kiocb.ki_pos = *ppos;
|
kiocb.ki_pos = *ppos;
|
||||||
kiocb.ki_nbytes = len;
|
|
||||||
iov_iter_init(&iter, READ, &iov, 1, len);
|
iov_iter_init(&iter, READ, &iov, 1, len);
|
||||||
|
|
||||||
ret = filp->f_op->read_iter(&kiocb, &iter);
|
ret = filp->f_op->read_iter(&kiocb, &iter);
|
||||||
if (-EIOCBQUEUED == ret)
|
BUG_ON(ret == -EIOCBQUEUED);
|
||||||
ret = wait_on_sync_kiocb(&kiocb);
|
|
||||||
*ppos = kiocb.ki_pos;
|
*ppos = kiocb.ki_pos;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -510,11 +499,9 @@ 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_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);
|
||||||
if (-EIOCBQUEUED == ret)
|
BUG_ON(ret == -EIOCBQUEUED);
|
||||||
ret = wait_on_sync_kiocb(&kiocb);
|
|
||||||
*ppos = kiocb.ki_pos;
|
*ppos = kiocb.ki_pos;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -530,12 +517,10 @@ ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t len, lo
|
||||||
|
|
||||||
init_sync_kiocb(&kiocb, filp);
|
init_sync_kiocb(&kiocb, filp);
|
||||||
kiocb.ki_pos = *ppos;
|
kiocb.ki_pos = *ppos;
|
||||||
kiocb.ki_nbytes = len;
|
|
||||||
iov_iter_init(&iter, WRITE, &iov, 1, len);
|
iov_iter_init(&iter, WRITE, &iov, 1, len);
|
||||||
|
|
||||||
ret = filp->f_op->write_iter(&kiocb, &iter);
|
ret = filp->f_op->write_iter(&kiocb, &iter);
|
||||||
if (-EIOCBQUEUED == ret)
|
BUG_ON(ret == -EIOCBQUEUED);
|
||||||
ret = wait_on_sync_kiocb(&kiocb);
|
|
||||||
*ppos = kiocb.ki_pos;
|
*ppos = kiocb.ki_pos;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -719,12 +704,10 @@ static ssize_t do_iter_readv_writev(struct file *filp, int rw, const struct iove
|
||||||
|
|
||||||
init_sync_kiocb(&kiocb, filp);
|
init_sync_kiocb(&kiocb, filp);
|
||||||
kiocb.ki_pos = *ppos;
|
kiocb.ki_pos = *ppos;
|
||||||
kiocb.ki_nbytes = len;
|
|
||||||
|
|
||||||
iov_iter_init(&iter, rw, iov, nr_segs, len);
|
iov_iter_init(&iter, rw, iov, nr_segs, len);
|
||||||
ret = fn(&kiocb, &iter);
|
ret = fn(&kiocb, &iter);
|
||||||
if (ret == -EIOCBQUEUED)
|
BUG_ON(ret == -EIOCBQUEUED);
|
||||||
ret = wait_on_sync_kiocb(&kiocb);
|
|
||||||
*ppos = kiocb.ki_pos;
|
*ppos = kiocb.ki_pos;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -737,11 +720,9 @@ 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_nbytes = len;
|
|
||||||
|
|
||||||
ret = fn(&kiocb, iov, nr_segs, kiocb.ki_pos);
|
ret = fn(&kiocb, iov, nr_segs, kiocb.ki_pos);
|
||||||
if (ret == -EIOCBQUEUED)
|
BUG_ON(ret == -EIOCBQUEUED);
|
||||||
ret = wait_on_sync_kiocb(&kiocb);
|
|
||||||
*ppos = kiocb.ki_pos;
|
*ppos = kiocb.ki_pos;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
#include <linux/writeback.h>
|
#include <linux/writeback.h>
|
||||||
#include <linux/quotaops.h>
|
#include <linux/quotaops.h>
|
||||||
#include <linux/swap.h>
|
#include <linux/swap.h>
|
||||||
#include <linux/aio.h>
|
#include <linux/uio.h>
|
||||||
|
|
||||||
int reiserfs_commit_write(struct file *f, struct page *page,
|
int reiserfs_commit_write(struct file *f, struct page *page,
|
||||||
unsigned from, unsigned to);
|
unsigned from, unsigned to);
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
#include <linux/gfp.h>
|
#include <linux/gfp.h>
|
||||||
#include <linux/socket.h>
|
#include <linux/socket.h>
|
||||||
#include <linux/compat.h>
|
#include <linux/compat.h>
|
||||||
#include <linux/aio.h>
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -50,7 +50,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ubifs.h"
|
#include "ubifs.h"
|
||||||
#include <linux/aio.h>
|
|
||||||
#include <linux/mount.h>
|
#include <linux/mount.h>
|
||||||
#include <linux/namei.h>
|
#include <linux/namei.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/pagemap.h>
|
#include <linux/pagemap.h>
|
||||||
#include <linux/buffer_head.h>
|
#include <linux/buffer_head.h>
|
||||||
#include <linux/aio.h>
|
#include <linux/uio.h>
|
||||||
|
|
||||||
#include "udf_i.h"
|
#include "udf_i.h"
|
||||||
#include "udf_sb.h"
|
#include "udf_sb.h"
|
||||||
|
@ -122,7 +122,7 @@ static ssize_t udf_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
|
||||||
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_nbytes;
|
size_t count = iov_iter_count(from);
|
||||||
struct udf_inode_info *iinfo = UDF_I(inode);
|
struct udf_inode_info *iinfo = UDF_I(inode);
|
||||||
|
|
||||||
mutex_lock(&inode->i_mutex);
|
mutex_lock(&inode->i_mutex);
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/crc-itu-t.h>
|
#include <linux/crc-itu-t.h>
|
||||||
#include <linux/mpage.h>
|
#include <linux/mpage.h>
|
||||||
#include <linux/aio.h>
|
#include <linux/uio.h>
|
||||||
|
|
||||||
#include "udf_i.h"
|
#include "udf_i.h"
|
||||||
#include "udf_sb.h"
|
#include "udf_sb.h"
|
||||||
|
|
|
@ -31,7 +31,6 @@
|
||||||
#include "xfs_bmap.h"
|
#include "xfs_bmap.h"
|
||||||
#include "xfs_bmap_util.h"
|
#include "xfs_bmap_util.h"
|
||||||
#include "xfs_bmap_btree.h"
|
#include "xfs_bmap_btree.h"
|
||||||
#include <linux/aio.h>
|
|
||||||
#include <linux/gfp.h>
|
#include <linux/gfp.h>
|
||||||
#include <linux/mpage.h>
|
#include <linux/mpage.h>
|
||||||
#include <linux/pagevec.h>
|
#include <linux/pagevec.h>
|
||||||
|
|
|
@ -38,7 +38,6 @@
|
||||||
#include "xfs_icache.h"
|
#include "xfs_icache.h"
|
||||||
#include "xfs_pnfs.h"
|
#include "xfs_pnfs.h"
|
||||||
|
|
||||||
#include <linux/aio.h>
|
|
||||||
#include <linux/dcache.h>
|
#include <linux/dcache.h>
|
||||||
#include <linux/falloc.h>
|
#include <linux/falloc.h>
|
||||||
#include <linux/pagevec.h>
|
#include <linux/pagevec.h>
|
||||||
|
|
|
@ -1,86 +1,23 @@
|
||||||
#ifndef __LINUX__AIO_H
|
#ifndef __LINUX__AIO_H
|
||||||
#define __LINUX__AIO_H
|
#define __LINUX__AIO_H
|
||||||
|
|
||||||
#include <linux/list.h>
|
|
||||||
#include <linux/workqueue.h>
|
|
||||||
#include <linux/aio_abi.h>
|
#include <linux/aio_abi.h>
|
||||||
#include <linux/uio.h>
|
|
||||||
#include <linux/rcupdate.h>
|
|
||||||
|
|
||||||
#include <linux/atomic.h>
|
|
||||||
|
|
||||||
struct kioctx;
|
struct kioctx;
|
||||||
struct kiocb;
|
struct kiocb;
|
||||||
|
struct mm_struct;
|
||||||
|
|
||||||
#define KIOCB_KEY 0
|
#define KIOCB_KEY 0
|
||||||
|
|
||||||
/*
|
|
||||||
* We use ki_cancel == KIOCB_CANCELLED to indicate that a kiocb has been either
|
|
||||||
* cancelled or completed (this makes a certain amount of sense because
|
|
||||||
* successful cancellation - io_cancel() - does deliver the completion to
|
|
||||||
* userspace).
|
|
||||||
*
|
|
||||||
* And since most things don't implement kiocb cancellation and we'd really like
|
|
||||||
* kiocb completion to be lockless when possible, we use ki_cancel to
|
|
||||||
* synchronize cancellation and completion - we only set it to KIOCB_CANCELLED
|
|
||||||
* with xchg() or cmpxchg(), see batch_complete_aio() and kiocb_cancel().
|
|
||||||
*/
|
|
||||||
#define KIOCB_CANCELLED ((void *) (~0ULL))
|
|
||||||
|
|
||||||
typedef int (kiocb_cancel_fn)(struct kiocb *);
|
typedef int (kiocb_cancel_fn)(struct kiocb *);
|
||||||
|
|
||||||
struct kiocb {
|
|
||||||
struct file *ki_filp;
|
|
||||||
struct kioctx *ki_ctx; /* NULL for sync ops */
|
|
||||||
kiocb_cancel_fn *ki_cancel;
|
|
||||||
void *private;
|
|
||||||
|
|
||||||
union {
|
|
||||||
void __user *user;
|
|
||||||
struct task_struct *tsk;
|
|
||||||
} ki_obj;
|
|
||||||
|
|
||||||
__u64 ki_user_data; /* user's data for completion */
|
|
||||||
loff_t ki_pos;
|
|
||||||
size_t ki_nbytes; /* copy of iocb->aio_nbytes */
|
|
||||||
|
|
||||||
struct list_head ki_list; /* the aio core uses this
|
|
||||||
* for cancellation */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If the aio_resfd field of the userspace iocb is not zero,
|
|
||||||
* this is the underlying eventfd context to deliver events to.
|
|
||||||
*/
|
|
||||||
struct eventfd_ctx *ki_eventfd;
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline bool is_sync_kiocb(struct kiocb *kiocb)
|
|
||||||
{
|
|
||||||
return kiocb->ki_ctx == NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void init_sync_kiocb(struct kiocb *kiocb, struct file *filp)
|
|
||||||
{
|
|
||||||
*kiocb = (struct kiocb) {
|
|
||||||
.ki_ctx = NULL,
|
|
||||||
.ki_filp = filp,
|
|
||||||
.ki_obj.tsk = current,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/* prototypes */
|
/* prototypes */
|
||||||
#ifdef CONFIG_AIO
|
#ifdef CONFIG_AIO
|
||||||
extern ssize_t wait_on_sync_kiocb(struct kiocb *iocb);
|
|
||||||
extern void aio_complete(struct kiocb *iocb, long res, long res2);
|
|
||||||
struct mm_struct;
|
|
||||||
extern void exit_aio(struct mm_struct *mm);
|
extern void exit_aio(struct mm_struct *mm);
|
||||||
extern long do_io_submit(aio_context_t ctx_id, long nr,
|
extern long do_io_submit(aio_context_t ctx_id, long nr,
|
||||||
struct iocb __user *__user *iocbpp, bool compat);
|
struct iocb __user *__user *iocbpp, bool compat);
|
||||||
void kiocb_set_cancel_fn(struct kiocb *req, kiocb_cancel_fn *cancel);
|
void kiocb_set_cancel_fn(struct kiocb *req, kiocb_cancel_fn *cancel);
|
||||||
#else
|
#else
|
||||||
static inline ssize_t wait_on_sync_kiocb(struct kiocb *iocb) { return 0; }
|
|
||||||
static inline void aio_complete(struct kiocb *iocb, long res, long res2) { }
|
|
||||||
struct mm_struct;
|
|
||||||
static inline void exit_aio(struct mm_struct *mm) { }
|
static inline void exit_aio(struct mm_struct *mm) { }
|
||||||
static inline long do_io_submit(aio_context_t ctx_id, long nr,
|
static inline long do_io_submit(aio_context_t ctx_id, long nr,
|
||||||
struct iocb __user * __user *iocbpp,
|
struct iocb __user * __user *iocbpp,
|
||||||
|
@ -89,11 +26,6 @@ static inline void kiocb_set_cancel_fn(struct kiocb *req,
|
||||||
kiocb_cancel_fn *cancel) { }
|
kiocb_cancel_fn *cancel) { }
|
||||||
#endif /* CONFIG_AIO */
|
#endif /* CONFIG_AIO */
|
||||||
|
|
||||||
static inline struct kiocb *list_kiocb(struct list_head *h)
|
|
||||||
{
|
|
||||||
return list_entry(h, struct kiocb, ki_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* for sysctl: */
|
/* for sysctl: */
|
||||||
extern unsigned long aio_nr;
|
extern unsigned long aio_nr;
|
||||||
extern unsigned long aio_max_nr;
|
extern unsigned long aio_max_nr;
|
||||||
|
|
|
@ -314,6 +314,28 @@ struct page;
|
||||||
struct address_space;
|
struct address_space;
|
||||||
struct writeback_control;
|
struct writeback_control;
|
||||||
|
|
||||||
|
#define IOCB_EVENTFD (1 << 0)
|
||||||
|
|
||||||
|
struct kiocb {
|
||||||
|
struct file *ki_filp;
|
||||||
|
loff_t ki_pos;
|
||||||
|
void (*ki_complete)(struct kiocb *iocb, long ret, long ret2);
|
||||||
|
void *private;
|
||||||
|
int ki_flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline bool is_sync_kiocb(struct kiocb *kiocb)
|
||||||
|
{
|
||||||
|
return kiocb->ki_complete == NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void init_sync_kiocb(struct kiocb *kiocb, struct file *filp)
|
||||||
|
{
|
||||||
|
*kiocb = (struct kiocb) {
|
||||||
|
.ki_filp = filp,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "descriptor" for what we're up to with a read.
|
* "descriptor" for what we're up to with a read.
|
||||||
* This allows us to use the same read code yet
|
* This allows us to use the same read code yet
|
||||||
|
|
|
@ -57,7 +57,6 @@
|
||||||
#include <linux/page_counter.h>
|
#include <linux/page_counter.h>
|
||||||
#include <linux/memcontrol.h>
|
#include <linux/memcontrol.h>
|
||||||
#include <linux/static_key.h>
|
#include <linux/static_key.h>
|
||||||
#include <linux/aio.h>
|
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
|
|
||||||
#include <linux/filter.h>
|
#include <linux/filter.h>
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
#include <linux/security.h>
|
#include <linux/security.h>
|
||||||
#include <linux/bootmem.h>
|
#include <linux/bootmem.h>
|
||||||
#include <linux/memblock.h>
|
#include <linux/memblock.h>
|
||||||
#include <linux/aio.h>
|
|
||||||
#include <linux/syscalls.h>
|
#include <linux/syscalls.h>
|
||||||
#include <linux/kexec.h>
|
#include <linux/kexec.h>
|
||||||
#include <linux/kdb.h>
|
#include <linux/kdb.h>
|
||||||
|
@ -46,6 +45,7 @@
|
||||||
#include <linux/irq_work.h>
|
#include <linux/irq_work.h>
|
||||||
#include <linux/utsname.h>
|
#include <linux/utsname.h>
|
||||||
#include <linux/ctype.h>
|
#include <linux/ctype.h>
|
||||||
|
#include <linux/uio.h>
|
||||||
|
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
|
|
||||||
|
@ -521,7 +521,7 @@ static ssize_t devkmsg_write(struct kiocb *iocb, struct iov_iter *from)
|
||||||
int i;
|
int i;
|
||||||
int level = default_message_loglevel;
|
int level = default_message_loglevel;
|
||||||
int facility = 1; /* LOG_USER */
|
int facility = 1; /* LOG_USER */
|
||||||
size_t len = iocb->ki_nbytes;
|
size_t len = iov_iter_count(from);
|
||||||
ssize_t ret = len;
|
ssize_t ret = len;
|
||||||
|
|
||||||
if (len > LOG_LINE_MAX)
|
if (len > LOG_LINE_MAX)
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/aio.h>
|
||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
#include <linux/swap.h>
|
#include <linux/swap.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
#include <linux/aio.h>
|
|
||||||
#include <linux/capability.h>
|
#include <linux/capability.h>
|
||||||
#include <linux/kernel_stat.h>
|
#include <linux/kernel_stat.h>
|
||||||
#include <linux/gfp.h>
|
#include <linux/gfp.h>
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
#include <linux/buffer_head.h>
|
#include <linux/buffer_head.h>
|
||||||
#include <linux/writeback.h>
|
#include <linux/writeback.h>
|
||||||
#include <linux/frontswap.h>
|
#include <linux/frontswap.h>
|
||||||
#include <linux/aio.h>
|
|
||||||
#include <linux/blkdev.h>
|
#include <linux/blkdev.h>
|
||||||
|
#include <linux/uio.h>
|
||||||
#include <asm/pgtable.h>
|
#include <asm/pgtable.h>
|
||||||
|
|
||||||
static struct bio *get_swap_bio(gfp_t gfp_flags,
|
static struct bio *get_swap_bio(gfp_t gfp_flags,
|
||||||
|
@ -274,7 +274,6 @@ int __swap_writepage(struct page *page, struct writeback_control *wbc,
|
||||||
iov_iter_bvec(&from, ITER_BVEC | WRITE, &bv, 1, PAGE_SIZE);
|
iov_iter_bvec(&from, ITER_BVEC | WRITE, &bv, 1, PAGE_SIZE);
|
||||||
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_nbytes = PAGE_SIZE;
|
|
||||||
|
|
||||||
set_page_writeback(page);
|
set_page_writeback(page);
|
||||||
unlock_page(page);
|
unlock_page(page);
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
#include <linux/swap.h>
|
#include <linux/swap.h>
|
||||||
#include <linux/aio.h>
|
#include <linux/uio.h>
|
||||||
|
|
||||||
static struct vfsmount *shm_mnt;
|
static struct vfsmount *shm_mnt;
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,6 @@
|
||||||
#include <linux/stddef.h>
|
#include <linux/stddef.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/aio.h>
|
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
|
|
|
@ -808,10 +808,10 @@ static ssize_t sock_read_iter(struct kiocb *iocb, struct iov_iter *to)
|
||||||
if (iocb->ki_pos != 0)
|
if (iocb->ki_pos != 0)
|
||||||
return -ESPIPE;
|
return -ESPIPE;
|
||||||
|
|
||||||
if (iocb->ki_nbytes == 0) /* Match SYS5 behaviour */
|
if (!iov_iter_count(to)) /* Match SYS5 behaviour */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
res = sock_recvmsg(sock, &msg, iocb->ki_nbytes, msg.msg_flags);
|
res = sock_recvmsg(sock, &msg, iov_iter_count(to), msg.msg_flags);
|
||||||
*to = msg.msg_iter;
|
*to = msg.msg_iter;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -833,7 +833,7 @@ static ssize_t sock_write_iter(struct kiocb *iocb, struct iov_iter *from)
|
||||||
if (sock->type == SOCK_SEQPACKET)
|
if (sock->type == SOCK_SEQPACKET)
|
||||||
msg.msg_flags |= MSG_EOR;
|
msg.msg_flags |= MSG_EOR;
|
||||||
|
|
||||||
res = sock_sendmsg(sock, &msg, iocb->ki_nbytes);
|
res = sock_sendmsg(sock, &msg, iov_iter_count(from));
|
||||||
*from = msg.msg_iter;
|
*from = msg.msg_iter;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/time.h>
|
#include <linux/time.h>
|
||||||
#include <linux/pm_qos.h>
|
#include <linux/pm_qos.h>
|
||||||
#include <linux/aio.h>
|
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/dma-mapping.h>
|
#include <linux/dma-mapping.h>
|
||||||
#include <sound/core.h>
|
#include <sound/core.h>
|
||||||
|
@ -35,6 +34,7 @@
|
||||||
#include <sound/pcm_params.h>
|
#include <sound/pcm_params.h>
|
||||||
#include <sound/timer.h>
|
#include <sound/timer.h>
|
||||||
#include <sound/minors.h>
|
#include <sound/minors.h>
|
||||||
|
#include <linux/uio.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compatibility
|
* Compatibility
|
||||||
|
|
Загрузка…
Ссылка в новой задаче