Merge remote-tracking branch 'remotes/kraxel/tags/pull-vga-20170103-1' into staging
[qemu.git] / block / vvfat.c
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