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

+116 -49
+11 -6
fs/ext4/balloc.c
··· 287 287 (int)block_group, (unsigned long long)bitmap_blk); 288 288 return NULL; 289 289 } 290 - if (!ext4_valid_block_bitmap(sb, desc, block_group, bh)) { 291 - put_bh(bh); 292 - return NULL; 293 - } 294 - 290 + ext4_valid_block_bitmap(sb, desc, block_group, bh); 291 + /* 292 + * file system mounted not to panic on error, 293 + * continue with corrupt bitmap 294 + */ 295 295 return bh; 296 296 } 297 297 /* ··· 1770 1770 "Allocating block in system zone - " 1771 1771 "blocks from %llu, length %lu", 1772 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 1781 performed_allocation = 1;
+45 -21
fs/ext4/mballoc.c
··· 2736 2736 struct ext4_sb_info *sbi; 2737 2737 struct super_block *sb; 2738 2738 ext4_fsblk_t block; 2739 - int err; 2739 + int err, len; 2740 2740 2741 2741 BUG_ON(ac->ac_status != AC_STATUS_FOUND); 2742 2742 BUG_ON(ac->ac_b_ex.fe_len <= 0); ··· 2770 2770 + ac->ac_b_ex.fe_start 2771 2771 + le32_to_cpu(es->s_first_data_block); 2772 2772 2773 - if (block == ext4_block_bitmap(sb, gdp) || 2774 - block == ext4_inode_bitmap(sb, gdp) || 2775 - in_range(block, ext4_inode_table(sb, gdp), 2776 - EXT4_SB(sb)->s_itb_per_group)) { 2777 - 2773 + len = ac->ac_b_ex.fe_len; 2774 + if (in_range(ext4_block_bitmap(sb, gdp), block, len) || 2775 + in_range(ext4_inode_bitmap(sb, gdp), block, len) || 2776 + in_range(block, ext4_inode_table(sb, gdp), 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 2780 ext4_error(sb, __func__, 2779 2781 "Allocating block in system zone - block = %llu", 2780 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 2795 #ifdef AGGRESSIVE_CHECK 2783 2796 { ··· 2893 2880 if (size < i_size_read(ac->ac_inode)) 2894 2881 size = i_size_read(ac->ac_inode); 2895 2882 2896 - /* max available blocks in a free group */ 2897 - max = EXT4_BLOCKS_PER_GROUP(ac->ac_sb) - 1 - 1 - 2898 - EXT4_SB(ac->ac_sb)->s_itb_per_group; 2883 + /* max size of free chunks */ 2884 + max = 2 << bsbits; 2899 2885 2900 - #define NRL_CHECK_SIZE(req, size, max,bits) \ 2901 - (req <= (size) || max <= ((size) >> bits)) 2886 + #define NRL_CHECK_SIZE(req, size, max, chunk_size) \ 2887 + (req <= (size) || max <= (chunk_size)) 2902 2888 2903 2889 /* first, try to predict filesize */ 2904 2890 /* XXX: should this table be tunable? */ ··· 2916 2904 size = 512 * 1024; 2917 2905 } else if (size <= 1024 * 1024) { 2918 2906 size = 1024 * 1024; 2919 - } else if (NRL_CHECK_SIZE(size, 4 * 1024 * 1024, max, bsbits)) { 2907 + } else if (NRL_CHECK_SIZE(size, 4 * 1024 * 1024, max, 2 * 1024)) { 2920 2908 start_off = ((loff_t)ac->ac_o_ex.fe_logical >> 2921 - (20 - bsbits)) << 20; 2922 - size = 1024 * 1024; 2923 - } else if (NRL_CHECK_SIZE(size, 8 * 1024 * 1024, max, bsbits)) { 2909 + (21 - bsbits)) << 21; 2910 + size = 2 * 1024 * 1024; 2911 + } else if (NRL_CHECK_SIZE(size, 8 * 1024 * 1024, max, 4 * 1024)) { 2924 2912 start_off = ((loff_t)ac->ac_o_ex.fe_logical >> 2925 2913 (22 - bsbits)) << 22; 2926 2914 size = 4 * 1024 * 1024; 2927 2915 } else if (NRL_CHECK_SIZE(ac->ac_o_ex.fe_len, 2928 - (8<<20)>>bsbits, max, bsbits)) { 2916 + (8<<20)>>bsbits, max, 8 * 1024)) { 2929 2917 start_off = ((loff_t)ac->ac_o_ex.fe_logical >> 2930 2918 (23 - bsbits)) << 23; 2931 2919 size = 8 * 1024 * 1024; ··· 4045 4033 4046 4034 ac->ac_op = EXT4_MB_HISTORY_ALLOC; 4047 4035 ext4_mb_normalize_request(ac, ar); 4048 - 4049 4036 repeat: 4050 4037 /* allocate space in core */ 4051 4038 ext4_mb_regular_allocator(ac); ··· 4058 4047 } 4059 4048 4060 4049 if (likely(ac->ac_status == AC_STATUS_FOUND)) { 4061 - ext4_mb_mark_diskspace_used(ac, handle); 4062 - *errp = 0; 4063 - block = ext4_grp_offs_to_block(sb, &ac->ac_b_ex); 4064 - ar->len = ac->ac_b_ex.fe_len; 4050 + *errp = ext4_mb_mark_diskspace_used(ac, handle); 4051 + if (*errp == -EAGAIN) { 4052 + ac->ac_b_ex.fe_group = 0; 4053 + ac->ac_b_ex.fe_start = 0; 4054 + ac->ac_b_ex.fe_len = 0; 4055 + ac->ac_status = AC_STATUS_CONTINUE; 4056 + goto repeat; 4057 + } else if (*errp) { 4058 + ac->ac_b_ex.fe_len = 0; 4059 + ar->len = 0; 4060 + ext4_mb_show_ac(ac); 4061 + } else { 4062 + block = ext4_grp_offs_to_block(sb, &ac->ac_b_ex); 4063 + ar->len = ac->ac_b_ex.fe_len; 4064 + } 4065 4065 } else { 4066 4066 freed = ext4_mb_discard_preallocations(sb, ac->ac_o_ex.fe_len); 4067 4067 if (freed) ··· 4259 4237 ext4_error(sb, __func__, 4260 4238 "Freeing blocks in system zone - " 4261 4239 "Block = %lu, count = %lu", block, count); 4240 + /* err = 0. ext4_std_error should be a no op */ 4241 + goto error_return; 4262 4242 } 4263 4243 4264 4244 BUFFER_TRACE(bitmap_bh, "getting write access");
+58 -22
fs/ext4/super.c
··· 979 979 int data_opt = 0; 980 980 int option; 981 981 #ifdef CONFIG_QUOTA 982 - int qtype; 982 + int qtype, qfmt; 983 983 char *qname; 984 984 #endif 985 985 ··· 1162 1162 case Opt_grpjquota: 1163 1163 qtype = GRPQUOTA; 1164 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 1168 printk(KERN_ERR 1167 - "EXT4-fs: Cannot change journalled " 1169 + "EXT4-fs: Cannot change journaled " 1168 1170 "quota options when quota turned on.\n"); 1169 1171 return 0; 1170 1172 } ··· 1202 1200 case Opt_offgrpjquota: 1203 1201 qtype = GRPQUOTA; 1204 1202 clear_qf_name: 1205 - if (sb_any_quota_enabled(sb)) { 1203 + if ((sb_any_quota_enabled(sb) || 1204 + sb_any_quota_suspended(sb)) && 1205 + sbi->s_qf_names[qtype]) { 1206 1206 printk(KERN_ERR "EXT4-fs: Cannot change " 1207 - "journalled quota options when " 1207 + "journaled quota options when " 1208 1208 "quota turned on.\n"); 1209 1209 return 0; 1210 1210 } ··· 1217 1213 sbi->s_qf_names[qtype] = NULL; 1218 1214 break; 1219 1215 case Opt_jqfmt_vfsold: 1220 - sbi->s_jquota_fmt = QFMT_VFS_OLD; 1221 - break; 1216 + qfmt = QFMT_VFS_OLD; 1217 + goto set_qf_format; 1222 1218 case Opt_jqfmt_vfsv0: 1223 - sbi->s_jquota_fmt = QFMT_VFS_V0; 1219 + qfmt = QFMT_VFS_V0; 1220 + set_qf_format: 1221 + if ((sb_any_quota_enabled(sb) || 1222 + sb_any_quota_suspended(sb)) && 1223 + sbi->s_jquota_fmt != qfmt) { 1224 + printk(KERN_ERR "EXT4-fs: Cannot change " 1225 + "journaled quota options when " 1226 + "quota turned on.\n"); 1227 + return 0; 1228 + } 1229 + sbi->s_jquota_fmt = qfmt; 1224 1230 break; 1225 1231 case Opt_quota: 1226 1232 case Opt_usrquota: ··· 1255 1241 case Opt_quota: 1256 1242 case Opt_usrquota: 1257 1243 case Opt_grpquota: 1244 + printk(KERN_ERR 1245 + "EXT4-fs: quota options not supported.\n"); 1246 + break; 1258 1247 case Opt_usrjquota: 1259 1248 case Opt_grpjquota: 1260 1249 case Opt_offusrjquota: ··· 1265 1248 case Opt_jqfmt_vfsold: 1266 1249 case Opt_jqfmt_vfsv0: 1267 1250 printk(KERN_ERR 1268 - "EXT4-fs: journalled quota options not " 1251 + "EXT4-fs: journaled quota options not " 1269 1252 "supported.\n"); 1270 1253 break; 1271 1254 case Opt_noquota: ··· 1350 1333 } 1351 1334 1352 1335 if (!sbi->s_jquota_fmt) { 1353 - printk(KERN_ERR "EXT4-fs: journalled quota format " 1336 + printk(KERN_ERR "EXT4-fs: journaled quota format " 1354 1337 "not specified.\n"); 1355 1338 return 0; 1356 1339 } 1357 1340 } else { 1358 1341 if (sbi->s_jquota_fmt) { 1359 - printk(KERN_ERR "EXT4-fs: journalled quota format " 1360 - "specified with no journalling " 1342 + printk(KERN_ERR "EXT4-fs: journaled quota format " 1343 + "specified with no journaling " 1361 1344 "enabled.\n"); 1362 1345 return 0; 1363 1346 } ··· 1598 1581 int ret = ext4_quota_on_mount(sb, i); 1599 1582 if (ret < 0) 1600 1583 printk(KERN_ERR 1601 - "EXT4-fs: Cannot turn on journalled " 1584 + "EXT4-fs: Cannot turn on journaled " 1602 1585 "quota: error %d\n", ret); 1603 1586 } 1604 1587 } ··· 3123 3106 3124 3107 static int ext4_mark_dquot_dirty(struct dquot *dquot) 3125 3108 { 3126 - /* Are we journalling quotas? */ 3109 + /* Are we journaling quotas? */ 3127 3110 if (EXT4_SB(dquot->dq_sb)->s_qf_names[USRQUOTA] || 3128 3111 EXT4_SB(dquot->dq_sb)->s_qf_names[GRPQUOTA]) { 3129 3112 dquot_mark_dquot_dirty(dquot); ··· 3170 3153 3171 3154 if (!test_opt(sb, QUOTA)) 3172 3155 return -EINVAL; 3173 - /* Not journalling quota? */ 3174 - if ((!EXT4_SB(sb)->s_qf_names[USRQUOTA] && 3175 - !EXT4_SB(sb)->s_qf_names[GRPQUOTA]) || remount) 3156 + /* When remounting, no checks are needed and in fact, path is NULL */ 3157 + if (remount) 3176 3158 return vfs_quota_on(sb, type, format_id, path, remount); 3159 + 3177 3160 err = path_lookup(path, LOOKUP_FOLLOW, &nd); 3178 3161 if (err) 3179 3162 return err; 3163 + 3180 3164 /* Quotafile not on the same filesystem? */ 3181 3165 if (nd.path.mnt->mnt_sb != sb) { 3182 3166 path_put(&nd.path); 3183 3167 return -EXDEV; 3184 3168 } 3185 - /* Quotafile not of fs root? */ 3186 - if (nd.path.dentry->d_parent->d_inode != sb->s_root->d_inode) 3187 - printk(KERN_WARNING 3188 - "EXT4-fs: Quota file not on filesystem root. " 3189 - "Journalled quota will not work.\n"); 3169 + /* Journaling quota? */ 3170 + if (EXT4_SB(sb)->s_qf_names[type]) { 3171 + /* Quotafile not of fs root? */ 3172 + if (nd.path.dentry->d_parent->d_inode != sb->s_root->d_inode) 3173 + printk(KERN_WARNING 3174 + "EXT4-fs: Quota file not on filesystem root. " 3175 + "Journaled quota will not work.\n"); 3176 + } 3177 + 3178 + /* 3179 + * When we journal data on quota file, we have to flush journal to see 3180 + * all updates to the file when we bypass pagecache... 3181 + */ 3182 + if (ext4_should_journal_data(nd.path.dentry->d_inode)) { 3183 + /* 3184 + * We don't need to lock updates but journal_flush() could 3185 + * otherwise be livelocked... 3186 + */ 3187 + jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); 3188 + jbd2_journal_flush(EXT4_SB(sb)->s_journal); 3189 + jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); 3190 + } 3191 + 3190 3192 path_put(&nd.path); 3191 3193 return vfs_quota_on(sb, type, format_id, path, remount); 3192 3194 }
+2
fs/jbd2/commit.c
··· 560 560 * transaction! Now comes the tricky part: we need to write out 561 561 * metadata. Loop over the transaction's entire buffer list: 562 562 */ 563 + spin_lock(&journal->j_state_lock); 563 564 commit_transaction->t_state = T_COMMIT; 565 + spin_unlock(&journal->j_state_lock); 564 566 565 567 stats.u.run.rs_logging = jiffies; 566 568 stats.u.run.rs_flushing = jbd2_time_diff(stats.u.run.rs_flushing,