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