aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r--fs/ext4/super.c117
1 files changed, 66 insertions, 51 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index e14d22c170d5..4e8983a9811b 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -241,6 +241,7 @@ handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks)
241 if (sb->s_flags & MS_RDONLY) 241 if (sb->s_flags & MS_RDONLY)
242 return ERR_PTR(-EROFS); 242 return ERR_PTR(-EROFS);
243 243
244 vfs_check_frozen(sb, SB_FREEZE_WRITE);
244 /* Special case here: if the journal has aborted behind our 245 /* Special case here: if the journal has aborted behind our
245 * backs (eg. EIO in the commit thread), then we still need to 246 * backs (eg. EIO in the commit thread), then we still need to
246 * take the FS itself readonly cleanly. */ 247 * take the FS itself readonly cleanly. */
@@ -645,6 +646,8 @@ static void ext4_put_super(struct super_block *sb)
645 struct ext4_super_block *es = sbi->s_es; 646 struct ext4_super_block *es = sbi->s_es;
646 int i, err; 647 int i, err;
647 648
649 dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED);
650
648 flush_workqueue(sbi->dio_unwritten_wq); 651 flush_workqueue(sbi->dio_unwritten_wq);
649 destroy_workqueue(sbi->dio_unwritten_wq); 652 destroy_workqueue(sbi->dio_unwritten_wq);
650 653
@@ -941,6 +944,8 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs)
941 seq_puts(seq, test_opt(sb, BARRIER) ? "1" : "0"); 944 seq_puts(seq, test_opt(sb, BARRIER) ? "1" : "0");
942 if (test_opt(sb, JOURNAL_ASYNC_COMMIT)) 945 if (test_opt(sb, JOURNAL_ASYNC_COMMIT))
943 seq_puts(seq, ",journal_async_commit"); 946 seq_puts(seq, ",journal_async_commit");
947 else if (test_opt(sb, JOURNAL_CHECKSUM))
948 seq_puts(seq, ",journal_checksum");
944 if (test_opt(sb, NOBH)) 949 if (test_opt(sb, NOBH))
945 seq_puts(seq, ",nobh"); 950 seq_puts(seq, ",nobh");
946 if (test_opt(sb, I_VERSION)) 951 if (test_opt(sb, I_VERSION))
@@ -1059,7 +1064,7 @@ static int ext4_release_dquot(struct dquot *dquot);
1059static int ext4_mark_dquot_dirty(struct dquot *dquot); 1064static int ext4_mark_dquot_dirty(struct dquot *dquot);
1060static int ext4_write_info(struct super_block *sb, int type); 1065static int ext4_write_info(struct super_block *sb, int type);
1061static int ext4_quota_on(struct super_block *sb, int type, int format_id, 1066static int ext4_quota_on(struct super_block *sb, int type, int format_id,
1062 char *path, int remount); 1067 char *path);
1063static int ext4_quota_on_mount(struct super_block *sb, int type); 1068static int ext4_quota_on_mount(struct super_block *sb, int type);
1064static ssize_t ext4_quota_read(struct super_block *sb, int type, char *data, 1069static ssize_t ext4_quota_read(struct super_block *sb, int type, char *data,
1065 size_t len, loff_t off); 1070 size_t len, loff_t off);
@@ -1081,12 +1086,12 @@ static const struct dquot_operations ext4_quota_operations = {
1081 1086
1082static const struct quotactl_ops ext4_qctl_operations = { 1087static const struct quotactl_ops ext4_qctl_operations = {
1083 .quota_on = ext4_quota_on, 1088 .quota_on = ext4_quota_on,
1084 .quota_off = vfs_quota_off, 1089 .quota_off = dquot_quota_off,
1085 .quota_sync = vfs_quota_sync, 1090 .quota_sync = dquot_quota_sync,
1086 .get_info = vfs_get_dqinfo, 1091 .get_info = dquot_get_dqinfo,
1087 .set_info = vfs_set_dqinfo, 1092 .set_info = dquot_set_dqinfo,
1088 .get_dqblk = vfs_get_dqblk, 1093 .get_dqblk = dquot_get_dqblk,
1089 .set_dqblk = vfs_set_dqblk 1094 .set_dqblk = dquot_set_dqblk
1090}; 1095};
1091#endif 1096#endif
1092 1097
@@ -2051,7 +2056,7 @@ static void ext4_orphan_cleanup(struct super_block *sb,
2051 /* Turn quotas off */ 2056 /* Turn quotas off */
2052 for (i = 0; i < MAXQUOTAS; i++) { 2057 for (i = 0; i < MAXQUOTAS; i++) {
2053 if (sb_dqopt(sb)->files[i]) 2058 if (sb_dqopt(sb)->files[i])
2054 vfs_quota_off(sb, i, 0); 2059 dquot_quota_off(sb, i);
2055 } 2060 }
2056#endif 2061#endif
2057 sb->s_flags = s_flags; /* Restore MS_RDONLY status */ 2062 sb->s_flags = s_flags; /* Restore MS_RDONLY status */
@@ -2213,7 +2218,7 @@ static unsigned long ext4_get_stripe_size(struct ext4_sb_info *sbi)
2213struct ext4_attr { 2218struct ext4_attr {
2214 struct attribute attr; 2219 struct attribute attr;
2215 ssize_t (*show)(struct ext4_attr *, struct ext4_sb_info *, char *); 2220 ssize_t (*show)(struct ext4_attr *, struct ext4_sb_info *, char *);
2216 ssize_t (*store)(struct ext4_attr *, struct ext4_sb_info *, 2221 ssize_t (*store)(struct ext4_attr *, struct ext4_sb_info *,
2217 const char *, size_t); 2222 const char *, size_t);
2218 int offset; 2223 int offset;
2219}; 2224};
@@ -2430,6 +2435,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
2430 __releases(kernel_lock) 2435 __releases(kernel_lock)
2431 __acquires(kernel_lock) 2436 __acquires(kernel_lock)
2432{ 2437{
2438 char *orig_data = kstrdup(data, GFP_KERNEL);
2433 struct buffer_head *bh; 2439 struct buffer_head *bh;
2434 struct ext4_super_block *es = NULL; 2440 struct ext4_super_block *es = NULL;
2435 struct ext4_sb_info *sbi; 2441 struct ext4_sb_info *sbi;
@@ -2793,24 +2799,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
2793 get_random_bytes(&sbi->s_next_generation, sizeof(u32)); 2799 get_random_bytes(&sbi->s_next_generation, sizeof(u32));
2794 spin_lock_init(&sbi->s_next_gen_lock); 2800 spin_lock_init(&sbi->s_next_gen_lock);
2795 2801
2796 err = percpu_counter_init(&sbi->s_freeblocks_counter,
2797 ext4_count_free_blocks(sb));
2798 if (!err) {
2799 err = percpu_counter_init(&sbi->s_freeinodes_counter,
2800 ext4_count_free_inodes(sb));
2801 }
2802 if (!err) {
2803 err = percpu_counter_init(&sbi->s_dirs_counter,
2804 ext4_count_dirs(sb));
2805 }
2806 if (!err) {
2807 err = percpu_counter_init(&sbi->s_dirtyblocks_counter, 0);
2808 }
2809 if (err) {
2810 ext4_msg(sb, KERN_ERR, "insufficient memory");
2811 goto failed_mount3;
2812 }
2813
2814 sbi->s_stripe = ext4_get_stripe_size(sbi); 2802 sbi->s_stripe = ext4_get_stripe_size(sbi);
2815 sbi->s_max_writeback_mb_bump = 128; 2803 sbi->s_max_writeback_mb_bump = 128;
2816 2804
@@ -2910,6 +2898,20 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
2910 set_task_ioprio(sbi->s_journal->j_task, journal_ioprio); 2898 set_task_ioprio(sbi->s_journal->j_task, journal_ioprio);
2911 2899
2912no_journal: 2900no_journal:
2901 err = percpu_counter_init(&sbi->s_freeblocks_counter,
2902 ext4_count_free_blocks(sb));
2903 if (!err)
2904 err = percpu_counter_init(&sbi->s_freeinodes_counter,
2905 ext4_count_free_inodes(sb));
2906 if (!err)
2907 err = percpu_counter_init(&sbi->s_dirs_counter,
2908 ext4_count_dirs(sb));
2909 if (!err)
2910 err = percpu_counter_init(&sbi->s_dirtyblocks_counter, 0);
2911 if (err) {
2912 ext4_msg(sb, KERN_ERR, "insufficient memory");
2913 goto failed_mount_wq;
2914 }
2913 if (test_opt(sb, NOBH)) { 2915 if (test_opt(sb, NOBH)) {
2914 if (!(test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)) { 2916 if (!(test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)) {
2915 ext4_msg(sb, KERN_WARNING, "Ignoring nobh option - " 2917 ext4_msg(sb, KERN_WARNING, "Ignoring nobh option - "
@@ -3001,7 +3003,7 @@ no_journal:
3001 err = ext4_setup_system_zone(sb); 3003 err = ext4_setup_system_zone(sb);
3002 if (err) { 3004 if (err) {
3003 ext4_msg(sb, KERN_ERR, "failed to initialize system " 3005 ext4_msg(sb, KERN_ERR, "failed to initialize system "
3004 "zone (%d)\n", err); 3006 "zone (%d)", err);
3005 goto failed_mount4; 3007 goto failed_mount4;
3006 } 3008 }
3007 3009
@@ -3040,9 +3042,11 @@ no_journal:
3040 } else 3042 } else
3041 descr = "out journal"; 3043 descr = "out journal";
3042 3044
3043 ext4_msg(sb, KERN_INFO, "mounted filesystem with%s", descr); 3045 ext4_msg(sb, KERN_INFO, "mounted filesystem with%s. "
3046 "Opts: %s", descr, orig_data);
3044 3047
3045 lock_kernel(); 3048 lock_kernel();
3049 kfree(orig_data);
3046 return 0; 3050 return 0;
3047 3051
3048cantfind_ext4: 3052cantfind_ext4:
@@ -3059,6 +3063,10 @@ failed_mount_wq:
3059 jbd2_journal_destroy(sbi->s_journal); 3063 jbd2_journal_destroy(sbi->s_journal);
3060 sbi->s_journal = NULL; 3064 sbi->s_journal = NULL;
3061 } 3065 }
3066 percpu_counter_destroy(&sbi->s_freeblocks_counter);
3067 percpu_counter_destroy(&sbi->s_freeinodes_counter);
3068 percpu_counter_destroy(&sbi->s_dirs_counter);
3069 percpu_counter_destroy(&sbi->s_dirtyblocks_counter);
3062failed_mount3: 3070failed_mount3:
3063 if (sbi->s_flex_groups) { 3071 if (sbi->s_flex_groups) {
3064 if (is_vmalloc_addr(sbi->s_flex_groups)) 3072 if (is_vmalloc_addr(sbi->s_flex_groups))
@@ -3066,10 +3074,6 @@ failed_mount3:
3066 else 3074 else
3067 kfree(sbi->s_flex_groups); 3075 kfree(sbi->s_flex_groups);
3068 } 3076 }
3069 percpu_counter_destroy(&sbi->s_freeblocks_counter);
3070 percpu_counter_destroy(&sbi->s_freeinodes_counter);
3071 percpu_counter_destroy(&sbi->s_dirs_counter);
3072 percpu_counter_destroy(&sbi->s_dirtyblocks_counter);
3073failed_mount2: 3077failed_mount2:
3074 for (i = 0; i < db_count; i++) 3078 for (i = 0; i < db_count; i++)
3075 brelse(sbi->s_group_desc[i]); 3079 brelse(sbi->s_group_desc[i]);
@@ -3089,6 +3093,7 @@ out_fail:
3089 kfree(sbi->s_blockgroup_lock); 3093 kfree(sbi->s_blockgroup_lock);
3090 kfree(sbi); 3094 kfree(sbi);
3091 lock_kernel(); 3095 lock_kernel();
3096 kfree(orig_data);
3092 return ret; 3097 return ret;
3093} 3098}
3094 3099
@@ -3380,7 +3385,7 @@ static int ext4_commit_super(struct super_block *sb, int sync)
3380 if (!(sb->s_flags & MS_RDONLY)) 3385 if (!(sb->s_flags & MS_RDONLY))
3381 es->s_wtime = cpu_to_le32(get_seconds()); 3386 es->s_wtime = cpu_to_le32(get_seconds());
3382 es->s_kbytes_written = 3387 es->s_kbytes_written =
3383 cpu_to_le64(EXT4_SB(sb)->s_kbytes_written + 3388 cpu_to_le64(EXT4_SB(sb)->s_kbytes_written +
3384 ((part_stat_read(sb->s_bdev->bd_part, sectors[1]) - 3389 ((part_stat_read(sb->s_bdev->bd_part, sectors[1]) -
3385 EXT4_SB(sb)->s_sectors_written_start) >> 1)); 3390 EXT4_SB(sb)->s_sectors_written_start) >> 1));
3386 ext4_free_blocks_count_set(es, percpu_counter_sum_positive( 3391 ext4_free_blocks_count_set(es, percpu_counter_sum_positive(
@@ -3485,8 +3490,10 @@ int ext4_force_commit(struct super_block *sb)
3485 return 0; 3490 return 0;
3486 3491
3487 journal = EXT4_SB(sb)->s_journal; 3492 journal = EXT4_SB(sb)->s_journal;
3488 if (journal) 3493 if (journal) {
3494 vfs_check_frozen(sb, SB_FREEZE_WRITE);
3489 ret = ext4_journal_force_commit(journal); 3495 ret = ext4_journal_force_commit(journal);
3496 }
3490 3497
3491 return ret; 3498 return ret;
3492} 3499}
@@ -3535,18 +3542,16 @@ static int ext4_freeze(struct super_block *sb)
3535 * the journal. 3542 * the journal.
3536 */ 3543 */
3537 error = jbd2_journal_flush(journal); 3544 error = jbd2_journal_flush(journal);
3538 if (error < 0) { 3545 if (error < 0)
3539 out: 3546 goto out;
3540 jbd2_journal_unlock_updates(journal);
3541 return error;
3542 }
3543 3547
3544 /* Journal blocked and flushed, clear needs_recovery flag. */ 3548 /* Journal blocked and flushed, clear needs_recovery flag. */
3545 EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); 3549 EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
3546 error = ext4_commit_super(sb, 1); 3550 error = ext4_commit_super(sb, 1);
3547 if (error) 3551out:
3548 goto out; 3552 /* we rely on s_frozen to stop further updates */
3549 return 0; 3553 jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
3554 return error;
3550} 3555}
3551 3556
3552/* 3557/*
@@ -3563,7 +3568,6 @@ static int ext4_unfreeze(struct super_block *sb)
3563 EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); 3568 EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
3564 ext4_commit_super(sb, 1); 3569 ext4_commit_super(sb, 1);
3565 unlock_super(sb); 3570 unlock_super(sb);
3566 jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
3567 return 0; 3571 return 0;
3568} 3572}
3569 3573
@@ -3574,12 +3578,14 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
3574 ext4_fsblk_t n_blocks_count = 0; 3578 ext4_fsblk_t n_blocks_count = 0;
3575 unsigned long old_sb_flags; 3579 unsigned long old_sb_flags;
3576 struct ext4_mount_options old_opts; 3580 struct ext4_mount_options old_opts;
3581 int enable_quota = 0;
3577 ext4_group_t g; 3582 ext4_group_t g;
3578 unsigned int journal_ioprio = DEFAULT_JOURNAL_IOPRIO; 3583 unsigned int journal_ioprio = DEFAULT_JOURNAL_IOPRIO;
3579 int err; 3584 int err;
3580#ifdef CONFIG_QUOTA 3585#ifdef CONFIG_QUOTA
3581 int i; 3586 int i;
3582#endif 3587#endif
3588 char *orig_data = kstrdup(data, GFP_KERNEL);
3583 3589
3584 lock_kernel(); 3590 lock_kernel();
3585 3591
@@ -3630,6 +3636,10 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
3630 } 3636 }
3631 3637
3632 if (*flags & MS_RDONLY) { 3638 if (*flags & MS_RDONLY) {
3639 err = dquot_suspend(sb, -1);
3640 if (err < 0)
3641 goto restore_opts;
3642
3633 /* 3643 /*
3634 * First of all, the unconditional stuff we have to do 3644 * First of all, the unconditional stuff we have to do
3635 * to disable replay of the journal when we next remount 3645 * to disable replay of the journal when we next remount
@@ -3698,6 +3708,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
3698 goto restore_opts; 3708 goto restore_opts;
3699 if (!ext4_setup_super(sb, es, 0)) 3709 if (!ext4_setup_super(sb, es, 0))
3700 sb->s_flags &= ~MS_RDONLY; 3710 sb->s_flags &= ~MS_RDONLY;
3711 enable_quota = 1;
3701 } 3712 }
3702 } 3713 }
3703 ext4_setup_system_zone(sb); 3714 ext4_setup_system_zone(sb);
@@ -3713,6 +3724,11 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
3713#endif 3724#endif
3714 unlock_super(sb); 3725 unlock_super(sb);
3715 unlock_kernel(); 3726 unlock_kernel();
3727 if (enable_quota)
3728 dquot_resume(sb, -1);
3729
3730 ext4_msg(sb, KERN_INFO, "re-mounted. Opts: %s", orig_data);
3731 kfree(orig_data);
3716 return 0; 3732 return 0;
3717 3733
3718restore_opts: 3734restore_opts:
@@ -3734,6 +3750,7 @@ restore_opts:
3734#endif 3750#endif
3735 unlock_super(sb); 3751 unlock_super(sb);
3736 unlock_kernel(); 3752 unlock_kernel();
3753 kfree(orig_data);
3737 return err; 3754 return err;
3738} 3755}
3739 3756
@@ -3906,24 +3923,21 @@ static int ext4_write_info(struct super_block *sb, int type)
3906 */ 3923 */
3907static int ext4_quota_on_mount(struct super_block *sb, int type) 3924static int ext4_quota_on_mount(struct super_block *sb, int type)
3908{ 3925{
3909 return vfs_quota_on_mount(sb, EXT4_SB(sb)->s_qf_names[type], 3926 return dquot_quota_on_mount(sb, EXT4_SB(sb)->s_qf_names[type],
3910 EXT4_SB(sb)->s_jquota_fmt, type); 3927 EXT4_SB(sb)->s_jquota_fmt, type);
3911} 3928}
3912 3929
3913/* 3930/*
3914 * Standard function to be called on quota_on 3931 * Standard function to be called on quota_on
3915 */ 3932 */
3916static int ext4_quota_on(struct super_block *sb, int type, int format_id, 3933static int ext4_quota_on(struct super_block *sb, int type, int format_id,
3917 char *name, int remount) 3934 char *name)
3918{ 3935{
3919 int err; 3936 int err;
3920 struct path path; 3937 struct path path;
3921 3938
3922 if (!test_opt(sb, QUOTA)) 3939 if (!test_opt(sb, QUOTA))
3923 return -EINVAL; 3940 return -EINVAL;
3924 /* When remounting, no checks are needed and in fact, name is NULL */
3925 if (remount)
3926 return vfs_quota_on(sb, type, format_id, name, remount);
3927 3941
3928 err = kern_path(name, LOOKUP_FOLLOW, &path); 3942 err = kern_path(name, LOOKUP_FOLLOW, &path);
3929 if (err) 3943 if (err)
@@ -3962,7 +3976,7 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id,
3962 } 3976 }
3963 } 3977 }
3964 3978
3965 err = vfs_quota_on_path(sb, type, format_id, &path); 3979 err = dquot_quota_on_path(sb, type, format_id, &path);
3966 path_put(&path); 3980 path_put(&path);
3967 return err; 3981 return err;
3968} 3982}
@@ -4141,6 +4155,7 @@ static int __init init_ext4_fs(void)
4141{ 4155{
4142 int err; 4156 int err;
4143 4157
4158 ext4_check_flag_values();
4144 err = init_ext4_system_zone(); 4159 err = init_ext4_system_zone();
4145 if (err) 4160 if (err)
4146 return err; 4161 return err;