1 /* vim:set shiftwidth=4 ts=4: */ 2 /* 3 * QEMU Block driver for virtual VFAT (shadows a local directory) 4 * 5 * Copyright (c) 2004,2005 Johannes E. Schindelin 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a copy 8 * of this software and associated documentation files (the "Software"), to deal 9 * in the Software without restriction, including without limitation the rights 10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 * copies of the Software, and to permit persons to whom the Software is 12 * furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included in 15 * all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 * THE SOFTWARE. 24 */ 25 26 #include "qemu/osdep.h" 27 #include <dirent.h> 28 #include <glib/gstdio.h> 29 #include "qapi/error.h" 30 #include "block/block-io.h" 31 #include "block/block_int.h" 32 #include "block/qdict.h" 33 #include "qemu/module.h" 34 #include "qemu/option.h" 35 #include "qemu/bswap.h" 36 #include "migration/blocker.h" 37 #include "qapi/qmp/qdict.h" 38 #include "qapi/qmp/qstring.h" 39 #include "qemu/ctype.h" 40 #include "qemu/cutils.h" 41 #include "qemu/error-report.h" 42 43 #ifndef S_IWGRP 44 #define S_IWGRP 0 45 #endif 46 #ifndef S_IWOTH 47 #define S_IWOTH 0 48 #endif 49 50 /* TODO: add ":bootsector=blabla.img:" */ 51 /* LATER TODO: add automatic boot sector generation from 52 BOOTEASY.ASM and Ranish Partition Manager 53 Note that DOS assumes the system files to be the first files in the 54 file system (test if the boot sector still relies on that fact)! */ 55 /* MAYBE TODO: write block-visofs.c */ 56 /* TODO: call try_commit() only after a timeout */ 57 58 /* #define DEBUG */ 59 60 #ifdef DEBUG 61 62 #define DLOG(a) a 63 64 static void checkpoint(void); 65 66 #else 67 68 #define DLOG(a) 69 70 #endif 71 72 /* bootsector OEM name. see related compatibility problems at: 73 * https://jdebp.eu/FGA/volume-boot-block-oem-name-field.html 74 * http://seasip.info/Misc/oemid.html 75 */ 76 #define BOOTSECTOR_OEM_NAME "MSWIN4.1" 77 78 #define DIR_DELETED 0xe5 79 #define DIR_KANJI DIR_DELETED 80 #define DIR_KANJI_FAKE 0x05 81 #define DIR_FREE 0x00 82 83 /* dynamic array functions */ 84 typedef struct array_t { 85 char* pointer; 86 unsigned int size,next,item_size; 87 } array_t; 88 89 static inline void array_init(array_t* array,unsigned int item_size) 90 { 91 array->pointer = NULL; 92 array->size=0; 93 array->next=0; 94 array->item_size=item_size; 95 } 96 97 static inline void array_free(array_t* array) 98 { 99 g_free(array->pointer); 100 array->size=array->next=0; 101 } 102 103 /* does not automatically grow */ 104 static inline void* array_get(array_t* array,unsigned int index) { 105 assert(index < array->next); 106 assert(array->pointer); 107 return array->pointer + index * array->item_size; 108 } 109 110 static inline void array_ensure_allocated(array_t *array, int index) 111 { 112 if((index + 1) * array->item_size > array->size) { 113 int new_size = (index + 32) * array->item_size; 114 array->pointer = g_realloc(array->pointer, new_size); 115 assert(array->pointer); 116 memset(array->pointer + array->size, 0, new_size - array->size); 117 array->size = new_size; 118 array->next = index + 1; 119 } 120 } 121 122 static inline void* array_get_next(array_t* array) { 123 unsigned int next = array->next; 124 125 array_ensure_allocated(array, next); 126 array->next = next + 1; 127 return array_get(array, next); 128 } 129 130 static inline void* array_insert(array_t* array,unsigned int index,unsigned int count) { 131 if((array->next+count)*array->item_size>array->size) { 132 int increment=count*array->item_size; 133 array->pointer=g_realloc(array->pointer,array->size+increment); 134 if(!array->pointer) 135 return NULL; 136 array->size+=increment; 137 } 138 memmove(array->pointer+(index+count)*array->item_size, 139 array->pointer+index*array->item_size, 140 (array->next-index)*array->item_size); 141 array->next+=count; 142 return array->pointer+index*array->item_size; 143 } 144 145 static inline int array_remove_slice(array_t* array,int index, int count) 146 { 147 assert(index >=0); 148 assert(count > 0); 149 assert(index + count <= array->next); 150 151 memmove(array->pointer + index * array->item_size, 152 array->pointer + (index + count) * array->item_size, 153 (array->next - index - count) * array->item_size); 154 155 array->next -= count; 156 return 0; 157 } 158 159 static int array_remove(array_t* array,int index) 160 { 161 return array_remove_slice(array, index, 1); 162 } 163 164 /* return the index for a given member */ 165 static int array_index(array_t* array, void* pointer) 166 { 167 size_t offset = (char*)pointer - array->pointer; 168 assert((offset % array->item_size) == 0); 169 assert(offset/array->item_size < array->next); 170 return offset/array->item_size; 171 } 172 173 /* These structures are used to fake a disk and the VFAT filesystem. 174 * For this reason we need to use QEMU_PACKED. */ 175 176 typedef struct bootsector_t { 177 uint8_t jump[3]; 178 uint8_t name[8]; 179 uint16_t sector_size; 180 uint8_t sectors_per_cluster; 181 uint16_t reserved_sectors; 182 uint8_t number_of_fats; 183 uint16_t root_entries; 184 uint16_t total_sectors16; 185 uint8_t media_type; 186 uint16_t sectors_per_fat; 187 uint16_t sectors_per_track; 188 uint16_t number_of_heads; 189 uint32_t hidden_sectors; 190 uint32_t total_sectors; 191 union { 192 struct { 193 uint8_t drive_number; 194 uint8_t reserved1; 195 uint8_t signature; 196 uint32_t id; 197 uint8_t volume_label[11]; 198 uint8_t fat_type[8]; 199 uint8_t ignored[0x1c0]; 200 } QEMU_PACKED fat16; 201 struct { 202 uint32_t sectors_per_fat; 203 uint16_t flags; 204 uint8_t major,minor; 205 uint32_t first_cluster_of_root_dir; 206 uint16_t info_sector; 207 uint16_t backup_boot_sector; 208 uint8_t reserved[12]; 209 uint8_t drive_number; 210 uint8_t reserved1; 211 uint8_t signature; 212 uint32_t id; 213 uint8_t volume_label[11]; 214 uint8_t fat_type[8]; 215 uint8_t ignored[0x1a4]; 216 } QEMU_PACKED fat32; 217 } u; 218 uint8_t magic[2]; 219 } QEMU_PACKED bootsector_t; 220 221 typedef struct { 222 uint8_t head; 223 uint8_t sector; 224 uint8_t cylinder; 225 } mbr_chs_t; 226 227 typedef struct partition_t { 228 uint8_t attributes; /* 0x80 = bootable */ 229 mbr_chs_t start_CHS; 230 uint8_t fs_type; /* 0x1 = FAT12, 0x6 = FAT16, 0xe = FAT16_LBA, 0xb = FAT32, 0xc = FAT32_LBA */ 231 mbr_chs_t end_CHS; 232 uint32_t start_sector_long; 233 uint32_t length_sector_long; 234 } QEMU_PACKED partition_t; 235 236 typedef struct mbr_t { 237 uint8_t ignored[0x1b8]; 238 uint32_t nt_id; 239 uint8_t ignored2[2]; 240 partition_t partition[4]; 241 uint8_t magic[2]; 242 } QEMU_PACKED mbr_t; 243 244 typedef struct direntry_t { 245 uint8_t name[8 + 3]; 246 uint8_t attributes; 247 uint8_t reserved[2]; 248 uint16_t ctime; 249 uint16_t cdate; 250 uint16_t adate; 251 uint16_t begin_hi; 252 uint16_t mtime; 253 uint16_t mdate; 254 uint16_t begin; 255 uint32_t size; 256 } QEMU_PACKED direntry_t; 257 258 /* this structure are used to transparently access the files */ 259 260 typedef struct mapping_t { 261 /* begin is the first cluster, end is the last+1 */ 262 uint32_t begin,end; 263 /* as s->directory is growable, no pointer may be used here */ 264 unsigned int dir_index; 265 /* the clusters of a file may be in any order; this points to the first */ 266 int first_mapping_index; 267 union { 268 /* offset is 269 * - the offset in the file (in clusters) for a file, or 270 * - the next cluster of the directory for a directory 271 */ 272 struct { 273 uint32_t offset; 274 } file; 275 struct { 276 int parent_mapping_index; 277 int first_dir_index; 278 } dir; 279 } info; 280 /* path contains the full path, i.e. it always starts with s->path */ 281 char* path; 282 283 enum { 284 MODE_UNDEFINED = 0, 285 MODE_NORMAL = 1, 286 MODE_MODIFIED = 2, 287 MODE_DIRECTORY = 4, 288 MODE_DELETED = 8, 289 } mode; 290 int read_only; 291 } mapping_t; 292 293 #ifdef DEBUG 294 static void print_direntry(const struct direntry_t*); 295 static void print_mapping(const struct mapping_t* mapping); 296 #endif 297 298 /* here begins the real VVFAT driver */ 299 300 typedef struct BDRVVVFATState { 301 CoMutex lock; 302 BlockDriverState* bs; /* pointer to parent */ 303 unsigned char first_sectors[0x40*0x200]; 304 305 int fat_type; /* 16 or 32 */ 306 array_t fat,directory,mapping; 307 char volume_label[11]; 308 309 uint32_t offset_to_bootsector; /* 0 for floppy, 0x3f for disk */ 310 311 unsigned int cluster_size; 312 unsigned int sectors_per_cluster; 313 unsigned int sectors_per_fat; 314 uint32_t last_cluster_of_root_directory; 315 /* how many entries are available in root directory (0 for FAT32) */ 316 uint16_t root_entries; 317 uint32_t sector_count; /* total number of sectors of the partition */ 318 uint32_t cluster_count; /* total number of clusters of this partition */ 319 uint32_t max_fat_value; 320 uint32_t offset_to_fat; 321 uint32_t offset_to_root_dir; 322 323 int current_fd; 324 mapping_t* current_mapping; 325 unsigned char* cluster; /* points to current cluster */ 326 unsigned char* cluster_buffer; /* points to a buffer to hold temp data */ 327 unsigned int current_cluster; 328 329 /* write support */ 330 char* qcow_filename; 331 BdrvChild* qcow; 332 void* fat2; 333 char* used_clusters; 334 array_t commits; 335 const char* path; 336 int downcase_short_names; 337 338 Error *migration_blocker; 339 } BDRVVVFATState; 340 341 /* take the sector position spos and convert it to Cylinder/Head/Sector position 342 * if the position is outside the specified geometry, fill maximum value for CHS 343 * and return 1 to signal overflow. 344 */ 345 static int sector2CHS(mbr_chs_t *chs, int spos, int cyls, int heads, int secs) 346 { 347 int head,sector; 348 sector = spos % secs; spos /= secs; 349 head = spos % heads; spos /= heads; 350 if (spos >= cyls) { 351 /* Overflow, 352 it happens if 32bit sector positions are used, while CHS is only 24bit. 353 Windows/Dos is said to take 1023/255/63 as nonrepresentable CHS */ 354 chs->head = 0xFF; 355 chs->sector = 0xFF; 356 chs->cylinder = 0xFF; 357 return 1; 358 } 359 chs->head = (uint8_t)head; 360 chs->sector = (uint8_t)( (sector+1) | ((spos>>8)<<6) ); 361 chs->cylinder = (uint8_t)spos; 362 return 0; 363 } 364 365 static void init_mbr(BDRVVVFATState *s, int cyls, int heads, int secs) 366 { 367 /* TODO: if the files mbr.img and bootsect.img exist, use them */ 368 mbr_t* real_mbr=(mbr_t*)s->first_sectors; 369 partition_t* partition = &(real_mbr->partition[0]); 370 int lba; 371 372 memset(s->first_sectors,0,512); 373 374 /* Win NT Disk Signature */ 375 real_mbr->nt_id= cpu_to_le32(0xbe1afdfa); 376 377 partition->attributes=0x80; /* bootable */ 378 379 /* LBA is used when partition is outside the CHS geometry */ 380 lba = sector2CHS(&partition->start_CHS, s->offset_to_bootsector, 381 cyls, heads, secs); 382 lba |= sector2CHS(&partition->end_CHS, s->bs->total_sectors - 1, 383 cyls, heads, secs); 384 385 /*LBA partitions are identified only by start/length_sector_long not by CHS*/ 386 partition->start_sector_long = cpu_to_le32(s->offset_to_bootsector); 387 partition->length_sector_long = cpu_to_le32(s->bs->total_sectors 388 - s->offset_to_bootsector); 389 390 /* FAT12/FAT16/FAT32 */ 391 /* DOS uses different types when partition is LBA, 392 probably to prevent older versions from using CHS on them */ 393 partition->fs_type = s->fat_type == 12 ? 0x1 : 394 s->fat_type == 16 ? (lba ? 0xe : 0x06) : 395 /*s->fat_type == 32*/ (lba ? 0xc : 0x0b); 396 397 real_mbr->magic[0]=0x55; real_mbr->magic[1]=0xaa; 398 } 399 400 /* direntry functions */ 401 402 static direntry_t *create_long_filename(BDRVVVFATState *s, const char *filename) 403 { 404 int number_of_entries, i; 405 glong length; 406 direntry_t *entry; 407 408 gunichar2 *longname = g_utf8_to_utf16(filename, -1, NULL, &length, NULL); 409 if (!longname) { 410 fprintf(stderr, "vvfat: invalid UTF-8 name: %s\n", filename); 411 return NULL; 412 } 413 414 number_of_entries = DIV_ROUND_UP(length * 2, 26); 415 416 for(i=0;i<number_of_entries;i++) { 417 entry=array_get_next(&(s->directory)); 418 entry->attributes=0xf; 419 entry->reserved[0]=0; 420 entry->begin=0; 421 entry->name[0]=(number_of_entries-i)|(i==0?0x40:0); 422 } 423 for(i=0;i<26*number_of_entries;i++) { 424 int offset=(i%26); 425 if(offset<10) offset=1+offset; 426 else if(offset<22) offset=14+offset-10; 427 else offset=28+offset-22; 428 entry=array_get(&(s->directory),s->directory.next-1-(i/26)); 429 /* ensure we don't write anything past entry->name */ 430 if (offset >= sizeof(entry->name)) { 431 continue; 432 } 433 if (i >= 2 * length + 2) { 434 entry->name[offset] = 0xff; 435 } else if (i % 2 == 0) { 436 entry->name[offset] = longname[i / 2] & 0xff; 437 } else { 438 entry->name[offset] = longname[i / 2] >> 8; 439 } 440 } 441 g_free(longname); 442 return array_get(&(s->directory),s->directory.next-number_of_entries); 443 } 444 445 static char is_free(const direntry_t* direntry) 446 { 447 return direntry->name[0] == DIR_DELETED || direntry->name[0] == DIR_FREE; 448 } 449 450 static char is_volume_label(const direntry_t* direntry) 451 { 452 return direntry->attributes == 0x28; 453 } 454 455 static char is_long_name(const direntry_t* direntry) 456 { 457 return direntry->attributes == 0xf; 458 } 459 460 static char is_short_name(const direntry_t* direntry) 461 { 462 return !is_volume_label(direntry) && !is_long_name(direntry) 463 && !is_free(direntry); 464 } 465 466 static char is_directory(const direntry_t* direntry) 467 { 468 return direntry->attributes & 0x10 && direntry->name[0] != DIR_DELETED; 469 } 470 471 static inline char is_dot(const direntry_t* direntry) 472 { 473 return is_short_name(direntry) && direntry->name[0] == '.'; 474 } 475 476 static char is_file(const direntry_t* direntry) 477 { 478 return is_short_name(direntry) && !is_directory(direntry); 479 } 480 481 static inline uint32_t begin_of_direntry(const direntry_t* direntry) 482 { 483 return le16_to_cpu(direntry->begin)|(le16_to_cpu(direntry->begin_hi)<<16); 484 } 485 486 static inline uint32_t filesize_of_direntry(const direntry_t* direntry) 487 { 488 return le32_to_cpu(direntry->size); 489 } 490 491 static void set_begin_of_direntry(direntry_t* direntry, uint32_t begin) 492 { 493 direntry->begin = cpu_to_le16(begin & 0xffff); 494 direntry->begin_hi = cpu_to_le16((begin >> 16) & 0xffff); 495 } 496 497 static bool valid_filename(const unsigned char *name) 498 { 499 unsigned char c; 500 if (!strcmp((const char*)name, ".") || !strcmp((const char*)name, "..")) { 501 return false; 502 } 503 for (; (c = *name); name++) { 504 if (!((c >= '0' && c <= '9') || 505 (c >= 'A' && c <= 'Z') || 506 (c >= 'a' && c <= 'z') || 507 c > 127 || 508 strchr(" $%'-_@~`!(){}^#&.+,;=[]", c) != NULL)) 509 { 510 return false; 511 } 512 } 513 return true; 514 } 515 516 static uint8_t to_valid_short_char(gunichar c) 517 { 518 c = g_unichar_toupper(c); 519 if ((c >= '0' && c <= '9') || 520 (c >= 'A' && c <= 'Z') || 521 strchr("$%'-_@~`!(){}^#&", c) != NULL) { 522 return c; 523 } else { 524 return 0; 525 } 526 } 527 528 static direntry_t *create_short_filename(BDRVVVFATState *s, 529 const char *filename, 530 unsigned int directory_start) 531 { 532 int i, j = 0; 533 direntry_t *entry = array_get_next(&(s->directory)); 534 const gchar *p, *last_dot = NULL; 535 gunichar c; 536 bool lossy_conversion = false; 537 char tail[8]; 538 539 if (!entry) { 540 return NULL; 541 } 542 memset(entry->name, 0x20, sizeof(entry->name)); 543 544 /* copy filename and search last dot */ 545 for (p = filename; ; p = g_utf8_next_char(p)) { 546 c = g_utf8_get_char(p); 547 if (c == '\0') { 548 break; 549 } else if (c == '.') { 550 if (j == 0) { 551 /* '.' at start of filename */ 552 lossy_conversion = true; 553 } else { 554 if (last_dot) { 555 lossy_conversion = true; 556 } 557 last_dot = p; 558 } 559 } else if (!last_dot) { 560 /* first part of the name; copy it */ 561 uint8_t v = to_valid_short_char(c); 562 if (j < 8 && v) { 563 entry->name[j++] = v; 564 } else { 565 lossy_conversion = true; 566 } 567 } 568 } 569 570 /* copy extension (if any) */ 571 if (last_dot) { 572 j = 0; 573 for (p = g_utf8_next_char(last_dot); ; p = g_utf8_next_char(p)) { 574 c = g_utf8_get_char(p); 575 if (c == '\0') { 576 break; 577 } else { 578 /* extension; copy it */ 579 uint8_t v = to_valid_short_char(c); 580 if (j < 3 && v) { 581 entry->name[8 + (j++)] = v; 582 } else { 583 lossy_conversion = true; 584 } 585 } 586 } 587 } 588 589 if (entry->name[0] == DIR_KANJI) { 590 entry->name[0] = DIR_KANJI_FAKE; 591 } 592 593 /* numeric-tail generation */ 594 for (j = 0; j < 8; j++) { 595 if (entry->name[j] == ' ') { 596 break; 597 } 598 } 599 for (i = lossy_conversion ? 1 : 0; i < 999999; i++) { 600 direntry_t *entry1; 601 if (i > 0) { 602 int len = snprintf(tail, sizeof(tail), "~%u", (unsigned)i); 603 assert(len <= 7); 604 memcpy(entry->name + MIN(j, 8 - len), tail, len); 605 } 606 for (entry1 = array_get(&(s->directory), directory_start); 607 entry1 < entry; entry1++) { 608 if (!is_long_name(entry1) && 609 !memcmp(entry1->name, entry->name, 11)) { 610 break; /* found dupe */ 611 } 612 } 613 if (entry1 == entry) { 614 /* no dupe found */ 615 return entry; 616 } 617 } 618 return NULL; 619 } 620 621 /* fat functions */ 622 623 static inline uint8_t fat_chksum(const direntry_t* entry) 624 { 625 uint8_t chksum=0; 626 int i; 627 628 for (i = 0; i < ARRAY_SIZE(entry->name); i++) { 629 chksum = (((chksum & 0xfe) >> 1) | 630 ((chksum & 0x01) ? 0x80 : 0)) + entry->name[i]; 631 } 632 633 return chksum; 634 } 635 636 /* if return_time==0, this returns the fat_date, else the fat_time */ 637 static uint16_t fat_datetime(time_t time,int return_time) { 638 struct tm* t; 639 struct tm t1; 640 t = &t1; 641 localtime_r(&time,t); 642 if(return_time) 643 return cpu_to_le16((t->tm_sec/2)|(t->tm_min<<5)|(t->tm_hour<<11)); 644 return cpu_to_le16((t->tm_mday)|((t->tm_mon+1)<<5)|((t->tm_year-80)<<9)); 645 } 646 647 static inline void fat_set(BDRVVVFATState* s,unsigned int cluster,uint32_t value) 648 { 649 if(s->fat_type==32) { 650 uint32_t* entry=array_get(&(s->fat),cluster); 651 *entry=cpu_to_le32(value); 652 } else if(s->fat_type==16) { 653 uint16_t* entry=array_get(&(s->fat),cluster); 654 *entry=cpu_to_le16(value&0xffff); 655 } else { 656 int offset = (cluster*3/2); 657 unsigned char* p = array_get(&(s->fat), offset); 658 switch (cluster&1) { 659 case 0: 660 p[0] = value&0xff; 661 p[1] = (p[1]&0xf0) | ((value>>8)&0xf); 662 break; 663 case 1: 664 p[0] = (p[0]&0xf) | ((value&0xf)<<4); 665 p[1] = (value>>4); 666 break; 667 } 668 } 669 } 670 671 static inline uint32_t fat_get(BDRVVVFATState* s,unsigned int cluster) 672 { 673 if(s->fat_type==32) { 674 uint32_t* entry=array_get(&(s->fat),cluster); 675 return le32_to_cpu(*entry); 676 } else if(s->fat_type==16) { 677 uint16_t* entry=array_get(&(s->fat),cluster); 678 return le16_to_cpu(*entry); 679 } else { 680 const uint8_t* x=(uint8_t*)(s->fat.pointer)+cluster*3/2; 681 return ((x[0]|(x[1]<<8))>>(cluster&1?4:0))&0x0fff; 682 } 683 } 684 685 static inline int fat_eof(BDRVVVFATState* s,uint32_t fat_entry) 686 { 687 if(fat_entry>s->max_fat_value-8) 688 return -1; 689 return 0; 690 } 691 692 static inline void init_fat(BDRVVVFATState* s) 693 { 694 if (s->fat_type == 12) { 695 array_init(&(s->fat),1); 696 array_ensure_allocated(&(s->fat), 697 s->sectors_per_fat * 0x200 * 3 / 2 - 1); 698 } else { 699 array_init(&(s->fat),(s->fat_type==32?4:2)); 700 array_ensure_allocated(&(s->fat), 701 s->sectors_per_fat * 0x200 / s->fat.item_size - 1); 702 } 703 memset(s->fat.pointer,0,s->fat.size); 704 705 switch(s->fat_type) { 706 case 12: s->max_fat_value=0xfff; break; 707 case 16: s->max_fat_value=0xffff; break; 708 case 32: s->max_fat_value=0x0fffffff; break; 709 default: s->max_fat_value=0; /* error... */ 710 } 711 712 } 713 714 static inline direntry_t* create_short_and_long_name(BDRVVVFATState* s, 715 unsigned int directory_start, const char* filename, int is_dot) 716 { 717 int long_index = s->directory.next; 718 direntry_t* entry = NULL; 719 direntry_t* entry_long = NULL; 720 721 if(is_dot) { 722 entry=array_get_next(&(s->directory)); 723 memset(entry->name, 0x20, sizeof(entry->name)); 724 memcpy(entry->name,filename,strlen(filename)); 725 return entry; 726 } 727 728 entry_long=create_long_filename(s,filename); 729 entry = create_short_filename(s, filename, directory_start); 730 731 /* calculate checksum; propagate to long name */ 732 if(entry_long) { 733 uint8_t chksum=fat_chksum(entry); 734 735 /* calculate anew, because realloc could have taken place */ 736 entry_long=array_get(&(s->directory),long_index); 737 while(entry_long<entry && is_long_name(entry_long)) { 738 entry_long->reserved[1]=chksum; 739 entry_long++; 740 } 741 } 742 743 return entry; 744 } 745 746 /* 747 * Read a directory. (the index of the corresponding mapping must be passed). 748 */ 749 static int read_directory(BDRVVVFATState* s, int mapping_index) 750 { 751 mapping_t* mapping = array_get(&(s->mapping), mapping_index); 752 direntry_t* direntry; 753 const char* dirname = mapping->path; 754 int first_cluster = mapping->begin; 755 int parent_index = mapping->info.dir.parent_mapping_index; 756 mapping_t* parent_mapping = (mapping_t*) 757 (parent_index >= 0 ? array_get(&(s->mapping), parent_index) : NULL); 758 int first_cluster_of_parent = parent_mapping ? parent_mapping->begin : -1; 759 760 DIR* dir=opendir(dirname); 761 struct dirent* entry; 762 int i; 763 764 assert(mapping->mode & MODE_DIRECTORY); 765 766 if(!dir) { 767 mapping->end = mapping->begin; 768 return -1; 769 } 770 771 i = mapping->info.dir.first_dir_index = 772 first_cluster == 0 ? 0 : s->directory.next; 773 774 if (first_cluster != 0) { 775 /* create the top entries of a subdirectory */ 776 (void)create_short_and_long_name(s, i, ".", 1); 777 (void)create_short_and_long_name(s, i, "..", 1); 778 } 779 780 /* actually read the directory, and allocate the mappings */ 781 while((entry=readdir(dir))) { 782 unsigned int length=strlen(dirname)+2+strlen(entry->d_name); 783 char* buffer; 784 struct stat st; 785 int is_dot=!strcmp(entry->d_name,"."); 786 int is_dotdot=!strcmp(entry->d_name,".."); 787 788 if (first_cluster == 0 && s->directory.next >= s->root_entries - 1) { 789 fprintf(stderr, "Too many entries in root directory\n"); 790 closedir(dir); 791 return -2; 792 } 793 794 if(first_cluster == 0 && (is_dotdot || is_dot)) 795 continue; 796 797 buffer = g_malloc(length); 798 snprintf(buffer,length,"%s/%s",dirname,entry->d_name); 799 800 if(stat(buffer,&st)<0) { 801 g_free(buffer); 802 continue; 803 } 804 805 /* create directory entry for this file */ 806 if (!is_dot && !is_dotdot) { 807 direntry = create_short_and_long_name(s, i, entry->d_name, 0); 808 } else { 809 direntry = array_get(&(s->directory), is_dot ? i : i + 1); 810 } 811 direntry->attributes=(S_ISDIR(st.st_mode)?0x10:0x20); 812 direntry->reserved[0]=direntry->reserved[1]=0; 813 direntry->ctime=fat_datetime(st.st_ctime,1); 814 direntry->cdate=fat_datetime(st.st_ctime,0); 815 direntry->adate=fat_datetime(st.st_atime,0); 816 direntry->begin_hi=0; 817 direntry->mtime=fat_datetime(st.st_mtime,1); 818 direntry->mdate=fat_datetime(st.st_mtime,0); 819 if(is_dotdot) 820 set_begin_of_direntry(direntry, first_cluster_of_parent); 821 else if(is_dot) 822 set_begin_of_direntry(direntry, first_cluster); 823 else 824 direntry->begin=0; /* do that later */ 825 if (st.st_size > 0x7fffffff) { 826 fprintf(stderr, "File %s is larger than 2GB\n", buffer); 827 g_free(buffer); 828 closedir(dir); 829 return -2; 830 } 831 direntry->size=cpu_to_le32(S_ISDIR(st.st_mode)?0:st.st_size); 832 833 /* create mapping for this file */ 834 if(!is_dot && !is_dotdot && (S_ISDIR(st.st_mode) || st.st_size)) { 835 s->current_mapping = array_get_next(&(s->mapping)); 836 s->current_mapping->begin=0; 837 s->current_mapping->end=st.st_size; 838 /* 839 * we get the direntry of the most recent direntry, which 840 * contains the short name and all the relevant information. 841 */ 842 s->current_mapping->dir_index=s->directory.next-1; 843 s->current_mapping->first_mapping_index = -1; 844 if (S_ISDIR(st.st_mode)) { 845 s->current_mapping->mode = MODE_DIRECTORY; 846 s->current_mapping->info.dir.parent_mapping_index = 847 mapping_index; 848 } else { 849 s->current_mapping->mode = MODE_UNDEFINED; 850 s->current_mapping->info.file.offset = 0; 851 } 852 s->current_mapping->path=buffer; 853 s->current_mapping->read_only = 854 (st.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)) == 0; 855 } else { 856 g_free(buffer); 857 } 858 } 859 closedir(dir); 860 861 /* fill with zeroes up to the end of the cluster */ 862 while(s->directory.next%(0x10*s->sectors_per_cluster)) { 863 direntry = array_get_next(&(s->directory)); 864 memset(direntry,0,sizeof(direntry_t)); 865 } 866 867 if (s->fat_type != 32 && 868 mapping_index == 0 && 869 s->directory.next < s->root_entries) { 870 /* root directory */ 871 int cur = s->directory.next; 872 array_ensure_allocated(&(s->directory), s->root_entries - 1); 873 s->directory.next = s->root_entries; 874 memset(array_get(&(s->directory), cur), 0, 875 (s->root_entries - cur) * sizeof(direntry_t)); 876 } 877 878 /* re-get the mapping, since s->mapping was possibly realloc()ed */ 879 mapping = array_get(&(s->mapping), mapping_index); 880 first_cluster += (s->directory.next - mapping->info.dir.first_dir_index) 881 * 0x20 / s->cluster_size; 882 mapping->end = first_cluster; 883 884 direntry = array_get(&(s->directory), mapping->dir_index); 885 set_begin_of_direntry(direntry, mapping->begin); 886 887 return 0; 888 } 889 890 static inline int32_t sector2cluster(BDRVVVFATState* s,off_t sector_num) 891 { 892 return (sector_num - s->offset_to_root_dir) / s->sectors_per_cluster; 893 } 894 895 static inline off_t cluster2sector(BDRVVVFATState* s, uint32_t cluster_num) 896 { 897 return s->offset_to_root_dir + s->sectors_per_cluster * cluster_num; 898 } 899 900 static int init_directories(BDRVVVFATState* s, 901 const char *dirname, int heads, int secs, 902 Error **errp) 903 { 904 bootsector_t* bootsector; 905 mapping_t* mapping; 906 unsigned int i; 907 unsigned int cluster; 908 909 memset(&(s->first_sectors[0]),0,0x40*0x200); 910 911 s->cluster_size=s->sectors_per_cluster*0x200; 912 s->cluster_buffer=g_malloc(s->cluster_size); 913 914 /* 915 * The formula: sc = spf+1+spf*spc*(512*8/fat_type), 916 * where sc is sector_count, 917 * spf is sectors_per_fat, 918 * spc is sectors_per_clusters, and 919 * fat_type = 12, 16 or 32. 920 */ 921 i = 1+s->sectors_per_cluster*0x200*8/s->fat_type; 922 s->sectors_per_fat=(s->sector_count+i)/i; /* round up */ 923 924 s->offset_to_fat = s->offset_to_bootsector + 1; 925 s->offset_to_root_dir = s->offset_to_fat + s->sectors_per_fat * 2; 926 927 array_init(&(s->mapping),sizeof(mapping_t)); 928 array_init(&(s->directory),sizeof(direntry_t)); 929 930 /* add volume label */ 931 { 932 direntry_t* entry=array_get_next(&(s->directory)); 933 entry->attributes=0x28; /* archive | volume label */ 934 memcpy(entry->name, s->volume_label, sizeof(entry->name)); 935 } 936 937 /* Now build FAT, and write back information into directory */ 938 init_fat(s); 939 940 /* TODO: if there are more entries, bootsector has to be adjusted! */ 941 s->root_entries = 0x02 * 0x10 * s->sectors_per_cluster; 942 s->cluster_count=sector2cluster(s, s->sector_count); 943 944 mapping = array_get_next(&(s->mapping)); 945 mapping->begin = 0; 946 mapping->dir_index = 0; 947 mapping->info.dir.parent_mapping_index = -1; 948 mapping->first_mapping_index = -1; 949 mapping->path = g_strdup(dirname); 950 i = strlen(mapping->path); 951 if (i > 0 && mapping->path[i - 1] == '/') 952 mapping->path[i - 1] = '\0'; 953 mapping->mode = MODE_DIRECTORY; 954 mapping->read_only = 0; 955 s->path = mapping->path; 956 957 for (i = 0, cluster = 0; i < s->mapping.next; i++) { 958 /* MS-DOS expects the FAT to be 0 for the root directory 959 * (except for the media byte). */ 960 /* LATER TODO: still true for FAT32? */ 961 int fix_fat = (i != 0); 962 mapping = array_get(&(s->mapping), i); 963 964 if (mapping->mode & MODE_DIRECTORY) { 965 char *path = mapping->path; 966 mapping->begin = cluster; 967 if(read_directory(s, i)) { 968 error_setg(errp, "Could not read directory %s", path); 969 return -1; 970 } 971 mapping = array_get(&(s->mapping), i); 972 } else { 973 assert(mapping->mode == MODE_UNDEFINED); 974 mapping->mode=MODE_NORMAL; 975 mapping->begin = cluster; 976 if (mapping->end > 0) { 977 direntry_t* direntry = array_get(&(s->directory), 978 mapping->dir_index); 979 980 mapping->end = cluster + 1 + (mapping->end-1)/s->cluster_size; 981 set_begin_of_direntry(direntry, mapping->begin); 982 } else { 983 mapping->end = cluster + 1; 984 fix_fat = 0; 985 } 986 } 987 988 assert(mapping->begin < mapping->end); 989 990 /* next free cluster */ 991 cluster = mapping->end; 992 993 if(cluster > s->cluster_count) { 994 error_setg(errp, 995 "Directory does not fit in FAT%d (capacity %.2f MB)", 996 s->fat_type, s->sector_count / 2000.0); 997 return -1; 998 } 999 1000 /* fix fat for entry */ 1001 if (fix_fat) { 1002 int j; 1003 for(j = mapping->begin; j < mapping->end - 1; j++) 1004 fat_set(s, j, j+1); 1005 fat_set(s, mapping->end - 1, s->max_fat_value); 1006 } 1007 } 1008 1009 mapping = array_get(&(s->mapping), 0); 1010 s->last_cluster_of_root_directory = mapping->end; 1011 1012 /* the FAT signature */ 1013 fat_set(s,0,s->max_fat_value); 1014 fat_set(s,1,s->max_fat_value); 1015 1016 s->current_mapping = NULL; 1017 1018 bootsector = (bootsector_t *)(s->first_sectors 1019 + s->offset_to_bootsector * 0x200); 1020 bootsector->jump[0]=0xeb; 1021 bootsector->jump[1]=0x3e; 1022 bootsector->jump[2]=0x90; 1023 memcpy(bootsector->name, BOOTSECTOR_OEM_NAME, 8); 1024 bootsector->sector_size=cpu_to_le16(0x200); 1025 bootsector->sectors_per_cluster=s->sectors_per_cluster; 1026 bootsector->reserved_sectors=cpu_to_le16(1); 1027 bootsector->number_of_fats=0x2; /* number of FATs */ 1028 bootsector->root_entries = cpu_to_le16(s->root_entries); 1029 bootsector->total_sectors16=s->sector_count>0xffff?0:cpu_to_le16(s->sector_count); 1030 /* media descriptor: hard disk=0xf8, floppy=0xf0 */ 1031 bootsector->media_type = (s->offset_to_bootsector > 0 ? 0xf8 : 0xf0); 1032 s->fat.pointer[0] = bootsector->media_type; 1033 bootsector->sectors_per_fat=cpu_to_le16(s->sectors_per_fat); 1034 bootsector->sectors_per_track = cpu_to_le16(secs); 1035 bootsector->number_of_heads = cpu_to_le16(heads); 1036 bootsector->hidden_sectors = cpu_to_le32(s->offset_to_bootsector); 1037 bootsector->total_sectors=cpu_to_le32(s->sector_count>0xffff?s->sector_count:0); 1038 1039 /* LATER TODO: if FAT32, this is wrong */ 1040 /* drive_number: fda=0, hda=0x80 */ 1041 bootsector->u.fat16.drive_number = s->offset_to_bootsector == 0 ? 0 : 0x80; 1042 bootsector->u.fat16.signature=0x29; 1043 bootsector->u.fat16.id=cpu_to_le32(0xfabe1afd); 1044 1045 memcpy(bootsector->u.fat16.volume_label, s->volume_label, 1046 sizeof(bootsector->u.fat16.volume_label)); 1047 memcpy(bootsector->u.fat16.fat_type, 1048 s->fat_type == 12 ? "FAT12 " : "FAT16 ", 8); 1049 bootsector->magic[0]=0x55; bootsector->magic[1]=0xaa; 1050 1051 return 0; 1052 } 1053 1054 #ifdef DEBUG 1055 static BDRVVVFATState *vvv = NULL; 1056 #endif 1057 1058 static int enable_write_target(BlockDriverState *bs, Error **errp); 1059 static int coroutine_fn is_consistent(BDRVVVFATState *s); 1060 1061 static QemuOptsList runtime_opts = { 1062 .name = "vvfat", 1063 .head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head), 1064 .desc = { 1065 { 1066 .name = "dir", 1067 .type = QEMU_OPT_STRING, 1068 .help = "Host directory to map to the vvfat device", 1069 }, 1070 { 1071 .name = "fat-type", 1072 .type = QEMU_OPT_NUMBER, 1073 .help = "FAT type (12, 16 or 32)", 1074 }, 1075 { 1076 .name = "floppy", 1077 .type = QEMU_OPT_BOOL, 1078 .help = "Create a floppy rather than a hard disk image", 1079 }, 1080 { 1081 .name = "label", 1082 .type = QEMU_OPT_STRING, 1083 .help = "Use a volume label other than QEMU VVFAT", 1084 }, 1085 { 1086 .name = "rw", 1087 .type = QEMU_OPT_BOOL, 1088 .help = "Make the image writable", 1089 }, 1090 { /* end of list */ } 1091 }, 1092 }; 1093 1094 static void vvfat_parse_filename(const char *filename, QDict *options, 1095 Error **errp) 1096 { 1097 int fat_type = 0; 1098 bool floppy = false; 1099 bool rw = false; 1100 int i; 1101 1102 if (!strstart(filename, "fat:", NULL)) { 1103 error_setg(errp, "File name string must start with 'fat:'"); 1104 return; 1105 } 1106 1107 /* Parse options */ 1108 if (strstr(filename, ":32:")) { 1109 fat_type = 32; 1110 } else if (strstr(filename, ":16:")) { 1111 fat_type = 16; 1112 } else if (strstr(filename, ":12:")) { 1113 fat_type = 12; 1114 } 1115 1116 if (strstr(filename, ":floppy:")) { 1117 floppy = true; 1118 } 1119 1120 if (strstr(filename, ":rw:")) { 1121 rw = true; 1122 } 1123 1124 /* Get the directory name without options */ 1125 i = strrchr(filename, ':') - filename; 1126 assert(i >= 3); 1127 if (filename[i - 2] == ':' && qemu_isalpha(filename[i - 1])) { 1128 /* workaround for DOS drive names */ 1129 filename += i - 1; 1130 } else { 1131 filename += i + 1; 1132 } 1133 1134 /* Fill in the options QDict */ 1135 qdict_put_str(options, "dir", filename); 1136 qdict_put_int(options, "fat-type", fat_type); 1137 qdict_put_bool(options, "floppy", floppy); 1138 qdict_put_bool(options, "rw", rw); 1139 } 1140 1141 static int vvfat_open(BlockDriverState *bs, QDict *options, int flags, 1142 Error **errp) 1143 { 1144 BDRVVVFATState *s = bs->opaque; 1145 int cyls, heads, secs; 1146 bool floppy; 1147 const char *dirname, *label; 1148 QemuOpts *opts; 1149 int ret; 1150 1151 GRAPH_RDLOCK_GUARD_MAINLOOP(); 1152 1153 #ifdef DEBUG 1154 vvv = s; 1155 #endif 1156 1157 opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort); 1158 if (!qemu_opts_absorb_qdict(opts, options, errp)) { 1159 ret = -EINVAL; 1160 goto fail; 1161 } 1162 1163 dirname = qemu_opt_get(opts, "dir"); 1164 if (!dirname) { 1165 error_setg(errp, "vvfat block driver requires a 'dir' option"); 1166 ret = -EINVAL; 1167 goto fail; 1168 } 1169 1170 s->fat_type = qemu_opt_get_number(opts, "fat-type", 0); 1171 floppy = qemu_opt_get_bool(opts, "floppy", false); 1172 1173 memset(s->volume_label, ' ', sizeof(s->volume_label)); 1174 label = qemu_opt_get(opts, "label"); 1175 if (label) { 1176 size_t label_length = strlen(label); 1177 if (label_length > 11) { 1178 error_setg(errp, "vvfat label cannot be longer than 11 bytes"); 1179 ret = -EINVAL; 1180 goto fail; 1181 } 1182 memcpy(s->volume_label, label, label_length); 1183 } else { 1184 memcpy(s->volume_label, "QEMU VVFAT", 10); 1185 } 1186 1187 if (floppy) { 1188 /* 1.44MB or 2.88MB floppy. 2.88MB can be FAT12 (default) or FAT16. */ 1189 if (!s->fat_type) { 1190 s->fat_type = 12; 1191 secs = 36; 1192 s->sectors_per_cluster = 2; 1193 } else { 1194 secs = s->fat_type == 12 ? 18 : 36; 1195 s->sectors_per_cluster = 1; 1196 } 1197 cyls = 80; 1198 heads = 2; 1199 } else { 1200 /* 32MB or 504MB disk*/ 1201 if (!s->fat_type) { 1202 s->fat_type = 16; 1203 } 1204 s->offset_to_bootsector = 0x3f; 1205 cyls = s->fat_type == 12 ? 64 : 1024; 1206 heads = 16; 1207 secs = 63; 1208 } 1209 1210 switch (s->fat_type) { 1211 case 32: 1212 warn_report("FAT32 has not been tested. You are welcome to do so!"); 1213 break; 1214 case 16: 1215 case 12: 1216 break; 1217 default: 1218 error_setg(errp, "Valid FAT types are only 12, 16 and 32"); 1219 ret = -EINVAL; 1220 goto fail; 1221 } 1222 1223 1224 s->bs = bs; 1225 1226 /* LATER TODO: if FAT32, adjust */ 1227 s->sectors_per_cluster=0x10; 1228 1229 s->current_cluster=0xffffffff; 1230 1231 s->qcow = NULL; 1232 s->qcow_filename = NULL; 1233 s->fat2 = NULL; 1234 s->downcase_short_names = 1; 1235 1236 DLOG(fprintf(stderr, "vvfat %s chs %d,%d,%d\n", 1237 dirname, cyls, heads, secs)); 1238 1239 s->sector_count = cyls * heads * secs - s->offset_to_bootsector; 1240 bs->total_sectors = cyls * heads * secs; 1241 1242 if (qemu_opt_get_bool(opts, "rw", false)) { 1243 if (!bdrv_is_read_only(bs)) { 1244 ret = enable_write_target(bs, errp); 1245 if (ret < 0) { 1246 goto fail; 1247 } 1248 } else { 1249 ret = -EPERM; 1250 error_setg(errp, 1251 "Unable to set VVFAT to 'rw' when drive is read-only"); 1252 goto fail; 1253 } 1254 } else { 1255 ret = bdrv_apply_auto_read_only(bs, NULL, errp); 1256 if (ret < 0) { 1257 goto fail; 1258 } 1259 } 1260 1261 if (init_directories(s, dirname, heads, secs, errp)) { 1262 ret = -EIO; 1263 goto fail; 1264 } 1265 1266 s->sector_count = s->offset_to_root_dir 1267 + s->sectors_per_cluster * s->cluster_count; 1268 1269 /* Disable migration when vvfat is used rw */ 1270 if (s->qcow) { 1271 error_setg(&s->migration_blocker, 1272 "The vvfat (rw) format used by node '%s' " 1273 "does not support live migration", 1274 bdrv_get_device_or_node_name(bs)); 1275 ret = migrate_add_blocker_normal(&s->migration_blocker, errp); 1276 if (ret < 0) { 1277 goto fail; 1278 } 1279 } 1280 1281 if (s->offset_to_bootsector > 0) { 1282 init_mbr(s, cyls, heads, secs); 1283 } 1284 1285 qemu_co_mutex_init(&s->lock); 1286 1287 qemu_opts_del(opts); 1288 1289 return 0; 1290 1291 fail: 1292 g_free(s->qcow_filename); 1293 s->qcow_filename = NULL; 1294 g_free(s->cluster_buffer); 1295 s->cluster_buffer = NULL; 1296 g_free(s->used_clusters); 1297 s->used_clusters = NULL; 1298 1299 qemu_opts_del(opts); 1300 return ret; 1301 } 1302 1303 static void vvfat_refresh_limits(BlockDriverState *bs, Error **errp) 1304 { 1305 bs->bl.request_alignment = BDRV_SECTOR_SIZE; /* No sub-sector I/O */ 1306 } 1307 1308 static inline void vvfat_close_current_file(BDRVVVFATState *s) 1309 { 1310 if(s->current_mapping) { 1311 s->current_mapping = NULL; 1312 if (s->current_fd) { 1313 qemu_close(s->current_fd); 1314 s->current_fd = 0; 1315 } 1316 } 1317 s->current_cluster = -1; 1318 } 1319 1320 /* mappings between index1 and index2-1 are supposed to be ordered 1321 * return value is the index of the last mapping for which end>cluster_num 1322 */ 1323 static inline int find_mapping_for_cluster_aux(BDRVVVFATState* s,int cluster_num,int index1,int index2) 1324 { 1325 while(1) { 1326 int index3; 1327 mapping_t* mapping; 1328 index3=(index1+index2)/2; 1329 mapping=array_get(&(s->mapping),index3); 1330 assert(mapping->begin < mapping->end); 1331 if(mapping->begin>=cluster_num) { 1332 assert(index2!=index3 || index2==0); 1333 if(index2==index3) 1334 return index1; 1335 index2=index3; 1336 } else { 1337 if(index1==index3) 1338 return mapping->end<=cluster_num ? index2 : index1; 1339 index1=index3; 1340 } 1341 assert(index1<=index2); 1342 DLOG(mapping=array_get(&(s->mapping),index1); 1343 assert(mapping->begin<=cluster_num); 1344 assert(index2 >= s->mapping.next || 1345 ((mapping = array_get(&(s->mapping),index2)) && 1346 mapping->end>cluster_num))); 1347 } 1348 } 1349 1350 static inline mapping_t* find_mapping_for_cluster(BDRVVVFATState* s,int cluster_num) 1351 { 1352 int index=find_mapping_for_cluster_aux(s,cluster_num,0,s->mapping.next); 1353 mapping_t* mapping; 1354 if(index>=s->mapping.next) 1355 return NULL; 1356 mapping=array_get(&(s->mapping),index); 1357 if(mapping->begin>cluster_num) 1358 return NULL; 1359 assert(mapping->begin<=cluster_num && mapping->end>cluster_num); 1360 return mapping; 1361 } 1362 1363 static int open_file(BDRVVVFATState* s,mapping_t* mapping) 1364 { 1365 if(!mapping) 1366 return -1; 1367 if(!s->current_mapping || 1368 strcmp(s->current_mapping->path,mapping->path)) { 1369 /* open file */ 1370 int fd = qemu_open_old(mapping->path, 1371 O_RDONLY | O_BINARY | O_LARGEFILE); 1372 if(fd<0) 1373 return -1; 1374 vvfat_close_current_file(s); 1375 s->current_fd = fd; 1376 } 1377 1378 s->current_mapping = mapping; 1379 return 0; 1380 } 1381 1382 static inline int read_cluster(BDRVVVFATState *s,int cluster_num) 1383 { 1384 if(s->current_cluster != cluster_num) { 1385 int result=0; 1386 off_t offset; 1387 assert(!s->current_mapping || s->current_fd || (s->current_mapping->mode & MODE_DIRECTORY)); 1388 if(!s->current_mapping 1389 || s->current_mapping->begin>cluster_num 1390 || s->current_mapping->end<=cluster_num) { 1391 /* binary search of mappings for file */ 1392 mapping_t* mapping=find_mapping_for_cluster(s,cluster_num); 1393 1394 assert(!mapping || (cluster_num>=mapping->begin && cluster_num<mapping->end)); 1395 1396 if (mapping && mapping->mode & MODE_DIRECTORY) { 1397 vvfat_close_current_file(s); 1398 s->current_mapping = mapping; 1399 read_cluster_directory: 1400 offset = s->cluster_size*(cluster_num-s->current_mapping->begin); 1401 s->cluster = (unsigned char*)s->directory.pointer+offset 1402 + 0x20*s->current_mapping->info.dir.first_dir_index; 1403 assert(((s->cluster-(unsigned char*)s->directory.pointer)%s->cluster_size)==0); 1404 assert((char*)s->cluster+s->cluster_size <= s->directory.pointer+s->directory.next*s->directory.item_size); 1405 s->current_cluster = cluster_num; 1406 return 0; 1407 } 1408 1409 if(open_file(s,mapping)) 1410 return -2; 1411 } else if (s->current_mapping->mode & MODE_DIRECTORY) 1412 goto read_cluster_directory; 1413 1414 assert(s->current_fd); 1415 1416 offset = s->cluster_size * 1417 ((cluster_num - s->current_mapping->begin) 1418 + s->current_mapping->info.file.offset); 1419 if(lseek(s->current_fd, offset, SEEK_SET)!=offset) 1420 return -3; 1421 s->cluster=s->cluster_buffer; 1422 result=read(s->current_fd,s->cluster,s->cluster_size); 1423 if(result<0) { 1424 s->current_cluster = -1; 1425 return -1; 1426 } 1427 s->current_cluster = cluster_num; 1428 } 1429 return 0; 1430 } 1431 1432 #ifdef DEBUG 1433 static void print_direntry(const direntry_t* direntry) 1434 { 1435 int j = 0; 1436 char buffer[1024]; 1437 1438 fprintf(stderr, "direntry %p: ", direntry); 1439 if(!direntry) 1440 return; 1441 if(is_long_name(direntry)) { 1442 unsigned char* c=(unsigned char*)direntry; 1443 int i; 1444 for(i=1;i<11 && c[i] && c[i]!=0xff;i+=2) 1445 #define ADD_CHAR(c) {buffer[j] = (c); if (buffer[j] < ' ') buffer[j] = 0xb0; j++;} 1446 ADD_CHAR(c[i]); 1447 for(i=14;i<26 && c[i] && c[i]!=0xff;i+=2) 1448 ADD_CHAR(c[i]); 1449 for(i=28;i<32 && c[i] && c[i]!=0xff;i+=2) 1450 ADD_CHAR(c[i]); 1451 buffer[j] = 0; 1452 fprintf(stderr, "%s\n", buffer); 1453 } else { 1454 int i; 1455 for(i=0;i<11;i++) 1456 ADD_CHAR(direntry->name[i]); 1457 buffer[j] = 0; 1458 fprintf(stderr, "%s attributes=0x%02x begin=%u size=%u\n", 1459 buffer, 1460 direntry->attributes, 1461 begin_of_direntry(direntry),le32_to_cpu(direntry->size)); 1462 } 1463 } 1464 1465 static void print_mapping(const mapping_t* mapping) 1466 { 1467 fprintf(stderr, "mapping (%p): begin, end = %u, %u, dir_index = %u, " 1468 "first_mapping_index = %d, name = %s, mode = 0x%x, " , 1469 mapping, mapping->begin, mapping->end, mapping->dir_index, 1470 mapping->first_mapping_index, mapping->path, mapping->mode); 1471 1472 if (mapping->mode & MODE_DIRECTORY) 1473 fprintf(stderr, "parent_mapping_index = %d, first_dir_index = %d\n", mapping->info.dir.parent_mapping_index, mapping->info.dir.first_dir_index); 1474 else 1475 fprintf(stderr, "offset = %u\n", mapping->info.file.offset); 1476 } 1477 #endif 1478 1479 static int coroutine_fn GRAPH_RDLOCK 1480 vvfat_read(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, int nb_sectors) 1481 { 1482 BDRVVVFATState *s = bs->opaque; 1483 int i; 1484 1485 for(i=0;i<nb_sectors;i++,sector_num++) { 1486 if (sector_num >= bs->total_sectors) 1487 return -1; 1488 if (s->qcow) { 1489 int64_t n; 1490 int ret; 1491 ret = bdrv_co_is_allocated(s->qcow->bs, sector_num * BDRV_SECTOR_SIZE, 1492 (nb_sectors - i) * BDRV_SECTOR_SIZE, &n); 1493 if (ret < 0) { 1494 return ret; 1495 } 1496 if (ret) { 1497 DLOG(fprintf(stderr, "sectors %" PRId64 "+%" PRId64 1498 " allocated\n", sector_num, 1499 n >> BDRV_SECTOR_BITS)); 1500 if (bdrv_co_pread(s->qcow, sector_num * BDRV_SECTOR_SIZE, n, 1501 buf + i * 0x200, 0) < 0) { 1502 return -1; 1503 } 1504 i += (n >> BDRV_SECTOR_BITS) - 1; 1505 sector_num += (n >> BDRV_SECTOR_BITS) - 1; 1506 continue; 1507 } 1508 DLOG(fprintf(stderr, "sector %" PRId64 " not allocated\n", 1509 sector_num)); 1510 } 1511 if (sector_num < s->offset_to_root_dir) { 1512 if (sector_num < s->offset_to_fat) { 1513 memcpy(buf + i * 0x200, 1514 &(s->first_sectors[sector_num * 0x200]), 1515 0x200); 1516 } else if (sector_num < s->offset_to_fat + s->sectors_per_fat) { 1517 memcpy(buf + i * 0x200, 1518 &(s->fat.pointer[(sector_num 1519 - s->offset_to_fat) * 0x200]), 1520 0x200); 1521 } else if (sector_num < s->offset_to_root_dir) { 1522 memcpy(buf + i * 0x200, 1523 &(s->fat.pointer[(sector_num - s->offset_to_fat 1524 - s->sectors_per_fat) * 0x200]), 1525 0x200); 1526 } 1527 } else { 1528 uint32_t sector = sector_num - s->offset_to_root_dir, 1529 sector_offset_in_cluster=(sector%s->sectors_per_cluster), 1530 cluster_num=sector/s->sectors_per_cluster; 1531 if(cluster_num > s->cluster_count || read_cluster(s, cluster_num) != 0) { 1532 /* LATER TODO: strict: return -1; */ 1533 memset(buf+i*0x200,0,0x200); 1534 continue; 1535 } 1536 memcpy(buf+i*0x200,s->cluster+sector_offset_in_cluster*0x200,0x200); 1537 } 1538 } 1539 return 0; 1540 } 1541 1542 static int coroutine_fn GRAPH_RDLOCK 1543 vvfat_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes, 1544 QEMUIOVector *qiov, BdrvRequestFlags flags) 1545 { 1546 int ret; 1547 BDRVVVFATState *s = bs->opaque; 1548 uint64_t sector_num = offset >> BDRV_SECTOR_BITS; 1549 int nb_sectors = bytes >> BDRV_SECTOR_BITS; 1550 void *buf; 1551 1552 assert(QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE)); 1553 assert(QEMU_IS_ALIGNED(bytes, BDRV_SECTOR_SIZE)); 1554 1555 buf = g_try_malloc(bytes); 1556 if (bytes && buf == NULL) { 1557 return -ENOMEM; 1558 } 1559 1560 qemu_co_mutex_lock(&s->lock); 1561 ret = vvfat_read(bs, sector_num, buf, nb_sectors); 1562 qemu_co_mutex_unlock(&s->lock); 1563 1564 qemu_iovec_from_buf(qiov, 0, buf, bytes); 1565 g_free(buf); 1566 1567 return ret; 1568 } 1569 1570 /* LATER TODO: statify all functions */ 1571 1572 /* 1573 * Idea of the write support (use snapshot): 1574 * 1575 * 1. check if all data is consistent, recording renames, modifications, 1576 * new files and directories (in s->commits). 1577 * 1578 * 2. if the data is not consistent, stop committing 1579 * 1580 * 3. handle renames, and create new files and directories (do not yet 1581 * write their contents) 1582 * 1583 * 4. walk the directories, fixing the mapping and direntries, and marking 1584 * the handled mappings as not deleted 1585 * 1586 * 5. commit the contents of the files 1587 * 1588 * 6. handle deleted files and directories 1589 * 1590 */ 1591 1592 typedef struct commit_t { 1593 char* path; 1594 union { 1595 struct { uint32_t cluster; } rename; 1596 struct { int dir_index; uint32_t modified_offset; } writeout; 1597 struct { uint32_t first_cluster; } new_file; 1598 struct { uint32_t cluster; } mkdir; 1599 } param; 1600 /* DELETEs and RMDIRs are handled differently: see handle_deletes() */ 1601 enum { 1602 ACTION_RENAME, ACTION_WRITEOUT, ACTION_NEW_FILE, ACTION_MKDIR 1603 } action; 1604 } commit_t; 1605 1606 static void clear_commits(BDRVVVFATState* s) 1607 { 1608 int i; 1609 DLOG(fprintf(stderr, "clear_commits (%u commits)\n", s->commits.next)); 1610 for (i = 0; i < s->commits.next; i++) { 1611 commit_t* commit = array_get(&(s->commits), i); 1612 assert(commit->path || commit->action == ACTION_WRITEOUT); 1613 if (commit->action != ACTION_WRITEOUT) { 1614 assert(commit->path); 1615 g_free(commit->path); 1616 } else 1617 assert(commit->path == NULL); 1618 } 1619 s->commits.next = 0; 1620 } 1621 1622 static void schedule_rename(BDRVVVFATState* s, 1623 uint32_t cluster, char* new_path) 1624 { 1625 commit_t* commit = array_get_next(&(s->commits)); 1626 commit->path = new_path; 1627 commit->param.rename.cluster = cluster; 1628 commit->action = ACTION_RENAME; 1629 } 1630 1631 static void schedule_writeout(BDRVVVFATState* s, 1632 int dir_index, uint32_t modified_offset) 1633 { 1634 commit_t* commit = array_get_next(&(s->commits)); 1635 commit->path = NULL; 1636 commit->param.writeout.dir_index = dir_index; 1637 commit->param.writeout.modified_offset = modified_offset; 1638 commit->action = ACTION_WRITEOUT; 1639 } 1640 1641 static void schedule_new_file(BDRVVVFATState* s, 1642 char* path, uint32_t first_cluster) 1643 { 1644 commit_t* commit = array_get_next(&(s->commits)); 1645 commit->path = path; 1646 commit->param.new_file.first_cluster = first_cluster; 1647 commit->action = ACTION_NEW_FILE; 1648 } 1649 1650 static void schedule_mkdir(BDRVVVFATState* s, uint32_t cluster, char* path) 1651 { 1652 commit_t* commit = array_get_next(&(s->commits)); 1653 commit->path = path; 1654 commit->param.mkdir.cluster = cluster; 1655 commit->action = ACTION_MKDIR; 1656 } 1657 1658 typedef struct { 1659 /* 1660 * Since the sequence number is at most 0x3f, and the filename 1661 * length is at most 13 times the sequence number, the maximal 1662 * filename length is 0x3f * 13 bytes. 1663 */ 1664 unsigned char name[0x3f * 13 + 1]; 1665 gunichar2 name2[0x3f * 13 + 1]; 1666 int checksum, len; 1667 int sequence_number; 1668 } long_file_name; 1669 1670 static void lfn_init(long_file_name* lfn) 1671 { 1672 lfn->sequence_number = lfn->len = 0; 1673 lfn->checksum = 0x100; 1674 } 1675 1676 /* return 0 if parsed successfully, > 0 if no long name, < 0 if error */ 1677 static int parse_long_name(long_file_name* lfn, 1678 const direntry_t* direntry) 1679 { 1680 int i, j, offset; 1681 const unsigned char* pointer = (const unsigned char*)direntry; 1682 1683 if (!is_long_name(direntry)) 1684 return 1; 1685 1686 if (pointer[0] & 0x40) { 1687 /* first entry; do some initialization */ 1688 lfn->sequence_number = pointer[0] & 0x3f; 1689 lfn->checksum = pointer[13]; 1690 lfn->name[0] = 0; 1691 lfn->name[lfn->sequence_number * 13] = 0; 1692 } else if ((pointer[0] & 0x3f) != --lfn->sequence_number) { 1693 /* not the expected sequence number */ 1694 return -1; 1695 } else if (pointer[13] != lfn->checksum) { 1696 /* not the expected checksum */ 1697 return -2; 1698 } else if (pointer[12] || pointer[26] || pointer[27]) { 1699 /* invalid zero fields */ 1700 return -3; 1701 } 1702 1703 offset = 13 * (lfn->sequence_number - 1); 1704 for (i = 0, j = 1; i < 13; i++, j+=2) { 1705 if (j == 11) 1706 j = 14; 1707 else if (j == 26) 1708 j = 28; 1709 1710 if (pointer[j] == 0 && pointer[j + 1] == 0) { 1711 /* end of long file name */ 1712 break; 1713 } 1714 gunichar2 c = (pointer[j + 1] << 8) + pointer[j]; 1715 lfn->name2[offset + i] = c; 1716 } 1717 1718 if (pointer[0] & 0x40) { 1719 /* first entry; set len */ 1720 lfn->len = offset + i; 1721 } 1722 if ((pointer[0] & 0x3f) == 0x01) { 1723 /* last entry; finalize entry */ 1724 glong olen; 1725 gchar *utf8 = g_utf16_to_utf8(lfn->name2, lfn->len, NULL, &olen, NULL); 1726 if (!utf8) { 1727 return -4; 1728 } 1729 lfn->len = olen; 1730 memcpy(lfn->name, utf8, olen + 1); 1731 g_free(utf8); 1732 } 1733 1734 return 0; 1735 } 1736 1737 /* returns 0 if successful, >0 if no short_name, and <0 on error */ 1738 static int parse_short_name(BDRVVVFATState* s, 1739 long_file_name* lfn, direntry_t* direntry) 1740 { 1741 int i, j; 1742 1743 if (!is_short_name(direntry)) 1744 return 1; 1745 1746 for (j = 7; j >= 0 && direntry->name[j] == ' '; j--); 1747 for (i = 0; i <= j; i++) { 1748 uint8_t c = direntry->name[i]; 1749 if (c != to_valid_short_char(c)) { 1750 return -1; 1751 } else if (s->downcase_short_names) { 1752 lfn->name[i] = qemu_tolower(direntry->name[i]); 1753 } else { 1754 lfn->name[i] = direntry->name[i]; 1755 } 1756 } 1757 1758 for (j = 2; j >= 0 && direntry->name[8 + j] == ' '; j--) { 1759 } 1760 if (j >= 0) { 1761 lfn->name[i++] = '.'; 1762 lfn->name[i + j + 1] = '\0'; 1763 for (;j >= 0; j--) { 1764 uint8_t c = direntry->name[8 + j]; 1765 if (c != to_valid_short_char(c)) { 1766 return -2; 1767 } else if (s->downcase_short_names) { 1768 lfn->name[i + j] = qemu_tolower(c); 1769 } else { 1770 lfn->name[i + j] = c; 1771 } 1772 } 1773 } else 1774 lfn->name[i + j + 1] = '\0'; 1775 1776 if (lfn->name[0] == DIR_KANJI_FAKE) { 1777 lfn->name[0] = DIR_KANJI; 1778 } 1779 lfn->len = strlen((char*)lfn->name); 1780 1781 return 0; 1782 } 1783 1784 static inline uint32_t modified_fat_get(BDRVVVFATState* s, 1785 unsigned int cluster) 1786 { 1787 if (cluster < s->last_cluster_of_root_directory) { 1788 if (cluster + 1 == s->last_cluster_of_root_directory) 1789 return s->max_fat_value; 1790 else 1791 return cluster + 1; 1792 } 1793 1794 if (s->fat_type==32) { 1795 uint32_t* entry=((uint32_t*)s->fat2)+cluster; 1796 return le32_to_cpu(*entry); 1797 } else if (s->fat_type==16) { 1798 uint16_t* entry=((uint16_t*)s->fat2)+cluster; 1799 return le16_to_cpu(*entry); 1800 } else { 1801 const uint8_t* x=s->fat2+cluster*3/2; 1802 return ((x[0]|(x[1]<<8))>>(cluster&1?4:0))&0x0fff; 1803 } 1804 } 1805 1806 static inline bool coroutine_fn GRAPH_RDLOCK 1807 cluster_was_modified(BDRVVVFATState *s, uint32_t cluster_num) 1808 { 1809 int was_modified = 0; 1810 int i; 1811 1812 if (s->qcow == NULL) { 1813 return 0; 1814 } 1815 1816 for (i = 0; !was_modified && i < s->sectors_per_cluster; i++) { 1817 was_modified = bdrv_co_is_allocated(s->qcow->bs, 1818 (cluster2sector(s, cluster_num) + 1819 i) * BDRV_SECTOR_SIZE, 1820 BDRV_SECTOR_SIZE, NULL); 1821 } 1822 1823 /* 1824 * Note that this treats failures to learn allocation status the 1825 * same as if an allocation has occurred. It's as safe as 1826 * anything else, given that a failure to learn allocation status 1827 * will probably result in more failures. 1828 */ 1829 return !!was_modified; 1830 } 1831 1832 static const char* get_basename(const char* path) 1833 { 1834 char* basename = strrchr(path, '/'); 1835 if (basename == NULL) 1836 return path; 1837 else 1838 return basename + 1; /* strip '/' */ 1839 } 1840 1841 /* 1842 * The array s->used_clusters holds the states of the clusters. If it is 1843 * part of a file, it has bit 2 set, in case of a directory, bit 1. If it 1844 * was modified, bit 3 is set. 1845 * If any cluster is allocated, but not part of a file or directory, this 1846 * driver refuses to commit. 1847 */ 1848 typedef enum { 1849 USED_DIRECTORY = 1, USED_FILE = 2, USED_ANY = 3, USED_ALLOCATED = 4 1850 } used_t; 1851 1852 /* 1853 * get_cluster_count_for_direntry() not only determines how many clusters 1854 * are occupied by direntry, but also if it was renamed or modified. 1855 * 1856 * A file is thought to be renamed *only* if there already was a file with 1857 * exactly the same first cluster, but a different name. 1858 * 1859 * Further, the files/directories handled by this function are 1860 * assumed to be *not* deleted (and *only* those). 1861 */ 1862 static uint32_t coroutine_fn GRAPH_RDLOCK 1863 get_cluster_count_for_direntry(BDRVVVFATState* s, direntry_t* direntry, const char* path) 1864 { 1865 /* 1866 * This is a little bit tricky: 1867 * IF the guest OS just inserts a cluster into the file chain, 1868 * and leaves the rest alone, (i.e. the original file had clusters 1869 * 15 -> 16, but now has 15 -> 32 -> 16), then the following happens: 1870 * 1871 * - do_commit will write the cluster into the file at the given 1872 * offset, but 1873 * 1874 * - the cluster which is overwritten should be moved to a later 1875 * position in the file. 1876 * 1877 * I am not aware that any OS does something as braindead, but this 1878 * situation could happen anyway when not committing for a long time. 1879 * Just to be sure that this does not bite us, detect it, and copy the 1880 * contents of the clusters to-be-overwritten into the qcow. 1881 */ 1882 int copy_it = 0; 1883 int was_modified = 0; 1884 int32_t ret = 0; 1885 1886 uint32_t cluster_num = begin_of_direntry(direntry); 1887 uint32_t offset = 0; 1888 mapping_t* mapping = NULL; 1889 const char* basename2 = NULL; 1890 1891 vvfat_close_current_file(s); 1892 1893 /* the root directory */ 1894 if (cluster_num == 0) 1895 return 0; 1896 1897 /* write support */ 1898 if (s->qcow) { 1899 basename2 = get_basename(path); 1900 1901 mapping = find_mapping_for_cluster(s, cluster_num); 1902 1903 if (mapping) { 1904 const char* basename; 1905 1906 assert(mapping->mode & MODE_DELETED); 1907 mapping->mode &= ~MODE_DELETED; 1908 1909 basename = get_basename(mapping->path); 1910 1911 assert(mapping->mode & MODE_NORMAL); 1912 1913 /* rename */ 1914 if (strcmp(basename, basename2)) 1915 schedule_rename(s, cluster_num, g_strdup(path)); 1916 } else if (is_file(direntry)) 1917 /* new file */ 1918 schedule_new_file(s, g_strdup(path), cluster_num); 1919 else { 1920 abort(); 1921 return 0; 1922 } 1923 } 1924 1925 while(1) { 1926 if (s->qcow) { 1927 if (!copy_it && cluster_was_modified(s, cluster_num)) { 1928 if (mapping == NULL || 1929 mapping->begin > cluster_num || 1930 mapping->end <= cluster_num) 1931 mapping = find_mapping_for_cluster(s, cluster_num); 1932 1933 1934 if (mapping && 1935 (mapping->mode & MODE_DIRECTORY) == 0) { 1936 1937 /* was modified in qcow */ 1938 if (offset != s->cluster_size 1939 * ((cluster_num - mapping->begin) 1940 + mapping->info.file.offset)) { 1941 /* offset of this cluster in file chain has changed */ 1942 abort(); 1943 copy_it = 1; 1944 } else if (offset == 0) { 1945 const char* basename = get_basename(mapping->path); 1946 1947 if (strcmp(basename, basename2)) 1948 copy_it = 1; 1949 } 1950 assert(mapping->first_mapping_index == -1 1951 || mapping->info.file.offset > 0); 1952 1953 /* need to write out? */ 1954 if (!was_modified && is_file(direntry)) { 1955 was_modified = 1; 1956 schedule_writeout(s, mapping->dir_index, offset); 1957 } 1958 } 1959 } 1960 1961 if (copy_it) { 1962 int i; 1963 /* 1964 * This is horribly inefficient, but that is okay, since 1965 * it is rarely executed, if at all. 1966 */ 1967 int64_t offs = cluster2sector(s, cluster_num); 1968 1969 vvfat_close_current_file(s); 1970 for (i = 0; i < s->sectors_per_cluster; i++) { 1971 int res; 1972 1973 res = bdrv_co_is_allocated(s->qcow->bs, 1974 (offs + i) * BDRV_SECTOR_SIZE, 1975 BDRV_SECTOR_SIZE, NULL); 1976 if (res < 0) { 1977 return -1; 1978 } 1979 if (!res) { 1980 res = vvfat_read(s->bs, offs, s->cluster_buffer, 1); 1981 if (res) { 1982 return -1; 1983 } 1984 res = bdrv_co_pwrite(s->qcow, offs * BDRV_SECTOR_SIZE, 1985 BDRV_SECTOR_SIZE, s->cluster_buffer, 1986 0); 1987 if (res < 0) { 1988 return -2; 1989 } 1990 } 1991 } 1992 } 1993 } 1994 1995 ret++; 1996 if (s->used_clusters[cluster_num] & USED_ANY) 1997 return 0; 1998 s->used_clusters[cluster_num] = USED_FILE; 1999 2000 cluster_num = modified_fat_get(s, cluster_num); 2001 2002 if (fat_eof(s, cluster_num)) 2003 return ret; 2004 else if (cluster_num < 2 || cluster_num > s->max_fat_value - 16) 2005 return -1; 2006 2007 offset += s->cluster_size; 2008 } 2009 } 2010 2011 /* 2012 * This function looks at the modified data (qcow). 2013 * It returns 0 upon inconsistency or error, and the number of clusters 2014 * used by the directory, its subdirectories and their files. 2015 */ 2016 static int coroutine_fn GRAPH_RDLOCK 2017 check_directory_consistency(BDRVVVFATState *s, int cluster_num, const char* path) 2018 { 2019 int ret = 0; 2020 unsigned char* cluster = g_malloc(s->cluster_size); 2021 direntry_t* direntries = (direntry_t*)cluster; 2022 mapping_t* mapping = find_mapping_for_cluster(s, cluster_num); 2023 2024 long_file_name lfn; 2025 int path_len = strlen(path); 2026 char path2[PATH_MAX + 1]; 2027 2028 assert(path_len < PATH_MAX); /* len was tested before! */ 2029 pstrcpy(path2, sizeof(path2), path); 2030 path2[path_len] = '/'; 2031 path2[path_len + 1] = '\0'; 2032 2033 if (mapping) { 2034 const char* basename = get_basename(mapping->path); 2035 const char* basename2 = get_basename(path); 2036 2037 assert(mapping->mode & MODE_DIRECTORY); 2038 2039 assert(mapping->mode & MODE_DELETED); 2040 mapping->mode &= ~MODE_DELETED; 2041 2042 if (strcmp(basename, basename2)) 2043 schedule_rename(s, cluster_num, g_strdup(path)); 2044 } else 2045 /* new directory */ 2046 schedule_mkdir(s, cluster_num, g_strdup(path)); 2047 2048 lfn_init(&lfn); 2049 do { 2050 int i; 2051 int subret = 0; 2052 2053 ret++; 2054 2055 if (s->used_clusters[cluster_num] & USED_ANY) { 2056 fprintf(stderr, "cluster %d used more than once\n", (int)cluster_num); 2057 goto fail; 2058 } 2059 s->used_clusters[cluster_num] = USED_DIRECTORY; 2060 2061 DLOG(fprintf(stderr, "read cluster %d (sector %d)\n", (int)cluster_num, (int)cluster2sector(s, cluster_num))); 2062 subret = vvfat_read(s->bs, cluster2sector(s, cluster_num), cluster, 2063 s->sectors_per_cluster); 2064 if (subret) { 2065 fprintf(stderr, "Error fetching direntries\n"); 2066 fail: 2067 g_free(cluster); 2068 return 0; 2069 } 2070 2071 for (i = 0; i < 0x10 * s->sectors_per_cluster; i++) { 2072 int cluster_count = 0; 2073 2074 DLOG(fprintf(stderr, "check direntry %d:\n", i); print_direntry(direntries + i)); 2075 if (is_volume_label(direntries + i) || is_dot(direntries + i) || 2076 is_free(direntries + i)) 2077 continue; 2078 2079 subret = parse_long_name(&lfn, direntries + i); 2080 if (subret < 0) { 2081 fprintf(stderr, "Error in long name\n"); 2082 goto fail; 2083 } 2084 if (subret == 0 || is_free(direntries + i)) 2085 continue; 2086 2087 if (fat_chksum(direntries+i) != lfn.checksum) { 2088 subret = parse_short_name(s, &lfn, direntries + i); 2089 if (subret < 0) { 2090 fprintf(stderr, "Error in short name (%d)\n", subret); 2091 goto fail; 2092 } 2093 if (subret > 0 || !strcmp((char*)lfn.name, ".") 2094 || !strcmp((char*)lfn.name, "..")) 2095 continue; 2096 } 2097 lfn.checksum = 0x100; /* cannot use long name twice */ 2098 2099 if (!valid_filename(lfn.name)) { 2100 fprintf(stderr, "Invalid file name\n"); 2101 goto fail; 2102 } 2103 if (path_len + 1 + lfn.len >= PATH_MAX) { 2104 fprintf(stderr, "Name too long: %s/%s\n", path, lfn.name); 2105 goto fail; 2106 } 2107 pstrcpy(path2 + path_len + 1, sizeof(path2) - path_len - 1, 2108 (char*)lfn.name); 2109 2110 if (is_directory(direntries + i)) { 2111 if (begin_of_direntry(direntries + i) == 0) { 2112 DLOG(fprintf(stderr, "invalid begin for directory: %s\n", path2); print_direntry(direntries + i)); 2113 goto fail; 2114 } 2115 cluster_count = check_directory_consistency(s, 2116 begin_of_direntry(direntries + i), path2); 2117 if (cluster_count == 0) { 2118 DLOG(fprintf(stderr, "problem in directory %s:\n", path2); print_direntry(direntries + i)); 2119 goto fail; 2120 } 2121 } else if (is_file(direntries + i)) { 2122 /* check file size with FAT */ 2123 cluster_count = get_cluster_count_for_direntry(s, direntries + i, path2); 2124 if (cluster_count != 2125 DIV_ROUND_UP(le32_to_cpu(direntries[i].size), s->cluster_size)) { 2126 DLOG(fprintf(stderr, "Cluster count mismatch\n")); 2127 goto fail; 2128 } 2129 } else 2130 abort(); /* cluster_count = 0; */ 2131 2132 ret += cluster_count; 2133 } 2134 2135 cluster_num = modified_fat_get(s, cluster_num); 2136 } while(!fat_eof(s, cluster_num)); 2137 2138 g_free(cluster); 2139 return ret; 2140 } 2141 2142 /* returns 1 on success */ 2143 static int coroutine_fn GRAPH_RDLOCK 2144 is_consistent(BDRVVVFATState* s) 2145 { 2146 int i, check; 2147 int used_clusters_count = 0; 2148 2149 DLOG(checkpoint()); 2150 /* 2151 * - get modified FAT 2152 * - compare the two FATs (TODO) 2153 * - get buffer for marking used clusters 2154 * - recurse direntries from root (using bs->bdrv_pread to make 2155 * sure to get the new data) 2156 * - check that the FAT agrees with the size 2157 * - count the number of clusters occupied by this directory and 2158 * its files 2159 * - check that the cumulative used cluster count agrees with the 2160 * FAT 2161 * - if all is fine, return number of used clusters 2162 */ 2163 if (s->fat2 == NULL) { 2164 int size = 0x200 * s->sectors_per_fat; 2165 s->fat2 = g_malloc(size); 2166 memcpy(s->fat2, s->fat.pointer, size); 2167 } 2168 check = vvfat_read(s->bs, 2169 s->offset_to_fat, s->fat2, s->sectors_per_fat); 2170 if (check) { 2171 fprintf(stderr, "Could not copy fat\n"); 2172 return 0; 2173 } 2174 assert (s->used_clusters); 2175 for (i = 0; i < sector2cluster(s, s->sector_count); i++) 2176 s->used_clusters[i] &= ~USED_ANY; 2177 2178 clear_commits(s); 2179 2180 /* mark every mapped file/directory as deleted. 2181 * (check_directory_consistency() will unmark those still present). */ 2182 if (s->qcow) 2183 for (i = 0; i < s->mapping.next; i++) { 2184 mapping_t* mapping = array_get(&(s->mapping), i); 2185 if (mapping->first_mapping_index < 0) 2186 mapping->mode |= MODE_DELETED; 2187 } 2188 2189 used_clusters_count = check_directory_consistency(s, 0, s->path); 2190 if (used_clusters_count <= 0) { 2191 DLOG(fprintf(stderr, "problem in directory\n")); 2192 return 0; 2193 } 2194 2195 check = s->last_cluster_of_root_directory; 2196 for (i = check; i < sector2cluster(s, s->sector_count); i++) { 2197 if (modified_fat_get(s, i)) { 2198 if(!s->used_clusters[i]) { 2199 DLOG(fprintf(stderr, "FAT was modified (%d), but cluster is not used?\n", i)); 2200 return 0; 2201 } 2202 check++; 2203 } 2204 2205 if (s->used_clusters[i] == USED_ALLOCATED) { 2206 /* allocated, but not used... */ 2207 DLOG(fprintf(stderr, "unused, modified cluster: %d\n", i)); 2208 return 0; 2209 } 2210 } 2211 2212 if (check != used_clusters_count) 2213 return 0; 2214 2215 return used_clusters_count; 2216 } 2217 2218 static inline void adjust_mapping_indices(BDRVVVFATState* s, 2219 int offset, int adjust) 2220 { 2221 int i; 2222 2223 for (i = 0; i < s->mapping.next; i++) { 2224 mapping_t* mapping = array_get(&(s->mapping), i); 2225 2226 #define ADJUST_MAPPING_INDEX(name) \ 2227 if (mapping->name >= offset) \ 2228 mapping->name += adjust 2229 2230 ADJUST_MAPPING_INDEX(first_mapping_index); 2231 if (mapping->mode & MODE_DIRECTORY) 2232 ADJUST_MAPPING_INDEX(info.dir.parent_mapping_index); 2233 } 2234 } 2235 2236 /* insert or update mapping */ 2237 static mapping_t* insert_mapping(BDRVVVFATState* s, 2238 uint32_t begin, uint32_t end) 2239 { 2240 /* 2241 * - find mapping where mapping->begin >= begin, 2242 * - if mapping->begin > begin: insert 2243 * - adjust all references to mappings! 2244 * - else: adjust 2245 * - replace name 2246 */ 2247 int index = find_mapping_for_cluster_aux(s, begin, 0, s->mapping.next); 2248 mapping_t* mapping = NULL; 2249 mapping_t* first_mapping = array_get(&(s->mapping), 0); 2250 2251 if (index < s->mapping.next && (mapping = array_get(&(s->mapping), index)) 2252 && mapping->begin < begin) { 2253 mapping->end = begin; 2254 index++; 2255 mapping = array_get(&(s->mapping), index); 2256 } 2257 if (index >= s->mapping.next || mapping->begin > begin) { 2258 mapping = array_insert(&(s->mapping), index, 1); 2259 mapping->path = NULL; 2260 adjust_mapping_indices(s, index, +1); 2261 } 2262 2263 mapping->begin = begin; 2264 mapping->end = end; 2265 2266 DLOG(mapping_t* next_mapping; 2267 assert(index + 1 >= s->mapping.next || 2268 ((next_mapping = array_get(&(s->mapping), index + 1)) && 2269 next_mapping->begin >= end))); 2270 2271 if (s->current_mapping && first_mapping != (mapping_t*)s->mapping.pointer) 2272 s->current_mapping = array_get(&(s->mapping), 2273 s->current_mapping - first_mapping); 2274 2275 return mapping; 2276 } 2277 2278 static int remove_mapping(BDRVVVFATState* s, int mapping_index) 2279 { 2280 mapping_t* mapping = array_get(&(s->mapping), mapping_index); 2281 mapping_t* first_mapping = array_get(&(s->mapping), 0); 2282 2283 /* free mapping */ 2284 if (mapping->first_mapping_index < 0) { 2285 g_free(mapping->path); 2286 } 2287 2288 /* remove from s->mapping */ 2289 array_remove(&(s->mapping), mapping_index); 2290 2291 /* adjust all references to mappings */ 2292 adjust_mapping_indices(s, mapping_index, -1); 2293 2294 if (s->current_mapping && first_mapping != (mapping_t*)s->mapping.pointer) 2295 s->current_mapping = array_get(&(s->mapping), 2296 s->current_mapping - first_mapping); 2297 2298 return 0; 2299 } 2300 2301 static void adjust_dirindices(BDRVVVFATState* s, int offset, int adjust) 2302 { 2303 int i; 2304 for (i = 0; i < s->mapping.next; i++) { 2305 mapping_t* mapping = array_get(&(s->mapping), i); 2306 if (mapping->dir_index >= offset) 2307 mapping->dir_index += adjust; 2308 if ((mapping->mode & MODE_DIRECTORY) && 2309 mapping->info.dir.first_dir_index >= offset) 2310 mapping->info.dir.first_dir_index += adjust; 2311 } 2312 } 2313 2314 static direntry_t* insert_direntries(BDRVVVFATState* s, 2315 int dir_index, int count) 2316 { 2317 /* 2318 * make room in s->directory, 2319 * adjust_dirindices 2320 */ 2321 direntry_t* result = array_insert(&(s->directory), dir_index, count); 2322 if (result == NULL) 2323 return NULL; 2324 adjust_dirindices(s, dir_index, count); 2325 return result; 2326 } 2327 2328 static int remove_direntries(BDRVVVFATState* s, int dir_index, int count) 2329 { 2330 int ret = array_remove_slice(&(s->directory), dir_index, count); 2331 if (ret) 2332 return ret; 2333 adjust_dirindices(s, dir_index, -count); 2334 return 0; 2335 } 2336 2337 /* 2338 * Adapt the mappings of the cluster chain starting at first cluster 2339 * (i.e. if a file starts at first_cluster, the chain is followed according 2340 * to the modified fat, and the corresponding entries in s->mapping are 2341 * adjusted) 2342 */ 2343 static int commit_mappings(BDRVVVFATState* s, 2344 uint32_t first_cluster, int dir_index) 2345 { 2346 mapping_t* mapping = find_mapping_for_cluster(s, first_cluster); 2347 direntry_t* direntry = array_get(&(s->directory), dir_index); 2348 uint32_t cluster = first_cluster; 2349 2350 vvfat_close_current_file(s); 2351 2352 assert(mapping); 2353 assert(mapping->begin == first_cluster); 2354 mapping->first_mapping_index = -1; 2355 mapping->dir_index = dir_index; 2356 mapping->mode = (dir_index <= 0 || is_directory(direntry)) ? 2357 MODE_DIRECTORY : MODE_NORMAL; 2358 2359 while (!fat_eof(s, cluster)) { 2360 uint32_t c, c1; 2361 2362 for (c = cluster, c1 = modified_fat_get(s, c); c + 1 == c1; 2363 c = c1, c1 = modified_fat_get(s, c1)); 2364 2365 c++; 2366 if (c > mapping->end) { 2367 int index = array_index(&(s->mapping), mapping); 2368 int i, max_i = s->mapping.next - index; 2369 for (i = 1; i < max_i && mapping[i].begin < c; i++); 2370 while (--i > 0) 2371 remove_mapping(s, index + 1); 2372 } 2373 assert(mapping == array_get(&(s->mapping), s->mapping.next - 1) 2374 || mapping[1].begin >= c); 2375 mapping->end = c; 2376 2377 if (!fat_eof(s, c1)) { 2378 int i = find_mapping_for_cluster_aux(s, c1, 0, s->mapping.next); 2379 mapping_t* next_mapping = i >= s->mapping.next ? NULL : 2380 array_get(&(s->mapping), i); 2381 2382 if (next_mapping == NULL || next_mapping->begin > c1) { 2383 int i1 = array_index(&(s->mapping), mapping); 2384 2385 next_mapping = insert_mapping(s, c1, c1+1); 2386 2387 if (c1 < c) 2388 i1++; 2389 mapping = array_get(&(s->mapping), i1); 2390 } 2391 2392 next_mapping->dir_index = mapping->dir_index; 2393 next_mapping->first_mapping_index = 2394 mapping->first_mapping_index < 0 ? 2395 array_index(&(s->mapping), mapping) : 2396 mapping->first_mapping_index; 2397 next_mapping->path = mapping->path; 2398 next_mapping->mode = mapping->mode; 2399 next_mapping->read_only = mapping->read_only; 2400 if (mapping->mode & MODE_DIRECTORY) { 2401 next_mapping->info.dir.parent_mapping_index = 2402 mapping->info.dir.parent_mapping_index; 2403 next_mapping->info.dir.first_dir_index = 2404 mapping->info.dir.first_dir_index + 2405 0x10 * s->sectors_per_cluster * 2406 (mapping->end - mapping->begin); 2407 } else 2408 next_mapping->info.file.offset = mapping->info.file.offset + 2409 (mapping->end - mapping->begin); 2410 2411 mapping = next_mapping; 2412 } 2413 2414 cluster = c1; 2415 } 2416 2417 return 0; 2418 } 2419 2420 static int coroutine_fn GRAPH_RDLOCK 2421 commit_direntries(BDRVVVFATState* s, int dir_index, int parent_mapping_index) 2422 { 2423 direntry_t* direntry = array_get(&(s->directory), dir_index); 2424 uint32_t first_cluster = dir_index == 0 ? 0 : begin_of_direntry(direntry); 2425 mapping_t* mapping = find_mapping_for_cluster(s, first_cluster); 2426 int factor = 0x10 * s->sectors_per_cluster; 2427 int old_cluster_count, new_cluster_count; 2428 int current_dir_index; 2429 int first_dir_index; 2430 int ret, i; 2431 uint32_t c; 2432 2433 assert(direntry); 2434 assert(mapping); 2435 assert(mapping->begin == first_cluster); 2436 assert(mapping->info.dir.first_dir_index < s->directory.next); 2437 assert(mapping->mode & MODE_DIRECTORY); 2438 assert(dir_index == 0 || is_directory(direntry)); 2439 2440 DLOG(fprintf(stderr, "commit_direntries for %s, parent_mapping_index %d\n", 2441 mapping->path, parent_mapping_index)); 2442 2443 current_dir_index = mapping->info.dir.first_dir_index; 2444 first_dir_index = current_dir_index; 2445 mapping->info.dir.parent_mapping_index = parent_mapping_index; 2446 2447 if (first_cluster == 0) { 2448 old_cluster_count = new_cluster_count = 2449 s->last_cluster_of_root_directory; 2450 } else { 2451 for (old_cluster_count = 0, c = first_cluster; !fat_eof(s, c); 2452 c = fat_get(s, c)) 2453 old_cluster_count++; 2454 2455 for (new_cluster_count = 0, c = first_cluster; !fat_eof(s, c); 2456 c = modified_fat_get(s, c)) 2457 new_cluster_count++; 2458 } 2459 2460 if (new_cluster_count > old_cluster_count) { 2461 if (insert_direntries(s, 2462 current_dir_index + factor * old_cluster_count, 2463 factor * (new_cluster_count - old_cluster_count)) == NULL) 2464 return -1; 2465 } else if (new_cluster_count < old_cluster_count) 2466 remove_direntries(s, 2467 current_dir_index + factor * new_cluster_count, 2468 factor * (old_cluster_count - new_cluster_count)); 2469 2470 for (c = first_cluster; !fat_eof(s, c); c = modified_fat_get(s, c)) { 2471 direntry_t *first_direntry; 2472 2473 direntry = array_get(&(s->directory), current_dir_index); 2474 ret = vvfat_read(s->bs, cluster2sector(s, c), (uint8_t *)direntry, 2475 s->sectors_per_cluster); 2476 if (ret) 2477 return ret; 2478 2479 /* The first directory entry on the filesystem is the volume name */ 2480 first_direntry = (direntry_t*) s->directory.pointer; 2481 assert(!memcmp(first_direntry->name, s->volume_label, 11)); 2482 2483 current_dir_index += factor; 2484 } 2485 2486 ret = commit_mappings(s, first_cluster, dir_index); 2487 if (ret) 2488 return ret; 2489 2490 /* recurse */ 2491 for (i = 0; i < factor * new_cluster_count; i++) { 2492 direntry = array_get(&(s->directory), first_dir_index + i); 2493 if (is_directory(direntry) && !is_dot(direntry)) { 2494 mapping = find_mapping_for_cluster(s, first_cluster); 2495 if (mapping == NULL) { 2496 return -1; 2497 } 2498 assert(mapping->mode & MODE_DIRECTORY); 2499 ret = commit_direntries(s, first_dir_index + i, 2500 array_index(&(s->mapping), mapping)); 2501 if (ret) 2502 return ret; 2503 } 2504 } 2505 2506 return 0; 2507 } 2508 2509 /* commit one file (adjust contents, adjust mapping), 2510 return first_mapping_index */ 2511 static int coroutine_fn GRAPH_RDLOCK 2512 commit_one_file(BDRVVVFATState* s, int dir_index, uint32_t offset) 2513 { 2514 direntry_t* direntry = array_get(&(s->directory), dir_index); 2515 uint32_t c = begin_of_direntry(direntry); 2516 uint32_t first_cluster = c; 2517 mapping_t* mapping = find_mapping_for_cluster(s, c); 2518 uint32_t size = filesize_of_direntry(direntry); 2519 char *cluster; 2520 uint32_t i; 2521 int fd = 0; 2522 2523 assert(offset < size); 2524 assert((offset % s->cluster_size) == 0); 2525 2526 if (mapping == NULL) { 2527 return -1; 2528 } 2529 2530 for (i = 0; i < offset; i += s->cluster_size) { 2531 c = modified_fat_get(s, c); 2532 } 2533 2534 fd = qemu_open_old(mapping->path, O_RDWR | O_CREAT | O_BINARY, 0666); 2535 if (fd < 0) { 2536 fprintf(stderr, "Could not open %s... (%s, %d)\n", mapping->path, 2537 strerror(errno), errno); 2538 return fd; 2539 } 2540 if (offset > 0) { 2541 if (lseek(fd, offset, SEEK_SET) != offset) { 2542 qemu_close(fd); 2543 return -3; 2544 } 2545 } 2546 2547 cluster = g_malloc(s->cluster_size); 2548 2549 while (offset < size) { 2550 uint32_t c1; 2551 int rest_size = (size - offset > s->cluster_size ? 2552 s->cluster_size : size - offset); 2553 int ret; 2554 2555 c1 = modified_fat_get(s, c); 2556 2557 assert((size - offset == 0 && fat_eof(s, c)) || 2558 (size > offset && c >=2 && !fat_eof(s, c))); 2559 2560 ret = vvfat_read(s->bs, cluster2sector(s, c), 2561 (uint8_t*)cluster, DIV_ROUND_UP(rest_size, 0x200)); 2562 2563 if (ret < 0) { 2564 qemu_close(fd); 2565 g_free(cluster); 2566 return ret; 2567 } 2568 2569 if (write(fd, cluster, rest_size) < 0) { 2570 qemu_close(fd); 2571 g_free(cluster); 2572 return -2; 2573 } 2574 2575 offset += rest_size; 2576 c = c1; 2577 } 2578 2579 if (ftruncate(fd, size)) { 2580 perror("ftruncate()"); 2581 qemu_close(fd); 2582 g_free(cluster); 2583 return -4; 2584 } 2585 qemu_close(fd); 2586 g_free(cluster); 2587 2588 return commit_mappings(s, first_cluster, dir_index); 2589 } 2590 2591 #ifdef DEBUG 2592 /* test, if all mappings point to valid direntries */ 2593 static void check1(BDRVVVFATState* s) 2594 { 2595 int i; 2596 for (i = 0; i < s->mapping.next; i++) { 2597 mapping_t* mapping = array_get(&(s->mapping), i); 2598 if (mapping->mode & MODE_DELETED) { 2599 fprintf(stderr, "deleted\n"); 2600 continue; 2601 } 2602 assert(mapping->dir_index < s->directory.next); 2603 direntry_t* direntry = array_get(&(s->directory), mapping->dir_index); 2604 assert(mapping->begin == begin_of_direntry(direntry) || mapping->first_mapping_index >= 0); 2605 if (mapping->mode & MODE_DIRECTORY) { 2606 assert(mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster * (mapping->end - mapping->begin) <= s->directory.next); 2607 assert((mapping->info.dir.first_dir_index % (0x10 * s->sectors_per_cluster)) == 0); 2608 } 2609 } 2610 } 2611 2612 /* test, if all direntries have mappings */ 2613 static void check2(BDRVVVFATState* s) 2614 { 2615 int i; 2616 int first_mapping = -1; 2617 2618 for (i = 0; i < s->directory.next; i++) { 2619 direntry_t* direntry = array_get(&(s->directory), i); 2620 2621 if (is_short_name(direntry) && begin_of_direntry(direntry)) { 2622 mapping_t* mapping = find_mapping_for_cluster(s, begin_of_direntry(direntry)); 2623 assert(mapping); 2624 assert(mapping->dir_index == i || is_dot(direntry)); 2625 assert(mapping->begin == begin_of_direntry(direntry) || is_dot(direntry)); 2626 } 2627 2628 if ((i % (0x10 * s->sectors_per_cluster)) == 0) { 2629 /* cluster start */ 2630 int j, count = 0; 2631 2632 for (j = 0; j < s->mapping.next; j++) { 2633 mapping_t* mapping = array_get(&(s->mapping), j); 2634 if (mapping->mode & MODE_DELETED) 2635 continue; 2636 if (mapping->mode & MODE_DIRECTORY) { 2637 if (mapping->info.dir.first_dir_index <= i && mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster > i) { 2638 assert(++count == 1); 2639 if (mapping->first_mapping_index == -1) 2640 first_mapping = array_index(&(s->mapping), mapping); 2641 else 2642 assert(first_mapping == mapping->first_mapping_index); 2643 if (mapping->info.dir.parent_mapping_index < 0) 2644 assert(j == 0); 2645 else { 2646 mapping_t* parent = array_get(&(s->mapping), mapping->info.dir.parent_mapping_index); 2647 assert(parent->mode & MODE_DIRECTORY); 2648 assert(parent->info.dir.first_dir_index < mapping->info.dir.first_dir_index); 2649 } 2650 } 2651 } 2652 } 2653 if (count == 0) 2654 first_mapping = -1; 2655 } 2656 } 2657 } 2658 #endif 2659 2660 static int handle_renames_and_mkdirs(BDRVVVFATState* s) 2661 { 2662 int i; 2663 2664 #ifdef DEBUG 2665 fprintf(stderr, "handle_renames\n"); 2666 for (i = 0; i < s->commits.next; i++) { 2667 commit_t* commit = array_get(&(s->commits), i); 2668 fprintf(stderr, "%d, %s (%u, %d)\n", i, 2669 commit->path ? commit->path : "(null)", 2670 commit->param.rename.cluster, commit->action); 2671 } 2672 #endif 2673 2674 for (i = 0; i < s->commits.next;) { 2675 commit_t* commit = array_get(&(s->commits), i); 2676 if (commit->action == ACTION_RENAME) { 2677 mapping_t* mapping = find_mapping_for_cluster(s, 2678 commit->param.rename.cluster); 2679 char *old_path; 2680 2681 if (mapping == NULL) { 2682 return -1; 2683 } 2684 old_path = mapping->path; 2685 assert(commit->path); 2686 mapping->path = commit->path; 2687 if (rename(old_path, mapping->path)) 2688 return -2; 2689 2690 if (mapping->mode & MODE_DIRECTORY) { 2691 int l1 = strlen(mapping->path); 2692 int l2 = strlen(old_path); 2693 int diff = l1 - l2; 2694 direntry_t* direntry = array_get(&(s->directory), 2695 mapping->info.dir.first_dir_index); 2696 uint32_t c = mapping->begin; 2697 int j = 0; 2698 2699 /* recurse */ 2700 while (!fat_eof(s, c)) { 2701 do { 2702 direntry_t *d = direntry + j; 2703 2704 if (is_file(d) || (is_directory(d) && !is_dot(d))) { 2705 int l; 2706 char *new_path; 2707 mapping_t* m = find_mapping_for_cluster(s, 2708 begin_of_direntry(d)); 2709 if (m == NULL) { 2710 return -1; 2711 } 2712 l = strlen(m->path); 2713 new_path = g_malloc(l + diff + 1); 2714 2715 assert(!strncmp(m->path, mapping->path, l2)); 2716 2717 pstrcpy(new_path, l + diff + 1, mapping->path); 2718 pstrcpy(new_path + l1, l + diff + 1 - l1, 2719 m->path + l2); 2720 2721 schedule_rename(s, m->begin, new_path); 2722 } 2723 j++; 2724 } while (j % (0x10 * s->sectors_per_cluster) != 0); 2725 c = fat_get(s, c); 2726 } 2727 } 2728 2729 g_free(old_path); 2730 array_remove(&(s->commits), i); 2731 continue; 2732 } else if (commit->action == ACTION_MKDIR) { 2733 mapping_t* mapping; 2734 int j, parent_path_len; 2735 2736 if (g_mkdir(commit->path, 0755)) { 2737 return -5; 2738 } 2739 2740 mapping = insert_mapping(s, commit->param.mkdir.cluster, 2741 commit->param.mkdir.cluster + 1); 2742 if (mapping == NULL) 2743 return -6; 2744 2745 mapping->mode = MODE_DIRECTORY; 2746 mapping->read_only = 0; 2747 mapping->path = commit->path; 2748 j = s->directory.next; 2749 assert(j); 2750 insert_direntries(s, s->directory.next, 2751 0x10 * s->sectors_per_cluster); 2752 mapping->info.dir.first_dir_index = j; 2753 2754 parent_path_len = strlen(commit->path) 2755 - strlen(get_basename(commit->path)) - 1; 2756 for (j = 0; j < s->mapping.next; j++) { 2757 mapping_t* m = array_get(&(s->mapping), j); 2758 if (m->first_mapping_index < 0 && m != mapping && 2759 !strncmp(m->path, mapping->path, parent_path_len) && 2760 strlen(m->path) == parent_path_len) 2761 break; 2762 } 2763 assert(j < s->mapping.next); 2764 mapping->info.dir.parent_mapping_index = j; 2765 2766 array_remove(&(s->commits), i); 2767 continue; 2768 } 2769 2770 i++; 2771 } 2772 return 0; 2773 } 2774 2775 /* 2776 * TODO: make sure that the short name is not matching *another* file 2777 */ 2778 static int coroutine_fn GRAPH_RDLOCK handle_commits(BDRVVVFATState* s) 2779 { 2780 int i, fail = 0; 2781 2782 vvfat_close_current_file(s); 2783 2784 for (i = 0; !fail && i < s->commits.next; i++) { 2785 commit_t* commit = array_get(&(s->commits), i); 2786 switch(commit->action) { 2787 case ACTION_RENAME: case ACTION_MKDIR: 2788 abort(); 2789 fail = -2; 2790 break; 2791 case ACTION_WRITEOUT: { 2792 direntry_t* entry = array_get(&(s->directory), 2793 commit->param.writeout.dir_index); 2794 uint32_t begin = begin_of_direntry(entry); 2795 mapping_t* mapping = find_mapping_for_cluster(s, begin); 2796 2797 assert(mapping); 2798 assert(mapping->begin == begin); 2799 assert(commit->path == NULL); 2800 2801 if (commit_one_file(s, commit->param.writeout.dir_index, 2802 commit->param.writeout.modified_offset)) 2803 fail = -3; 2804 2805 break; 2806 } 2807 case ACTION_NEW_FILE: { 2808 int begin = commit->param.new_file.first_cluster; 2809 mapping_t* mapping = find_mapping_for_cluster(s, begin); 2810 direntry_t* entry; 2811 int j; 2812 2813 /* find direntry */ 2814 for (j = 0; j < s->directory.next; j++) { 2815 entry = array_get(&(s->directory), j); 2816 if (is_file(entry) && begin_of_direntry(entry) == begin) 2817 break; 2818 } 2819 2820 if (j >= s->directory.next) { 2821 fail = -6; 2822 continue; 2823 } 2824 2825 /* make sure there exists an initial mapping */ 2826 if (mapping && mapping->begin != begin) { 2827 mapping->end = begin; 2828 mapping = NULL; 2829 } 2830 if (mapping == NULL) { 2831 mapping = insert_mapping(s, begin, begin+1); 2832 } 2833 /* most members will be fixed in commit_mappings() */ 2834 assert(commit->path); 2835 mapping->path = commit->path; 2836 mapping->read_only = 0; 2837 mapping->mode = MODE_NORMAL; 2838 mapping->info.file.offset = 0; 2839 2840 if (commit_one_file(s, j, 0)) { 2841 fail = -7; 2842 } 2843 2844 break; 2845 } 2846 default: 2847 abort(); 2848 } 2849 } 2850 if (i > 0 && array_remove_slice(&(s->commits), 0, i)) 2851 return -1; 2852 return fail; 2853 } 2854 2855 static int handle_deletes(BDRVVVFATState* s) 2856 { 2857 int i, deferred = 1, deleted = 1; 2858 2859 /* delete files corresponding to mappings marked as deleted */ 2860 /* handle DELETEs and unused mappings (modified_fat_get(s, mapping->begin) == 0) */ 2861 while (deferred && deleted) { 2862 deferred = 0; 2863 deleted = 0; 2864 2865 for (i = 1; i < s->mapping.next; i++) { 2866 mapping_t* mapping = array_get(&(s->mapping), i); 2867 if (mapping->mode & MODE_DELETED) { 2868 direntry_t* entry = array_get(&(s->directory), 2869 mapping->dir_index); 2870 2871 if (is_free(entry)) { 2872 /* remove file/directory */ 2873 if (mapping->mode & MODE_DIRECTORY) { 2874 int j, next_dir_index = s->directory.next, 2875 first_dir_index = mapping->info.dir.first_dir_index; 2876 2877 if (rmdir(mapping->path) < 0) { 2878 if (errno == ENOTEMPTY) { 2879 deferred++; 2880 continue; 2881 } else 2882 return -5; 2883 } 2884 2885 for (j = 1; j < s->mapping.next; j++) { 2886 mapping_t* m = array_get(&(s->mapping), j); 2887 if (m->mode & MODE_DIRECTORY && 2888 m->info.dir.first_dir_index > 2889 first_dir_index && 2890 m->info.dir.first_dir_index < 2891 next_dir_index) 2892 next_dir_index = 2893 m->info.dir.first_dir_index; 2894 } 2895 remove_direntries(s, first_dir_index, 2896 next_dir_index - first_dir_index); 2897 2898 deleted++; 2899 } 2900 } else { 2901 if (unlink(mapping->path)) 2902 return -4; 2903 deleted++; 2904 } 2905 DLOG(fprintf(stderr, "DELETE (%d)\n", i); print_mapping(mapping); print_direntry(entry)); 2906 remove_mapping(s, i); 2907 } 2908 } 2909 } 2910 2911 return 0; 2912 } 2913 2914 /* 2915 * synchronize mapping with new state: 2916 * 2917 * - copy FAT (with bdrv_pread) 2918 * - mark all filenames corresponding to mappings as deleted 2919 * - recurse direntries from root (using bs->bdrv_pread) 2920 * - delete files corresponding to mappings marked as deleted 2921 */ 2922 static int coroutine_fn GRAPH_RDLOCK do_commit(BDRVVVFATState* s) 2923 { 2924 int ret = 0; 2925 2926 /* the real meat are the commits. Nothing to do? Move along! */ 2927 if (s->commits.next == 0) 2928 return 0; 2929 2930 vvfat_close_current_file(s); 2931 2932 ret = handle_renames_and_mkdirs(s); 2933 if (ret) { 2934 fprintf(stderr, "Error handling renames (%d)\n", ret); 2935 abort(); 2936 return ret; 2937 } 2938 2939 /* copy FAT (with bdrv_pread) */ 2940 memcpy(s->fat.pointer, s->fat2, 0x200 * s->sectors_per_fat); 2941 2942 /* recurse direntries from root (using bs->bdrv_pread) */ 2943 ret = commit_direntries(s, 0, -1); 2944 if (ret) { 2945 fprintf(stderr, "Fatal: error while committing (%d)\n", ret); 2946 abort(); 2947 return ret; 2948 } 2949 2950 ret = handle_commits(s); 2951 if (ret) { 2952 fprintf(stderr, "Error handling commits (%d)\n", ret); 2953 abort(); 2954 return ret; 2955 } 2956 2957 ret = handle_deletes(s); 2958 if (ret) { 2959 fprintf(stderr, "Error deleting\n"); 2960 abort(); 2961 return ret; 2962 } 2963 2964 bdrv_make_empty(s->qcow, NULL); 2965 2966 memset(s->used_clusters, 0, sector2cluster(s, s->sector_count)); 2967 2968 DLOG(checkpoint()); 2969 return 0; 2970 } 2971 2972 static int coroutine_fn GRAPH_RDLOCK try_commit(BDRVVVFATState* s) 2973 { 2974 vvfat_close_current_file(s); 2975 DLOG(checkpoint()); 2976 if(!is_consistent(s)) 2977 return -1; 2978 return do_commit(s); 2979 } 2980 2981 static int coroutine_fn GRAPH_RDLOCK 2982 vvfat_write(BlockDriverState *bs, int64_t sector_num, 2983 const uint8_t *buf, int nb_sectors) 2984 { 2985 BDRVVVFATState *s = bs->opaque; 2986 int i, ret; 2987 int first_cluster, last_cluster; 2988 2989 DLOG(checkpoint()); 2990 2991 /* Check if we're operating in read-only mode */ 2992 if (s->qcow == NULL) { 2993 return -EACCES; 2994 } 2995 2996 vvfat_close_current_file(s); 2997 2998 if (sector_num == s->offset_to_bootsector && nb_sectors == 1) { 2999 /* 3000 * Write on bootsector. Allow only changing the reserved1 field, 3001 * used to mark volume dirtiness 3002 */ 3003 unsigned char *bootsector = s->first_sectors 3004 + s->offset_to_bootsector * 0x200; 3005 /* 3006 * LATER TODO: if FAT32, this is wrong (see init_directories(), 3007 * which always creates a FAT16 bootsector) 3008 */ 3009 const int reserved1_offset = offsetof(bootsector_t, u.fat16.reserved1); 3010 3011 for (i = 0; i < 0x200; i++) { 3012 if (i != reserved1_offset && bootsector[i] != buf[i]) { 3013 fprintf(stderr, "Tried to write to protected bootsector\n"); 3014 return -1; 3015 } 3016 } 3017 3018 /* Update bootsector with the only updatable byte, and return success */ 3019 bootsector[reserved1_offset] = buf[reserved1_offset]; 3020 return 0; 3021 } 3022 3023 /* 3024 * Some sanity checks: 3025 * - do not allow writing to the boot sector 3026 */ 3027 if (sector_num < s->offset_to_fat) 3028 return -1; 3029 3030 /* 3031 * Values will be negative for writes to the FAT, which is located before 3032 * the root directory. 3033 */ 3034 first_cluster = sector2cluster(s, sector_num); 3035 last_cluster = sector2cluster(s, sector_num + nb_sectors - 1); 3036 3037 for (i = first_cluster; i <= last_cluster;) { 3038 mapping_t *mapping = NULL; 3039 3040 if (i >= 0) { 3041 mapping = find_mapping_for_cluster(s, i); 3042 } 3043 3044 if (mapping) { 3045 if (mapping->read_only) { 3046 fprintf(stderr, "Tried to write to write-protected file %s\n", 3047 mapping->path); 3048 return -1; 3049 } 3050 3051 if (mapping->mode & MODE_DIRECTORY) { 3052 int begin = cluster2sector(s, i); 3053 int end = begin + s->sectors_per_cluster, k; 3054 int dir_index; 3055 const direntry_t* direntries; 3056 long_file_name lfn; 3057 3058 lfn_init(&lfn); 3059 3060 if (begin < sector_num) 3061 begin = sector_num; 3062 if (end > sector_num + nb_sectors) 3063 end = sector_num + nb_sectors; 3064 dir_index = mapping->dir_index + 3065 0x10 * (begin - mapping->begin * s->sectors_per_cluster); 3066 direntries = (direntry_t*)(buf + 0x200 * (begin - sector_num)); 3067 3068 for (k = 0; k < (end - begin) * 0x10; k++) { 3069 /* no access to the direntry of a read-only file */ 3070 if (is_short_name(direntries + k) && 3071 (direntries[k].attributes & 1)) { 3072 if (memcmp(direntries + k, 3073 array_get(&(s->directory), dir_index + k), 3074 sizeof(direntry_t))) { 3075 warn_report("tried to write to write-protected " 3076 "file"); 3077 return -1; 3078 } 3079 } 3080 } 3081 } 3082 i = mapping->end; 3083 } else { 3084 i++; 3085 } 3086 } 3087 3088 /* 3089 * Use qcow backend. Commit later. 3090 */ 3091 DLOG(fprintf(stderr, "Write to qcow backend: %d + %d\n", (int)sector_num, nb_sectors)); 3092 ret = bdrv_co_pwrite(s->qcow, sector_num * BDRV_SECTOR_SIZE, 3093 nb_sectors * BDRV_SECTOR_SIZE, buf, 0); 3094 if (ret < 0) { 3095 fprintf(stderr, "Error writing to qcow backend\n"); 3096 return ret; 3097 } 3098 3099 for (i = first_cluster; i <= last_cluster; i++) { 3100 if (i >= 0) { 3101 s->used_clusters[i] |= USED_ALLOCATED; 3102 } 3103 } 3104 3105 DLOG(checkpoint()); 3106 /* TODO: add timeout */ 3107 try_commit(s); 3108 3109 DLOG(checkpoint()); 3110 return 0; 3111 } 3112 3113 static int coroutine_fn GRAPH_RDLOCK 3114 vvfat_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes, 3115 QEMUIOVector *qiov, BdrvRequestFlags flags) 3116 { 3117 int ret; 3118 BDRVVVFATState *s = bs->opaque; 3119 uint64_t sector_num = offset >> BDRV_SECTOR_BITS; 3120 int nb_sectors = bytes >> BDRV_SECTOR_BITS; 3121 void *buf; 3122 3123 assert(QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE)); 3124 assert(QEMU_IS_ALIGNED(bytes, BDRV_SECTOR_SIZE)); 3125 3126 buf = g_try_malloc(bytes); 3127 if (bytes && buf == NULL) { 3128 return -ENOMEM; 3129 } 3130 qemu_iovec_to_buf(qiov, 0, buf, bytes); 3131 3132 qemu_co_mutex_lock(&s->lock); 3133 ret = vvfat_write(bs, sector_num, buf, nb_sectors); 3134 qemu_co_mutex_unlock(&s->lock); 3135 3136 g_free(buf); 3137 3138 return ret; 3139 } 3140 3141 static int coroutine_fn vvfat_co_block_status(BlockDriverState *bs, 3142 bool want_zero, int64_t offset, 3143 int64_t bytes, int64_t *n, 3144 int64_t *map, 3145 BlockDriverState **file) 3146 { 3147 *n = bytes; 3148 return BDRV_BLOCK_DATA; 3149 } 3150 3151 static void vvfat_qcow_options(BdrvChildRole role, bool parent_is_format, 3152 int *child_flags, QDict *child_options, 3153 int parent_flags, QDict *parent_options) 3154 { 3155 qdict_set_default_str(child_options, BDRV_OPT_READ_ONLY, "off"); 3156 qdict_set_default_str(child_options, BDRV_OPT_AUTO_READ_ONLY, "off"); 3157 qdict_set_default_str(child_options, BDRV_OPT_CACHE_NO_FLUSH, "on"); 3158 } 3159 3160 static BdrvChildClass child_vvfat_qcow; 3161 3162 static int enable_write_target(BlockDriverState *bs, Error **errp) 3163 { 3164 BDRVVVFATState *s = bs->opaque; 3165 BlockDriver *bdrv_qcow = NULL; 3166 QemuOpts *opts = NULL; 3167 int ret; 3168 int size = sector2cluster(s, s->sector_count); 3169 QDict *options; 3170 3171 s->used_clusters = g_malloc0(size); 3172 3173 array_init(&(s->commits), sizeof(commit_t)); 3174 3175 s->qcow_filename = create_tmp_file(errp); 3176 if (!s->qcow_filename) { 3177 ret = -ENOENT; 3178 goto err; 3179 } 3180 3181 bdrv_qcow = bdrv_find_format("qcow"); 3182 if (!bdrv_qcow) { 3183 error_setg(errp, "Failed to locate qcow driver"); 3184 ret = -ENOENT; 3185 goto err; 3186 } 3187 3188 opts = qemu_opts_create(bdrv_qcow->create_opts, NULL, 0, &error_abort); 3189 qemu_opt_set_number(opts, BLOCK_OPT_SIZE, 3190 bs->total_sectors * BDRV_SECTOR_SIZE, &error_abort); 3191 qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, "fat:", &error_abort); 3192 3193 ret = bdrv_create(bdrv_qcow, s->qcow_filename, opts, errp); 3194 qemu_opts_del(opts); 3195 if (ret < 0) { 3196 goto err; 3197 } 3198 3199 options = qdict_new(); 3200 qdict_put_str(options, "write-target.driver", "qcow"); 3201 s->qcow = bdrv_open_child(s->qcow_filename, options, "write-target", bs, 3202 &child_vvfat_qcow, 3203 BDRV_CHILD_DATA | BDRV_CHILD_METADATA, 3204 false, errp); 3205 qobject_unref(options); 3206 if (!s->qcow) { 3207 ret = -EINVAL; 3208 goto err; 3209 } 3210 3211 #ifndef _WIN32 3212 unlink(s->qcow_filename); 3213 #endif 3214 3215 return 0; 3216 3217 err: 3218 return ret; 3219 } 3220 3221 static void vvfat_child_perm(BlockDriverState *bs, BdrvChild *c, 3222 BdrvChildRole role, 3223 BlockReopenQueue *reopen_queue, 3224 uint64_t perm, uint64_t shared, 3225 uint64_t *nperm, uint64_t *nshared) 3226 { 3227 assert(role & BDRV_CHILD_DATA); 3228 /* This is a private node, nobody should try to attach to it */ 3229 *nperm = BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE; 3230 *nshared = BLK_PERM_WRITE_UNCHANGED; 3231 } 3232 3233 static void vvfat_close(BlockDriverState *bs) 3234 { 3235 BDRVVVFATState *s = bs->opaque; 3236 3237 vvfat_close_current_file(s); 3238 array_free(&(s->fat)); 3239 array_free(&(s->directory)); 3240 array_free(&(s->mapping)); 3241 g_free(s->cluster_buffer); 3242 3243 if (s->qcow) { 3244 migrate_del_blocker(&s->migration_blocker); 3245 } 3246 } 3247 3248 static const char *const vvfat_strong_runtime_opts[] = { 3249 "dir", 3250 "fat-type", 3251 "floppy", 3252 "label", 3253 "rw", 3254 3255 NULL 3256 }; 3257 3258 static BlockDriver bdrv_vvfat = { 3259 .format_name = "vvfat", 3260 .protocol_name = "fat", 3261 .instance_size = sizeof(BDRVVVFATState), 3262 3263 .bdrv_parse_filename = vvfat_parse_filename, 3264 .bdrv_open = vvfat_open, 3265 .bdrv_refresh_limits = vvfat_refresh_limits, 3266 .bdrv_close = vvfat_close, 3267 .bdrv_child_perm = vvfat_child_perm, 3268 3269 .bdrv_co_preadv = vvfat_co_preadv, 3270 .bdrv_co_pwritev = vvfat_co_pwritev, 3271 .bdrv_co_block_status = vvfat_co_block_status, 3272 3273 .strong_runtime_opts = vvfat_strong_runtime_opts, 3274 }; 3275 3276 static void bdrv_vvfat_init(void) 3277 { 3278 child_vvfat_qcow = child_of_bds; 3279 child_vvfat_qcow.inherit_options = vvfat_qcow_options; 3280 bdrv_register(&bdrv_vvfat); 3281 } 3282 3283 block_init(bdrv_vvfat_init); 3284 3285 #ifdef DEBUG 3286 static void checkpoint(void) 3287 { 3288 assert(((mapping_t*)array_get(&(vvv->mapping), 0))->end == 2); 3289 check1(vvv); 3290 check2(vvv); 3291 assert(!vvv->current_mapping || vvv->current_fd || (vvv->current_mapping->mode & MODE_DIRECTORY)); 3292 } 3293 #endif 3294