diff options
author | Benjamin LaHaise <bcrl@kvack.org> | 2013-09-17 10:18:25 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2013-11-09 00:16:28 -0500 |
commit | 71ad7490c1f32bd7829df76360f9fa17829868f3 (patch) | |
tree | 60415c4319102944aedd0ada63bf9ba26f985419 /fs/aio.c | |
parent | 6987843ff7e836ea65b554905aec34d2fad05c94 (diff) |
rework aio migrate pages to use aio fs
Don't abuse anon_inodes.c to host private files needed by aio;
we can bloody well declare a mini-fs of our own instead of
patching up what anon_inodes can create for us.
Tested-by: Benjamin LaHaise <bcrl@kvack.org>
Acked-by: Benjamin LaHaise <bcrl@kvack.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/aio.c')
-rw-r--r-- | fs/aio.c | 63 |
1 files changed, 57 insertions, 6 deletions
@@ -36,10 +36,10 @@ | |||
36 | #include <linux/eventfd.h> | 36 | #include <linux/eventfd.h> |
37 | #include <linux/blkdev.h> | 37 | #include <linux/blkdev.h> |
38 | #include <linux/compat.h> | 38 | #include <linux/compat.h> |
39 | #include <linux/anon_inodes.h> | ||
40 | #include <linux/migrate.h> | 39 | #include <linux/migrate.h> |
41 | #include <linux/ramfs.h> | 40 | #include <linux/ramfs.h> |
42 | #include <linux/percpu-refcount.h> | 41 | #include <linux/percpu-refcount.h> |
42 | #include <linux/mount.h> | ||
43 | 43 | ||
44 | #include <asm/kmap_types.h> | 44 | #include <asm/kmap_types.h> |
45 | #include <asm/uaccess.h> | 45 | #include <asm/uaccess.h> |
@@ -152,12 +152,67 @@ unsigned long aio_max_nr = 0x10000; /* system wide maximum number of aio request | |||
152 | static struct kmem_cache *kiocb_cachep; | 152 | static struct kmem_cache *kiocb_cachep; |
153 | static struct kmem_cache *kioctx_cachep; | 153 | static struct kmem_cache *kioctx_cachep; |
154 | 154 | ||
155 | static struct vfsmount *aio_mnt; | ||
156 | |||
157 | static const struct file_operations aio_ring_fops; | ||
158 | static const struct address_space_operations aio_ctx_aops; | ||
159 | |||
160 | static struct file *aio_private_file(struct kioctx *ctx, loff_t nr_pages) | ||
161 | { | ||
162 | struct qstr this = QSTR_INIT("[aio]", 5); | ||
163 | struct file *file; | ||
164 | struct path path; | ||
165 | struct inode *inode = alloc_anon_inode(aio_mnt->mnt_sb); | ||
166 | if (!inode) | ||
167 | return ERR_PTR(-ENOMEM); | ||
168 | |||
169 | inode->i_mapping->a_ops = &aio_ctx_aops; | ||
170 | inode->i_mapping->private_data = ctx; | ||
171 | inode->i_size = PAGE_SIZE * nr_pages; | ||
172 | |||
173 | path.dentry = d_alloc_pseudo(aio_mnt->mnt_sb, &this); | ||
174 | if (!path.dentry) { | ||
175 | iput(inode); | ||
176 | return ERR_PTR(-ENOMEM); | ||
177 | } | ||
178 | path.mnt = mntget(aio_mnt); | ||
179 | |||
180 | d_instantiate(path.dentry, inode); | ||
181 | file = alloc_file(&path, FMODE_READ | FMODE_WRITE, &aio_ring_fops); | ||
182 | if (IS_ERR(file)) { | ||
183 | path_put(&path); | ||
184 | return file; | ||
185 | } | ||
186 | |||
187 | file->f_flags = O_RDWR; | ||
188 | file->private_data = ctx; | ||
189 | return file; | ||
190 | } | ||
191 | |||
192 | static struct dentry *aio_mount(struct file_system_type *fs_type, | ||
193 | int flags, const char *dev_name, void *data) | ||
194 | { | ||
195 | static const struct dentry_operations ops = { | ||
196 | .d_dname = simple_dname, | ||
197 | }; | ||
198 | return mount_pseudo(fs_type, "aio:", NULL, &ops, 0xa10a10a1); | ||
199 | } | ||
200 | |||
155 | /* aio_setup | 201 | /* aio_setup |
156 | * Creates the slab caches used by the aio routines, panic on | 202 | * Creates the slab caches used by the aio routines, panic on |
157 | * failure as this is done early during the boot sequence. | 203 | * failure as this is done early during the boot sequence. |
158 | */ | 204 | */ |
159 | static int __init aio_setup(void) | 205 | static int __init aio_setup(void) |
160 | { | 206 | { |
207 | static struct file_system_type aio_fs = { | ||
208 | .name = "aio", | ||
209 | .mount = aio_mount, | ||
210 | .kill_sb = kill_anon_super, | ||
211 | }; | ||
212 | aio_mnt = kern_mount(&aio_fs); | ||
213 | if (IS_ERR(aio_mnt)) | ||
214 | panic("Failed to create aio fs mount."); | ||
215 | |||
161 | kiocb_cachep = KMEM_CACHE(kiocb, SLAB_HWCACHE_ALIGN|SLAB_PANIC); | 216 | kiocb_cachep = KMEM_CACHE(kiocb, SLAB_HWCACHE_ALIGN|SLAB_PANIC); |
162 | kioctx_cachep = KMEM_CACHE(kioctx,SLAB_HWCACHE_ALIGN|SLAB_PANIC); | 217 | kioctx_cachep = KMEM_CACHE(kioctx,SLAB_HWCACHE_ALIGN|SLAB_PANIC); |
163 | 218 | ||
@@ -283,16 +338,12 @@ static int aio_setup_ring(struct kioctx *ctx) | |||
283 | if (nr_pages < 0) | 338 | if (nr_pages < 0) |
284 | return -EINVAL; | 339 | return -EINVAL; |
285 | 340 | ||
286 | file = anon_inode_getfile_private("[aio]", &aio_ring_fops, ctx, O_RDWR); | 341 | file = aio_private_file(ctx, nr_pages); |
287 | if (IS_ERR(file)) { | 342 | if (IS_ERR(file)) { |
288 | ctx->aio_ring_file = NULL; | 343 | ctx->aio_ring_file = NULL; |
289 | return -EAGAIN; | 344 | return -EAGAIN; |
290 | } | 345 | } |
291 | 346 | ||
292 | file->f_inode->i_mapping->a_ops = &aio_ctx_aops; | ||
293 | file->f_inode->i_mapping->private_data = ctx; | ||
294 | file->f_inode->i_size = PAGE_SIZE * (loff_t)nr_pages; | ||
295 | |||
296 | for (i = 0; i < nr_pages; i++) { | 347 | for (i = 0; i < nr_pages; i++) { |
297 | struct page *page; | 348 | struct page *page; |
298 | page = find_or_create_page(file->f_inode->i_mapping, | 349 | page = find_or_create_page(file->f_inode->i_mapping, |