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