Revision 298800ca block/qed.c
b/block/qed.c | ||
---|---|---|
155 | 155 |
return 0; |
156 | 156 |
} |
157 | 157 |
|
158 |
QEDTable *qed_alloc_table(BDRVQEDState *s) |
|
159 |
{ |
|
160 |
/* Honor O_DIRECT memory alignment requirements */ |
|
161 |
return qemu_blockalign(s->bs, |
|
162 |
s->header.cluster_size * s->header.table_size); |
|
163 |
} |
|
164 |
|
|
158 | 165 |
static int bdrv_qed_open(BlockDriverState *bs, int flags) |
159 | 166 |
{ |
160 | 167 |
BDRVQEDState *s = bs->opaque; |
... | ... | |
244 | 251 |
bdrv_flush(bs->file); |
245 | 252 |
} |
246 | 253 |
|
254 |
s->l1_table = qed_alloc_table(s); |
|
255 |
qed_init_l2_cache(&s->l2_cache); |
|
256 |
|
|
257 |
ret = qed_read_l1_table_sync(s); |
|
258 |
if (ret) { |
|
259 |
qed_free_l2_cache(&s->l2_cache); |
|
260 |
qemu_vfree(s->l1_table); |
|
261 |
} |
|
247 | 262 |
return ret; |
248 | 263 |
} |
249 | 264 |
|
250 | 265 |
static void bdrv_qed_close(BlockDriverState *bs) |
251 | 266 |
{ |
267 |
BDRVQEDState *s = bs->opaque; |
|
268 |
|
|
269 |
qed_free_l2_cache(&s->l2_cache); |
|
270 |
qemu_vfree(s->l1_table); |
|
252 | 271 |
} |
253 | 272 |
|
254 | 273 |
static int bdrv_qed_flush(BlockDriverState *bs) |
... | ... | |
368 | 387 |
backing_file, backing_fmt); |
369 | 388 |
} |
370 | 389 |
|
390 |
typedef struct { |
|
391 |
int is_allocated; |
|
392 |
int *pnum; |
|
393 |
} QEDIsAllocatedCB; |
|
394 |
|
|
395 |
static void qed_is_allocated_cb(void *opaque, int ret, uint64_t offset, size_t len) |
|
396 |
{ |
|
397 |
QEDIsAllocatedCB *cb = opaque; |
|
398 |
*cb->pnum = len / BDRV_SECTOR_SIZE; |
|
399 |
cb->is_allocated = ret == QED_CLUSTER_FOUND; |
|
400 |
} |
|
401 |
|
|
371 | 402 |
static int bdrv_qed_is_allocated(BlockDriverState *bs, int64_t sector_num, |
372 | 403 |
int nb_sectors, int *pnum) |
373 | 404 |
{ |
374 |
return -ENOTSUP; |
|
405 |
BDRVQEDState *s = bs->opaque; |
|
406 |
uint64_t pos = (uint64_t)sector_num * BDRV_SECTOR_SIZE; |
|
407 |
size_t len = (size_t)nb_sectors * BDRV_SECTOR_SIZE; |
|
408 |
QEDIsAllocatedCB cb = { |
|
409 |
.is_allocated = -1, |
|
410 |
.pnum = pnum, |
|
411 |
}; |
|
412 |
QEDRequest request = { .l2_table = NULL }; |
|
413 |
|
|
414 |
async_context_push(); |
|
415 |
|
|
416 |
qed_find_cluster(s, &request, pos, len, qed_is_allocated_cb, &cb); |
|
417 |
|
|
418 |
while (cb.is_allocated == -1) { |
|
419 |
qemu_aio_wait(); |
|
420 |
} |
|
421 |
|
|
422 |
async_context_pop(); |
|
423 |
|
|
424 |
qed_unref_l2_cache_entry(request.l2_table); |
|
425 |
|
|
426 |
return cb.is_allocated; |
|
375 | 427 |
} |
376 | 428 |
|
377 | 429 |
static int bdrv_qed_make_empty(BlockDriverState *bs) |
Also available in: Unified diff