1 |
From 584f54de25634442d9c9c390385ff0c50bd9d7f4 Mon Sep 17 00:00:00 2001 |
2 |
From: =?UTF-8?q?Javier=20Gonz=C3=A1lez?= <javier@javigon.com> |
3 |
Date: Tue, 9 Oct 2018 13:12:07 +0200 |
4 |
Subject: [PATCH 014/145] lightnvm: pblk: fix race on sysfs line state |
5 |
MIME-Version: 1.0 |
6 |
Content-Type: text/plain; charset=UTF-8 |
7 |
Content-Transfer-Encoding: 8bit |
8 |
|
9 |
[ Upstream commit 44cdbdc657b23f75736eca3e88b781f009104363 ] |
10 |
|
11 |
pblk exposes a sysfs interface that represents its internal state. Part |
12 |
of this state is the map bitmap for the current open line, which should |
13 |
be protected by the line lock to avoid a race when freeing the line |
14 |
metadata. Currently, it is not. |
15 |
|
16 |
This patch makes sure that the line state is consistent and NULL |
17 |
bitmap pointers are not dereferenced. |
18 |
|
19 |
Signed-off-by: Javier González <javier@cnexlabs.com> |
20 |
Signed-off-by: Matias Bjørling <mb@lightnvm.io> |
21 |
Signed-off-by: Jens Axboe <axboe@kernel.dk> |
22 |
Signed-off-by: Sasha Levin <sashal@kernel.org> |
23 |
--- |
24 |
drivers/lightnvm/pblk-core.c | 5 +++-- |
25 |
drivers/lightnvm/pblk-sysfs.c | 8 +++++++- |
26 |
2 files changed, 10 insertions(+), 3 deletions(-) |
27 |
|
28 |
diff --git a/drivers/lightnvm/pblk-core.c b/drivers/lightnvm/pblk-core.c |
29 |
index 00984b486fea..2940cdc87af1 100644 |
30 |
--- a/drivers/lightnvm/pblk-core.c |
31 |
+++ b/drivers/lightnvm/pblk-core.c |
32 |
@@ -1539,13 +1539,14 @@ struct pblk_line *pblk_line_replace_data(struct pblk *pblk) |
33 |
struct pblk_line *cur, *new = NULL; |
34 |
unsigned int left_seblks; |
35 |
|
36 |
- cur = l_mg->data_line; |
37 |
new = l_mg->data_next; |
38 |
if (!new) |
39 |
goto out; |
40 |
- l_mg->data_line = new; |
41 |
|
42 |
spin_lock(&l_mg->free_lock); |
43 |
+ cur = l_mg->data_line; |
44 |
+ l_mg->data_line = new; |
45 |
+ |
46 |
pblk_line_setup_metadata(new, l_mg, &pblk->lm); |
47 |
spin_unlock(&l_mg->free_lock); |
48 |
|
49 |
diff --git a/drivers/lightnvm/pblk-sysfs.c b/drivers/lightnvm/pblk-sysfs.c |
50 |
index 9fc3dfa168b4..8d2ed510c04b 100644 |
51 |
--- a/drivers/lightnvm/pblk-sysfs.c |
52 |
+++ b/drivers/lightnvm/pblk-sysfs.c |
53 |
@@ -262,8 +262,14 @@ static ssize_t pblk_sysfs_lines(struct pblk *pblk, char *page) |
54 |
sec_in_line = l_mg->data_line->sec_in_line; |
55 |
meta_weight = bitmap_weight(&l_mg->meta_bitmap, |
56 |
PBLK_DATA_LINES); |
57 |
- map_weight = bitmap_weight(l_mg->data_line->map_bitmap, |
58 |
+ |
59 |
+ spin_lock(&l_mg->data_line->lock); |
60 |
+ if (l_mg->data_line->map_bitmap) |
61 |
+ map_weight = bitmap_weight(l_mg->data_line->map_bitmap, |
62 |
lm->sec_per_line); |
63 |
+ else |
64 |
+ map_weight = 0; |
65 |
+ spin_unlock(&l_mg->data_line->lock); |
66 |
} |
67 |
spin_unlock(&l_mg->free_lock); |
68 |
|
69 |
-- |
70 |
2.19.1 |
71 |
|