ext4_grpblk_t bit;
        unsigned int i;
        struct ext4_group_desc *desc;
-       struct ext4_super_block *es;
-       struct ext4_sb_info *sbi;
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
        int err = 0, ret, blk_free_count;
        ext4_grpblk_t blocks_freed;
        struct ext4_group_info *grp;
 
-       sbi = EXT4_SB(sb);
-       es = sbi->s_es;
        ext4_debug("Adding block(s) %llu-%llu\n", block, block + count - 1);
 
        ext4_get_group_no_and_offset(sb, block, &block_group, &bit);
        ret = ext4_handle_dirty_metadata(handle, NULL, gd_bh);
        if (!err)
                err = ret;
-       sb->s_dirt = 1;
 
 error_return:
        brelse(bitmap_bh);
 
        spin_unlock(ext4_group_lock_ptr(sb, group));
 }
 
+static inline void ext4_mark_super_dirty(struct super_block *sb)
+{
+       if (EXT4_SB(sb)->s_journal == NULL)
+               sb->s_dirt =1;
+}
+
 /*
  * Inodes and files operations
  */
 
        }
        return err;
 }
+
+int __ext4_handle_dirty_super(const char *where, handle_t *handle,
+                             struct super_block *sb)
+{
+       struct buffer_head *bh = EXT4_SB(sb)->s_sbh;
+       int err = 0;
+
+       if (ext4_handle_valid(handle)) {
+               err = jbd2_journal_dirty_metadata(handle, bh);
+               if (err)
+                       ext4_journal_abort_handle(where, __func__, bh,
+                                                 handle, err);
+       } else
+               sb->s_dirt = 1;
+       return err;
+}
 
 int __ext4_handle_dirty_metadata(const char *where, handle_t *handle,
                                 struct inode *inode, struct buffer_head *bh);
 
+int __ext4_handle_dirty_super(const char *where, handle_t *handle,
+                             struct super_block *sb);
+
 #define ext4_journal_get_undo_access(handle, bh) \
        __ext4_journal_get_undo_access(__func__, (handle), (bh))
 #define ext4_journal_get_write_access(handle, bh) \
        __ext4_journal_get_create_access(__func__, (handle), (bh))
 #define ext4_handle_dirty_metadata(handle, inode, bh) \
        __ext4_handle_dirty_metadata(__func__, (handle), (inode), (bh))
+#define ext4_handle_dirty_super(handle, sb) \
+       __ext4_handle_dirty_super(__func__, (handle), (sb))
 
 handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks);
 int __ext4_journal_stop(const char *where, handle_t *handle);
 
                if (!IS_ERR(cp)) {
                        memcpy(sbi->s_es->s_last_mounted, cp,
                               sizeof(sbi->s_es->s_last_mounted));
-                       sb->s_dirt = 1;
+                       ext4_mark_super_dirty(sb);
                }
        }
        return dquot_file_open(inode, filp);
 
                err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh);
                if (!fatal)
                        fatal = err;
-               sb->s_dirt = 1;
+               ext4_mark_super_dirty(sb);
        } else
                ext4_error(sb, "bit already cleared for inode %lu", ino);
 
        percpu_counter_dec(&sbi->s_freeinodes_counter);
        if (S_ISDIR(mode))
                percpu_counter_inc(&sbi->s_dirs_counter);
-       sb->s_dirt = 1;
+       ext4_mark_super_dirty(sb);
 
        if (sbi->s_log_groups_per_flex) {
                flex_group = ext4_flex_group(sbi, group);
 
        err = ext4_handle_dirty_metadata(handle, NULL, gdp_bh);
 
 out_err:
-       sb->s_dirt = 1;
+       ext4_mark_super_dirty(sb);
        brelse(bitmap_bh);
        return err;
 }
                put_bh(bitmap_bh);
                goto do_more;
        }
-       sb->s_dirt = 1;
+       ext4_mark_super_dirty(sb);
 error_return:
        if (freed)
                dquot_free_block(inode, freed);
 
                           &sbi->s_flex_groups[flex_group].free_inodes);
        }
 
-       ext4_handle_dirty_metadata(handle, NULL, sbi->s_sbh);
-       sb->s_dirt = 1;
+       ext4_handle_dirty_super(handle, sb);
 
 exit_journal:
        mutex_unlock(&sbi->s_resize_lock);
                goto exit_put;
        }
        ext4_blocks_count_set(es, o_blocks_count + add);
-       ext4_handle_dirty_metadata(handle, NULL, EXT4_SB(sb)->s_sbh);
-       sb->s_dirt = 1;
        mutex_unlock(&EXT4_SB(sb)->s_resize_lock);
        ext4_debug("freeing blocks %llu through %llu\n", o_blocks_count,
                   o_blocks_count + add);
        /* We add the blocks to the bitmap and set the group need init bit */
        ext4_add_groupblocks(handle, sb, o_blocks_count, add);
+       ext4_handle_dirty_super(handle, sb);
        ext4_debug("freed blocks %llu through %llu\n", o_blocks_count,
                   o_blocks_count + add);
        if ((err = ext4_journal_stop(handle)))
 
 
        if (ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh) == 0) {
                EXT4_SET_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_EXT_ATTR);
-               sb->s_dirt = 1;
-               ext4_handle_dirty_metadata(handle, NULL, EXT4_SB(sb)->s_sbh);
+               ext4_handle_dirty_super(handle, sb);
        }
 }