aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Woodhouse <David.Woodhouse@intel.com>2010-06-03 03:09:12 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2010-06-03 03:22:04 -0400
commite72e6497e74811e01d72b4c1b7537b3aea3ee857 (patch)
treed78dec67d0aaeea807e5ab32141802620ec7ae41
parentf324e4cb2cadd9a42932c8a158e761ae31b88e72 (diff)
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>
-rw-r--r--fs/jffs2/dir.c12
-rw-r--r--fs/jffs2/fs.c7
2 files changed, 16 insertions, 3 deletions
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
index cb7ef34d384c..166062a68230 100644
--- a/fs/jffs2/dir.c
+++ b/fs/jffs2/dir.c
@@ -222,15 +222,18 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode,
222 dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(ri->ctime)); 222 dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(ri->ctime));
223 223
224 jffs2_free_raw_inode(ri); 224 jffs2_free_raw_inode(ri);
225 d_instantiate(dentry, inode);
226 225
227 D1(printk(KERN_DEBUG "jffs2_create: Created ino #%lu with mode %o, nlink %d(%d). nrpages %ld\n", 226 D1(printk(KERN_DEBUG "jffs2_create: Created ino #%lu with mode %o, nlink %d(%d). nrpages %ld\n",
228 inode->i_ino, inode->i_mode, inode->i_nlink, 227 inode->i_ino, inode->i_mode, inode->i_nlink,
229 f->inocache->pino_nlink, inode->i_mapping->nrpages)); 228 f->inocache->pino_nlink, inode->i_mapping->nrpages));
229
230 d_instantiate(dentry, inode);
231 unlock_new_inode(inode);
230 return 0; 232 return 0;
231 233
232 fail: 234 fail:
233 make_bad_inode(inode); 235 make_bad_inode(inode);
236 unlock_new_inode(inode);
234 iput(inode); 237 iput(inode);
235 jffs2_free_raw_inode(ri); 238 jffs2_free_raw_inode(ri);
236 return ret; 239 return ret;
@@ -447,10 +450,12 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
447 jffs2_complete_reservation(c); 450 jffs2_complete_reservation(c);
448 451
449 d_instantiate(dentry, inode); 452 d_instantiate(dentry, inode);
453 unlock_new_inode(inode);
450 return 0; 454 return 0;
451 455
452 fail: 456 fail:
453 make_bad_inode(inode); 457 make_bad_inode(inode);
458 unlock_new_inode(inode);
454 iput(inode); 459 iput(inode);
455 return ret; 460 return ret;
456} 461}
@@ -592,10 +597,12 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
592 jffs2_complete_reservation(c); 597 jffs2_complete_reservation(c);
593 598
594 d_instantiate(dentry, inode); 599 d_instantiate(dentry, inode);
600 unlock_new_inode(inode);
595 return 0; 601 return 0;
596 602
597 fail: 603 fail:
598 make_bad_inode(inode); 604 make_bad_inode(inode);
605 unlock_new_inode(inode);
599 iput(inode); 606 iput(inode);
600 return ret; 607 return ret;
601} 608}
@@ -767,11 +774,12 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
767 jffs2_complete_reservation(c); 774 jffs2_complete_reservation(c);
768 775
769 d_instantiate(dentry, inode); 776 d_instantiate(dentry, inode);
770 777 unlock_new_inode(inode);
771 return 0; 778 return 0;
772 779
773 fail: 780 fail:
774 make_bad_inode(inode); 781 make_bad_inode(inode);
782 unlock_new_inode(inode);
775 iput(inode); 783 iput(inode);
776 return ret; 784 return ret;
777} 785}
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index 86e0821fc989..26037e2d6154 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -465,7 +465,12 @@ struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_i
465 inode->i_blocks = 0; 465 inode->i_blocks = 0;
466 inode->i_size = 0; 466 inode->i_size = 0;
467 467
468 insert_inode_hash(inode); 468 if (insert_inode_locked(inode) < 0) {
469 make_bad_inode(inode);
470 unlock_new_inode(inode);
471 iput(inode);
472 return ERR_PTR(-EINVAL);
473 }
469 474
470 return inode; 475 return inode;
471} 476}