diff options
author | Wenwei Tao <ww.tao0320@gmail.com> | 2016-03-03 09:06:38 -0500 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2016-03-18 21:10:38 -0400 |
commit | da1e284919b0b99c5bf0618b6c98cbaf2c17e62e (patch) | |
tree | ef1d8fe8821376dd57fbd4d3319a747841df38e6 /drivers/lightnvm/gennvm.c | |
parent | 4c9dacb82d5aa36aa2568df60d897f2eb3d8819b (diff) |
lightnvm: add a bitmap of luns
Add a bitmap of luns to indicate the status
of luns: inuse/available. When create targets
do the necessary check to avoid allocating luns
that are already allocated.
Signed-off-by: Wenwei Tao <ww.tao0320@gmail.com>
Freed dev->lun_map if nvm_core_init later failed in the init process.
Signed-off-by: Matias Bjørling <m@bjorling.me>
Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'drivers/lightnvm/gennvm.c')
-rw-r--r-- | drivers/lightnvm/gennvm.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/lightnvm/gennvm.c b/drivers/lightnvm/gennvm.c index d460b37bb016..b97801c00099 100644 --- a/drivers/lightnvm/gennvm.c +++ b/drivers/lightnvm/gennvm.c | |||
@@ -192,6 +192,9 @@ static int gennvm_block_map(u64 slba, u32 nlb, __le64 *entries, void *private) | |||
192 | lun_id = div_u64(pba, dev->sec_per_lun); | 192 | lun_id = div_u64(pba, dev->sec_per_lun); |
193 | lun = &gn->luns[lun_id]; | 193 | lun = &gn->luns[lun_id]; |
194 | 194 | ||
195 | if (!test_bit(lun_id, dev->lun_map)) | ||
196 | __set_bit(lun_id, dev->lun_map); | ||
197 | |||
195 | /* Calculate block offset into lun */ | 198 | /* Calculate block offset into lun */ |
196 | pba = pba - (dev->sec_per_lun * lun_id); | 199 | pba = pba - (dev->sec_per_lun * lun_id); |
197 | blk = &lun->vlun.blocks[div_u64(pba, dev->sec_per_blk)]; | 200 | blk = &lun->vlun.blocks[div_u64(pba, dev->sec_per_blk)]; |
@@ -482,10 +485,23 @@ static int gennvm_erase_blk(struct nvm_dev *dev, struct nvm_block *blk, | |||
482 | return nvm_erase_ppa(dev, &addr, 1); | 485 | return nvm_erase_ppa(dev, &addr, 1); |
483 | } | 486 | } |
484 | 487 | ||
488 | static int gennvm_reserve_lun(struct nvm_dev *dev, int lunid) | ||
489 | { | ||
490 | return test_and_set_bit(lunid, dev->lun_map); | ||
491 | } | ||
492 | |||
493 | static void gennvm_release_lun(struct nvm_dev *dev, int lunid) | ||
494 | { | ||
495 | WARN_ON(!test_and_clear_bit(lunid, dev->lun_map)); | ||
496 | } | ||
497 | |||
485 | static struct nvm_lun *gennvm_get_lun(struct nvm_dev *dev, int lunid) | 498 | static struct nvm_lun *gennvm_get_lun(struct nvm_dev *dev, int lunid) |
486 | { | 499 | { |
487 | struct gen_nvm *gn = dev->mp; | 500 | struct gen_nvm *gn = dev->mp; |
488 | 501 | ||
502 | if (unlikely(lunid >= dev->nr_luns)) | ||
503 | return NULL; | ||
504 | |||
489 | return &gn->luns[lunid].vlun; | 505 | return &gn->luns[lunid].vlun; |
490 | } | 506 | } |
491 | 507 | ||
@@ -527,6 +543,8 @@ static struct nvmm_type gennvm = { | |||
527 | .erase_blk = gennvm_erase_blk, | 543 | .erase_blk = gennvm_erase_blk, |
528 | 544 | ||
529 | .get_lun = gennvm_get_lun, | 545 | .get_lun = gennvm_get_lun, |
546 | .reserve_lun = gennvm_reserve_lun, | ||
547 | .release_lun = gennvm_release_lun, | ||
530 | .lun_info_print = gennvm_lun_info_print, | 548 | .lun_info_print = gennvm_lun_info_print, |
531 | 549 | ||
532 | .get_area = gennvm_get_area, | 550 | .get_area = gennvm_get_area, |