Commit bebd6997 authored by J. Bruce Fields's avatar J. Bruce Fields

nfsd: initialize i_private before d_add

A process could race in an open and attempt to read one of these files
before i_private is initialized, and get a spurious error.
Reported-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent dc46bba7
...@@ -1171,13 +1171,17 @@ static struct inode *nfsd_get_inode(struct super_block *sb, umode_t mode) ...@@ -1171,13 +1171,17 @@ static struct inode *nfsd_get_inode(struct super_block *sb, umode_t mode)
return inode; return inode;
} }
static int __nfsd_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) static int __nfsd_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode, struct nfsdfs_client *ncl)
{ {
struct inode *inode; struct inode *inode;
inode = nfsd_get_inode(dir->i_sb, mode); inode = nfsd_get_inode(dir->i_sb, mode);
if (!inode) if (!inode)
return -ENOMEM; return -ENOMEM;
if (ncl) {
inode->i_private = ncl;
kref_get(&ncl->cl_ref);
}
d_add(dentry, inode); d_add(dentry, inode);
inc_nlink(dir); inc_nlink(dir);
fsnotify_mkdir(dir, dentry); fsnotify_mkdir(dir, dentry);
...@@ -1194,13 +1198,9 @@ static struct dentry *nfsd_mkdir(struct dentry *parent, struct nfsdfs_client *nc ...@@ -1194,13 +1198,9 @@ static struct dentry *nfsd_mkdir(struct dentry *parent, struct nfsdfs_client *nc
dentry = d_alloc_name(parent, name); dentry = d_alloc_name(parent, name);
if (!dentry) if (!dentry)
goto out_err; goto out_err;
ret = __nfsd_mkdir(d_inode(parent), dentry, S_IFDIR | 0600); ret = __nfsd_mkdir(d_inode(parent), dentry, S_IFDIR | 0600, ncl);
if (ret) if (ret)
goto out_err; goto out_err;
if (ncl) {
d_inode(dentry)->i_private = ncl;
kref_get(&ncl->cl_ref);
}
out: out:
inode_unlock(dir); inode_unlock(dir);
return dentry; return dentry;
......
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