diff options
author | Christoph Hellwig <hch@infradead.org> | 2013-09-04 09:04:39 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2013-09-04 09:23:46 -0400 |
commit | 7b7a8665edd8db733980389b098530f9e4f630b2 (patch) | |
tree | 968d570a9f0c4d861226aefed2f5f97a131c8d53 /include/linux | |
parent | 4b6ccca701ef5977d0ffbc2c932430dea88b38b6 (diff) |
direct-io: Implement generic deferred AIO completions
Add support to the core direct-io code to defer AIO completions to user
context using a workqueue. This replaces opencoded and less efficient
code in XFS and ext4 (we save a memory allocation for each direct IO)
and will be needed to properly support O_(D)SYNC for AIO.
The communication between the filesystem and the direct I/O code requires
a new buffer head flag, which is a bit ugly but not avoidable until the
direct I/O code stops abusing the buffer_head structure for communicating
with the filesystems.
Currently this creates a per-superblock unbound workqueue for these
completions, which is taken from an earlier patch by Jan Kara. I'm
not really convinced about this use and would prefer a "normal" global
workqueue with a high concurrency limit, but this needs further discussion.
JK: Fixed ext4 part, dynamic allocation of the workqueue.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/buffer_head.h | 2 | ||||
-rw-r--r-- | include/linux/fs.h | 7 |
2 files changed, 7 insertions, 2 deletions
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h index 91fa9a94ae92..d77797a52b7b 100644 --- a/include/linux/buffer_head.h +++ b/include/linux/buffer_head.h | |||
@@ -36,6 +36,7 @@ enum bh_state_bits { | |||
36 | BH_Quiet, /* Buffer Error Prinks to be quiet */ | 36 | BH_Quiet, /* Buffer Error Prinks to be quiet */ |
37 | BH_Meta, /* Buffer contains metadata */ | 37 | BH_Meta, /* Buffer contains metadata */ |
38 | BH_Prio, /* Buffer should be submitted with REQ_PRIO */ | 38 | BH_Prio, /* Buffer should be submitted with REQ_PRIO */ |
39 | BH_Defer_Completion, /* Defer AIO completion to workqueue */ | ||
39 | 40 | ||
40 | BH_PrivateStart,/* not a state bit, but the first bit available | 41 | BH_PrivateStart,/* not a state bit, but the first bit available |
41 | * for private allocation by other entities | 42 | * for private allocation by other entities |
@@ -128,6 +129,7 @@ BUFFER_FNS(Write_EIO, write_io_error) | |||
128 | BUFFER_FNS(Unwritten, unwritten) | 129 | BUFFER_FNS(Unwritten, unwritten) |
129 | BUFFER_FNS(Meta, meta) | 130 | BUFFER_FNS(Meta, meta) |
130 | BUFFER_FNS(Prio, prio) | 131 | BUFFER_FNS(Prio, prio) |
132 | BUFFER_FNS(Defer_Completion, defer_completion) | ||
131 | 133 | ||
132 | #define bh_offset(bh) ((unsigned long)(bh)->b_data & ~PAGE_MASK) | 134 | #define bh_offset(bh) ((unsigned long)(bh)->b_data & ~PAGE_MASK) |
133 | 135 | ||
diff --git a/include/linux/fs.h b/include/linux/fs.h index 65c9929cd340..c9013876eb29 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -46,6 +46,7 @@ struct vfsmount; | |||
46 | struct cred; | 46 | struct cred; |
47 | struct swap_info_struct; | 47 | struct swap_info_struct; |
48 | struct seq_file; | 48 | struct seq_file; |
49 | struct workqueue_struct; | ||
49 | 50 | ||
50 | extern void __init inode_init(void); | 51 | extern void __init inode_init(void); |
51 | extern void __init inode_init_early(void); | 52 | extern void __init inode_init_early(void); |
@@ -63,8 +64,7 @@ struct buffer_head; | |||
63 | typedef int (get_block_t)(struct inode *inode, sector_t iblock, | 64 | typedef int (get_block_t)(struct inode *inode, sector_t iblock, |
64 | struct buffer_head *bh_result, int create); | 65 | struct buffer_head *bh_result, int create); |
65 | typedef void (dio_iodone_t)(struct kiocb *iocb, loff_t offset, | 66 | typedef void (dio_iodone_t)(struct kiocb *iocb, loff_t offset, |
66 | ssize_t bytes, void *private, int ret, | 67 | ssize_t bytes, void *private); |
67 | bool is_async); | ||
68 | 68 | ||
69 | #define MAY_EXEC 0x00000001 | 69 | #define MAY_EXEC 0x00000001 |
70 | #define MAY_WRITE 0x00000002 | 70 | #define MAY_WRITE 0x00000002 |
@@ -1328,6 +1328,9 @@ struct super_block { | |||
1328 | 1328 | ||
1329 | /* Being remounted read-only */ | 1329 | /* Being remounted read-only */ |
1330 | int s_readonly_remount; | 1330 | int s_readonly_remount; |
1331 | |||
1332 | /* AIO completions deferred from interrupt context */ | ||
1333 | struct workqueue_struct *s_dio_done_wq; | ||
1331 | }; | 1334 | }; |
1332 | 1335 | ||
1333 | /* superblock cache pruning functions */ | 1336 | /* superblock cache pruning functions */ |