diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-05-15 21:28:28 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-05-15 21:28:28 -0400 |
| commit | ac0e9c30b1cb22c01f3edbb94857de2bae7611ca (patch) | |
| tree | 9d9c8f381b86f473ac36db3602faea64d05dbaba | |
| parent | a76bfd0da2321ed0a978ccbef192856ce7ed687a (diff) | |
| parent | 02c471cb17203c748e9bc87003052c1f46e5df69 (diff) | |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4:
jbd2: update transaction t_state to T_COMMIT fix
ext4: Retry block allocation if new blocks are allocated from system zone.
ext4: mballoc fix mb_normalize_request algorithm for 1KB block size filesystems
ext4: fix typos in messages and comments (journalled -> journaled)
ext4: fix synchronization of quota files in journal=data mode
ext4: Fix mount messages when quota disabled
ext4: correct mount option parsing to detect when quota options can be changed
| -rw-r--r-- | fs/ext4/balloc.c | 17 | ||||
| -rw-r--r-- | fs/ext4/mballoc.c | 66 | ||||
| -rw-r--r-- | fs/ext4/super.c | 80 | ||||
| -rw-r--r-- | fs/jbd2/commit.c | 2 |
4 files changed, 116 insertions, 49 deletions
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index da994374ec3b..30494c5da843 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c | |||
| @@ -287,11 +287,11 @@ read_block_bitmap(struct super_block *sb, ext4_group_t block_group) | |||
| 287 | (int)block_group, (unsigned long long)bitmap_blk); | 287 | (int)block_group, (unsigned long long)bitmap_blk); |
| 288 | return NULL; | 288 | return NULL; |
| 289 | } | 289 | } |
| 290 | if (!ext4_valid_block_bitmap(sb, desc, block_group, bh)) { | 290 | ext4_valid_block_bitmap(sb, desc, block_group, bh); |
| 291 | put_bh(bh); | 291 | /* |
| 292 | return NULL; | 292 | * file system mounted not to panic on error, |
| 293 | } | 293 | * continue with corrupt bitmap |
| 294 | 294 | */ | |
| 295 | return bh; | 295 | return bh; |
| 296 | } | 296 | } |
| 297 | /* | 297 | /* |
| @@ -1770,7 +1770,12 @@ allocated: | |||
| 1770 | "Allocating block in system zone - " | 1770 | "Allocating block in system zone - " |
| 1771 | "blocks from %llu, length %lu", | 1771 | "blocks from %llu, length %lu", |
| 1772 | ret_block, num); | 1772 | ret_block, num); |
| 1773 | goto out; | 1773 | /* |
| 1774 | * claim_block marked the blocks we allocated | ||
| 1775 | * as in use. So we may want to selectively | ||
| 1776 | * mark some of the blocks as free | ||
| 1777 | */ | ||
| 1778 | goto retry_alloc; | ||
| 1774 | } | 1779 | } |
| 1775 | 1780 | ||
| 1776 | performed_allocation = 1; | 1781 | performed_allocation = 1; |
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index b128bdc0f55c..873ad9b3418c 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
| @@ -2736,7 +2736,7 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac, | |||
| 2736 | struct ext4_sb_info *sbi; | 2736 | struct ext4_sb_info *sbi; |
| 2737 | struct super_block *sb; | 2737 | struct super_block *sb; |
| 2738 | ext4_fsblk_t block; | 2738 | ext4_fsblk_t block; |
| 2739 | int err; | 2739 | int err, len; |
| 2740 | 2740 | ||
| 2741 | BUG_ON(ac->ac_status != AC_STATUS_FOUND); | 2741 | BUG_ON(ac->ac_status != AC_STATUS_FOUND); |
| 2742 | BUG_ON(ac->ac_b_ex.fe_len <= 0); | 2742 | BUG_ON(ac->ac_b_ex.fe_len <= 0); |
| @@ -2770,14 +2770,27 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac, | |||
| 2770 | + ac->ac_b_ex.fe_start | 2770 | + ac->ac_b_ex.fe_start |
| 2771 | + le32_to_cpu(es->s_first_data_block); | 2771 | + le32_to_cpu(es->s_first_data_block); |
| 2772 | 2772 | ||
| 2773 | if (block == ext4_block_bitmap(sb, gdp) || | 2773 | len = ac->ac_b_ex.fe_len; |
| 2774 | block == ext4_inode_bitmap(sb, gdp) || | 2774 | if (in_range(ext4_block_bitmap(sb, gdp), block, len) || |
| 2775 | in_range(block, ext4_inode_table(sb, gdp), | 2775 | in_range(ext4_inode_bitmap(sb, gdp), block, len) || |
| 2776 | EXT4_SB(sb)->s_itb_per_group)) { | 2776 | in_range(block, ext4_inode_table(sb, gdp), |
| 2777 | 2777 | EXT4_SB(sb)->s_itb_per_group) || | |
| 2778 | in_range(block + len - 1, ext4_inode_table(sb, gdp), | ||
| 2779 | EXT4_SB(sb)->s_itb_per_group)) { | ||
| 2778 | ext4_error(sb, __func__, | 2780 | ext4_error(sb, __func__, |
| 2779 | "Allocating block in system zone - block = %llu", | 2781 | "Allocating block in system zone - block = %llu", |
| 2780 | block); | 2782 | block); |
| 2783 | /* File system mounted not to panic on error | ||
| 2784 | * Fix the bitmap and repeat the block allocation | ||
| 2785 | * We leak some of the blocks here. | ||
| 2786 | */ | ||
| 2787 | mb_set_bits(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group), | ||
| 2788 | bitmap_bh->b_data, ac->ac_b_ex.fe_start, | ||
| 2789 | ac->ac_b_ex.fe_len); | ||
| 2790 | err = ext4_journal_dirty_metadata(handle, bitmap_bh); | ||
| 2791 | if (!err) | ||
| 2792 | err = -EAGAIN; | ||
| 2793 | goto out_err; | ||
| 2781 | } | 2794 | } |
| 2782 | #ifdef AGGRESSIVE_CHECK | 2795 | #ifdef AGGRESSIVE_CHECK |
| 2783 | { | 2796 | { |
| @@ -2880,12 +2893,11 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac, | |||
| 2880 | if (size < i_size_read(ac->ac_inode)) | 2893 | if (size < i_size_read(ac->ac_inode)) |
| 2881 | size = i_size_read(ac->ac_inode); | 2894 | size = i_size_read(ac->ac_inode); |
| 2882 | 2895 | ||
| 2883 | /* max available blocks in a free group */ | 2896 | /* max size of free chunks */ |
| 2884 | max = EXT4_BLOCKS_PER_GROUP(ac->ac_sb) - 1 - 1 - | 2897 | max = 2 << bsbits; |
| 2885 | EXT4_SB(ac->ac_sb)->s_itb_per_group; | ||
| 2886 | 2898 | ||
| 2887 | #define NRL_CHECK_SIZE(req, size, max,bits) \ | 2899 | #define NRL_CHECK_SIZE(req, size, max, chunk_size) \ |
| 2888 | (req <= (size) || max <= ((size) >> bits)) | 2900 | (req <= (size) || max <= (chunk_size)) |
| 2889 | 2901 | ||
| 2890 | /* first, try to predict filesize */ | 2902 | /* first, try to predict filesize */ |
| 2891 | /* XXX: should this table be tunable? */ | 2903 | /* XXX: should this table be tunable? */ |
| @@ -2904,16 +2916,16 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac, | |||
| 2904 | size = 512 * 1024; | 2916 | size = 512 * 1024; |
| 2905 | } else if (size <= 1024 * 1024) { | 2917 | } else if (size <= 1024 * 1024) { |
| 2906 | size = 1024 * 1024; | 2918 | size = 1024 * 1024; |
| 2907 | } else if (NRL_CHECK_SIZE(size, 4 * 1024 * 1024, max, bsbits)) { | 2919 | } else if (NRL_CHECK_SIZE(size, 4 * 1024 * 1024, max, 2 * 1024)) { |
| 2908 | start_off = ((loff_t)ac->ac_o_ex.fe_logical >> | 2920 | start_off = ((loff_t)ac->ac_o_ex.fe_logical >> |
| 2909 | (20 - bsbits)) << 20; | 2921 | (21 - bsbits)) << 21; |
| 2910 | size = 1024 * 1024; | 2922 | size = 2 * 1024 * 1024; |
| 2911 | } else if (NRL_CHECK_SIZE(size, 8 * 1024 * 1024, max, bsbits)) { | 2923 | } else if (NRL_CHECK_SIZE(size, 8 * 1024 * 1024, max, 4 * 1024)) { |
| 2912 | start_off = ((loff_t)ac->ac_o_ex.fe_logical >> | 2924 | start_off = ((loff_t)ac->ac_o_ex.fe_logical >> |
| 2913 | (22 - bsbits)) << 22; | 2925 | (22 - bsbits)) << 22; |
| 2914 | size = 4 * 1024 * 1024; | 2926 | size = 4 * 1024 * 1024; |
| 2915 | } else if (NRL_CHECK_SIZE(ac->ac_o_ex.fe_len, | 2927 | } else if (NRL_CHECK_SIZE(ac->ac_o_ex.fe_len, |
| 2916 | (8<<20)>>bsbits, max, bsbits)) { | 2928 | (8<<20)>>bsbits, max, 8 * 1024)) { |
| 2917 | start_off = ((loff_t)ac->ac_o_ex.fe_logical >> | 2929 | start_off = ((loff_t)ac->ac_o_ex.fe_logical >> |
| 2918 | (23 - bsbits)) << 23; | 2930 | (23 - bsbits)) << 23; |
| 2919 | size = 8 * 1024 * 1024; | 2931 | size = 8 * 1024 * 1024; |
| @@ -4033,7 +4045,6 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, | |||
| 4033 | 4045 | ||
| 4034 | ac->ac_op = EXT4_MB_HISTORY_ALLOC; | 4046 | ac->ac_op = EXT4_MB_HISTORY_ALLOC; |
| 4035 | ext4_mb_normalize_request(ac, ar); | 4047 | ext4_mb_normalize_request(ac, ar); |
| 4036 | |||
| 4037 | repeat: | 4048 | repeat: |
| 4038 | /* allocate space in core */ | 4049 | /* allocate space in core */ |
| 4039 | ext4_mb_regular_allocator(ac); | 4050 | ext4_mb_regular_allocator(ac); |
| @@ -4047,10 +4058,21 @@ repeat: | |||
| 4047 | } | 4058 | } |
| 4048 | 4059 | ||
| 4049 | if (likely(ac->ac_status == AC_STATUS_FOUND)) { | 4060 | if (likely(ac->ac_status == AC_STATUS_FOUND)) { |
| 4050 | ext4_mb_mark_diskspace_used(ac, handle); | 4061 | *errp = ext4_mb_mark_diskspace_used(ac, handle); |
| 4051 | *errp = 0; | 4062 | if (*errp == -EAGAIN) { |
| 4052 | block = ext4_grp_offs_to_block(sb, &ac->ac_b_ex); | 4063 | ac->ac_b_ex.fe_group = 0; |
| 4053 | ar->len = ac->ac_b_ex.fe_len; | 4064 | ac->ac_b_ex.fe_start = 0; |
| 4065 | ac->ac_b_ex.fe_len = 0; | ||
| 4066 | ac->ac_status = AC_STATUS_CONTINUE; | ||
| 4067 | goto repeat; | ||
| 4068 | } else if (*errp) { | ||
| 4069 | ac->ac_b_ex.fe_len = 0; | ||
| 4070 | ar->len = 0; | ||
| 4071 | ext4_mb_show_ac(ac); | ||
| 4072 | } else { | ||
| 4073 | block = ext4_grp_offs_to_block(sb, &ac->ac_b_ex); | ||
| 4074 | ar->len = ac->ac_b_ex.fe_len; | ||
| 4075 | } | ||
| 4054 | } else { | 4076 | } else { |
| 4055 | freed = ext4_mb_discard_preallocations(sb, ac->ac_o_ex.fe_len); | 4077 | freed = ext4_mb_discard_preallocations(sb, ac->ac_o_ex.fe_len); |
| 4056 | if (freed) | 4078 | if (freed) |
| @@ -4237,6 +4259,8 @@ do_more: | |||
| 4237 | ext4_error(sb, __func__, | 4259 | ext4_error(sb, __func__, |
| 4238 | "Freeing blocks in system zone - " | 4260 | "Freeing blocks in system zone - " |
| 4239 | "Block = %lu, count = %lu", block, count); | 4261 | "Block = %lu, count = %lu", block, count); |
| 4262 | /* err = 0. ext4_std_error should be a no op */ | ||
| 4263 | goto error_return; | ||
| 4240 | } | 4264 | } |
| 4241 | 4265 | ||
| 4242 | BUFFER_TRACE(bitmap_bh, "getting write access"); | 4266 | BUFFER_TRACE(bitmap_bh, "getting write access"); |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 52dd0679a4e2..09d9359c8055 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
| @@ -979,7 +979,7 @@ static int parse_options (char *options, struct super_block *sb, | |||
| 979 | int data_opt = 0; | 979 | int data_opt = 0; |
| 980 | int option; | 980 | int option; |
| 981 | #ifdef CONFIG_QUOTA | 981 | #ifdef CONFIG_QUOTA |
| 982 | int qtype; | 982 | int qtype, qfmt; |
| 983 | char *qname; | 983 | char *qname; |
| 984 | #endif | 984 | #endif |
| 985 | 985 | ||
| @@ -1162,9 +1162,11 @@ static int parse_options (char *options, struct super_block *sb, | |||
| 1162 | case Opt_grpjquota: | 1162 | case Opt_grpjquota: |
| 1163 | qtype = GRPQUOTA; | 1163 | qtype = GRPQUOTA; |
| 1164 | set_qf_name: | 1164 | set_qf_name: |
| 1165 | if (sb_any_quota_enabled(sb)) { | 1165 | if ((sb_any_quota_enabled(sb) || |
| 1166 | sb_any_quota_suspended(sb)) && | ||
| 1167 | !sbi->s_qf_names[qtype]) { | ||
| 1166 | printk(KERN_ERR | 1168 | printk(KERN_ERR |
| 1167 | "EXT4-fs: Cannot change journalled " | 1169 | "EXT4-fs: Cannot change journaled " |
| 1168 | "quota options when quota turned on.\n"); | 1170 | "quota options when quota turned on.\n"); |
| 1169 | return 0; | 1171 | return 0; |
| 1170 | } | 1172 | } |
| @@ -1200,9 +1202,11 @@ set_qf_name: | |||
| 1200 | case Opt_offgrpjquota: | 1202 | case Opt_offgrpjquota: |
| 1201 | qtype = GRPQUOTA; | 1203 | qtype = GRPQUOTA; |
| 1202 | clear_qf_name: | 1204 | clear_qf_name: |
| 1203 | if (sb_any_quota_enabled(sb)) { | 1205 | if ((sb_any_quota_enabled(sb) || |
| 1206 | sb_any_quota_suspended(sb)) && | ||
| 1207 | sbi->s_qf_names[qtype]) { | ||
| 1204 | printk(KERN_ERR "EXT4-fs: Cannot change " | 1208 | printk(KERN_ERR "EXT4-fs: Cannot change " |
| 1205 | "journalled quota options when " | 1209 | "journaled quota options when " |
| 1206 | "quota turned on.\n"); | 1210 | "quota turned on.\n"); |
| 1207 | return 0; | 1211 | return 0; |
| 1208 | } | 1212 | } |
| @@ -1213,10 +1217,20 @@ clear_qf_name: | |||
| 1213 | sbi->s_qf_names[qtype] = NULL; | 1217 | sbi->s_qf_names[qtype] = NULL; |
| 1214 | break; | 1218 | break; |
| 1215 | case Opt_jqfmt_vfsold: | 1219 | case Opt_jqfmt_vfsold: |
| 1216 | sbi->s_jquota_fmt = QFMT_VFS_OLD; | 1220 | qfmt = QFMT_VFS_OLD; |
| 1217 | break; | 1221 | goto set_qf_format; |
| 1218 | case Opt_jqfmt_vfsv0: | 1222 | case Opt_jqfmt_vfsv0: |
| 1219 | sbi->s_jquota_fmt = QFMT_VFS_V0; | 1223 | qfmt = QFMT_VFS_V0; |
| 1224 | set_qf_format: | ||
| 1225 | if ((sb_any_quota_enabled(sb) || | ||
| 1226 | sb_any_quota_suspended(sb)) && | ||
| 1227 | sbi->s_jquota_fmt != qfmt) { | ||
| 1228 | printk(KERN_ERR "EXT4-fs: Cannot change " | ||
| 1229 | "journaled quota options when " | ||
| 1230 | "quota turned on.\n"); | ||
| 1231 | return 0; | ||
| 1232 | } | ||
| 1233 | sbi->s_jquota_fmt = qfmt; | ||
| 1220 | break; | 1234 | break; |
| 1221 | case Opt_quota: | 1235 | case Opt_quota: |
| 1222 | case Opt_usrquota: | 1236 | case Opt_usrquota: |
| @@ -1241,6 +1255,9 @@ clear_qf_name: | |||
| 1241 | case Opt_quota: | 1255 | case Opt_quota: |
| 1242 | case Opt_usrquota: | 1256 | case Opt_usrquota: |
| 1243 | case Opt_grpquota: | 1257 | case Opt_grpquota: |
| 1258 | printk(KERN_ERR | ||
| 1259 | "EXT4-fs: quota options not supported.\n"); | ||
| 1260 | break; | ||
| 1244 | case Opt_usrjquota: | 1261 | case Opt_usrjquota: |
| 1245 | case Opt_grpjquota: | 1262 | case Opt_grpjquota: |
| 1246 | case Opt_offusrjquota: | 1263 | case Opt_offusrjquota: |
| @@ -1248,7 +1265,7 @@ clear_qf_name: | |||
| 1248 | case Opt_jqfmt_vfsold: | 1265 | case Opt_jqfmt_vfsold: |
| 1249 | case Opt_jqfmt_vfsv0: | 1266 | case Opt_jqfmt_vfsv0: |
| 1250 | printk(KERN_ERR | 1267 | printk(KERN_ERR |
| 1251 | "EXT4-fs: journalled quota options not " | 1268 | "EXT4-fs: journaled quota options not " |
| 1252 | "supported.\n"); | 1269 | "supported.\n"); |
| 1253 | break; | 1270 | break; |
| 1254 | case Opt_noquota: | 1271 | case Opt_noquota: |
| @@ -1333,14 +1350,14 @@ clear_qf_name: | |||
| 1333 | } | 1350 | } |
| 1334 | 1351 | ||
| 1335 | if (!sbi->s_jquota_fmt) { | 1352 | if (!sbi->s_jquota_fmt) { |
| 1336 | printk(KERN_ERR "EXT4-fs: journalled quota format " | 1353 | printk(KERN_ERR "EXT4-fs: journaled quota format " |
| 1337 | "not specified.\n"); | 1354 | "not specified.\n"); |
| 1338 | return 0; | 1355 | return 0; |
| 1339 | } | 1356 | } |
| 1340 | } else { | 1357 | } else { |
| 1341 | if (sbi->s_jquota_fmt) { | 1358 | if (sbi->s_jquota_fmt) { |
| 1342 | printk(KERN_ERR "EXT4-fs: journalled quota format " | 1359 | printk(KERN_ERR "EXT4-fs: journaled quota format " |
| 1343 | "specified with no journalling " | 1360 | "specified with no journaling " |
| 1344 | "enabled.\n"); | 1361 | "enabled.\n"); |
| 1345 | return 0; | 1362 | return 0; |
| 1346 | } | 1363 | } |
| @@ -1581,7 +1598,7 @@ static void ext4_orphan_cleanup (struct super_block * sb, | |||
| 1581 | int ret = ext4_quota_on_mount(sb, i); | 1598 | int ret = ext4_quota_on_mount(sb, i); |
| 1582 | if (ret < 0) | 1599 | if (ret < 0) |
| 1583 | printk(KERN_ERR | 1600 | printk(KERN_ERR |
| 1584 | "EXT4-fs: Cannot turn on journalled " | 1601 | "EXT4-fs: Cannot turn on journaled " |
| 1585 | "quota: error %d\n", ret); | 1602 | "quota: error %d\n", ret); |
| 1586 | } | 1603 | } |
| 1587 | } | 1604 | } |
| @@ -3106,7 +3123,7 @@ static int ext4_release_dquot(struct dquot *dquot) | |||
| 3106 | 3123 | ||
| 3107 | static int ext4_mark_dquot_dirty(struct dquot *dquot) | 3124 | static int ext4_mark_dquot_dirty(struct dquot *dquot) |
| 3108 | { | 3125 | { |
| 3109 | /* Are we journalling quotas? */ | 3126 | /* Are we journaling quotas? */ |
| 3110 | if (EXT4_SB(dquot->dq_sb)->s_qf_names[USRQUOTA] || | 3127 | if (EXT4_SB(dquot->dq_sb)->s_qf_names[USRQUOTA] || |
| 3111 | EXT4_SB(dquot->dq_sb)->s_qf_names[GRPQUOTA]) { | 3128 | EXT4_SB(dquot->dq_sb)->s_qf_names[GRPQUOTA]) { |
| 3112 | dquot_mark_dquot_dirty(dquot); | 3129 | dquot_mark_dquot_dirty(dquot); |
| @@ -3153,23 +3170,42 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id, | |||
| 3153 | 3170 | ||
| 3154 | if (!test_opt(sb, QUOTA)) | 3171 | if (!test_opt(sb, QUOTA)) |
| 3155 | return -EINVAL; | 3172 | return -EINVAL; |
| 3156 | /* Not journalling quota? */ | 3173 | /* When remounting, no checks are needed and in fact, path is NULL */ |
| 3157 | if ((!EXT4_SB(sb)->s_qf_names[USRQUOTA] && | 3174 | if (remount) |
| 3158 | !EXT4_SB(sb)->s_qf_names[GRPQUOTA]) || remount) | ||
| 3159 | return vfs_quota_on(sb, type, format_id, path, remount); | 3175 | return vfs_quota_on(sb, type, format_id, path, remount); |
| 3176 | |||
| 3160 | err = path_lookup(path, LOOKUP_FOLLOW, &nd); | 3177 | err = path_lookup(path, LOOKUP_FOLLOW, &nd); |
| 3161 | if (err) | 3178 | if (err) |
| 3162 | return err; | 3179 | return err; |
| 3180 | |||
| 3163 | /* Quotafile not on the same filesystem? */ | 3181 | /* Quotafile not on the same filesystem? */ |
| 3164 | if (nd.path.mnt->mnt_sb != sb) { | 3182 | if (nd.path.mnt->mnt_sb != sb) { |
| 3165 | path_put(&nd.path); | 3183 | path_put(&nd.path); |
| 3166 | return -EXDEV; | 3184 | return -EXDEV; |
| 3167 | } | 3185 | } |
| 3168 | /* Quotafile not of fs root? */ | 3186 | /* Journaling quota? */ |
| 3169 | if (nd.path.dentry->d_parent->d_inode != sb->s_root->d_inode) | 3187 | if (EXT4_SB(sb)->s_qf_names[type]) { |
| 3170 | printk(KERN_WARNING | 3188 | /* Quotafile not of fs root? */ |
| 3171 | "EXT4-fs: Quota file not on filesystem root. " | 3189 | if (nd.path.dentry->d_parent->d_inode != sb->s_root->d_inode) |
| 3172 | "Journalled quota will not work.\n"); | 3190 | printk(KERN_WARNING |
| 3191 | "EXT4-fs: Quota file not on filesystem root. " | ||
| 3192 | "Journaled quota will not work.\n"); | ||
| 3193 | } | ||
| 3194 | |||
| 3195 | /* | ||
| 3196 | * When we journal data on quota file, we have to flush journal to see | ||
| 3197 | * all updates to the file when we bypass pagecache... | ||
| 3198 | */ | ||
| 3199 | if (ext4_should_journal_data(nd.path.dentry->d_inode)) { | ||
| 3200 | /* | ||
| 3201 | * We don't need to lock updates but journal_flush() could | ||
| 3202 | * otherwise be livelocked... | ||
| 3203 | */ | ||
| 3204 | jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); | ||
| 3205 | jbd2_journal_flush(EXT4_SB(sb)->s_journal); | ||
| 3206 | jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); | ||
| 3207 | } | ||
| 3208 | |||
| 3173 | path_put(&nd.path); | 3209 | path_put(&nd.path); |
| 3174 | return vfs_quota_on(sb, type, format_id, path, remount); | 3210 | return vfs_quota_on(sb, type, format_id, path, remount); |
| 3175 | } | 3211 | } |
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index e0139786f717..4d99685fdce4 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c | |||
| @@ -560,7 +560,9 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
| 560 | * transaction! Now comes the tricky part: we need to write out | 560 | * transaction! Now comes the tricky part: we need to write out |
| 561 | * metadata. Loop over the transaction's entire buffer list: | 561 | * metadata. Loop over the transaction's entire buffer list: |
| 562 | */ | 562 | */ |
| 563 | spin_lock(&journal->j_state_lock); | ||
| 563 | commit_transaction->t_state = T_COMMIT; | 564 | commit_transaction->t_state = T_COMMIT; |
| 565 | spin_unlock(&journal->j_state_lock); | ||
| 564 | 566 | ||
| 565 | stats.u.run.rs_logging = jiffies; | 567 | stats.u.run.rs_logging = jiffies; |
| 566 | stats.u.run.rs_flushing = jbd2_time_diff(stats.u.run.rs_flushing, | 568 | stats.u.run.rs_flushing = jbd2_time_diff(stats.u.run.rs_flushing, |
