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 #ifndef _WIN32 25 #include "qemu-common.h" 26 #include "block_int.h" 27 #include "module.h" 28 #include <sys/mman.h> 29 30 /**************************************************************/ 31 /* COW block driver using file system holes */ 32 33 /* user mode linux compatible COW file */ 34 #define COW_MAGIC 0x4f4f4f4d /* MOOO */ 35 #define COW_VERSION 2 36 37 struct cow_header_v2 { 38 uint32_t magic; 39 uint32_t version; 40 char backing_file[1024]; 41 int32_t mtime; 42 uint64_t size; 43 uint32_t sectorsize; 44 }; 45 46 typedef struct BDRVCowState { 47 int fd; 48 uint8_t *cow_bitmap; /* if non NULL, COW mappings are used first */ 49 uint8_t *cow_bitmap_addr; /* mmap address of cow_bitmap */ 50 int cow_bitmap_size; 51 int64_t cow_sectors_offset; 52 } BDRVCowState; 53 54 static int cow_probe(const uint8_t *buf, int buf_size, const char *filename) 55 { 56 const struct cow_header_v2 *cow_header = (const void *)buf; 57 58 if (buf_size >= sizeof(struct cow_header_v2) && 59 be32_to_cpu(cow_header->magic) == COW_MAGIC && 60 be32_to_cpu(cow_header->version) == COW_VERSION) 61 return 100; 62 else 63 return 0; 64 } 65 66 static int cow_open(BlockDriverState *bs, const char *filename, int flags) 67 { 68 BDRVCowState *s = bs->opaque; 69 int fd; 70 struct cow_header_v2 cow_header; 71 int64_t size; 72 73 fd = open(filename, O_RDWR | O_BINARY | O_LARGEFILE); 74 if (fd < 0) { 75 fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE); 76 if (fd < 0) 77 return -1; 78 } 79 s->fd = fd; 80 /* see if it is a cow image */ 81 if (read(fd, &cow_header, sizeof(cow_header)) != sizeof(cow_header)) { 82 goto fail; 83 } 84 85 if (be32_to_cpu(cow_header.magic) != COW_MAGIC || 86 be32_to_cpu(cow_header.version) != COW_VERSION) { 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 97 /* mmap the bitmap */ 98 s->cow_bitmap_size = ((bs->total_sectors + 7) >> 3) + sizeof(cow_header); 99 s->cow_bitmap_addr = (void *)mmap(get_mmap_addr(s->cow_bitmap_size), 100 s->cow_bitmap_size, 101 PROT_READ | PROT_WRITE, 102 MAP_SHARED, s->fd, 0); 103 if (s->cow_bitmap_addr == MAP_FAILED) 104 goto fail; 105 s->cow_bitmap = s->cow_bitmap_addr + sizeof(cow_header); 106 s->cow_sectors_offset = (s->cow_bitmap_size + 511) & ~511; 107 return 0; 108 fail: 109 close(fd); 110 return -1; 111 } 112 113 static inline void cow_set_bit(uint8_t *bitmap, int64_t bitnum) 114 { 115 bitmap[bitnum / 8] |= (1 << (bitnum%8)); 116 } 117 118 static inline int is_bit_set(const uint8_t *bitmap, int64_t bitnum) 119 { 120 return !!(bitmap[bitnum / 8] & (1 << (bitnum%8))); 121 } 122 123 124 /* Return true if first block has been changed (ie. current version is 125 * in COW file). Set the number of continuous blocks for which that 126 * is true. */ 127 static inline int is_changed(uint8_t *bitmap, 128 int64_t sector_num, int nb_sectors, 129 int *num_same) 130 { 131 int changed; 132 133 if (!bitmap || nb_sectors == 0) { 134 *num_same = nb_sectors; 135 return 0; 136 } 137 138 changed = is_bit_set(bitmap, sector_num); 139 for (*num_same = 1; *num_same < nb_sectors; (*num_same)++) { 140 if (is_bit_set(bitmap, sector_num + *num_same) != changed) 141 break; 142 } 143 144 return changed; 145 } 146 147 static int cow_is_allocated(BlockDriverState *bs, int64_t sector_num, 148 int nb_sectors, int *pnum) 149 { 150 BDRVCowState *s = bs->opaque; 151 return is_changed(s->cow_bitmap, sector_num, nb_sectors, pnum); 152 } 153 154 static int cow_read(BlockDriverState *bs, int64_t sector_num, 155 uint8_t *buf, int nb_sectors) 156 { 157 BDRVCowState *s = bs->opaque; 158 int ret, n; 159 160 while (nb_sectors > 0) { 161 if (is_changed(s->cow_bitmap, sector_num, nb_sectors, &n)) { 162 lseek(s->fd, s->cow_sectors_offset + sector_num * 512, SEEK_SET); 163 ret = read(s->fd, buf, n * 512); 164 if (ret != n * 512) 165 return -1; 166 } else { 167 if (bs->backing_hd) { 168 /* read from the base image */ 169 ret = bdrv_read(bs->backing_hd, sector_num, buf, n); 170 if (ret < 0) 171 return -1; 172 } else { 173 memset(buf, 0, n * 512); 174 } 175 } 176 nb_sectors -= n; 177 sector_num += n; 178 buf += n * 512; 179 } 180 return 0; 181 } 182 183 static int cow_write(BlockDriverState *bs, int64_t sector_num, 184 const uint8_t *buf, int nb_sectors) 185 { 186 BDRVCowState *s = bs->opaque; 187 int ret, i; 188 189 lseek(s->fd, s->cow_sectors_offset + sector_num * 512, SEEK_SET); 190 ret = write(s->fd, buf, nb_sectors * 512); 191 if (ret != nb_sectors * 512) 192 return -1; 193 for (i = 0; i < nb_sectors; i++) 194 cow_set_bit(s->cow_bitmap, sector_num + i); 195 return 0; 196 } 197 198 static void cow_close(BlockDriverState *bs) 199 { 200 BDRVCowState *s = bs->opaque; 201 munmap((void *)s->cow_bitmap_addr, s->cow_bitmap_size); 202 close(s->fd); 203 } 204 205 static int cow_create(const char *filename, QEMUOptionParameter *options) 206 { 207 int fd, cow_fd; 208 struct cow_header_v2 cow_header; 209 struct stat st; 210 int64_t image_sectors = 0; 211 const char *image_filename = NULL; 212 213 /* Read out options */ 214 while (options && options->name) { 215 if (!strcmp(options->name, BLOCK_OPT_SIZE)) { 216 image_sectors = options->value.n / 512; 217 } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) { 218 image_filename = options->value.s; 219 } 220 options++; 221 } 222 223 cow_fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 224 0644); 225 if (cow_fd < 0) 226 return -1; 227 memset(&cow_header, 0, sizeof(cow_header)); 228 cow_header.magic = cpu_to_be32(COW_MAGIC); 229 cow_header.version = cpu_to_be32(COW_VERSION); 230 if (image_filename) { 231 /* Note: if no file, we put a dummy mtime */ 232 cow_header.mtime = cpu_to_be32(0); 233 234 fd = open(image_filename, O_RDONLY | O_BINARY); 235 if (fd < 0) { 236 close(cow_fd); 237 goto mtime_fail; 238 } 239 if (fstat(fd, &st) != 0) { 240 close(fd); 241 goto mtime_fail; 242 } 243 close(fd); 244 cow_header.mtime = cpu_to_be32(st.st_mtime); 245 mtime_fail: 246 pstrcpy(cow_header.backing_file, sizeof(cow_header.backing_file), 247 image_filename); 248 } 249 cow_header.sectorsize = cpu_to_be32(512); 250 cow_header.size = cpu_to_be64(image_sectors * 512); 251 write(cow_fd, &cow_header, sizeof(cow_header)); 252 /* resize to include at least all the bitmap */ 253 ftruncate(cow_fd, sizeof(cow_header) + ((image_sectors + 7) >> 3)); 254 close(cow_fd); 255 return 0; 256 } 257 258 static void cow_flush(BlockDriverState *bs) 259 { 260 BDRVCowState *s = bs->opaque; 261 fsync(s->fd); 262 } 263 264 static QEMUOptionParameter cow_create_options[] = { 265 { 266 .name = BLOCK_OPT_SIZE, 267 .type = OPT_SIZE, 268 .help = "Virtual disk size" 269 }, 270 { 271 .name = BLOCK_OPT_BACKING_FILE, 272 .type = OPT_STRING, 273 .help = "File name of a base image" 274 }, 275 { NULL } 276 }; 277 278 static BlockDriver bdrv_cow = { 279 .format_name = "cow", 280 .instance_size = sizeof(BDRVCowState), 281 .bdrv_probe = cow_probe, 282 .bdrv_open = cow_open, 283 .bdrv_read = cow_read, 284 .bdrv_write = cow_write, 285 .bdrv_close = cow_close, 286 .bdrv_create = cow_create, 287 .bdrv_flush = cow_flush, 288 .bdrv_is_allocated = cow_is_allocated, 289 290 .create_options = cow_create_options, 291 }; 292 293 static void bdrv_cow_init(void) 294 { 295 bdrv_register(&bdrv_cow); 296 } 297 298 block_init(bdrv_cow_init); 299 #endif 300