diff options
Diffstat (limited to 'fs/anon_inodes.c')
-rw-r--r-- | fs/anon_inodes.c | 114 |
1 files changed, 1 insertions, 113 deletions
diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c index 85c961849953..24084732b1d0 100644 --- a/fs/anon_inodes.c +++ b/fs/anon_inodes.c | |||
@@ -24,7 +24,6 @@ | |||
24 | 24 | ||
25 | static struct vfsmount *anon_inode_mnt __read_mostly; | 25 | static struct vfsmount *anon_inode_mnt __read_mostly; |
26 | static struct inode *anon_inode_inode; | 26 | static struct inode *anon_inode_inode; |
27 | static const struct file_operations anon_inode_fops; | ||
28 | 27 | ||
29 | /* | 28 | /* |
30 | * anon_inodefs_dname() is called from d_path(). | 29 | * anon_inodefs_dname() is called from d_path(). |
@@ -39,51 +38,6 @@ static const struct dentry_operations anon_inodefs_dentry_operations = { | |||
39 | .d_dname = anon_inodefs_dname, | 38 | .d_dname = anon_inodefs_dname, |
40 | }; | 39 | }; |
41 | 40 | ||
42 | /* | ||
43 | * nop .set_page_dirty method so that people can use .page_mkwrite on | ||
44 | * anon inodes. | ||
45 | */ | ||
46 | static int anon_set_page_dirty(struct page *page) | ||
47 | { | ||
48 | return 0; | ||
49 | }; | ||
50 | |||
51 | static const struct address_space_operations anon_aops = { | ||
52 | .set_page_dirty = anon_set_page_dirty, | ||
53 | }; | ||
54 | |||
55 | /* | ||
56 | * A single inode exists for all anon_inode files. Contrary to pipes, | ||
57 | * anon_inode inodes have no associated per-instance data, so we need | ||
58 | * only allocate one of them. | ||
59 | */ | ||
60 | static struct inode *anon_inode_mkinode(struct super_block *s) | ||
61 | { | ||
62 | struct inode *inode = new_inode_pseudo(s); | ||
63 | |||
64 | if (!inode) | ||
65 | return ERR_PTR(-ENOMEM); | ||
66 | |||
67 | inode->i_ino = get_next_ino(); | ||
68 | inode->i_fop = &anon_inode_fops; | ||
69 | |||
70 | inode->i_mapping->a_ops = &anon_aops; | ||
71 | |||
72 | /* | ||
73 | * Mark the inode dirty from the very beginning, | ||
74 | * that way it will never be moved to the dirty | ||
75 | * list because mark_inode_dirty() will think | ||
76 | * that it already _is_ on the dirty list. | ||
77 | */ | ||
78 | inode->i_state = I_DIRTY; | ||
79 | inode->i_mode = S_IRUSR | S_IWUSR; | ||
80 | inode->i_uid = current_fsuid(); | ||
81 | inode->i_gid = current_fsgid(); | ||
82 | inode->i_flags |= S_PRIVATE; | ||
83 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | ||
84 | return inode; | ||
85 | } | ||
86 | |||
87 | static struct dentry *anon_inodefs_mount(struct file_system_type *fs_type, | 41 | static struct dentry *anon_inodefs_mount(struct file_system_type *fs_type, |
88 | int flags, const char *dev_name, void *data) | 42 | int flags, const char *dev_name, void *data) |
89 | { | 43 | { |
@@ -92,7 +46,7 @@ static struct dentry *anon_inodefs_mount(struct file_system_type *fs_type, | |||
92 | &anon_inodefs_dentry_operations, ANON_INODE_FS_MAGIC); | 46 | &anon_inodefs_dentry_operations, ANON_INODE_FS_MAGIC); |
93 | if (!IS_ERR(root)) { | 47 | if (!IS_ERR(root)) { |
94 | struct super_block *s = root->d_sb; | 48 | struct super_block *s = root->d_sb; |
95 | anon_inode_inode = anon_inode_mkinode(s); | 49 | anon_inode_inode = alloc_anon_inode(s); |
96 | if (IS_ERR(anon_inode_inode)) { | 50 | if (IS_ERR(anon_inode_inode)) { |
97 | dput(root); | 51 | dput(root); |
98 | deactivate_locked_super(s); | 52 | deactivate_locked_super(s); |
@@ -109,72 +63,6 @@ static struct file_system_type anon_inode_fs_type = { | |||
109 | }; | 63 | }; |
110 | 64 | ||
111 | /** | 65 | /** |
112 | * anon_inode_getfile_private - creates a new file instance by hooking it up to an | ||
113 | * anonymous inode, and a dentry that describe the "class" | ||
114 | * of the file | ||
115 | * | ||
116 | * @name: [in] name of the "class" of the new file | ||
117 | * @fops: [in] file operations for the new file | ||
118 | * @priv: [in] private data for the new file (will be file's private_data) | ||
119 | * @flags: [in] flags | ||
120 | * | ||
121 | * | ||
122 | * Similar to anon_inode_getfile, but each file holds a single inode. | ||
123 | * | ||
124 | */ | ||
125 | struct file *anon_inode_getfile_private(const char *name, | ||
126 | const struct file_operations *fops, | ||
127 | void *priv, int flags) | ||
128 | { | ||
129 | struct qstr this; | ||
130 | struct path path; | ||
131 | struct file *file; | ||
132 | struct inode *inode; | ||
133 | |||
134 | if (fops->owner && !try_module_get(fops->owner)) | ||
135 | return ERR_PTR(-ENOENT); | ||
136 | |||
137 | inode = anon_inode_mkinode(anon_inode_mnt->mnt_sb); | ||
138 | if (IS_ERR(inode)) { | ||
139 | file = ERR_PTR(-ENOMEM); | ||
140 | goto err_module; | ||
141 | } | ||
142 | |||
143 | /* | ||
144 | * Link the inode to a directory entry by creating a unique name | ||
145 | * using the inode sequence number. | ||
146 | */ | ||
147 | file = ERR_PTR(-ENOMEM); | ||
148 | this.name = name; | ||
149 | this.len = strlen(name); | ||
150 | this.hash = 0; | ||
151 | path.dentry = d_alloc_pseudo(anon_inode_mnt->mnt_sb, &this); | ||
152 | if (!path.dentry) | ||
153 | goto err_module; | ||
154 | |||
155 | path.mnt = mntget(anon_inode_mnt); | ||
156 | |||
157 | d_instantiate(path.dentry, inode); | ||
158 | |||
159 | file = alloc_file(&path, OPEN_FMODE(flags), fops); | ||
160 | if (IS_ERR(file)) | ||
161 | goto err_dput; | ||
162 | |||
163 | file->f_mapping = inode->i_mapping; | ||
164 | file->f_flags = flags & (O_ACCMODE | O_NONBLOCK); | ||
165 | file->private_data = priv; | ||
166 | |||
167 | return file; | ||
168 | |||
169 | err_dput: | ||
170 | path_put(&path); | ||
171 | err_module: | ||
172 | module_put(fops->owner); | ||
173 | return file; | ||
174 | } | ||
175 | EXPORT_SYMBOL_GPL(anon_inode_getfile_private); | ||
176 | |||
177 | /** | ||
178 | * anon_inode_getfile - creates a new file instance by hooking it up to an | 66 | * anon_inode_getfile - creates a new file instance by hooking it up to an |
179 | * anonymous inode, and a dentry that describe the "class" | 67 | * anonymous inode, and a dentry that describe the "class" |
180 | * of the file | 68 | * of the file |