jffs2: Fix NFS race by using insert_inode_locked()

Linux-MTD Mailing List linux-mtd at lists.infradead.org
Thu Jun 3 06:59:02 EDT 2010


Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=e72e6497e74811e01d72b4c1b7537b3aea3ee857
Commit:     e72e6497e74811e01d72b4c1b7537b3aea3ee857
Parent:     f324e4cb2cadd9a42932c8a158e761ae31b88e72
Author:     David Woodhouse <David.Woodhouse at intel.com>
AuthorDate: Thu Jun 3 08:09:12 2010 +0100
Committer:  David Woodhouse <David.Woodhouse at intel.com>
CommitDate: Thu Jun 3 08:22:04 2010 +0100

    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 at intel.com>
---
 fs/jffs2/dir.c |   12 ++++++++++--
 fs/jffs2/fs.c  |    7 ++++++-
 2 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
index cb7ef34..166062a 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,
 	dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(ri->ctime));
 
 	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",
 		  inode->i_ino, inode->i_mode, inode->i_nlink,
 		  f->inocache->pino_nlink, inode->i_mapping->nrpages));
+
+	d_instantiate(dentry, inode);
+	unlock_new_inode(inode);
 	return 0;
 
  fail:
 	make_bad_inode(inode);
+	unlock_new_inode(inode);
 	iput(inode);
 	jffs2_free_raw_inode(ri);
 	return ret;
@@ -447,10 +450,12 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
 	jffs2_complete_reservation(c);
 
 	d_instantiate(dentry, inode);
+	unlock_new_inode(inode);
 	return 0;
 
  fail:
 	make_bad_inode(inode);
+	unlock_new_inode(inode);
 	iput(inode);
 	return ret;
 }
@@ -592,10 +597,12 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
 	jffs2_complete_reservation(c);
 
 	d_instantiate(dentry, inode);
+	unlock_new_inode(inode);
 	return 0;
 
  fail:
 	make_bad_inode(inode);
+	unlock_new_inode(inode);
 	iput(inode);
 	return ret;
 }
@@ -767,11 +774,12 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
 	jffs2_complete_reservation(c);
 
 	d_instantiate(dentry, inode);
-
+	unlock_new_inode(inode);
 	return 0;
 
  fail:
 	make_bad_inode(inode);
+	unlock_new_inode(inode);
 	iput(inode);
 	return ret;
 }
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index 86e0821..26037e2 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
 	inode->i_blocks = 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;
 }



More information about the linux-mtd-cvs mailing list