diff options
author | Roland Dreier <rdreier@cisco.com> | 2009-12-18 12:41:24 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2009-12-22 12:27:34 -0500 |
commit | 628ff7c1d8d8466a5ad8078bd0206a130f8b8a51 (patch) | |
tree | cc7ab0c90849be38e200fc6ff6a3a09e3caf0405 /fs/anon_inodes.c | |
parent | ed2617585f39dd12fae38c657bba68b9779ea10d (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.c | 12 |
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 | ||