2 #include "qemu-common.h"
6 static int raw_open(BlockDriverState
*bs
, int flags
)
12 /* check for the user attempting to write something that looks like a
13 block format header to the beginning of the image and fail out.
15 static int check_for_block_signature(BlockDriverState
*bs
, const uint8_t *buf
)
17 static const uint8_t signatures
[][4] = {
18 { 'Q', 'F', 'I', 0xfb }, /* qcow/qcow2 */
19 { 'C', 'O', 'W', 'D' }, /* VMDK3 */
20 { 'V', 'M', 'D', 'K' }, /* VMDK4 */
21 { 'O', 'O', 'O', 'M' }, /* UML COW */
26 for (i
= 0; signatures
[i
][0] != 0; i
++) {
27 if (memcmp(buf
, signatures
[i
], 4) == 0) {
35 static int check_write_unsafe(BlockDriverState
*bs
, int64_t sector_num
,
36 const uint8_t *buf
, int nb_sectors
)
38 /* assume that if the user specifies the format explicitly, then assume
39 that they will continue to do so and provide no safety net */
44 if (sector_num
== 0 && nb_sectors
> 0) {
45 return check_for_block_signature(bs
, buf
);
51 static int raw_read(BlockDriverState
*bs
, int64_t sector_num
,
52 uint8_t *buf
, int nb_sectors
)
54 return bdrv_read(bs
->file
, sector_num
, buf
, nb_sectors
);
57 static int raw_write_scrubbed_bootsect(BlockDriverState
*bs
,
60 uint8_t bootsect
[512];
62 /* scrub the dangerous signature */
63 memcpy(bootsect
, buf
, 512);
64 memset(bootsect
, 0, 4);
66 return bdrv_write(bs
->file
, 0, bootsect
, 1);
69 static int raw_write(BlockDriverState
*bs
, int64_t sector_num
,
70 const uint8_t *buf
, int nb_sectors
)
72 if (check_write_unsafe(bs
, sector_num
, buf
, nb_sectors
)) {
75 ret
= raw_write_scrubbed_bootsect(bs
, buf
);
80 ret
= bdrv_write(bs
->file
, 1, buf
+ 512, nb_sectors
- 1);
88 return bdrv_write(bs
->file
, sector_num
, buf
, nb_sectors
);
91 static BlockDriverAIOCB
*raw_aio_readv(BlockDriverState
*bs
,
92 int64_t sector_num
, QEMUIOVector
*qiov
, int nb_sectors
,
93 BlockDriverCompletionFunc
*cb
, void *opaque
)
95 return bdrv_aio_readv(bs
->file
, sector_num
, qiov
, nb_sectors
, cb
, opaque
);
98 typedef struct RawScrubberBounce
100 BlockDriverCompletionFunc
*cb
;
105 static void raw_aio_writev_scrubbed(void *opaque
, int ret
)
107 RawScrubberBounce
*b
= opaque
;
110 b
->cb(b
->opaque
, ret
);
112 b
->cb(b
->opaque
, ret
+ 512);
115 qemu_iovec_destroy(&b
->qiov
);
119 static BlockDriverAIOCB
*raw_aio_writev(BlockDriverState
*bs
,
120 int64_t sector_num
, QEMUIOVector
*qiov
, int nb_sectors
,
121 BlockDriverCompletionFunc
*cb
, void *opaque
)
123 const uint8_t *first_buf
;
124 int first_buf_index
= 0, i
;
126 /* This is probably being paranoid, but handle cases of zero size
128 for (i
= 0; i
< qiov
->niov
; i
++) {
129 if (qiov
->iov
[i
].iov_len
) {
130 assert(qiov
->iov
[i
].iov_len
>= 512);
136 first_buf
= qiov
->iov
[first_buf_index
].iov_base
;
138 if (check_write_unsafe(bs
, sector_num
, first_buf
, nb_sectors
)) {
139 RawScrubberBounce
*b
;
142 /* write the first sector using sync I/O */
143 ret
= raw_write_scrubbed_bootsect(bs
, first_buf
);
148 /* adjust request to be everything but first sector */
150 b
= qemu_malloc(sizeof(*b
));
154 qemu_iovec_init(&b
->qiov
, qiov
->nalloc
);
155 qemu_iovec_concat(&b
->qiov
, qiov
, qiov
->size
);
158 b
->qiov
.iov
[first_buf_index
].iov_base
+= 512;
159 b
->qiov
.iov
[first_buf_index
].iov_len
-= 512;
161 return bdrv_aio_writev(bs
->file
, sector_num
+ 1, &b
->qiov
,
162 nb_sectors
- 1, raw_aio_writev_scrubbed
, b
);
165 return bdrv_aio_writev(bs
->file
, sector_num
, qiov
, nb_sectors
, cb
, opaque
);
168 static void raw_close(BlockDriverState
*bs
)
172 static void raw_flush(BlockDriverState
*bs
)
174 bdrv_flush(bs
->file
);
177 static BlockDriverAIOCB
*raw_aio_flush(BlockDriverState
*bs
,
178 BlockDriverCompletionFunc
*cb
, void *opaque
)
180 return bdrv_aio_flush(bs
->file
, cb
, opaque
);
183 static int64_t raw_getlength(BlockDriverState
*bs
)
185 return bdrv_getlength(bs
->file
);
188 static int raw_truncate(BlockDriverState
*bs
, int64_t offset
)
190 return bdrv_truncate(bs
->file
, offset
);
193 static int raw_probe(const uint8_t *buf
, int buf_size
, const char *filename
)
195 return 1; /* everything can be opened as raw image */
198 static int raw_is_inserted(BlockDriverState
*bs
)
200 return bdrv_is_inserted(bs
->file
);
203 static int raw_eject(BlockDriverState
*bs
, int eject_flag
)
205 return bdrv_eject(bs
->file
, eject_flag
);
208 static int raw_set_locked(BlockDriverState
*bs
, int locked
)
210 bdrv_set_locked(bs
->file
, locked
);
214 static int raw_ioctl(BlockDriverState
*bs
, unsigned long int req
, void *buf
)
216 return bdrv_ioctl(bs
->file
, req
, buf
);
219 static BlockDriverAIOCB
*raw_aio_ioctl(BlockDriverState
*bs
,
220 unsigned long int req
, void *buf
,
221 BlockDriverCompletionFunc
*cb
, void *opaque
)
223 return bdrv_aio_ioctl(bs
->file
, req
, buf
, cb
, opaque
);
226 static int raw_create(const char *filename
, QEMUOptionParameter
*options
)
228 return bdrv_create_file(filename
, options
);
231 static QEMUOptionParameter raw_create_options
[] = {
233 .name
= BLOCK_OPT_SIZE
,
235 .help
= "Virtual disk size"
240 static int raw_has_zero_init(BlockDriverState
*bs
)
242 return bdrv_has_zero_init(bs
->file
);
245 static BlockDriver bdrv_raw
= {
246 .format_name
= "raw",
248 /* It's really 0, but we need to make qemu_malloc() happy */
251 .bdrv_open
= raw_open
,
252 .bdrv_close
= raw_close
,
253 .bdrv_read
= raw_read
,
254 .bdrv_write
= raw_write
,
255 .bdrv_flush
= raw_flush
,
256 .bdrv_probe
= raw_probe
,
257 .bdrv_getlength
= raw_getlength
,
258 .bdrv_truncate
= raw_truncate
,
260 .bdrv_aio_readv
= raw_aio_readv
,
261 .bdrv_aio_writev
= raw_aio_writev
,
262 .bdrv_aio_flush
= raw_aio_flush
,
264 .bdrv_is_inserted
= raw_is_inserted
,
265 .bdrv_eject
= raw_eject
,
266 .bdrv_set_locked
= raw_set_locked
,
267 .bdrv_ioctl
= raw_ioctl
,
268 .bdrv_aio_ioctl
= raw_aio_ioctl
,
270 .bdrv_create
= raw_create
,
271 .create_options
= raw_create_options
,
272 .bdrv_has_zero_init
= raw_has_zero_init
,
275 static void bdrv_raw_init(void)
277 bdrv_register(&bdrv_raw
);
280 block_init(bdrv_raw_init
);