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 #include "qemu/osdep.h" 26 #include <dirent.h> 27 #include "qapi/error.h" 28 #include "block/block_int.h" 29 #include "qemu/module.h" 30 #include "qemu/bswap.h" 31 #include "migration/blocker.h" 32 #include "qapi/qmp/qbool.h" 33 #include "qapi/qmp/qstring.h" 34 #include "qemu/cutils.h" 35 #include "qemu/error-report.h" 36 37 #ifndef S_IWGRP 38 #define S_IWGRP 0 39 #endif 40 #ifndef S_IWOTH 41 #define S_IWOTH 0 42 #endif 43 44 /* TODO: add ":bootsector=blabla.img:" */ 45 /* LATER TODO: add automatic boot sector generation from 46 BOOTEASY.ASM and Ranish Partition Manager 47 Note that DOS assumes the system files to be the first files in the 48 file system (test if the boot sector still relies on that fact)! */ 49 /* MAYBE TODO: write block-visofs.c */ 50 /* TODO: call try_commit() only after a timeout */ 51 52 /* #define DEBUG */ 53 54 #ifdef DEBUG 55 56 #define DLOG(a) a 57 58 static void checkpoint(void); 59 60 #else 61 62 #define DLOG(a) 63 64 #endif 65 66 /* bootsector OEM name. see related compatibility problems at: 67 * https://jdebp.eu/FGA/volume-boot-block-oem-name-field.html 68 * http://seasip.info/Misc/oemid.html 69 */ 70 #define BOOTSECTOR_OEM_NAME "MSWIN4.1" 71 72 #define DIR_DELETED 0xe5 73 #define DIR_KANJI DIR_DELETED 74 #define DIR_KANJI_FAKE 0x05 75 #define DIR_FREE 0x00 76 77 /* dynamic array functions */ 78 typedef struct array_t { 79 char* pointer; 80 unsigned int size,next,item_size; 81 } array_t; 82 83 static inline void array_init(array_t* array,unsigned int item_size) 84 { 85 array->pointer = NULL; 86 array->size=0; 87 array->next=0; 88 array->item_size=item_size; 89 } 90 91 static inline void array_free(array_t* array) 92 { 93 g_free(array->pointer); 94 array->size=array->next=0; 95 } 96 97 /* does not automatically grow */ 98 static inline void* array_get(array_t* array,unsigned int index) { 99 assert(index < array->next); 100 return array->pointer + index * array->item_size; 101 } 102 103 static inline int array_ensure_allocated(array_t* array, int index) 104 { 105 if((index + 1) * array->item_size > array->size) { 106 int new_size = (index + 32) * array->item_size; 107 array->pointer = g_realloc(array->pointer, new_size); 108 if (!array->pointer) 109 return -1; 110 memset(array->pointer + array->size, 0, new_size - array->size); 111 array->size = new_size; 112 array->next = index + 1; 113 } 114 115 return 0; 116 } 117 118 static inline void* array_get_next(array_t* array) { 119 unsigned int next = array->next; 120 121 if (array_ensure_allocated(array, next) < 0) 122 return NULL; 123 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 mapping->begin = cluster; 974 if(read_directory(s, i)) { 975 error_setg(errp, "Could not read directory %s", 976 mapping->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 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 if (!bdrv_is_read_only(bs)) { 1263 error_report("Opening non-rw vvfat images without an explicit " 1264 "read-only=on option is deprecated. Future versions " 1265 "will refuse to open the image instead of " 1266 "automatically marking the image read-only."); 1267 /* read only is the default for safety */ 1268 ret = bdrv_set_read_only(bs, true, &local_err); 1269 if (ret < 0) { 1270 error_propagate(errp, local_err); 1271 goto fail; 1272 } 1273 } 1274 1275 bs->total_sectors = cyls * heads * secs; 1276 1277 if (init_directories(s, dirname, heads, secs, errp)) { 1278 ret = -EIO; 1279 goto fail; 1280 } 1281 1282 s->sector_count = s->offset_to_root_dir 1283 + s->sectors_per_cluster * s->cluster_count; 1284 1285 /* Disable migration when vvfat is used rw */ 1286 if (s->qcow) { 1287 error_setg(&s->migration_blocker, 1288 "The vvfat (rw) format used by node '%s' " 1289 "does not support live migration", 1290 bdrv_get_device_or_node_name(bs)); 1291 ret = migrate_add_blocker(s->migration_blocker, &local_err); 1292 if (local_err) { 1293 error_propagate(errp, local_err); 1294 error_free(s->migration_blocker); 1295 goto fail; 1296 } 1297 } 1298 1299 if (s->offset_to_bootsector > 0) { 1300 init_mbr(s, cyls, heads, secs); 1301 } 1302 1303 qemu_co_mutex_init(&s->lock); 1304 1305 ret = 0; 1306 fail: 1307 qemu_opts_del(opts); 1308 return ret; 1309 } 1310 1311 static void vvfat_refresh_limits(BlockDriverState *bs, Error **errp) 1312 { 1313 bs->bl.request_alignment = BDRV_SECTOR_SIZE; /* No sub-sector I/O */ 1314 } 1315 1316 static inline void vvfat_close_current_file(BDRVVVFATState *s) 1317 { 1318 if(s->current_mapping) { 1319 s->current_mapping = NULL; 1320 if (s->current_fd) { 1321 qemu_close(s->current_fd); 1322 s->current_fd = 0; 1323 } 1324 } 1325 s->current_cluster = -1; 1326 } 1327 1328 /* mappings between index1 and index2-1 are supposed to be ordered 1329 * return value is the index of the last mapping for which end>cluster_num 1330 */ 1331 static inline int find_mapping_for_cluster_aux(BDRVVVFATState* s,int cluster_num,int index1,int index2) 1332 { 1333 while(1) { 1334 int index3; 1335 mapping_t* mapping; 1336 index3=(index1+index2)/2; 1337 mapping=array_get(&(s->mapping),index3); 1338 assert(mapping->begin < mapping->end); 1339 if(mapping->begin>=cluster_num) { 1340 assert(index2!=index3 || index2==0); 1341 if(index2==index3) 1342 return index1; 1343 index2=index3; 1344 } else { 1345 if(index1==index3) 1346 return mapping->end<=cluster_num ? index2 : index1; 1347 index1=index3; 1348 } 1349 assert(index1<=index2); 1350 DLOG(mapping=array_get(&(s->mapping),index1); 1351 assert(mapping->begin<=cluster_num); 1352 assert(index2 >= s->mapping.next || 1353 ((mapping = array_get(&(s->mapping),index2)) && 1354 mapping->end>cluster_num))); 1355 } 1356 } 1357 1358 static inline mapping_t* find_mapping_for_cluster(BDRVVVFATState* s,int cluster_num) 1359 { 1360 int index=find_mapping_for_cluster_aux(s,cluster_num,0,s->mapping.next); 1361 mapping_t* mapping; 1362 if(index>=s->mapping.next) 1363 return NULL; 1364 mapping=array_get(&(s->mapping),index); 1365 if(mapping->begin>cluster_num) 1366 return NULL; 1367 assert(mapping->begin<=cluster_num && mapping->end>cluster_num); 1368 return mapping; 1369 } 1370 1371 static int open_file(BDRVVVFATState* s,mapping_t* mapping) 1372 { 1373 if(!mapping) 1374 return -1; 1375 if(!s->current_mapping || 1376 strcmp(s->current_mapping->path,mapping->path)) { 1377 /* open file */ 1378 int fd = qemu_open(mapping->path, O_RDONLY | O_BINARY | O_LARGEFILE); 1379 if(fd<0) 1380 return -1; 1381 vvfat_close_current_file(s); 1382 s->current_fd = fd; 1383 s->current_mapping = mapping; 1384 } 1385 return 0; 1386 } 1387 1388 static inline int read_cluster(BDRVVVFATState *s,int cluster_num) 1389 { 1390 if(s->current_cluster != cluster_num) { 1391 int result=0; 1392 off_t offset; 1393 assert(!s->current_mapping || s->current_fd || (s->current_mapping->mode & MODE_DIRECTORY)); 1394 if(!s->current_mapping 1395 || s->current_mapping->begin>cluster_num 1396 || s->current_mapping->end<=cluster_num) { 1397 /* binary search of mappings for file */ 1398 mapping_t* mapping=find_mapping_for_cluster(s,cluster_num); 1399 1400 assert(!mapping || (cluster_num>=mapping->begin && cluster_num<mapping->end)); 1401 1402 if (mapping && mapping->mode & MODE_DIRECTORY) { 1403 vvfat_close_current_file(s); 1404 s->current_mapping = mapping; 1405 read_cluster_directory: 1406 offset = s->cluster_size*(cluster_num-s->current_mapping->begin); 1407 s->cluster = (unsigned char*)s->directory.pointer+offset 1408 + 0x20*s->current_mapping->info.dir.first_dir_index; 1409 assert(((s->cluster-(unsigned char*)s->directory.pointer)%s->cluster_size)==0); 1410 assert((char*)s->cluster+s->cluster_size <= s->directory.pointer+s->directory.next*s->directory.item_size); 1411 s->current_cluster = cluster_num; 1412 return 0; 1413 } 1414 1415 if(open_file(s,mapping)) 1416 return -2; 1417 } else if (s->current_mapping->mode & MODE_DIRECTORY) 1418 goto read_cluster_directory; 1419 1420 assert(s->current_fd); 1421 1422 offset=s->cluster_size*(cluster_num-s->current_mapping->begin)+s->current_mapping->info.file.offset; 1423 if(lseek(s->current_fd, offset, SEEK_SET)!=offset) 1424 return -3; 1425 s->cluster=s->cluster_buffer; 1426 result=read(s->current_fd,s->cluster,s->cluster_size); 1427 if(result<0) { 1428 s->current_cluster = -1; 1429 return -1; 1430 } 1431 s->current_cluster = cluster_num; 1432 } 1433 return 0; 1434 } 1435 1436 #ifdef DEBUG 1437 static void print_direntry(const direntry_t* direntry) 1438 { 1439 int j = 0; 1440 char buffer[1024]; 1441 1442 fprintf(stderr, "direntry %p: ", direntry); 1443 if(!direntry) 1444 return; 1445 if(is_long_name(direntry)) { 1446 unsigned char* c=(unsigned char*)direntry; 1447 int i; 1448 for(i=1;i<11 && c[i] && c[i]!=0xff;i+=2) 1449 #define ADD_CHAR(c) {buffer[j] = (c); if (buffer[j] < ' ') buffer[j] = 0xb0; j++;} 1450 ADD_CHAR(c[i]); 1451 for(i=14;i<26 && c[i] && c[i]!=0xff;i+=2) 1452 ADD_CHAR(c[i]); 1453 for(i=28;i<32 && c[i] && c[i]!=0xff;i+=2) 1454 ADD_CHAR(c[i]); 1455 buffer[j] = 0; 1456 fprintf(stderr, "%s\n", buffer); 1457 } else { 1458 int i; 1459 for(i=0;i<11;i++) 1460 ADD_CHAR(direntry->name[i]); 1461 buffer[j] = 0; 1462 fprintf(stderr,"%s attributes=0x%02x begin=%d size=%d\n", 1463 buffer, 1464 direntry->attributes, 1465 begin_of_direntry(direntry),le32_to_cpu(direntry->size)); 1466 } 1467 } 1468 1469 static void print_mapping(const mapping_t* mapping) 1470 { 1471 fprintf(stderr, "mapping (%p): begin, end = %d, %d, dir_index = %d, " 1472 "first_mapping_index = %d, name = %s, mode = 0x%x, " , 1473 mapping, mapping->begin, mapping->end, mapping->dir_index, 1474 mapping->first_mapping_index, mapping->path, mapping->mode); 1475 1476 if (mapping->mode & MODE_DIRECTORY) 1477 fprintf(stderr, "parent_mapping_index = %d, first_dir_index = %d\n", mapping->info.dir.parent_mapping_index, mapping->info.dir.first_dir_index); 1478 else 1479 fprintf(stderr, "offset = %d\n", mapping->info.file.offset); 1480 } 1481 #endif 1482 1483 static int vvfat_read(BlockDriverState *bs, int64_t sector_num, 1484 uint8_t *buf, int nb_sectors) 1485 { 1486 BDRVVVFATState *s = bs->opaque; 1487 int i; 1488 1489 for(i=0;i<nb_sectors;i++,sector_num++) { 1490 if (sector_num >= bs->total_sectors) 1491 return -1; 1492 if (s->qcow) { 1493 int64_t n; 1494 int ret; 1495 ret = bdrv_is_allocated(s->qcow->bs, sector_num * BDRV_SECTOR_SIZE, 1496 (nb_sectors - i) * BDRV_SECTOR_SIZE, &n); 1497 if (ret < 0) { 1498 return ret; 1499 } 1500 if (ret) { 1501 DLOG(fprintf(stderr, "sectors %" PRId64 "+%" PRId64 1502 " allocated\n", sector_num, 1503 n >> BDRV_SECTOR_BITS)); 1504 if (bdrv_read(s->qcow, sector_num, buf + i * 0x200, 1505 n >> BDRV_SECTOR_BITS)) { 1506 return -1; 1507 } 1508 i += (n >> BDRV_SECTOR_BITS) - 1; 1509 sector_num += (n >> BDRV_SECTOR_BITS) - 1; 1510 continue; 1511 } 1512 DLOG(fprintf(stderr, "sector %" PRId64 " not allocated\n", 1513 sector_num)); 1514 } 1515 if (sector_num < s->offset_to_root_dir) { 1516 if (sector_num < s->offset_to_fat) { 1517 memcpy(buf + i * 0x200, 1518 &(s->first_sectors[sector_num * 0x200]), 1519 0x200); 1520 } else if (sector_num < s->offset_to_fat + s->sectors_per_fat) { 1521 memcpy(buf + i * 0x200, 1522 &(s->fat.pointer[(sector_num 1523 - s->offset_to_fat) * 0x200]), 1524 0x200); 1525 } else if (sector_num < s->offset_to_root_dir) { 1526 memcpy(buf + i * 0x200, 1527 &(s->fat.pointer[(sector_num - s->offset_to_fat 1528 - s->sectors_per_fat) * 0x200]), 1529 0x200); 1530 } 1531 } else { 1532 uint32_t sector = sector_num - s->offset_to_root_dir, 1533 sector_offset_in_cluster=(sector%s->sectors_per_cluster), 1534 cluster_num=sector/s->sectors_per_cluster; 1535 if(cluster_num > s->cluster_count || read_cluster(s, cluster_num) != 0) { 1536 /* LATER TODO: strict: return -1; */ 1537 memset(buf+i*0x200,0,0x200); 1538 continue; 1539 } 1540 memcpy(buf+i*0x200,s->cluster+sector_offset_in_cluster*0x200,0x200); 1541 } 1542 } 1543 return 0; 1544 } 1545 1546 static int coroutine_fn 1547 vvfat_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes, 1548 QEMUIOVector *qiov, int flags) 1549 { 1550 int ret; 1551 BDRVVVFATState *s = bs->opaque; 1552 uint64_t sector_num = offset >> BDRV_SECTOR_BITS; 1553 int nb_sectors = bytes >> BDRV_SECTOR_BITS; 1554 void *buf; 1555 1556 assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0); 1557 assert((bytes & (BDRV_SECTOR_SIZE - 1)) == 0); 1558 1559 buf = g_try_malloc(bytes); 1560 if (bytes && buf == NULL) { 1561 return -ENOMEM; 1562 } 1563 1564 qemu_co_mutex_lock(&s->lock); 1565 ret = vvfat_read(bs, sector_num, buf, nb_sectors); 1566 qemu_co_mutex_unlock(&s->lock); 1567 1568 qemu_iovec_from_buf(qiov, 0, buf, bytes); 1569 g_free(buf); 1570 1571 return ret; 1572 } 1573 1574 /* LATER TODO: statify all functions */ 1575 1576 /* 1577 * Idea of the write support (use snapshot): 1578 * 1579 * 1. check if all data is consistent, recording renames, modifications, 1580 * new files and directories (in s->commits). 1581 * 1582 * 2. if the data is not consistent, stop committing 1583 * 1584 * 3. handle renames, and create new files and directories (do not yet 1585 * write their contents) 1586 * 1587 * 4. walk the directories, fixing the mapping and direntries, and marking 1588 * the handled mappings as not deleted 1589 * 1590 * 5. commit the contents of the files 1591 * 1592 * 6. handle deleted files and directories 1593 * 1594 */ 1595 1596 typedef struct commit_t { 1597 char* path; 1598 union { 1599 struct { uint32_t cluster; } rename; 1600 struct { int dir_index; uint32_t modified_offset; } writeout; 1601 struct { uint32_t first_cluster; } new_file; 1602 struct { uint32_t cluster; } mkdir; 1603 } param; 1604 /* DELETEs and RMDIRs are handled differently: see handle_deletes() */ 1605 enum { 1606 ACTION_RENAME, ACTION_WRITEOUT, ACTION_NEW_FILE, ACTION_MKDIR 1607 } action; 1608 } commit_t; 1609 1610 static void clear_commits(BDRVVVFATState* s) 1611 { 1612 int i; 1613 DLOG(fprintf(stderr, "clear_commits (%d commits)\n", s->commits.next)); 1614 for (i = 0; i < s->commits.next; i++) { 1615 commit_t* commit = array_get(&(s->commits), i); 1616 assert(commit->path || commit->action == ACTION_WRITEOUT); 1617 if (commit->action != ACTION_WRITEOUT) { 1618 assert(commit->path); 1619 g_free(commit->path); 1620 } else 1621 assert(commit->path == NULL); 1622 } 1623 s->commits.next = 0; 1624 } 1625 1626 static void schedule_rename(BDRVVVFATState* s, 1627 uint32_t cluster, char* new_path) 1628 { 1629 commit_t* commit = array_get_next(&(s->commits)); 1630 commit->path = new_path; 1631 commit->param.rename.cluster = cluster; 1632 commit->action = ACTION_RENAME; 1633 } 1634 1635 static void schedule_writeout(BDRVVVFATState* s, 1636 int dir_index, uint32_t modified_offset) 1637 { 1638 commit_t* commit = array_get_next(&(s->commits)); 1639 commit->path = NULL; 1640 commit->param.writeout.dir_index = dir_index; 1641 commit->param.writeout.modified_offset = modified_offset; 1642 commit->action = ACTION_WRITEOUT; 1643 } 1644 1645 static void schedule_new_file(BDRVVVFATState* s, 1646 char* path, uint32_t first_cluster) 1647 { 1648 commit_t* commit = array_get_next(&(s->commits)); 1649 commit->path = path; 1650 commit->param.new_file.first_cluster = first_cluster; 1651 commit->action = ACTION_NEW_FILE; 1652 } 1653 1654 static void schedule_mkdir(BDRVVVFATState* s, uint32_t cluster, char* path) 1655 { 1656 commit_t* commit = array_get_next(&(s->commits)); 1657 commit->path = path; 1658 commit->param.mkdir.cluster = cluster; 1659 commit->action = ACTION_MKDIR; 1660 } 1661 1662 typedef struct { 1663 /* 1664 * Since the sequence number is at most 0x3f, and the filename 1665 * length is at most 13 times the sequence number, the maximal 1666 * filename length is 0x3f * 13 bytes. 1667 */ 1668 unsigned char name[0x3f * 13 + 1]; 1669 gunichar2 name2[0x3f * 13 + 1]; 1670 int checksum, len; 1671 int sequence_number; 1672 } long_file_name; 1673 1674 static void lfn_init(long_file_name* lfn) 1675 { 1676 lfn->sequence_number = lfn->len = 0; 1677 lfn->checksum = 0x100; 1678 } 1679 1680 /* return 0 if parsed successfully, > 0 if no long name, < 0 if error */ 1681 static int parse_long_name(long_file_name* lfn, 1682 const direntry_t* direntry) 1683 { 1684 int i, j, offset; 1685 const unsigned char* pointer = (const unsigned char*)direntry; 1686 1687 if (!is_long_name(direntry)) 1688 return 1; 1689 1690 if (pointer[0] & 0x40) { 1691 /* first entry; do some initialization */ 1692 lfn->sequence_number = pointer[0] & 0x3f; 1693 lfn->checksum = pointer[13]; 1694 lfn->name[0] = 0; 1695 lfn->name[lfn->sequence_number * 13] = 0; 1696 } else if ((pointer[0] & 0x3f) != --lfn->sequence_number) { 1697 /* not the expected sequence number */ 1698 return -1; 1699 } else if (pointer[13] != lfn->checksum) { 1700 /* not the expected checksum */ 1701 return -2; 1702 } else if (pointer[12] || pointer[26] || pointer[27]) { 1703 /* invalid zero fields */ 1704 return -3; 1705 } 1706 1707 offset = 13 * (lfn->sequence_number - 1); 1708 for (i = 0, j = 1; i < 13; i++, j+=2) { 1709 if (j == 11) 1710 j = 14; 1711 else if (j == 26) 1712 j = 28; 1713 1714 if (pointer[j] == 0 && pointer[j + 1] == 0) { 1715 /* end of long file name */ 1716 break; 1717 } 1718 gunichar2 c = (pointer[j + 1] << 8) + pointer[j]; 1719 lfn->name2[offset + i] = c; 1720 } 1721 1722 if (pointer[0] & 0x40) { 1723 /* first entry; set len */ 1724 lfn->len = offset + i; 1725 } 1726 if ((pointer[0] & 0x3f) == 0x01) { 1727 /* last entry; finalize entry */ 1728 glong olen; 1729 gchar *utf8 = g_utf16_to_utf8(lfn->name2, lfn->len, NULL, &olen, NULL); 1730 if (!utf8) { 1731 return -4; 1732 } 1733 lfn->len = olen; 1734 memcpy(lfn->name, utf8, olen + 1); 1735 g_free(utf8); 1736 } 1737 1738 return 0; 1739 } 1740 1741 /* returns 0 if successful, >0 if no short_name, and <0 on error */ 1742 static int parse_short_name(BDRVVVFATState* s, 1743 long_file_name* lfn, direntry_t* direntry) 1744 { 1745 int i, j; 1746 1747 if (!is_short_name(direntry)) 1748 return 1; 1749 1750 for (j = 7; j >= 0 && direntry->name[j] == ' '; j--); 1751 for (i = 0; i <= j; i++) { 1752 uint8_t c = direntry->name[i]; 1753 if (c != to_valid_short_char(c)) { 1754 return -1; 1755 } else if (s->downcase_short_names) { 1756 lfn->name[i] = qemu_tolower(direntry->name[i]); 1757 } else { 1758 lfn->name[i] = direntry->name[i]; 1759 } 1760 } 1761 1762 for (j = 2; j >= 0 && direntry->name[8 + j] == ' '; j--) { 1763 } 1764 if (j >= 0) { 1765 lfn->name[i++] = '.'; 1766 lfn->name[i + j + 1] = '\0'; 1767 for (;j >= 0; j--) { 1768 uint8_t c = direntry->name[8 + j]; 1769 if (c != to_valid_short_char(c)) { 1770 return -2; 1771 } else if (s->downcase_short_names) { 1772 lfn->name[i + j] = qemu_tolower(c); 1773 } else { 1774 lfn->name[i + j] = c; 1775 } 1776 } 1777 } else 1778 lfn->name[i + j + 1] = '\0'; 1779 1780 if (lfn->name[0] == DIR_KANJI_FAKE) { 1781 lfn->name[0] = DIR_KANJI; 1782 } 1783 lfn->len = strlen((char*)lfn->name); 1784 1785 return 0; 1786 } 1787 1788 static inline uint32_t modified_fat_get(BDRVVVFATState* s, 1789 unsigned int cluster) 1790 { 1791 if (cluster < s->last_cluster_of_root_directory) { 1792 if (cluster + 1 == s->last_cluster_of_root_directory) 1793 return s->max_fat_value; 1794 else 1795 return cluster + 1; 1796 } 1797 1798 if (s->fat_type==32) { 1799 uint32_t* entry=((uint32_t*)s->fat2)+cluster; 1800 return le32_to_cpu(*entry); 1801 } else if (s->fat_type==16) { 1802 uint16_t* entry=((uint16_t*)s->fat2)+cluster; 1803 return le16_to_cpu(*entry); 1804 } else { 1805 const uint8_t* x=s->fat2+cluster*3/2; 1806 return ((x[0]|(x[1]<<8))>>(cluster&1?4:0))&0x0fff; 1807 } 1808 } 1809 1810 static inline bool cluster_was_modified(BDRVVVFATState *s, 1811 uint32_t cluster_num) 1812 { 1813 int was_modified = 0; 1814 int i; 1815 1816 if (s->qcow == NULL) { 1817 return 0; 1818 } 1819 1820 for (i = 0; !was_modified && i < s->sectors_per_cluster; i++) { 1821 was_modified = bdrv_is_allocated(s->qcow->bs, 1822 (cluster2sector(s, cluster_num) + 1823 i) * BDRV_SECTOR_SIZE, 1824 BDRV_SECTOR_SIZE, NULL); 1825 } 1826 1827 /* 1828 * Note that this treats failures to learn allocation status the 1829 * same as if an allocation has occurred. It's as safe as 1830 * anything else, given that a failure to learn allocation status 1831 * will probably result in more failures. 1832 */ 1833 return !!was_modified; 1834 } 1835 1836 static const char* get_basename(const char* path) 1837 { 1838 char* basename = strrchr(path, '/'); 1839 if (basename == NULL) 1840 return path; 1841 else 1842 return basename + 1; /* strip '/' */ 1843 } 1844 1845 /* 1846 * The array s->used_clusters holds the states of the clusters. If it is 1847 * part of a file, it has bit 2 set, in case of a directory, bit 1. If it 1848 * was modified, bit 3 is set. 1849 * If any cluster is allocated, but not part of a file or directory, this 1850 * driver refuses to commit. 1851 */ 1852 typedef enum { 1853 USED_DIRECTORY = 1, USED_FILE = 2, USED_ANY = 3, USED_ALLOCATED = 4 1854 } used_t; 1855 1856 /* 1857 * get_cluster_count_for_direntry() not only determines how many clusters 1858 * are occupied by direntry, but also if it was renamed or modified. 1859 * 1860 * A file is thought to be renamed *only* if there already was a file with 1861 * exactly the same first cluster, but a different name. 1862 * 1863 * Further, the files/directories handled by this function are 1864 * assumed to be *not* deleted (and *only* those). 1865 */ 1866 static uint32_t get_cluster_count_for_direntry(BDRVVVFATState* s, 1867 direntry_t* direntry, const char* path) 1868 { 1869 /* 1870 * This is a little bit tricky: 1871 * IF the guest OS just inserts a cluster into the file chain, 1872 * and leaves the rest alone, (i.e. the original file had clusters 1873 * 15 -> 16, but now has 15 -> 32 -> 16), then the following happens: 1874 * 1875 * - do_commit will write the cluster into the file at the given 1876 * offset, but 1877 * 1878 * - the cluster which is overwritten should be moved to a later 1879 * position in the file. 1880 * 1881 * I am not aware that any OS does something as braindead, but this 1882 * situation could happen anyway when not committing for a long time. 1883 * Just to be sure that this does not bite us, detect it, and copy the 1884 * contents of the clusters to-be-overwritten into the qcow. 1885 */ 1886 int copy_it = 0; 1887 int was_modified = 0; 1888 int32_t ret = 0; 1889 1890 uint32_t cluster_num = begin_of_direntry(direntry); 1891 uint32_t offset = 0; 1892 int first_mapping_index = -1; 1893 mapping_t* mapping = NULL; 1894 const char* basename2 = NULL; 1895 1896 vvfat_close_current_file(s); 1897 1898 /* the root directory */ 1899 if (cluster_num == 0) 1900 return 0; 1901 1902 /* write support */ 1903 if (s->qcow) { 1904 basename2 = get_basename(path); 1905 1906 mapping = find_mapping_for_cluster(s, cluster_num); 1907 1908 if (mapping) { 1909 const char* basename; 1910 1911 assert(mapping->mode & MODE_DELETED); 1912 mapping->mode &= ~MODE_DELETED; 1913 1914 basename = get_basename(mapping->path); 1915 1916 assert(mapping->mode & MODE_NORMAL); 1917 1918 /* rename */ 1919 if (strcmp(basename, basename2)) 1920 schedule_rename(s, cluster_num, g_strdup(path)); 1921 } else if (is_file(direntry)) 1922 /* new file */ 1923 schedule_new_file(s, g_strdup(path), cluster_num); 1924 else { 1925 abort(); 1926 return 0; 1927 } 1928 } 1929 1930 while(1) { 1931 if (s->qcow) { 1932 if (!copy_it && cluster_was_modified(s, cluster_num)) { 1933 if (mapping == NULL || 1934 mapping->begin > cluster_num || 1935 mapping->end <= cluster_num) 1936 mapping = find_mapping_for_cluster(s, cluster_num); 1937 1938 1939 if (mapping && 1940 (mapping->mode & MODE_DIRECTORY) == 0) { 1941 1942 /* was modified in qcow */ 1943 if (offset != mapping->info.file.offset + s->cluster_size 1944 * (cluster_num - mapping->begin)) { 1945 /* offset of this cluster in file chain has changed */ 1946 abort(); 1947 copy_it = 1; 1948 } else if (offset == 0) { 1949 const char* basename = get_basename(mapping->path); 1950 1951 if (strcmp(basename, basename2)) 1952 copy_it = 1; 1953 first_mapping_index = array_index(&(s->mapping), mapping); 1954 } 1955 1956 if (mapping->first_mapping_index != first_mapping_index 1957 && mapping->info.file.offset > 0) { 1958 abort(); 1959 copy_it = 1; 1960 } 1961 1962 /* need to write out? */ 1963 if (!was_modified && is_file(direntry)) { 1964 was_modified = 1; 1965 schedule_writeout(s, mapping->dir_index, offset); 1966 } 1967 } 1968 } 1969 1970 if (copy_it) { 1971 int i; 1972 /* 1973 * This is horribly inefficient, but that is okay, since 1974 * it is rarely executed, if at all. 1975 */ 1976 int64_t offset = cluster2sector(s, cluster_num); 1977 1978 vvfat_close_current_file(s); 1979 for (i = 0; i < s->sectors_per_cluster; i++) { 1980 int res; 1981 1982 res = bdrv_is_allocated(s->qcow->bs, 1983 (offset + i) * BDRV_SECTOR_SIZE, 1984 BDRV_SECTOR_SIZE, NULL); 1985 if (res < 0) { 1986 return -1; 1987 } 1988 if (!res) { 1989 res = vvfat_read(s->bs, offset, s->cluster_buffer, 1); 1990 if (res) { 1991 return -1; 1992 } 1993 res = bdrv_write(s->qcow, offset, s->cluster_buffer, 1); 1994 if (res) { 1995 return -2; 1996 } 1997 } 1998 } 1999 } 2000 } 2001 2002 ret++; 2003 if (s->used_clusters[cluster_num] & USED_ANY) 2004 return 0; 2005 s->used_clusters[cluster_num] = USED_FILE; 2006 2007 cluster_num = modified_fat_get(s, cluster_num); 2008 2009 if (fat_eof(s, cluster_num)) 2010 return ret; 2011 else if (cluster_num < 2 || cluster_num > s->max_fat_value - 16) 2012 return -1; 2013 2014 offset += s->cluster_size; 2015 } 2016 } 2017 2018 /* 2019 * This function looks at the modified data (qcow). 2020 * It returns 0 upon inconsistency or error, and the number of clusters 2021 * used by the directory, its subdirectories and their files. 2022 */ 2023 static int check_directory_consistency(BDRVVVFATState *s, 2024 int cluster_num, const char* path) 2025 { 2026 int ret = 0; 2027 unsigned char* cluster = g_malloc(s->cluster_size); 2028 direntry_t* direntries = (direntry_t*)cluster; 2029 mapping_t* mapping = find_mapping_for_cluster(s, cluster_num); 2030 2031 long_file_name lfn; 2032 int path_len = strlen(path); 2033 char path2[PATH_MAX + 1]; 2034 2035 assert(path_len < PATH_MAX); /* len was tested before! */ 2036 pstrcpy(path2, sizeof(path2), path); 2037 path2[path_len] = '/'; 2038 path2[path_len + 1] = '\0'; 2039 2040 if (mapping) { 2041 const char* basename = get_basename(mapping->path); 2042 const char* basename2 = get_basename(path); 2043 2044 assert(mapping->mode & MODE_DIRECTORY); 2045 2046 assert(mapping->mode & MODE_DELETED); 2047 mapping->mode &= ~MODE_DELETED; 2048 2049 if (strcmp(basename, basename2)) 2050 schedule_rename(s, cluster_num, g_strdup(path)); 2051 } else 2052 /* new directory */ 2053 schedule_mkdir(s, cluster_num, g_strdup(path)); 2054 2055 lfn_init(&lfn); 2056 do { 2057 int i; 2058 int subret = 0; 2059 2060 ret++; 2061 2062 if (s->used_clusters[cluster_num] & USED_ANY) { 2063 fprintf(stderr, "cluster %d used more than once\n", (int)cluster_num); 2064 goto fail; 2065 } 2066 s->used_clusters[cluster_num] = USED_DIRECTORY; 2067 2068 DLOG(fprintf(stderr, "read cluster %d (sector %d)\n", (int)cluster_num, (int)cluster2sector(s, cluster_num))); 2069 subret = vvfat_read(s->bs, cluster2sector(s, cluster_num), cluster, 2070 s->sectors_per_cluster); 2071 if (subret) { 2072 fprintf(stderr, "Error fetching direntries\n"); 2073 fail: 2074 g_free(cluster); 2075 return 0; 2076 } 2077 2078 for (i = 0; i < 0x10 * s->sectors_per_cluster; i++) { 2079 int cluster_count = 0; 2080 2081 DLOG(fprintf(stderr, "check direntry %d:\n", i); print_direntry(direntries + i)); 2082 if (is_volume_label(direntries + i) || is_dot(direntries + i) || 2083 is_free(direntries + i)) 2084 continue; 2085 2086 subret = parse_long_name(&lfn, direntries + i); 2087 if (subret < 0) { 2088 fprintf(stderr, "Error in long name\n"); 2089 goto fail; 2090 } 2091 if (subret == 0 || is_free(direntries + i)) 2092 continue; 2093 2094 if (fat_chksum(direntries+i) != lfn.checksum) { 2095 subret = parse_short_name(s, &lfn, direntries + i); 2096 if (subret < 0) { 2097 fprintf(stderr, "Error in short name (%d)\n", subret); 2098 goto fail; 2099 } 2100 if (subret > 0 || !strcmp((char*)lfn.name, ".") 2101 || !strcmp((char*)lfn.name, "..")) 2102 continue; 2103 } 2104 lfn.checksum = 0x100; /* cannot use long name twice */ 2105 2106 if (path_len + 1 + lfn.len >= PATH_MAX) { 2107 fprintf(stderr, "Name too long: %s/%s\n", path, lfn.name); 2108 goto fail; 2109 } 2110 pstrcpy(path2 + path_len + 1, sizeof(path2) - path_len - 1, 2111 (char*)lfn.name); 2112 2113 if (is_directory(direntries + i)) { 2114 if (begin_of_direntry(direntries + i) == 0) { 2115 DLOG(fprintf(stderr, "invalid begin for directory: %s\n", path2); print_direntry(direntries + i)); 2116 goto fail; 2117 } 2118 cluster_count = check_directory_consistency(s, 2119 begin_of_direntry(direntries + i), path2); 2120 if (cluster_count == 0) { 2121 DLOG(fprintf(stderr, "problem in directory %s:\n", path2); print_direntry(direntries + i)); 2122 goto fail; 2123 } 2124 } else if (is_file(direntries + i)) { 2125 /* check file size with FAT */ 2126 cluster_count = get_cluster_count_for_direntry(s, direntries + i, path2); 2127 if (cluster_count != 2128 DIV_ROUND_UP(le32_to_cpu(direntries[i].size), s->cluster_size)) { 2129 DLOG(fprintf(stderr, "Cluster count mismatch\n")); 2130 goto fail; 2131 } 2132 } else 2133 abort(); /* cluster_count = 0; */ 2134 2135 ret += cluster_count; 2136 } 2137 2138 cluster_num = modified_fat_get(s, cluster_num); 2139 } while(!fat_eof(s, cluster_num)); 2140 2141 g_free(cluster); 2142 return ret; 2143 } 2144 2145 /* returns 1 on success */ 2146 static int is_consistent(BDRVVVFATState* s) 2147 { 2148 int i, check; 2149 int used_clusters_count = 0; 2150 2151 DLOG(checkpoint()); 2152 /* 2153 * - get modified FAT 2154 * - compare the two FATs (TODO) 2155 * - get buffer for marking used clusters 2156 * - recurse direntries from root (using bs->bdrv_read to make 2157 * sure to get the new data) 2158 * - check that the FAT agrees with the size 2159 * - count the number of clusters occupied by this directory and 2160 * its files 2161 * - check that the cumulative used cluster count agrees with the 2162 * FAT 2163 * - if all is fine, return number of used clusters 2164 */ 2165 if (s->fat2 == NULL) { 2166 int size = 0x200 * s->sectors_per_fat; 2167 s->fat2 = g_malloc(size); 2168 memcpy(s->fat2, s->fat.pointer, size); 2169 } 2170 check = vvfat_read(s->bs, 2171 s->offset_to_fat, s->fat2, s->sectors_per_fat); 2172 if (check) { 2173 fprintf(stderr, "Could not copy fat\n"); 2174 return 0; 2175 } 2176 assert (s->used_clusters); 2177 for (i = 0; i < sector2cluster(s, s->sector_count); i++) 2178 s->used_clusters[i] &= ~USED_ANY; 2179 2180 clear_commits(s); 2181 2182 /* mark every mapped file/directory as deleted. 2183 * (check_directory_consistency() will unmark those still present). */ 2184 if (s->qcow) 2185 for (i = 0; i < s->mapping.next; i++) { 2186 mapping_t* mapping = array_get(&(s->mapping), i); 2187 if (mapping->first_mapping_index < 0) 2188 mapping->mode |= MODE_DELETED; 2189 } 2190 2191 used_clusters_count = check_directory_consistency(s, 0, s->path); 2192 if (used_clusters_count <= 0) { 2193 DLOG(fprintf(stderr, "problem in directory\n")); 2194 return 0; 2195 } 2196 2197 check = s->last_cluster_of_root_directory; 2198 for (i = check; i < sector2cluster(s, s->sector_count); i++) { 2199 if (modified_fat_get(s, i)) { 2200 if(!s->used_clusters[i]) { 2201 DLOG(fprintf(stderr, "FAT was modified (%d), but cluster is not used?\n", i)); 2202 return 0; 2203 } 2204 check++; 2205 } 2206 2207 if (s->used_clusters[i] == USED_ALLOCATED) { 2208 /* allocated, but not used... */ 2209 DLOG(fprintf(stderr, "unused, modified cluster: %d\n", i)); 2210 return 0; 2211 } 2212 } 2213 2214 if (check != used_clusters_count) 2215 return 0; 2216 2217 return used_clusters_count; 2218 } 2219 2220 static inline void adjust_mapping_indices(BDRVVVFATState* s, 2221 int offset, int adjust) 2222 { 2223 int i; 2224 2225 for (i = 0; i < s->mapping.next; i++) { 2226 mapping_t* mapping = array_get(&(s->mapping), i); 2227 2228 #define ADJUST_MAPPING_INDEX(name) \ 2229 if (mapping->name >= offset) \ 2230 mapping->name += adjust 2231 2232 ADJUST_MAPPING_INDEX(first_mapping_index); 2233 if (mapping->mode & MODE_DIRECTORY) 2234 ADJUST_MAPPING_INDEX(info.dir.parent_mapping_index); 2235 } 2236 } 2237 2238 /* insert or update mapping */ 2239 static mapping_t* insert_mapping(BDRVVVFATState* s, 2240 uint32_t begin, uint32_t end) 2241 { 2242 /* 2243 * - find mapping where mapping->begin >= begin, 2244 * - if mapping->begin > begin: insert 2245 * - adjust all references to mappings! 2246 * - else: adjust 2247 * - replace name 2248 */ 2249 int index = find_mapping_for_cluster_aux(s, begin, 0, s->mapping.next); 2250 mapping_t* mapping = NULL; 2251 mapping_t* first_mapping = array_get(&(s->mapping), 0); 2252 2253 if (index < s->mapping.next && (mapping = array_get(&(s->mapping), index)) 2254 && mapping->begin < begin) { 2255 mapping->end = begin; 2256 index++; 2257 mapping = array_get(&(s->mapping), index); 2258 } 2259 if (index >= s->mapping.next || mapping->begin > begin) { 2260 mapping = array_insert(&(s->mapping), index, 1); 2261 mapping->path = NULL; 2262 adjust_mapping_indices(s, index, +1); 2263 } 2264 2265 mapping->begin = begin; 2266 mapping->end = end; 2267 2268 DLOG(mapping_t* next_mapping; 2269 assert(index + 1 >= s->mapping.next || 2270 ((next_mapping = array_get(&(s->mapping), index + 1)) && 2271 next_mapping->begin >= end))); 2272 2273 if (s->current_mapping && first_mapping != (mapping_t*)s->mapping.pointer) 2274 s->current_mapping = array_get(&(s->mapping), 2275 s->current_mapping - first_mapping); 2276 2277 return mapping; 2278 } 2279 2280 static int remove_mapping(BDRVVVFATState* s, int mapping_index) 2281 { 2282 mapping_t* mapping = array_get(&(s->mapping), mapping_index); 2283 mapping_t* first_mapping = array_get(&(s->mapping), 0); 2284 2285 /* free mapping */ 2286 if (mapping->first_mapping_index < 0) { 2287 g_free(mapping->path); 2288 } 2289 2290 /* remove from s->mapping */ 2291 array_remove(&(s->mapping), mapping_index); 2292 2293 /* adjust all references to mappings */ 2294 adjust_mapping_indices(s, mapping_index, -1); 2295 2296 if (s->current_mapping && first_mapping != (mapping_t*)s->mapping.pointer) 2297 s->current_mapping = array_get(&(s->mapping), 2298 s->current_mapping - first_mapping); 2299 2300 return 0; 2301 } 2302 2303 static void adjust_dirindices(BDRVVVFATState* s, int offset, int adjust) 2304 { 2305 int i; 2306 for (i = 0; i < s->mapping.next; i++) { 2307 mapping_t* mapping = array_get(&(s->mapping), i); 2308 if (mapping->dir_index >= offset) 2309 mapping->dir_index += adjust; 2310 if ((mapping->mode & MODE_DIRECTORY) && 2311 mapping->info.dir.first_dir_index >= offset) 2312 mapping->info.dir.first_dir_index += adjust; 2313 } 2314 } 2315 2316 static direntry_t* insert_direntries(BDRVVVFATState* s, 2317 int dir_index, int count) 2318 { 2319 /* 2320 * make room in s->directory, 2321 * adjust_dirindices 2322 */ 2323 direntry_t* result = array_insert(&(s->directory), dir_index, count); 2324 if (result == NULL) 2325 return NULL; 2326 adjust_dirindices(s, dir_index, count); 2327 return result; 2328 } 2329 2330 static int remove_direntries(BDRVVVFATState* s, int dir_index, int count) 2331 { 2332 int ret = array_remove_slice(&(s->directory), dir_index, count); 2333 if (ret) 2334 return ret; 2335 adjust_dirindices(s, dir_index, -count); 2336 return 0; 2337 } 2338 2339 /* 2340 * Adapt the mappings of the cluster chain starting at first cluster 2341 * (i.e. if a file starts at first_cluster, the chain is followed according 2342 * to the modified fat, and the corresponding entries in s->mapping are 2343 * adjusted) 2344 */ 2345 static int commit_mappings(BDRVVVFATState* s, 2346 uint32_t first_cluster, int dir_index) 2347 { 2348 mapping_t* mapping = find_mapping_for_cluster(s, first_cluster); 2349 direntry_t* direntry = array_get(&(s->directory), dir_index); 2350 uint32_t cluster = first_cluster; 2351 2352 vvfat_close_current_file(s); 2353 2354 assert(mapping); 2355 assert(mapping->begin == first_cluster); 2356 mapping->first_mapping_index = -1; 2357 mapping->dir_index = dir_index; 2358 mapping->mode = (dir_index <= 0 || is_directory(direntry)) ? 2359 MODE_DIRECTORY : MODE_NORMAL; 2360 2361 while (!fat_eof(s, cluster)) { 2362 uint32_t c, c1; 2363 2364 for (c = cluster, c1 = modified_fat_get(s, c); c + 1 == c1; 2365 c = c1, c1 = modified_fat_get(s, c1)); 2366 2367 c++; 2368 if (c > mapping->end) { 2369 int index = array_index(&(s->mapping), mapping); 2370 int i, max_i = s->mapping.next - index; 2371 for (i = 1; i < max_i && mapping[i].begin < c; i++); 2372 while (--i > 0) 2373 remove_mapping(s, index + 1); 2374 } 2375 assert(mapping == array_get(&(s->mapping), s->mapping.next - 1) 2376 || mapping[1].begin >= c); 2377 mapping->end = c; 2378 2379 if (!fat_eof(s, c1)) { 2380 int i = find_mapping_for_cluster_aux(s, c1, 0, s->mapping.next); 2381 mapping_t* next_mapping = i >= s->mapping.next ? NULL : 2382 array_get(&(s->mapping), i); 2383 2384 if (next_mapping == NULL || next_mapping->begin > c1) { 2385 int i1 = array_index(&(s->mapping), mapping); 2386 2387 next_mapping = insert_mapping(s, c1, c1+1); 2388 2389 if (c1 < c) 2390 i1++; 2391 mapping = array_get(&(s->mapping), i1); 2392 } 2393 2394 next_mapping->dir_index = mapping->dir_index; 2395 next_mapping->first_mapping_index = 2396 mapping->first_mapping_index < 0 ? 2397 array_index(&(s->mapping), mapping) : 2398 mapping->first_mapping_index; 2399 next_mapping->path = mapping->path; 2400 next_mapping->mode = mapping->mode; 2401 next_mapping->read_only = mapping->read_only; 2402 if (mapping->mode & MODE_DIRECTORY) { 2403 next_mapping->info.dir.parent_mapping_index = 2404 mapping->info.dir.parent_mapping_index; 2405 next_mapping->info.dir.first_dir_index = 2406 mapping->info.dir.first_dir_index + 2407 0x10 * s->sectors_per_cluster * 2408 (mapping->end - mapping->begin); 2409 } else 2410 next_mapping->info.file.offset = mapping->info.file.offset + 2411 mapping->end - mapping->begin; 2412 2413 mapping = next_mapping; 2414 } 2415 2416 cluster = c1; 2417 } 2418 2419 return 0; 2420 } 2421 2422 static int commit_direntries(BDRVVVFATState* s, 2423 int dir_index, int parent_mapping_index) 2424 { 2425 direntry_t* direntry = array_get(&(s->directory), dir_index); 2426 uint32_t first_cluster = dir_index == 0 ? 0 : begin_of_direntry(direntry); 2427 mapping_t* mapping = find_mapping_for_cluster(s, first_cluster); 2428 2429 int factor = 0x10 * s->sectors_per_cluster; 2430 int old_cluster_count, new_cluster_count; 2431 int current_dir_index = mapping->info.dir.first_dir_index; 2432 int first_dir_index = current_dir_index; 2433 int ret, i; 2434 uint32_t c; 2435 2436 DLOG(fprintf(stderr, "commit_direntries for %s, parent_mapping_index %d\n", mapping->path, parent_mapping_index)); 2437 2438 assert(direntry); 2439 assert(mapping); 2440 assert(mapping->begin == first_cluster); 2441 assert(mapping->info.dir.first_dir_index < s->directory.next); 2442 assert(mapping->mode & MODE_DIRECTORY); 2443 assert(dir_index == 0 || is_directory(direntry)); 2444 2445 mapping->info.dir.parent_mapping_index = parent_mapping_index; 2446 2447 if (first_cluster == 0) { 2448 old_cluster_count = new_cluster_count = 2449 s->last_cluster_of_root_directory; 2450 } else { 2451 for (old_cluster_count = 0, c = first_cluster; !fat_eof(s, c); 2452 c = fat_get(s, c)) 2453 old_cluster_count++; 2454 2455 for (new_cluster_count = 0, c = first_cluster; !fat_eof(s, c); 2456 c = modified_fat_get(s, c)) 2457 new_cluster_count++; 2458 } 2459 2460 if (new_cluster_count > old_cluster_count) { 2461 if (insert_direntries(s, 2462 current_dir_index + factor * old_cluster_count, 2463 factor * (new_cluster_count - old_cluster_count)) == NULL) 2464 return -1; 2465 } else if (new_cluster_count < old_cluster_count) 2466 remove_direntries(s, 2467 current_dir_index + factor * new_cluster_count, 2468 factor * (old_cluster_count - new_cluster_count)); 2469 2470 for (c = first_cluster; !fat_eof(s, c); c = modified_fat_get(s, c)) { 2471 direntry_t *first_direntry; 2472 void* direntry = array_get(&(s->directory), current_dir_index); 2473 int ret = vvfat_read(s->bs, cluster2sector(s, c), direntry, 2474 s->sectors_per_cluster); 2475 if (ret) 2476 return ret; 2477 2478 /* The first directory entry on the filesystem is the volume name */ 2479 first_direntry = (direntry_t*) s->directory.pointer; 2480 assert(!memcmp(first_direntry->name, s->volume_label, 11)); 2481 2482 current_dir_index += factor; 2483 } 2484 2485 ret = commit_mappings(s, first_cluster, dir_index); 2486 if (ret) 2487 return ret; 2488 2489 /* recurse */ 2490 for (i = 0; i < factor * new_cluster_count; i++) { 2491 direntry = array_get(&(s->directory), first_dir_index + i); 2492 if (is_directory(direntry) && !is_dot(direntry)) { 2493 mapping = find_mapping_for_cluster(s, first_cluster); 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 = g_malloc(s->cluster_size); 2516 uint32_t i; 2517 int fd = 0; 2518 2519 assert(offset < size); 2520 assert((offset % s->cluster_size) == 0); 2521 2522 for (i = s->cluster_size; i < offset; i += s->cluster_size) 2523 c = modified_fat_get(s, c); 2524 2525 fd = qemu_open(mapping->path, O_RDWR | O_CREAT | O_BINARY, 0666); 2526 if (fd < 0) { 2527 fprintf(stderr, "Could not open %s... (%s, %d)\n", mapping->path, 2528 strerror(errno), errno); 2529 g_free(cluster); 2530 return fd; 2531 } 2532 if (offset > 0) { 2533 if (lseek(fd, offset, SEEK_SET) != offset) { 2534 qemu_close(fd); 2535 g_free(cluster); 2536 return -3; 2537 } 2538 } 2539 2540 while (offset < size) { 2541 uint32_t c1; 2542 int rest_size = (size - offset > s->cluster_size ? 2543 s->cluster_size : size - offset); 2544 int ret; 2545 2546 c1 = modified_fat_get(s, c); 2547 2548 assert((size - offset == 0 && fat_eof(s, c)) || 2549 (size > offset && c >=2 && !fat_eof(s, c))); 2550 2551 ret = vvfat_read(s->bs, cluster2sector(s, c), 2552 (uint8_t*)cluster, DIV_ROUND_UP(rest_size, 0x200)); 2553 2554 if (ret < 0) { 2555 qemu_close(fd); 2556 g_free(cluster); 2557 return ret; 2558 } 2559 2560 if (write(fd, cluster, rest_size) < 0) { 2561 qemu_close(fd); 2562 g_free(cluster); 2563 return -2; 2564 } 2565 2566 offset += rest_size; 2567 c = c1; 2568 } 2569 2570 if (ftruncate(fd, size)) { 2571 perror("ftruncate()"); 2572 qemu_close(fd); 2573 g_free(cluster); 2574 return -4; 2575 } 2576 qemu_close(fd); 2577 g_free(cluster); 2578 2579 return commit_mappings(s, first_cluster, dir_index); 2580 } 2581 2582 #ifdef DEBUG 2583 /* test, if all mappings point to valid direntries */ 2584 static void check1(BDRVVVFATState* s) 2585 { 2586 int i; 2587 for (i = 0; i < s->mapping.next; i++) { 2588 mapping_t* mapping = array_get(&(s->mapping), i); 2589 if (mapping->mode & MODE_DELETED) { 2590 fprintf(stderr, "deleted\n"); 2591 continue; 2592 } 2593 assert(mapping->dir_index < s->directory.next); 2594 direntry_t* direntry = array_get(&(s->directory), mapping->dir_index); 2595 assert(mapping->begin == begin_of_direntry(direntry) || mapping->first_mapping_index >= 0); 2596 if (mapping->mode & MODE_DIRECTORY) { 2597 assert(mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster * (mapping->end - mapping->begin) <= s->directory.next); 2598 assert((mapping->info.dir.first_dir_index % (0x10 * s->sectors_per_cluster)) == 0); 2599 } 2600 } 2601 } 2602 2603 /* test, if all direntries have mappings */ 2604 static void check2(BDRVVVFATState* s) 2605 { 2606 int i; 2607 int first_mapping = -1; 2608 2609 for (i = 0; i < s->directory.next; i++) { 2610 direntry_t* direntry = array_get(&(s->directory), i); 2611 2612 if (is_short_name(direntry) && begin_of_direntry(direntry)) { 2613 mapping_t* mapping = find_mapping_for_cluster(s, begin_of_direntry(direntry)); 2614 assert(mapping); 2615 assert(mapping->dir_index == i || is_dot(direntry)); 2616 assert(mapping->begin == begin_of_direntry(direntry) || is_dot(direntry)); 2617 } 2618 2619 if ((i % (0x10 * s->sectors_per_cluster)) == 0) { 2620 /* cluster start */ 2621 int j, count = 0; 2622 2623 for (j = 0; j < s->mapping.next; j++) { 2624 mapping_t* mapping = array_get(&(s->mapping), j); 2625 if (mapping->mode & MODE_DELETED) 2626 continue; 2627 if (mapping->mode & MODE_DIRECTORY) { 2628 if (mapping->info.dir.first_dir_index <= i && mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster > i) { 2629 assert(++count == 1); 2630 if (mapping->first_mapping_index == -1) 2631 first_mapping = array_index(&(s->mapping), mapping); 2632 else 2633 assert(first_mapping == mapping->first_mapping_index); 2634 if (mapping->info.dir.parent_mapping_index < 0) 2635 assert(j == 0); 2636 else { 2637 mapping_t* parent = array_get(&(s->mapping), mapping->info.dir.parent_mapping_index); 2638 assert(parent->mode & MODE_DIRECTORY); 2639 assert(parent->info.dir.first_dir_index < mapping->info.dir.first_dir_index); 2640 } 2641 } 2642 } 2643 } 2644 if (count == 0) 2645 first_mapping = -1; 2646 } 2647 } 2648 } 2649 #endif 2650 2651 static int handle_renames_and_mkdirs(BDRVVVFATState* s) 2652 { 2653 int i; 2654 2655 #ifdef DEBUG 2656 fprintf(stderr, "handle_renames\n"); 2657 for (i = 0; i < s->commits.next; i++) { 2658 commit_t* commit = array_get(&(s->commits), i); 2659 fprintf(stderr, "%d, %s (%d, %d)\n", i, commit->path ? commit->path : "(null)", commit->param.rename.cluster, commit->action); 2660 } 2661 #endif 2662 2663 for (i = 0; i < s->commits.next;) { 2664 commit_t* commit = array_get(&(s->commits), i); 2665 if (commit->action == ACTION_RENAME) { 2666 mapping_t* mapping = find_mapping_for_cluster(s, 2667 commit->param.rename.cluster); 2668 char* old_path = mapping->path; 2669 2670 assert(commit->path); 2671 mapping->path = commit->path; 2672 if (rename(old_path, mapping->path)) 2673 return -2; 2674 2675 if (mapping->mode & MODE_DIRECTORY) { 2676 int l1 = strlen(mapping->path); 2677 int l2 = strlen(old_path); 2678 int diff = l1 - l2; 2679 direntry_t* direntry = array_get(&(s->directory), 2680 mapping->info.dir.first_dir_index); 2681 uint32_t c = mapping->begin; 2682 int i = 0; 2683 2684 /* recurse */ 2685 while (!fat_eof(s, c)) { 2686 do { 2687 direntry_t* d = direntry + i; 2688 2689 if (is_file(d) || (is_directory(d) && !is_dot(d))) { 2690 mapping_t* m = find_mapping_for_cluster(s, 2691 begin_of_direntry(d)); 2692 int l = strlen(m->path); 2693 char* new_path = g_malloc(l + diff + 1); 2694 2695 assert(!strncmp(m->path, mapping->path, l2)); 2696 2697 pstrcpy(new_path, l + diff + 1, mapping->path); 2698 pstrcpy(new_path + l1, l + diff + 1 - l1, 2699 m->path + l2); 2700 2701 schedule_rename(s, m->begin, new_path); 2702 } 2703 i++; 2704 } while((i % (0x10 * s->sectors_per_cluster)) != 0); 2705 c = fat_get(s, c); 2706 } 2707 } 2708 2709 g_free(old_path); 2710 array_remove(&(s->commits), i); 2711 continue; 2712 } else if (commit->action == ACTION_MKDIR) { 2713 mapping_t* mapping; 2714 int j, parent_path_len; 2715 2716 #ifdef __MINGW32__ 2717 if (mkdir(commit->path)) 2718 return -5; 2719 #else 2720 if (mkdir(commit->path, 0755)) 2721 return -5; 2722 #endif 2723 2724 mapping = insert_mapping(s, commit->param.mkdir.cluster, 2725 commit->param.mkdir.cluster + 1); 2726 if (mapping == NULL) 2727 return -6; 2728 2729 mapping->mode = MODE_DIRECTORY; 2730 mapping->read_only = 0; 2731 mapping->path = commit->path; 2732 j = s->directory.next; 2733 assert(j); 2734 insert_direntries(s, s->directory.next, 2735 0x10 * s->sectors_per_cluster); 2736 mapping->info.dir.first_dir_index = j; 2737 2738 parent_path_len = strlen(commit->path) 2739 - strlen(get_basename(commit->path)) - 1; 2740 for (j = 0; j < s->mapping.next; j++) { 2741 mapping_t* m = array_get(&(s->mapping), j); 2742 if (m->first_mapping_index < 0 && m != mapping && 2743 !strncmp(m->path, mapping->path, parent_path_len) && 2744 strlen(m->path) == parent_path_len) 2745 break; 2746 } 2747 assert(j < s->mapping.next); 2748 mapping->info.dir.parent_mapping_index = j; 2749 2750 array_remove(&(s->commits), i); 2751 continue; 2752 } 2753 2754 i++; 2755 } 2756 return 0; 2757 } 2758 2759 /* 2760 * TODO: make sure that the short name is not matching *another* file 2761 */ 2762 static int handle_commits(BDRVVVFATState* s) 2763 { 2764 int i, fail = 0; 2765 2766 vvfat_close_current_file(s); 2767 2768 for (i = 0; !fail && i < s->commits.next; i++) { 2769 commit_t* commit = array_get(&(s->commits), i); 2770 switch(commit->action) { 2771 case ACTION_RENAME: case ACTION_MKDIR: 2772 abort(); 2773 fail = -2; 2774 break; 2775 case ACTION_WRITEOUT: { 2776 #ifndef NDEBUG 2777 /* these variables are only used by assert() below */ 2778 direntry_t* entry = array_get(&(s->directory), 2779 commit->param.writeout.dir_index); 2780 uint32_t begin = begin_of_direntry(entry); 2781 mapping_t* mapping = find_mapping_for_cluster(s, begin); 2782 #endif 2783 2784 assert(mapping); 2785 assert(mapping->begin == begin); 2786 assert(commit->path == NULL); 2787 2788 if (commit_one_file(s, commit->param.writeout.dir_index, 2789 commit->param.writeout.modified_offset)) 2790 fail = -3; 2791 2792 break; 2793 } 2794 case ACTION_NEW_FILE: { 2795 int begin = commit->param.new_file.first_cluster; 2796 mapping_t* mapping = find_mapping_for_cluster(s, begin); 2797 direntry_t* entry; 2798 int i; 2799 2800 /* find direntry */ 2801 for (i = 0; i < s->directory.next; i++) { 2802 entry = array_get(&(s->directory), i); 2803 if (is_file(entry) && begin_of_direntry(entry) == begin) 2804 break; 2805 } 2806 2807 if (i >= s->directory.next) { 2808 fail = -6; 2809 continue; 2810 } 2811 2812 /* make sure there exists an initial mapping */ 2813 if (mapping && mapping->begin != begin) { 2814 mapping->end = begin; 2815 mapping = NULL; 2816 } 2817 if (mapping == NULL) { 2818 mapping = insert_mapping(s, begin, begin+1); 2819 } 2820 /* most members will be fixed in commit_mappings() */ 2821 assert(commit->path); 2822 mapping->path = commit->path; 2823 mapping->read_only = 0; 2824 mapping->mode = MODE_NORMAL; 2825 mapping->info.file.offset = 0; 2826 2827 if (commit_one_file(s, i, 0)) 2828 fail = -7; 2829 2830 break; 2831 } 2832 default: 2833 abort(); 2834 } 2835 } 2836 if (i > 0 && array_remove_slice(&(s->commits), 0, i)) 2837 return -1; 2838 return fail; 2839 } 2840 2841 static int handle_deletes(BDRVVVFATState* s) 2842 { 2843 int i, deferred = 1, deleted = 1; 2844 2845 /* delete files corresponding to mappings marked as deleted */ 2846 /* handle DELETEs and unused mappings (modified_fat_get(s, mapping->begin) == 0) */ 2847 while (deferred && deleted) { 2848 deferred = 0; 2849 deleted = 0; 2850 2851 for (i = 1; i < s->mapping.next; i++) { 2852 mapping_t* mapping = array_get(&(s->mapping), i); 2853 if (mapping->mode & MODE_DELETED) { 2854 direntry_t* entry = array_get(&(s->directory), 2855 mapping->dir_index); 2856 2857 if (is_free(entry)) { 2858 /* remove file/directory */ 2859 if (mapping->mode & MODE_DIRECTORY) { 2860 int j, next_dir_index = s->directory.next, 2861 first_dir_index = mapping->info.dir.first_dir_index; 2862 2863 if (rmdir(mapping->path) < 0) { 2864 if (errno == ENOTEMPTY) { 2865 deferred++; 2866 continue; 2867 } else 2868 return -5; 2869 } 2870 2871 for (j = 1; j < s->mapping.next; j++) { 2872 mapping_t* m = array_get(&(s->mapping), j); 2873 if (m->mode & MODE_DIRECTORY && 2874 m->info.dir.first_dir_index > 2875 first_dir_index && 2876 m->info.dir.first_dir_index < 2877 next_dir_index) 2878 next_dir_index = 2879 m->info.dir.first_dir_index; 2880 } 2881 remove_direntries(s, first_dir_index, 2882 next_dir_index - first_dir_index); 2883 2884 deleted++; 2885 } 2886 } else { 2887 if (unlink(mapping->path)) 2888 return -4; 2889 deleted++; 2890 } 2891 DLOG(fprintf(stderr, "DELETE (%d)\n", i); print_mapping(mapping); print_direntry(entry)); 2892 remove_mapping(s, i); 2893 } 2894 } 2895 } 2896 2897 return 0; 2898 } 2899 2900 /* 2901 * synchronize mapping with new state: 2902 * 2903 * - copy FAT (with bdrv_read) 2904 * - mark all filenames corresponding to mappings as deleted 2905 * - recurse direntries from root (using bs->bdrv_read) 2906 * - delete files corresponding to mappings marked as deleted 2907 */ 2908 static int do_commit(BDRVVVFATState* s) 2909 { 2910 int ret = 0; 2911 2912 /* the real meat are the commits. Nothing to do? Move along! */ 2913 if (s->commits.next == 0) 2914 return 0; 2915 2916 vvfat_close_current_file(s); 2917 2918 ret = handle_renames_and_mkdirs(s); 2919 if (ret) { 2920 fprintf(stderr, "Error handling renames (%d)\n", ret); 2921 abort(); 2922 return ret; 2923 } 2924 2925 /* copy FAT (with bdrv_read) */ 2926 memcpy(s->fat.pointer, s->fat2, 0x200 * s->sectors_per_fat); 2927 2928 /* recurse direntries from root (using bs->bdrv_read) */ 2929 ret = commit_direntries(s, 0, -1); 2930 if (ret) { 2931 fprintf(stderr, "Fatal: error while committing (%d)\n", ret); 2932 abort(); 2933 return ret; 2934 } 2935 2936 ret = handle_commits(s); 2937 if (ret) { 2938 fprintf(stderr, "Error handling commits (%d)\n", ret); 2939 abort(); 2940 return ret; 2941 } 2942 2943 ret = handle_deletes(s); 2944 if (ret) { 2945 fprintf(stderr, "Error deleting\n"); 2946 abort(); 2947 return ret; 2948 } 2949 2950 if (s->qcow->bs->drv && s->qcow->bs->drv->bdrv_make_empty) { 2951 s->qcow->bs->drv->bdrv_make_empty(s->qcow->bs); 2952 } 2953 2954 memset(s->used_clusters, 0, sector2cluster(s, s->sector_count)); 2955 2956 DLOG(checkpoint()); 2957 return 0; 2958 } 2959 2960 static int try_commit(BDRVVVFATState* s) 2961 { 2962 vvfat_close_current_file(s); 2963 DLOG(checkpoint()); 2964 if(!is_consistent(s)) 2965 return -1; 2966 return do_commit(s); 2967 } 2968 2969 static int vvfat_write(BlockDriverState *bs, int64_t sector_num, 2970 const uint8_t *buf, int nb_sectors) 2971 { 2972 BDRVVVFATState *s = bs->opaque; 2973 int i, ret; 2974 2975 DLOG(checkpoint()); 2976 2977 /* Check if we're operating in read-only mode */ 2978 if (s->qcow == NULL) { 2979 return -EACCES; 2980 } 2981 2982 vvfat_close_current_file(s); 2983 2984 /* 2985 * Some sanity checks: 2986 * - do not allow writing to the boot sector 2987 */ 2988 2989 if (sector_num < s->offset_to_fat) 2990 return -1; 2991 2992 for (i = sector2cluster(s, sector_num); 2993 i <= sector2cluster(s, sector_num + nb_sectors - 1);) { 2994 mapping_t* mapping = find_mapping_for_cluster(s, i); 2995 if (mapping) { 2996 if (mapping->read_only) { 2997 fprintf(stderr, "Tried to write to write-protected file %s\n", 2998 mapping->path); 2999 return -1; 3000 } 3001 3002 if (mapping->mode & MODE_DIRECTORY) { 3003 int begin = cluster2sector(s, i); 3004 int end = begin + s->sectors_per_cluster, k; 3005 int dir_index; 3006 const direntry_t* direntries; 3007 long_file_name lfn; 3008 3009 lfn_init(&lfn); 3010 3011 if (begin < sector_num) 3012 begin = sector_num; 3013 if (end > sector_num + nb_sectors) 3014 end = sector_num + nb_sectors; 3015 dir_index = mapping->dir_index + 3016 0x10 * (begin - mapping->begin * s->sectors_per_cluster); 3017 direntries = (direntry_t*)(buf + 0x200 * (begin - sector_num)); 3018 3019 for (k = 0; k < (end - begin) * 0x10; k++) { 3020 /* no access to the direntry of a read-only file */ 3021 if (is_short_name(direntries + k) && 3022 (direntries[k].attributes & 1)) { 3023 if (memcmp(direntries + k, 3024 array_get(&(s->directory), dir_index + k), 3025 sizeof(direntry_t))) { 3026 warn_report("tried to write to write-protected " 3027 "file"); 3028 return -1; 3029 } 3030 } 3031 } 3032 } 3033 i = mapping->end; 3034 } else 3035 i++; 3036 } 3037 3038 /* 3039 * Use qcow backend. Commit later. 3040 */ 3041 DLOG(fprintf(stderr, "Write to qcow backend: %d + %d\n", (int)sector_num, nb_sectors)); 3042 ret = bdrv_write(s->qcow, sector_num, buf, nb_sectors); 3043 if (ret < 0) { 3044 fprintf(stderr, "Error writing to qcow backend\n"); 3045 return ret; 3046 } 3047 3048 for (i = sector2cluster(s, sector_num); 3049 i <= sector2cluster(s, sector_num + nb_sectors - 1); i++) 3050 if (i >= 0) 3051 s->used_clusters[i] |= USED_ALLOCATED; 3052 3053 DLOG(checkpoint()); 3054 /* TODO: add timeout */ 3055 try_commit(s); 3056 3057 DLOG(checkpoint()); 3058 return 0; 3059 } 3060 3061 static int coroutine_fn 3062 vvfat_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes, 3063 QEMUIOVector *qiov, int flags) 3064 { 3065 int ret; 3066 BDRVVVFATState *s = bs->opaque; 3067 uint64_t sector_num = offset >> BDRV_SECTOR_BITS; 3068 int nb_sectors = bytes >> BDRV_SECTOR_BITS; 3069 void *buf; 3070 3071 assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0); 3072 assert((bytes & (BDRV_SECTOR_SIZE - 1)) == 0); 3073 3074 buf = g_try_malloc(bytes); 3075 if (bytes && buf == NULL) { 3076 return -ENOMEM; 3077 } 3078 qemu_iovec_to_buf(qiov, 0, buf, bytes); 3079 3080 qemu_co_mutex_lock(&s->lock); 3081 ret = vvfat_write(bs, sector_num, buf, nb_sectors); 3082 qemu_co_mutex_unlock(&s->lock); 3083 3084 g_free(buf); 3085 3086 return ret; 3087 } 3088 3089 static int64_t coroutine_fn vvfat_co_get_block_status(BlockDriverState *bs, 3090 int64_t sector_num, int nb_sectors, int *n, BlockDriverState **file) 3091 { 3092 *n = bs->total_sectors - sector_num; 3093 if (*n > nb_sectors) { 3094 *n = nb_sectors; 3095 } else if (*n < 0) { 3096 return 0; 3097 } 3098 return BDRV_BLOCK_DATA; 3099 } 3100 3101 static int coroutine_fn 3102 write_target_commit(BlockDriverState *bs, uint64_t offset, uint64_t bytes, 3103 QEMUIOVector *qiov, int flags) 3104 { 3105 int ret; 3106 3107 BDRVVVFATState* s = *((BDRVVVFATState**) bs->opaque); 3108 qemu_co_mutex_lock(&s->lock); 3109 ret = try_commit(s); 3110 qemu_co_mutex_unlock(&s->lock); 3111 3112 return ret; 3113 } 3114 3115 static void write_target_close(BlockDriverState *bs) { 3116 BDRVVVFATState* s = *((BDRVVVFATState**) bs->opaque); 3117 bdrv_unref_child(s->bs, s->qcow); 3118 g_free(s->qcow_filename); 3119 } 3120 3121 static BlockDriver vvfat_write_target = { 3122 .format_name = "vvfat_write_target", 3123 .instance_size = sizeof(void*), 3124 .bdrv_co_pwritev = write_target_commit, 3125 .bdrv_close = write_target_close, 3126 }; 3127 3128 static void vvfat_qcow_options(int *child_flags, QDict *child_options, 3129 int parent_flags, QDict *parent_options) 3130 { 3131 qdict_set_default_str(child_options, BDRV_OPT_READ_ONLY, "off"); 3132 *child_flags = BDRV_O_NO_FLUSH; 3133 } 3134 3135 static const BdrvChildRole child_vvfat_qcow = { 3136 .inherit_options = vvfat_qcow_options, 3137 }; 3138 3139 static int enable_write_target(BlockDriverState *bs, Error **errp) 3140 { 3141 BDRVVVFATState *s = bs->opaque; 3142 BlockDriver *bdrv_qcow = NULL; 3143 BlockDriverState *backing; 3144 QemuOpts *opts = NULL; 3145 int ret; 3146 int size = sector2cluster(s, s->sector_count); 3147 QDict *options; 3148 3149 s->used_clusters = calloc(size, 1); 3150 3151 array_init(&(s->commits), sizeof(commit_t)); 3152 3153 s->qcow_filename = g_malloc(PATH_MAX); 3154 ret = get_tmp_filename(s->qcow_filename, PATH_MAX); 3155 if (ret < 0) { 3156 error_setg_errno(errp, -ret, "can't create temporary file"); 3157 goto err; 3158 } 3159 3160 bdrv_qcow = bdrv_find_format("qcow"); 3161 if (!bdrv_qcow) { 3162 error_setg(errp, "Failed to locate qcow driver"); 3163 ret = -ENOENT; 3164 goto err; 3165 } 3166 3167 opts = qemu_opts_create(bdrv_qcow->create_opts, NULL, 0, &error_abort); 3168 qemu_opt_set_number(opts, BLOCK_OPT_SIZE, s->sector_count * 512, 3169 &error_abort); 3170 qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, "fat:", &error_abort); 3171 3172 ret = bdrv_create(bdrv_qcow, s->qcow_filename, opts, errp); 3173 qemu_opts_del(opts); 3174 if (ret < 0) { 3175 goto err; 3176 } 3177 3178 options = qdict_new(); 3179 qdict_put_str(options, "write-target.driver", "qcow"); 3180 s->qcow = bdrv_open_child(s->qcow_filename, options, "write-target", bs, 3181 &child_vvfat_qcow, false, errp); 3182 QDECREF(options); 3183 if (!s->qcow) { 3184 ret = -EINVAL; 3185 goto err; 3186 } 3187 3188 #ifndef _WIN32 3189 unlink(s->qcow_filename); 3190 #endif 3191 3192 backing = bdrv_new_open_driver(&vvfat_write_target, NULL, BDRV_O_ALLOW_RDWR, 3193 &error_abort); 3194 *(void**) backing->opaque = s; 3195 3196 bdrv_set_backing_hd(s->bs, backing, &error_abort); 3197 bdrv_unref(backing); 3198 3199 return 0; 3200 3201 err: 3202 g_free(s->qcow_filename); 3203 s->qcow_filename = NULL; 3204 return ret; 3205 } 3206 3207 static void vvfat_child_perm(BlockDriverState *bs, BdrvChild *c, 3208 const BdrvChildRole *role, 3209 BlockReopenQueue *reopen_queue, 3210 uint64_t perm, uint64_t shared, 3211 uint64_t *nperm, uint64_t *nshared) 3212 { 3213 BDRVVVFATState *s = bs->opaque; 3214 3215 assert(c == s->qcow || role == &child_backing); 3216 3217 if (c == s->qcow) { 3218 /* This is a private node, nobody should try to attach to it */ 3219 *nperm = BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE; 3220 *nshared = BLK_PERM_WRITE_UNCHANGED; 3221 } else { 3222 /* The backing file is there so 'commit' can use it. vvfat doesn't 3223 * access it in any way. */ 3224 *nperm = 0; 3225 *nshared = BLK_PERM_ALL; 3226 } 3227 } 3228 3229 static void vvfat_close(BlockDriverState *bs) 3230 { 3231 BDRVVVFATState *s = bs->opaque; 3232 3233 vvfat_close_current_file(s); 3234 array_free(&(s->fat)); 3235 array_free(&(s->directory)); 3236 array_free(&(s->mapping)); 3237 g_free(s->cluster_buffer); 3238 3239 if (s->qcow) { 3240 migrate_del_blocker(s->migration_blocker); 3241 error_free(s->migration_blocker); 3242 } 3243 } 3244 3245 static BlockDriver bdrv_vvfat = { 3246 .format_name = "vvfat", 3247 .protocol_name = "fat", 3248 .instance_size = sizeof(BDRVVVFATState), 3249 3250 .bdrv_parse_filename = vvfat_parse_filename, 3251 .bdrv_file_open = vvfat_open, 3252 .bdrv_refresh_limits = vvfat_refresh_limits, 3253 .bdrv_close = vvfat_close, 3254 .bdrv_child_perm = vvfat_child_perm, 3255 3256 .bdrv_co_preadv = vvfat_co_preadv, 3257 .bdrv_co_pwritev = vvfat_co_pwritev, 3258 .bdrv_co_get_block_status = vvfat_co_get_block_status, 3259 }; 3260 3261 static void bdrv_vvfat_init(void) 3262 { 3263 bdrv_register(&bdrv_vvfat); 3264 } 3265 3266 block_init(bdrv_vvfat_init); 3267 3268 #ifdef DEBUG 3269 static void checkpoint(void) 3270 { 3271 assert(((mapping_t*)array_get(&(vvv->mapping), 0))->end == 2); 3272 check1(vvv); 3273 check2(vvv); 3274 assert(!vvv->current_mapping || vvv->current_fd || (vvv->current_mapping->mode & MODE_DIRECTORY)); 3275 } 3276 #endif 3277