Commit e72e6497 authored by David Woodhouse's avatar David Woodhouse

jffs2: Fix NFS race by using insert_inode_locked()

New inodes need to be locked as we're creating them, so they don't get used
by other things (like NFSd) before they're ready.

Pointed out by Al Viro.
Signed-off-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
parent f324e4cb
...@@ -222,15 +222,18 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode, ...@@ -222,15 +222,18 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode,
dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(ri->ctime)); dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(ri->ctime));
jffs2_free_raw_inode(ri); jffs2_free_raw_inode(ri);
d_instantiate(dentry, inode);
D1(printk(KERN_DEBUG "jffs2_create: Created ino #%lu with mode %o, nlink %d(%d). nrpages %ld\n", D1(printk(KERN_DEBUG "jffs2_create: Created ino #%lu with mode %o, nlink %d(%d). nrpages %ld\n",
inode->i_ino, inode->i_mode, inode->i_nlink, inode->i_ino, inode->i_mode, inode->i_nlink,
f->inocache->pino_nlink, inode->i_mapping->nrpages)); f->inocache->pino_nlink, inode->i_mapping->nrpages));
d_instantiate(dentry, inode);
unlock_new_inode(inode);
return 0; return 0;
fail: fail:
make_bad_inode(inode); make_bad_inode(inode);
unlock_new_inode(inode);
iput(inode); iput(inode);
jffs2_free_raw_inode(ri); jffs2_free_raw_inode(ri);
return ret; return ret;
...@@ -447,10 +450,12 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char ...@@ -447,10 +450,12 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
jffs2_complete_reservation(c); jffs2_complete_reservation(c);
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
unlock_new_inode(inode);
return 0; return 0;
fail: fail:
make_bad_inode(inode); make_bad_inode(inode);
unlock_new_inode(inode);
iput(inode); iput(inode);
return ret; return ret;
} }
...@@ -592,10 +597,12 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode) ...@@ -592,10 +597,12 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
jffs2_complete_reservation(c); jffs2_complete_reservation(c);
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
unlock_new_inode(inode);
return 0; return 0;
fail: fail:
make_bad_inode(inode); make_bad_inode(inode);
unlock_new_inode(inode);
iput(inode); iput(inode);
return ret; return ret;
} }
...@@ -767,11 +774,12 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de ...@@ -767,11 +774,12 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
jffs2_complete_reservation(c); jffs2_complete_reservation(c);
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
unlock_new_inode(inode);
return 0; return 0;
fail: fail:
make_bad_inode(inode); make_bad_inode(inode);
unlock_new_inode(inode);
iput(inode); iput(inode);
return ret; return ret;
} }
......
...@@ -465,7 +465,12 @@ struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_i ...@@ -465,7 +465,12 @@ struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_i
inode->i_blocks = 0; inode->i_blocks = 0;
inode->i_size = 0; inode->i_size = 0;
insert_inode_hash(inode); if (insert_inode_locked(inode) < 0) {
make_bad_inode(inode);
unlock_new_inode(inode);
iput(inode);
return ERR_PTR(-EINVAL);
}
return inode; return inode;
} }
......
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