diff options
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/dir.c | 9 | ||||
-rw-r--r-- | fs/nfs/getroot.c | 14 |
2 files changed, 11 insertions, 12 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index efdba2e802d7..3e64b98f3a93 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -707,9 +707,7 @@ static int nfs_is_exclusive_create(struct inode *dir, struct nameidata *nd) | |||
707 | { | 707 | { |
708 | if (NFS_PROTO(dir)->version == 2) | 708 | if (NFS_PROTO(dir)->version == 2) |
709 | return 0; | 709 | return 0; |
710 | if (nd == NULL || nfs_lookup_check_intent(nd, LOOKUP_CREATE) == 0) | 710 | return nd && nfs_lookup_check_intent(nd, LOOKUP_EXCL); |
711 | return 0; | ||
712 | return (nd->intent.open.flags & O_EXCL) != 0; | ||
713 | } | 711 | } |
714 | 712 | ||
715 | /* | 713 | /* |
@@ -1009,7 +1007,7 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry | |||
1009 | 1007 | ||
1010 | /* Let vfs_create() deal with O_EXCL. Instantiate, but don't hash | 1008 | /* Let vfs_create() deal with O_EXCL. Instantiate, but don't hash |
1011 | * the dentry. */ | 1009 | * the dentry. */ |
1012 | if (nd->intent.open.flags & O_EXCL) { | 1010 | if (nd->flags & LOOKUP_EXCL) { |
1013 | d_instantiate(dentry, NULL); | 1011 | d_instantiate(dentry, NULL); |
1014 | goto out; | 1012 | goto out; |
1015 | } | 1013 | } |
@@ -1959,6 +1957,9 @@ force_lookup: | |||
1959 | } else | 1957 | } else |
1960 | res = PTR_ERR(cred); | 1958 | res = PTR_ERR(cred); |
1961 | out: | 1959 | out: |
1960 | if (!res && (mask & MAY_EXEC) && !execute_ok(inode)) | ||
1961 | res = -EACCES; | ||
1962 | |||
1962 | dfprintk(VFS, "NFS: permission(%s/%ld), mask=0x%x, res=%d\n", | 1963 | dfprintk(VFS, "NFS: permission(%s/%ld), mask=0x%x, res=%d\n", |
1963 | inode->i_sb->s_id, inode->i_ino, mask, res); | 1964 | inode->i_sb->s_id, inode->i_ino, mask, res); |
1964 | return res; | 1965 | return res; |
diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c index fae97196daad..b7c9b2df1f29 100644 --- a/fs/nfs/getroot.c +++ b/fs/nfs/getroot.c | |||
@@ -107,11 +107,10 @@ struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh *mntfh) | |||
107 | * if the dentry tree reaches them; however if the dentry already | 107 | * if the dentry tree reaches them; however if the dentry already |
108 | * exists, we'll pick it up at this point and use it as the root | 108 | * exists, we'll pick it up at this point and use it as the root |
109 | */ | 109 | */ |
110 | mntroot = d_alloc_anon(inode); | 110 | mntroot = d_obtain_alias(inode); |
111 | if (!mntroot) { | 111 | if (IS_ERR(mntroot)) { |
112 | iput(inode); | ||
113 | dprintk("nfs_get_root: get root dentry failed\n"); | 112 | dprintk("nfs_get_root: get root dentry failed\n"); |
114 | return ERR_PTR(-ENOMEM); | 113 | return mntroot; |
115 | } | 114 | } |
116 | 115 | ||
117 | security_d_instantiate(mntroot, inode); | 116 | security_d_instantiate(mntroot, inode); |
@@ -277,11 +276,10 @@ struct dentry *nfs4_get_root(struct super_block *sb, struct nfs_fh *mntfh) | |||
277 | * if the dentry tree reaches them; however if the dentry already | 276 | * if the dentry tree reaches them; however if the dentry already |
278 | * exists, we'll pick it up at this point and use it as the root | 277 | * exists, we'll pick it up at this point and use it as the root |
279 | */ | 278 | */ |
280 | mntroot = d_alloc_anon(inode); | 279 | mntroot = d_obtain_alias(inode); |
281 | if (!mntroot) { | 280 | if (IS_ERR(mntroot)) { |
282 | iput(inode); | ||
283 | dprintk("nfs_get_root: get root dentry failed\n"); | 281 | dprintk("nfs_get_root: get root dentry failed\n"); |
284 | return ERR_PTR(-ENOMEM); | 282 | return mntroot; |
285 | } | 283 | } |
286 | 284 | ||
287 | security_d_instantiate(mntroot, inode); | 285 | security_d_instantiate(mntroot, inode); |