summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2011-06-25 19:15:54 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2011-07-20 01:43:52 -0400
commit8a5e929dd2e05ab4d3d89f58c5e8fca596af8f3a (patch)
tree8cbed05fcd99d24e881e5ea12d8a954865e31085 /fs
parent554a8b9f54cd7ca2b89f5dc227df08be082fae0d (diff)
downloadlinux-stable-8a5e929dd2e05ab4d3d89f58c5e8fca596af8f3a.tar.gz
linux-stable-8a5e929dd2e05ab4d3d89f58c5e8fca596af8f3a.tar.bz2
linux-stable-8a5e929dd2e05ab4d3d89f58c5e8fca596af8f3a.zip
don't transliterate lower bits of ->intent.open.flags to FMODE_...
->create() instances are much happier that way... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs')
-rw-r--r--fs/9p/vfs_inode.c2
-rw-r--r--fs/9p/vfs_inode_dotl.c2
-rw-r--r--fs/ceph/file.c2
-rw-r--r--fs/fuse/dir.c2
-rw-r--r--fs/namei.c21
-rw-r--r--fs/nfs/dir.c24
6 files changed, 23 insertions, 30 deletions
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 7f6c67703195..47f71eb66b32 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -634,7 +634,7 @@ v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode,
v9ses = v9fs_inode2v9ses(dir);
perm = unixmode2p9mode(v9ses, mode);
if (nd && nd->flags & LOOKUP_OPEN)
- flags = nd->intent.open.flags - 1;
+ flags = nd->intent.open.flags;
else
flags = O_RDWR;
diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c
index 691c78f58bef..d148e69f21b5 100644
--- a/fs/9p/vfs_inode_dotl.c
+++ b/fs/9p/vfs_inode_dotl.c
@@ -174,7 +174,7 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int omode,
v9ses = v9fs_inode2v9ses(dir);
if (nd && nd->flags & LOOKUP_OPEN)
- flags = nd->intent.open.flags - 1;
+ flags = nd->intent.open.flags;
else {
/*
* create call without LOOKUP_OPEN is due
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index 4698a5c553dc..0a292459c895 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -226,7 +226,7 @@ struct dentry *ceph_lookup_open(struct inode *dir, struct dentry *dentry,
struct inode *parent_inode = get_dentry_parent_inode(file->f_dentry);
struct ceph_mds_request *req;
int err;
- int flags = nd->intent.open.flags - 1; /* silly vfs! */
+ int flags = nd->intent.open.flags;
dout("ceph_lookup_open dentry %p '%.*s' flags %d mode 0%o\n",
dentry, dentry->d_name.len, dentry->d_name.name, flags, mode);
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index e2b14001cea5..47559dd33193 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -382,7 +382,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
struct fuse_entry_out outentry;
struct fuse_file *ff;
struct file *file;
- int flags = nd->intent.open.flags - 1;
+ int flags = nd->intent.open.flags;
if (fc->no_create)
return -ENOSYS;
diff --git a/fs/namei.c b/fs/namei.c
index 94fd0fa2d647..5e65f67ee926 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1965,27 +1965,10 @@ static int handle_truncate(struct file *filp)
return error;
}
-/*
- * Note that while the flag value (low two bits) for sys_open means:
- * 00 - read-only
- * 01 - write-only
- * 10 - read-write
- * 11 - special
- * it is changed into
- * 00 - no permissions needed
- * 01 - read-permission
- * 10 - write-permission
- * 11 - read-write
- * for the internal routines (ie open_namei()/follow_link() etc)
- * This is more logical, and also allows the 00 "no perm needed"
- * to be used for symlinks (where the permissions are checked
- * later).
- *
-*/
static inline int open_to_namei_flags(int flag)
{
- if ((flag+1) & O_ACCMODE)
- flag++;
+ if ((flag & O_ACCMODE) == 3)
+ flag--;
return flag;
}
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 1f4625749038..b5f63a50fa7f 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1338,16 +1338,26 @@ static int is_atomic_open(struct nameidata *nd)
return 0;
/* Are we trying to write to a read only partition? */
if (__mnt_is_readonly(nd->path.mnt) &&
- (nd->intent.open.flags & (O_CREAT|O_TRUNC|FMODE_WRITE)))
+ (nd->intent.open.flags & (O_CREAT|O_TRUNC|O_ACCMODE)))
return 0;
return 1;
}
+static fmode_t flags_to_mode(int flags)
+{
+ fmode_t res = (__force fmode_t)flags & FMODE_EXEC;
+ if ((flags & O_ACCMODE) != O_WRONLY)
+ res |= FMODE_READ;
+ if ((flags & O_ACCMODE) != O_RDONLY)
+ res |= FMODE_WRITE;
+ return res;
+}
+
static struct nfs_open_context *create_nfs_open_context(struct dentry *dentry, int open_flags)
{
struct nfs_open_context *ctx;
struct rpc_cred *cred;
- fmode_t fmode = open_flags & (FMODE_READ | FMODE_WRITE | FMODE_EXEC);
+ fmode_t fmode = flags_to_mode(open_flags);
cred = rpc_lookup_cred();
if (IS_ERR(cred))
@@ -1567,7 +1577,7 @@ static int nfs_open_create(struct inode *dir, struct dentry *dentry, int mode,
struct nfs_open_context *ctx = NULL;
struct iattr attr;
int error;
- int open_flags = O_CREAT|O_EXCL|FMODE_READ;
+ int open_flags = O_CREAT|O_EXCL;
dfprintk(VFS, "NFS: create(%s/%ld), %s\n",
dir->i_sb->s_id, dir->i_ino, dentry->d_name.name);
@@ -1657,7 +1667,7 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode,
{
struct iattr attr;
int error;
- int open_flags = O_CREAT|O_EXCL|FMODE_READ;
+ int open_flags = O_CREAT|O_EXCL;
dfprintk(VFS, "NFS: create(%s/%ld), %s\n",
dir->i_sb->s_id, dir->i_ino, dentry->d_name.name);
@@ -2256,11 +2266,11 @@ static int nfs_open_permission_mask(int openflags)
{
int mask = 0;
- if (openflags & FMODE_READ)
+ if ((openflags & O_ACCMODE) != O_WRONLY)
mask |= MAY_READ;
- if (openflags & FMODE_WRITE)
+ if ((openflags & O_ACCMODE) != O_RDONLY)
mask |= MAY_WRITE;
- if (openflags & FMODE_EXEC)
+ if (openflags & __FMODE_EXEC)
mask |= MAY_EXEC;
return mask;
}