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 */ |
