]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/5.0.4/bcache-treat-stale-dirty-keys-as-bad-keys.patch
Linux 4.19.31
[thirdparty/kernel/stable-queue.git] / releases / 5.0.4 / bcache-treat-stale-dirty-keys-as-bad-keys.patch
1 From 58ac323084ebf44f8470eeb8b82660f9d0ee3689 Mon Sep 17 00:00:00 2001
2 From: Tang Junhui <tang.junhui.linux@gmail.com>
3 Date: Sat, 9 Feb 2019 12:52:58 +0800
4 Subject: bcache: treat stale && dirty keys as bad keys
5
6 From: Tang Junhui <tang.junhui.linux@gmail.com>
7
8 commit 58ac323084ebf44f8470eeb8b82660f9d0ee3689 upstream.
9
10 Stale && dirty keys can be produced in the follow way:
11 After writeback in write_dirty_finish(), dirty keys k1 will
12 replace by clean keys k2
13 ==>ret = bch_btree_insert(dc->disk.c, &keys, NULL, &w->key);
14 ==>btree_insert_fn(struct btree_op *b_op, struct btree *b)
15 ==>static int bch_btree_insert_node(struct btree *b,
16 struct btree_op *op,
17 struct keylist *insert_keys,
18 atomic_t *journal_ref,
19 Then two steps:
20 A) update k1 to k2 in btree node memory;
21 bch_btree_insert_keys(b, op, insert_keys, replace_key)
22 B) Write the bset(contains k2) to cache disk by a 30s delay work
23 bch_btree_leaf_dirty(b, journal_ref).
24 But before the 30s delay work write the bset to cache device,
25 these things happened:
26 A) GC works, and reclaim the bucket k2 point to;
27 B) Allocator works, and invalidate the bucket k2 point to,
28 and increase the gen of the bucket, and place it into free_inc
29 fifo;
30 C) Until now, the 30s delay work still does not finish work,
31 so in the disk, the key still is k1, it is dirty and stale
32 (its gen is smaller than the gen of the bucket). and then the
33 machine power off suddenly happens;
34 D) When the machine power on again, after the btree reconstruction,
35 the stale dirty key appear.
36
37 In bch_extent_bad(), when expensive_debug_checks is off, it would
38 treat the dirty key as good even it is stale keys, and it would
39 cause bellow probelms:
40 A) In read_dirty() it would cause machine crash:
41 BUG_ON(ptr_stale(dc->disk.c, &w->key, 0));
42 B) It could be worse when reads hits stale dirty keys, it would
43 read old incorrect data.
44
45 This patch tolerate the existence of these stale && dirty keys,
46 and treat them as bad key in bch_extent_bad().
47
48 (Coly Li: fix indent which was modified by sender's email client)
49
50 Signed-off-by: Tang Junhui <tang.junhui.linux@gmail.com>
51 Cc: stable@vger.kernel.org
52 Signed-off-by: Coly Li <colyli@suse.de>
53 Signed-off-by: Jens Axboe <axboe@kernel.dk>
54 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
55
56 ---
57 drivers/md/bcache/extents.c | 13 +++++++------
58 1 file changed, 7 insertions(+), 6 deletions(-)
59
60 --- a/drivers/md/bcache/extents.c
61 +++ b/drivers/md/bcache/extents.c
62 @@ -538,6 +538,7 @@ static bool bch_extent_bad(struct btree_
63 {
64 struct btree *b = container_of(bk, struct btree, keys);
65 unsigned int i, stale;
66 + char buf[80];
67
68 if (!KEY_PTRS(k) ||
69 bch_extent_invalid(bk, k))
70 @@ -547,19 +548,19 @@ static bool bch_extent_bad(struct btree_
71 if (!ptr_available(b->c, k, i))
72 return true;
73
74 - if (!expensive_debug_checks(b->c) && KEY_DIRTY(k))
75 - return false;
76 -
77 for (i = 0; i < KEY_PTRS(k); i++) {
78 stale = ptr_stale(b->c, k, i);
79
80 + if (stale && KEY_DIRTY(k)) {
81 + bch_extent_to_text(buf, sizeof(buf), k);
82 + pr_info("stale dirty pointer, stale %u, key: %s",
83 + stale, buf);
84 + }
85 +
86 btree_bug_on(stale > BUCKET_GC_GEN_MAX, b,
87 "key too stale: %i, need_gc %u",
88 stale, b->c->need_gc);
89
90 - btree_bug_on(stale && KEY_DIRTY(k) && KEY_SIZE(k),
91 - b, "stale dirty pointer");
92 -
93 if (stale)
94 return true;
95