diff options
author | Eric Blake <eblake@redhat.com> | 2017-03-08 15:34:28 -0600 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2017-03-13 12:49:33 +0100 |
commit | 6f712ee08036f4e8066cdddcfed288bf01914e55 (patch) | |
tree | 3bfcd926750194275ca58e8bf0e69ada915627c7 | |
parent | 666a9543fa957169b6e25805aac88ca72c08f0b5 (diff) |
vvfat: React to bdrv_is_allocated() errors
If bdrv_is_allocated() fails, we should react to that failure.
For 2 of the 3 callers, reporting the error was easy. But in
cluster_was_modified() and its lone caller
get_cluster_count_for_direntry(), it's rather invasive to update
the logic to pass the error back; so there, I went with merely
documenting the issue by changing the return type to bool (in
all likelihood, treating the cluster as modified will then
trigger a read which will also fail, and eventually get to an
error - but given the appalling number of abort() calls in this
code, I'm not making it any worse).
Signed-off-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
-rw-r--r-- | block/vvfat.c | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/block/vvfat.c b/block/vvfat.c index aa61c329e7..af5153d27d 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -1394,7 +1394,13 @@ static int vvfat_read(BlockDriverState *bs, int64_t sector_num, return -1; if (s->qcow) { int n; - if (bdrv_is_allocated(s->qcow->bs, sector_num, nb_sectors-i, &n)) { + int ret; + ret = bdrv_is_allocated(s->qcow->bs, sector_num, + nb_sectors - i, &n); + if (ret < 0) { + return ret; + } + if (ret) { DLOG(fprintf(stderr, "sectors %d+%d allocated\n", (int)sector_num, n)); if (bdrv_read(s->qcow, sector_num, buf + i * 0x200, n)) { @@ -1668,7 +1674,8 @@ static inline uint32_t modified_fat_get(BDRVVVFATState* s, } } -static inline int cluster_was_modified(BDRVVVFATState* s, uint32_t cluster_num) +static inline bool cluster_was_modified(BDRVVVFATState *s, + uint32_t cluster_num) { int was_modified = 0; int i, dummy; @@ -1683,7 +1690,13 @@ static inline int cluster_was_modified(BDRVVVFATState* s, uint32_t cluster_num) 1, &dummy); } - return was_modified; + /* + * Note that this treats failures to learn allocation status the + * same as if an allocation has occurred. It's as safe as + * anything else, given that a failure to learn allocation status + * will probably result in more failures. + */ + return !!was_modified; } static const char* get_basename(const char* path) @@ -1833,6 +1846,9 @@ static uint32_t get_cluster_count_for_direntry(BDRVVVFATState* s, int res; res = bdrv_is_allocated(s->qcow->bs, offset + i, 1, &dummy); + if (res < 0) { + return -1; + } if (!res) { res = vvfat_read(s->bs, offset, s->cluster_buffer, 1); if (res) { |