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