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

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'libnvdimm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm

Pull libnvdimm fixes from Dan Williams:
"Three fixes, the first two are tagged for -stable:

- The ndctl utility/library gained expanded unit tests illuminating a
long standing bug in the libnvdimm SMART data retrieval
implementation.

It has been broken since its initial implementation, now fixed.

- Another one line fix for the detection of stale info blocks.

Without this change userspace can get into a situation where it is
unable to reconfigure a namespace.

- Fix the badblock initialization path in the presence of the new (in
v4.6-rc1) section alignment workarounds.

Without this change badblocks will be reported at the wrong offset.

These have received a build success report from the kbuild robot and
have appeared in -next with no reported issues"

* 'libnvdimm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm:
libnvdimm, pfn: fix nvdimm_namespace_add_poison() vs section alignment
libnvdimm, pfn: fix uuid validation
libnvdimm: fix smart data retrieval

+52 -31
+1 -1
drivers/nvdimm/bus.c
··· 407 407 [ND_CMD_IMPLEMENTED] = { }, 408 408 [ND_CMD_SMART] = { 409 409 .out_num = 2, 410 - .out_sizes = { 4, 8, }, 410 + .out_sizes = { 4, 128, }, 411 411 }, 412 412 [ND_CMD_SMART_THRESHOLD] = { 413 413 .out_num = 2,
+20 -21
drivers/nvdimm/core.c
··· 417 417 set_badblock(bb, start_sector, num_sectors); 418 418 } 419 419 420 - static void namespace_add_poison(struct list_head *poison_list, 421 - struct badblocks *bb, struct resource *res) 420 + static void badblocks_populate(struct list_head *poison_list, 421 + struct badblocks *bb, const struct resource *res) 422 422 { 423 423 struct nd_poison *pl; 424 424 ··· 460 460 } 461 461 462 462 /** 463 - * nvdimm_namespace_add_poison() - Convert a list of poison ranges to badblocks 464 - * @ndns: the namespace containing poison ranges 465 - * @bb: badblocks instance to populate 466 - * @offset: offset at the start of the namespace before 'sector 0' 463 + * nvdimm_badblocks_populate() - Convert a list of poison ranges to badblocks 464 + * @region: parent region of the range to interrogate 465 + * @bb: badblocks instance to populate 466 + * @res: resource range to consider 467 467 * 468 - * The poison list generated during NFIT initialization may contain multiple, 469 - * possibly overlapping ranges in the SPA (System Physical Address) space. 470 - * Compare each of these ranges to the namespace currently being initialized, 471 - * and add badblocks to the gendisk for all matching sub-ranges 468 + * The poison list generated during bus initialization may contain 469 + * multiple, possibly overlapping physical address ranges. Compare each 470 + * of these ranges to the resource range currently being initialized, 471 + * and add badblocks entries for all matching sub-ranges 472 472 */ 473 - void nvdimm_namespace_add_poison(struct nd_namespace_common *ndns, 474 - struct badblocks *bb, resource_size_t offset) 473 + void nvdimm_badblocks_populate(struct nd_region *nd_region, 474 + struct badblocks *bb, const struct resource *res) 475 475 { 476 - struct nd_namespace_io *nsio = to_nd_namespace_io(&ndns->dev); 477 - struct nd_region *nd_region = to_nd_region(ndns->dev.parent); 478 476 struct nvdimm_bus *nvdimm_bus; 479 477 struct list_head *poison_list; 480 - struct resource res = { 481 - .start = nsio->res.start + offset, 482 - .end = nsio->res.end, 483 - }; 484 478 485 - nvdimm_bus = to_nvdimm_bus(nd_region->dev.parent); 479 + if (!is_nd_pmem(&nd_region->dev)) { 480 + dev_WARN_ONCE(&nd_region->dev, 1, 481 + "%s only valid for pmem regions\n", __func__); 482 + return; 483 + } 484 + nvdimm_bus = walk_to_nvdimm_bus(&nd_region->dev); 486 485 poison_list = &nvdimm_bus->poison_list; 487 486 488 487 nvdimm_bus_lock(&nvdimm_bus->dev); 489 - namespace_add_poison(poison_list, bb, &res); 488 + badblocks_populate(poison_list, bb, res); 490 489 nvdimm_bus_unlock(&nvdimm_bus->dev); 491 490 } 492 - EXPORT_SYMBOL_GPL(nvdimm_namespace_add_poison); 491 + EXPORT_SYMBOL_GPL(nvdimm_badblocks_populate); 493 492 494 493 static int add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length) 495 494 {
+2 -2
drivers/nvdimm/nd.h
··· 266 266 int nvdimm_namespace_detach_btt(struct nd_namespace_common *ndns); 267 267 const char *nvdimm_namespace_disk_name(struct nd_namespace_common *ndns, 268 268 char *name); 269 - void nvdimm_namespace_add_poison(struct nd_namespace_common *ndns, 270 - struct badblocks *bb, resource_size_t offset); 269 + void nvdimm_badblocks_populate(struct nd_region *nd_region, 270 + struct badblocks *bb, const struct resource *res); 271 271 int nd_blk_region_init(struct nd_region *nd_region); 272 272 void __nd_iostat_start(struct bio *bio, unsigned long *start); 273 273 static inline bool nd_iostat_start(struct bio *bio, unsigned long *start)
+1 -1
drivers/nvdimm/pfn_devs.c
··· 376 376 } else { 377 377 /* from init we validate */ 378 378 if (memcmp(nd_pfn->uuid, pfn_sb->uuid, 16) != 0) 379 - return -EINVAL; 379 + return -ENODEV; 380 380 } 381 381 382 382 if (nd_pfn->align > nvdimm_namespace_capacity(ndns)) {
+28 -6
drivers/nvdimm/pmem.c
··· 244 244 static int pmem_attach_disk(struct device *dev, 245 245 struct nd_namespace_common *ndns, struct pmem_device *pmem) 246 246 { 247 + struct nd_namespace_io *nsio = to_nd_namespace_io(&ndns->dev); 247 248 int nid = dev_to_node(dev); 249 + struct resource bb_res; 248 250 struct gendisk *disk; 249 251 250 252 blk_queue_make_request(pmem->pmem_queue, pmem_make_request); ··· 273 271 devm_exit_badblocks(dev, &pmem->bb); 274 272 if (devm_init_badblocks(dev, &pmem->bb)) 275 273 return -ENOMEM; 276 - nvdimm_namespace_add_poison(ndns, &pmem->bb, pmem->data_offset); 274 + bb_res.start = nsio->res.start + pmem->data_offset; 275 + bb_res.end = nsio->res.end; 276 + if (is_nd_pfn(dev)) { 277 + struct nd_pfn *nd_pfn = to_nd_pfn(dev); 278 + struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb; 277 279 280 + bb_res.start += __le32_to_cpu(pfn_sb->start_pad); 281 + bb_res.end -= __le32_to_cpu(pfn_sb->end_trunc); 282 + } 283 + nvdimm_badblocks_populate(to_nd_region(dev->parent), &pmem->bb, 284 + &bb_res); 278 285 disk->bb = &pmem->bb; 279 286 add_disk(disk); 280 287 revalidate_disk(disk); ··· 564 553 ndns->rw_bytes = pmem_rw_bytes; 565 554 if (devm_init_badblocks(dev, &pmem->bb)) 566 555 return -ENOMEM; 567 - nvdimm_namespace_add_poison(ndns, &pmem->bb, 0); 556 + nvdimm_badblocks_populate(nd_region, &pmem->bb, &nsio->res); 568 557 569 558 if (is_nd_btt(dev)) { 570 559 /* btt allocates its own request_queue */ ··· 606 595 { 607 596 struct pmem_device *pmem = dev_get_drvdata(dev); 608 597 struct nd_namespace_common *ndns = pmem->ndns; 598 + struct nd_region *nd_region = to_nd_region(dev->parent); 599 + struct nd_namespace_io *nsio = to_nd_namespace_io(&ndns->dev); 600 + struct resource res = { 601 + .start = nsio->res.start + pmem->data_offset, 602 + .end = nsio->res.end, 603 + }; 609 604 610 605 if (event != NVDIMM_REVALIDATE_POISON) 611 606 return; 612 607 613 - if (is_nd_btt(dev)) 614 - nvdimm_namespace_add_poison(ndns, &pmem->bb, 0); 615 - else 616 - nvdimm_namespace_add_poison(ndns, &pmem->bb, pmem->data_offset); 608 + if (is_nd_pfn(dev)) { 609 + struct nd_pfn *nd_pfn = to_nd_pfn(dev); 610 + struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb; 611 + 612 + res.start += __le32_to_cpu(pfn_sb->start_pad); 613 + res.end -= __le32_to_cpu(pfn_sb->end_trunc); 614 + } 615 + 616 + nvdimm_badblocks_populate(nd_region, &pmem->bb, &res); 617 617 } 618 618 619 619 MODULE_ALIAS("pmem");