mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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>
This commit is contained in:
		
							parent
							
								
									6987843ff7
								
							
						
					
					
						commit
						71ad7490c1
					
				
					 1 changed files with 57 additions and 6 deletions
				
			
		
							
								
								
									
										63
									
								
								fs/aio.c
									
									
									
									
									
								
							
							
						
						
									
										63
									
								
								fs/aio.c
									
									
									
									
									
								
							| 
						 | 
					@ -36,10 +36,10 @@
 | 
				
			||||||
#include <linux/eventfd.h>
 | 
					#include <linux/eventfd.h>
 | 
				
			||||||
#include <linux/blkdev.h>
 | 
					#include <linux/blkdev.h>
 | 
				
			||||||
#include <linux/compat.h>
 | 
					#include <linux/compat.h>
 | 
				
			||||||
#include <linux/anon_inodes.h>
 | 
					 | 
				
			||||||
#include <linux/migrate.h>
 | 
					#include <linux/migrate.h>
 | 
				
			||||||
#include <linux/ramfs.h>
 | 
					#include <linux/ramfs.h>
 | 
				
			||||||
#include <linux/percpu-refcount.h>
 | 
					#include <linux/percpu-refcount.h>
 | 
				
			||||||
 | 
					#include <linux/mount.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <asm/kmap_types.h>
 | 
					#include <asm/kmap_types.h>
 | 
				
			||||||
#include <asm/uaccess.h>
 | 
					#include <asm/uaccess.h>
 | 
				
			||||||
| 
						 | 
					@ -152,12 +152,67 @@ unsigned long aio_max_nr = 0x10000; /* system wide maximum number of aio request
 | 
				
			||||||
static struct kmem_cache	*kiocb_cachep;
 | 
					static struct kmem_cache	*kiocb_cachep;
 | 
				
			||||||
static struct kmem_cache	*kioctx_cachep;
 | 
					static struct kmem_cache	*kioctx_cachep;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct vfsmount *aio_mnt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct file_operations aio_ring_fops;
 | 
				
			||||||
 | 
					static const struct address_space_operations aio_ctx_aops;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct file *aio_private_file(struct kioctx *ctx, loff_t nr_pages)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct qstr this = QSTR_INIT("[aio]", 5);
 | 
				
			||||||
 | 
						struct file *file;
 | 
				
			||||||
 | 
						struct path path;
 | 
				
			||||||
 | 
						struct inode *inode = alloc_anon_inode(aio_mnt->mnt_sb);
 | 
				
			||||||
 | 
						if (!inode)
 | 
				
			||||||
 | 
							return ERR_PTR(-ENOMEM);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						inode->i_mapping->a_ops = &aio_ctx_aops;
 | 
				
			||||||
 | 
						inode->i_mapping->private_data = ctx;
 | 
				
			||||||
 | 
						inode->i_size = PAGE_SIZE * nr_pages;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						path.dentry = d_alloc_pseudo(aio_mnt->mnt_sb, &this);
 | 
				
			||||||
 | 
						if (!path.dentry) {
 | 
				
			||||||
 | 
							iput(inode);
 | 
				
			||||||
 | 
							return ERR_PTR(-ENOMEM);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						path.mnt = mntget(aio_mnt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						d_instantiate(path.dentry, inode);
 | 
				
			||||||
 | 
						file = alloc_file(&path, FMODE_READ | FMODE_WRITE, &aio_ring_fops);
 | 
				
			||||||
 | 
						if (IS_ERR(file)) {
 | 
				
			||||||
 | 
							path_put(&path);
 | 
				
			||||||
 | 
							return file;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						file->f_flags = O_RDWR;
 | 
				
			||||||
 | 
						file->private_data = ctx;
 | 
				
			||||||
 | 
						return file;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct dentry *aio_mount(struct file_system_type *fs_type,
 | 
				
			||||||
 | 
									int flags, const char *dev_name, void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						static const struct dentry_operations ops = {
 | 
				
			||||||
 | 
							.d_dname	= simple_dname,
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						return mount_pseudo(fs_type, "aio:", NULL, &ops, 0xa10a10a1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* aio_setup
 | 
					/* aio_setup
 | 
				
			||||||
 *	Creates the slab caches used by the aio routines, panic on
 | 
					 *	Creates the slab caches used by the aio routines, panic on
 | 
				
			||||||
 *	failure as this is done early during the boot sequence.
 | 
					 *	failure as this is done early during the boot sequence.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static int __init aio_setup(void)
 | 
					static int __init aio_setup(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						static struct file_system_type aio_fs = {
 | 
				
			||||||
 | 
							.name		= "aio",
 | 
				
			||||||
 | 
							.mount		= aio_mount,
 | 
				
			||||||
 | 
							.kill_sb	= kill_anon_super,
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						aio_mnt = kern_mount(&aio_fs);
 | 
				
			||||||
 | 
						if (IS_ERR(aio_mnt))
 | 
				
			||||||
 | 
							panic("Failed to create aio fs mount.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	kiocb_cachep = KMEM_CACHE(kiocb, SLAB_HWCACHE_ALIGN|SLAB_PANIC);
 | 
						kiocb_cachep = KMEM_CACHE(kiocb, SLAB_HWCACHE_ALIGN|SLAB_PANIC);
 | 
				
			||||||
	kioctx_cachep = KMEM_CACHE(kioctx,SLAB_HWCACHE_ALIGN|SLAB_PANIC);
 | 
						kioctx_cachep = KMEM_CACHE(kioctx,SLAB_HWCACHE_ALIGN|SLAB_PANIC);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -283,16 +338,12 @@ static int aio_setup_ring(struct kioctx *ctx)
 | 
				
			||||||
	if (nr_pages < 0)
 | 
						if (nr_pages < 0)
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	file = anon_inode_getfile_private("[aio]", &aio_ring_fops, ctx, O_RDWR);
 | 
						file = aio_private_file(ctx, nr_pages);
 | 
				
			||||||
	if (IS_ERR(file)) {
 | 
						if (IS_ERR(file)) {
 | 
				
			||||||
		ctx->aio_ring_file = NULL;
 | 
							ctx->aio_ring_file = NULL;
 | 
				
			||||||
		return -EAGAIN;
 | 
							return -EAGAIN;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	file->f_inode->i_mapping->a_ops = &aio_ctx_aops;
 | 
					 | 
				
			||||||
	file->f_inode->i_mapping->private_data = ctx;
 | 
					 | 
				
			||||||
	file->f_inode->i_size = PAGE_SIZE * (loff_t)nr_pages;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for (i = 0; i < nr_pages; i++) {
 | 
						for (i = 0; i < nr_pages; i++) {
 | 
				
			||||||
		struct page *page;
 | 
							struct page *page;
 | 
				
			||||||
		page = find_or_create_page(file->f_inode->i_mapping,
 | 
							page = find_or_create_page(file->f_inode->i_mapping,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue