From 628ff7c1d8d8466a5ad8078bd0206a130f8b8a51 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Fri, 18 Dec 2009 09:41:24 -0800 Subject: 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 Signed-off-by: Al Viro --- fs/anon_inodes.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'fs/anon_inodes.c') 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, struct qstr this; struct path path; struct file *file; + fmode_t mode; int error; if (IS_ERR(anon_inode_inode)) return ERR_PTR(-ENODEV); + switch (flags & O_ACCMODE) { + case O_RDONLY: mode = FMODE_READ; break; + case O_WRONLY: mode = FMODE_WRITE; break; + case O_RDWR: mode = FMODE_READ | FMODE_WRITE; break; + default: return ERR_PTR(-EINVAL); + } + if (fops->owner && !try_module_get(fops->owner)) return ERR_PTR(-ENOENT); @@ -121,13 +129,13 @@ struct file *anon_inode_getfile(const char *name, d_instantiate(path.dentry, anon_inode_inode); error = -ENFILE; - file = alloc_file(&path, FMODE_READ | FMODE_WRITE, fops); + file = alloc_file(&path, mode, fops); if (!file) goto err_dput; file->f_mapping = anon_inode_inode->i_mapping; file->f_pos = 0; - file->f_flags = O_RDWR | (flags & O_NONBLOCK); + file->f_flags = flags & (O_ACCMODE | O_NONBLOCK); file->f_version = 0; file->private_data = priv; -- cgit v1.2.2