aboutsummaryrefslogtreecommitdiffstats
path: root/fs/anon_inodes.c
diff options
context:
space:
mode:
authorRoland Dreier <rdreier@cisco.com>2009-12-18 12:41:24 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2009-12-22 12:27:34 -0500
commit628ff7c1d8d8466a5ad8078bd0206a130f8b8a51 (patch)
treecc7ab0c90849be38e200fc6ff6a3a09e3caf0405 /fs/anon_inodes.c
parented2617585f39dd12fae38c657bba68b9779ea10d (diff)
anonfd: Allow making anon files read-only
It seems a couple places such as arch/ia64/kernel/perfmon.c and drivers/infiniband/core/uverbs_main.c could use anon_inode_getfile() instead of a private pseudo-fs + alloc_file(), if only there were a way to get a read-only file. So provide this by having anon_inode_getfile() create a read-only file if we pass O_RDONLY in flags. Signed-off-by: Roland Dreier <rolandd@cisco.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/anon_inodes.c')
-rw-r--r--fs/anon_inodes.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c
index 2c994591f4d7..598237e97221 100644
--- a/fs/anon_inodes.c
+++ b/fs/anon_inodes.c
@@ -89,11 +89,19 @@ struct file *anon_inode_getfile(const char *name,
89 struct qstr this; 89 struct qstr this;
90 struct path path; 90 struct path path;
91 struct file *file; 91 struct file *file;
92 fmode_t mode;
92 int error; 93 int error;
93 94
94 if (IS_ERR(anon_inode_inode)) 95 if (IS_ERR(anon_inode_inode))
95 return ERR_PTR(-ENODEV); 96 return ERR_PTR(-ENODEV);
96 97
98 switch (flags & O_ACCMODE) {
99 case O_RDONLY: mode = FMODE_READ; break;
100 case O_WRONLY: mode = FMODE_WRITE; break;
101 case O_RDWR: mode = FMODE_READ | FMODE_WRITE; break;
102 default: return ERR_PTR(-EINVAL);
103 }
104
97 if (fops->owner && !try_module_get(fops->owner)) 105 if (fops->owner && !try_module_get(fops->owner))
98 return ERR_PTR(-ENOENT); 106 return ERR_PTR(-ENOENT);
99 107
@@ -121,13 +129,13 @@ struct file *anon_inode_getfile(const char *name,
121 d_instantiate(path.dentry, anon_inode_inode); 129 d_instantiate(path.dentry, anon_inode_inode);
122 130
123 error = -ENFILE; 131 error = -ENFILE;
124 file = alloc_file(&path, FMODE_READ | FMODE_WRITE, fops); 132 file = alloc_file(&path, mode, fops);
125 if (!file) 133 if (!file)
126 goto err_dput; 134 goto err_dput;
127 file->f_mapping = anon_inode_inode->i_mapping; 135 file->f_mapping = anon_inode_inode->i_mapping;
128 136
129 file->f_pos = 0; 137 file->f_pos = 0;
130 file->f_flags = O_RDWR | (flags & O_NONBLOCK); 138 file->f_flags = flags & (O_ACCMODE | O_NONBLOCK);
131 file->f_version = 0; 139 file->f_version = 0;
132 file->private_data = priv; 140 file->private_data = priv;
133 141