aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJavier González <javier@javigon.com>2018-10-09 07:12:07 -0400
committerJens Axboe <axboe@kernel.dk>2018-10-09 10:25:08 -0400
commit44cdbdc657b23f75736eca3e88b781f009104363 (patch)
treedb6d14e7d352ee04ff6f7ec6ea20a34fdf990d8d
parent02a1520d56d11982ccc8eab56e4c562fd05d2c86 (diff)
lightnvm: pblk: fix race on sysfs line state
pblk exposes a sysfs interface that represents its internal state. Part of this state is the map bitmap for the current open line, which should be protected by the line lock to avoid a race when freeing the line metadata. Currently, it is not. This patch makes sure that the line state is consistent and NULL bitmap pointers are not dereferenced. Signed-off-by: Javier González <javier@cnexlabs.com> Signed-off-by: Matias Bjørling <mb@lightnvm.io> Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r--drivers/lightnvm/pblk-core.c5
-rw-r--r--drivers/lightnvm/pblk-sysfs.c8
2 files changed, 10 insertions, 3 deletions
diff --git a/drivers/lightnvm/pblk-core.c b/drivers/lightnvm/pblk-core.c
index 4045a9b1ee74..6944aac43b01 100644
--- a/drivers/lightnvm/pblk-core.c
+++ b/drivers/lightnvm/pblk-core.c
@@ -1611,13 +1611,14 @@ struct pblk_line *pblk_line_replace_data(struct pblk *pblk)
1611 struct pblk_line *cur, *new = NULL; 1611 struct pblk_line *cur, *new = NULL;
1612 unsigned int left_seblks; 1612 unsigned int left_seblks;
1613 1613
1614 cur = l_mg->data_line;
1615 new = l_mg->data_next; 1614 new = l_mg->data_next;
1616 if (!new) 1615 if (!new)
1617 goto out; 1616 goto out;
1618 l_mg->data_line = new;
1619 1617
1620 spin_lock(&l_mg->free_lock); 1618 spin_lock(&l_mg->free_lock);
1619 cur = l_mg->data_line;
1620 l_mg->data_line = new;
1621
1621 pblk_line_setup_metadata(new, l_mg, &pblk->lm); 1622 pblk_line_setup_metadata(new, l_mg, &pblk->lm);
1622 spin_unlock(&l_mg->free_lock); 1623 spin_unlock(&l_mg->free_lock);
1623 1624
diff --git a/drivers/lightnvm/pblk-sysfs.c b/drivers/lightnvm/pblk-sysfs.c
index cba83ac43e62..2d2818155aa8 100644
--- a/drivers/lightnvm/pblk-sysfs.c
+++ b/drivers/lightnvm/pblk-sysfs.c
@@ -263,8 +263,14 @@ static ssize_t pblk_sysfs_lines(struct pblk *pblk, char *page)
263 sec_in_line = l_mg->data_line->sec_in_line; 263 sec_in_line = l_mg->data_line->sec_in_line;
264 meta_weight = bitmap_weight(&l_mg->meta_bitmap, 264 meta_weight = bitmap_weight(&l_mg->meta_bitmap,
265 PBLK_DATA_LINES); 265 PBLK_DATA_LINES);
266 map_weight = bitmap_weight(l_mg->data_line->map_bitmap, 266
267 spin_lock(&l_mg->data_line->lock);
268 if (l_mg->data_line->map_bitmap)
269 map_weight = bitmap_weight(l_mg->data_line->map_bitmap,
267 lm->sec_per_line); 270 lm->sec_per_line);
271 else
272 map_weight = 0;
273 spin_unlock(&l_mg->data_line->lock);
268 } 274 }
269 spin_unlock(&l_mg->free_lock); 275 spin_unlock(&l_mg->free_lock);
270 276