Merge tag 'powerpc-5.9-3' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc...
[linux-2.6-microblaze.git] / fs / ext4 / super.c
index 0907f90..ea425b4 100644 (file)
@@ -66,10 +66,10 @@ static int ext4_load_journal(struct super_block *, struct ext4_super_block *,
                             unsigned long journal_devnum);
 static int ext4_show_options(struct seq_file *seq, struct dentry *root);
 static int ext4_commit_super(struct super_block *sb, int sync);
-static void ext4_mark_recovery_complete(struct super_block *sb,
+static int ext4_mark_recovery_complete(struct super_block *sb,
                                        struct ext4_super_block *es);
-static void ext4_clear_journal_err(struct super_block *sb,
-                                  struct ext4_super_block *es);
+static int ext4_clear_journal_err(struct super_block *sb,
+                                 struct ext4_super_block *es);
 static int ext4_sync_fs(struct super_block *sb, int wait);
 static int ext4_remount(struct super_block *sb, int *flags, char *data);
 static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf);
@@ -744,6 +744,7 @@ void __ext4_msg(struct super_block *sb,
        struct va_format vaf;
        va_list args;
 
+       atomic_inc(&EXT4_SB(sb)->s_msg_count);
        if (!___ratelimit(&(EXT4_SB(sb)->s_msg_ratelimit_state), "EXT4-fs"))
                return;
 
@@ -754,9 +755,12 @@ void __ext4_msg(struct super_block *sb,
        va_end(args);
 }
 
-#define ext4_warning_ratelimit(sb)                                     \
-               ___ratelimit(&(EXT4_SB(sb)->s_warning_ratelimit_state), \
-                            "EXT4-fs warning")
+static int ext4_warning_ratelimit(struct super_block *sb)
+{
+       atomic_inc(&EXT4_SB(sb)->s_warning_count);
+       return ___ratelimit(&(EXT4_SB(sb)->s_warning_ratelimit_state),
+                           "EXT4-fs warning");
+}
 
 void __ext4_warning(struct super_block *sb, const char *function,
                    unsigned int line, const char *fmt, ...)
@@ -1123,6 +1127,7 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
        inode_set_iversion(&ei->vfs_inode, 1);
        spin_lock_init(&ei->i_raw_lock);
        INIT_LIST_HEAD(&ei->i_prealloc_list);
+       atomic_set(&ei->i_prealloc_active, 0);
        spin_lock_init(&ei->i_prealloc_lock);
        ext4_es_init_tree(&ei->i_es_tree);
        rwlock_init(&ei->i_es_lock);
@@ -1216,7 +1221,7 @@ void ext4_clear_inode(struct inode *inode)
 {
        invalidate_inode_buffers(inode);
        clear_inode(inode);
-       ext4_discard_preallocations(inode);
+       ext4_discard_preallocations(inode, 0);
        ext4_es_remove_extent(inode, 0, EXT_MAX_BLOCKS);
        dquot_drop(inode);
        if (EXT4_I(inode)->jinode) {
@@ -1288,8 +1293,8 @@ static int bdev_try_to_free_page(struct super_block *sb, struct page *page,
        if (!page_has_buffers(page))
                return 0;
        if (journal)
-               return jbd2_journal_try_to_free_buffers(journal, page,
-                                               wait & ~__GFP_DIRECT_RECLAIM);
+               return jbd2_journal_try_to_free_buffers(journal, page);
+
        return try_to_free_buffers(page);
 }
 
@@ -1522,6 +1527,7 @@ enum {
        Opt_dioread_nolock, Opt_dioread_lock,
        Opt_discard, Opt_nodiscard, Opt_init_itable, Opt_noinit_itable,
        Opt_max_dir_size_kb, Opt_nojournal_checksum, Opt_nombcache,
+       Opt_prefetch_block_bitmaps,
 };
 
 static const match_table_t tokens = {
@@ -1614,6 +1620,7 @@ static const match_table_t tokens = {
        {Opt_inlinecrypt, "inlinecrypt"},
        {Opt_nombcache, "nombcache"},
        {Opt_nombcache, "no_mbcache"},  /* for backward compatibility */
+       {Opt_prefetch_block_bitmaps, "prefetch_block_bitmaps"},
        {Opt_removed, "check=none"},    /* mount option from ext2/3 */
        {Opt_removed, "nocheck"},       /* mount option from ext2/3 */
        {Opt_removed, "reservation"},   /* mount option from ext2/3 */
@@ -1831,6 +1838,8 @@ static const struct mount_opts {
        {Opt_max_dir_size_kb, 0, MOPT_GTE0},
        {Opt_test_dummy_encryption, 0, MOPT_STRING},
        {Opt_nombcache, EXT4_MOUNT_NO_MBCACHE, MOPT_SET},
+       {Opt_prefetch_block_bitmaps, EXT4_MOUNT_PREFETCH_BLOCK_BITMAPS,
+        MOPT_SET},
        {Opt_err, 0, 0}
 };
 
@@ -3213,15 +3222,34 @@ static void print_daily_error_info(struct timer_list *t)
 static int ext4_run_li_request(struct ext4_li_request *elr)
 {
        struct ext4_group_desc *gdp = NULL;
-       ext4_group_t group, ngroups;
-       struct super_block *sb;
+       struct super_block *sb = elr->lr_super;
+       ext4_group_t ngroups = EXT4_SB(sb)->s_groups_count;
+       ext4_group_t group = elr->lr_next_group;
        unsigned long timeout = 0;
+       unsigned int prefetch_ios = 0;
        int ret = 0;
 
-       sb = elr->lr_super;
-       ngroups = EXT4_SB(sb)->s_groups_count;
+       if (elr->lr_mode == EXT4_LI_MODE_PREFETCH_BBITMAP) {
+               elr->lr_next_group = ext4_mb_prefetch(sb, group,
+                               EXT4_SB(sb)->s_mb_prefetch, &prefetch_ios);
+               if (prefetch_ios)
+                       ext4_mb_prefetch_fini(sb, elr->lr_next_group,
+                                             prefetch_ios);
+               trace_ext4_prefetch_bitmaps(sb, group, elr->lr_next_group,
+                                           prefetch_ios);
+               if (group >= elr->lr_next_group) {
+                       ret = 1;
+                       if (elr->lr_first_not_zeroed != ngroups &&
+                           !sb_rdonly(sb) && test_opt(sb, INIT_INODE_TABLE)) {
+                               elr->lr_next_group = elr->lr_first_not_zeroed;
+                               elr->lr_mode = EXT4_LI_MODE_ITABLE;
+                               ret = 0;
+                       }
+               }
+               return ret;
+       }
 
-       for (group = elr->lr_next_group; group < ngroups; group++) {
+       for (; group < ngroups; group++) {
                gdp = ext4_get_group_desc(sb, group, NULL);
                if (!gdp) {
                        ret = 1;
@@ -3239,9 +3267,10 @@ static int ext4_run_li_request(struct ext4_li_request *elr)
                timeout = jiffies;
                ret = ext4_init_inode_table(sb, group,
                                            elr->lr_timeout ? 0 : 1);
+               trace_ext4_lazy_itable_init(sb, group);
                if (elr->lr_timeout == 0) {
                        timeout = (jiffies - timeout) *
-                                 elr->lr_sbi->s_li_wait_mult;
+                               EXT4_SB(elr->lr_super)->s_li_wait_mult;
                        elr->lr_timeout = timeout;
                }
                elr->lr_next_sched = jiffies + elr->lr_timeout;
@@ -3256,15 +3285,11 @@ static int ext4_run_li_request(struct ext4_li_request *elr)
  */
 static void ext4_remove_li_request(struct ext4_li_request *elr)
 {
-       struct ext4_sb_info *sbi;
-
        if (!elr)
                return;
 
-       sbi = elr->lr_sbi;
-
        list_del(&elr->lr_request);
-       sbi->s_li_request = NULL;
+       EXT4_SB(elr->lr_super)->s_li_request = NULL;
        kfree(elr);
 }
 
@@ -3473,7 +3498,6 @@ static int ext4_li_info_new(void)
 static struct ext4_li_request *ext4_li_request_new(struct super_block *sb,
                                            ext4_group_t start)
 {
-       struct ext4_sb_info *sbi = EXT4_SB(sb);
        struct ext4_li_request *elr;
 
        elr = kzalloc(sizeof(*elr), GFP_KERNEL);
@@ -3481,8 +3505,13 @@ static struct ext4_li_request *ext4_li_request_new(struct super_block *sb,
                return NULL;
 
        elr->lr_super = sb;
-       elr->lr_sbi = sbi;
-       elr->lr_next_group = start;
+       elr->lr_first_not_zeroed = start;
+       if (test_opt(sb, PREFETCH_BLOCK_BITMAPS))
+               elr->lr_mode = EXT4_LI_MODE_PREFETCH_BBITMAP;
+       else {
+               elr->lr_mode = EXT4_LI_MODE_ITABLE;
+               elr->lr_next_group = start;
+       }
 
        /*
         * Randomize first schedule time of the request to
@@ -3512,8 +3541,9 @@ int ext4_register_li_request(struct super_block *sb,
                goto out;
        }
 
-       if (first_not_zeroed == ngroups || sb_rdonly(sb) ||
-           !test_opt(sb, INIT_INODE_TABLE))
+       if (!test_opt(sb, PREFETCH_BLOCK_BITMAPS) &&
+           (first_not_zeroed == ngroups || sb_rdonly(sb) ||
+            !test_opt(sb, INIT_INODE_TABLE)))
                goto out;
 
        elr = ext4_li_request_new(sb, first_not_zeroed);
@@ -4710,11 +4740,13 @@ no_journal:
 
        ext4_set_resv_clusters(sb);
 
-       err = ext4_setup_system_zone(sb);
-       if (err) {
-               ext4_msg(sb, KERN_ERR, "failed to initialize system "
-                        "zone (%d)", err);
-               goto failed_mount4a;
+       if (test_opt(sb, BLOCK_VALIDITY)) {
+               err = ext4_setup_system_zone(sb);
+               if (err) {
+                       ext4_msg(sb, KERN_ERR, "failed to initialize system "
+                                "zone (%d)", err);
+                       goto failed_mount4a;
+               }
        }
 
        ext4_ext_init(sb);
@@ -4777,12 +4809,23 @@ no_journal:
        }
 #endif  /* CONFIG_QUOTA */
 
+       /*
+        * Save the original bdev mapping's wb_err value which could be
+        * used to detect the metadata async write error.
+        */
+       spin_lock_init(&sbi->s_bdev_wb_lock);
+       if (!sb_rdonly(sb))
+               errseq_check_and_advance(&sb->s_bdev->bd_inode->i_mapping->wb_err,
+                                        &sbi->s_bdev_wb_err);
+       sb->s_bdev->bd_super = sb;
        EXT4_SB(sb)->s_mount_state |= EXT4_ORPHAN_FS;
        ext4_orphan_cleanup(sb, es);
        EXT4_SB(sb)->s_mount_state &= ~EXT4_ORPHAN_FS;
        if (needs_recovery) {
                ext4_msg(sb, KERN_INFO, "recovery complete");
-               ext4_mark_recovery_complete(sb, es);
+               err = ext4_mark_recovery_complete(sb, es);
+               if (err)
+                       goto failed_mount8;
        }
        if (EXT4_SB(sb)->s_journal) {
                if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA)
@@ -4816,6 +4859,8 @@ no_journal:
        ratelimit_state_init(&sbi->s_err_ratelimit_state, 5 * HZ, 10);
        ratelimit_state_init(&sbi->s_warning_ratelimit_state, 5 * HZ, 10);
        ratelimit_state_init(&sbi->s_msg_ratelimit_state, 5 * HZ, 10);
+       atomic_set(&sbi->s_warning_count, 0);
+       atomic_set(&sbi->s_msg_count, 0);
 
        kfree(orig_data);
        return 0;
@@ -4825,10 +4870,8 @@ cantfind_ext4:
                ext4_msg(sb, KERN_ERR, "VFS: Can't find ext4 filesystem");
        goto failed_mount;
 
-#ifdef CONFIG_QUOTA
 failed_mount8:
        ext4_unregister_sysfs(sb);
-#endif
 failed_mount7:
        ext4_unregister_li_request(sb);
 failed_mount6:
@@ -4968,7 +5011,8 @@ static journal_t *ext4_get_journal(struct super_block *sb,
        struct inode *journal_inode;
        journal_t *journal;
 
-       BUG_ON(!ext4_has_feature_journal(sb));
+       if (WARN_ON_ONCE(!ext4_has_feature_journal(sb)))
+               return NULL;
 
        journal_inode = ext4_get_journal_inode(sb, journal_inum);
        if (!journal_inode)
@@ -4998,7 +5042,8 @@ static journal_t *ext4_get_dev_journal(struct super_block *sb,
        struct ext4_super_block *es;
        struct block_device *bdev;
 
-       BUG_ON(!ext4_has_feature_journal(sb));
+       if (WARN_ON_ONCE(!ext4_has_feature_journal(sb)))
+               return NULL;
 
        bdev = ext4_blkdev_get(j_dev, sb);
        if (bdev == NULL)
@@ -5089,8 +5134,10 @@ static int ext4_load_journal(struct super_block *sb,
        dev_t journal_dev;
        int err = 0;
        int really_read_only;
+       int journal_dev_ro;
 
-       BUG_ON(!ext4_has_feature_journal(sb));
+       if (WARN_ON_ONCE(!ext4_has_feature_journal(sb)))
+               return -EFSCORRUPTED;
 
        if (journal_devnum &&
            journal_devnum != le32_to_cpu(es->s_journal_dev)) {
@@ -5100,7 +5147,31 @@ static int ext4_load_journal(struct super_block *sb,
        } else
                journal_dev = new_decode_dev(le32_to_cpu(es->s_journal_dev));
 
-       really_read_only = bdev_read_only(sb->s_bdev);
+       if (journal_inum && journal_dev) {
+               ext4_msg(sb, KERN_ERR,
+                        "filesystem has both journal inode and journal device!");
+               return -EINVAL;
+       }
+
+       if (journal_inum) {
+               journal = ext4_get_journal(sb, journal_inum);
+               if (!journal)
+                       return -EINVAL;
+       } else {
+               journal = ext4_get_dev_journal(sb, journal_dev);
+               if (!journal)
+                       return -EINVAL;
+       }
+
+       journal_dev_ro = bdev_read_only(journal->j_dev);
+       really_read_only = bdev_read_only(sb->s_bdev) | journal_dev_ro;
+
+       if (journal_dev_ro && !sb_rdonly(sb)) {
+               ext4_msg(sb, KERN_ERR,
+                        "journal device read-only, try mounting with '-o ro'");
+               err = -EROFS;
+               goto err_out;
+       }
 
        /*
         * Are we loading a blank journal or performing recovery after a
@@ -5115,27 +5186,14 @@ static int ext4_load_journal(struct super_block *sb,
                                ext4_msg(sb, KERN_ERR, "write access "
                                        "unavailable, cannot proceed "
                                        "(try mounting with noload)");
-                               return -EROFS;
+                               err = -EROFS;
+                               goto err_out;
                        }
                        ext4_msg(sb, KERN_INFO, "write access will "
                               "be enabled during recovery");
                }
        }
 
-       if (journal_inum && journal_dev) {
-               ext4_msg(sb, KERN_ERR, "filesystem has both journal "
-                      "and inode journals!");
-               return -EINVAL;
-       }
-
-       if (journal_inum) {
-               if (!(journal = ext4_get_journal(sb, journal_inum)))
-                       return -EINVAL;
-       } else {
-               if (!(journal = ext4_get_dev_journal(sb, journal_dev)))
-                       return -EINVAL;
-       }
-
        if (!(journal->j_flags & JBD2_BARRIER))
                ext4_msg(sb, KERN_INFO, "barriers disabled");
 
@@ -5155,12 +5213,16 @@ static int ext4_load_journal(struct super_block *sb,
 
        if (err) {
                ext4_msg(sb, KERN_ERR, "error loading journal");
-               jbd2_journal_destroy(journal);
-               return err;
+               goto err_out;
        }
 
        EXT4_SB(sb)->s_journal = journal;
-       ext4_clear_journal_err(sb, es);
+       err = ext4_clear_journal_err(sb, es);
+       if (err) {
+               EXT4_SB(sb)->s_journal = NULL;
+               jbd2_journal_destroy(journal);
+               return err;
+       }
 
        if (!really_read_only && journal_devnum &&
            journal_devnum != le32_to_cpu(es->s_journal_dev)) {
@@ -5171,6 +5233,10 @@ static int ext4_load_journal(struct super_block *sb,
        }
 
        return 0;
+
+err_out:
+       jbd2_journal_destroy(journal);
+       return err;
 }
 
 static int ext4_commit_super(struct super_block *sb, int sync)
@@ -5182,13 +5248,6 @@ static int ext4_commit_super(struct super_block *sb, int sync)
        if (!sbh || block_device_ejected(sb))
                return error;
 
-       /*
-        * The superblock bh should be mapped, but it might not be if the
-        * device was hot-removed. Not much we can do but fail the I/O.
-        */
-       if (!buffer_mapped(sbh))
-               return error;
-
        /*
         * If the file system is mounted read-only, don't update the
         * superblock write time.  This avoids updating the superblock
@@ -5256,26 +5315,32 @@ static int ext4_commit_super(struct super_block *sb, int sync)
  * remounting) the filesystem readonly, then we will end up with a
  * consistent fs on disk.  Record that fact.
  */
-static void ext4_mark_recovery_complete(struct super_block *sb,
-                                       struct ext4_super_block *es)
+static int ext4_mark_recovery_complete(struct super_block *sb,
+                                      struct ext4_super_block *es)
 {
+       int err;
        journal_t *journal = EXT4_SB(sb)->s_journal;
 
        if (!ext4_has_feature_journal(sb)) {
-               BUG_ON(journal != NULL);
-               return;
+               if (journal != NULL) {
+                       ext4_error(sb, "Journal got removed while the fs was "
+                                  "mounted!");
+                       return -EFSCORRUPTED;
+               }
+               return 0;
        }
        jbd2_journal_lock_updates(journal);
-       if (jbd2_journal_flush(journal) < 0)
+       err = jbd2_journal_flush(journal);
+       if (err < 0)
                goto out;
 
        if (ext4_has_feature_journal_needs_recovery(sb) && sb_rdonly(sb)) {
                ext4_clear_feature_journal_needs_recovery(sb);
                ext4_commit_super(sb, 1);
        }
-
 out:
        jbd2_journal_unlock_updates(journal);
+       return err;
 }
 
 /*
@@ -5283,14 +5348,17 @@ out:
  * has recorded an error from a previous lifetime, move that error to the
  * main filesystem now.
  */
-static void ext4_clear_journal_err(struct super_block *sb,
+static int ext4_clear_journal_err(struct super_block *sb,
                                   struct ext4_super_block *es)
 {
        journal_t *journal;
        int j_errno;
        const char *errstr;
 
-       BUG_ON(!ext4_has_feature_journal(sb));
+       if (!ext4_has_feature_journal(sb)) {
+               ext4_error(sb, "Journal got removed while the fs was mounted!");
+               return -EFSCORRUPTED;
+       }
 
        journal = EXT4_SB(sb)->s_journal;
 
@@ -5315,6 +5383,7 @@ static void ext4_clear_journal_err(struct super_block *sb,
                jbd2_journal_clear_err(journal);
                jbd2_journal_update_sb_errno(journal);
        }
+       return 0;
 }
 
 /*
@@ -5457,7 +5526,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
 {
        struct ext4_super_block *es;
        struct ext4_sb_info *sbi = EXT4_SB(sb);
-       unsigned long old_sb_flags;
+       unsigned long old_sb_flags, vfs_flags;
        struct ext4_mount_options old_opts;
        int enable_quota = 0;
        ext4_group_t g;
@@ -5500,6 +5569,14 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
        if (sbi->s_journal && sbi->s_journal->j_task->io_context)
                journal_ioprio = sbi->s_journal->j_task->io_context->ioprio;
 
+       /*
+        * Some options can be enabled by ext4 and/or by VFS mount flag
+        * either way we need to make sure it matches in both *flags and
+        * s_flags. Copy those selected flags from *flags to s_flags
+        */
+       vfs_flags = SB_LAZYTIME | SB_I_VERSION;
+       sb->s_flags = (sb->s_flags & ~vfs_flags) | (*flags & vfs_flags);
+
        if (!parse_options(data, sb, NULL, &journal_ioprio, 1)) {
                err = -EINVAL;
                goto restore_opts;
@@ -5553,9 +5630,6 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
                set_task_ioprio(sbi->s_journal->j_task, journal_ioprio);
        }
 
-       if (*flags & SB_LAZYTIME)
-               sb->s_flags |= SB_LAZYTIME;
-
        if ((bool)(*flags & SB_RDONLY) != sb_rdonly(sb)) {
                if (sbi->s_mount_flags & EXT4_MF_FS_ABORTED) {
                        err = -EROFS;
@@ -5585,8 +5659,13 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
                            (sbi->s_mount_state & EXT4_VALID_FS))
                                es->s_state = cpu_to_le16(sbi->s_mount_state);
 
-                       if (sbi->s_journal)
+                       if (sbi->s_journal) {
+                               /*
+                                * We let remount-ro finish even if marking fs
+                                * as clean failed...
+                                */
                                ext4_mark_recovery_complete(sb, es);
+                       }
                        if (sbi->s_mmp_tsk)
                                kthread_stop(sbi->s_mmp_tsk);
                } else {
@@ -5628,14 +5707,25 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
                                goto restore_opts;
                        }
 
+                       /*
+                        * Update the original bdev mapping's wb_err value
+                        * which could be used to detect the metadata async
+                        * write error.
+                        */
+                       errseq_check_and_advance(&sb->s_bdev->bd_inode->i_mapping->wb_err,
+                                                &sbi->s_bdev_wb_err);
+
                        /*
                         * Mounting a RDONLY partition read-write, so reread
                         * and store the current valid flag.  (It may have
                         * been changed by e2fsck since we originally mounted
                         * the partition.)
                         */
-                       if (sbi->s_journal)
-                               ext4_clear_journal_err(sb, es);
+                       if (sbi->s_journal) {
+                               err = ext4_clear_journal_err(sb, es);
+                               if (err)
+                                       goto restore_opts;
+                       }
                        sbi->s_mount_state = le16_to_cpu(es->s_state);
 
                        err = ext4_setup_super(sb, es, 0);
@@ -5665,7 +5755,17 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
                ext4_register_li_request(sb, first_not_zeroed);
        }
 
-       ext4_setup_system_zone(sb);
+       /*
+        * Handle creation of system zone data early because it can fail.
+        * Releasing of existing data is done when we are sure remount will
+        * succeed.
+        */
+       if (test_opt(sb, BLOCK_VALIDITY) && !sbi->system_blks) {
+               err = ext4_setup_system_zone(sb);
+               if (err)
+                       goto restore_opts;
+       }
+
        if (sbi->s_journal == NULL && !(old_sb_flags & SB_RDONLY)) {
                err = ext4_commit_super(sb, 1);
                if (err)
@@ -5686,8 +5786,16 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
                }
        }
 #endif
+       if (!test_opt(sb, BLOCK_VALIDITY) && sbi->system_blks)
+               ext4_release_system_zone(sb);
+
+       /*
+        * Some options can be enabled by ext4 and/or by VFS mount flag
+        * either way we need to make sure it matches in both *flags and
+        * s_flags. Copy those selected flags from s_flags to *flags
+        */
+       *flags = (*flags & ~vfs_flags) | (sb->s_flags & vfs_flags);
 
-       *flags = (*flags & ~SB_LAZYTIME) | (sb->s_flags & SB_LAZYTIME);
        ext4_msg(sb, KERN_INFO, "re-mounted. Opts: %s", orig_data);
        kfree(orig_data);
        return 0;
@@ -5701,6 +5809,8 @@ restore_opts:
        sbi->s_commit_interval = old_opts.s_commit_interval;
        sbi->s_min_batch_time = old_opts.s_min_batch_time;
        sbi->s_max_batch_time = old_opts.s_max_batch_time;
+       if (!test_opt(sb, BLOCK_VALIDITY) && sbi->system_blks)
+               ext4_release_system_zone(sb);
 #ifdef CONFIG_QUOTA
        sbi->s_jquota_fmt = old_opts.s_jquota_fmt;
        for (i = 0; i < EXT4_MAXQUOTAS; i++) {