diff options
Diffstat (limited to 'drivers/nvdimm/namespace_devs.c')
-rw-r--r-- | drivers/nvdimm/namespace_devs.c | 40 |
1 files changed, 31 insertions, 9 deletions
diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c index a16e52251a30..43401325c874 100644 --- a/drivers/nvdimm/namespace_devs.c +++ b/drivers/nvdimm/namespace_devs.c | |||
@@ -1006,10 +1006,10 @@ static ssize_t __size_store(struct device *dev, unsigned long long val) | |||
1006 | return -ENXIO; | 1006 | return -ENXIO; |
1007 | } | 1007 | } |
1008 | 1008 | ||
1009 | div_u64_rem(val, SZ_4K * nd_region->ndr_mappings, &remainder); | 1009 | div_u64_rem(val, PAGE_SIZE * nd_region->ndr_mappings, &remainder); |
1010 | if (remainder) { | 1010 | if (remainder) { |
1011 | dev_dbg(dev, "%llu is not %dK aligned\n", val, | 1011 | dev_dbg(dev, "%llu is not %ldK aligned\n", val, |
1012 | (SZ_4K * nd_region->ndr_mappings) / SZ_1K); | 1012 | (PAGE_SIZE * nd_region->ndr_mappings) / SZ_1K); |
1013 | return -EINVAL; | 1013 | return -EINVAL; |
1014 | } | 1014 | } |
1015 | 1015 | ||
@@ -2462,6 +2462,27 @@ static struct device **create_namespaces(struct nd_region *nd_region) | |||
2462 | return devs; | 2462 | return devs; |
2463 | } | 2463 | } |
2464 | 2464 | ||
2465 | static void deactivate_labels(void *region) | ||
2466 | { | ||
2467 | struct nd_region *nd_region = region; | ||
2468 | int i; | ||
2469 | |||
2470 | for (i = 0; i < nd_region->ndr_mappings; i++) { | ||
2471 | struct nd_mapping *nd_mapping = &nd_region->mapping[i]; | ||
2472 | struct nvdimm_drvdata *ndd = nd_mapping->ndd; | ||
2473 | struct nvdimm *nvdimm = nd_mapping->nvdimm; | ||
2474 | |||
2475 | mutex_lock(&nd_mapping->lock); | ||
2476 | nd_mapping_free_labels(nd_mapping); | ||
2477 | mutex_unlock(&nd_mapping->lock); | ||
2478 | |||
2479 | put_ndd(ndd); | ||
2480 | nd_mapping->ndd = NULL; | ||
2481 | if (ndd) | ||
2482 | atomic_dec(&nvdimm->busy); | ||
2483 | } | ||
2484 | } | ||
2485 | |||
2465 | static int init_active_labels(struct nd_region *nd_region) | 2486 | static int init_active_labels(struct nd_region *nd_region) |
2466 | { | 2487 | { |
2467 | int i; | 2488 | int i; |
@@ -2519,16 +2540,17 @@ static int init_active_labels(struct nd_region *nd_region) | |||
2519 | mutex_unlock(&nd_mapping->lock); | 2540 | mutex_unlock(&nd_mapping->lock); |
2520 | } | 2541 | } |
2521 | 2542 | ||
2522 | if (j >= count) | 2543 | if (j < count) |
2523 | continue; | 2544 | break; |
2545 | } | ||
2524 | 2546 | ||
2525 | mutex_lock(&nd_mapping->lock); | 2547 | if (i < nd_region->ndr_mappings) { |
2526 | nd_mapping_free_labels(nd_mapping); | 2548 | deactivate_labels(nd_region); |
2527 | mutex_unlock(&nd_mapping->lock); | ||
2528 | return -ENOMEM; | 2549 | return -ENOMEM; |
2529 | } | 2550 | } |
2530 | 2551 | ||
2531 | return 0; | 2552 | return devm_add_action_or_reset(&nd_region->dev, deactivate_labels, |
2553 | nd_region); | ||
2532 | } | 2554 | } |
2533 | 2555 | ||
2534 | int nd_region_register_namespaces(struct nd_region *nd_region, int *err) | 2556 | int nd_region_register_namespaces(struct nd_region *nd_region, int *err) |