History

Merge tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4

Pull ext4 fixes from Ted Ts'o: "Miscellaneous ext4 bug fixes for 5.1" * tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: ext4: prohibit fstrim in norecovery mode ext4: cleanup bh release code in ext4_ind_remove_space() ext4: brelse all indirect buffer in ext4_ind_remove_space() ext4: report real fs size after failed resize ext4: add missing brelse() in add_new_gdb_meta_bg() ext4: remove useless ext4_pin_inode() ext4: avoid panic during forced reboot ext4: fix data corruption caused by unaligned direct AIO ext4: fix NULL pointer dereference while journal is aborted

Linus Torvalds committed 7 years ago

Commit 17403fa2 parents 231c807 18915b57 files · +58 −59Browse files

Unified · Split

7 files
  1. fs/ext4/ext4_jbd2.h +1 −1
  2. fs/ext4/file.c +1 −1
  3. fs/ext4/indirect.c +22 −21
  4. fs/ext4/inode.c +0 −30
  5. fs/ext4/ioctl.c +7 −0
  6. fs/ext4/resize.c +14 −3
  7. fs/ext4/super.c +13 −3
fs/ext4/ext4_jbd2.h+1−1
@@ -384,7 +384,7 @@ static inline void ext4_update_inode_fsync_trans(handle_t *handle, · 383 unmodified lines
384384 {
385385 struct ext4_inode_info *ei = EXT4_I(inode);
386386
387− if (ext4_handle_valid(handle)) {
387+ if (ext4_handle_valid(handle) && !is_handle_aborted(handle)) {
388388 ei->i_sync_tid = handle->h_transaction->t_tid;
389389 if (datasync)
390390 ei->i_datasync_tid = handle->h_transaction->t_tid;
fs/ext4/file.c+1−1
@@ -125,7 +125,7 @@ ext4_unaligned_aio(struct inode *inode, struct iov_iter *from, loff_t pos) · 124 unmodified lines
125125 struct super_block *sb = inode->i_sb;
126126 int blockmask = sb->s_blocksize - 1;
127127
128− if (pos >= i_size_read(inode))
128+ if (pos >= ALIGN(i_size_read(inode), sb->s_blocksize))
129129 return 0;
130130
131131 if ((pos | iov_iter_alignment(from)) & blockmask)
fs/ext4/indirect.c+22−21
@@ -1222,6 +1222,7 @@ int ext4_ind_remove_space(handle_t *handle, struct inode *inode, · 1221 unmodified lines
12221222 ext4_lblk_t offsets[4], offsets2[4];
12231223 Indirect chain[4], chain2[4];
12241224 Indirect *partial, *partial2;
1225+ Indirect *p = NULL, *p2 = NULL;
12251226 ext4_lblk_t max_block;
12261227 __le32 nr = 0, nr2 = 0;
12271228 int n = 0, n2 = 0;
@@ -1263,7 +1264,7 @@ int ext4_ind_remove_space(handle_t *handle, struct inode *inode, · 35 unmodified lines
12631264 }
12641265
12651266
1266− partial = ext4_find_shared(inode, n, offsets, chain, &nr);
1267+ partial = p = ext4_find_shared(inode, n, offsets, chain, &nr);
12671268 if (nr) {
12681269 if (partial == chain) {
12691270 /* Shared branch grows from the inode */
@@ -1288,13 +1289,11 @@ int ext4_ind_remove_space(handle_t *handle, struct inode *inode, · 18 unmodified lines
12881289 partial->p + 1,
12891290 (__le32 *)partial->bh->b_data+addr_per_block,
12901291 (chain+n-1) - partial);
1291− BUFFER_TRACE(partial->bh, "call brelse");
1292− brelse(partial->bh);
12931292 partial--;
12941293 }
12951294
12961295 end_range:
1297− partial2 = ext4_find_shared(inode, n2, offsets2, chain2, &nr2);
1296+ partial2 = p2 = ext4_find_shared(inode, n2, offsets2, chain2, &nr2);
12981297 if (nr2) {
12991298 if (partial2 == chain2) {
13001299 /*
@@ -1324,16 +1323,14 @@ end_range: · 23 unmodified lines
13241323 (__le32 *)partial2->bh->b_data,
13251324 partial2->p,
13261325 (chain2+n2-1) - partial2);
1327− BUFFER_TRACE(partial2->bh, "call brelse");
1328− brelse(partial2->bh);
13291326 partial2--;
13301327 }
13311328 goto do_indirects;
13321329 }
13331330
13341331 /* Punch happened within the same level (n == n2) */
1335− partial = ext4_find_shared(inode, n, offsets, chain, &nr);
1336− partial2 = ext4_find_shared(inode, n2, offsets2, chain2, &nr2);
1332+ partial = p = ext4_find_shared(inode, n, offsets, chain, &nr);
1333+ partial2 = p2 = ext4_find_shared(inode, n2, offsets2, chain2, &nr2);
13371334
13381335 /* Free top, but only if partial2 isn't its subtree. */
13391336 if (nr) {
@@ -1390,11 +1387,7 @@ end_range: · 50 unmodified lines
13901387 partial->p + 1,
13911388 partial2->p,
13921389 (chain+n-1) - partial);
1393− BUFFER_TRACE(partial->bh, "call brelse");
1394− brelse(partial->bh);
1395− BUFFER_TRACE(partial2->bh, "call brelse");
1396− brelse(partial2->bh);
1397− return 0;
1390+ goto cleanup;
13981391 }
13991392
14001393 /*
@@ -1409,8 +1402,6 @@ end_range: · 8 unmodified lines
14091402 partial->p + 1,
14101403 (__le32 *)partial->bh->b_data+addr_per_block,
14111404 (chain+n-1) - partial);
1412− BUFFER_TRACE(partial->bh, "call brelse");
1413− brelse(partial->bh);
14141405 partial--;
14151406 }
14161407 if (partial2 > chain2 && depth2 <= depth) {
@@ -1418,11 +1409,21 @@ end_range: · 1 unmodified line
14181409 (__le32 *)partial2->bh->b_data,
14191410 partial2->p,
14201411 (chain2+n2-1) - partial2);
1421− BUFFER_TRACE(partial2->bh, "call brelse");
1422− brelse(partial2->bh);
14231412 partial2--;
14241413 }
14251414 }
1415+
1416+cleanup:
1417+ while (p && p > chain) {
1418+ BUFFER_TRACE(p->bh, "call brelse");
1419+ brelse(p->bh);
1420+ p--;
1421+ }
1422+ while (p2 && p2 > chain2) {
1423+ BUFFER_TRACE(p2->bh, "call brelse");
1424+ brelse(p2->bh);
1425+ p2--;
1426+ }
14261427 return 0;
14271428
14281429 do_indirects:
@@ -1430,7 +1431,7 @@ do_indirects: · 1 unmodified line
14301431 switch (offsets[0]) {
14311432 default:
14321433 if (++n >= n2)
1433− return 0;
1434+ break;
14341435 nr = i_data[EXT4_IND_BLOCK];
14351436 if (nr) {
14361437 ext4_free_branches(handle, inode, NULL, &nr, &nr+1, 1);
@@ -1439,7 +1440,7 @@ do_indirects: · 2 unmodified lines
14391440 /* fall through */
14401441 case EXT4_IND_BLOCK:
14411442 if (++n >= n2)
1442− return 0;
1443+ break;
14431444 nr = i_data[EXT4_DIND_BLOCK];
14441445 if (nr) {
14451446 ext4_free_branches(handle, inode, NULL, &nr, &nr+1, 2);
@@ -1448,7 +1449,7 @@ do_indirects: · 2 unmodified lines
14481449 /* fall through */
14491450 case EXT4_DIND_BLOCK:
14501451 if (++n >= n2)
1451− return 0;
1452+ break;
14521453 nr = i_data[EXT4_TIND_BLOCK];
14531454 if (nr) {
14541455 ext4_free_branches(handle, inode, NULL, &nr, &nr+1, 3);
@@ -1458,5 +1459,5 @@ do_indirects: · 3 unmodified lines
14581459 case EXT4_TIND_BLOCK:
14591460 ;
14601461 }
1461− return 0;
1462+ goto cleanup;
14621463 }
fs/ext4/inode.c+0−30
@@ -6080,36 +6080,6 @@ out: · 6079 unmodified lines
60806080 return;
60816081 }
60826082
6083−#if 0
6084−/*
6085− * Bind an inode's backing buffer_head into this transaction, to prevent
6086− * it from being flushed to disk early. Unlike
6087− * ext4_reserve_inode_write, this leaves behind no bh reference and
6088− * returns no iloc structure, so the caller needs to repeat the iloc
6089− * lookup to mark the inode dirty later.
6090− */
6091−static int ext4_pin_inode(handle_t *handle, struct inode *inode)
6092−{
6093− struct ext4_iloc iloc;
6094−
6095− int err = 0;
6096− if (handle) {
6097− err = ext4_get_inode_loc(inode, &iloc);
6098− if (!err) {
6099− BUFFER_TRACE(iloc.bh, "get_write_access");
6100− err = jbd2_journal_get_write_access(handle, iloc.bh);
6101− if (!err)
6102− err = ext4_handle_dirty_metadata(handle,
6103− NULL,
6104− iloc.bh);
6105− brelse(iloc.bh);
6106− }
6107− }
6108− ext4_std_error(inode->i_sb, err);
6109− return err;
6110−}
6111−#endif
6112−
61136083 int ext4_change_inode_journal_flag(struct inode *inode, int val)
61146084 {
61156085 journal_t *journal;
fs/ext4/ioctl.c+7−0
@@ -1000,6 +1000,13 @@ resizefs_out: · 999 unmodified lines
10001000 if (!blk_queue_discard(q))
10011001 return -EOPNOTSUPP;
10021002
1003+ /*
1004+ * We haven't replayed the journal, so we cannot use our
1005+ * block-bitmap-guided storage zapping commands.
1006+ */
1007+ if (test_opt(sb, NOLOAD) && ext4_has_feature_journal(sb))
1008+ return -EROFS;
1009+
10031010 if (copy_from_user(&range, (struct fstrim_range __user *)arg,
10041011 sizeof(range)))
10051012 return -EFAULT;
fs/ext4/resize.c+14−3
@@ -932,11 +932,18 @@ static int add_new_gdb_meta_bg(struct super_block *sb, · 931 unmodified lines
932932 memcpy(n_group_desc, o_group_desc,
933933 EXT4_SB(sb)->s_gdb_count * sizeof(struct buffer_head *));
934934 n_group_desc[gdb_num] = gdb_bh;
935+
936+ BUFFER_TRACE(gdb_bh, "get_write_access");
937+ err = ext4_journal_get_write_access(handle, gdb_bh);
938+ if (err) {
939+ kvfree(n_group_desc);
940+ brelse(gdb_bh);
941+ return err;
942+ }
943+
935944 EXT4_SB(sb)->s_group_desc = n_group_desc;
936945 EXT4_SB(sb)->s_gdb_count++;
937946 kvfree(o_group_desc);
938− BUFFER_TRACE(gdb_bh, "get_write_access");
939− err = ext4_journal_get_write_access(handle, gdb_bh);
940947 return err;
941948 }
942949
@@ -2073,6 +2080,10 @@ out: · 1130 unmodified lines
20732080 free_flex_gd(flex_gd);
20742081 if (resize_inode != NULL)
20752082 iput(resize_inode);
2076− ext4_msg(sb, KERN_INFO, "resized filesystem to %llu", n_blocks_count);
2083+ if (err)
2084+ ext4_warning(sb, "error (%d) occurred during "
2085+ "file system resize", err);
2086+ ext4_msg(sb, KERN_INFO, "resized filesystem to %llu",
2087+ ext4_blocks_count(es));
20772088 return err;
20782089 }
fs/ext4/super.c+13−3
@@ -430,6 +430,12 @@ static void ext4_journal_commit_callback(journal_t *journal, transaction_t *txn) · 429 unmodified lines
430430 spin_unlock(&sbi->s_md_lock);
431431 }
432432
433+static bool system_going_down(void)
434+{
435+ return system_state == SYSTEM_HALT || system_state == SYSTEM_POWER_OFF
436+ || system_state == SYSTEM_RESTART;
437+}
438+
433439 /* Deal with the reporting of failure conditions on a filesystem such as
434440 * inconsistencies detected or read IO failures.
435441 *
@@ -460,7 +466,12 @@ static void ext4_handle_error(struct super_block *sb) · 24 unmodified lines
460466 if (journal)
461467 jbd2_journal_abort(journal, -EIO);
462468 }
463− if (test_opt(sb, ERRORS_RO)) {
469+ /*
470+ * We force ERRORS_RO behavior when system is rebooting. Otherwise we
471+ * could panic during 'reboot -f' as the underlying device got already
472+ * disabled.
473+ */
474+ if (test_opt(sb, ERRORS_RO) || system_going_down()) {
464475 ext4_msg(sb, KERN_CRIT, "Remounting filesystem read-only");
465476 /*
466477 * Make sure updated value of ->s_mount_flags will be visible
@@ -468,8 +479,7 @@ static void ext4_handle_error(struct super_block *sb) · 1 unmodified line
468479 */
469480 smp_wmb();
470481 sb->s_flags |= SB_RDONLY;
471− }
472− if (test_opt(sb, ERRORS_PANIC)) {
482+ } else if (test_opt(sb, ERRORS_PANIC)) {
473483 if (EXT4_SB(sb)->s_journal &&
474484 !(EXT4_SB(sb)->s_journal->j_flags & JBD2_REC_ERR))
475485 return;