drivers/nvdimm/label.c
Source file repositories/reference/linux-study-clean/drivers/nvdimm/label.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/nvdimm/label.c- Extension
.c- Size
- 30472 bytes
- Lines
- 1122
- Domain
- Driver Families
- Bucket
- drivers/nvdimm
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/device.hlinux/ndctl.hlinux/uuid.hlinux/slab.hlinux/io.hlinux/nd.hnd-core.hlabel.hnd.h
Detected Declarations
function best_seqfunction sizeof_namespace_labelfunction __sizeof_namespace_indexfunction __nvdimm_num_label_slotsfunction nvdimm_num_label_slotsfunction sizeof_namespace_indexfunction __nd_label_validatefunction nd_label_validatefunction nd_label_copyfunction to_slotfunction preamble_indexfunction preamble_currentfunction preamble_nextfunction nsl_validate_checksumfunction nsl_calculate_checksumfunction slot_validfunction nd_label_reserve_dpafunction for_each_clear_bit_lefunction nd_label_data_initfunction nd_label_active_countfunction for_each_clear_bit_lefunction for_each_clear_bit_lefunction nd_label_alloc_slotfunction nd_label_free_slotfunction nd_label_nfreefunction nd_label_write_indexfunction nd_label_offsetfunction guid_to_nvdimm_cclassfunction uuid_to_nvdimm_cclassfunction reap_victimfunction nsl_set_type_guidfunction nsl_validate_type_guidfunction nsl_set_claim_classfunction nsl_get_claim_classfunction __pmem_label_updatefunction list_for_each_entryfunction init_labelsfunction del_labelsfunction nd_pmem_namespace_label_updatefunction nd_label_init
Annotated Snippet
if (memcmp(sig, NSINDEX_SIGNATURE, NSINDEX_SIG_LEN) != 0) {
dev_dbg(dev, "nsindex%d signature invalid\n", i);
continue;
}
/* label sizes larger than 128 arrived with v1.2 */
version = __le16_to_cpu(nsindex[i]->major) * 100
+ __le16_to_cpu(nsindex[i]->minor);
if (version >= 102)
labelsize = 1 << (7 + nsindex[i]->labelsize);
else
labelsize = 128;
if (labelsize != sizeof_namespace_label(ndd)) {
dev_dbg(dev, "nsindex%d labelsize %d invalid\n",
i, nsindex[i]->labelsize);
continue;
}
sum_save = __le64_to_cpu(nsindex[i]->checksum);
nsindex[i]->checksum = __cpu_to_le64(0);
sum = nd_fletcher64(nsindex[i], sizeof_namespace_index(ndd), 1);
nsindex[i]->checksum = __cpu_to_le64(sum_save);
if (sum != sum_save) {
dev_dbg(dev, "nsindex%d checksum invalid\n", i);
continue;
}
seq = __le32_to_cpu(nsindex[i]->seq);
if ((seq & NSINDEX_SEQ_MASK) == 0) {
dev_dbg(dev, "nsindex%d sequence: %#x invalid\n", i, seq);
continue;
}
/* sanity check the index against expected values */
if (__le64_to_cpu(nsindex[i]->myoff)
!= i * sizeof_namespace_index(ndd)) {
dev_dbg(dev, "nsindex%d myoff: %#llx invalid\n",
i, (unsigned long long)
__le64_to_cpu(nsindex[i]->myoff));
continue;
}
if (__le64_to_cpu(nsindex[i]->otheroff)
!= (!i) * sizeof_namespace_index(ndd)) {
dev_dbg(dev, "nsindex%d otheroff: %#llx invalid\n",
i, (unsigned long long)
__le64_to_cpu(nsindex[i]->otheroff));
continue;
}
if (__le64_to_cpu(nsindex[i]->labeloff)
!= 2 * sizeof_namespace_index(ndd)) {
dev_dbg(dev, "nsindex%d labeloff: %#llx invalid\n",
i, (unsigned long long)
__le64_to_cpu(nsindex[i]->labeloff));
continue;
}
size = __le64_to_cpu(nsindex[i]->mysize);
if (size > sizeof_namespace_index(ndd)
|| size < sizeof(struct nd_namespace_index)) {
dev_dbg(dev, "nsindex%d mysize: %#llx invalid\n", i, size);
continue;
}
nslot = __le32_to_cpu(nsindex[i]->nslot);
if (nslot * sizeof_namespace_label(ndd)
+ 2 * sizeof_namespace_index(ndd)
> ndd->nsarea.config_size) {
dev_dbg(dev, "nsindex%d nslot: %u invalid, config_size: %#x\n",
i, nslot, ndd->nsarea.config_size);
continue;
}
valid[i] = true;
num_valid++;
}
switch (num_valid) {
case 0:
break;
case 1:
for (i = 0; i < num_index; i++)
if (valid[i])
return i;
/* can't have num_valid > 0 but valid[] = { false, false } */
WARN_ON(1);
break;
default:
/* pick the best index... */
seq = best_seq(__le32_to_cpu(nsindex[0]->seq),
__le32_to_cpu(nsindex[1]->seq));
Annotation
- Immediate include surface: `linux/device.h`, `linux/ndctl.h`, `linux/uuid.h`, `linux/slab.h`, `linux/io.h`, `linux/nd.h`, `nd-core.h`, `label.h`.
- Detected declarations: `function best_seq`, `function sizeof_namespace_label`, `function __sizeof_namespace_index`, `function __nvdimm_num_label_slots`, `function nvdimm_num_label_slots`, `function sizeof_namespace_index`, `function __nd_label_validate`, `function nd_label_validate`, `function nd_label_copy`, `function to_slot`.
- Atlas domain: Driver Families / drivers/nvdimm.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.