aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/lightnvm/core.c
diff options
context:
space:
mode:
authorJavier González <jg@lightnvm.io>2017-04-15 14:55:42 -0400
committerJens Axboe <axboe@fb.com>2017-04-16 12:06:25 -0400
commitedee1bdd66bf0fda46a176bc3ee5c992dbbc466e (patch)
treee899f7abec10a0cffd5e89883411360efcab8a4f /drivers/lightnvm/core.c
parentb0e0306ce14180baee00cea9be5600eef6750af8 (diff)
lightnvm: double-clear of dev->lun_map on target init error
The dev->lun_map bits are cleared twice if an target init error occurs. First in the target clean routine, and then next in the nvm_tgt_create error function. Make sure that it is only cleared once by extending nvm_remove_tgt_devi() with a clear bit, such that clearing of bits can ignored when cleaning up a successful initialized target. Signed-off-by: Javier González <javier@cnexlabs.com> Fix style. Signed-off-by: Matias Bjørling <matias@cnexlabs.com> Signed-off-by: Matias Bjørling <matias@cnexlabs.com> Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'drivers/lightnvm/core.c')
-rw-r--r--drivers/lightnvm/core.c17
1 files changed, 10 insertions, 7 deletions
diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c
index a14c52c24e23..5eea3d5ecc30 100644
--- a/drivers/lightnvm/core.c
+++ b/drivers/lightnvm/core.c
@@ -89,7 +89,7 @@ static void nvm_release_luns_err(struct nvm_dev *dev, int lun_begin,
89 WARN_ON(!test_and_clear_bit(i, dev->lun_map)); 89 WARN_ON(!test_and_clear_bit(i, dev->lun_map));
90} 90}
91 91
92static void nvm_remove_tgt_dev(struct nvm_tgt_dev *tgt_dev) 92static void nvm_remove_tgt_dev(struct nvm_tgt_dev *tgt_dev, int clear)
93{ 93{
94 struct nvm_dev *dev = tgt_dev->parent; 94 struct nvm_dev *dev = tgt_dev->parent;
95 struct nvm_dev_map *dev_map = tgt_dev->map; 95 struct nvm_dev_map *dev_map = tgt_dev->map;
@@ -100,11 +100,14 @@ static void nvm_remove_tgt_dev(struct nvm_tgt_dev *tgt_dev)
100 int *lun_offs = ch_map->lun_offs; 100 int *lun_offs = ch_map->lun_offs;
101 int ch = i + ch_map->ch_off; 101 int ch = i + ch_map->ch_off;
102 102
103 for (j = 0; j < ch_map->nr_luns; j++) { 103 if (clear) {
104 int lun = j + lun_offs[j]; 104 for (j = 0; j < ch_map->nr_luns; j++) {
105 int lunid = (ch * dev->geo.luns_per_chnl) + lun; 105 int lun = j + lun_offs[j];
106 int lunid = (ch * dev->geo.luns_per_chnl) + lun;
106 107
107 WARN_ON(!test_and_clear_bit(lunid, dev->lun_map)); 108 WARN_ON(!test_and_clear_bit(lunid,
109 dev->lun_map));
110 }
108 } 111 }
109 112
110 kfree(ch_map->lun_offs); 113 kfree(ch_map->lun_offs);
@@ -309,7 +312,7 @@ err_init:
309err_queue: 312err_queue:
310 blk_cleanup_queue(tqueue); 313 blk_cleanup_queue(tqueue);
311err_dev: 314err_dev:
312 nvm_remove_tgt_dev(tgt_dev); 315 nvm_remove_tgt_dev(tgt_dev, 0);
313err_t: 316err_t:
314 kfree(t); 317 kfree(t);
315err_reserve: 318err_reserve:
@@ -332,7 +335,7 @@ static void __nvm_remove_target(struct nvm_target *t)
332 if (tt->exit) 335 if (tt->exit)
333 tt->exit(tdisk->private_data); 336 tt->exit(tdisk->private_data);
334 337
335 nvm_remove_tgt_dev(t->dev); 338 nvm_remove_tgt_dev(t->dev, 1);
336 put_disk(tdisk); 339 put_disk(tdisk);
337 340
338 list_del(&t->list); 341 list_del(&t->list);