aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/nvdimm/namespace_devs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/nvdimm/namespace_devs.c')
-rw-r--r--drivers/nvdimm/namespace_devs.c61
1 files changed, 59 insertions, 2 deletions
diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c
index f05d9b0672bf..c96e31330213 100644
--- a/drivers/nvdimm/namespace_devs.c
+++ b/drivers/nvdimm/namespace_devs.c
@@ -1411,6 +1411,58 @@ static ssize_t dpa_extents_show(struct device *dev,
1411} 1411}
1412static DEVICE_ATTR_RO(dpa_extents); 1412static DEVICE_ATTR_RO(dpa_extents);
1413 1413
1414static int btt_claim_class(struct device *dev)
1415{
1416 struct nd_region *nd_region = to_nd_region(dev->parent);
1417 int i, loop_bitmask = 0;
1418
1419 for (i = 0; i < nd_region->ndr_mappings; i++) {
1420 struct nd_mapping *nd_mapping = &nd_region->mapping[i];
1421 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
1422 struct nd_namespace_index *nsindex;
1423
1424 nsindex = to_namespace_index(ndd, ndd->ns_current);
1425 if (nsindex == NULL)
1426 loop_bitmask |= 1;
1427 else {
1428 /* check whether existing labels are v1.1 or v1.2 */
1429 if (__le16_to_cpu(nsindex->major) == 1
1430 && __le16_to_cpu(nsindex->minor) == 1)
1431 loop_bitmask |= 2;
1432 else
1433 loop_bitmask |= 4;
1434 }
1435 }
1436 /*
1437 * If nsindex is null loop_bitmask's bit 0 will be set, and if an index
1438 * block is found, a v1.1 label for any mapping will set bit 1, and a
1439 * v1.2 label will set bit 2.
1440 *
1441 * At the end of the loop, at most one of the three bits must be set.
1442 * If multiple bits were set, it means the different mappings disagree
1443 * about their labels, and this must be cleaned up first.
1444 *
1445 * If all the label index blocks are found to agree, nsindex of NULL
1446 * implies labels haven't been initialized yet, and when they will,
1447 * they will be of the 1.2 format, so we can assume BTT2.0
1448 *
1449 * If 1.1 labels are found, we enforce BTT1.1, and if 1.2 labels are
1450 * found, we enforce BTT2.0
1451 *
1452 * If the loop was never entered, default to BTT1.1 (legacy namespaces)
1453 */
1454 switch (loop_bitmask) {
1455 case 0:
1456 case 2:
1457 return NVDIMM_CCLASS_BTT;
1458 case 1:
1459 case 4:
1460 return NVDIMM_CCLASS_BTT2;
1461 default:
1462 return -ENXIO;
1463 }
1464}
1465
1414static ssize_t holder_show(struct device *dev, 1466static ssize_t holder_show(struct device *dev,
1415 struct device_attribute *attr, char *buf) 1467 struct device_attribute *attr, char *buf)
1416{ 1468{
@@ -1433,7 +1485,7 @@ static ssize_t __holder_class_store(struct device *dev, const char *buf)
1433 return -EBUSY; 1485 return -EBUSY;
1434 1486
1435 if (strcmp(buf, "btt") == 0 || strcmp(buf, "btt\n") == 0) 1487 if (strcmp(buf, "btt") == 0 || strcmp(buf, "btt\n") == 0)
1436 ndns->claim_class = NVDIMM_CCLASS_BTT; 1488 ndns->claim_class = btt_claim_class(dev);
1437 else if (strcmp(buf, "pfn") == 0 || strcmp(buf, "pfn\n") == 0) 1489 else if (strcmp(buf, "pfn") == 0 || strcmp(buf, "pfn\n") == 0)
1438 ndns->claim_class = NVDIMM_CCLASS_PFN; 1490 ndns->claim_class = NVDIMM_CCLASS_PFN;
1439 else if (strcmp(buf, "dax") == 0 || strcmp(buf, "dax\n") == 0) 1491 else if (strcmp(buf, "dax") == 0 || strcmp(buf, "dax\n") == 0)
@@ -1443,6 +1495,10 @@ static ssize_t __holder_class_store(struct device *dev, const char *buf)
1443 else 1495 else
1444 return -EINVAL; 1496 return -EINVAL;
1445 1497
1498 /* btt_claim_class() could've returned an error */
1499 if (ndns->claim_class < 0)
1500 return ndns->claim_class;
1501
1446 return 0; 1502 return 0;
1447} 1503}
1448 1504
@@ -1474,7 +1530,8 @@ static ssize_t holder_class_show(struct device *dev,
1474 device_lock(dev); 1530 device_lock(dev);
1475 if (ndns->claim_class == NVDIMM_CCLASS_NONE) 1531 if (ndns->claim_class == NVDIMM_CCLASS_NONE)
1476 rc = sprintf(buf, "\n"); 1532 rc = sprintf(buf, "\n");
1477 else if (ndns->claim_class == NVDIMM_CCLASS_BTT) 1533 else if ((ndns->claim_class == NVDIMM_CCLASS_BTT) ||
1534 (ndns->claim_class == NVDIMM_CCLASS_BTT2))
1478 rc = sprintf(buf, "btt\n"); 1535 rc = sprintf(buf, "btt\n");
1479 else if (ndns->claim_class == NVDIMM_CCLASS_PFN) 1536 else if (ndns->claim_class == NVDIMM_CCLASS_PFN)
1480 rc = sprintf(buf, "pfn\n"); 1537 rc = sprintf(buf, "pfn\n");