From: Jan Kara jack@suse.cz
hulk inclusion category: bugfix bugzilla: 46758 CVE: NA ---------------------------
Protect all superblock modifications (including checksum computation) with a superblock buffer lock. That way we are sure computed checksum matches current superblock contents (a mismatch could cause checksum failures in nojournal mode or if an unjournalled superblock update races with a journalled one). Also we avoid modifying superblock contents while it is being written out (which can cause DIF/DIX failures if we are running in nojournal mode).
Signed-off-by: Jan Kara jack@suse.cz [backport the 10th patch: https://www.spinics.net/lists/linux-ext4/msg75423.html drop the other lock_buffer besides operation for orphan] Signed-off-by: yangerkun yangerkun@huawei.com Reviewed-by: zhangyi (F) yi.zhang@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- fs/ext4/ext4_jbd2.c | 1 - fs/ext4/file.c | 1 + fs/ext4/inode.c | 1 + fs/ext4/namei.c | 6 ++++++ fs/ext4/resize.c | 4 ++++ fs/ext4/xattr.c | 1 + 6 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/fs/ext4/ext4_jbd2.c b/fs/ext4/ext4_jbd2.c index a589b7f79558..f9ac7dfd93bf 100644 --- a/fs/ext4/ext4_jbd2.c +++ b/fs/ext4/ext4_jbd2.c @@ -361,7 +361,6 @@ int __ext4_handle_dirty_super(const char *where, unsigned int line, struct buffer_head *bh = EXT4_SB(sb)->s_sbh; int err = 0;
- ext4_superblock_csum_set(sb); if (ext4_handle_valid(handle)) { err = jbd2_journal_dirty_metadata(handle, bh); if (err) diff --git a/fs/ext4/file.c b/fs/ext4/file.c index 52d155b4e733..1703871fa2d0 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c @@ -434,6 +434,7 @@ static int ext4_sample_last_mounted(struct super_block *sb, goto out_journal; strlcpy(sbi->s_es->s_last_mounted, cp, sizeof(sbi->s_es->s_last_mounted)); + ext4_superblock_csum_set(sb); ext4_handle_dirty_super(handle, sb); out_journal: ext4_journal_stop(handle); diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 8d7e2cd9ae37..6ee89cd7a408 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -5398,6 +5398,7 @@ static int ext4_do_update_inode(handle_t *handle, if (err) goto out_brelse; ext4_set_feature_large_file(sb); + ext4_superblock_csum_set(sb); ext4_handle_sync(handle); err = ext4_handle_dirty_super(handle, sb); } diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index ffc3695eb153..762eb6913240 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -2889,7 +2889,10 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode) (le32_to_cpu(sbi->s_es->s_inodes_count))) { /* Insert this inode at the head of the on-disk orphan list */ NEXT_ORPHAN(inode) = le32_to_cpu(sbi->s_es->s_last_orphan); + lock_buffer(sbi->s_sbh); sbi->s_es->s_last_orphan = cpu_to_le32(inode->i_ino); + ext4_superblock_csum_set(sb); + unlock_buffer(sbi->s_sbh); dirty = true; } list_add(&EXT4_I(inode)->i_orphan, &sbi->s_orphan); @@ -2972,7 +2975,10 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode) mutex_unlock(&sbi->s_orphan_lock); goto out_brelse; } + lock_buffer(sbi->s_sbh); sbi->s_es->s_last_orphan = cpu_to_le32(ino_next); + ext4_superblock_csum_set(inode->i_sb); + unlock_buffer(sbi->s_sbh); mutex_unlock(&sbi->s_orphan_lock); err = ext4_handle_dirty_super(handle, inode->i_sb); } else { diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index 6a0c5c880354..c2e007d836e4 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c @@ -901,6 +901,7 @@ static int add_new_gdb(handle_t *handle, struct inode *inode, ext4_kvfree_array_rcu(o_group_desc);
le16_add_cpu(&es->s_reserved_gdt_blocks, -1); + ext4_superblock_csum_set(sb); err = ext4_handle_dirty_super(handle, sb); if (err) ext4_std_error(sb, err); @@ -1423,6 +1424,7 @@ static void ext4_update_super(struct super_block *sb, * active. */ ext4_r_blocks_count_set(es, ext4_r_blocks_count(es) + reserved_blocks); + ext4_superblock_csum_set(sb);
/* Update the free space counts */ percpu_counter_add(&sbi->s_freeclusters_counter, @@ -1721,6 +1723,7 @@ static int ext4_group_extend_no_check(struct super_block *sb,
ext4_blocks_count_set(es, o_blocks_count + add); ext4_free_blocks_count_set(es, ext4_free_blocks_count(es) + add); + ext4_superblock_csum_set(sb); ext4_debug("freeing blocks %llu through %llu\n", o_blocks_count, o_blocks_count + add); /* We add the blocks to the bitmap and set the group need init bit */ @@ -1882,6 +1885,7 @@ static int ext4_convert_meta_bg(struct super_block *sb, struct inode *inode) ext4_set_feature_meta_bg(sb); sbi->s_es->s_first_meta_bg = cpu_to_le32(num_desc_blocks(sb, sbi->s_groups_count)); + ext4_superblock_csum_set(sb);
err = ext4_handle_dirty_super(handle, sb); if (err) { diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 24cf730ba6b0..ae029dccebc1 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -791,6 +791,7 @@ static void ext4_xattr_update_super_block(handle_t *handle, BUFFER_TRACE(EXT4_SB(sb)->s_sbh, "get_write_access"); if (ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh) == 0) { ext4_set_feature_xattr(sb); + ext4_superblock_csum_set(sb); ext4_handle_dirty_super(handle, sb); } }
From: Chenguangli chenguangli2@huawei.com
driver inclusion category: bug bugzilla: NA
------------------------------------------------------------------
Resolved the issue that the system is suspended due to log screen flushing during the pressure test.
Signed-off-by: Chenguangli chenguangli2@huawei.com Reviewed-by: Zengweiliang zengweiliang.zengweiliang@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- drivers/scsi/huawei/hifc/unf_common.h | 2 +- drivers/scsi/huawei/hifc/unf_log.h | 2 +- drivers/scsi/huawei/hifc/unf_service.c | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/huawei/hifc/unf_common.h b/drivers/scsi/huawei/hifc/unf_common.h index c338ef1c7e4e..2793acb5dea7 100644 --- a/drivers/scsi/huawei/hifc/unf_common.h +++ b/drivers/scsi/huawei/hifc/unf_common.h @@ -13,7 +13,7 @@ /* B version, B0XX Corresponding x.x */ #define UNF_B_VERSION "5.0" /* Indicates the minor version number of the driver */ -#define UNF_DRIVER_VERSION "9" +#define UNF_DRIVER_VERSION "10" /* version num */ #define UNF_FC_VERSION UNF_MAJOR_VERSION "." UNF_B_VERSION "." UNF_DRIVER_VERSION extern unsigned int unf_dbg_level; diff --git a/drivers/scsi/huawei/hifc/unf_log.h b/drivers/scsi/huawei/hifc/unf_log.h index a46a77a42ded..1da7ab821b10 100644 --- a/drivers/scsi/huawei/hifc/unf_log.h +++ b/drivers/scsi/huawei/hifc/unf_log.h @@ -58,7 +58,7 @@ enum event_log_e { #define UNF_IO_ATT_PRINT_TIMES 2 #define UNF_LOGIN_ATT_PRINT_TIMES 100
-#define UNF_IO_ATT_PRINT_LIMIT msecs_to_jiffies(2 * 1000) +#define UNF_IO_ATT_PRINT_LIMIT msecs_to_jiffies(6 * 1000)
extern unsigned int unf_dbg_level; extern unsigned int log_print_level; diff --git a/drivers/scsi/huawei/hifc/unf_service.c b/drivers/scsi/huawei/hifc/unf_service.c index 263d5b43fc99..ec6e3fa96a47 100644 --- a/drivers/scsi/huawei/hifc/unf_service.c +++ b/drivers/scsi/huawei/hifc/unf_service.c @@ -2074,6 +2074,9 @@ unsigned int unf_send_rrq(struct unf_lport_s *v_lport, UNF_CHECK_VALID(0x3363, UNF_TRUE, v_rport, return UNF_RETURN_ERROR); UNF_CHECK_VALID(0x3364, UNF_TRUE, v_xchg, return UNF_RETURN_ERROR);
+ if (v_xchg->rport_bind_jifs != v_rport->rport_alloc_jifs || + (v_rport->nport_id == INVALID_VALUE32)) + return ret; /* Get & Set New free Exchange for RRQ */ xchg = unf_get_sfs_free_xchg_and_init(v_lport, v_rport->nport_id, v_rport, &fc_entry);