Merge branch 'for_linus' into for_linus_merged
[profile/ivi/kernel-adaptation-intel-automotive.git] / fs / ext4 / ialloc.c
index 4637af0..25d8c97 100644 (file)
@@ -252,7 +252,7 @@ void ext4_free_inode(handle_t *handle, struct inode *inode)
                fatal = ext4_journal_get_write_access(handle, bh2);
        }
        ext4_lock_group(sb, block_group);
-       cleared = ext4_clear_bit(bit, bitmap_bh->b_data);
+       cleared = ext4_test_and_clear_bit(bit, bitmap_bh->b_data);
        if (fatal || !cleared) {
                ext4_unlock_group(sb, block_group);
                goto out;
@@ -358,7 +358,7 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent,
        struct ext4_sb_info *sbi = EXT4_SB(sb);
        ext4_group_t real_ngroups = ext4_get_groups_count(sb);
        int inodes_per_group = EXT4_INODES_PER_GROUP(sb);
-       unsigned int freei, avefreei;
+       unsigned int freei, avefreei, grp_free;
        ext4_fsblk_t freeb, avefreec;
        unsigned int ndirs;
        int max_dirs, min_inodes;
@@ -477,8 +477,8 @@ fallback_retry:
        for (i = 0; i < ngroups; i++) {
                grp = (parent_group + i) % ngroups;
                desc = ext4_get_group_desc(sb, grp, NULL);
-               if (desc && ext4_free_inodes_count(sb, desc) &&
-                   ext4_free_inodes_count(sb, desc) >= avefreei) {
+               grp_free = ext4_free_inodes_count(sb, desc);
+               if (desc && grp_free && grp_free >= avefreei) {
                        *group = grp;
                        return 0;
                }
@@ -618,7 +618,7 @@ static int ext4_claim_inode(struct super_block *sb,
         */
        down_read(&grp->alloc_sem);
        ext4_lock_group(sb, group);
-       if (ext4_set_bit(ino, inode_bitmap_bh->b_data)) {
+       if (ext4_test_and_set_bit(ino, inode_bitmap_bh->b_data)) {
                /* not a free inode */
                retval = 1;
                goto err_ret;
@@ -885,8 +885,12 @@ got:
        if (IS_DIRSYNC(inode))
                ext4_handle_sync(handle);
        if (insert_inode_locked(inode) < 0) {
-               err = -EINVAL;
-               goto fail_drop;
+               /*
+                * Likely a bitmap corruption causing inode to be allocated
+                * twice.
+                */
+               err = -EIO;
+               goto fail;
        }
        spin_lock(&sbi->s_next_gen_lock);
        inode->i_generation = sbi->s_next_generation++;