Skip to content

Commit

Permalink
nfsd: initialize i_private before d_add
Browse files Browse the repository at this point in the history
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: Al Viro <[email protected]>
Signed-off-by: J. Bruce Fields <[email protected]>
  • Loading branch information
J. Bruce Fields committed Aug 15, 2019
1 parent dc46bba commit bebd699
Showing 1 changed file with 6 additions and 6 deletions.
12 changes: 6 additions & 6 deletions fs/nfsd/nfsctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1171,13 +1171,17 @@ static struct inode *nfsd_get_inode(struct super_block *sb, umode_t mode)
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;

inode = nfsd_get_inode(dir->i_sb, mode);
if (!inode)
return -ENOMEM;
if (ncl) {
inode->i_private = ncl;
kref_get(&ncl->cl_ref);
}
d_add(dentry, inode);
inc_nlink(dir);
fsnotify_mkdir(dir, dentry);
Expand All @@ -1194,13 +1198,9 @@ static struct dentry *nfsd_mkdir(struct dentry *parent, struct nfsdfs_client *nc
dentry = d_alloc_name(parent, name);
if (!dentry)
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)
goto out_err;
if (ncl) {
d_inode(dentry)->i_private = ncl;
kref_get(&ncl->cl_ref);
}
out:
inode_unlock(dir);
return dentry;
Expand Down

0 comments on commit bebd699

Please sign in to comment.