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