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 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4

Pull ext4 fixes from Ted Ts'o:
"A number of bug fixes for ext4:

- Fix for the new fast_commit feature

- Fix some error handling codepaths in whiteout handling and
mountpoint sampling

- Fix how we write ext4_error information so it goes through the
journal when journalling is active, to avoid races that can lead to
lost error information, superblock checksum failures, or DIF/DIX
features"

* tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4:
ext4: remove expensive flush on fast commit
ext4: fix bug for rename with RENAME_WHITEOUT
ext4: fix wrong list_splice in ext4_fc_cleanup
ext4: use IS_ERR instead of IS_ERR_OR_NULL and set inode null when IS_ERR
ext4: don't leak old mountpoint samples
ext4: drop ext4_handle_dirty_super()
ext4: fix superblock checksum failure when setting password salt
ext4: use sbi instead of EXT4_SB(sb) in ext4_update_super()
ext4: save error info to sb through journal if available
ext4: protect superblock modifications with a buffer lock
ext4: drop sync argument of ext4_commit_super()
ext4: combine ext4_handle_error() and save_error_info()

+188 -131
-17
fs/ext4/ext4_jbd2.c
··· 372 372 } 373 373 return err; 374 374 } 375 - 376 - int __ext4_handle_dirty_super(const char *where, unsigned int line, 377 - handle_t *handle, struct super_block *sb) 378 - { 379 - struct buffer_head *bh = EXT4_SB(sb)->s_sbh; 380 - int err = 0; 381 - 382 - ext4_superblock_csum_set(sb); 383 - if (ext4_handle_valid(handle)) { 384 - err = jbd2_journal_dirty_metadata(handle, bh); 385 - if (err) 386 - ext4_journal_abort_handle(where, line, __func__, 387 - bh, handle, err); 388 - } else 389 - mark_buffer_dirty(bh); 390 - return err; 391 - }
-5
fs/ext4/ext4_jbd2.h
··· 244 244 handle_t *handle, struct inode *inode, 245 245 struct buffer_head *bh); 246 246 247 - int __ext4_handle_dirty_super(const char *where, unsigned int line, 248 - handle_t *handle, struct super_block *sb); 249 - 250 247 #define ext4_journal_get_write_access(handle, bh) \ 251 248 __ext4_journal_get_write_access(__func__, __LINE__, (handle), (bh)) 252 249 #define ext4_forget(handle, is_metadata, inode, bh, block_nr) \ ··· 254 257 #define ext4_handle_dirty_metadata(handle, inode, bh) \ 255 258 __ext4_handle_dirty_metadata(__func__, __LINE__, (handle), (inode), \ 256 259 (bh)) 257 - #define ext4_handle_dirty_super(handle, sb) \ 258 - __ext4_handle_dirty_super(__func__, __LINE__, (handle), (sb)) 259 260 260 261 handle_t *__ext4_journal_start_sb(struct super_block *sb, unsigned int line, 261 262 int type, int blocks, int rsv_blocks,
+18 -17
fs/ext4/fast_commit.c
··· 604 604 trace_ext4_fc_track_range(inode, start, end, ret); 605 605 } 606 606 607 - static void ext4_fc_submit_bh(struct super_block *sb) 607 + static void ext4_fc_submit_bh(struct super_block *sb, bool is_tail) 608 608 { 609 609 int write_flags = REQ_SYNC; 610 610 struct buffer_head *bh = EXT4_SB(sb)->s_fc_bh; 611 611 612 - /* TODO: REQ_FUA | REQ_PREFLUSH is unnecessarily expensive. */ 613 - if (test_opt(sb, BARRIER)) 612 + /* Add REQ_FUA | REQ_PREFLUSH only its tail */ 613 + if (test_opt(sb, BARRIER) && is_tail) 614 614 write_flags |= REQ_FUA | REQ_PREFLUSH; 615 615 lock_buffer(bh); 616 616 set_buffer_dirty(bh); ··· 684 684 *crc = ext4_chksum(sbi, *crc, tl, sizeof(*tl)); 685 685 if (pad_len > 0) 686 686 ext4_fc_memzero(sb, tl + 1, pad_len, crc); 687 - ext4_fc_submit_bh(sb); 687 + ext4_fc_submit_bh(sb, false); 688 688 689 689 ret = jbd2_fc_get_buf(EXT4_SB(sb)->s_journal, &bh); 690 690 if (ret) ··· 741 741 tail.fc_crc = cpu_to_le32(crc); 742 742 ext4_fc_memcpy(sb, dst, &tail.fc_crc, sizeof(tail.fc_crc), NULL); 743 743 744 - ext4_fc_submit_bh(sb); 744 + ext4_fc_submit_bh(sb, true); 745 745 746 746 return 0; 747 747 } ··· 1268 1268 list_splice_init(&sbi->s_fc_dentry_q[FC_Q_STAGING], 1269 1269 &sbi->s_fc_dentry_q[FC_Q_MAIN]); 1270 1270 list_splice_init(&sbi->s_fc_q[FC_Q_STAGING], 1271 - &sbi->s_fc_q[FC_Q_STAGING]); 1271 + &sbi->s_fc_q[FC_Q_MAIN]); 1272 1272 1273 1273 ext4_clear_mount_flag(sb, EXT4_MF_FC_COMMITTING); 1274 1274 ext4_clear_mount_flag(sb, EXT4_MF_FC_INELIGIBLE); ··· 1318 1318 entry.len = darg.dname_len; 1319 1319 inode = ext4_iget(sb, darg.ino, EXT4_IGET_NORMAL); 1320 1320 1321 - if (IS_ERR_OR_NULL(inode)) { 1321 + if (IS_ERR(inode)) { 1322 1322 jbd_debug(1, "Inode %d not found", darg.ino); 1323 1323 return 0; 1324 1324 } 1325 1325 1326 1326 old_parent = ext4_iget(sb, darg.parent_ino, 1327 1327 EXT4_IGET_NORMAL); 1328 - if (IS_ERR_OR_NULL(old_parent)) { 1328 + if (IS_ERR(old_parent)) { 1329 1329 jbd_debug(1, "Dir with inode %d not found", darg.parent_ino); 1330 1330 iput(inode); 1331 1331 return 0; ··· 1410 1410 darg.parent_ino, darg.dname_len); 1411 1411 1412 1412 inode = ext4_iget(sb, darg.ino, EXT4_IGET_NORMAL); 1413 - if (IS_ERR_OR_NULL(inode)) { 1413 + if (IS_ERR(inode)) { 1414 1414 jbd_debug(1, "Inode not found."); 1415 1415 return 0; 1416 1416 } ··· 1466 1466 trace_ext4_fc_replay(sb, tag, ino, 0, 0); 1467 1467 1468 1468 inode = ext4_iget(sb, ino, EXT4_IGET_NORMAL); 1469 - if (!IS_ERR_OR_NULL(inode)) { 1469 + if (!IS_ERR(inode)) { 1470 1470 ext4_ext_clear_bb(inode); 1471 1471 iput(inode); 1472 1472 } 1473 + inode = NULL; 1473 1474 1474 1475 ext4_fc_record_modified_inode(sb, ino); 1475 1476 ··· 1513 1512 1514 1513 /* Given that we just wrote the inode on disk, this SHOULD succeed. */ 1515 1514 inode = ext4_iget(sb, ino, EXT4_IGET_NORMAL); 1516 - if (IS_ERR_OR_NULL(inode)) { 1515 + if (IS_ERR(inode)) { 1517 1516 jbd_debug(1, "Inode not found."); 1518 1517 return -EFSCORRUPTED; 1519 1518 } ··· 1565 1564 goto out; 1566 1565 1567 1566 inode = ext4_iget(sb, darg.ino, EXT4_IGET_NORMAL); 1568 - if (IS_ERR_OR_NULL(inode)) { 1567 + if (IS_ERR(inode)) { 1569 1568 jbd_debug(1, "inode %d not found.", darg.ino); 1570 1569 inode = NULL; 1571 1570 ret = -EINVAL; ··· 1578 1577 * dot and dot dot dirents are setup properly. 1579 1578 */ 1580 1579 dir = ext4_iget(sb, darg.parent_ino, EXT4_IGET_NORMAL); 1581 - if (IS_ERR_OR_NULL(dir)) { 1580 + if (IS_ERR(dir)) { 1582 1581 jbd_debug(1, "Dir %d not found.", darg.ino); 1583 1582 goto out; 1584 1583 } ··· 1654 1653 1655 1654 inode = ext4_iget(sb, le32_to_cpu(fc_add_ex->fc_ino), 1656 1655 EXT4_IGET_NORMAL); 1657 - if (IS_ERR_OR_NULL(inode)) { 1656 + if (IS_ERR(inode)) { 1658 1657 jbd_debug(1, "Inode not found."); 1659 1658 return 0; 1660 1659 } ··· 1778 1777 le32_to_cpu(lrange->fc_ino), cur, remaining); 1779 1778 1780 1779 inode = ext4_iget(sb, le32_to_cpu(lrange->fc_ino), EXT4_IGET_NORMAL); 1781 - if (IS_ERR_OR_NULL(inode)) { 1780 + if (IS_ERR(inode)) { 1782 1781 jbd_debug(1, "Inode %d not found", le32_to_cpu(lrange->fc_ino)); 1783 1782 return 0; 1784 1783 } ··· 1833 1832 for (i = 0; i < state->fc_modified_inodes_used; i++) { 1834 1833 inode = ext4_iget(sb, state->fc_modified_inodes[i], 1835 1834 EXT4_IGET_NORMAL); 1836 - if (IS_ERR_OR_NULL(inode)) { 1835 + if (IS_ERR(inode)) { 1837 1836 jbd_debug(1, "Inode %d not found.", 1838 1837 state->fc_modified_inodes[i]); 1839 1838 continue; ··· 1850 1849 1851 1850 if (ret > 0) { 1852 1851 path = ext4_find_extent(inode, map.m_lblk, NULL, 0); 1853 - if (!IS_ERR_OR_NULL(path)) { 1852 + if (!IS_ERR(path)) { 1854 1853 for (j = 0; j < path->p_depth; j++) 1855 1854 ext4_mb_mark_bb(inode->i_sb, 1856 1855 path[j].p_block, 1, 1);
+5 -2
fs/ext4/file.c
··· 809 809 err = ext4_journal_get_write_access(handle, sbi->s_sbh); 810 810 if (err) 811 811 goto out_journal; 812 - strlcpy(sbi->s_es->s_last_mounted, cp, 812 + lock_buffer(sbi->s_sbh); 813 + strncpy(sbi->s_es->s_last_mounted, cp, 813 814 sizeof(sbi->s_es->s_last_mounted)); 814 - ext4_handle_dirty_super(handle, sb); 815 + ext4_superblock_csum_set(sb); 816 + unlock_buffer(sbi->s_sbh); 817 + ext4_handle_dirty_metadata(handle, NULL, sbi->s_sbh); 815 818 out_journal: 816 819 ext4_journal_stop(handle); 817 820 out:
+5 -1
fs/ext4/inode.c
··· 5150 5150 err = ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh); 5151 5151 if (err) 5152 5152 goto out_brelse; 5153 + lock_buffer(EXT4_SB(sb)->s_sbh); 5153 5154 ext4_set_feature_large_file(sb); 5155 + ext4_superblock_csum_set(sb); 5156 + unlock_buffer(EXT4_SB(sb)->s_sbh); 5154 5157 ext4_handle_sync(handle); 5155 - err = ext4_handle_dirty_super(handle, sb); 5158 + err = ext4_handle_dirty_metadata(handle, NULL, 5159 + EXT4_SB(sb)->s_sbh); 5156 5160 } 5157 5161 ext4_update_inode_fsync_trans(handle, inode, need_datasync); 5158 5162 out_brelse:
+3
fs/ext4/ioctl.c
··· 1157 1157 err = ext4_journal_get_write_access(handle, sbi->s_sbh); 1158 1158 if (err) 1159 1159 goto pwsalt_err_journal; 1160 + lock_buffer(sbi->s_sbh); 1160 1161 generate_random_uuid(sbi->s_es->s_encrypt_pw_salt); 1162 + ext4_superblock_csum_set(sb); 1163 + unlock_buffer(sbi->s_sbh); 1161 1164 err = ext4_handle_dirty_metadata(handle, NULL, 1162 1165 sbi->s_sbh); 1163 1166 pwsalt_err_journal:
+19 -12
fs/ext4/namei.c
··· 2976 2976 (le32_to_cpu(sbi->s_es->s_inodes_count))) { 2977 2977 /* Insert this inode at the head of the on-disk orphan list */ 2978 2978 NEXT_ORPHAN(inode) = le32_to_cpu(sbi->s_es->s_last_orphan); 2979 + lock_buffer(sbi->s_sbh); 2979 2980 sbi->s_es->s_last_orphan = cpu_to_le32(inode->i_ino); 2981 + ext4_superblock_csum_set(sb); 2982 + unlock_buffer(sbi->s_sbh); 2980 2983 dirty = true; 2981 2984 } 2982 2985 list_add(&EXT4_I(inode)->i_orphan, &sbi->s_orphan); 2983 2986 mutex_unlock(&sbi->s_orphan_lock); 2984 2987 2985 2988 if (dirty) { 2986 - err = ext4_handle_dirty_super(handle, sb); 2989 + err = ext4_handle_dirty_metadata(handle, NULL, sbi->s_sbh); 2987 2990 rc = ext4_mark_iloc_dirty(handle, inode, &iloc); 2988 2991 if (!err) 2989 2992 err = rc; ··· 3062 3059 mutex_unlock(&sbi->s_orphan_lock); 3063 3060 goto out_brelse; 3064 3061 } 3062 + lock_buffer(sbi->s_sbh); 3065 3063 sbi->s_es->s_last_orphan = cpu_to_le32(ino_next); 3064 + ext4_superblock_csum_set(inode->i_sb); 3065 + unlock_buffer(sbi->s_sbh); 3066 3066 mutex_unlock(&sbi->s_orphan_lock); 3067 - err = ext4_handle_dirty_super(handle, inode->i_sb); 3067 + err = ext4_handle_dirty_metadata(handle, NULL, sbi->s_sbh); 3068 3068 } else { 3069 3069 struct ext4_iloc iloc2; 3070 3070 struct inode *i_prev = ··· 3599 3593 return retval2; 3600 3594 } 3601 3595 } 3602 - brelse(ent->bh); 3603 - ent->bh = NULL; 3604 - 3605 3596 return retval; 3606 3597 } 3607 3598 ··· 3797 3794 } 3798 3795 } 3799 3796 3797 + old_file_type = old.de->file_type; 3800 3798 if (IS_DIRSYNC(old.dir) || IS_DIRSYNC(new.dir)) 3801 3799 ext4_handle_sync(handle); 3802 3800 ··· 3825 3821 force_reread = (new.dir->i_ino == old.dir->i_ino && 3826 3822 ext4_test_inode_flag(new.dir, EXT4_INODE_INLINE_DATA)); 3827 3823 3828 - old_file_type = old.de->file_type; 3829 3824 if (whiteout) { 3830 3825 /* 3831 3826 * Do this before adding a new entry, so the old entry is sure ··· 3922 3919 retval = 0; 3923 3920 3924 3921 end_rename: 3922 + if (whiteout) { 3923 + if (retval) { 3924 + ext4_setent(handle, &old, 3925 + old.inode->i_ino, old_file_type); 3926 + drop_nlink(whiteout); 3927 + } 3928 + unlock_new_inode(whiteout); 3929 + iput(whiteout); 3930 + 3931 + } 3925 3932 brelse(old.dir_bh); 3926 3933 brelse(old.bh); 3927 3934 brelse(new.bh); 3928 - if (whiteout) { 3929 - if (retval) 3930 - drop_nlink(whiteout); 3931 - unlock_new_inode(whiteout); 3932 - iput(whiteout); 3933 - } 3934 3935 if (handle) 3935 3936 ext4_journal_stop(handle); 3936 3937 return retval;
+16 -4
fs/ext4/resize.c
··· 899 899 EXT4_SB(sb)->s_gdb_count++; 900 900 ext4_kvfree_array_rcu(o_group_desc); 901 901 902 + lock_buffer(EXT4_SB(sb)->s_sbh); 902 903 le16_add_cpu(&es->s_reserved_gdt_blocks, -1); 903 - err = ext4_handle_dirty_super(handle, sb); 904 + ext4_superblock_csum_set(sb); 905 + unlock_buffer(EXT4_SB(sb)->s_sbh); 906 + err = ext4_handle_dirty_metadata(handle, NULL, EXT4_SB(sb)->s_sbh); 904 907 if (err) 905 908 ext4_std_error(sb, err); 906 909 return err; ··· 1387 1384 reserved_blocks *= blocks_count; 1388 1385 do_div(reserved_blocks, 100); 1389 1386 1387 + lock_buffer(sbi->s_sbh); 1390 1388 ext4_blocks_count_set(es, ext4_blocks_count(es) + blocks_count); 1391 1389 ext4_free_blocks_count_set(es, ext4_free_blocks_count(es) + free_blocks); 1392 1390 le32_add_cpu(&es->s_inodes_count, EXT4_INODES_PER_GROUP(sb) * ··· 1425 1421 * active. */ 1426 1422 ext4_r_blocks_count_set(es, ext4_r_blocks_count(es) + 1427 1423 reserved_blocks); 1424 + ext4_superblock_csum_set(sb); 1425 + unlock_buffer(sbi->s_sbh); 1428 1426 1429 1427 /* Update the free space counts */ 1430 1428 percpu_counter_add(&sbi->s_freeclusters_counter, ··· 1521 1515 1522 1516 ext4_update_super(sb, flex_gd); 1523 1517 1524 - err = ext4_handle_dirty_super(handle, sb); 1518 + err = ext4_handle_dirty_metadata(handle, NULL, sbi->s_sbh); 1525 1519 1526 1520 exit_journal: 1527 1521 err2 = ext4_journal_stop(handle); ··· 1723 1717 goto errout; 1724 1718 } 1725 1719 1720 + lock_buffer(EXT4_SB(sb)->s_sbh); 1726 1721 ext4_blocks_count_set(es, o_blocks_count + add); 1727 1722 ext4_free_blocks_count_set(es, ext4_free_blocks_count(es) + add); 1723 + ext4_superblock_csum_set(sb); 1724 + unlock_buffer(EXT4_SB(sb)->s_sbh); 1728 1725 ext4_debug("freeing blocks %llu through %llu\n", o_blocks_count, 1729 1726 o_blocks_count + add); 1730 1727 /* We add the blocks to the bitmap and set the group need init bit */ 1731 1728 err = ext4_group_add_blocks(handle, sb, o_blocks_count, add); 1732 1729 if (err) 1733 1730 goto errout; 1734 - ext4_handle_dirty_super(handle, sb); 1731 + ext4_handle_dirty_metadata(handle, NULL, EXT4_SB(sb)->s_sbh); 1735 1732 ext4_debug("freed blocks %llu through %llu\n", o_blocks_count, 1736 1733 o_blocks_count + add); 1737 1734 errout: ··· 1883 1874 if (err) 1884 1875 goto errout; 1885 1876 1877 + lock_buffer(sbi->s_sbh); 1886 1878 ext4_clear_feature_resize_inode(sb); 1887 1879 ext4_set_feature_meta_bg(sb); 1888 1880 sbi->s_es->s_first_meta_bg = 1889 1881 cpu_to_le32(num_desc_blocks(sb, sbi->s_groups_count)); 1882 + ext4_superblock_csum_set(sb); 1883 + unlock_buffer(sbi->s_sbh); 1890 1884 1891 - err = ext4_handle_dirty_super(handle, sb); 1885 + err = ext4_handle_dirty_metadata(handle, NULL, sbi->s_sbh); 1892 1886 if (err) { 1893 1887 ext4_std_error(sb, err); 1894 1888 goto errout;
+118 -72
fs/ext4/super.c
··· 65 65 static int ext4_load_journal(struct super_block *, struct ext4_super_block *, 66 66 unsigned long journal_devnum); 67 67 static int ext4_show_options(struct seq_file *seq, struct dentry *root); 68 - static int ext4_commit_super(struct super_block *sb, int sync); 68 + static void ext4_update_super(struct super_block *sb); 69 + static int ext4_commit_super(struct super_block *sb); 69 70 static int ext4_mark_recovery_complete(struct super_block *sb, 70 71 struct ext4_super_block *es); 71 72 static int ext4_clear_journal_err(struct super_block *sb, ··· 587 586 return EXT4_ERR_UNKNOWN; 588 587 } 589 588 590 - static void __save_error_info(struct super_block *sb, int error, 591 - __u32 ino, __u64 block, 592 - const char *func, unsigned int line) 589 + static void save_error_info(struct super_block *sb, int error, 590 + __u32 ino, __u64 block, 591 + const char *func, unsigned int line) 593 592 { 594 593 struct ext4_sb_info *sbi = EXT4_SB(sb); 595 594 596 - EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; 597 - if (bdev_read_only(sb->s_bdev)) 598 - return; 599 595 /* We default to EFSCORRUPTED error... */ 600 596 if (error == 0) 601 597 error = EFSCORRUPTED; ··· 616 618 spin_unlock(&sbi->s_error_lock); 617 619 } 618 620 619 - static void save_error_info(struct super_block *sb, int error, 620 - __u32 ino, __u64 block, 621 - const char *func, unsigned int line) 622 - { 623 - __save_error_info(sb, error, ino, block, func, line); 624 - if (!bdev_read_only(sb->s_bdev)) 625 - ext4_commit_super(sb, 1); 626 - } 627 - 628 621 /* Deal with the reporting of failure conditions on a filesystem such as 629 622 * inconsistencies detected or read IO failures. 630 623 * ··· 636 647 * used to deal with unrecoverable failures such as journal IO errors or ENOMEM 637 648 * at a critical moment in log management. 638 649 */ 639 - static void ext4_handle_error(struct super_block *sb, bool force_ro) 650 + static void ext4_handle_error(struct super_block *sb, bool force_ro, int error, 651 + __u32 ino, __u64 block, 652 + const char *func, unsigned int line) 640 653 { 641 654 journal_t *journal = EXT4_SB(sb)->s_journal; 655 + bool continue_fs = !force_ro && test_opt(sb, ERRORS_CONT); 642 656 657 + EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; 643 658 if (test_opt(sb, WARN_ON_ERROR)) 644 659 WARN_ON_ONCE(1); 645 660 646 - if (sb_rdonly(sb) || (!force_ro && test_opt(sb, ERRORS_CONT))) 661 + if (!continue_fs && !sb_rdonly(sb)) { 662 + ext4_set_mount_flag(sb, EXT4_MF_FS_ABORTED); 663 + if (journal) 664 + jbd2_journal_abort(journal, -EIO); 665 + } 666 + 667 + if (!bdev_read_only(sb->s_bdev)) { 668 + save_error_info(sb, error, ino, block, func, line); 669 + /* 670 + * In case the fs should keep running, we need to writeout 671 + * superblock through the journal. Due to lock ordering 672 + * constraints, it may not be safe to do it right here so we 673 + * defer superblock flushing to a workqueue. 674 + */ 675 + if (continue_fs) 676 + schedule_work(&EXT4_SB(sb)->s_error_work); 677 + else 678 + ext4_commit_super(sb); 679 + } 680 + 681 + if (sb_rdonly(sb) || continue_fs) 647 682 return; 648 683 649 - ext4_set_mount_flag(sb, EXT4_MF_FS_ABORTED); 650 - if (journal) 651 - jbd2_journal_abort(journal, -EIO); 652 684 /* 653 685 * We force ERRORS_RO behavior when system is rebooting. Otherwise we 654 686 * could panic during 'reboot -f' as the underlying device got already ··· 692 682 { 693 683 struct ext4_sb_info *sbi = container_of(work, struct ext4_sb_info, 694 684 s_error_work); 685 + journal_t *journal = sbi->s_journal; 686 + handle_t *handle; 695 687 696 - ext4_commit_super(sbi->s_sb, 1); 688 + /* 689 + * If the journal is still running, we have to write out superblock 690 + * through the journal to avoid collisions of other journalled sb 691 + * updates. 692 + * 693 + * We use directly jbd2 functions here to avoid recursing back into 694 + * ext4 error handling code during handling of previous errors. 695 + */ 696 + if (!sb_rdonly(sbi->s_sb) && journal) { 697 + handle = jbd2_journal_start(journal, 1); 698 + if (IS_ERR(handle)) 699 + goto write_directly; 700 + if (jbd2_journal_get_write_access(handle, sbi->s_sbh)) { 701 + jbd2_journal_stop(handle); 702 + goto write_directly; 703 + } 704 + ext4_update_super(sbi->s_sb); 705 + if (jbd2_journal_dirty_metadata(handle, sbi->s_sbh)) { 706 + jbd2_journal_stop(handle); 707 + goto write_directly; 708 + } 709 + jbd2_journal_stop(handle); 710 + return; 711 + } 712 + write_directly: 713 + /* 714 + * Write through journal failed. Write sb directly to get error info 715 + * out and hope for the best. 716 + */ 717 + ext4_commit_super(sbi->s_sb); 697 718 } 698 719 699 720 #define ext4_error_ratelimit(sb) \ ··· 751 710 sb->s_id, function, line, current->comm, &vaf); 752 711 va_end(args); 753 712 } 754 - save_error_info(sb, error, 0, block, function, line); 755 - ext4_handle_error(sb, force_ro); 713 + ext4_handle_error(sb, force_ro, error, 0, block, function, line); 756 714 } 757 715 758 716 void __ext4_error_inode(struct inode *inode, const char *function, ··· 781 741 current->comm, &vaf); 782 742 va_end(args); 783 743 } 784 - save_error_info(inode->i_sb, error, inode->i_ino, block, 785 - function, line); 786 - ext4_handle_error(inode->i_sb, false); 744 + ext4_handle_error(inode->i_sb, false, error, inode->i_ino, block, 745 + function, line); 787 746 } 788 747 789 748 void __ext4_error_file(struct file *file, const char *function, ··· 819 780 current->comm, path, &vaf); 820 781 va_end(args); 821 782 } 822 - save_error_info(inode->i_sb, EFSCORRUPTED, inode->i_ino, block, 823 - function, line); 824 - ext4_handle_error(inode->i_sb, false); 783 + ext4_handle_error(inode->i_sb, false, EFSCORRUPTED, inode->i_ino, block, 784 + function, line); 825 785 } 826 786 827 787 const char *ext4_decode_error(struct super_block *sb, int errno, ··· 887 849 sb->s_id, function, line, errstr); 888 850 } 889 851 890 - save_error_info(sb, -errno, 0, 0, function, line); 891 - ext4_handle_error(sb, false); 852 + ext4_handle_error(sb, false, -errno, 0, 0, function, line); 892 853 } 893 854 894 855 void __ext4_msg(struct super_block *sb, ··· 981 944 if (test_opt(sb, ERRORS_CONT)) { 982 945 if (test_opt(sb, WARN_ON_ERROR)) 983 946 WARN_ON_ONCE(1); 984 - __save_error_info(sb, EFSCORRUPTED, ino, block, function, line); 985 - schedule_work(&EXT4_SB(sb)->s_error_work); 947 + EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; 948 + if (!bdev_read_only(sb->s_bdev)) { 949 + save_error_info(sb, EFSCORRUPTED, ino, block, function, 950 + line); 951 + schedule_work(&EXT4_SB(sb)->s_error_work); 952 + } 986 953 return; 987 954 } 988 955 ext4_unlock_group(sb, grp); 989 - save_error_info(sb, EFSCORRUPTED, ino, block, function, line); 990 - ext4_handle_error(sb, false); 956 + ext4_handle_error(sb, false, EFSCORRUPTED, ino, block, function, line); 991 957 /* 992 958 * We only get here in the ERRORS_RO case; relocking the group 993 959 * may be dangerous, but nothing bad will happen since the ··· 1192 1152 es->s_state = cpu_to_le16(sbi->s_mount_state); 1193 1153 } 1194 1154 if (!sb_rdonly(sb)) 1195 - ext4_commit_super(sb, 1); 1155 + ext4_commit_super(sb); 1196 1156 1197 1157 rcu_read_lock(); 1198 1158 group_desc = rcu_dereference(sbi->s_group_desc); ··· 2682 2642 if (sbi->s_journal) 2683 2643 ext4_set_feature_journal_needs_recovery(sb); 2684 2644 2685 - err = ext4_commit_super(sb, 1); 2645 + err = ext4_commit_super(sb); 2686 2646 done: 2687 2647 if (test_opt(sb, DEBUG)) 2688 2648 printk(KERN_INFO "[EXT4 FS bs=%lu, gc=%u, " ··· 4908 4868 if (DUMMY_ENCRYPTION_ENABLED(sbi) && !sb_rdonly(sb) && 4909 4869 !ext4_has_feature_encrypt(sb)) { 4910 4870 ext4_set_feature_encrypt(sb); 4911 - ext4_commit_super(sb, 1); 4871 + ext4_commit_super(sb); 4912 4872 } 4913 4873 4914 4874 /* ··· 5458 5418 es->s_journal_dev = cpu_to_le32(journal_devnum); 5459 5419 5460 5420 /* Make sure we flush the recovery flag to disk. */ 5461 - ext4_commit_super(sb, 1); 5421 + ext4_commit_super(sb); 5462 5422 } 5463 5423 5464 5424 return 0; ··· 5468 5428 return err; 5469 5429 } 5470 5430 5471 - static int ext4_commit_super(struct super_block *sb, int sync) 5431 + /* Copy state of EXT4_SB(sb) into buffer for on-disk superblock */ 5432 + static void ext4_update_super(struct super_block *sb) 5472 5433 { 5473 5434 struct ext4_sb_info *sbi = EXT4_SB(sb); 5474 - struct ext4_super_block *es = EXT4_SB(sb)->s_es; 5475 - struct buffer_head *sbh = EXT4_SB(sb)->s_sbh; 5476 - int error = 0; 5435 + struct ext4_super_block *es = sbi->s_es; 5436 + struct buffer_head *sbh = sbi->s_sbh; 5477 5437 5478 - if (!sbh || block_device_ejected(sb)) 5479 - return error; 5480 - 5438 + lock_buffer(sbh); 5481 5439 /* 5482 5440 * If the file system is mounted read-only, don't update the 5483 5441 * superblock write time. This avoids updating the superblock ··· 5489 5451 if (!(sb->s_flags & SB_RDONLY)) 5490 5452 ext4_update_tstamp(es, s_wtime); 5491 5453 es->s_kbytes_written = 5492 - cpu_to_le64(EXT4_SB(sb)->s_kbytes_written + 5454 + cpu_to_le64(sbi->s_kbytes_written + 5493 5455 ((part_stat_read(sb->s_bdev, sectors[STAT_WRITE]) - 5494 - EXT4_SB(sb)->s_sectors_written_start) >> 1)); 5495 - if (percpu_counter_initialized(&EXT4_SB(sb)->s_freeclusters_counter)) 5456 + sbi->s_sectors_written_start) >> 1)); 5457 + if (percpu_counter_initialized(&sbi->s_freeclusters_counter)) 5496 5458 ext4_free_blocks_count_set(es, 5497 - EXT4_C2B(EXT4_SB(sb), percpu_counter_sum_positive( 5498 - &EXT4_SB(sb)->s_freeclusters_counter))); 5499 - if (percpu_counter_initialized(&EXT4_SB(sb)->s_freeinodes_counter)) 5459 + EXT4_C2B(sbi, percpu_counter_sum_positive( 5460 + &sbi->s_freeclusters_counter))); 5461 + if (percpu_counter_initialized(&sbi->s_freeinodes_counter)) 5500 5462 es->s_free_inodes_count = 5501 5463 cpu_to_le32(percpu_counter_sum_positive( 5502 - &EXT4_SB(sb)->s_freeinodes_counter)); 5464 + &sbi->s_freeinodes_counter)); 5503 5465 /* Copy error information to the on-disk superblock */ 5504 5466 spin_lock(&sbi->s_error_lock); 5505 5467 if (sbi->s_add_error_count > 0) { ··· 5540 5502 } 5541 5503 spin_unlock(&sbi->s_error_lock); 5542 5504 5543 - BUFFER_TRACE(sbh, "marking dirty"); 5544 5505 ext4_superblock_csum_set(sb); 5545 - if (sync) 5546 - lock_buffer(sbh); 5506 + unlock_buffer(sbh); 5507 + } 5508 + 5509 + static int ext4_commit_super(struct super_block *sb) 5510 + { 5511 + struct buffer_head *sbh = EXT4_SB(sb)->s_sbh; 5512 + int error = 0; 5513 + 5514 + if (!sbh || block_device_ejected(sb)) 5515 + return error; 5516 + 5517 + ext4_update_super(sb); 5518 + 5547 5519 if (buffer_write_io_error(sbh) || !buffer_uptodate(sbh)) { 5548 5520 /* 5549 5521 * Oh, dear. A previous attempt to write the ··· 5568 5520 clear_buffer_write_io_error(sbh); 5569 5521 set_buffer_uptodate(sbh); 5570 5522 } 5523 + BUFFER_TRACE(sbh, "marking dirty"); 5571 5524 mark_buffer_dirty(sbh); 5572 - if (sync) { 5573 - unlock_buffer(sbh); 5574 - error = __sync_dirty_buffer(sbh, 5575 - REQ_SYNC | (test_opt(sb, BARRIER) ? REQ_FUA : 0)); 5576 - if (buffer_write_io_error(sbh)) { 5577 - ext4_msg(sb, KERN_ERR, "I/O error while writing " 5578 - "superblock"); 5579 - clear_buffer_write_io_error(sbh); 5580 - set_buffer_uptodate(sbh); 5581 - } 5525 + error = __sync_dirty_buffer(sbh, 5526 + REQ_SYNC | (test_opt(sb, BARRIER) ? REQ_FUA : 0)); 5527 + if (buffer_write_io_error(sbh)) { 5528 + ext4_msg(sb, KERN_ERR, "I/O error while writing " 5529 + "superblock"); 5530 + clear_buffer_write_io_error(sbh); 5531 + set_buffer_uptodate(sbh); 5582 5532 } 5583 5533 return error; 5584 5534 } ··· 5607 5561 5608 5562 if (ext4_has_feature_journal_needs_recovery(sb) && sb_rdonly(sb)) { 5609 5563 ext4_clear_feature_journal_needs_recovery(sb); 5610 - ext4_commit_super(sb, 1); 5564 + ext4_commit_super(sb); 5611 5565 } 5612 5566 out: 5613 5567 jbd2_journal_unlock_updates(journal); ··· 5649 5603 5650 5604 EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; 5651 5605 es->s_state |= cpu_to_le16(EXT4_ERROR_FS); 5652 - ext4_commit_super(sb, 1); 5606 + ext4_commit_super(sb); 5653 5607 5654 5608 jbd2_journal_clear_err(journal); 5655 5609 jbd2_journal_update_sb_errno(journal); ··· 5751 5705 ext4_clear_feature_journal_needs_recovery(sb); 5752 5706 } 5753 5707 5754 - error = ext4_commit_super(sb, 1); 5708 + error = ext4_commit_super(sb); 5755 5709 out: 5756 5710 if (journal) 5757 5711 /* we rely on upper layer to stop further updates */ ··· 5773 5727 ext4_set_feature_journal_needs_recovery(sb); 5774 5728 } 5775 5729 5776 - ext4_commit_super(sb, 1); 5730 + ext4_commit_super(sb); 5777 5731 return 0; 5778 5732 } 5779 5733 ··· 6033 5987 } 6034 5988 6035 5989 if (sbi->s_journal == NULL && !(old_sb_flags & SB_RDONLY)) { 6036 - err = ext4_commit_super(sb, 1); 5990 + err = ext4_commit_super(sb); 6037 5991 if (err) 6038 5992 goto restore_opts; 6039 5993 }
+4 -1
fs/ext4/xattr.c
··· 792 792 793 793 BUFFER_TRACE(EXT4_SB(sb)->s_sbh, "get_write_access"); 794 794 if (ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh) == 0) { 795 + lock_buffer(EXT4_SB(sb)->s_sbh); 795 796 ext4_set_feature_xattr(sb); 796 - ext4_handle_dirty_super(handle, sb); 797 + ext4_superblock_csum_set(sb); 798 + unlock_buffer(EXT4_SB(sb)->s_sbh); 799 + ext4_handle_dirty_metadata(handle, NULL, EXT4_SB(sb)->s_sbh); 797 800 } 798 801 } 799 802