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: David Woodhouse <David.Woodhouse@intel.com>
This commit is contained in:
parent
f324e4cb2c
commit
e72e6497e7
|
@ -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
|
||||||
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)
|
||||||
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
|
||||||
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
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue