|
|
1.1 root 1: /*
2: * Block driver for the COW format
3: *
4: * Copyright (c) 2004 Fabrice Bellard
5: *
6: * Permission is hereby granted, free of charge, to any person obtaining a copy
7: * of this software and associated documentation files (the "Software"), to deal
8: * in the Software without restriction, including without limitation the rights
9: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10: * copies of the Software, and to permit persons to whom the Software is
11: * furnished to do so, subject to the following conditions:
12: *
13: * The above copyright notice and this permission notice shall be included in
14: * all copies or substantial portions of the Software.
15: *
16: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19: * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22: * THE SOFTWARE.
23: */
24: #include "qemu-common.h"
25: #include "block_int.h"
26: #include "module.h"
27:
28: /**************************************************************/
29: /* COW block driver using file system holes */
30:
31: /* user mode linux compatible COW file */
32: #define COW_MAGIC 0x4f4f4f4d /* MOOO */
33: #define COW_VERSION 2
34:
35: struct cow_header_v2 {
36: uint32_t magic;
37: uint32_t version;
38: char backing_file[1024];
39: int32_t mtime;
40: uint64_t size;
41: uint32_t sectorsize;
42: };
43:
44: typedef struct BDRVCowState {
1.1.1.5 root 45: CoMutex lock;
1.1 root 46: int64_t cow_sectors_offset;
47: } BDRVCowState;
48:
49: static int cow_probe(const uint8_t *buf, int buf_size, const char *filename)
50: {
51: const struct cow_header_v2 *cow_header = (const void *)buf;
52:
53: if (buf_size >= sizeof(struct cow_header_v2) &&
54: be32_to_cpu(cow_header->magic) == COW_MAGIC &&
55: be32_to_cpu(cow_header->version) == COW_VERSION)
56: return 100;
57: else
58: return 0;
59: }
60:
1.1.1.3 root 61: static int cow_open(BlockDriverState *bs, int flags)
1.1 root 62: {
63: BDRVCowState *s = bs->opaque;
64: struct cow_header_v2 cow_header;
1.1.1.3 root 65: int bitmap_size;
1.1 root 66: int64_t size;
1.1.1.6 ! root 67: int ret;
1.1 root 68:
69: /* see if it is a cow image */
1.1.1.6 ! root 70: ret = bdrv_pread(bs->file, 0, &cow_header, sizeof(cow_header));
! 71: if (ret < 0) {
! 72: goto fail;
! 73: }
! 74:
! 75: if (be32_to_cpu(cow_header.magic) != COW_MAGIC) {
! 76: ret = -EINVAL;
1.1 root 77: goto fail;
78: }
79:
1.1.1.6 ! root 80: if (be32_to_cpu(cow_header.version) != COW_VERSION) {
! 81: char version[64];
! 82: snprintf(version, sizeof(version),
! 83: "COW version %d", cow_header.version);
! 84: qerror_report(QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,
! 85: bs->device_name, "cow", version);
! 86: ret = -ENOTSUP;
1.1 root 87: goto fail;
88: }
89:
90: /* cow image found */
91: size = be64_to_cpu(cow_header.size);
92: bs->total_sectors = size / 512;
93:
94: pstrcpy(bs->backing_file, sizeof(bs->backing_file),
95: cow_header.backing_file);
96:
1.1.1.3 root 97: bitmap_size = ((bs->total_sectors + 7) >> 3) + sizeof(cow_header);
98: s->cow_sectors_offset = (bitmap_size + 511) & ~511;
1.1.1.5 root 99: qemu_co_mutex_init(&s->lock);
1.1 root 100: return 0;
101: fail:
1.1.1.6 ! root 102: return ret;
1.1 root 103: }
104:
1.1.1.3 root 105: /*
1.1.1.6 ! root 106: * XXX(hch): right now these functions are extremely inefficient.
1.1.1.3 root 107: * We should just read the whole bitmap we'll need in one go instead.
108: */
109: static inline int cow_set_bit(BlockDriverState *bs, int64_t bitnum)
110: {
111: uint64_t offset = sizeof(struct cow_header_v2) + bitnum / 8;
112: uint8_t bitmap;
113: int ret;
114:
115: ret = bdrv_pread(bs->file, offset, &bitmap, sizeof(bitmap));
116: if (ret < 0) {
117: return ret;
118: }
119:
120: bitmap |= (1 << (bitnum % 8));
121:
122: ret = bdrv_pwrite_sync(bs->file, offset, &bitmap, sizeof(bitmap));
123: if (ret < 0) {
124: return ret;
125: }
126: return 0;
1.1 root 127: }
128:
1.1.1.3 root 129: static inline int is_bit_set(BlockDriverState *bs, int64_t bitnum)
1.1 root 130: {
1.1.1.3 root 131: uint64_t offset = sizeof(struct cow_header_v2) + bitnum / 8;
132: uint8_t bitmap;
133: int ret;
134:
135: ret = bdrv_pread(bs->file, offset, &bitmap, sizeof(bitmap));
136: if (ret < 0) {
137: return ret;
138: }
1.1 root 139:
1.1.1.3 root 140: return !!(bitmap & (1 << (bitnum % 8)));
141: }
1.1 root 142:
143: /* Return true if first block has been changed (ie. current version is
144: * in COW file). Set the number of continuous blocks for which that
145: * is true. */
1.1.1.6 ! root 146: static int coroutine_fn cow_co_is_allocated(BlockDriverState *bs,
! 147: int64_t sector_num, int nb_sectors, int *num_same)
1.1 root 148: {
149: int changed;
150:
1.1.1.3 root 151: if (nb_sectors == 0) {
1.1 root 152: *num_same = nb_sectors;
153: return 0;
154: }
155:
1.1.1.3 root 156: changed = is_bit_set(bs, sector_num);
157: if (changed < 0) {
158: return 0; /* XXX: how to return I/O errors? */
159: }
160:
1.1 root 161: for (*num_same = 1; *num_same < nb_sectors; (*num_same)++) {
1.1.1.3 root 162: if (is_bit_set(bs, sector_num + *num_same) != changed)
1.1 root 163: break;
164: }
165:
166: return changed;
167: }
168:
1.1.1.3 root 169: static int cow_update_bitmap(BlockDriverState *bs, int64_t sector_num,
170: int nb_sectors)
1.1 root 171: {
1.1.1.3 root 172: int error = 0;
173: int i;
174:
175: for (i = 0; i < nb_sectors; i++) {
176: error = cow_set_bit(bs, sector_num + i);
177: if (error) {
178: break;
179: }
180: }
181:
182: return error;
1.1 root 183: }
184:
1.1.1.6 ! root 185: static int coroutine_fn cow_read(BlockDriverState *bs, int64_t sector_num,
! 186: uint8_t *buf, int nb_sectors)
1.1 root 187: {
188: BDRVCowState *s = bs->opaque;
189: int ret, n;
190:
191: while (nb_sectors > 0) {
1.1.1.6 ! root 192: if (bdrv_co_is_allocated(bs, sector_num, nb_sectors, &n)) {
1.1.1.3 root 193: ret = bdrv_pread(bs->file,
194: s->cow_sectors_offset + sector_num * 512,
195: buf, n * 512);
1.1.1.6 ! root 196: if (ret < 0) {
! 197: return ret;
! 198: }
1.1 root 199: } else {
200: if (bs->backing_hd) {
201: /* read from the base image */
202: ret = bdrv_read(bs->backing_hd, sector_num, buf, n);
1.1.1.6 ! root 203: if (ret < 0) {
! 204: return ret;
! 205: }
1.1 root 206: } else {
1.1.1.6 ! root 207: memset(buf, 0, n * 512);
! 208: }
1.1 root 209: }
210: nb_sectors -= n;
211: sector_num += n;
212: buf += n * 512;
213: }
214: return 0;
215: }
216:
1.1.1.5 root 217: static coroutine_fn int cow_co_read(BlockDriverState *bs, int64_t sector_num,
218: uint8_t *buf, int nb_sectors)
219: {
220: int ret;
221: BDRVCowState *s = bs->opaque;
222: qemu_co_mutex_lock(&s->lock);
223: ret = cow_read(bs, sector_num, buf, nb_sectors);
224: qemu_co_mutex_unlock(&s->lock);
225: return ret;
226: }
227:
1.1 root 228: static int cow_write(BlockDriverState *bs, int64_t sector_num,
229: const uint8_t *buf, int nb_sectors)
230: {
231: BDRVCowState *s = bs->opaque;
1.1.1.3 root 232: int ret;
1.1 root 233:
1.1.1.3 root 234: ret = bdrv_pwrite(bs->file, s->cow_sectors_offset + sector_num * 512,
235: buf, nb_sectors * 512);
1.1.1.6 ! root 236: if (ret < 0) {
! 237: return ret;
! 238: }
1.1.1.3 root 239:
240: return cow_update_bitmap(bs, sector_num, nb_sectors);
1.1 root 241: }
242:
1.1.1.5 root 243: static coroutine_fn int cow_co_write(BlockDriverState *bs, int64_t sector_num,
244: const uint8_t *buf, int nb_sectors)
245: {
246: int ret;
247: BDRVCowState *s = bs->opaque;
248: qemu_co_mutex_lock(&s->lock);
249: ret = cow_write(bs, sector_num, buf, nb_sectors);
250: qemu_co_mutex_unlock(&s->lock);
251: return ret;
252: }
253:
1.1 root 254: static void cow_close(BlockDriverState *bs)
255: {
256: }
257:
258: static int cow_create(const char *filename, QEMUOptionParameter *options)
259: {
260: struct cow_header_v2 cow_header;
261: struct stat st;
262: int64_t image_sectors = 0;
263: const char *image_filename = NULL;
1.1.1.3 root 264: int ret;
1.1.1.6 ! root 265: BlockDriverState *cow_bs;
1.1 root 266:
267: /* Read out options */
268: while (options && options->name) {
269: if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
270: image_sectors = options->value.n / 512;
271: } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
272: image_filename = options->value.s;
273: }
274: options++;
275: }
276:
1.1.1.6 ! root 277: ret = bdrv_create_file(filename, options);
! 278: if (ret < 0) {
! 279: return ret;
! 280: }
! 281:
! 282: ret = bdrv_file_open(&cow_bs, filename, BDRV_O_RDWR);
! 283: if (ret < 0) {
! 284: return ret;
! 285: }
! 286:
1.1 root 287: memset(&cow_header, 0, sizeof(cow_header));
288: cow_header.magic = cpu_to_be32(COW_MAGIC);
289: cow_header.version = cpu_to_be32(COW_VERSION);
290: if (image_filename) {
291: /* Note: if no file, we put a dummy mtime */
292: cow_header.mtime = cpu_to_be32(0);
293:
1.1.1.6 ! root 294: if (stat(image_filename, &st) != 0) {
1.1 root 295: goto mtime_fail;
296: }
297: cow_header.mtime = cpu_to_be32(st.st_mtime);
298: mtime_fail:
299: pstrcpy(cow_header.backing_file, sizeof(cow_header.backing_file),
300: image_filename);
301: }
302: cow_header.sectorsize = cpu_to_be32(512);
303: cow_header.size = cpu_to_be64(image_sectors * 512);
1.1.1.6 ! root 304: ret = bdrv_pwrite(cow_bs, 0, &cow_header, sizeof(cow_header));
! 305: if (ret < 0) {
1.1.1.3 root 306: goto exit;
307: }
308:
1.1 root 309: /* resize to include at least all the bitmap */
1.1.1.6 ! root 310: ret = bdrv_truncate(cow_bs,
! 311: sizeof(cow_header) + ((image_sectors + 7) >> 3));
! 312: if (ret < 0) {
1.1.1.3 root 313: goto exit;
314: }
315:
316: exit:
1.1.1.6 ! root 317: bdrv_delete(cow_bs);
1.1.1.3 root 318: return ret;
1.1 root 319: }
320:
321: static QEMUOptionParameter cow_create_options[] = {
322: {
323: .name = BLOCK_OPT_SIZE,
324: .type = OPT_SIZE,
325: .help = "Virtual disk size"
326: },
327: {
328: .name = BLOCK_OPT_BACKING_FILE,
329: .type = OPT_STRING,
330: .help = "File name of a base image"
331: },
332: { NULL }
333: };
334:
335: static BlockDriver bdrv_cow = {
1.1.1.5 root 336: .format_name = "cow",
337: .instance_size = sizeof(BDRVCowState),
338:
339: .bdrv_probe = cow_probe,
340: .bdrv_open = cow_open,
341: .bdrv_close = cow_close,
342: .bdrv_create = cow_create,
343:
344: .bdrv_read = cow_co_read,
345: .bdrv_write = cow_co_write,
1.1.1.6 ! root 346: .bdrv_co_is_allocated = cow_co_is_allocated,
1.1 root 347:
348: .create_options = cow_create_options,
349: };
350:
351: static void bdrv_cow_init(void)
352: {
353: bdrv_register(&bdrv_cow);
354: }
355:
356: block_init(bdrv_cow_init);
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.