Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Javier González and committed by
Jens Axboe
edee1bdd b0e0306c

+10 -7
+10 -7
drivers/lightnvm/core.c
··· 89 89 WARN_ON(!test_and_clear_bit(i, dev->lun_map)); 90 90 } 91 91 92 - static void nvm_remove_tgt_dev(struct nvm_tgt_dev *tgt_dev) 92 + static void nvm_remove_tgt_dev(struct nvm_tgt_dev *tgt_dev, int clear) 93 93 { 94 94 struct nvm_dev *dev = tgt_dev->parent; 95 95 struct nvm_dev_map *dev_map = tgt_dev->map; ··· 100 100 int *lun_offs = ch_map->lun_offs; 101 101 int ch = i + ch_map->ch_off; 102 102 103 - for (j = 0; j < ch_map->nr_luns; j++) { 104 - int lun = j + lun_offs[j]; 105 - int lunid = (ch * dev->geo.luns_per_chnl) + lun; 103 + if (clear) { 104 + for (j = 0; j < ch_map->nr_luns; j++) { 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 113 kfree(ch_map->lun_offs); ··· 312 309 err_queue: 313 310 blk_cleanup_queue(tqueue); 314 311 err_dev: 315 - nvm_remove_tgt_dev(tgt_dev); 312 + nvm_remove_tgt_dev(tgt_dev, 0); 316 313 err_t: 317 314 kfree(t); 318 315 err_reserve: ··· 335 332 if (tt->exit) 336 333 tt->exit(tdisk->private_data); 337 334 338 - nvm_remove_tgt_dev(t->dev); 335 + nvm_remove_tgt_dev(t->dev, 1); 339 336 put_disk(tdisk); 340 337 341 338 list_del(&t->list);