aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2015-02-02 08:49:06 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2015-03-13 12:10:27 -0400
commit04b2fa9f8f36ec6fb6fd1c9dc9df6fff0cd27323 (patch)
treef9fdc8004b4decca27e30da1614529eaf1455136 /include
parent599bd19bdc4c6b20fd91d50f2f79dececbaf80c1 (diff)
fs: split generic and aio kiocb
Most callers in the kernel want to perform synchronous file I/O, but still have to bloat the stack with a full struct kiocb. Split out the parts needed in filesystem code from those in the aio code, and only allocate those needed to pass down argument on the stack. The aio code embedds the generic iocb in the one it allocates and can easily get back to it by using container_of. Also add a ->ki_complete method to struct kiocb, this is used to call into the aio code and thus removes the dependency on aio for filesystems impementing asynchronous operations. It will also allow other callers to substitute their own completion callback. We also add a new ->ki_flags field to work around the nasty layering violation recently introduced in commit 5e33f6 ("usb: gadget: ffs: add eventfd notification about ffs events"). Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'include')
-rw-r--r--include/linux/aio.h46
1 files changed, 6 insertions, 40 deletions
diff --git a/include/linux/aio.h b/include/linux/aio.h
index f8516430490d..5c40b61285ac 100644
--- a/include/linux/aio.h
+++ b/include/linux/aio.h
@@ -14,67 +14,38 @@ struct kiocb;
14 14
15#define KIOCB_KEY 0 15#define KIOCB_KEY 0
16 16
17/*
18 * We use ki_cancel == KIOCB_CANCELLED to indicate that a kiocb has been either
19 * cancelled or completed (this makes a certain amount of sense because
20 * successful cancellation - io_cancel() - does deliver the completion to
21 * userspace).
22 *
23 * And since most things don't implement kiocb cancellation and we'd really like
24 * kiocb completion to be lockless when possible, we use ki_cancel to
25 * synchronize cancellation and completion - we only set it to KIOCB_CANCELLED
26 * with xchg() or cmpxchg(), see batch_complete_aio() and kiocb_cancel().
27 */
28#define KIOCB_CANCELLED ((void *) (~0ULL))
29
30typedef int (kiocb_cancel_fn)(struct kiocb *); 17typedef int (kiocb_cancel_fn)(struct kiocb *);
31 18
19#define IOCB_EVENTFD (1 << 0)
20
32struct kiocb { 21struct kiocb {
33 struct file *ki_filp; 22 struct file *ki_filp;
34 struct kioctx *ki_ctx; /* NULL for sync ops */
35 kiocb_cancel_fn *ki_cancel;
36 void *private;
37
38 union {
39 void __user *user;
40 } ki_obj;
41
42 __u64 ki_user_data; /* user's data for completion */
43 loff_t ki_pos; 23 loff_t ki_pos;
44 24 void (*ki_complete)(struct kiocb *iocb, long ret, long ret2);
45 struct list_head ki_list; /* the aio core uses this 25 void *private;
46 * for cancellation */ 26 int ki_flags;
47
48 /*
49 * If the aio_resfd field of the userspace iocb is not zero,
50 * this is the underlying eventfd context to deliver events to.
51 */
52 struct eventfd_ctx *ki_eventfd;
53}; 27};
54 28
55static inline bool is_sync_kiocb(struct kiocb *kiocb) 29static inline bool is_sync_kiocb(struct kiocb *kiocb)
56{ 30{
57 return kiocb->ki_ctx == NULL; 31 return kiocb->ki_complete == NULL;
58} 32}
59 33
60static inline void init_sync_kiocb(struct kiocb *kiocb, struct file *filp) 34static inline void init_sync_kiocb(struct kiocb *kiocb, struct file *filp)
61{ 35{
62 *kiocb = (struct kiocb) { 36 *kiocb = (struct kiocb) {
63 .ki_ctx = NULL,
64 .ki_filp = filp, 37 .ki_filp = filp,
65 }; 38 };
66} 39}
67 40
68/* prototypes */ 41/* prototypes */
69#ifdef CONFIG_AIO 42#ifdef CONFIG_AIO
70extern void aio_complete(struct kiocb *iocb, long res, long res2);
71struct mm_struct; 43struct mm_struct;
72extern void exit_aio(struct mm_struct *mm); 44extern void exit_aio(struct mm_struct *mm);
73extern long do_io_submit(aio_context_t ctx_id, long nr, 45extern long do_io_submit(aio_context_t ctx_id, long nr,
74 struct iocb __user *__user *iocbpp, bool compat); 46 struct iocb __user *__user *iocbpp, bool compat);
75void kiocb_set_cancel_fn(struct kiocb *req, kiocb_cancel_fn *cancel); 47void kiocb_set_cancel_fn(struct kiocb *req, kiocb_cancel_fn *cancel);
76#else 48#else
77static inline void aio_complete(struct kiocb *iocb, long res, long res2) { }
78struct mm_struct; 49struct mm_struct;
79static inline void exit_aio(struct mm_struct *mm) { } 50static inline void exit_aio(struct mm_struct *mm) { }
80static inline long do_io_submit(aio_context_t ctx_id, long nr, 51static inline long do_io_submit(aio_context_t ctx_id, long nr,
@@ -84,11 +55,6 @@ static inline void kiocb_set_cancel_fn(struct kiocb *req,
84 kiocb_cancel_fn *cancel) { } 55 kiocb_cancel_fn *cancel) { }
85#endif /* CONFIG_AIO */ 56#endif /* CONFIG_AIO */
86 57
87static inline struct kiocb *list_kiocb(struct list_head *h)
88{
89 return list_entry(h, struct kiocb, ki_list);
90}
91
92/* for sysctl: */ 58/* for sysctl: */
93extern unsigned long aio_nr; 59extern unsigned long aio_nr;
94extern unsigned long aio_max_nr; 60extern unsigned long aio_max_nr;