This patch set fix some growfs problems:
Long Li (1): xfs: fix dir3 block read verify fail during log recover
Wu Guanghao (1): xfs: fix the problem of mount failure caused by not refreshing mp->m_sb
yangerkun (2): xfs: fix mounting failed caused by sequencing problem in the log records xfs: keep growfs sb log item active until ail flush success
fs/xfs/libxfs/xfs_log_recover.h | 1 + fs/xfs/xfs_buf_item.c | 2 +- fs/xfs/xfs_buf_item.h | 8 +++++++- fs/xfs/xfs_buf_item_recover.c | 36 +++++++++++++++++++++++++++------ fs/xfs/xfs_log_recover.c | 26 +++++++++++++++++++++--- fs/xfs/xfs_trans.c | 8 ++++++++ 6 files changed, 70 insertions(+), 11 deletions(-)
From: Wu Guanghao wuguanghao3@huawei.com
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I8LHTR CVE: NA
--------------------------------
After testing xfs_growfs + fsstress + fault injection, the following stack appeared when mounting the filesystem:
[ 149.902032] XFS (loop0): xfs_buf_map_verify: daddr 0x200001 out of range, EOFS 0x200000 [ 149.902072] WARNING: CPU: 12 PID: 3045 at fs/xfs/xfs_buf.c:535 xfs_buf_get_map+0x5ae/0x650 [xfs] ... [ 149.902473] xfs_buf_read_map+0x59/0x330 [xfs] [ 149.902621] ? xlog_recover_items_pass2+0x55/0xd0 [xfs] [ 149.902809] xlog_recover_buf_commit_pass2+0xff/0x640 [xfs] [ 149.902959] ? xlog_recover_items_pass2+0x55/0xd0 [xfs] [ 149.903104] xlog_recover_items_pass2+0x55/0xd0 [xfs] [ 149.903247] xlog_recover_commit_trans+0x2e0/0x330 [xfs] [ 149.903390] xlog_recovery_process_trans+0x8e/0xf0 [xfs] [ 149.903531] xlog_recover_process_data+0x9c/0x130 [xfs] [ 149.903687] xlog_do_recovery_pass+0x3cc/0x5d0 [xfs] [ 149.903843] xlog_do_log_recovery+0x5c/0x80 [xfs] [ 149.903984] xlog_do_recover+0x33/0x1c0 [xfs] [ 149.904125] xlog_recover+0xdd/0x190 [xfs] [ 149.904265] xfs_log_mount+0x125/0x2f0 [xfs] [ 149.904410] xfs_mountfs+0x41a/0x910 [xfs] [ 149.904558] ? __pfx_xfs_fstrm_free_func+0x10/0x10 [xfs] [ 149.904725] xfs_fs_fill_super+0x4b7/0x940 [xfs] [ 149.904873] ? __pfx_xfs_fs_fill_super+0x10/0x10 [xfs] [ 149.905016] get_tree_bdev+0x19a/0x280 [ 149.905020] vfs_get_tree+0x29/0xd0 [ 149.905023] path_mount+0x69e/0x9b0 [ 149.905026] do_mount+0x7d/0xa0 [ 149.905029] __x64_sys_mount+0xdc/0x100 [ 149.905032] do_syscall_64+0x3e/0x90 [ 149.905035] entry_SYSCALL_64_after_hwframe+0x72/0xdc
The trigger process is as follows:
1. Growfs size from 0x200000 to 0x300000 2. Using the space range of 0x200000~0x300000 3. The above operations have only been written to the log area on disk 4. Fault injection and shutdown filesystem 5. Mount the filesystem and replay the log about growfs, but only modify the superblock buffer without modifying the mp->m_sb structure in memory 6. Continuing the log replay, at this point we are replaying operation 2, then it was discovered that the blocks used more than mp->m_sb.sb_dblocks
Therefore, during log replay, if there are any modifications made to the superblock, we should refresh the information recorded in the mp->m_sb.
Signed-off-by: Wu Guanghao wuguanghao3@huawei.com Signed-off-by: Zhihao Cheng chengzhihao1@huawei.com Signed-off-by: Long Li leo.lilong@huawei.com --- fs/xfs/xfs_buf_item_recover.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+)
diff --git a/fs/xfs/xfs_buf_item_recover.c b/fs/xfs/xfs_buf_item_recover.c index 43167f543afc..e98cf3e97593 100644 --- a/fs/xfs/xfs_buf_item_recover.c +++ b/fs/xfs/xfs_buf_item_recover.c @@ -22,6 +22,8 @@ #include "xfs_inode.h" #include "xfs_dir2.h" #include "xfs_quota.h" +#include "xfs_sb.h" +#include "xfs_ag.h"
/* * This is the number of entries in the l_buf_cancel_table used during @@ -969,6 +971,29 @@ xlog_recover_buf_commit_pass2( goto out_release; } else { xlog_recover_do_reg_buffer(mp, item, bp, buf_f, current_lsn); + /* + * If the superblock buffer is modified, we also need to modify the + * content of the mp. + */ + if (bp->b_maps[0].bm_bn == XFS_SB_DADDR && bp->b_ops) { + struct xfs_dsb *sb = bp->b_addr; + + bp->b_ops->verify_write(bp); + error = bp->b_error; + if (error) + goto out_release; + + if (be32_to_cpu(sb->sb_agcount) > mp->m_sb.sb_agcount) { + error = xfs_initialize_perag(mp, + be32_to_cpu(sb->sb_agcount), + be64_to_cpu(sb->sb_dblocks), + &mp->m_maxagi); + if (error) + goto out_release; + } + + xfs_sb_from_disk(&mp->m_sb, sb); + } }
/*
From: yangerkun yangerkun@huawei.com
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I8LHTR CVE: NA
--------------------------------
During the test of growfs + power-off, we encountered a mounting failure issue. The specific call stack is as follows:
[584505.210179] XFS (loop0): xfs_buf_find: daddr 0x6d6002 out of range, EOFS 0x6d6000 ... [584505.210739] Call Trace: [584505.210776] xfs_buf_get_map+0x44/0x230 [xfs] [584505.210780] ? trace_event_buffer_commit+0x57/0x140 [584505.210818] xfs_buf_read_map+0x54/0x280 [xfs] [584505.210858] ? xlog_recover_items_pass2+0x53/0xb0 [xfs] [584505.210899] xlog_recover_buf_commit_pass2+0x112/0x440 [xfs] [584505.210939] ? xlog_recover_items_pass2+0x53/0xb0 [xfs] [584505.210980] xlog_recover_items_pass2+0x53/0xb0 [xfs] [584505.211020] xlog_recover_commit_trans+0x2ca/0x320 [xfs] [584505.211061] xlog_recovery_process_trans+0xc6/0xf0 [xfs] [584505.211101] xlog_recover_process_data+0x9e/0x110 [xfs] [584505.211141] xlog_do_recovery_pass+0x3b4/0x5c0 [xfs] [584505.211181] xlog_do_log_recovery+0x5e/0x80 [xfs] [584505.211223] xlog_do_recover+0x33/0x1a0 [xfs] [584505.211262] xlog_recover+0xd7/0x170 [xfs] [584505.211303] xfs_log_mount+0x217/0x2b0 [xfs] [584505.211341] xfs_mountfs+0x3da/0x870 [xfs] [584505.211384] xfs_fc_fill_super+0x3fa/0x7a0 [xfs] [584505.211428] ? xfs_setup_devices+0x80/0x80 [xfs] [584505.211432] get_tree_bdev+0x16f/0x260 [584505.211434] vfs_get_tree+0x25/0xc0 [584505.211436] do_new_mount+0x156/0x1b0 [584505.211438] __se_sys_mount+0x165/0x1d0 [584505.211440] do_syscall_64+0x33/0x40 [584505.211442] entry_SYSCALL_64_after_hwframe+0x61/0xc6
After analyzing the log records, we have discovered the following content:
============================================================================ cycle: 173 version: 2 lsn: 173,2742 tail_lsn: 173,1243 length of Log Record: 25600 prev offset: 2702 num ops: 258 uuid: fb958458-48a3-4c76-ae23-7a1cf3053065 format: little endian linux h_size: 32768 ---------------------------------------------------------------------------- ... ---------------------------------------------------------------------------- Oper (100): tid: 1c010724 len: 24 clientid: TRANS flags: none BUF: #regs: 2 start blkno: 7168002 (0x6d6002) len: 1 bmap size: 1 flags: 0x3800 Oper (101): tid: 1c010724 len: 128 clientid: TRANS flags: none AGI Buffer: XAGI ver: 1 seq#: 28 len: 2048 cnt: 0 root: 3 level: 1 free#: 0x0 newino: 0x140 bucket[0 - 3]: 0xffffffff 0xffffffff 0xffffffff 0xffffffff bucket[4 - 7]: 0xffffffff 0xffffffff 0xffffffff 0xffffffff bucket[8 - 11]: 0xffffffff 0xffffffff 0xffffffff 0xffffffff bucket[12 - 15]: 0xffffffff 0xffffffff 0xffffffff 0xffffffff bucket[16 - 19]: 0xffffffff ---------------------------------------------------------------------------- ... ---------------------------------------------------------------------------- Oper (108): tid: 1c010724 len: 24 clientid: TRANS flags: none BUF: #regs: 2 start blkno: 0 (0x0) len: 1 bmap size: 1 flags: 0x9000 Oper (109): tid: 1c010724 len: 384 clientid: TRANS flags: none SUPER BLOCK Buffer: icount: 6360863066640355328 ifree: 898048 fdblks: 0 frext: 0 ---------------------------------------------------------------------------- ...
We found that in the log records, the modification transaction for the expanded block is before the growfs transaction, which leads to verification failure during log replay.
We need to ensure that when replaying logs, transactions related to the superblock are replayed first.
Signed-off-by: Wu Guanghao wuguanghao3@huawei.com Signed-off-by: yangerkun yangerkun@huawei.com Signed-off-by: Long Li leo.lilong@huawei.com --- fs/xfs/libxfs/xfs_log_recover.h | 1 + fs/xfs/xfs_buf_item_recover.c | 2 ++ fs/xfs/xfs_log_recover.c | 26 +++++++++++++++++++++++--- 3 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/fs/xfs/libxfs/xfs_log_recover.h b/fs/xfs/libxfs/xfs_log_recover.h index a5100a11faf9..1190537d02b7 100644 --- a/fs/xfs/libxfs/xfs_log_recover.h +++ b/fs/xfs/libxfs/xfs_log_recover.h @@ -18,6 +18,7 @@ enum xlog_recover_reorder { XLOG_REORDER_ITEM_LIST, XLOG_REORDER_INODE_BUFFER_LIST, XLOG_REORDER_CANCEL_LIST, + XLOG_REORDER_SB_BUFFER_LIST, };
struct xlog_recover_item_ops { diff --git a/fs/xfs/xfs_buf_item_recover.c b/fs/xfs/xfs_buf_item_recover.c index e98cf3e97593..6b8d81e5cc57 100644 --- a/fs/xfs/xfs_buf_item_recover.c +++ b/fs/xfs/xfs_buf_item_recover.c @@ -162,6 +162,8 @@ xlog_recover_buf_reorder( return XLOG_REORDER_CANCEL_LIST; if (buf_f->blf_flags & XFS_BLF_INODE_BUF) return XLOG_REORDER_INODE_BUFFER_LIST; + if (buf_f->blf_blkno == XFS_SB_DADDR) + return XLOG_REORDER_SB_BUFFER_LIST; return XLOG_REORDER_BUFFER_LIST; }
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index a1e18b24971a..7606ce475088 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -1900,6 +1900,9 @@ xlog_recover_reorder_trans( case XLOG_REORDER_BUFFER_LIST: list_move_tail(&item->ri_list, &buffer_list); break; + case XLOG_REORDER_SB_BUFFER_LIST: + list_move(&item->ri_list, &buffer_list); + break; case XLOG_REORDER_CANCEL_LIST: trace_xfs_log_recover_item_reorder_head(log, trans, item, pass); @@ -1963,6 +1966,25 @@ xlog_recover_items_pass2( return error; }
+#define XLOG_RECOVER_COMMIT_QUEUE_MAX 100 +static inline bool +xlog_recover_should_pass2( + struct xlog_recover_item *item, + int items_queued) +{ + struct xfs_buf_log_format *buf_f; + + if (items_queued >= XLOG_RECOVER_COMMIT_QUEUE_MAX) + return true; + if (ITEM_TYPE(item) == XFS_LI_BUF) { + buf_f = item->ri_buf[0].i_addr; + if (buf_f->blf_blkno == XFS_SB_DADDR) + return true; + } + + return false; +} + /* * Perform the transaction. * @@ -1983,8 +2005,6 @@ xlog_recover_commit_trans( LIST_HEAD (ra_list); LIST_HEAD (done_list);
- #define XLOG_RECOVER_COMMIT_QUEUE_MAX 100 - hlist_del_init(&trans->r_list);
error = xlog_recover_reorder_trans(log, trans, pass); @@ -2004,7 +2024,7 @@ xlog_recover_commit_trans( item->ri_ops->ra_pass2(log, item); list_move_tail(&item->ri_list, &ra_list); items_queued++; - if (items_queued >= XLOG_RECOVER_COMMIT_QUEUE_MAX) { + if (xlog_recover_should_pass2(item, items_queued)) { error = xlog_recover_items_pass2(log, trans, buffer_list, &ra_list); list_splice_tail_init(&ra_list, &done_list);
From: yangerkun yangerkun@huawei.com
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I8LHTR CVE: NA
--------------------------------
Our growfs test trigger mount error show as below:
[ 40.100164] ------------[ cut here ]------------ [ 40.101808] WARNING: CPU: 5 PID: 769 at fs/xfs/xfs_buf.c:615 xfs_buf_find+0x40d/0x510 ... [ 40.127061] Call Trace: [ 40.127502] xfs_buf_get_map+0x45/0x240 [ 40.128205] xfs_buf_read_map+0x54/0x230 [ 40.129854] xlog_recover_buf_commit_pass2+0x14e/0x490 [ 40.131743] xlog_recover_items_pass2+0x4d/0xa0 [ 40.132605] xlog_recover_commit_trans+0x325/0x350 [ 40.133496] xlog_recovery_process_trans+0xa7/0xe0 [ 40.134408] xlog_recover_process_data+0x8e/0x130 [ 40.135288] xlog_do_recovery_pass+0x3a4/0x730 [ 40.136874] xlog_do_log_recovery+0x62/0xb0 [ 40.137672] xlog_do_recover+0x34/0x1b0 [ 40.138392] xlog_recover+0xd9/0x170 [ 40.139072] xfs_log_mount+0x17f/0x2e0 [ 40.139790] xfs_mountfs+0x3de/0x8a0 [ 40.140473] xfs_fc_fill_super+0x485/0x7f0 [ 40.142095] get_tree_bdev+0x169/0x260 [ 40.142771] vfs_get_tree+0x1f/0xb0 [ 40.143438] do_new_mount+0x15e/0x2d0 [ 40.144141] __x64_sys_mount+0x101/0x140 [ 40.144900] do_syscall_64+0x2d/0x40 [ 40.145591] entry_SYSCALL_64_after_hwframe+0x61/0xc6 ... [ 40.158456] ---[ end trace 0fa38b12a77950ba ]--- [ 40.159354] XFS (loop0): log mount/recovery failed: error -117 [ 40.160956] XFS (loop0): log mount failed
---------------------------> time line +-------------------+----------------+------------------+ | growfs sb item ...|new agi item ...|growfs sb item ...| SHUTDOWN +-------------------+----------------+------------------+ CTX1 CTX2 CTX3
The testcase do multi growfs and then fail the IO which shutdown the xfs. Like the upper order, CTX1 add a new ag, CTX2 may log the agi, CTX3 will do another gorwfs. The sb item may still exist in ail after CTX3 iclog bio success, then the item lsn will change, which may change the tail_lsn.
Then, when we mount the img, and when we recover CTX2, the read for new agi will fail since the ag number still keep invalid.
Fix it by pin the sb lsn as CTX1, and then mount will first replay CTX1.
Signed-off-by: yangerkun yangerkun@huawei.com Signed-off-by: Long Li leo.lilong@huawei.com --- fs/xfs/xfs_buf_item.c | 2 +- fs/xfs/xfs_buf_item.h | 8 +++++++- fs/xfs/xfs_trans.c | 8 ++++++++ 3 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index 023d4e0385dd..f782363cdb38 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c @@ -776,7 +776,7 @@ xfs_buf_item_committed(
trace_xfs_buf_item_committed(bip);
- if ((bip->bli_flags & XFS_BLI_INODE_ALLOC_BUF) && lip->li_lsn != 0) + if ((bip->bli_flags & XFS_BLI_KEEP_LSN) && lip->li_lsn != 0) return lip->li_lsn; return lsn; } diff --git a/fs/xfs/xfs_buf_item.h b/fs/xfs/xfs_buf_item.h index 4d8a6aece995..51e8ec085786 100644 --- a/fs/xfs/xfs_buf_item.h +++ b/fs/xfs/xfs_buf_item.h @@ -20,6 +20,11 @@ struct xfs_mount; #define XFS_BLI_STALE_INODE (1u << 5) #define XFS_BLI_INODE_BUF (1u << 6) #define XFS_BLI_ORDERED (1u << 7) +#define XFS_BLI_GROW_SB_BUF (1u << 8) + +#define XFS_BLI_KEEP_LSN \ + (XFS_BLI_INODE_ALLOC_BUF | \ + XFS_BLI_GROW_SB_BUF)
#define XFS_BLI_FLAGS \ { XFS_BLI_HOLD, "HOLD" }, \ @@ -29,7 +34,8 @@ struct xfs_mount; { XFS_BLI_INODE_ALLOC_BUF, "INODE_ALLOC" }, \ { XFS_BLI_STALE_INODE, "STALE_INODE" }, \ { XFS_BLI_INODE_BUF, "INODE_BUF" }, \ - { XFS_BLI_ORDERED, "ORDERED" } + { XFS_BLI_ORDERED, "ORDERED" }, \ + { XFS_BLI_GROW_SB_BUF, "GROW_SB" }
/* * This is the in core log item structure used to track information diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 8c0bfc9a33b1..1ec339ca5053 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -24,6 +24,7 @@ #include "xfs_dquot_item.h" #include "xfs_dquot.h" #include "xfs_icache.h" +#include "xfs_buf_item.h"
struct kmem_cache *xfs_trans_cache;
@@ -476,9 +477,12 @@ xfs_trans_apply_sb_deltas( { struct xfs_dsb *sbp; struct xfs_buf *bp; + struct xfs_buf_log_item *bip; int whole = 0; + int grow = 0;
bp = xfs_trans_getsb(tp); + bip = bp->b_log_item; sbp = bp->b_addr;
/* @@ -524,10 +528,12 @@ xfs_trans_apply_sb_deltas( if (tp->t_dblocks_delta) { be64_add_cpu(&sbp->sb_dblocks, tp->t_dblocks_delta); whole = 1; + grow = 1; } if (tp->t_agcount_delta) { be32_add_cpu(&sbp->sb_agcount, tp->t_agcount_delta); whole = 1; + grow = 1; } if (tp->t_imaxpct_delta) { sbp->sb_imax_pct += tp->t_imaxpct_delta; @@ -555,6 +561,8 @@ xfs_trans_apply_sb_deltas( }
xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SB_BUF); + if (grow) + bip->bli_flags |= XFS_BLI_GROW_SB_BUF; if (whole) /* * Log the whole thing, the fields are noncontiguous.
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I8LHTR CVE: NA
--------------------------------
Our growfs test trigger mount error show as below:
XFS (dm-3): Starting recovery (logdev: internal) XFS (dm-3): Internal error !ino_ok at line 201 of file fs/xfs/libxfs/xfs_dir2.c. Caller xfs_dir_ino_validate+0x54/0xc0 [xfs] CPU: 0 PID: 3719345 Comm: mount Kdump: loaded Not tainted 5.10.0-136.12.0.86.h1036.kasan.eulerosv2r12.aarch64 #1 Hardware name: QEMU KVM Virtual Machine, BIOS 0.0.0 02/06/2015 Call trace: dump_backtrace+0x0/0x3a4 show_stack+0x34/0x4c dump_stack+0x170/0x1dc xfs_corruption_error+0x104/0x11c [xfs] xfs_dir_ino_validate+0x8c/0xc0 [xfs] __xfs_dir3_data_check+0x5e4/0xb60 [xfs] xfs_dir3_block_verify+0x108/0x190 [xfs] xfs_dir3_block_read_verify+0x10c/0x184 [xfs] xlog_recover_buf_commit_pass2+0x388/0x8e0 [xfs] xlog_recover_items_pass2+0xc8/0x160 [xfs] xlog_recover_commit_trans+0x56c/0x58c [xfs] xlog_recovery_process_trans+0x174/0x180 [xfs] xlog_recover_process_ophdr+0x120/0x210 [xfs] xlog_recover_process_data+0xcc/0x1b4 [xfs] xlog_recover_process+0x124/0x25c [xfs] xlog_do_recovery_pass+0x534/0x864 [xfs] xlog_do_log_recovery+0x98/0xc4 [xfs] xlog_do_recover+0x64/0x2ec [xfs] xlog_recover+0x1c4/0x2f0 [xfs] xfs_log_mount+0x1b8/0x550 [xfs] xfs_mountfs+0x768/0xe40 [xfs] xfs_fc_fill_super+0xb54/0xeb0 [xfs] get_tree_bdev+0x240/0x3e0 xfs_fc_get_tree+0x30/0x40 [xfs] vfs_get_tree+0x5c/0x1a4 do_new_mount+0x1c8/0x220 path_mount+0x2a8/0x3f0 __arm64_sys_mount+0x1cc/0x220 el0_svc_common.constprop.0+0xc0/0x2c4 do_el0_svc+0xb4/0xec el0_svc+0x24/0x3c el0_sync_handler+0x160/0x164 el0_sync+0x160/0x180 XFS (dm-3): Corruption detected. Unmount and run xfs_repair XFS (dm-3): Invalid inode number 0xd00082 XFS (dm-3): Metadata corruption detected at __xfs_dir3_data_check+0xa08/0xb60 [xfs], xfs_dir3_block block 0x100070 XFS (dm-3): Unmount and run xfs_repair XFS (dm-3): First 128 bytes of corrupted metadata buffer: 00000000: 58 44 42 33 f3 c3 ae cf 00 00 00 00 00 10 00 70 XDB3...........p 00000010: 00 00 00 01 00 00 0c 3e 85 a6 68 6c 63 b3 42 30 .......>..hlc.B0 00000020: b0 6b d1 b5 9d eb 55 7d 00 00 00 00 00 10 00 90 .k....U}........ 00000030: 03 60 0b 78 01 40 00 40 00 b0 00 40 00 00 00 00 .`.x.@.@...@.... 00000040: 00 00 00 00 00 10 00 90 01 2e 02 00 00 00 00 40 ...............@ 00000050: 00 00 00 00 00 10 00 81 02 2e 2e 02 00 00 00 50 ...............P 00000060: 00 00 00 00 00 10 00 91 02 66 65 01 00 00 00 60 .........fe....` 00000070: 00 00 00 00 00 10 00 92 02 66 66 01 00 00 00 70 .........ff....p
Consider the following log format, dir3 block has 2 items in the log, and the inode number recorded ondisk in diri3 block exceeds the current file system boundary. When replaying log items, it will skipping replay of first dir3 buffer log item due to the log item LSN being behind the ondisk buffer, but verification is still required. Since the superblock hasn't been replayed yet, the inode number in dir3 block exceeds the file system boundary and causes log recovery to fail.
log record: +---------------+----------------+--------------+-------------------+ | dir3 buf item | growfs sb item | inode item | dir3 buf item .. | +---------------+----------------+--------------+-------------------+ lsn X lsn X+A lsn X+A+B lsn X+A+B+C
metadata block: +-----------+-----------+------------+-----------+-----------+ | sb block | ... | dir3 block | ... | inodes | +-----------+-----------+------------+-----------+-----------+ lsn < X lsn X+A+B+C
Remove buffer read verify during log recovry pass2, clear buffer's XBF_DONE flag, so it can be verified in the next buf read after log recover.
Fixes: 22ed903eee23 ("xfs: verify buffer contents when we skip log replay") Signed-off-by: Long Li leo.lilong@huawei.com --- fs/xfs/xfs_buf_item_recover.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/fs/xfs/xfs_buf_item_recover.c b/fs/xfs/xfs_buf_item_recover.c index 6b8d81e5cc57..2383cc2d0354 100644 --- a/fs/xfs/xfs_buf_item_recover.c +++ b/fs/xfs/xfs_buf_item_recover.c @@ -950,13 +950,10 @@ xlog_recover_buf_commit_pass2(
/* * We're skipping replay of this buffer log item due to the log - * item LSN being behind the ondisk buffer. Verify the buffer - * contents since we aren't going to run the write verifier. + * item LSN being behind the ondisk buffer. clear XBF_DONE flag + * of the buffer to prevent buffer from being used without verify. */ - if (bp->b_ops) { - bp->b_ops->verify_read(bp); - error = bp->b_error; - } + bp->b_flags &= ~XBF_DONE; goto out_release; }
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/3397 邮件列表地址:https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/6...
FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/3397 Mailing list address: https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/6...