diff --git a/drivers/staging/pohmelfs/dir.c b/drivers/staging/pohmelfs/dir.c index 9732a9666cc4fa8a2400efb78f313dca94b00f00..7598e77672a512875d583612dad0ac0bb73617f6 100644 --- a/drivers/staging/pohmelfs/dir.c +++ b/drivers/staging/pohmelfs/dir.c @@ -512,7 +512,7 @@ struct dentry *pohmelfs_lookup(struct inode *dir, struct dentry *dentry, struct int err, lock_type = POHMELFS_READ_LOCK, need_lock = 1; struct qstr str = dentry->d_name; - if ((nd->intent.open.flags & O_ACCMODE) > 1) + if ((nd->intent.open.flags & O_ACCMODE) != O_RDONLY) lock_type = POHMELFS_WRITE_LOCK; if (test_bit(NETFS_INODE_OWNED, &parent->state)) { diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 7f6c6770319538c3094f7b26eb40fc18a398475d..47f71eb66b32e0c82be58d8ce87af1371392c30b 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 691c78f58bef23eaeac32489399479d981397aed..d148e69f21b55163e454e8caf40e34a49a44aa55 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 4698a5c553dc010fa0aedabe3f3f4e0fb68b65c8..0a292459c895aaa2f44cf137dbab787c82809906 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 e2b14001cea5b0c098a72fc92ca2379299ecce3d..47559dd331935e73c2de41836091828b47074983 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 94fd0fa2d6470a459d7c62e6631a555460f28a98..5e65f67ee92616257c8819d36533e5dc5906a998 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 1f4625749038ca0074978bead538c21e8c7acd21..b5f63a50fa7f9e10398830d5d85edcbc67176fe3 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; }