diff options
Diffstat (limited to 'fs/ext3/super.c')
-rw-r--r-- | fs/ext3/super.c | 84 |
1 files changed, 60 insertions, 24 deletions
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index fe3119a71ada..8ddced384674 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,23 +2774,42 @@ 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 | |||
2779 | path_put(&nd.path); | 2813 | path_put(&nd.path); |
2780 | return vfs_quota_on(sb, type, format_id, path, remount); | 2814 | return vfs_quota_on(sb, type, format_id, path, remount); |
2781 | } | 2815 | } |
@@ -2875,8 +2909,10 @@ static ssize_t ext3_quota_write(struct super_block *sb, int type, | |||
2875 | blk++; | 2909 | blk++; |
2876 | } | 2910 | } |
2877 | out: | 2911 | out: |
2878 | if (len == towrite) | 2912 | if (len == towrite) { |
2913 | mutex_unlock(&inode->i_mutex); | ||
2879 | return err; | 2914 | return err; |
2915 | } | ||
2880 | if (inode->i_size < off+len-towrite) { | 2916 | if (inode->i_size < off+len-towrite) { |
2881 | i_size_write(inode, off+len-towrite); | 2917 | i_size_write(inode, off+len-towrite); |
2882 | EXT3_I(inode)->i_disksize = inode->i_size; | 2918 | EXT3_I(inode)->i_disksize = inode->i_size; |