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 35struct 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 44typedef struct BDRVCowState { 45 int64_t cow_sectors_offset; 46} BDRVCowState; 47 48static int cow_probe(const uint8_t *buf, int buf_size, const char *filename) 49{ 50 const struct cow_header_v2 *cow_header = (const void *)buf; 51 52 if (buf_size >= sizeof(struct cow_header_v2) && 53 be32_to_cpu(cow_header->magic) == COW_MAGIC && 54 be32_to_cpu(cow_header->version) == COW_VERSION) 55 return 100; 56 else 57 return 0; 58} 59 60static int cow_open(BlockDriverState *bs, int flags) 61{ 62 BDRVCowState *s = bs->opaque; 63 struct cow_header_v2 cow_header; 64 int bitmap_size; 65 int64_t size; 66 67 /* see if it is a cow image */ 68 if (bdrv_pread(bs->file, 0, &cow_header, sizeof(cow_header)) != 69 sizeof(cow_header)) { 70 goto fail; 71 } 72 73 if (be32_to_cpu(cow_header.magic) != COW_MAGIC || 74 be32_to_cpu(cow_header.version) != COW_VERSION) { 75 goto fail; 76 } 77 78 /* cow image found */ 79 size = be64_to_cpu(cow_header.size); 80 bs->total_sectors = size / 512; 81 82 pstrcpy(bs->backing_file, sizeof(bs->backing_file), 83 cow_header.backing_file); 84 85 bitmap_size = ((bs->total_sectors + 7) >> 3) + sizeof(cow_header); 86 s->cow_sectors_offset = (bitmap_size + 511) & ~511; 87 return 0; 88 fail: 89 return -1; 90} 91 92/* 93 * XXX(hch): right now these functions are extremly ineffcient. 94 * We should just read the whole bitmap we'll need in one go instead. 95 */ 96static inline int cow_set_bit(BlockDriverState *bs, int64_t bitnum) 97{ 98 uint64_t offset = sizeof(struct cow_header_v2) + bitnum / 8; 99 uint8_t bitmap; 100 int ret; 101 102 ret = bdrv_pread(bs->file, offset, &bitmap, sizeof(bitmap)); 103 if (ret < 0) { 104 return ret; 105 } 106 107 bitmap |= (1 << (bitnum % 8)); 108 109 ret = bdrv_pwrite_sync(bs->file, offset, &bitmap, sizeof(bitmap)); 110 if (ret < 0) { 111 return ret; 112 } 113 return 0; 114} 115 116static inline int is_bit_set(BlockDriverState *bs, int64_t bitnum) 117{ 118 uint64_t offset = sizeof(struct cow_header_v2) + bitnum / 8; 119 uint8_t bitmap; 120 int ret; 121 122 ret = bdrv_pread(bs->file, offset, &bitmap, sizeof(bitmap)); 123 if (ret < 0) { 124 return ret; 125 } 126 127 return !!(bitmap & (1 << (bitnum % 8))); 128} 129 130/* Return true if first block has been changed (ie. current version is 131 * in COW file). Set the number of continuous blocks for which that 132 * is true. */ 133static int cow_is_allocated(BlockDriverState *bs, int64_t sector_num, 134 int nb_sectors, int *num_same) 135{ 136 int changed; 137 138 if (nb_sectors == 0) { 139 *num_same = nb_sectors; 140 return 0; 141 } 142 143 changed = is_bit_set(bs, sector_num); 144 if (changed < 0) { 145 return 0; /* XXX: how to return I/O errors? */ 146 } 147 148 for (*num_same = 1; *num_same < nb_sectors; (*num_same)++) { 149 if (is_bit_set(bs, sector_num + *num_same) != changed) 150 break; 151 } 152 153 return changed; 154} 155 156static int cow_update_bitmap(BlockDriverState *bs, int64_t sector_num, 157 int nb_sectors) 158{ 159 int error = 0; 160 int i; 161 162 for (i = 0; i < nb_sectors; i++) { 163 error = cow_set_bit(bs, sector_num + i); 164 if (error) { 165 break; 166 } 167 } 168 169 return error; 170} 171 172static int cow_read(BlockDriverState *bs, int64_t sector_num, 173 uint8_t *buf, int nb_sectors) 174{ 175 BDRVCowState *s = bs->opaque; 176 int ret, n; 177 178 while (nb_sectors > 0) { 179 if (cow_is_allocated(bs, sector_num, nb_sectors, &n)) { 180 ret = bdrv_pread(bs->file, 181 s->cow_sectors_offset + sector_num * 512, 182 buf, n * 512); 183 if (ret != n * 512) 184 return -1; 185 } else { 186 if (bs->backing_hd) { 187 /* read from the base image */ 188 ret = bdrv_read(bs->backing_hd, sector_num, buf, n); 189 if (ret < 0) 190 return -1; 191 } else { 192 memset(buf, 0, n * 512); 193 } 194 } 195 nb_sectors -= n; 196 sector_num += n; 197 buf += n * 512; 198 } 199 return 0; 200} 201 202static int cow_write(BlockDriverState *bs, int64_t sector_num, 203 const uint8_t *buf, int nb_sectors) 204{ 205 BDRVCowState *s = bs->opaque; 206 int ret; 207 208 ret = bdrv_pwrite(bs->file, s->cow_sectors_offset + sector_num * 512, 209 buf, nb_sectors * 512); 210 if (ret != nb_sectors * 512) 211 return -1; 212 213 return cow_update_bitmap(bs, sector_num, nb_sectors); 214} 215 216static void cow_close(BlockDriverState *bs) 217{ 218} 219 220static int cow_create(const char *filename, QEMUOptionParameter *options) 221{ 222 int fd, cow_fd; 223 struct cow_header_v2 cow_header; 224 struct stat st; 225 int64_t image_sectors = 0; 226 const char *image_filename = NULL; 227 int ret; 228 229 /* Read out options */ 230 while (options && options->name) { 231 if (!strcmp(options->name, BLOCK_OPT_SIZE)) { 232 image_sectors = options->value.n / 512; 233 } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) { 234 image_filename = options->value.s; 235 } 236 options++; 237 } 238 239 cow_fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 240 0644); 241 if (cow_fd < 0) 242 return -errno; 243 memset(&cow_header, 0, sizeof(cow_header)); 244 cow_header.magic = cpu_to_be32(COW_MAGIC); 245 cow_header.version = cpu_to_be32(COW_VERSION); 246 if (image_filename) { 247 /* Note: if no file, we put a dummy mtime */ 248 cow_header.mtime = cpu_to_be32(0); 249 250 fd = open(image_filename, O_RDONLY | O_BINARY); 251 if (fd < 0) { 252 close(cow_fd); 253 goto mtime_fail; 254 } 255 if (fstat(fd, &st) != 0) { 256 close(fd); 257 goto mtime_fail; 258 } 259 close(fd); 260 cow_header.mtime = cpu_to_be32(st.st_mtime); 261 mtime_fail: 262 pstrcpy(cow_header.backing_file, sizeof(cow_header.backing_file), 263 image_filename); 264 } 265 cow_header.sectorsize = cpu_to_be32(512); 266 cow_header.size = cpu_to_be64(image_sectors * 512); 267 ret = qemu_write_full(cow_fd, &cow_header, sizeof(cow_header)); 268 if (ret != sizeof(cow_header)) { 269 ret = -errno; 270 goto exit; 271 } 272 273 /* resize to include at least all the bitmap */ 274 ret = ftruncate(cow_fd, sizeof(cow_header) + ((image_sectors + 7) >> 3)); 275 if (ret) { 276 ret = -errno; 277 goto exit; 278 } 279 280exit: 281 close(cow_fd); 282 return ret; 283} 284 285static void cow_flush(BlockDriverState *bs) 286{ 287 bdrv_flush(bs->file); 288} 289 290static QEMUOptionParameter cow_create_options[] = { 291 { 292 .name = BLOCK_OPT_SIZE, 293 .type = OPT_SIZE, 294 .help = "Virtual disk size" 295 }, 296 { 297 .name = BLOCK_OPT_BACKING_FILE, 298 .type = OPT_STRING, 299 .help = "File name of a base image" 300 }, 301 { NULL } 302}; 303 304static BlockDriver bdrv_cow = { 305 .format_name = "cow", 306 .instance_size = sizeof(BDRVCowState), 307 .bdrv_probe = cow_probe, 308 .bdrv_open = cow_open, 309 .bdrv_read = cow_read, 310 .bdrv_write = cow_write, 311 .bdrv_close = cow_close, 312 .bdrv_create = cow_create, 313 .bdrv_flush = cow_flush, 314 .bdrv_is_allocated = cow_is_allocated, 315 316 .create_options = cow_create_options, 317}; 318 319static void bdrv_cow_init(void) 320{ 321 bdrv_register(&bdrv_cow); 322} 323 324block_init(bdrv_cow_init); 325