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