Index: sys/dev/nvdimm/nvdimm.c =================================================================== --- sys/dev/nvdimm/nvdimm.c +++ sys/dev/nvdimm/nvdimm.c @@ -183,7 +183,7 @@ { uint64_t checksum; - index = (struct nvdimm_label_index *)((uint8_t *)index + offset); + index = (struct nvdimm_label_index *)((uint8_t *)index + size * offset); if (strcmp(index->signature, NVDIMM_INDEX_BLOCK_SIGNATURE) != 0) return false; checksum = index->checksum; @@ -242,7 +242,7 @@ static int read_labels(struct nvdimm_dev *nv) { - struct nvdimm_label_index *indices; + struct nvdimm_label_index *index0, *index1; size_t bitfield_size, index_size, num_labels; int error, n; bool index_0_valid, index_1_valid; @@ -257,32 +257,34 @@ num_labels = (nv->label_area_size - index_size) / sizeof(struct nvdimm_label); bitfield_size = roundup2(num_labels, 8) / 8; - indices = malloc(2 * index_size, M_NVDIMM, M_WAITOK); - error = read_label_area(nv, (void *)indices, 0, 2 * index_size); + index0 = malloc(2 * index_size, M_NVDIMM, M_WAITOK); + index1 = (void *)((uint8_t *)index0 + index_size); + error = read_label_area(nv, (void *)index0, 0, 2 * index_size); if (error != 0) { - free(indices, M_NVDIMM); + free(index0, M_NVDIMM); return (error); } - index_0_valid = label_index_is_valid(indices, num_labels, index_size, + index_0_valid = label_index_is_valid(index0, num_labels, index_size, 0); - index_1_valid = label_index_is_valid(indices, num_labels, index_size, + index_1_valid = label_index_is_valid(index0, num_labels, index_size, 1); if (!index_0_valid && !index_1_valid) { - free(indices, M_NVDIMM); + free(index0, M_NVDIMM); return (ENXIO); } if (index_0_valid && index_1_valid && - (indices[1].seq > indices[0].seq || - (indices[1].seq == 1 && indices[0].seq == 3))) + (index1->seq - index0->seq == 1 || + (int)index1->seq - index0->seq == -2)) index_0_valid = false; nv->label_index = malloc(index_size, M_NVDIMM, M_WAITOK); - bcopy(indices + (index_0_valid ? 0 : 1), nv->label_index, index_size); - free(indices, M_NVDIMM); - for (bit_ffc_at((bitstr_t *)nv->label_index->free, 0, num_labels, &n); - n >= 0; - bit_ffc_at((bitstr_t *)nv->label_index->free, n + 1, num_labels, - &n)) { + bcopy(index_0_valid ? index0 : index1, nv->label_index, index_size); + free(index0, M_NVDIMM); + bit_ffc_at((bitstr_t *)nv->label_index->free, 0, + nv->label_index->slot_cnt, &n); + while (n >= 0) { read_label(nv, n); + bit_ffc_at((bitstr_t *)nv->label_index->free, n + 1, + nv->label_index->slot_cnt, &n); } return (0); }