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