diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index bbf3525fd222..06dff2c30c9b 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -219,14 +219,16 @@ static int create_dir(struct kobject *kobj, struct dentry *parent,
 		goto out_drop;
 	sd->s_elem.dir.kobj = kobj;
 
-	inode = sysfs_new_inode(sd);
+	inode = sysfs_get_inode(sd);
 	if (!inode)
 		goto out_sput;
 
-	inode->i_op = &sysfs_dir_inode_operations;
-	inode->i_fop = &sysfs_dir_operations;
-	/* directory inodes start off with i_nlink == 2 (for "." entry) */
-	inc_nlink(inode);
+	if (inode->i_state & I_NEW) {
+		inode->i_op = &sysfs_dir_inode_operations;
+		inode->i_fop = &sysfs_dir_operations;
+		/* directory inodes start off with i_nlink == 2 (for ".") */
+		inc_nlink(inode);
+	}
 
 	/* link in */
 	error = -EEXIST;
@@ -310,20 +312,23 @@ static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry,
 		return NULL;
 
 	/* attach dentry and inode */
-	inode = sysfs_new_inode(sd);
+	inode = sysfs_get_inode(sd);
 	if (!inode)
 		return ERR_PTR(-ENOMEM);
 
-	/* initialize inode according to type */
-	if (sd->s_type & SYSFS_KOBJ_ATTR) {
-		inode->i_size = PAGE_SIZE;
-		inode->i_fop = &sysfs_file_operations;
-	} else if (sd->s_type & SYSFS_KOBJ_BIN_ATTR) {
-		struct bin_attribute *bin_attr = sd->s_elem.bin_attr.bin_attr;
-		inode->i_size = bin_attr->size;
-		inode->i_fop = &bin_fops;
-	} else if (sd->s_type & SYSFS_KOBJ_LINK)
-		inode->i_op = &sysfs_symlink_inode_operations;
+	if (inode->i_state & I_NEW) {
+		/* initialize inode according to type */
+		if (sd->s_type & SYSFS_KOBJ_ATTR) {
+			inode->i_size = PAGE_SIZE;
+			inode->i_fop = &sysfs_file_operations;
+		} else if (sd->s_type & SYSFS_KOBJ_BIN_ATTR) {
+			struct bin_attribute *bin_attr =
+				sd->s_elem.bin_attr.bin_attr;
+			inode->i_size = bin_attr->size;
+			inode->i_fop = &bin_fops;
+		} else if (sd->s_type & SYSFS_KOBJ_LINK)
+			inode->i_op = &sysfs_symlink_inode_operations;
+	}
 
 	sysfs_instantiate(dentry, inode);
 	sysfs_attach_dentry(sd, dentry);
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index 26d8503c8997..3eab9c46a71b 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -153,10 +153,12 @@ void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode)
 }
 
 /**
- *	sysfs_new_inode - allocate new inode for sysfs_dirent
+ *	sysfs_get_inode - get inode for sysfs_dirent
  *	@sd: sysfs_dirent to allocate inode for
  *
- *	Allocate inode for @sd and initialize basics.
+ *	Get inode for @sd.  If such inode doesn't exist, a new inode
+ *	is allocated and basics are initialized.  New inode is
+ *	returned locked.
  *
  *	LOCKING:
  *	Kernel thread context (may sleep).
@@ -164,12 +166,12 @@ void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode)
  *	RETURNS:
  *	Pointer to allocated inode on success, NULL on failure.
  */
-struct inode * sysfs_new_inode(struct sysfs_dirent *sd)
+struct inode * sysfs_get_inode(struct sysfs_dirent *sd)
 {
 	struct inode *inode;
 
-	inode = new_inode(sysfs_sb);
-	if (inode)
+	inode = iget_locked(sysfs_sb, sd->s_ino);
+	if (inode && (inode->i_state & I_NEW))
 		sysfs_init_inode(sd, inode);
 
 	return inode;
@@ -180,7 +182,7 @@ struct inode * sysfs_new_inode(struct sysfs_dirent *sd)
  *	@dentry: dentry to be instantiated
  *	@inode: inode associated with @sd
  *
- *	Instantiate @dentry with @inode.
+ *	Unlock @inode if locked and instantiate @dentry with @inode.
  *
  *	LOCKING:
  *	None.
@@ -189,9 +191,13 @@ void sysfs_instantiate(struct dentry *dentry, struct inode *inode)
 {
 	BUG_ON(!dentry || dentry->d_inode);
 
-	if (dentry->d_parent && dentry->d_parent->d_inode) {
-		struct inode *p_inode = dentry->d_parent->d_inode;
-		p_inode->i_mtime = p_inode->i_ctime = CURRENT_TIME;
+	if (inode->i_state & I_NEW) {
+		unlock_new_inode(inode);
+
+		if (dentry->d_parent && dentry->d_parent->d_inode) {
+			struct inode *p_inode = dentry->d_parent->d_inode;
+			p_inode->i_mtime = p_inode->i_ctime = CURRENT_TIME;
+		}
 	}
 
 	d_instantiate(dentry, inode);
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index 143fdbe56c14..627bf3940dfa 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -58,7 +58,7 @@ extern struct kmem_cache *sysfs_dir_cachep;
 
 extern void sysfs_delete_inode(struct inode *inode);
 extern void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode);
-extern struct inode * sysfs_new_inode(struct sysfs_dirent *sd);
+extern struct inode * sysfs_get_inode(struct sysfs_dirent *sd);
 extern void sysfs_instantiate(struct dentry *dentry, struct inode *inode);
 
 extern void release_sysfs_dirent(struct sysfs_dirent * sd);