diff options
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r-- | fs/ext4/super.c | 120 |
1 files changed, 95 insertions, 25 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 52dd0679a4e2..02bf24343979 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -671,6 +671,7 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
671 | unsigned long def_mount_opts; | 671 | unsigned long def_mount_opts; |
672 | struct super_block *sb = vfs->mnt_sb; | 672 | struct super_block *sb = vfs->mnt_sb; |
673 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 673 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
674 | journal_t *journal = sbi->s_journal; | ||
674 | struct ext4_super_block *es = sbi->s_es; | 675 | struct ext4_super_block *es = sbi->s_es; |
675 | 676 | ||
676 | def_mount_opts = le32_to_cpu(es->s_default_mount_opts); | 677 | def_mount_opts = le32_to_cpu(es->s_default_mount_opts); |
@@ -729,8 +730,15 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
729 | seq_printf(seq, ",commit=%u", | 730 | seq_printf(seq, ",commit=%u", |
730 | (unsigned) (sbi->s_commit_interval / HZ)); | 731 | (unsigned) (sbi->s_commit_interval / HZ)); |
731 | } | 732 | } |
732 | if (test_opt(sb, BARRIER)) | 733 | /* |
733 | seq_puts(seq, ",barrier=1"); | 734 | * We're changing the default of barrier mount option, so |
735 | * let's always display its mount state so it's clear what its | ||
736 | * status is. | ||
737 | */ | ||
738 | seq_puts(seq, ",barrier="); | ||
739 | seq_puts(seq, test_opt(sb, BARRIER) ? "1" : "0"); | ||
740 | if (test_opt(sb, JOURNAL_ASYNC_COMMIT)) | ||
741 | seq_puts(seq, ",journal_async_commit"); | ||
734 | if (test_opt(sb, NOBH)) | 742 | if (test_opt(sb, NOBH)) |
735 | seq_puts(seq, ",nobh"); | 743 | seq_puts(seq, ",nobh"); |
736 | if (!test_opt(sb, EXTENTS)) | 744 | if (!test_opt(sb, EXTENTS)) |
@@ -979,7 +987,7 @@ static int parse_options (char *options, struct super_block *sb, | |||
979 | int data_opt = 0; | 987 | int data_opt = 0; |
980 | int option; | 988 | int option; |
981 | #ifdef CONFIG_QUOTA | 989 | #ifdef CONFIG_QUOTA |
982 | int qtype; | 990 | int qtype, qfmt; |
983 | char *qname; | 991 | char *qname; |
984 | #endif | 992 | #endif |
985 | 993 | ||
@@ -1162,9 +1170,11 @@ static int parse_options (char *options, struct super_block *sb, | |||
1162 | case Opt_grpjquota: | 1170 | case Opt_grpjquota: |
1163 | qtype = GRPQUOTA; | 1171 | qtype = GRPQUOTA; |
1164 | set_qf_name: | 1172 | set_qf_name: |
1165 | if (sb_any_quota_enabled(sb)) { | 1173 | if ((sb_any_quota_enabled(sb) || |
1174 | sb_any_quota_suspended(sb)) && | ||
1175 | !sbi->s_qf_names[qtype]) { | ||
1166 | printk(KERN_ERR | 1176 | printk(KERN_ERR |
1167 | "EXT4-fs: Cannot change journalled " | 1177 | "EXT4-fs: Cannot change journaled " |
1168 | "quota options when quota turned on.\n"); | 1178 | "quota options when quota turned on.\n"); |
1169 | return 0; | 1179 | return 0; |
1170 | } | 1180 | } |
@@ -1200,9 +1210,11 @@ set_qf_name: | |||
1200 | case Opt_offgrpjquota: | 1210 | case Opt_offgrpjquota: |
1201 | qtype = GRPQUOTA; | 1211 | qtype = GRPQUOTA; |
1202 | clear_qf_name: | 1212 | clear_qf_name: |
1203 | if (sb_any_quota_enabled(sb)) { | 1213 | if ((sb_any_quota_enabled(sb) || |
1214 | sb_any_quota_suspended(sb)) && | ||
1215 | sbi->s_qf_names[qtype]) { | ||
1204 | printk(KERN_ERR "EXT4-fs: Cannot change " | 1216 | printk(KERN_ERR "EXT4-fs: Cannot change " |
1205 | "journalled quota options when " | 1217 | "journaled quota options when " |
1206 | "quota turned on.\n"); | 1218 | "quota turned on.\n"); |
1207 | return 0; | 1219 | return 0; |
1208 | } | 1220 | } |
@@ -1213,10 +1225,20 @@ clear_qf_name: | |||
1213 | sbi->s_qf_names[qtype] = NULL; | 1225 | sbi->s_qf_names[qtype] = NULL; |
1214 | break; | 1226 | break; |
1215 | case Opt_jqfmt_vfsold: | 1227 | case Opt_jqfmt_vfsold: |
1216 | sbi->s_jquota_fmt = QFMT_VFS_OLD; | 1228 | qfmt = QFMT_VFS_OLD; |
1217 | break; | 1229 | goto set_qf_format; |
1218 | case Opt_jqfmt_vfsv0: | 1230 | case Opt_jqfmt_vfsv0: |
1219 | sbi->s_jquota_fmt = QFMT_VFS_V0; | 1231 | qfmt = QFMT_VFS_V0; |
1232 | set_qf_format: | ||
1233 | if ((sb_any_quota_enabled(sb) || | ||
1234 | sb_any_quota_suspended(sb)) && | ||
1235 | sbi->s_jquota_fmt != qfmt) { | ||
1236 | printk(KERN_ERR "EXT4-fs: Cannot change " | ||
1237 | "journaled quota options when " | ||
1238 | "quota turned on.\n"); | ||
1239 | return 0; | ||
1240 | } | ||
1241 | sbi->s_jquota_fmt = qfmt; | ||
1220 | break; | 1242 | break; |
1221 | case Opt_quota: | 1243 | case Opt_quota: |
1222 | case Opt_usrquota: | 1244 | case Opt_usrquota: |
@@ -1241,6 +1263,9 @@ clear_qf_name: | |||
1241 | case Opt_quota: | 1263 | case Opt_quota: |
1242 | case Opt_usrquota: | 1264 | case Opt_usrquota: |
1243 | case Opt_grpquota: | 1265 | case Opt_grpquota: |
1266 | printk(KERN_ERR | ||
1267 | "EXT4-fs: quota options not supported.\n"); | ||
1268 | break; | ||
1244 | case Opt_usrjquota: | 1269 | case Opt_usrjquota: |
1245 | case Opt_grpjquota: | 1270 | case Opt_grpjquota: |
1246 | case Opt_offusrjquota: | 1271 | case Opt_offusrjquota: |
@@ -1248,7 +1273,7 @@ clear_qf_name: | |||
1248 | case Opt_jqfmt_vfsold: | 1273 | case Opt_jqfmt_vfsold: |
1249 | case Opt_jqfmt_vfsv0: | 1274 | case Opt_jqfmt_vfsv0: |
1250 | printk(KERN_ERR | 1275 | printk(KERN_ERR |
1251 | "EXT4-fs: journalled quota options not " | 1276 | "EXT4-fs: journaled quota options not " |
1252 | "supported.\n"); | 1277 | "supported.\n"); |
1253 | break; | 1278 | break; |
1254 | case Opt_noquota: | 1279 | case Opt_noquota: |
@@ -1333,14 +1358,14 @@ clear_qf_name: | |||
1333 | } | 1358 | } |
1334 | 1359 | ||
1335 | if (!sbi->s_jquota_fmt) { | 1360 | if (!sbi->s_jquota_fmt) { |
1336 | printk(KERN_ERR "EXT4-fs: journalled quota format " | 1361 | printk(KERN_ERR "EXT4-fs: journaled quota format " |
1337 | "not specified.\n"); | 1362 | "not specified.\n"); |
1338 | return 0; | 1363 | return 0; |
1339 | } | 1364 | } |
1340 | } else { | 1365 | } else { |
1341 | if (sbi->s_jquota_fmt) { | 1366 | if (sbi->s_jquota_fmt) { |
1342 | printk(KERN_ERR "EXT4-fs: journalled quota format " | 1367 | printk(KERN_ERR "EXT4-fs: journaled quota format " |
1343 | "specified with no journalling " | 1368 | "specified with no journaling " |
1344 | "enabled.\n"); | 1369 | "enabled.\n"); |
1345 | return 0; | 1370 | return 0; |
1346 | } | 1371 | } |
@@ -1581,7 +1606,7 @@ static void ext4_orphan_cleanup (struct super_block * sb, | |||
1581 | int ret = ext4_quota_on_mount(sb, i); | 1606 | int ret = ext4_quota_on_mount(sb, i); |
1582 | if (ret < 0) | 1607 | if (ret < 0) |
1583 | printk(KERN_ERR | 1608 | printk(KERN_ERR |
1584 | "EXT4-fs: Cannot turn on journalled " | 1609 | "EXT4-fs: Cannot turn on journaled " |
1585 | "quota: error %d\n", ret); | 1610 | "quota: error %d\n", ret); |
1586 | } | 1611 | } |
1587 | } | 1612 | } |
@@ -1890,6 +1915,7 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) | |||
1890 | sbi->s_resgid = le16_to_cpu(es->s_def_resgid); | 1915 | sbi->s_resgid = le16_to_cpu(es->s_def_resgid); |
1891 | 1916 | ||
1892 | set_opt(sbi->s_mount_opt, RESERVATION); | 1917 | set_opt(sbi->s_mount_opt, RESERVATION); |
1918 | set_opt(sbi->s_mount_opt, BARRIER); | ||
1893 | 1919 | ||
1894 | /* | 1920 | /* |
1895 | * turn on extents feature by default in ext4 filesystem | 1921 | * turn on extents feature by default in ext4 filesystem |
@@ -2172,6 +2198,29 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) | |||
2172 | EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)) { | 2198 | EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)) { |
2173 | if (ext4_load_journal(sb, es, journal_devnum)) | 2199 | if (ext4_load_journal(sb, es, journal_devnum)) |
2174 | goto failed_mount3; | 2200 | goto failed_mount3; |
2201 | if (!(sb->s_flags & MS_RDONLY) && | ||
2202 | EXT4_SB(sb)->s_journal->j_failed_commit) { | ||
2203 | printk(KERN_CRIT "EXT4-fs error (device %s): " | ||
2204 | "ext4_fill_super: Journal transaction " | ||
2205 | "%u is corrupt\n", sb->s_id, | ||
2206 | EXT4_SB(sb)->s_journal->j_failed_commit); | ||
2207 | if (test_opt (sb, ERRORS_RO)) { | ||
2208 | printk (KERN_CRIT | ||
2209 | "Mounting filesystem read-only\n"); | ||
2210 | sb->s_flags |= MS_RDONLY; | ||
2211 | EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; | ||
2212 | es->s_state |= cpu_to_le16(EXT4_ERROR_FS); | ||
2213 | } | ||
2214 | if (test_opt(sb, ERRORS_PANIC)) { | ||
2215 | EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; | ||
2216 | es->s_state |= cpu_to_le16(EXT4_ERROR_FS); | ||
2217 | ext4_commit_super(sb, es, 1); | ||
2218 | printk(KERN_CRIT | ||
2219 | "EXT4-fs (device %s): mount failed\n", | ||
2220 | sb->s_id); | ||
2221 | goto failed_mount4; | ||
2222 | } | ||
2223 | } | ||
2175 | } else if (journal_inum) { | 2224 | } else if (journal_inum) { |
2176 | if (ext4_create_journal(sb, es, journal_inum)) | 2225 | if (ext4_create_journal(sb, es, journal_inum)) |
2177 | goto failed_mount3; | 2226 | goto failed_mount3; |
@@ -3106,7 +3155,7 @@ static int ext4_release_dquot(struct dquot *dquot) | |||
3106 | 3155 | ||
3107 | static int ext4_mark_dquot_dirty(struct dquot *dquot) | 3156 | static int ext4_mark_dquot_dirty(struct dquot *dquot) |
3108 | { | 3157 | { |
3109 | /* Are we journalling quotas? */ | 3158 | /* Are we journaling quotas? */ |
3110 | if (EXT4_SB(dquot->dq_sb)->s_qf_names[USRQUOTA] || | 3159 | if (EXT4_SB(dquot->dq_sb)->s_qf_names[USRQUOTA] || |
3111 | EXT4_SB(dquot->dq_sb)->s_qf_names[GRPQUOTA]) { | 3160 | EXT4_SB(dquot->dq_sb)->s_qf_names[GRPQUOTA]) { |
3112 | dquot_mark_dquot_dirty(dquot); | 3161 | dquot_mark_dquot_dirty(dquot); |
@@ -3153,23 +3202,42 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id, | |||
3153 | 3202 | ||
3154 | if (!test_opt(sb, QUOTA)) | 3203 | if (!test_opt(sb, QUOTA)) |
3155 | return -EINVAL; | 3204 | return -EINVAL; |
3156 | /* Not journalling quota? */ | 3205 | /* When remounting, no checks are needed and in fact, path is NULL */ |
3157 | if ((!EXT4_SB(sb)->s_qf_names[USRQUOTA] && | 3206 | if (remount) |
3158 | !EXT4_SB(sb)->s_qf_names[GRPQUOTA]) || remount) | ||
3159 | return vfs_quota_on(sb, type, format_id, path, remount); | 3207 | return vfs_quota_on(sb, type, format_id, path, remount); |
3208 | |||
3160 | err = path_lookup(path, LOOKUP_FOLLOW, &nd); | 3209 | err = path_lookup(path, LOOKUP_FOLLOW, &nd); |
3161 | if (err) | 3210 | if (err) |
3162 | return err; | 3211 | return err; |
3212 | |||
3163 | /* Quotafile not on the same filesystem? */ | 3213 | /* Quotafile not on the same filesystem? */ |
3164 | if (nd.path.mnt->mnt_sb != sb) { | 3214 | if (nd.path.mnt->mnt_sb != sb) { |
3165 | path_put(&nd.path); | 3215 | path_put(&nd.path); |
3166 | return -EXDEV; | 3216 | return -EXDEV; |
3167 | } | 3217 | } |
3168 | /* Quotafile not of fs root? */ | 3218 | /* Journaling quota? */ |
3169 | if (nd.path.dentry->d_parent->d_inode != sb->s_root->d_inode) | 3219 | if (EXT4_SB(sb)->s_qf_names[type]) { |
3170 | printk(KERN_WARNING | 3220 | /* Quotafile not of fs root? */ |
3171 | "EXT4-fs: Quota file not on filesystem root. " | 3221 | if (nd.path.dentry->d_parent->d_inode != sb->s_root->d_inode) |
3172 | "Journalled quota will not work.\n"); | 3222 | printk(KERN_WARNING |
3223 | "EXT4-fs: Quota file not on filesystem root. " | ||
3224 | "Journaled quota will not work.\n"); | ||
3225 | } | ||
3226 | |||
3227 | /* | ||
3228 | * When we journal data on quota file, we have to flush journal to see | ||
3229 | * all updates to the file when we bypass pagecache... | ||
3230 | */ | ||
3231 | if (ext4_should_journal_data(nd.path.dentry->d_inode)) { | ||
3232 | /* | ||
3233 | * We don't need to lock updates but journal_flush() could | ||
3234 | * otherwise be livelocked... | ||
3235 | */ | ||
3236 | jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); | ||
3237 | jbd2_journal_flush(EXT4_SB(sb)->s_journal); | ||
3238 | jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); | ||
3239 | } | ||
3240 | |||
3173 | path_put(&nd.path); | 3241 | path_put(&nd.path); |
3174 | return vfs_quota_on(sb, type, format_id, path, remount); | 3242 | return vfs_quota_on(sb, type, format_id, path, remount); |
3175 | } | 3243 | } |
@@ -3269,8 +3337,10 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type, | |||
3269 | blk++; | 3337 | blk++; |
3270 | } | 3338 | } |
3271 | out: | 3339 | out: |
3272 | if (len == towrite) | 3340 | if (len == towrite) { |
3341 | mutex_unlock(&inode->i_mutex); | ||
3273 | return err; | 3342 | return err; |
3343 | } | ||
3274 | if (inode->i_size < off+len-towrite) { | 3344 | if (inode->i_size < off+len-towrite) { |
3275 | i_size_write(inode, off+len-towrite); | 3345 | i_size_write(inode, off+len-towrite); |
3276 | EXT4_I(inode)->i_disksize = inode->i_size; | 3346 | EXT4_I(inode)->i_disksize = inode->i_size; |