Commit 3516586a authored by Al Viro's avatar Al Viro

[PATCH] make O_EXCL in nd->intent.flags visible in nd->flags

New flag: LOOKUP_EXCL.  Set before doing the final step of pathname
resolution on the paths that have LOOKUP_CREATE and O_EXCL.
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 2c552d81
...@@ -69,7 +69,7 @@ static int gfs2_create(struct inode *dir, struct dentry *dentry, ...@@ -69,7 +69,7 @@ static int gfs2_create(struct inode *dir, struct dentry *dentry,
mark_inode_dirty(inode); mark_inode_dirty(inode);
break; break;
} else if (PTR_ERR(inode) != -EEXIST || } else if (PTR_ERR(inode) != -EEXIST ||
(nd && (nd->intent.open.flags & O_EXCL))) { (nd && nd->flags & LOOKUP_EXCL)) {
gfs2_holder_uninit(ghs); gfs2_holder_uninit(ghs);
return PTR_ERR(inode); return PTR_ERR(inode);
} }
......
...@@ -1709,6 +1709,8 @@ struct file *do_filp_open(int dfd, const char *pathname, ...@@ -1709,6 +1709,8 @@ struct file *do_filp_open(int dfd, const char *pathname,
dir = nd.path.dentry; dir = nd.path.dentry;
nd.flags &= ~LOOKUP_PARENT; nd.flags &= ~LOOKUP_PARENT;
nd.flags |= LOOKUP_CREATE | LOOKUP_OPEN; nd.flags |= LOOKUP_CREATE | LOOKUP_OPEN;
if (flag & O_EXCL)
nd.flags |= LOOKUP_EXCL;
mutex_lock(&dir->d_inode->i_mutex); mutex_lock(&dir->d_inode->i_mutex);
path.dentry = lookup_hash(&nd); path.dentry = lookup_hash(&nd);
path.mnt = nd.path.mnt; path.mnt = nd.path.mnt;
...@@ -1906,7 +1908,7 @@ struct dentry *lookup_create(struct nameidata *nd, int is_dir) ...@@ -1906,7 +1908,7 @@ struct dentry *lookup_create(struct nameidata *nd, int is_dir)
if (nd->last_type != LAST_NORM) if (nd->last_type != LAST_NORM)
goto fail; goto fail;
nd->flags &= ~LOOKUP_PARENT; nd->flags &= ~LOOKUP_PARENT;
nd->flags |= LOOKUP_CREATE; nd->flags |= LOOKUP_CREATE | LOOKUP_EXCL;
nd->intent.open.flags = O_EXCL; nd->intent.open.flags = O_EXCL;
/* /*
......
...@@ -707,9 +707,7 @@ static int nfs_is_exclusive_create(struct inode *dir, struct nameidata *nd) ...@@ -707,9 +707,7 @@ static int nfs_is_exclusive_create(struct inode *dir, struct nameidata *nd)
{ {
if (NFS_PROTO(dir)->version == 2) if (NFS_PROTO(dir)->version == 2)
return 0; return 0;
if (nd == NULL || nfs_lookup_check_intent(nd, LOOKUP_CREATE) == 0) return nd && nfs_lookup_check_intent(nd, LOOKUP_EXCL);
return 0;
return (nd->intent.open.flags & O_EXCL) != 0;
} }
/* /*
...@@ -1009,7 +1007,7 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry ...@@ -1009,7 +1007,7 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
/* Let vfs_create() deal with O_EXCL. Instantiate, but don't hash /* Let vfs_create() deal with O_EXCL. Instantiate, but don't hash
* the dentry. */ * the dentry. */
if (nd->intent.open.flags & O_EXCL) { if (nd->flags & LOOKUP_EXCL) {
d_instantiate(dentry, NULL); d_instantiate(dentry, NULL);
goto out; goto out;
} }
......
...@@ -51,8 +51,9 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND}; ...@@ -51,8 +51,9 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND};
/* /*
* Intent data * Intent data
*/ */
#define LOOKUP_OPEN (0x0100) #define LOOKUP_OPEN 0x0100
#define LOOKUP_CREATE (0x0200) #define LOOKUP_CREATE 0x0200
#define LOOKUP_EXCL 0x0400
extern int user_path_at(int, const char __user *, unsigned, struct path *); extern int user_path_at(int, const char __user *, unsigned, struct path *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment