aboutsummaryrefslogtreecommitdiffstats
path: root/fs/super.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2013-09-04 09:04:39 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-09-04 09:23:46 -0400
commit7b7a8665edd8db733980389b098530f9e4f630b2 (patch)
tree968d570a9f0c4d861226aefed2f5f97a131c8d53 /fs/super.c
parent4b6ccca701ef5977d0ffbc2c932430dea88b38b6 (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 'fs/super.c')
-rw-r--r--fs/super.c18
1 files changed, 9 insertions, 9 deletions
diff --git a/fs/super.c b/fs/super.c
index 68307c029228..5536a95186e2 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -152,15 +152,9 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags)
152 static const struct super_operations default_op; 152 static const struct super_operations default_op;
153 153
154 if (s) { 154 if (s) {
155 if (security_sb_alloc(s)) { 155 if (security_sb_alloc(s))
156 /* 156 goto out_free_sb;
157 * We cannot call security_sb_free() without 157
158 * security_sb_alloc() succeeding. So bail out manually
159 */
160 kfree(s);
161 s = NULL;
162 goto out;
163 }
164#ifdef CONFIG_SMP 158#ifdef CONFIG_SMP
165 s->s_files = alloc_percpu(struct list_head); 159 s->s_files = alloc_percpu(struct list_head);
166 if (!s->s_files) 160 if (!s->s_files)
@@ -228,6 +222,7 @@ err_out:
228 free_percpu(s->s_files); 222 free_percpu(s->s_files);
229#endif 223#endif
230 destroy_sb_writers(s); 224 destroy_sb_writers(s);
225out_free_sb:
231 kfree(s); 226 kfree(s);
232 s = NULL; 227 s = NULL;
233 goto out; 228 goto out;
@@ -414,6 +409,11 @@ void generic_shutdown_super(struct super_block *sb)
414 409
415 evict_inodes(sb); 410 evict_inodes(sb);
416 411
412 if (sb->s_dio_done_wq) {
413 destroy_workqueue(sb->s_dio_done_wq);
414 sb->s_dio_done_wq = NULL;
415 }
416
417 if (sop->put_super) 417 if (sop->put_super)
418 sop->put_super(sb); 418 sop->put_super(sb);
419 419