Commit b71d1c2e1135328301a763a6c91db0556c00b913
1 parent
1fa79228
block-vpc: Use the qemu block layer (Kevin Wolf)
Instead of accessing the file directly, use the qemu block layer. Signed-off-by: Kevin Wolf <kwolf@suse.de> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6457 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
32 additions
and
27 deletions
block-vpc.c
| ... | ... | @@ -105,7 +105,7 @@ struct vhd_dyndisk_header { |
| 105 | 105 | }; |
| 106 | 106 | |
| 107 | 107 | typedef struct BDRVVPCState { |
| 108 | - int fd; | |
| 108 | + BlockDriverState *hd; | |
| 109 | 109 | |
| 110 | 110 | int max_table_entries; |
| 111 | 111 | uint32_t *pagetable; |
| ... | ... | @@ -130,20 +130,18 @@ static int vpc_probe(const uint8_t *buf, int buf_size, const char *filename) |
| 130 | 130 | static int vpc_open(BlockDriverState *bs, const char *filename, int flags) |
| 131 | 131 | { |
| 132 | 132 | BDRVVPCState *s = bs->opaque; |
| 133 | - int fd, i; | |
| 133 | + int ret, i; | |
| 134 | 134 | struct vhd_footer* footer; |
| 135 | 135 | struct vhd_dyndisk_header* dyndisk_header; |
| 136 | 136 | uint8_t buf[HEADER_SIZE]; |
| 137 | 137 | |
| 138 | - fd = open(filename, O_RDONLY | O_BINARY); | |
| 139 | - if (fd < 0) | |
| 140 | - return -1; | |
| 141 | - | |
| 142 | 138 | bs->read_only = 1; // no write support yet |
| 143 | 139 | |
| 144 | - s->fd = fd; | |
| 140 | + ret = bdrv_file_open(&s->hd, filename, flags); | |
| 141 | + if (ret < 0) | |
| 142 | + return ret; | |
| 145 | 143 | |
| 146 | - if (read(fd, buf, HEADER_SIZE) != HEADER_SIZE) | |
| 144 | + if (bdrv_pread(s->hd, 0, buf, HEADER_SIZE) != HEADER_SIZE) | |
| 147 | 145 | goto fail; |
| 148 | 146 | |
| 149 | 147 | footer = (struct vhd_footer*) buf; |
| ... | ... | @@ -156,8 +154,8 @@ static int vpc_open(BlockDriverState *bs, const char *filename, int flags) |
| 156 | 154 | bs->total_sectors = (int64_t) |
| 157 | 155 | be16_to_cpu(footer->cyls) * footer->heads * footer->secs_per_cyl; |
| 158 | 156 | |
| 159 | - lseek(s->fd, be64_to_cpu(footer->data_offset), SEEK_SET); | |
| 160 | - if (read(fd, buf, HEADER_SIZE) != HEADER_SIZE) | |
| 157 | + if (bdrv_pread(s->hd, be64_to_cpu(footer->data_offset), buf, HEADER_SIZE) | |
| 158 | + != HEADER_SIZE) | |
| 161 | 159 | goto fail; |
| 162 | 160 | |
| 163 | 161 | footer = NULL; |
| ... | ... | @@ -166,15 +164,16 @@ static int vpc_open(BlockDriverState *bs, const char *filename, int flags) |
| 166 | 164 | if (strncmp(dyndisk_header->magic, "cxsparse", 8)) |
| 167 | 165 | goto fail; |
| 168 | 166 | |
| 169 | - lseek(s->fd, be64_to_cpu(dyndisk_header->table_offset), SEEK_SET); | |
| 170 | 167 | |
| 171 | 168 | s->max_table_entries = be32_to_cpu(dyndisk_header->max_table_entries); |
| 172 | 169 | s->pagetable = qemu_malloc(s->max_table_entries * 4); |
| 173 | 170 | if (!s->pagetable) |
| 174 | - goto fail; | |
| 175 | - if (read(s->fd, s->pagetable, s->max_table_entries * 4) != | |
| 176 | - s->max_table_entries * 4) | |
| 177 | - goto fail; | |
| 171 | + goto fail; | |
| 172 | + | |
| 173 | + if (bdrv_pread(s->hd, be64_to_cpu(dyndisk_header->table_offset), | |
| 174 | + s->pagetable, s->max_table_entries * 4) != s->max_table_entries * 4) | |
| 175 | + goto fail; | |
| 176 | + | |
| 178 | 177 | for (i = 0; i < s->max_table_entries; i++) |
| 179 | 178 | be32_to_cpus(&s->pagetable[i]); |
| 180 | 179 | |
| ... | ... | @@ -190,11 +189,15 @@ static int vpc_open(BlockDriverState *bs, const char *filename, int flags) |
| 190 | 189 | |
| 191 | 190 | return 0; |
| 192 | 191 | fail: |
| 193 | - close(fd); | |
| 192 | + bdrv_delete(s->hd); | |
| 194 | 193 | return -1; |
| 195 | 194 | } |
| 196 | 195 | |
| 197 | -static inline int seek_to_sector(BlockDriverState *bs, int64_t sector_num) | |
| 196 | +/* | |
| 197 | + * Returns the absolute byte offset of the given sector in the image file. | |
| 198 | + * If the sector is not allocated, -1 is returned instead. | |
| 199 | + */ | |
| 200 | +static inline int64_t get_sector_offset(BlockDriverState *bs, int64_t sector_num) | |
| 198 | 201 | { |
| 199 | 202 | BDRVVPCState *s = bs->opaque; |
| 200 | 203 | uint64_t offset = sector_num * 512; |
| ... | ... | @@ -241,9 +244,8 @@ static inline int seek_to_sector(BlockDriverState *bs, int64_t sector_num) |
| 241 | 244 | return -1; // not allocated |
| 242 | 245 | #endif |
| 243 | 246 | #endif |
| 244 | - lseek(s->fd, block_offset, SEEK_SET); | |
| 245 | 247 | |
| 246 | - return 0; | |
| 248 | + return block_offset; | |
| 247 | 249 | } |
| 248 | 250 | |
| 249 | 251 | static int vpc_read(BlockDriverState *bs, int64_t sector_num, |
| ... | ... | @@ -251,16 +253,19 @@ static int vpc_read(BlockDriverState *bs, int64_t sector_num, |
| 251 | 253 | { |
| 252 | 254 | BDRVVPCState *s = bs->opaque; |
| 253 | 255 | int ret; |
| 256 | + int64_t offset; | |
| 254 | 257 | |
| 255 | 258 | while (nb_sectors > 0) { |
| 256 | - if (!seek_to_sector(bs, sector_num)) | |
| 257 | - { | |
| 258 | - ret = read(s->fd, buf, 512); | |
| 259 | - if (ret != 512) | |
| 260 | - return -1; | |
| 261 | - } | |
| 262 | - else | |
| 259 | + offset = get_sector_offset(bs, sector_num); | |
| 260 | + | |
| 261 | + if (offset == -1) { | |
| 263 | 262 | memset(buf, 0, 512); |
| 263 | + } else { | |
| 264 | + ret = bdrv_pread(s->hd, offset, buf, 512); | |
| 265 | + if (ret != 512) | |
| 266 | + return -1; | |
| 267 | + } | |
| 268 | + | |
| 264 | 269 | nb_sectors--; |
| 265 | 270 | sector_num++; |
| 266 | 271 | buf += 512; |
| ... | ... | @@ -275,7 +280,7 @@ static void vpc_close(BlockDriverState *bs) |
| 275 | 280 | #ifdef CACHE |
| 276 | 281 | qemu_free(s->pageentry_u8); |
| 277 | 282 | #endif |
| 278 | - close(s->fd); | |
| 283 | + bdrv_delete(s->hd); | |
| 279 | 284 | } |
| 280 | 285 | |
| 281 | 286 | BlockDriver bdrv_vpc = { | ... | ... |