mirror of https://github.com/xemu-project/xemu.git
block: Improve get_allocated_file_size's default
There are two practical problems with bdrv_get_allocated_file_size()'s default right now: (1) For drivers with children, we should generally sum all their sizes instead of just passing the request through to bs->file. The latter is good for filters, but not so much for format drivers. (2) Filters need not have bs->file, so we should actually go to the filtered child instead of hard-coding bs->file. Fix this by splitting the default implementation into three branches: (1) For filter drivers: Return the size of the filtered child (2) For protocol drivers: Return -ENOTSUP, because the default implementation cannot make a guess (3) For other drivers: Sum all data-bearing children's sizes Signed-off-by: Max Reitz <mreitz@redhat.com>
This commit is contained in:
parent
f706a92f24
commit
081e465026
42
block.c
42
block.c
|
@ -5005,6 +5005,31 @@ exit:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of BlockDriver.bdrv_get_allocated_file_size() that
|
||||||
|
* sums the size of all data-bearing children. (This excludes backing
|
||||||
|
* children.)
|
||||||
|
*/
|
||||||
|
static int64_t bdrv_sum_allocated_file_size(BlockDriverState *bs)
|
||||||
|
{
|
||||||
|
BdrvChild *child;
|
||||||
|
int64_t child_size, sum = 0;
|
||||||
|
|
||||||
|
QLIST_FOREACH(child, &bs->children, next) {
|
||||||
|
if (child->role & (BDRV_CHILD_DATA | BDRV_CHILD_METADATA |
|
||||||
|
BDRV_CHILD_FILTERED))
|
||||||
|
{
|
||||||
|
child_size = bdrv_get_allocated_file_size(child->bs);
|
||||||
|
if (child_size < 0) {
|
||||||
|
return child_size;
|
||||||
|
}
|
||||||
|
sum += child_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Length of a allocated file in bytes. Sparse files are counted by actual
|
* Length of a allocated file in bytes. Sparse files are counted by actual
|
||||||
* allocated space. Return < 0 if error or unknown.
|
* allocated space. Return < 0 if error or unknown.
|
||||||
|
@ -5018,10 +5043,21 @@ int64_t bdrv_get_allocated_file_size(BlockDriverState *bs)
|
||||||
if (drv->bdrv_get_allocated_file_size) {
|
if (drv->bdrv_get_allocated_file_size) {
|
||||||
return drv->bdrv_get_allocated_file_size(bs);
|
return drv->bdrv_get_allocated_file_size(bs);
|
||||||
}
|
}
|
||||||
if (bs->file) {
|
|
||||||
return bdrv_get_allocated_file_size(bs->file->bs);
|
if (drv->bdrv_file_open) {
|
||||||
|
/*
|
||||||
|
* Protocol drivers default to -ENOTSUP (most of their data is
|
||||||
|
* not stored in any of their children (if they even have any),
|
||||||
|
* so there is no generic way to figure it out).
|
||||||
|
*/
|
||||||
|
return -ENOTSUP;
|
||||||
|
} else if (drv->is_filter) {
|
||||||
|
/* Filter drivers default to the size of their filtered child */
|
||||||
|
return bdrv_get_allocated_file_size(bdrv_filter_bs(bs));
|
||||||
|
} else {
|
||||||
|
/* Other drivers default to summing their children's sizes */
|
||||||
|
return bdrv_sum_allocated_file_size(bs);
|
||||||
}
|
}
|
||||||
return -ENOTSUP;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue