]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-4.14/f2fs-fix-to-do-sanity-check-with-current-segment-num.patch
autosel patches for 4.14
[thirdparty/kernel/stable-queue.git] / queue-4.14 / f2fs-fix-to-do-sanity-check-with-current-segment-num.patch
1 From a0e6e9405f2500924e7c3cf9a07d83a5120cb7fc Mon Sep 17 00:00:00 2001
2 From: Chao Yu <yuchao0@huawei.com>
3 Date: Thu, 6 Sep 2018 20:34:12 +0800
4 Subject: f2fs: fix to do sanity check with current segment number
5
6 [ Upstream commit 042be0f849e5fc24116d0afecfaf926eed5cac63 ]
7
8 https://bugzilla.kernel.org/show_bug.cgi?id=200219
9
10 Reproduction way:
11 - mount image
12 - run poc code
13 - umount image
14
15 F2FS-fs (loop1): Bitmap was wrongly set, blk:15364
16 ------------[ cut here ]------------
17 kernel BUG at /home/yuchao/git/devf2fs/segment.c:2061!
18 invalid opcode: 0000 [#1] PREEMPT SMP
19 CPU: 2 PID: 17686 Comm: umount Tainted: G W O 4.18.0-rc2+ #39
20 Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
21 EIP: update_sit_entry+0x459/0x4e0 [f2fs]
22 Code: e8 1c b5 fd ff 0f 0b 0f 0b 8b 45 e4 c7 44 24 08 9c 7a 6c f8 c7 44 24 04 bc 4a 6c f8 89 44 24 0c 8b 06 89 04 24 e8 f7 b4 fd ff <0f> 0b 8b 45 e4 0f b6 d2 89 54 24 10 c7 44 24 08 60 7a 6c f8 c7 44
23 EAX: 00000032 EBX: 000000f8 ECX: 00000002 EDX: 00000001
24 ESI: d7177000 EDI: f520fe68 EBP: d6477c6c ESP: d6477c34
25 DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 EFLAGS: 00010282
26 CR0: 80050033 CR2: b7fbe000 CR3: 2a99b3c0 CR4: 000406f0
27 Call Trace:
28 f2fs_allocate_data_block+0x124/0x580 [f2fs]
29 do_write_page+0x78/0x150 [f2fs]
30 f2fs_do_write_node_page+0x25/0xa0 [f2fs]
31 __write_node_page+0x2bf/0x550 [f2fs]
32 f2fs_sync_node_pages+0x60e/0x6d0 [f2fs]
33 ? sync_inode_metadata+0x2f/0x40
34 ? f2fs_write_checkpoint+0x28f/0x7d0 [f2fs]
35 ? up_write+0x1e/0x80
36 f2fs_write_checkpoint+0x2a9/0x7d0 [f2fs]
37 ? mark_held_locks+0x5d/0x80
38 ? _raw_spin_unlock_irq+0x27/0x50
39 kill_f2fs_super+0x68/0x90 [f2fs]
40 deactivate_locked_super+0x3d/0x70
41 deactivate_super+0x40/0x60
42 cleanup_mnt+0x39/0x70
43 __cleanup_mnt+0x10/0x20
44 task_work_run+0x81/0xa0
45 exit_to_usermode_loop+0x59/0xa7
46 do_fast_syscall_32+0x1f5/0x22c
47 entry_SYSENTER_32+0x53/0x86
48 EIP: 0xb7f95c51
49 Code: c1 1e f7 ff ff 89 e5 8b 55 08 85 d2 8b 81 64 cd ff ff 74 02 89 02 5d c3 8b 0c 24 c3 8b 1c 24 c3 90 51 52 55 89 e5 0f 34 cd 80 <5d> 5a 59 c3 90 90 90 90 8d 76 00 58 b8 77 00 00 00 cd 80 90 8d 76
50 EAX: 00000000 EBX: 0871ab90 ECX: bfb2cd00 EDX: 00000000
51 ESI: 00000000 EDI: 0871ab90 EBP: 0871ab90 ESP: bfb2cd7c
52 DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 007b EFLAGS: 00000246
53 Modules linked in: f2fs(O) crc32_generic bnep rfcomm bluetooth ecdh_generic snd_intel8x0 snd_ac97_codec ac97_bus snd_pcm snd_seq_midi snd_seq_midi_event snd_rawmidi snd_seq pcbc joydev aesni_intel snd_seq_device aes_i586 snd_timer crypto_simd snd cryptd soundcore mac_hid serio_raw video i2c_piix4 parport_pc ppdev lp parport hid_generic psmouse usbhid hid e1000 [last unloaded: f2fs]
54 ---[ end trace d423f83982cfcdc5 ]---
55
56 The reason is, different log headers using the same segment, once
57 one log's next block address is used by another log, it will cause
58 panic as above.
59
60 Main area: 24 segs, 24 secs 24 zones
61 - COLD data: 0, 0, 0
62 - WARM data: 1, 1, 1
63 - HOT data: 20, 20, 20
64 - Dir dnode: 22, 22, 22
65 - File dnode: 22, 22, 22
66 - Indir nodes: 21, 21, 21
67
68 So this patch adds sanity check to detect such condition to avoid
69 this issue.
70
71 Signed-off-by: Chao Yu <yuchao0@huawei.com>
72
73 Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
74
75 Signed-off-by: Sasha Levin <sashal@kernel.org>
76 ---
77 fs/f2fs/super.c | 34 +++++++++++++++++++++++++++++++++-
78 1 file changed, 33 insertions(+), 1 deletion(-)
79
80 diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
81 index fc5c41257e68..4c169ba50c0f 100644
82 --- a/fs/f2fs/super.c
83 +++ b/fs/f2fs/super.c
84 @@ -1959,7 +1959,7 @@ int sanity_check_ckpt(struct f2fs_sb_info *sbi)
85 unsigned int segment_count_main;
86 unsigned int cp_pack_start_sum, cp_payload;
87 block_t user_block_count;
88 - int i;
89 + int i, j;
90
91 total = le32_to_cpu(raw_super->segment_count);
92 fsmeta = le32_to_cpu(raw_super->segment_count_ckpt);
93 @@ -2000,11 +2000,43 @@ int sanity_check_ckpt(struct f2fs_sb_info *sbi)
94 if (le32_to_cpu(ckpt->cur_node_segno[i]) >= main_segs ||
95 le16_to_cpu(ckpt->cur_node_blkoff[i]) >= blocks_per_seg)
96 return 1;
97 + for (j = i + 1; j < NR_CURSEG_NODE_TYPE; j++) {
98 + if (le32_to_cpu(ckpt->cur_node_segno[i]) ==
99 + le32_to_cpu(ckpt->cur_node_segno[j])) {
100 + f2fs_msg(sbi->sb, KERN_ERR,
101 + "Node segment (%u, %u) has the same "
102 + "segno: %u", i, j,
103 + le32_to_cpu(ckpt->cur_node_segno[i]));
104 + return 1;
105 + }
106 + }
107 }
108 for (i = 0; i < NR_CURSEG_DATA_TYPE; i++) {
109 if (le32_to_cpu(ckpt->cur_data_segno[i]) >= main_segs ||
110 le16_to_cpu(ckpt->cur_data_blkoff[i]) >= blocks_per_seg)
111 return 1;
112 + for (j = i + 1; j < NR_CURSEG_DATA_TYPE; j++) {
113 + if (le32_to_cpu(ckpt->cur_data_segno[i]) ==
114 + le32_to_cpu(ckpt->cur_data_segno[j])) {
115 + f2fs_msg(sbi->sb, KERN_ERR,
116 + "Data segment (%u, %u) has the same "
117 + "segno: %u", i, j,
118 + le32_to_cpu(ckpt->cur_data_segno[i]));
119 + return 1;
120 + }
121 + }
122 + }
123 + for (i = 0; i < NR_CURSEG_NODE_TYPE; i++) {
124 + for (j = i; j < NR_CURSEG_DATA_TYPE; j++) {
125 + if (le32_to_cpu(ckpt->cur_node_segno[i]) ==
126 + le32_to_cpu(ckpt->cur_data_segno[j])) {
127 + f2fs_msg(sbi->sb, KERN_ERR,
128 + "Data segment (%u) and Data segment (%u)"
129 + " has the same segno: %u", i, j,
130 + le32_to_cpu(ckpt->cur_node_segno[i]));
131 + return 1;
132 + }
133 + }
134 }
135
136 sit_bitmap_size = le32_to_cpu(ckpt->sit_ver_bitmap_bytesize);
137 --
138 2.19.1
139