aboutsummaryrefslogtreecommitdiffstats
path: root/fs/aio.c
diff options
context:
space:
mode:
authorBenjamin LaHaise <bcrl@kvack.org>2013-09-17 10:18:25 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-11-09 00:16:28 -0500
commit71ad7490c1f32bd7829df76360f9fa17829868f3 (patch)
tree60415c4319102944aedd0ada63bf9ba26f985419 /fs/aio.c
parent6987843ff7e836ea65b554905aec34d2fad05c94 (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.c63
1 files changed, 57 insertions, 6 deletions
diff --git a/fs/aio.c b/fs/aio.c
index 067e3d340c35..1f602d9be4c5 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -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
152static struct kmem_cache *kiocb_cachep; 152static struct kmem_cache *kiocb_cachep;
153static struct kmem_cache *kioctx_cachep; 153static struct kmem_cache *kioctx_cachep;
154 154
155static struct vfsmount *aio_mnt;
156
157static const struct file_operations aio_ring_fops;
158static const struct address_space_operations aio_ctx_aops;
159
160static 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
192static 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 */
159static int __init aio_setup(void) 205static 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,