/** * Check an L2 table * * @ret: Number of invalid cluster offsets */ static unsigned int qed_check_l2_table(QEDCheck *check, QEDTable *table) { BDRVQEDState *s = check->s; unsigned int i, num_invalid = 0; for (i = 0; i < s->table_nelems; i++) { uint64_t offset = table->offsets[i]; if (qed_offset_is_unalloc_cluster(offset) || qed_offset_is_zero_cluster(offset)) { continue; } /* Detect invalid cluster offset */ if (!qed_check_cluster_offset(s, offset)) { if (check->fix) { table->offsets[i] = 0; } else { check->result->corruptions++; } num_invalid++; continue; } qed_set_used_clusters(check, offset, 1); } return num_invalid; }
static void qed_find_cluster_cb(void *opaque, int ret) { QEDFindClusterCB *find_cluster_cb = opaque; BDRVQEDState *s = find_cluster_cb->s; QEDRequest *request = find_cluster_cb->request; uint64_t offset = 0; size_t len = 0; unsigned int index; unsigned int n; if (ret) { goto out; } index = qed_l2_index(s, find_cluster_cb->pos); n = qed_bytes_to_clusters(s, qed_offset_into_cluster(s, find_cluster_cb->pos) + find_cluster_cb->len); n = qed_count_contiguous_clusters(s, request->l2_table->table, index, n, &offset); if (qed_offset_is_unalloc_cluster(offset)) { ret = QED_CLUSTER_L2; } else if (qed_offset_is_zero_cluster(offset)) { ret = QED_CLUSTER_ZERO; } else if (qed_check_cluster_offset(s, offset)) { ret = QED_CLUSTER_FOUND; } else { ret = -EINVAL; } len = MIN(find_cluster_cb->len, n * s->header.cluster_size - qed_offset_into_cluster(s, find_cluster_cb->pos)); out: find_cluster_cb->cb(find_cluster_cb->opaque, ret, offset, len); g_free(find_cluster_cb); }
/** * Check an L2 table * * @ret: Number of invalid cluster offsets */ static unsigned int qed_check_l2_table(QEDCheck *check, QEDTable *table) { BDRVQEDState *s = check->s; unsigned int i, num_invalid = 0; uint64_t last_offset = 0; for (i = 0; i < s->table_nelems; i++) { uint64_t offset = table->offsets[i]; if (qed_offset_is_unalloc_cluster(offset) || qed_offset_is_zero_cluster(offset)) { continue; } check->result->bfi.allocated_clusters++; if (last_offset && (last_offset + s->header.cluster_size != offset)) { check->result->bfi.fragmented_clusters++; } last_offset = offset; /* Detect invalid cluster offset */ if (!qed_check_cluster_offset(s, offset)) { if (check->fix) { table->offsets[i] = 0; check->result->corruptions_fixed++; } else { check->result->corruptions++; } num_invalid++; continue; } qed_set_used_clusters(check, offset, 1); } return num_invalid; }