spin_lock(&sbi->s_next_gen_lock);
        inode->i_generation = sbi->s_next_generation++;
        spin_unlock(&sbi->s_next_gen_lock);
-       insert_inode_hash(inode);
+       if (insert_inode_locked(inode) < 0) {
+               err = -EINVAL;
+               goto fail_drop;
+       }
 
        if (DQUOT_ALLOC_INODE(inode)) {
                err = -EDQUOT;
        DQUOT_DROP(inode);
        inode->i_flags |= S_NOQUOTA;
        inode->i_nlink = 0;
+       unlock_new_inode(inode);
        iput(inode);
        return ERR_PTR(err);
 
 
        int err = ext2_add_link(dentry, inode);
        if (!err) {
                d_instantiate(dentry, inode);
+               unlock_new_inode(inode);
                return 0;
        }
        inode_dec_link_count(inode);
+       unlock_new_inode(inode);
        iput(inode);
        return err;
 }
 
 out_fail:
        inode_dec_link_count(inode);
+       unlock_new_inode(inode);
        iput (inode);
        goto out;
 }
        struct dentry *dentry)
 {
        struct inode *inode = old_dentry->d_inode;
+       int err;
 
        if (inode->i_nlink >= EXT2_LINK_MAX)
                return -EMLINK;
        inode_inc_link_count(inode);
        atomic_inc(&inode->i_count);
 
-       return ext2_add_nondir(dentry, inode);
+       err = ext2_add_link(dentry, inode);
+       if (!err) {
+               d_instantiate(dentry, inode);
+               return 0;
+       }
+       inode_dec_link_count(inode);
+       iput(inode);
+       return err;
 }
 
 static int ext2_mkdir(struct inode * dir, struct dentry * dentry, int mode)
                goto out_fail;
 
        d_instantiate(dentry, inode);
+       unlock_new_inode(inode);
 out:
        return err;
 
 out_fail:
        inode_dec_link_count(inode);
        inode_dec_link_count(inode);
+       unlock_new_inode(inode);
        iput(inode);
 out_dir:
        inode_dec_link_count(dir);