ext4: call ext4_ioend_wait and ext4_flush_completed_IO in ext4_evict_inode
[firefly-linux-kernel-4.4.55.git] / fs / ext4 / super.c
index 9ea71aa864b3a620667aed2c7fbbe5348341d312..44d0c8db2239f958d08d4de4462cdc6ca936d1e1 100644 (file)
@@ -110,6 +110,35 @@ static struct file_system_type ext3_fs_type = {
 #define IS_EXT3_SB(sb) (0)
 #endif
 
+void *ext4_kvmalloc(size_t size, gfp_t flags)
+{
+       void *ret;
+
+       ret = kmalloc(size, flags);
+       if (!ret)
+               ret = __vmalloc(size, flags, PAGE_KERNEL);
+       return ret;
+}
+
+void *ext4_kvzalloc(size_t size, gfp_t flags)
+{
+       void *ret;
+
+       ret = kzalloc(size, flags);
+       if (!ret)
+               ret = __vmalloc(size, flags | __GFP_ZERO, PAGE_KERNEL);
+       return ret;
+}
+
+void ext4_kvfree(void *ptr)
+{
+       if (is_vmalloc_addr(ptr))
+               vfree(ptr);
+       else
+               kfree(ptr);
+
+}
+
 ext4_fsblk_t ext4_block_bitmap(struct super_block *sb,
                               struct ext4_group_desc *bg)
 {
@@ -269,6 +298,7 @@ handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks)
        journal_t *journal;
        handle_t  *handle;
 
+       trace_ext4_journal_start(sb, nblocks, _RET_IP_);
        if (sb->s_flags & MS_RDONLY)
                return ERR_PTR(-EROFS);
 
@@ -789,11 +819,8 @@ static void ext4_put_super(struct super_block *sb)
 
        for (i = 0; i < sbi->s_gdb_count; i++)
                brelse(sbi->s_group_desc[i]);
-       kfree(sbi->s_group_desc);
-       if (is_vmalloc_addr(sbi->s_flex_groups))
-               vfree(sbi->s_flex_groups);
-       else
-               kfree(sbi->s_flex_groups);
+       ext4_kvfree(sbi->s_group_desc);
+       ext4_kvfree(sbi->s_flex_groups);
        percpu_counter_destroy(&sbi->s_freeblocks_counter);
        percpu_counter_destroy(&sbi->s_freeinodes_counter);
        percpu_counter_destroy(&sbi->s_dirs_counter);
@@ -892,7 +919,6 @@ static void ext4_i_callback(struct rcu_head *head)
 
 static void ext4_destroy_inode(struct inode *inode)
 {
-       ext4_ioend_wait(inode);
        if (!list_empty(&(EXT4_I(inode)->i_orphan))) {
                ext4_msg(inode->i_sb, KERN_ERR,
                         "Inode %lu (%p): orphan list check failed!",
@@ -1976,15 +2002,11 @@ static int ext4_fill_flex_info(struct super_block *sb)
                        ((le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) + 1) <<
                              EXT4_DESC_PER_BLOCK_BITS(sb))) / groups_per_flex;
        size = flex_group_count * sizeof(struct flex_groups);
-       sbi->s_flex_groups = kzalloc(size, GFP_KERNEL);
+       sbi->s_flex_groups = ext4_kvzalloc(size, GFP_KERNEL);
        if (sbi->s_flex_groups == NULL) {
-               sbi->s_flex_groups = vzalloc(size);
-               if (sbi->s_flex_groups == NULL) {
-                       ext4_msg(sb, KERN_ERR,
-                                "not enough memory for %u flex groups",
-                                flex_group_count);
-                       goto failed;
-               }
+               ext4_msg(sb, KERN_ERR, "not enough memory for %u flex groups",
+                        flex_group_count);
+               goto failed;
        }
 
        for (i = 0; i < sbi->s_groups_count; i++) {
@@ -2383,17 +2405,25 @@ static unsigned long ext4_get_stripe_size(struct ext4_sb_info *sbi)
        unsigned long stride = le16_to_cpu(sbi->s_es->s_raid_stride);
        unsigned long stripe_width =
                        le32_to_cpu(sbi->s_es->s_raid_stripe_width);
+       int ret;
 
        if (sbi->s_stripe && sbi->s_stripe <= sbi->s_blocks_per_group)
-               return sbi->s_stripe;
-
-       if (stripe_width <= sbi->s_blocks_per_group)
-               return stripe_width;
+               ret = sbi->s_stripe;
+       else if (stripe_width <= sbi->s_blocks_per_group)
+               ret = stripe_width;
+       else if (stride <= sbi->s_blocks_per_group)
+               ret = stride;
+       else
+               ret = 0;
 
-       if (stride <= sbi->s_blocks_per_group)
-               return stride;
+       /*
+        * If the stripe width is 1, this makes no sense and
+        * we set it to 0 to turn off stripe handling code.
+        */
+       if (ret <= 1)
+               ret = 0;
 
-       return 0;
+       return ret;
 }
 
 /* sysfs supprt */
@@ -3408,8 +3438,9 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
                        (EXT4_MAX_BLOCK_FILE_PHYS / EXT4_BLOCKS_PER_GROUP(sb)));
        db_count = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) /
                   EXT4_DESC_PER_BLOCK(sb);
-       sbi->s_group_desc = kmalloc(db_count * sizeof(struct buffer_head *),
-                                   GFP_KERNEL);
+       sbi->s_group_desc = ext4_kvmalloc(db_count *
+                                         sizeof(struct buffer_head *),
+                                         GFP_KERNEL);
        if (sbi->s_group_desc == NULL) {
                ext4_msg(sb, KERN_ERR, "not enough memory");
                goto failed_mount;
@@ -3491,7 +3522,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 
        INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */
        mutex_init(&sbi->s_orphan_lock);
-       mutex_init(&sbi->s_resize_lock);
+       sbi->s_resize_flags = 0;
 
        sb->s_root = NULL;
 
@@ -3741,12 +3772,8 @@ failed_mount_wq:
        }
 failed_mount3:
        del_timer(&sbi->s_err_report);
-       if (sbi->s_flex_groups) {
-               if (is_vmalloc_addr(sbi->s_flex_groups))
-                       vfree(sbi->s_flex_groups);
-               else
-                       kfree(sbi->s_flex_groups);
-       }
+       if (sbi->s_flex_groups)
+               ext4_kvfree(sbi->s_flex_groups);
        percpu_counter_destroy(&sbi->s_freeblocks_counter);
        percpu_counter_destroy(&sbi->s_freeinodes_counter);
        percpu_counter_destroy(&sbi->s_dirs_counter);
@@ -3756,7 +3783,7 @@ failed_mount3:
 failed_mount2:
        for (i = 0; i < db_count; i++)
                brelse(sbi->s_group_desc[i]);
-       kfree(sbi->s_group_desc);
+       ext4_kvfree(sbi->s_group_desc);
 failed_mount:
        if (sbi->s_proc) {
                remove_proc_entry(sb->s_id, ext4_proc_root);