Revision b71d1c2e
b/block-vpc.c | ||
---|---|---|
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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 = { |
Also available in: Unified diff