diff options
Diffstat (limited to 'fs/ext3/super.c')
| -rw-r--r-- | fs/ext3/super.c | 83 |
1 files changed, 59 insertions, 24 deletions
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 2845425077e8..f38a5afc39a1 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
| @@ -472,7 +472,7 @@ static void ext3_destroy_inode(struct inode *inode) | |||
| 472 | kmem_cache_free(ext3_inode_cachep, EXT3_I(inode)); | 472 | kmem_cache_free(ext3_inode_cachep, EXT3_I(inode)); |
| 473 | } | 473 | } |
| 474 | 474 | ||
| 475 | static void init_once(struct kmem_cache * cachep, void *foo) | 475 | static void init_once(void *foo) |
| 476 | { | 476 | { |
| 477 | struct ext3_inode_info *ei = (struct ext3_inode_info *) foo; | 477 | struct ext3_inode_info *ei = (struct ext3_inode_info *) foo; |
| 478 | 478 | ||
| @@ -842,7 +842,7 @@ static int parse_options (char *options, struct super_block *sb, | |||
| 842 | int data_opt = 0; | 842 | int data_opt = 0; |
| 843 | int option; | 843 | int option; |
| 844 | #ifdef CONFIG_QUOTA | 844 | #ifdef CONFIG_QUOTA |
| 845 | int qtype; | 845 | int qtype, qfmt; |
| 846 | char *qname; | 846 | char *qname; |
| 847 | #endif | 847 | #endif |
| 848 | 848 | ||
| @@ -1018,9 +1018,11 @@ static int parse_options (char *options, struct super_block *sb, | |||
| 1018 | case Opt_grpjquota: | 1018 | case Opt_grpjquota: |
| 1019 | qtype = GRPQUOTA; | 1019 | qtype = GRPQUOTA; |
| 1020 | set_qf_name: | 1020 | set_qf_name: |
| 1021 | if (sb_any_quota_enabled(sb)) { | 1021 | if ((sb_any_quota_enabled(sb) || |
| 1022 | sb_any_quota_suspended(sb)) && | ||
| 1023 | !sbi->s_qf_names[qtype]) { | ||
| 1022 | printk(KERN_ERR | 1024 | printk(KERN_ERR |
| 1023 | "EXT3-fs: Cannot change journalled " | 1025 | "EXT3-fs: Cannot change journaled " |
| 1024 | "quota options when quota turned on.\n"); | 1026 | "quota options when quota turned on.\n"); |
| 1025 | return 0; | 1027 | return 0; |
| 1026 | } | 1028 | } |
| @@ -1056,9 +1058,11 @@ set_qf_name: | |||
| 1056 | case Opt_offgrpjquota: | 1058 | case Opt_offgrpjquota: |
| 1057 | qtype = GRPQUOTA; | 1059 | qtype = GRPQUOTA; |
| 1058 | clear_qf_name: | 1060 | clear_qf_name: |
| 1059 | if (sb_any_quota_enabled(sb)) { | 1061 | if ((sb_any_quota_enabled(sb) || |
| 1062 | sb_any_quota_suspended(sb)) && | ||
| 1063 | sbi->s_qf_names[qtype]) { | ||
| 1060 | printk(KERN_ERR "EXT3-fs: Cannot change " | 1064 | printk(KERN_ERR "EXT3-fs: Cannot change " |
| 1061 | "journalled quota options when " | 1065 | "journaled quota options when " |
| 1062 | "quota turned on.\n"); | 1066 | "quota turned on.\n"); |
| 1063 | return 0; | 1067 | return 0; |
| 1064 | } | 1068 | } |
| @@ -1069,10 +1073,20 @@ clear_qf_name: | |||
| 1069 | sbi->s_qf_names[qtype] = NULL; | 1073 | sbi->s_qf_names[qtype] = NULL; |
| 1070 | break; | 1074 | break; |
| 1071 | case Opt_jqfmt_vfsold: | 1075 | case Opt_jqfmt_vfsold: |
| 1072 | sbi->s_jquota_fmt = QFMT_VFS_OLD; | 1076 | qfmt = QFMT_VFS_OLD; |
| 1073 | break; | 1077 | goto set_qf_format; |
| 1074 | case Opt_jqfmt_vfsv0: | 1078 | case Opt_jqfmt_vfsv0: |
| 1075 | sbi->s_jquota_fmt = QFMT_VFS_V0; | 1079 | qfmt = QFMT_VFS_V0; |
| 1080 | set_qf_format: | ||
| 1081 | if ((sb_any_quota_enabled(sb) || | ||
| 1082 | sb_any_quota_suspended(sb)) && | ||
| 1083 | sbi->s_jquota_fmt != qfmt) { | ||
| 1084 | printk(KERN_ERR "EXT3-fs: Cannot change " | ||
| 1085 | "journaled quota options when " | ||
| 1086 | "quota turned on.\n"); | ||
| 1087 | return 0; | ||
| 1088 | } | ||
| 1089 | sbi->s_jquota_fmt = qfmt; | ||
| 1076 | break; | 1090 | break; |
| 1077 | case Opt_quota: | 1091 | case Opt_quota: |
| 1078 | case Opt_usrquota: | 1092 | case Opt_usrquota: |
| @@ -1084,7 +1098,8 @@ clear_qf_name: | |||
| 1084 | set_opt(sbi->s_mount_opt, GRPQUOTA); | 1098 | set_opt(sbi->s_mount_opt, GRPQUOTA); |
| 1085 | break; | 1099 | break; |
| 1086 | case Opt_noquota: | 1100 | case Opt_noquota: |
| 1087 | if (sb_any_quota_enabled(sb)) { | 1101 | if (sb_any_quota_enabled(sb) || |
| 1102 | sb_any_quota_suspended(sb)) { | ||
| 1088 | printk(KERN_ERR "EXT3-fs: Cannot change quota " | 1103 | printk(KERN_ERR "EXT3-fs: Cannot change quota " |
| 1089 | "options when quota turned on.\n"); | 1104 | "options when quota turned on.\n"); |
| 1090 | return 0; | 1105 | return 0; |
| @@ -1169,14 +1184,14 @@ clear_qf_name: | |||
| 1169 | } | 1184 | } |
| 1170 | 1185 | ||
| 1171 | if (!sbi->s_jquota_fmt) { | 1186 | if (!sbi->s_jquota_fmt) { |
| 1172 | printk(KERN_ERR "EXT3-fs: journalled quota format " | 1187 | printk(KERN_ERR "EXT3-fs: journaled quota format " |
| 1173 | "not specified.\n"); | 1188 | "not specified.\n"); |
| 1174 | return 0; | 1189 | return 0; |
| 1175 | } | 1190 | } |
| 1176 | } else { | 1191 | } else { |
| 1177 | if (sbi->s_jquota_fmt) { | 1192 | if (sbi->s_jquota_fmt) { |
| 1178 | printk(KERN_ERR "EXT3-fs: journalled quota format " | 1193 | printk(KERN_ERR "EXT3-fs: journaled quota format " |
| 1179 | "specified with no journalling " | 1194 | "specified with no journaling " |
| 1180 | "enabled.\n"); | 1195 | "enabled.\n"); |
| 1181 | return 0; | 1196 | return 0; |
| 1182 | } | 1197 | } |
| @@ -1370,7 +1385,7 @@ static void ext3_orphan_cleanup (struct super_block * sb, | |||
| 1370 | int ret = ext3_quota_on_mount(sb, i); | 1385 | int ret = ext3_quota_on_mount(sb, i); |
| 1371 | if (ret < 0) | 1386 | if (ret < 0) |
| 1372 | printk(KERN_ERR | 1387 | printk(KERN_ERR |
| 1373 | "EXT3-fs: Cannot turn on journalled " | 1388 | "EXT3-fs: Cannot turn on journaled " |
| 1374 | "quota: error %d\n", ret); | 1389 | "quota: error %d\n", ret); |
| 1375 | } | 1390 | } |
| 1376 | } | 1391 | } |
| @@ -2712,7 +2727,7 @@ static int ext3_release_dquot(struct dquot *dquot) | |||
| 2712 | 2727 | ||
| 2713 | static int ext3_mark_dquot_dirty(struct dquot *dquot) | 2728 | static int ext3_mark_dquot_dirty(struct dquot *dquot) |
| 2714 | { | 2729 | { |
| 2715 | /* Are we journalling quotas? */ | 2730 | /* Are we journaling quotas? */ |
| 2716 | if (EXT3_SB(dquot->dq_sb)->s_qf_names[USRQUOTA] || | 2731 | if (EXT3_SB(dquot->dq_sb)->s_qf_names[USRQUOTA] || |
| 2717 | EXT3_SB(dquot->dq_sb)->s_qf_names[GRPQUOTA]) { | 2732 | EXT3_SB(dquot->dq_sb)->s_qf_names[GRPQUOTA]) { |
| 2718 | dquot_mark_dquot_dirty(dquot); | 2733 | dquot_mark_dquot_dirty(dquot); |
| @@ -2759,25 +2774,45 @@ static int ext3_quota_on(struct super_block *sb, int type, int format_id, | |||
| 2759 | 2774 | ||
| 2760 | if (!test_opt(sb, QUOTA)) | 2775 | if (!test_opt(sb, QUOTA)) |
| 2761 | return -EINVAL; | 2776 | return -EINVAL; |
| 2762 | /* Not journalling quota or remount? */ | 2777 | /* When remounting, no checks are needed and in fact, path is NULL */ |
| 2763 | if ((!EXT3_SB(sb)->s_qf_names[USRQUOTA] && | 2778 | if (remount) |
| 2764 | !EXT3_SB(sb)->s_qf_names[GRPQUOTA]) || remount) | ||
| 2765 | return vfs_quota_on(sb, type, format_id, path, remount); | 2779 | return vfs_quota_on(sb, type, format_id, path, remount); |
| 2780 | |||
| 2766 | err = path_lookup(path, LOOKUP_FOLLOW, &nd); | 2781 | err = path_lookup(path, LOOKUP_FOLLOW, &nd); |
| 2767 | if (err) | 2782 | if (err) |
| 2768 | return err; | 2783 | return err; |
| 2784 | |||
| 2769 | /* Quotafile not on the same filesystem? */ | 2785 | /* Quotafile not on the same filesystem? */ |
| 2770 | if (nd.path.mnt->mnt_sb != sb) { | 2786 | if (nd.path.mnt->mnt_sb != sb) { |
| 2771 | path_put(&nd.path); | 2787 | path_put(&nd.path); |
| 2772 | return -EXDEV; | 2788 | return -EXDEV; |
| 2773 | } | 2789 | } |
| 2774 | /* Quotafile not in fs root? */ | 2790 | /* Journaling quota? */ |
| 2775 | if (nd.path.dentry->d_parent->d_inode != sb->s_root->d_inode) | 2791 | if (EXT3_SB(sb)->s_qf_names[type]) { |
| 2776 | printk(KERN_WARNING | 2792 | /* Quotafile not of fs root? */ |
| 2777 | "EXT3-fs: Quota file not on filesystem root. " | 2793 | if (nd.path.dentry->d_parent->d_inode != sb->s_root->d_inode) |
| 2778 | "Journalled quota will not work.\n"); | 2794 | printk(KERN_WARNING |
| 2795 | "EXT3-fs: Quota file not on filesystem root. " | ||
| 2796 | "Journaled quota will not work.\n"); | ||
| 2797 | } | ||
| 2798 | |||
| 2799 | /* | ||
| 2800 | * When we journal data on quota file, we have to flush journal to see | ||
| 2801 | * all updates to the file when we bypass pagecache... | ||
| 2802 | */ | ||
| 2803 | if (ext3_should_journal_data(nd.path.dentry->d_inode)) { | ||
| 2804 | /* | ||
| 2805 | * We don't need to lock updates but journal_flush() could | ||
| 2806 | * otherwise be livelocked... | ||
| 2807 | */ | ||
| 2808 | journal_lock_updates(EXT3_SB(sb)->s_journal); | ||
| 2809 | journal_flush(EXT3_SB(sb)->s_journal); | ||
| 2810 | journal_unlock_updates(EXT3_SB(sb)->s_journal); | ||
| 2811 | } | ||
| 2812 | |||
| 2813 | err = vfs_quota_on_path(sb, type, format_id, &nd.path); | ||
| 2779 | path_put(&nd.path); | 2814 | path_put(&nd.path); |
| 2780 | return vfs_quota_on(sb, type, format_id, path, remount); | 2815 | return err; |
| 2781 | } | 2816 | } |
| 2782 | 2817 | ||
| 2783 | /* Read data from quotafile - avoid pagecache and such because we cannot afford | 2818 | /* Read data from quotafile - avoid pagecache and such because we cannot afford |
