aboutsummaryrefslogtreecommitdiff
path: root/fs/anon_inodes.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/anon_inodes.c')
-rw-r--r--fs/anon_inodes.c108
1 files changed, 22 insertions, 86 deletions
diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c
index 57ce55b2564..80ef38c73e5 100644
--- a/fs/anon_inodes.c
+++ b/fs/anon_inodes.c
@@ -24,13 +24,6 @@
static struct vfsmount *anon_inode_mnt __read_mostly;
static struct inode *anon_inode_inode;
-static const struct file_operations anon_inode_fops;
-
-static struct dentry *anon_inodefs_mount(struct file_system_type *fs_type,
- int flags, const char *dev_name, void *data)
-{
- return mount_pseudo(fs_type, "anon_inode:", NULL, ANON_INODE_FS_MAGIC);
-}
/*
* anon_inodefs_dname() is called from d_path().
@@ -41,32 +34,27 @@ static char *anon_inodefs_dname(struct dentry *dentry, char *buffer, int buflen)
dentry->d_name.name);
}
-static struct file_system_type anon_inode_fs_type = {
- .name = "anon_inodefs",
- .mount = anon_inodefs_mount,
- .kill_sb = kill_anon_super,
-};
static const struct dentry_operations anon_inodefs_dentry_operations = {
.d_dname = anon_inodefs_dname,
};
-/*
- * nop .set_page_dirty method so that people can use .page_mkwrite on
- * anon inodes.
- */
-static int anon_set_page_dirty(struct page *page)
+static struct dentry *anon_inodefs_mount(struct file_system_type *fs_type,
+ int flags, const char *dev_name, void *data)
{
- return 0;
-};
+ return mount_pseudo(fs_type, "anon_inode:", NULL,
+ &anon_inodefs_dentry_operations, ANON_INODE_FS_MAGIC);
+}
-static const struct address_space_operations anon_aops = {
- .set_page_dirty = anon_set_page_dirty,
+static struct file_system_type anon_inode_fs_type = {
+ .name = "anon_inodefs",
+ .mount = anon_inodefs_mount,
+ .kill_sb = kill_anon_super,
};
/**
- * anon_inode_getfd - creates a new file instance by hooking it up to an
- * anonymous inode, and a dentry that describe the "class"
- * of the file
+ * anon_inode_getfile - creates a new file instance by hooking it up to an
+ * anonymous inode, and a dentry that describe the "class"
+ * of the file
*
* @name: [in] name of the "class" of the new file
* @fops: [in] file operations for the new file
@@ -86,7 +74,6 @@ struct file *anon_inode_getfile(const char *name,
struct qstr this;
struct path path;
struct file *file;
- int error;
if (IS_ERR(anon_inode_inode))
return ERR_PTR(-ENODEV);
@@ -98,11 +85,11 @@ struct file *anon_inode_getfile(const char *name,
* Link the inode to a directory entry by creating a unique name
* using the inode sequence number.
*/
- error = -ENOMEM;
+ file = ERR_PTR(-ENOMEM);
this.name = name;
this.len = strlen(name);
this.hash = 0;
- path.dentry = d_alloc(anon_inode_mnt->mnt_sb->s_root, &this);
+ path.dentry = d_alloc_pseudo(anon_inode_mnt->mnt_sb, &this);
if (!path.dentry)
goto err_module;
@@ -113,18 +100,14 @@ struct file *anon_inode_getfile(const char *name,
*/
ihold(anon_inode_inode);
- path.dentry->d_op = &anon_inodefs_dentry_operations;
d_instantiate(path.dentry, anon_inode_inode);
- error = -ENFILE;
file = alloc_file(&path, OPEN_FMODE(flags), fops);
- if (!file)
+ if (IS_ERR(file))
goto err_dput;
file->f_mapping = anon_inode_inode->i_mapping;
- file->f_pos = 0;
file->f_flags = flags & (O_ACCMODE | O_NONBLOCK);
- file->f_version = 0;
file->private_data = priv;
return file;
@@ -133,7 +116,7 @@ err_dput:
path_put(&path);
err_module:
module_put(fops->owner);
- return ERR_PTR(error);
+ return file;
}
EXPORT_SYMBOL_GPL(anon_inode_getfile);
@@ -179,64 +162,17 @@ err_put_unused_fd:
}
EXPORT_SYMBOL_GPL(anon_inode_getfd);
-/*
- * A single inode exists for all anon_inode files. Contrary to pipes,
- * anon_inode inodes have no associated per-instance data, so we need
- * only allocate one of them.
- */
-static struct inode *anon_inode_mkinode(void)
-{
- struct inode *inode = new_inode(anon_inode_mnt->mnt_sb);
-
- if (!inode)
- return ERR_PTR(-ENOMEM);
-
- inode->i_ino = get_next_ino();
- inode->i_fop = &anon_inode_fops;
-
- inode->i_mapping->a_ops = &anon_aops;
-
- /*
- * Mark the inode dirty from the very beginning,
- * that way it will never be moved to the dirty
- * list because mark_inode_dirty() will think
- * that it already _is_ on the dirty list.
- */
- inode->i_state = I_DIRTY;
- inode->i_mode = S_IRUSR | S_IWUSR;
- inode->i_uid = current_fsuid();
- inode->i_gid = current_fsgid();
- inode->i_flags |= S_PRIVATE;
- inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
- return inode;
-}
-
static int __init anon_inode_init(void)
{
- int error;
-
- error = register_filesystem(&anon_inode_fs_type);
- if (error)
- goto err_exit;
anon_inode_mnt = kern_mount(&anon_inode_fs_type);
- if (IS_ERR(anon_inode_mnt)) {
- error = PTR_ERR(anon_inode_mnt);
- goto err_unregister_filesystem;
- }
- anon_inode_inode = anon_inode_mkinode();
- if (IS_ERR(anon_inode_inode)) {
- error = PTR_ERR(anon_inode_inode);
- goto err_mntput;
- }
+ if (IS_ERR(anon_inode_mnt))
+ panic("anon_inode_init() kernel mount failed (%ld)\n", PTR_ERR(anon_inode_mnt));
- return 0;
+ anon_inode_inode = alloc_anon_inode(anon_inode_mnt->mnt_sb);
+ if (IS_ERR(anon_inode_inode))
+ panic("anon_inode_init() inode allocation failed (%ld)\n", PTR_ERR(anon_inode_inode));
-err_mntput:
- mntput(anon_inode_mnt);
-err_unregister_filesystem:
- unregister_filesystem(&anon_inode_fs_type);
-err_exit:
- panic(KERN_ERR "anon_inode_init() failed (%d)\n", error);
+ return 0;
}
fs_initcall(anon_inode_init);