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