Revision 5fafdf24 block-bochs.c
b/block-bochs.c | ||
---|---|---|
1 | 1 |
/* |
2 | 2 |
* Block driver for the various disk image formats used by Bochs |
3 | 3 |
* Currently only for "growing" type in read-only mode |
4 |
*
|
|
4 |
* |
|
5 | 5 |
* Copyright (c) 2005 Alex Beregszaszi |
6 |
*
|
|
6 |
* |
|
7 | 7 |
* Permission is hereby granted, free of charge, to any person obtaining a copy |
8 | 8 |
* of this software and associated documentation files (the "Software"), to deal |
9 | 9 |
* in the Software without restriction, including without limitation the rights |
... | ... | |
44 | 44 |
char subtype[16]; // "Undoable" / "Volatile" / "Growing" |
45 | 45 |
uint32_t version; |
46 | 46 |
uint32_t header; // size of header |
47 |
|
|
47 |
|
|
48 | 48 |
union { |
49 | 49 |
struct { |
50 | 50 |
uint32_t catalog; // num of entries |
... | ... | |
64 | 64 |
char subtype[16]; // "Undoable" / "Volatile" / "Growing" |
65 | 65 |
uint32_t version; |
66 | 66 |
uint32_t header; // size of header |
67 |
|
|
67 |
|
|
68 | 68 |
union { |
69 | 69 |
struct { |
70 | 70 |
uint32_t catalog; // num of entries |
... | ... | |
83 | 83 |
|
84 | 84 |
uint32_t *catalog_bitmap; |
85 | 85 |
int catalog_size; |
86 |
|
|
86 |
|
|
87 | 87 |
int data_offset; |
88 |
|
|
88 |
|
|
89 | 89 |
int bitmap_blocks; |
90 | 90 |
int extent_blocks; |
91 | 91 |
int extent_size; |
... | ... | |
94 | 94 |
static int bochs_probe(const uint8_t *buf, int buf_size, const char *filename) |
95 | 95 |
{ |
96 | 96 |
const struct bochs_header *bochs = (const void *)buf; |
97 |
|
|
97 |
|
|
98 | 98 |
if (buf_size < HEADER_SIZE) |
99 | 99 |
return 0; |
100 | 100 |
|
... | ... | |
121 | 121 |
if (fd < 0) |
122 | 122 |
return -1; |
123 | 123 |
} |
124 |
|
|
124 |
|
|
125 | 125 |
bs->read_only = 1; // no write support yet |
126 |
|
|
126 |
|
|
127 | 127 |
s->fd = fd; |
128 | 128 |
|
129 | 129 |
if (read(fd, &bochs, sizeof(bochs)) != sizeof(bochs)) { |
... | ... | |
161 | 161 |
|
162 | 162 |
s->bitmap_blocks = 1 + (le32_to_cpu(bochs.extra.redolog.bitmap) - 1) / 512; |
163 | 163 |
s->extent_blocks = 1 + (le32_to_cpu(bochs.extra.redolog.extent) - 1) / 512; |
164 |
|
|
164 |
|
|
165 | 165 |
s->extent_size = le32_to_cpu(bochs.extra.redolog.extent); |
166 | 166 |
|
167 | 167 |
return 0; |
... | ... | |
180 | 180 |
// seek to sector |
181 | 181 |
extent_index = offset / s->extent_size; |
182 | 182 |
extent_offset = (offset % s->extent_size) / 512; |
183 |
|
|
183 |
|
|
184 | 184 |
if (s->catalog_bitmap[extent_index] == 0xffffffff) |
185 | 185 |
{ |
186 | 186 |
// fprintf(stderr, "page not allocated [%x - %x:%x]\n", |
... | ... | |
191 | 191 |
bitmap_offset = s->data_offset + (512 * s->catalog_bitmap[extent_index] * |
192 | 192 |
(s->extent_blocks + s->bitmap_blocks)); |
193 | 193 |
block_offset = bitmap_offset + (512 * (s->bitmap_blocks + extent_offset)); |
194 |
|
|
194 |
|
|
195 | 195 |
// fprintf(stderr, "sect: %x [ext i: %x o: %x] -> %x bitmap: %x block: %x\n", |
196 | 196 |
// sector_num, extent_index, extent_offset, |
197 | 197 |
// le32_to_cpu(s->catalog_bitmap[extent_index]), |
198 | 198 |
// bitmap_offset, block_offset); |
199 |
|
|
199 |
|
|
200 | 200 |
// read in bitmap for current extent |
201 | 201 |
lseek(s->fd, bitmap_offset + (extent_offset / 8), SEEK_SET); |
202 |
|
|
202 |
|
|
203 | 203 |
read(s->fd, &bitmap_entry, 1); |
204 |
|
|
204 |
|
|
205 | 205 |
if (!((bitmap_entry >> (extent_offset % 8)) & 1)) |
206 | 206 |
{ |
207 | 207 |
// fprintf(stderr, "sector (%x) in bitmap not allocated\n", |
... | ... | |
210 | 210 |
} |
211 | 211 |
|
212 | 212 |
lseek(s->fd, block_offset, SEEK_SET); |
213 |
|
|
213 |
|
|
214 | 214 |
return 0; |
215 | 215 |
} |
216 | 216 |
|
217 |
static int bochs_read(BlockDriverState *bs, int64_t sector_num,
|
|
217 |
static int bochs_read(BlockDriverState *bs, int64_t sector_num, |
|
218 | 218 |
uint8_t *buf, int nb_sectors) |
219 | 219 |
{ |
220 | 220 |
BDRVBochsState *s = bs->opaque; |
Also available in: Unified diff