Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

Pull ext4 fixes from Ted Ts'o:
"Fix a number of ext4 bugs; the most serious of which is a bug in the
lazytime mount optimization code where we could end up updating the
timestamps to the wrong inode"

* tag 'for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4:
ext4: fix an ext3 collapse range regression in xfstests
jbd2: fix r_count overflows leading to buffer overflow in journal recovery
ext4: check for zero length extent explicitly
ext4: fix NULL pointer dereference when journal restart fails
ext4: remove unused function prototype from ext4.h
ext4: don't save the error information if the block device is read-only
ext4: fix lazytime optimization

+53 -21
-1
fs/ext4/ext4.h
··· 2889 2889 struct ext4_map_blocks *map, int flags); 2890 2890 extern int ext4_ext_calc_metadata_amount(struct inode *inode, 2891 2891 ext4_lblk_t lblocks); 2892 - extern int ext4_extent_tree_init(handle_t *, struct inode *); 2893 2892 extern int ext4_ext_calc_credits_for_single_extent(struct inode *inode, 2894 2893 int num, 2895 2894 struct ext4_ext_path *path);
+6
fs/ext4/ext4_jbd2.c
··· 87 87 ext4_put_nojournal(handle); 88 88 return 0; 89 89 } 90 + 91 + if (!handle->h_transaction) { 92 + err = jbd2_journal_stop(handle); 93 + return handle->h_err ? handle->h_err : err; 94 + } 95 + 90 96 sb = handle->h_transaction->t_journal->j_private; 91 97 err = handle->h_err; 92 98 rc = jbd2_journal_stop(handle);
+9 -1
fs/ext4/extents.c
··· 377 377 ext4_lblk_t lblock = le32_to_cpu(ext->ee_block); 378 378 ext4_lblk_t last = lblock + len - 1; 379 379 380 - if (lblock > last) 380 + if (len == 0 || lblock > last) 381 381 return 0; 382 382 return ext4_data_block_valid(EXT4_SB(inode->i_sb), block, len); 383 383 } ··· 5395 5395 unsigned int credits; 5396 5396 loff_t new_size, ioffset; 5397 5397 int ret; 5398 + 5399 + /* 5400 + * We need to test this early because xfstests assumes that a 5401 + * collapse range of (0, 1) will return EOPNOTSUPP if the file 5402 + * system does not support collapse range. 5403 + */ 5404 + if (!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) 5405 + return -EOPNOTSUPP; 5398 5406 5399 5407 /* Collapse range works only on fs block size aligned offsets. */ 5400 5408 if (offset & (EXT4_CLUSTER_SIZE(sb) - 1) ||
+1 -1
fs/ext4/inode.c
··· 4345 4345 int inode_size = EXT4_INODE_SIZE(sb); 4346 4346 4347 4347 oi.orig_ino = orig_ino; 4348 - ino = orig_ino & ~(inodes_per_block - 1); 4348 + ino = (orig_ino & ~(inodes_per_block - 1)) + 1; 4349 4349 for (i = 0; i < inodes_per_block; i++, ino++, buf += inode_size) { 4350 4350 if (ino == orig_ino) 4351 4351 continue;
+2
fs/ext4/super.c
··· 294 294 struct ext4_super_block *es = EXT4_SB(sb)->s_es; 295 295 296 296 EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; 297 + if (bdev_read_only(sb->s_bdev)) 298 + return; 297 299 es->s_state |= cpu_to_le16(EXT4_ERROR_FS); 298 300 es->s_last_error_time = cpu_to_le32(get_seconds()); 299 301 strncpy(es->s_last_error_func, func, sizeof(es->s_last_error_func));
+9 -1
fs/jbd2/recovery.c
··· 842 842 { 843 843 jbd2_journal_revoke_header_t *header; 844 844 int offset, max; 845 + int csum_size = 0; 846 + __u32 rcount; 845 847 int record_len = 4; 846 848 847 849 header = (jbd2_journal_revoke_header_t *) bh->b_data; 848 850 offset = sizeof(jbd2_journal_revoke_header_t); 849 - max = be32_to_cpu(header->r_count); 851 + rcount = be32_to_cpu(header->r_count); 850 852 851 853 if (!jbd2_revoke_block_csum_verify(journal, header)) 852 854 return -EINVAL; 855 + 856 + if (jbd2_journal_has_csum_v2or3(journal)) 857 + csum_size = sizeof(struct jbd2_journal_revoke_tail); 858 + if (rcount > journal->j_blocksize - csum_size) 859 + return -EINVAL; 860 + max = rcount; 853 861 854 862 if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT)) 855 863 record_len = 8;
+10 -8
fs/jbd2/revoke.c
··· 577 577 { 578 578 int csum_size = 0; 579 579 struct buffer_head *descriptor; 580 - int offset; 580 + int sz, offset; 581 581 journal_header_t *header; 582 582 583 583 /* If we are already aborting, this all becomes a noop. We ··· 594 594 if (jbd2_journal_has_csum_v2or3(journal)) 595 595 csum_size = sizeof(struct jbd2_journal_revoke_tail); 596 596 597 + if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT)) 598 + sz = 8; 599 + else 600 + sz = 4; 601 + 597 602 /* Make sure we have a descriptor with space left for the record */ 598 603 if (descriptor) { 599 - if (offset >= journal->j_blocksize - csum_size) { 604 + if (offset + sz > journal->j_blocksize - csum_size) { 600 605 flush_descriptor(journal, descriptor, offset, write_op); 601 606 descriptor = NULL; 602 607 } ··· 624 619 *descriptorp = descriptor; 625 620 } 626 621 627 - if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT)) { 622 + if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT)) 628 623 * ((__be64 *)(&descriptor->b_data[offset])) = 629 624 cpu_to_be64(record->blocknr); 630 - offset += 8; 631 - 632 - } else { 625 + else 633 626 * ((__be32 *)(&descriptor->b_data[offset])) = 634 627 cpu_to_be32(record->blocknr); 635 - offset += 4; 636 - } 628 + offset += sz; 637 629 638 630 *offsetp = offset; 639 631 }
+16 -9
fs/jbd2/transaction.c
··· 551 551 int result; 552 552 int wanted; 553 553 554 - WARN_ON(!transaction); 555 554 if (is_handle_aborted(handle)) 556 555 return -EROFS; 557 556 journal = transaction->t_journal; ··· 626 627 tid_t tid; 627 628 int need_to_start, ret; 628 629 629 - WARN_ON(!transaction); 630 630 /* If we've had an abort of any type, don't even think about 631 631 * actually doing the restart! */ 632 632 if (is_handle_aborted(handle)) ··· 783 785 int need_copy = 0; 784 786 unsigned long start_lock, time_lock; 785 787 786 - WARN_ON(!transaction); 787 788 if (is_handle_aborted(handle)) 788 789 return -EROFS; 789 790 journal = transaction->t_journal; ··· 1048 1051 int err; 1049 1052 1050 1053 jbd_debug(5, "journal_head %p\n", jh); 1051 - WARN_ON(!transaction); 1052 1054 err = -EROFS; 1053 1055 if (is_handle_aborted(handle)) 1054 1056 goto out; ··· 1262 1266 struct journal_head *jh; 1263 1267 int ret = 0; 1264 1268 1265 - WARN_ON(!transaction); 1266 1269 if (is_handle_aborted(handle)) 1267 1270 return -EROFS; 1268 1271 journal = transaction->t_journal; ··· 1392 1397 int err = 0; 1393 1398 int was_modified = 0; 1394 1399 1395 - WARN_ON(!transaction); 1396 1400 if (is_handle_aborted(handle)) 1397 1401 return -EROFS; 1398 1402 journal = transaction->t_journal; ··· 1524 1530 tid_t tid; 1525 1531 pid_t pid; 1526 1532 1527 - if (!transaction) 1528 - goto free_and_exit; 1533 + if (!transaction) { 1534 + /* 1535 + * Handle is already detached from the transaction so 1536 + * there is nothing to do other than decrease a refcount, 1537 + * or free the handle if refcount drops to zero 1538 + */ 1539 + if (--handle->h_ref > 0) { 1540 + jbd_debug(4, "h_ref %d -> %d\n", handle->h_ref + 1, 1541 + handle->h_ref); 1542 + return err; 1543 + } else { 1544 + if (handle->h_rsv_handle) 1545 + jbd2_free_handle(handle->h_rsv_handle); 1546 + goto free_and_exit; 1547 + } 1548 + } 1529 1549 journal = transaction->t_journal; 1530 1550 1531 1551 J_ASSERT(journal_current_handle() == handle); ··· 2381 2373 transaction_t *transaction = handle->h_transaction; 2382 2374 journal_t *journal; 2383 2375 2384 - WARN_ON(!transaction); 2385 2376 if (is_handle_aborted(handle)) 2386 2377 return -EROFS; 2387 2378 journal = transaction->t_journal;