xref: /openbmc/qemu/block/vvfat.c (revision cffaca0fab7ccb955c0e498c5132b801844d2c41)
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          direntry_t* direntry;
781          struct stat st;
782          int is_dot=!strcmp(entry->d_name,".");
783          int is_dotdot=!strcmp(entry->d_name,"..");
784  
785          if (first_cluster == 0 && s->directory.next >= s->root_entries - 1) {
786              fprintf(stderr, "Too many entries in root directory\n");
787              closedir(dir);
788              return -2;
789          }
790  
791          if(first_cluster == 0 && (is_dotdot || is_dot))
792              continue;
793  
794          buffer = g_malloc(length);
795          snprintf(buffer,length,"%s/%s",dirname,entry->d_name);
796  
797          if(stat(buffer,&st)<0) {
798              g_free(buffer);
799              continue;
800          }
801  
802          /* create directory entry for this file */
803          if (!is_dot && !is_dotdot) {
804              direntry = create_short_and_long_name(s, i, entry->d_name, 0);
805          } else {
806              direntry = array_get(&(s->directory), is_dot ? i : i + 1);
807          }
808          direntry->attributes=(S_ISDIR(st.st_mode)?0x10:0x20);
809          direntry->reserved[0]=direntry->reserved[1]=0;
810          direntry->ctime=fat_datetime(st.st_ctime,1);
811          direntry->cdate=fat_datetime(st.st_ctime,0);
812          direntry->adate=fat_datetime(st.st_atime,0);
813          direntry->begin_hi=0;
814          direntry->mtime=fat_datetime(st.st_mtime,1);
815          direntry->mdate=fat_datetime(st.st_mtime,0);
816          if(is_dotdot)
817              set_begin_of_direntry(direntry, first_cluster_of_parent);
818          else if(is_dot)
819              set_begin_of_direntry(direntry, first_cluster);
820          else
821              direntry->begin=0; /* do that later */
822          if (st.st_size > 0x7fffffff) {
823              fprintf(stderr, "File %s is larger than 2GB\n", buffer);
824              g_free(buffer);
825              closedir(dir);
826              return -2;
827          }
828          direntry->size=cpu_to_le32(S_ISDIR(st.st_mode)?0:st.st_size);
829  
830          /* create mapping for this file */
831          if(!is_dot && !is_dotdot && (S_ISDIR(st.st_mode) || st.st_size)) {
832              s->current_mapping = array_get_next(&(s->mapping));
833              s->current_mapping->begin=0;
834              s->current_mapping->end=st.st_size;
835              /*
836               * we get the direntry of the most recent direntry, which
837               * contains the short name and all the relevant information.
838               */
839              s->current_mapping->dir_index=s->directory.next-1;
840              s->current_mapping->first_mapping_index = -1;
841              if (S_ISDIR(st.st_mode)) {
842                  s->current_mapping->mode = MODE_DIRECTORY;
843                  s->current_mapping->info.dir.parent_mapping_index =
844                      mapping_index;
845              } else {
846                  s->current_mapping->mode = MODE_UNDEFINED;
847                  s->current_mapping->info.file.offset = 0;
848              }
849              s->current_mapping->path=buffer;
850              s->current_mapping->read_only =
851                  (st.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)) == 0;
852          } else {
853              g_free(buffer);
854          }
855      }
856      closedir(dir);
857  
858      /* fill with zeroes up to the end of the cluster */
859      while(s->directory.next%(0x10*s->sectors_per_cluster)) {
860          direntry_t* direntry=array_get_next(&(s->directory));
861          memset(direntry,0,sizeof(direntry_t));
862      }
863  
864      if (s->fat_type != 32 &&
865          mapping_index == 0 &&
866          s->directory.next < s->root_entries) {
867          /* root directory */
868          int cur = s->directory.next;
869          array_ensure_allocated(&(s->directory), s->root_entries - 1);
870          s->directory.next = s->root_entries;
871          memset(array_get(&(s->directory), cur), 0,
872                  (s->root_entries - cur) * sizeof(direntry_t));
873      }
874  
875      /* re-get the mapping, since s->mapping was possibly realloc()ed */
876      mapping = array_get(&(s->mapping), mapping_index);
877      first_cluster += (s->directory.next - mapping->info.dir.first_dir_index)
878          * 0x20 / s->cluster_size;
879      mapping->end = first_cluster;
880  
881      direntry = array_get(&(s->directory), mapping->dir_index);
882      set_begin_of_direntry(direntry, mapping->begin);
883  
884      return 0;
885  }
886  
887  static inline int32_t sector2cluster(BDRVVVFATState* s,off_t sector_num)
888  {
889      return (sector_num - s->offset_to_root_dir) / s->sectors_per_cluster;
890  }
891  
892  static inline off_t cluster2sector(BDRVVVFATState* s, uint32_t cluster_num)
893  {
894      return s->offset_to_root_dir + s->sectors_per_cluster * cluster_num;
895  }
896  
897  static int init_directories(BDRVVVFATState* s,
898                              const char *dirname, int heads, int secs,
899                              Error **errp)
900  {
901      bootsector_t* bootsector;
902      mapping_t* mapping;
903      unsigned int i;
904      unsigned int cluster;
905  
906      memset(&(s->first_sectors[0]),0,0x40*0x200);
907  
908      s->cluster_size=s->sectors_per_cluster*0x200;
909      s->cluster_buffer=g_malloc(s->cluster_size);
910  
911      /*
912       * The formula: sc = spf+1+spf*spc*(512*8/fat_type),
913       * where sc is sector_count,
914       * spf is sectors_per_fat,
915       * spc is sectors_per_clusters, and
916       * fat_type = 12, 16 or 32.
917       */
918      i = 1+s->sectors_per_cluster*0x200*8/s->fat_type;
919      s->sectors_per_fat=(s->sector_count+i)/i; /* round up */
920  
921      s->offset_to_fat = s->offset_to_bootsector + 1;
922      s->offset_to_root_dir = s->offset_to_fat + s->sectors_per_fat * 2;
923  
924      array_init(&(s->mapping),sizeof(mapping_t));
925      array_init(&(s->directory),sizeof(direntry_t));
926  
927      /* add volume label */
928      {
929          direntry_t* entry=array_get_next(&(s->directory));
930          entry->attributes=0x28; /* archive | volume label */
931          memcpy(entry->name, s->volume_label, sizeof(entry->name));
932      }
933  
934      /* Now build FAT, and write back information into directory */
935      init_fat(s);
936  
937      /* TODO: if there are more entries, bootsector has to be adjusted! */
938      s->root_entries = 0x02 * 0x10 * s->sectors_per_cluster;
939      s->cluster_count=sector2cluster(s, s->sector_count);
940  
941      mapping = array_get_next(&(s->mapping));
942      mapping->begin = 0;
943      mapping->dir_index = 0;
944      mapping->info.dir.parent_mapping_index = -1;
945      mapping->first_mapping_index = -1;
946      mapping->path = g_strdup(dirname);
947      i = strlen(mapping->path);
948      if (i > 0 && mapping->path[i - 1] == '/')
949          mapping->path[i - 1] = '\0';
950      mapping->mode = MODE_DIRECTORY;
951      mapping->read_only = 0;
952      s->path = mapping->path;
953  
954      for (i = 0, cluster = 0; i < s->mapping.next; i++) {
955          /* MS-DOS expects the FAT to be 0 for the root directory
956           * (except for the media byte). */
957          /* LATER TODO: still true for FAT32? */
958          int fix_fat = (i != 0);
959          mapping = array_get(&(s->mapping), i);
960  
961          if (mapping->mode & MODE_DIRECTORY) {
962              char *path = mapping->path;
963              mapping->begin = cluster;
964              if(read_directory(s, i)) {
965                  error_setg(errp, "Could not read directory %s", path);
966                  return -1;
967              }
968              mapping = array_get(&(s->mapping), i);
969          } else {
970              assert(mapping->mode == MODE_UNDEFINED);
971              mapping->mode=MODE_NORMAL;
972              mapping->begin = cluster;
973              if (mapping->end > 0) {
974                  direntry_t* direntry = array_get(&(s->directory),
975                          mapping->dir_index);
976  
977                  mapping->end = cluster + 1 + (mapping->end-1)/s->cluster_size;
978                  set_begin_of_direntry(direntry, mapping->begin);
979              } else {
980                  mapping->end = cluster + 1;
981                  fix_fat = 0;
982              }
983          }
984  
985          assert(mapping->begin < mapping->end);
986  
987          /* next free cluster */
988          cluster = mapping->end;
989  
990          if(cluster > s->cluster_count) {
991              error_setg(errp,
992                         "Directory does not fit in FAT%d (capacity %.2f MB)",
993                         s->fat_type, s->sector_count / 2000.0);
994              return -1;
995          }
996  
997          /* fix fat for entry */
998          if (fix_fat) {
999              int j;
1000              for(j = mapping->begin; j < mapping->end - 1; j++)
1001                  fat_set(s, j, j+1);
1002              fat_set(s, mapping->end - 1, s->max_fat_value);
1003          }
1004      }
1005  
1006      mapping = array_get(&(s->mapping), 0);
1007      s->last_cluster_of_root_directory = mapping->end;
1008  
1009      /* the FAT signature */
1010      fat_set(s,0,s->max_fat_value);
1011      fat_set(s,1,s->max_fat_value);
1012  
1013      s->current_mapping = NULL;
1014  
1015      bootsector = (bootsector_t *)(s->first_sectors
1016                                    + s->offset_to_bootsector * 0x200);
1017      bootsector->jump[0]=0xeb;
1018      bootsector->jump[1]=0x3e;
1019      bootsector->jump[2]=0x90;
1020      memcpy(bootsector->name, BOOTSECTOR_OEM_NAME, 8);
1021      bootsector->sector_size=cpu_to_le16(0x200);
1022      bootsector->sectors_per_cluster=s->sectors_per_cluster;
1023      bootsector->reserved_sectors=cpu_to_le16(1);
1024      bootsector->number_of_fats=0x2; /* number of FATs */
1025      bootsector->root_entries = cpu_to_le16(s->root_entries);
1026      bootsector->total_sectors16=s->sector_count>0xffff?0:cpu_to_le16(s->sector_count);
1027      /* media descriptor: hard disk=0xf8, floppy=0xf0 */
1028      bootsector->media_type = (s->offset_to_bootsector > 0 ? 0xf8 : 0xf0);
1029      s->fat.pointer[0] = bootsector->media_type;
1030      bootsector->sectors_per_fat=cpu_to_le16(s->sectors_per_fat);
1031      bootsector->sectors_per_track = cpu_to_le16(secs);
1032      bootsector->number_of_heads = cpu_to_le16(heads);
1033      bootsector->hidden_sectors = cpu_to_le32(s->offset_to_bootsector);
1034      bootsector->total_sectors=cpu_to_le32(s->sector_count>0xffff?s->sector_count:0);
1035  
1036      /* LATER TODO: if FAT32, this is wrong */
1037      /* drive_number: fda=0, hda=0x80 */
1038      bootsector->u.fat16.drive_number = s->offset_to_bootsector == 0 ? 0 : 0x80;
1039      bootsector->u.fat16.signature=0x29;
1040      bootsector->u.fat16.id=cpu_to_le32(0xfabe1afd);
1041  
1042      memcpy(bootsector->u.fat16.volume_label, s->volume_label,
1043             sizeof(bootsector->u.fat16.volume_label));
1044      memcpy(bootsector->u.fat16.fat_type,
1045             s->fat_type == 12 ? "FAT12   " : "FAT16   ", 8);
1046      bootsector->magic[0]=0x55; bootsector->magic[1]=0xaa;
1047  
1048      return 0;
1049  }
1050  
1051  #ifdef DEBUG
1052  static BDRVVVFATState *vvv = NULL;
1053  #endif
1054  
1055  static int enable_write_target(BlockDriverState *bs, Error **errp);
1056  static int is_consistent(BDRVVVFATState *s);
1057  
1058  static QemuOptsList runtime_opts = {
1059      .name = "vvfat",
1060      .head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
1061      .desc = {
1062          {
1063              .name = "dir",
1064              .type = QEMU_OPT_STRING,
1065              .help = "Host directory to map to the vvfat device",
1066          },
1067          {
1068              .name = "fat-type",
1069              .type = QEMU_OPT_NUMBER,
1070              .help = "FAT type (12, 16 or 32)",
1071          },
1072          {
1073              .name = "floppy",
1074              .type = QEMU_OPT_BOOL,
1075              .help = "Create a floppy rather than a hard disk image",
1076          },
1077          {
1078              .name = "label",
1079              .type = QEMU_OPT_STRING,
1080              .help = "Use a volume label other than QEMU VVFAT",
1081          },
1082          {
1083              .name = "rw",
1084              .type = QEMU_OPT_BOOL,
1085              .help = "Make the image writable",
1086          },
1087          { /* end of list */ }
1088      },
1089  };
1090  
1091  static void vvfat_parse_filename(const char *filename, QDict *options,
1092                                   Error **errp)
1093  {
1094      int fat_type = 0;
1095      bool floppy = false;
1096      bool rw = false;
1097      int i;
1098  
1099      if (!strstart(filename, "fat:", NULL)) {
1100          error_setg(errp, "File name string must start with 'fat:'");
1101          return;
1102      }
1103  
1104      /* Parse options */
1105      if (strstr(filename, ":32:")) {
1106          fat_type = 32;
1107      } else if (strstr(filename, ":16:")) {
1108          fat_type = 16;
1109      } else if (strstr(filename, ":12:")) {
1110          fat_type = 12;
1111      }
1112  
1113      if (strstr(filename, ":floppy:")) {
1114          floppy = true;
1115      }
1116  
1117      if (strstr(filename, ":rw:")) {
1118          rw = true;
1119      }
1120  
1121      /* Get the directory name without options */
1122      i = strrchr(filename, ':') - filename;
1123      assert(i >= 3);
1124      if (filename[i - 2] == ':' && qemu_isalpha(filename[i - 1])) {
1125          /* workaround for DOS drive names */
1126          filename += i - 1;
1127      } else {
1128          filename += i + 1;
1129      }
1130  
1131      /* Fill in the options QDict */
1132      qdict_put_str(options, "dir", filename);
1133      qdict_put_int(options, "fat-type", fat_type);
1134      qdict_put_bool(options, "floppy", floppy);
1135      qdict_put_bool(options, "rw", rw);
1136  }
1137  
1138  static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
1139                        Error **errp)
1140  {
1141      BDRVVVFATState *s = bs->opaque;
1142      int cyls, heads, secs;
1143      bool floppy;
1144      const char *dirname, *label;
1145      QemuOpts *opts;
1146      int ret;
1147  
1148  #ifdef DEBUG
1149      vvv = s;
1150  #endif
1151  
1152      opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
1153      if (!qemu_opts_absorb_qdict(opts, options, errp)) {
1154          ret = -EINVAL;
1155          goto fail;
1156      }
1157  
1158      dirname = qemu_opt_get(opts, "dir");
1159      if (!dirname) {
1160          error_setg(errp, "vvfat block driver requires a 'dir' option");
1161          ret = -EINVAL;
1162          goto fail;
1163      }
1164  
1165      s->fat_type = qemu_opt_get_number(opts, "fat-type", 0);
1166      floppy = qemu_opt_get_bool(opts, "floppy", false);
1167  
1168      memset(s->volume_label, ' ', sizeof(s->volume_label));
1169      label = qemu_opt_get(opts, "label");
1170      if (label) {
1171          size_t label_length = strlen(label);
1172          if (label_length > 11) {
1173              error_setg(errp, "vvfat label cannot be longer than 11 bytes");
1174              ret = -EINVAL;
1175              goto fail;
1176          }
1177          memcpy(s->volume_label, label, label_length);
1178      } else {
1179          memcpy(s->volume_label, "QEMU VVFAT", 10);
1180      }
1181  
1182      if (floppy) {
1183          /* 1.44MB or 2.88MB floppy.  2.88MB can be FAT12 (default) or FAT16. */
1184          if (!s->fat_type) {
1185              s->fat_type = 12;
1186              secs = 36;
1187              s->sectors_per_cluster = 2;
1188          } else {
1189              secs = s->fat_type == 12 ? 18 : 36;
1190              s->sectors_per_cluster = 1;
1191          }
1192          cyls = 80;
1193          heads = 2;
1194      } else {
1195          /* 32MB or 504MB disk*/
1196          if (!s->fat_type) {
1197              s->fat_type = 16;
1198          }
1199          s->offset_to_bootsector = 0x3f;
1200          cyls = s->fat_type == 12 ? 64 : 1024;
1201          heads = 16;
1202          secs = 63;
1203      }
1204  
1205      switch (s->fat_type) {
1206      case 32:
1207          warn_report("FAT32 has not been tested. You are welcome to do so!");
1208          break;
1209      case 16:
1210      case 12:
1211          break;
1212      default:
1213          error_setg(errp, "Valid FAT types are only 12, 16 and 32");
1214          ret = -EINVAL;
1215          goto fail;
1216      }
1217  
1218  
1219      s->bs = bs;
1220  
1221      /* LATER TODO: if FAT32, adjust */
1222      s->sectors_per_cluster=0x10;
1223  
1224      s->current_cluster=0xffffffff;
1225  
1226      s->qcow = NULL;
1227      s->qcow_filename = NULL;
1228      s->fat2 = NULL;
1229      s->downcase_short_names = 1;
1230  
1231      DLOG(fprintf(stderr, "vvfat %s chs %d,%d,%d\n",
1232                   dirname, cyls, heads, secs));
1233  
1234      s->sector_count = cyls * heads * secs - s->offset_to_bootsector;
1235      bs->total_sectors = cyls * heads * secs;
1236  
1237      if (qemu_opt_get_bool(opts, "rw", false)) {
1238          if (!bdrv_is_read_only(bs)) {
1239              ret = enable_write_target(bs, errp);
1240              if (ret < 0) {
1241                  goto fail;
1242              }
1243          } else {
1244              ret = -EPERM;
1245              error_setg(errp,
1246                         "Unable to set VVFAT to 'rw' when drive is read-only");
1247              goto fail;
1248          }
1249      } else {
1250          ret = bdrv_apply_auto_read_only(bs, NULL, errp);
1251          if (ret < 0) {
1252              goto fail;
1253          }
1254      }
1255  
1256      if (init_directories(s, dirname, heads, secs, errp)) {
1257          ret = -EIO;
1258          goto fail;
1259      }
1260  
1261      s->sector_count = s->offset_to_root_dir
1262                      + s->sectors_per_cluster * s->cluster_count;
1263  
1264      /* Disable migration when vvfat is used rw */
1265      if (s->qcow) {
1266          error_setg(&s->migration_blocker,
1267                     "The vvfat (rw) format used by node '%s' "
1268                     "does not support live migration",
1269                     bdrv_get_device_or_node_name(bs));
1270          ret = migrate_add_blocker(s->migration_blocker, errp);
1271          if (ret < 0) {
1272              error_free(s->migration_blocker);
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          s->current_mapping = mapping;
1373      }
1374      return 0;
1375  }
1376  
1377  static inline int read_cluster(BDRVVVFATState *s,int cluster_num)
1378  {
1379      if(s->current_cluster != cluster_num) {
1380          int result=0;
1381          off_t offset;
1382          assert(!s->current_mapping || s->current_fd || (s->current_mapping->mode & MODE_DIRECTORY));
1383          if(!s->current_mapping
1384                  || s->current_mapping->begin>cluster_num
1385                  || s->current_mapping->end<=cluster_num) {
1386              /* binary search of mappings for file */
1387              mapping_t* mapping=find_mapping_for_cluster(s,cluster_num);
1388  
1389              assert(!mapping || (cluster_num>=mapping->begin && cluster_num<mapping->end));
1390  
1391              if (mapping && mapping->mode & MODE_DIRECTORY) {
1392                  vvfat_close_current_file(s);
1393                  s->current_mapping = mapping;
1394  read_cluster_directory:
1395                  offset = s->cluster_size*(cluster_num-s->current_mapping->begin);
1396                  s->cluster = (unsigned char*)s->directory.pointer+offset
1397                          + 0x20*s->current_mapping->info.dir.first_dir_index;
1398                  assert(((s->cluster-(unsigned char*)s->directory.pointer)%s->cluster_size)==0);
1399                  assert((char*)s->cluster+s->cluster_size <= s->directory.pointer+s->directory.next*s->directory.item_size);
1400                  s->current_cluster = cluster_num;
1401                  return 0;
1402              }
1403  
1404              if(open_file(s,mapping))
1405                  return -2;
1406          } else if (s->current_mapping->mode & MODE_DIRECTORY)
1407              goto read_cluster_directory;
1408  
1409          assert(s->current_fd);
1410  
1411          offset=s->cluster_size*(cluster_num-s->current_mapping->begin)+s->current_mapping->info.file.offset;
1412          if(lseek(s->current_fd, offset, SEEK_SET)!=offset)
1413              return -3;
1414          s->cluster=s->cluster_buffer;
1415          result=read(s->current_fd,s->cluster,s->cluster_size);
1416          if(result<0) {
1417              s->current_cluster = -1;
1418              return -1;
1419          }
1420          s->current_cluster = cluster_num;
1421      }
1422      return 0;
1423  }
1424  
1425  #ifdef DEBUG
1426  static void print_direntry(const direntry_t* direntry)
1427  {
1428      int j = 0;
1429      char buffer[1024];
1430  
1431      fprintf(stderr, "direntry %p: ", direntry);
1432      if(!direntry)
1433          return;
1434      if(is_long_name(direntry)) {
1435          unsigned char* c=(unsigned char*)direntry;
1436          int i;
1437          for(i=1;i<11 && c[i] && c[i]!=0xff;i+=2)
1438  #define ADD_CHAR(c) {buffer[j] = (c); if (buffer[j] < ' ') buffer[j] = 0xb0; j++;}
1439              ADD_CHAR(c[i]);
1440          for(i=14;i<26 && c[i] && c[i]!=0xff;i+=2)
1441              ADD_CHAR(c[i]);
1442          for(i=28;i<32 && c[i] && c[i]!=0xff;i+=2)
1443              ADD_CHAR(c[i]);
1444          buffer[j] = 0;
1445          fprintf(stderr, "%s\n", buffer);
1446      } else {
1447          int i;
1448          for(i=0;i<11;i++)
1449              ADD_CHAR(direntry->name[i]);
1450          buffer[j] = 0;
1451          fprintf(stderr, "%s attributes=0x%02x begin=%u size=%u\n",
1452                  buffer,
1453                  direntry->attributes,
1454                  begin_of_direntry(direntry),le32_to_cpu(direntry->size));
1455      }
1456  }
1457  
1458  static void print_mapping(const mapping_t* mapping)
1459  {
1460      fprintf(stderr, "mapping (%p): begin, end = %u, %u, dir_index = %u, "
1461          "first_mapping_index = %d, name = %s, mode = 0x%x, " ,
1462          mapping, mapping->begin, mapping->end, mapping->dir_index,
1463          mapping->first_mapping_index, mapping->path, mapping->mode);
1464  
1465      if (mapping->mode & MODE_DIRECTORY)
1466          fprintf(stderr, "parent_mapping_index = %d, first_dir_index = %d\n", mapping->info.dir.parent_mapping_index, mapping->info.dir.first_dir_index);
1467      else
1468          fprintf(stderr, "offset = %u\n", mapping->info.file.offset);
1469  }
1470  #endif
1471  
1472  static int vvfat_read(BlockDriverState *bs, int64_t sector_num,
1473                      uint8_t *buf, int nb_sectors)
1474  {
1475      BDRVVVFATState *s = bs->opaque;
1476      int i;
1477  
1478      for(i=0;i<nb_sectors;i++,sector_num++) {
1479          if (sector_num >= bs->total_sectors)
1480             return -1;
1481          if (s->qcow) {
1482              int64_t n;
1483              int ret;
1484              ret = bdrv_is_allocated(s->qcow->bs, sector_num * BDRV_SECTOR_SIZE,
1485                                      (nb_sectors - i) * BDRV_SECTOR_SIZE, &n);
1486              if (ret < 0) {
1487                  return ret;
1488              }
1489              if (ret) {
1490                  DLOG(fprintf(stderr, "sectors %" PRId64 "+%" PRId64
1491                               " allocated\n", sector_num,
1492                               n >> BDRV_SECTOR_BITS));
1493                  if (bdrv_pread(s->qcow, sector_num * BDRV_SECTOR_SIZE, n,
1494                                 buf + i * 0x200, 0) < 0) {
1495                      return -1;
1496                  }
1497                  i += (n >> BDRV_SECTOR_BITS) - 1;
1498                  sector_num += (n >> BDRV_SECTOR_BITS) - 1;
1499                  continue;
1500              }
1501              DLOG(fprintf(stderr, "sector %" PRId64 " not allocated\n",
1502                           sector_num));
1503          }
1504          if (sector_num < s->offset_to_root_dir) {
1505              if (sector_num < s->offset_to_fat) {
1506                  memcpy(buf + i * 0x200,
1507                         &(s->first_sectors[sector_num * 0x200]),
1508                         0x200);
1509              } else if (sector_num < s->offset_to_fat + s->sectors_per_fat) {
1510                  memcpy(buf + i * 0x200,
1511                         &(s->fat.pointer[(sector_num
1512                                         - s->offset_to_fat) * 0x200]),
1513                         0x200);
1514              } else if (sector_num < s->offset_to_root_dir) {
1515                  memcpy(buf + i * 0x200,
1516                         &(s->fat.pointer[(sector_num - s->offset_to_fat
1517                                         - s->sectors_per_fat) * 0x200]),
1518                         0x200);
1519              }
1520          } else {
1521              uint32_t sector = sector_num - s->offset_to_root_dir,
1522              sector_offset_in_cluster=(sector%s->sectors_per_cluster),
1523              cluster_num=sector/s->sectors_per_cluster;
1524              if(cluster_num > s->cluster_count || read_cluster(s, cluster_num) != 0) {
1525                  /* LATER TODO: strict: return -1; */
1526                  memset(buf+i*0x200,0,0x200);
1527                  continue;
1528              }
1529              memcpy(buf+i*0x200,s->cluster+sector_offset_in_cluster*0x200,0x200);
1530          }
1531      }
1532      return 0;
1533  }
1534  
1535  static int coroutine_fn
1536  vvfat_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
1537                  QEMUIOVector *qiov, BdrvRequestFlags flags)
1538  {
1539      int ret;
1540      BDRVVVFATState *s = bs->opaque;
1541      uint64_t sector_num = offset >> BDRV_SECTOR_BITS;
1542      int nb_sectors = bytes >> BDRV_SECTOR_BITS;
1543      void *buf;
1544  
1545      assert(QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE));
1546      assert(QEMU_IS_ALIGNED(bytes, BDRV_SECTOR_SIZE));
1547  
1548      buf = g_try_malloc(bytes);
1549      if (bytes && buf == NULL) {
1550          return -ENOMEM;
1551      }
1552  
1553      qemu_co_mutex_lock(&s->lock);
1554      ret = vvfat_read(bs, sector_num, buf, nb_sectors);
1555      qemu_co_mutex_unlock(&s->lock);
1556  
1557      qemu_iovec_from_buf(qiov, 0, buf, bytes);
1558      g_free(buf);
1559  
1560      return ret;
1561  }
1562  
1563  /* LATER TODO: statify all functions */
1564  
1565  /*
1566   * Idea of the write support (use snapshot):
1567   *
1568   * 1. check if all data is consistent, recording renames, modifications,
1569   *    new files and directories (in s->commits).
1570   *
1571   * 2. if the data is not consistent, stop committing
1572   *
1573   * 3. handle renames, and create new files and directories (do not yet
1574   *    write their contents)
1575   *
1576   * 4. walk the directories, fixing the mapping and direntries, and marking
1577   *    the handled mappings as not deleted
1578   *
1579   * 5. commit the contents of the files
1580   *
1581   * 6. handle deleted files and directories
1582   *
1583   */
1584  
1585  typedef struct commit_t {
1586      char* path;
1587      union {
1588          struct { uint32_t cluster; } rename;
1589          struct { int dir_index; uint32_t modified_offset; } writeout;
1590          struct { uint32_t first_cluster; } new_file;
1591          struct { uint32_t cluster; } mkdir;
1592      } param;
1593      /* DELETEs and RMDIRs are handled differently: see handle_deletes() */
1594      enum {
1595          ACTION_RENAME, ACTION_WRITEOUT, ACTION_NEW_FILE, ACTION_MKDIR
1596      } action;
1597  } commit_t;
1598  
1599  static void clear_commits(BDRVVVFATState* s)
1600  {
1601      int i;
1602  DLOG(fprintf(stderr, "clear_commits (%u commits)\n", s->commits.next));
1603      for (i = 0; i < s->commits.next; i++) {
1604          commit_t* commit = array_get(&(s->commits), i);
1605          assert(commit->path || commit->action == ACTION_WRITEOUT);
1606          if (commit->action != ACTION_WRITEOUT) {
1607              assert(commit->path);
1608              g_free(commit->path);
1609          } else
1610              assert(commit->path == NULL);
1611      }
1612      s->commits.next = 0;
1613  }
1614  
1615  static void schedule_rename(BDRVVVFATState* s,
1616          uint32_t cluster, char* new_path)
1617  {
1618      commit_t* commit = array_get_next(&(s->commits));
1619      commit->path = new_path;
1620      commit->param.rename.cluster = cluster;
1621      commit->action = ACTION_RENAME;
1622  }
1623  
1624  static void schedule_writeout(BDRVVVFATState* s,
1625          int dir_index, uint32_t modified_offset)
1626  {
1627      commit_t* commit = array_get_next(&(s->commits));
1628      commit->path = NULL;
1629      commit->param.writeout.dir_index = dir_index;
1630      commit->param.writeout.modified_offset = modified_offset;
1631      commit->action = ACTION_WRITEOUT;
1632  }
1633  
1634  static void schedule_new_file(BDRVVVFATState* s,
1635          char* path, uint32_t first_cluster)
1636  {
1637      commit_t* commit = array_get_next(&(s->commits));
1638      commit->path = path;
1639      commit->param.new_file.first_cluster = first_cluster;
1640      commit->action = ACTION_NEW_FILE;
1641  }
1642  
1643  static void schedule_mkdir(BDRVVVFATState* s, uint32_t cluster, char* path)
1644  {
1645      commit_t* commit = array_get_next(&(s->commits));
1646      commit->path = path;
1647      commit->param.mkdir.cluster = cluster;
1648      commit->action = ACTION_MKDIR;
1649  }
1650  
1651  typedef struct {
1652      /*
1653       * Since the sequence number is at most 0x3f, and the filename
1654       * length is at most 13 times the sequence number, the maximal
1655       * filename length is 0x3f * 13 bytes.
1656       */
1657      unsigned char name[0x3f * 13 + 1];
1658      gunichar2 name2[0x3f * 13 + 1];
1659      int checksum, len;
1660      int sequence_number;
1661  } long_file_name;
1662  
1663  static void lfn_init(long_file_name* lfn)
1664  {
1665     lfn->sequence_number = lfn->len = 0;
1666     lfn->checksum = 0x100;
1667  }
1668  
1669  /* return 0 if parsed successfully, > 0 if no long name, < 0 if error */
1670  static int parse_long_name(long_file_name* lfn,
1671          const direntry_t* direntry)
1672  {
1673      int i, j, offset;
1674      const unsigned char* pointer = (const unsigned char*)direntry;
1675  
1676      if (!is_long_name(direntry))
1677          return 1;
1678  
1679      if (pointer[0] & 0x40) {
1680          /* first entry; do some initialization */
1681          lfn->sequence_number = pointer[0] & 0x3f;
1682          lfn->checksum = pointer[13];
1683          lfn->name[0] = 0;
1684          lfn->name[lfn->sequence_number * 13] = 0;
1685      } else if ((pointer[0] & 0x3f) != --lfn->sequence_number) {
1686          /* not the expected sequence number */
1687          return -1;
1688      } else if (pointer[13] != lfn->checksum) {
1689          /* not the expected checksum */
1690          return -2;
1691      } else if (pointer[12] || pointer[26] || pointer[27]) {
1692          /* invalid zero fields */
1693          return -3;
1694      }
1695  
1696      offset = 13 * (lfn->sequence_number - 1);
1697      for (i = 0, j = 1; i < 13; i++, j+=2) {
1698          if (j == 11)
1699              j = 14;
1700          else if (j == 26)
1701              j = 28;
1702  
1703          if (pointer[j] == 0 && pointer[j + 1] == 0) {
1704              /* end of long file name */
1705              break;
1706          }
1707          gunichar2 c = (pointer[j + 1] << 8) + pointer[j];
1708          lfn->name2[offset + i] = c;
1709      }
1710  
1711      if (pointer[0] & 0x40) {
1712          /* first entry; set len */
1713          lfn->len = offset + i;
1714      }
1715      if ((pointer[0] & 0x3f) == 0x01) {
1716          /* last entry; finalize entry */
1717          glong olen;
1718          gchar *utf8 = g_utf16_to_utf8(lfn->name2, lfn->len, NULL, &olen, NULL);
1719          if (!utf8) {
1720              return -4;
1721          }
1722          lfn->len = olen;
1723          memcpy(lfn->name, utf8, olen + 1);
1724          g_free(utf8);
1725      }
1726  
1727      return 0;
1728  }
1729  
1730  /* returns 0 if successful, >0 if no short_name, and <0 on error */
1731  static int parse_short_name(BDRVVVFATState* s,
1732          long_file_name* lfn, direntry_t* direntry)
1733  {
1734      int i, j;
1735  
1736      if (!is_short_name(direntry))
1737          return 1;
1738  
1739      for (j = 7; j >= 0 && direntry->name[j] == ' '; j--);
1740      for (i = 0; i <= j; i++) {
1741          uint8_t c = direntry->name[i];
1742          if (c != to_valid_short_char(c)) {
1743              return -1;
1744          } else if (s->downcase_short_names) {
1745              lfn->name[i] = qemu_tolower(direntry->name[i]);
1746          } else {
1747              lfn->name[i] = direntry->name[i];
1748          }
1749      }
1750  
1751      for (j = 2; j >= 0 && direntry->name[8 + j] == ' '; j--) {
1752      }
1753      if (j >= 0) {
1754          lfn->name[i++] = '.';
1755          lfn->name[i + j + 1] = '\0';
1756          for (;j >= 0; j--) {
1757              uint8_t c = direntry->name[8 + j];
1758              if (c != to_valid_short_char(c)) {
1759                  return -2;
1760              } else if (s->downcase_short_names) {
1761                  lfn->name[i + j] = qemu_tolower(c);
1762              } else {
1763                  lfn->name[i + j] = c;
1764              }
1765          }
1766      } else
1767          lfn->name[i + j + 1] = '\0';
1768  
1769      if (lfn->name[0] == DIR_KANJI_FAKE) {
1770          lfn->name[0] = DIR_KANJI;
1771      }
1772      lfn->len = strlen((char*)lfn->name);
1773  
1774      return 0;
1775  }
1776  
1777  static inline uint32_t modified_fat_get(BDRVVVFATState* s,
1778          unsigned int cluster)
1779  {
1780      if (cluster < s->last_cluster_of_root_directory) {
1781          if (cluster + 1 == s->last_cluster_of_root_directory)
1782              return s->max_fat_value;
1783          else
1784              return cluster + 1;
1785      }
1786  
1787      if (s->fat_type==32) {
1788          uint32_t* entry=((uint32_t*)s->fat2)+cluster;
1789          return le32_to_cpu(*entry);
1790      } else if (s->fat_type==16) {
1791          uint16_t* entry=((uint16_t*)s->fat2)+cluster;
1792          return le16_to_cpu(*entry);
1793      } else {
1794          const uint8_t* x=s->fat2+cluster*3/2;
1795          return ((x[0]|(x[1]<<8))>>(cluster&1?4:0))&0x0fff;
1796      }
1797  }
1798  
1799  static inline bool cluster_was_modified(BDRVVVFATState *s,
1800                                          uint32_t cluster_num)
1801  {
1802      int was_modified = 0;
1803      int i;
1804  
1805      if (s->qcow == NULL) {
1806          return 0;
1807      }
1808  
1809      for (i = 0; !was_modified && i < s->sectors_per_cluster; i++) {
1810          was_modified = bdrv_is_allocated(s->qcow->bs,
1811                                           (cluster2sector(s, cluster_num) +
1812                                            i) * BDRV_SECTOR_SIZE,
1813                                           BDRV_SECTOR_SIZE, NULL);
1814      }
1815  
1816      /*
1817       * Note that this treats failures to learn allocation status the
1818       * same as if an allocation has occurred.  It's as safe as
1819       * anything else, given that a failure to learn allocation status
1820       * will probably result in more failures.
1821       */
1822      return !!was_modified;
1823  }
1824  
1825  static const char* get_basename(const char* path)
1826  {
1827      char* basename = strrchr(path, '/');
1828      if (basename == NULL)
1829          return path;
1830      else
1831          return basename + 1; /* strip '/' */
1832  }
1833  
1834  /*
1835   * The array s->used_clusters holds the states of the clusters. If it is
1836   * part of a file, it has bit 2 set, in case of a directory, bit 1. If it
1837   * was modified, bit 3 is set.
1838   * If any cluster is allocated, but not part of a file or directory, this
1839   * driver refuses to commit.
1840   */
1841  typedef enum {
1842       USED_DIRECTORY = 1, USED_FILE = 2, USED_ANY = 3, USED_ALLOCATED = 4
1843  } used_t;
1844  
1845  /*
1846   * get_cluster_count_for_direntry() not only determines how many clusters
1847   * are occupied by direntry, but also if it was renamed or modified.
1848   *
1849   * A file is thought to be renamed *only* if there already was a file with
1850   * exactly the same first cluster, but a different name.
1851   *
1852   * Further, the files/directories handled by this function are
1853   * assumed to be *not* deleted (and *only* those).
1854   */
1855  static uint32_t get_cluster_count_for_direntry(BDRVVVFATState* s,
1856          direntry_t* direntry, const char* path)
1857  {
1858      /*
1859       * This is a little bit tricky:
1860       * IF the guest OS just inserts a cluster into the file chain,
1861       * and leaves the rest alone, (i.e. the original file had clusters
1862       * 15 -> 16, but now has 15 -> 32 -> 16), then the following happens:
1863       *
1864       * - do_commit will write the cluster into the file at the given
1865       *   offset, but
1866       *
1867       * - the cluster which is overwritten should be moved to a later
1868       *   position in the file.
1869       *
1870       * I am not aware that any OS does something as braindead, but this
1871       * situation could happen anyway when not committing for a long time.
1872       * Just to be sure that this does not bite us, detect it, and copy the
1873       * contents of the clusters to-be-overwritten into the qcow.
1874       */
1875      int copy_it = 0;
1876      int was_modified = 0;
1877      int32_t ret = 0;
1878  
1879      uint32_t cluster_num = begin_of_direntry(direntry);
1880      uint32_t offset = 0;
1881      int first_mapping_index = -1;
1882      mapping_t* mapping = NULL;
1883      const char* basename2 = NULL;
1884  
1885      vvfat_close_current_file(s);
1886  
1887      /* the root directory */
1888      if (cluster_num == 0)
1889          return 0;
1890  
1891      /* write support */
1892      if (s->qcow) {
1893          basename2 = get_basename(path);
1894  
1895          mapping = find_mapping_for_cluster(s, cluster_num);
1896  
1897          if (mapping) {
1898              const char* basename;
1899  
1900              assert(mapping->mode & MODE_DELETED);
1901              mapping->mode &= ~MODE_DELETED;
1902  
1903              basename = get_basename(mapping->path);
1904  
1905              assert(mapping->mode & MODE_NORMAL);
1906  
1907              /* rename */
1908              if (strcmp(basename, basename2))
1909                  schedule_rename(s, cluster_num, g_strdup(path));
1910          } else if (is_file(direntry))
1911              /* new file */
1912              schedule_new_file(s, g_strdup(path), cluster_num);
1913          else {
1914              abort();
1915              return 0;
1916          }
1917      }
1918  
1919      while(1) {
1920          if (s->qcow) {
1921              if (!copy_it && cluster_was_modified(s, cluster_num)) {
1922                  if (mapping == NULL ||
1923                          mapping->begin > cluster_num ||
1924                          mapping->end <= cluster_num)
1925                  mapping = find_mapping_for_cluster(s, cluster_num);
1926  
1927  
1928                  if (mapping &&
1929                          (mapping->mode & MODE_DIRECTORY) == 0) {
1930  
1931                      /* was modified in qcow */
1932                      if (offset != mapping->info.file.offset + s->cluster_size
1933                              * (cluster_num - mapping->begin)) {
1934                          /* offset of this cluster in file chain has changed */
1935                          abort();
1936                          copy_it = 1;
1937                      } else if (offset == 0) {
1938                          const char* basename = get_basename(mapping->path);
1939  
1940                          if (strcmp(basename, basename2))
1941                              copy_it = 1;
1942                          first_mapping_index = array_index(&(s->mapping), mapping);
1943                      }
1944  
1945                      if (mapping->first_mapping_index != first_mapping_index
1946                              && mapping->info.file.offset > 0) {
1947                          abort();
1948                          copy_it = 1;
1949                      }
1950  
1951                      /* need to write out? */
1952                      if (!was_modified && is_file(direntry)) {
1953                          was_modified = 1;
1954                          schedule_writeout(s, mapping->dir_index, offset);
1955                      }
1956                  }
1957              }
1958  
1959              if (copy_it) {
1960                  int i;
1961                  /*
1962                   * This is horribly inefficient, but that is okay, since
1963                   * it is rarely executed, if at all.
1964                   */
1965                  int64_t offset = cluster2sector(s, cluster_num);
1966  
1967                  vvfat_close_current_file(s);
1968                  for (i = 0; i < s->sectors_per_cluster; i++) {
1969                      int res;
1970  
1971                      res = bdrv_is_allocated(s->qcow->bs,
1972                                              (offset + i) * BDRV_SECTOR_SIZE,
1973                                              BDRV_SECTOR_SIZE, NULL);
1974                      if (res < 0) {
1975                          return -1;
1976                      }
1977                      if (!res) {
1978                          res = vvfat_read(s->bs, offset, s->cluster_buffer, 1);
1979                          if (res) {
1980                              return -1;
1981                          }
1982                          res = bdrv_pwrite(s->qcow, offset * BDRV_SECTOR_SIZE,
1983                                            BDRV_SECTOR_SIZE, s->cluster_buffer,
1984                                            0);
1985                          if (res < 0) {
1986                              return -2;
1987                          }
1988                      }
1989                  }
1990              }
1991          }
1992  
1993          ret++;
1994          if (s->used_clusters[cluster_num] & USED_ANY)
1995              return 0;
1996          s->used_clusters[cluster_num] = USED_FILE;
1997  
1998          cluster_num = modified_fat_get(s, cluster_num);
1999  
2000          if (fat_eof(s, cluster_num))
2001              return ret;
2002          else if (cluster_num < 2 || cluster_num > s->max_fat_value - 16)
2003              return -1;
2004  
2005          offset += s->cluster_size;
2006      }
2007  }
2008  
2009  /*
2010   * This function looks at the modified data (qcow).
2011   * It returns 0 upon inconsistency or error, and the number of clusters
2012   * used by the directory, its subdirectories and their files.
2013   */
2014  static int check_directory_consistency(BDRVVVFATState *s,
2015          int cluster_num, const char* path)
2016  {
2017      int ret = 0;
2018      unsigned char* cluster = g_malloc(s->cluster_size);
2019      direntry_t* direntries = (direntry_t*)cluster;
2020      mapping_t* mapping = find_mapping_for_cluster(s, cluster_num);
2021  
2022      long_file_name lfn;
2023      int path_len = strlen(path);
2024      char path2[PATH_MAX + 1];
2025  
2026      assert(path_len < PATH_MAX); /* len was tested before! */
2027      pstrcpy(path2, sizeof(path2), path);
2028      path2[path_len] = '/';
2029      path2[path_len + 1] = '\0';
2030  
2031      if (mapping) {
2032          const char* basename = get_basename(mapping->path);
2033          const char* basename2 = get_basename(path);
2034  
2035          assert(mapping->mode & MODE_DIRECTORY);
2036  
2037          assert(mapping->mode & MODE_DELETED);
2038          mapping->mode &= ~MODE_DELETED;
2039  
2040          if (strcmp(basename, basename2))
2041              schedule_rename(s, cluster_num, g_strdup(path));
2042      } else
2043          /* new directory */
2044          schedule_mkdir(s, cluster_num, g_strdup(path));
2045  
2046      lfn_init(&lfn);
2047      do {
2048          int i;
2049          int subret = 0;
2050  
2051          ret++;
2052  
2053          if (s->used_clusters[cluster_num] & USED_ANY) {
2054              fprintf(stderr, "cluster %d used more than once\n", (int)cluster_num);
2055              goto fail;
2056          }
2057          s->used_clusters[cluster_num] = USED_DIRECTORY;
2058  
2059  DLOG(fprintf(stderr, "read cluster %d (sector %d)\n", (int)cluster_num, (int)cluster2sector(s, cluster_num)));
2060          subret = vvfat_read(s->bs, cluster2sector(s, cluster_num), cluster,
2061                  s->sectors_per_cluster);
2062          if (subret) {
2063              fprintf(stderr, "Error fetching direntries\n");
2064          fail:
2065              g_free(cluster);
2066              return 0;
2067          }
2068  
2069          for (i = 0; i < 0x10 * s->sectors_per_cluster; i++) {
2070              int cluster_count = 0;
2071  
2072  DLOG(fprintf(stderr, "check direntry %d:\n", i); print_direntry(direntries + i));
2073              if (is_volume_label(direntries + i) || is_dot(direntries + i) ||
2074                      is_free(direntries + i))
2075                  continue;
2076  
2077              subret = parse_long_name(&lfn, direntries + i);
2078              if (subret < 0) {
2079                  fprintf(stderr, "Error in long name\n");
2080                  goto fail;
2081              }
2082              if (subret == 0 || is_free(direntries + i))
2083                  continue;
2084  
2085              if (fat_chksum(direntries+i) != lfn.checksum) {
2086                  subret = parse_short_name(s, &lfn, direntries + i);
2087                  if (subret < 0) {
2088                      fprintf(stderr, "Error in short name (%d)\n", subret);
2089                      goto fail;
2090                  }
2091                  if (subret > 0 || !strcmp((char*)lfn.name, ".")
2092                          || !strcmp((char*)lfn.name, ".."))
2093                      continue;
2094              }
2095              lfn.checksum = 0x100; /* cannot use long name twice */
2096  
2097              if (!valid_filename(lfn.name)) {
2098                  fprintf(stderr, "Invalid file name\n");
2099                  goto fail;
2100              }
2101              if (path_len + 1 + lfn.len >= PATH_MAX) {
2102                  fprintf(stderr, "Name too long: %s/%s\n", path, lfn.name);
2103                  goto fail;
2104              }
2105              pstrcpy(path2 + path_len + 1, sizeof(path2) - path_len - 1,
2106                      (char*)lfn.name);
2107  
2108              if (is_directory(direntries + i)) {
2109                  if (begin_of_direntry(direntries + i) == 0) {
2110                      DLOG(fprintf(stderr, "invalid begin for directory: %s\n", path2); print_direntry(direntries + i));
2111                      goto fail;
2112                  }
2113                  cluster_count = check_directory_consistency(s,
2114                          begin_of_direntry(direntries + i), path2);
2115                  if (cluster_count == 0) {
2116                      DLOG(fprintf(stderr, "problem in directory %s:\n", path2); print_direntry(direntries + i));
2117                      goto fail;
2118                  }
2119              } else if (is_file(direntries + i)) {
2120                  /* check file size with FAT */
2121                  cluster_count = get_cluster_count_for_direntry(s, direntries + i, path2);
2122                  if (cluster_count !=
2123              DIV_ROUND_UP(le32_to_cpu(direntries[i].size), s->cluster_size)) {
2124                      DLOG(fprintf(stderr, "Cluster count mismatch\n"));
2125                      goto fail;
2126                  }
2127              } else
2128                  abort(); /* cluster_count = 0; */
2129  
2130              ret += cluster_count;
2131          }
2132  
2133          cluster_num = modified_fat_get(s, cluster_num);
2134      } while(!fat_eof(s, cluster_num));
2135  
2136      g_free(cluster);
2137      return ret;
2138  }
2139  
2140  /* returns 1 on success */
2141  static int is_consistent(BDRVVVFATState* s)
2142  {
2143      int i, check;
2144      int used_clusters_count = 0;
2145  
2146  DLOG(checkpoint());
2147      /*
2148       * - get modified FAT
2149       * - compare the two FATs (TODO)
2150       * - get buffer for marking used clusters
2151       * - recurse direntries from root (using bs->bdrv_pread to make
2152       *    sure to get the new data)
2153       *   - check that the FAT agrees with the size
2154       *   - count the number of clusters occupied by this directory and
2155       *     its files
2156       * - check that the cumulative used cluster count agrees with the
2157       *   FAT
2158       * - if all is fine, return number of used clusters
2159       */
2160      if (s->fat2 == NULL) {
2161          int size = 0x200 * s->sectors_per_fat;
2162          s->fat2 = g_malloc(size);
2163          memcpy(s->fat2, s->fat.pointer, size);
2164      }
2165      check = vvfat_read(s->bs,
2166              s->offset_to_fat, s->fat2, s->sectors_per_fat);
2167      if (check) {
2168          fprintf(stderr, "Could not copy fat\n");
2169          return 0;
2170      }
2171      assert (s->used_clusters);
2172      for (i = 0; i < sector2cluster(s, s->sector_count); i++)
2173          s->used_clusters[i] &= ~USED_ANY;
2174  
2175      clear_commits(s);
2176  
2177      /* mark every mapped file/directory as deleted.
2178       * (check_directory_consistency() will unmark those still present). */
2179      if (s->qcow)
2180          for (i = 0; i < s->mapping.next; i++) {
2181              mapping_t* mapping = array_get(&(s->mapping), i);
2182              if (mapping->first_mapping_index < 0)
2183                  mapping->mode |= MODE_DELETED;
2184          }
2185  
2186      used_clusters_count = check_directory_consistency(s, 0, s->path);
2187      if (used_clusters_count <= 0) {
2188          DLOG(fprintf(stderr, "problem in directory\n"));
2189          return 0;
2190      }
2191  
2192      check = s->last_cluster_of_root_directory;
2193      for (i = check; i < sector2cluster(s, s->sector_count); i++) {
2194          if (modified_fat_get(s, i)) {
2195              if(!s->used_clusters[i]) {
2196                  DLOG(fprintf(stderr, "FAT was modified (%d), but cluster is not used?\n", i));
2197                  return 0;
2198              }
2199              check++;
2200          }
2201  
2202          if (s->used_clusters[i] == USED_ALLOCATED) {
2203              /* allocated, but not used... */
2204              DLOG(fprintf(stderr, "unused, modified cluster: %d\n", i));
2205              return 0;
2206          }
2207      }
2208  
2209      if (check != used_clusters_count)
2210          return 0;
2211  
2212      return used_clusters_count;
2213  }
2214  
2215  static inline void adjust_mapping_indices(BDRVVVFATState* s,
2216          int offset, int adjust)
2217  {
2218      int i;
2219  
2220      for (i = 0; i < s->mapping.next; i++) {
2221          mapping_t* mapping = array_get(&(s->mapping), i);
2222  
2223  #define ADJUST_MAPPING_INDEX(name) \
2224          if (mapping->name >= offset) \
2225              mapping->name += adjust
2226  
2227          ADJUST_MAPPING_INDEX(first_mapping_index);
2228          if (mapping->mode & MODE_DIRECTORY)
2229              ADJUST_MAPPING_INDEX(info.dir.parent_mapping_index);
2230      }
2231  }
2232  
2233  /* insert or update mapping */
2234  static mapping_t* insert_mapping(BDRVVVFATState* s,
2235          uint32_t begin, uint32_t end)
2236  {
2237      /*
2238       * - find mapping where mapping->begin >= begin,
2239       * - if mapping->begin > begin: insert
2240       *   - adjust all references to mappings!
2241       * - else: adjust
2242       * - replace name
2243       */
2244      int index = find_mapping_for_cluster_aux(s, begin, 0, s->mapping.next);
2245      mapping_t* mapping = NULL;
2246      mapping_t* first_mapping = array_get(&(s->mapping), 0);
2247  
2248      if (index < s->mapping.next && (mapping = array_get(&(s->mapping), index))
2249              && mapping->begin < begin) {
2250          mapping->end = begin;
2251          index++;
2252          mapping = array_get(&(s->mapping), index);
2253      }
2254      if (index >= s->mapping.next || mapping->begin > begin) {
2255          mapping = array_insert(&(s->mapping), index, 1);
2256          mapping->path = NULL;
2257          adjust_mapping_indices(s, index, +1);
2258      }
2259  
2260      mapping->begin = begin;
2261      mapping->end = end;
2262  
2263  DLOG(mapping_t* next_mapping;
2264  assert(index + 1 >= s->mapping.next ||
2265  ((next_mapping = array_get(&(s->mapping), index + 1)) &&
2266   next_mapping->begin >= end)));
2267  
2268      if (s->current_mapping && first_mapping != (mapping_t*)s->mapping.pointer)
2269          s->current_mapping = array_get(&(s->mapping),
2270                  s->current_mapping - first_mapping);
2271  
2272      return mapping;
2273  }
2274  
2275  static int remove_mapping(BDRVVVFATState* s, int mapping_index)
2276  {
2277      mapping_t* mapping = array_get(&(s->mapping), mapping_index);
2278      mapping_t* first_mapping = array_get(&(s->mapping), 0);
2279  
2280      /* free mapping */
2281      if (mapping->first_mapping_index < 0) {
2282          g_free(mapping->path);
2283      }
2284  
2285      /* remove from s->mapping */
2286      array_remove(&(s->mapping), mapping_index);
2287  
2288      /* adjust all references to mappings */
2289      adjust_mapping_indices(s, mapping_index, -1);
2290  
2291      if (s->current_mapping && first_mapping != (mapping_t*)s->mapping.pointer)
2292          s->current_mapping = array_get(&(s->mapping),
2293                  s->current_mapping - first_mapping);
2294  
2295      return 0;
2296  }
2297  
2298  static void adjust_dirindices(BDRVVVFATState* s, int offset, int adjust)
2299  {
2300      int i;
2301      for (i = 0; i < s->mapping.next; i++) {
2302          mapping_t* mapping = array_get(&(s->mapping), i);
2303          if (mapping->dir_index >= offset)
2304              mapping->dir_index += adjust;
2305          if ((mapping->mode & MODE_DIRECTORY) &&
2306                  mapping->info.dir.first_dir_index >= offset)
2307              mapping->info.dir.first_dir_index += adjust;
2308      }
2309  }
2310  
2311  static direntry_t* insert_direntries(BDRVVVFATState* s,
2312          int dir_index, int count)
2313  {
2314      /*
2315       * make room in s->directory,
2316       * adjust_dirindices
2317       */
2318      direntry_t* result = array_insert(&(s->directory), dir_index, count);
2319      if (result == NULL)
2320          return NULL;
2321      adjust_dirindices(s, dir_index, count);
2322      return result;
2323  }
2324  
2325  static int remove_direntries(BDRVVVFATState* s, int dir_index, int count)
2326  {
2327      int ret = array_remove_slice(&(s->directory), dir_index, count);
2328      if (ret)
2329          return ret;
2330      adjust_dirindices(s, dir_index, -count);
2331      return 0;
2332  }
2333  
2334  /*
2335   * Adapt the mappings of the cluster chain starting at first cluster
2336   * (i.e. if a file starts at first_cluster, the chain is followed according
2337   * to the modified fat, and the corresponding entries in s->mapping are
2338   * adjusted)
2339   */
2340  static int commit_mappings(BDRVVVFATState* s,
2341          uint32_t first_cluster, int dir_index)
2342  {
2343      mapping_t* mapping = find_mapping_for_cluster(s, first_cluster);
2344      direntry_t* direntry = array_get(&(s->directory), dir_index);
2345      uint32_t cluster = first_cluster;
2346  
2347      vvfat_close_current_file(s);
2348  
2349      assert(mapping);
2350      assert(mapping->begin == first_cluster);
2351      mapping->first_mapping_index = -1;
2352      mapping->dir_index = dir_index;
2353      mapping->mode = (dir_index <= 0 || is_directory(direntry)) ?
2354          MODE_DIRECTORY : MODE_NORMAL;
2355  
2356      while (!fat_eof(s, cluster)) {
2357          uint32_t c, c1;
2358  
2359          for (c = cluster, c1 = modified_fat_get(s, c); c + 1 == c1;
2360                  c = c1, c1 = modified_fat_get(s, c1));
2361  
2362          c++;
2363          if (c > mapping->end) {
2364              int index = array_index(&(s->mapping), mapping);
2365              int i, max_i = s->mapping.next - index;
2366              for (i = 1; i < max_i && mapping[i].begin < c; i++);
2367              while (--i > 0)
2368                  remove_mapping(s, index + 1);
2369          }
2370          assert(mapping == array_get(&(s->mapping), s->mapping.next - 1)
2371                  || mapping[1].begin >= c);
2372          mapping->end = c;
2373  
2374          if (!fat_eof(s, c1)) {
2375              int i = find_mapping_for_cluster_aux(s, c1, 0, s->mapping.next);
2376              mapping_t* next_mapping = i >= s->mapping.next ? NULL :
2377                  array_get(&(s->mapping), i);
2378  
2379              if (next_mapping == NULL || next_mapping->begin > c1) {
2380                  int i1 = array_index(&(s->mapping), mapping);
2381  
2382                  next_mapping = insert_mapping(s, c1, c1+1);
2383  
2384                  if (c1 < c)
2385                      i1++;
2386                  mapping = array_get(&(s->mapping), i1);
2387              }
2388  
2389              next_mapping->dir_index = mapping->dir_index;
2390              next_mapping->first_mapping_index =
2391                  mapping->first_mapping_index < 0 ?
2392                  array_index(&(s->mapping), mapping) :
2393                  mapping->first_mapping_index;
2394              next_mapping->path = mapping->path;
2395              next_mapping->mode = mapping->mode;
2396              next_mapping->read_only = mapping->read_only;
2397              if (mapping->mode & MODE_DIRECTORY) {
2398                  next_mapping->info.dir.parent_mapping_index =
2399                          mapping->info.dir.parent_mapping_index;
2400                  next_mapping->info.dir.first_dir_index =
2401                          mapping->info.dir.first_dir_index +
2402                          0x10 * s->sectors_per_cluster *
2403                          (mapping->end - mapping->begin);
2404              } else
2405                  next_mapping->info.file.offset = mapping->info.file.offset +
2406                          mapping->end - mapping->begin;
2407  
2408              mapping = next_mapping;
2409          }
2410  
2411          cluster = c1;
2412      }
2413  
2414      return 0;
2415  }
2416  
2417  static int commit_direntries(BDRVVVFATState* s,
2418          int dir_index, int parent_mapping_index)
2419  {
2420      direntry_t* direntry = array_get(&(s->directory), dir_index);
2421      uint32_t first_cluster = dir_index == 0 ? 0 : begin_of_direntry(direntry);
2422      mapping_t* mapping = find_mapping_for_cluster(s, first_cluster);
2423      int factor = 0x10 * s->sectors_per_cluster;
2424      int old_cluster_count, new_cluster_count;
2425      int current_dir_index;
2426      int first_dir_index;
2427      int ret, i;
2428      uint32_t c;
2429  
2430      assert(direntry);
2431      assert(mapping);
2432      assert(mapping->begin == first_cluster);
2433      assert(mapping->info.dir.first_dir_index < s->directory.next);
2434      assert(mapping->mode & MODE_DIRECTORY);
2435      assert(dir_index == 0 || is_directory(direntry));
2436  
2437      DLOG(fprintf(stderr, "commit_direntries for %s, parent_mapping_index %d\n",
2438                   mapping->path, parent_mapping_index));
2439  
2440      current_dir_index = mapping->info.dir.first_dir_index;
2441      first_dir_index = current_dir_index;
2442      mapping->info.dir.parent_mapping_index = parent_mapping_index;
2443  
2444      if (first_cluster == 0) {
2445          old_cluster_count = new_cluster_count =
2446              s->last_cluster_of_root_directory;
2447      } else {
2448          for (old_cluster_count = 0, c = first_cluster; !fat_eof(s, c);
2449                  c = fat_get(s, c))
2450              old_cluster_count++;
2451  
2452          for (new_cluster_count = 0, c = first_cluster; !fat_eof(s, c);
2453                  c = modified_fat_get(s, c))
2454              new_cluster_count++;
2455      }
2456  
2457      if (new_cluster_count > old_cluster_count) {
2458          if (insert_direntries(s,
2459                  current_dir_index + factor * old_cluster_count,
2460                  factor * (new_cluster_count - old_cluster_count)) == NULL)
2461              return -1;
2462      } else if (new_cluster_count < old_cluster_count)
2463          remove_direntries(s,
2464                  current_dir_index + factor * new_cluster_count,
2465                  factor * (old_cluster_count - new_cluster_count));
2466  
2467      for (c = first_cluster; !fat_eof(s, c); c = modified_fat_get(s, c)) {
2468          direntry_t *first_direntry;
2469          void* direntry = array_get(&(s->directory), current_dir_index);
2470          int ret = vvfat_read(s->bs, cluster2sector(s, c), 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 commit_one_file(BDRVVVFATState* s,
2508          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 = s->cluster_size; i < offset; i += s->cluster_size)
2527          c = modified_fat_get(s, c);
2528  
2529      fd = qemu_open_old(mapping->path, O_RDWR | O_CREAT | O_BINARY, 0666);
2530      if (fd < 0) {
2531          fprintf(stderr, "Could not open %s... (%s, %d)\n", mapping->path,
2532                  strerror(errno), errno);
2533          return fd;
2534      }
2535      if (offset > 0) {
2536          if (lseek(fd, offset, SEEK_SET) != offset) {
2537              qemu_close(fd);
2538              return -3;
2539          }
2540      }
2541  
2542      cluster = g_malloc(s->cluster_size);
2543  
2544      while (offset < size) {
2545          uint32_t c1;
2546          int rest_size = (size - offset > s->cluster_size ?
2547                  s->cluster_size : size - offset);
2548          int ret;
2549  
2550          c1 = modified_fat_get(s, c);
2551  
2552          assert((size - offset == 0 && fat_eof(s, c)) ||
2553                  (size > offset && c >=2 && !fat_eof(s, c)));
2554  
2555          ret = vvfat_read(s->bs, cluster2sector(s, c),
2556              (uint8_t*)cluster, DIV_ROUND_UP(rest_size, 0x200));
2557  
2558          if (ret < 0) {
2559              qemu_close(fd);
2560              g_free(cluster);
2561              return ret;
2562          }
2563  
2564          if (write(fd, cluster, rest_size) < 0) {
2565              qemu_close(fd);
2566              g_free(cluster);
2567              return -2;
2568          }
2569  
2570          offset += rest_size;
2571          c = c1;
2572      }
2573  
2574      if (ftruncate(fd, size)) {
2575          perror("ftruncate()");
2576          qemu_close(fd);
2577          g_free(cluster);
2578          return -4;
2579      }
2580      qemu_close(fd);
2581      g_free(cluster);
2582  
2583      return commit_mappings(s, first_cluster, dir_index);
2584  }
2585  
2586  #ifdef DEBUG
2587  /* test, if all mappings point to valid direntries */
2588  static void check1(BDRVVVFATState* s)
2589  {
2590      int i;
2591      for (i = 0; i < s->mapping.next; i++) {
2592          mapping_t* mapping = array_get(&(s->mapping), i);
2593          if (mapping->mode & MODE_DELETED) {
2594              fprintf(stderr, "deleted\n");
2595              continue;
2596          }
2597          assert(mapping->dir_index < s->directory.next);
2598          direntry_t* direntry = array_get(&(s->directory), mapping->dir_index);
2599          assert(mapping->begin == begin_of_direntry(direntry) || mapping->first_mapping_index >= 0);
2600          if (mapping->mode & MODE_DIRECTORY) {
2601              assert(mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster * (mapping->end - mapping->begin) <= s->directory.next);
2602              assert((mapping->info.dir.first_dir_index % (0x10 * s->sectors_per_cluster)) == 0);
2603          }
2604      }
2605  }
2606  
2607  /* test, if all direntries have mappings */
2608  static void check2(BDRVVVFATState* s)
2609  {
2610      int i;
2611      int first_mapping = -1;
2612  
2613      for (i = 0; i < s->directory.next; i++) {
2614          direntry_t* direntry = array_get(&(s->directory), i);
2615  
2616          if (is_short_name(direntry) && begin_of_direntry(direntry)) {
2617              mapping_t* mapping = find_mapping_for_cluster(s, begin_of_direntry(direntry));
2618              assert(mapping);
2619              assert(mapping->dir_index == i || is_dot(direntry));
2620              assert(mapping->begin == begin_of_direntry(direntry) || is_dot(direntry));
2621          }
2622  
2623          if ((i % (0x10 * s->sectors_per_cluster)) == 0) {
2624              /* cluster start */
2625              int j, count = 0;
2626  
2627              for (j = 0; j < s->mapping.next; j++) {
2628                  mapping_t* mapping = array_get(&(s->mapping), j);
2629                  if (mapping->mode & MODE_DELETED)
2630                      continue;
2631                  if (mapping->mode & MODE_DIRECTORY) {
2632                      if (mapping->info.dir.first_dir_index <= i && mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster > i) {
2633                          assert(++count == 1);
2634                          if (mapping->first_mapping_index == -1)
2635                              first_mapping = array_index(&(s->mapping), mapping);
2636                          else
2637                              assert(first_mapping == mapping->first_mapping_index);
2638                          if (mapping->info.dir.parent_mapping_index < 0)
2639                              assert(j == 0);
2640                          else {
2641                              mapping_t* parent = array_get(&(s->mapping), mapping->info.dir.parent_mapping_index);
2642                              assert(parent->mode & MODE_DIRECTORY);
2643                              assert(parent->info.dir.first_dir_index < mapping->info.dir.first_dir_index);
2644                          }
2645                      }
2646                  }
2647              }
2648              if (count == 0)
2649                  first_mapping = -1;
2650          }
2651      }
2652  }
2653  #endif
2654  
2655  static int handle_renames_and_mkdirs(BDRVVVFATState* s)
2656  {
2657      int i;
2658  
2659  #ifdef DEBUG
2660      fprintf(stderr, "handle_renames\n");
2661      for (i = 0; i < s->commits.next; i++) {
2662          commit_t* commit = array_get(&(s->commits), i);
2663          fprintf(stderr, "%d, %s (%u, %d)\n", i,
2664                  commit->path ? commit->path : "(null)",
2665                  commit->param.rename.cluster, commit->action);
2666      }
2667  #endif
2668  
2669      for (i = 0; i < s->commits.next;) {
2670          commit_t* commit = array_get(&(s->commits), i);
2671          if (commit->action == ACTION_RENAME) {
2672              mapping_t* mapping = find_mapping_for_cluster(s,
2673                      commit->param.rename.cluster);
2674              char *old_path;
2675  
2676              if (mapping == NULL) {
2677                  return -1;
2678              }
2679              old_path = mapping->path;
2680              assert(commit->path);
2681              mapping->path = commit->path;
2682              if (rename(old_path, mapping->path))
2683                  return -2;
2684  
2685              if (mapping->mode & MODE_DIRECTORY) {
2686                  int l1 = strlen(mapping->path);
2687                  int l2 = strlen(old_path);
2688                  int diff = l1 - l2;
2689                  direntry_t* direntry = array_get(&(s->directory),
2690                          mapping->info.dir.first_dir_index);
2691                  uint32_t c = mapping->begin;
2692                  int i = 0;
2693  
2694                  /* recurse */
2695                  while (!fat_eof(s, c)) {
2696                      do {
2697                          direntry_t* d = direntry + i;
2698  
2699                          if (is_file(d) || (is_directory(d) && !is_dot(d))) {
2700                              int l;
2701                              char *new_path;
2702                              mapping_t* m = find_mapping_for_cluster(s,
2703                                      begin_of_direntry(d));
2704                              if (m == NULL) {
2705                                  return -1;
2706                              }
2707                              l = strlen(m->path);
2708                              new_path = g_malloc(l + diff + 1);
2709  
2710                              assert(!strncmp(m->path, mapping->path, l2));
2711  
2712                              pstrcpy(new_path, l + diff + 1, mapping->path);
2713                              pstrcpy(new_path + l1, l + diff + 1 - l1,
2714                                      m->path + l2);
2715  
2716                              schedule_rename(s, m->begin, new_path);
2717                          }
2718                          i++;
2719                      } while((i % (0x10 * s->sectors_per_cluster)) != 0);
2720                      c = fat_get(s, c);
2721                  }
2722              }
2723  
2724              g_free(old_path);
2725              array_remove(&(s->commits), i);
2726              continue;
2727          } else if (commit->action == ACTION_MKDIR) {
2728              mapping_t* mapping;
2729              int j, parent_path_len;
2730  
2731              if (g_mkdir(commit->path, 0755)) {
2732                  return -5;
2733              }
2734  
2735              mapping = insert_mapping(s, commit->param.mkdir.cluster,
2736                      commit->param.mkdir.cluster + 1);
2737              if (mapping == NULL)
2738                  return -6;
2739  
2740              mapping->mode = MODE_DIRECTORY;
2741              mapping->read_only = 0;
2742              mapping->path = commit->path;
2743              j = s->directory.next;
2744              assert(j);
2745              insert_direntries(s, s->directory.next,
2746                      0x10 * s->sectors_per_cluster);
2747              mapping->info.dir.first_dir_index = j;
2748  
2749              parent_path_len = strlen(commit->path)
2750                  - strlen(get_basename(commit->path)) - 1;
2751              for (j = 0; j < s->mapping.next; j++) {
2752                  mapping_t* m = array_get(&(s->mapping), j);
2753                  if (m->first_mapping_index < 0 && m != mapping &&
2754                          !strncmp(m->path, mapping->path, parent_path_len) &&
2755                          strlen(m->path) == parent_path_len)
2756                      break;
2757              }
2758              assert(j < s->mapping.next);
2759              mapping->info.dir.parent_mapping_index = j;
2760  
2761              array_remove(&(s->commits), i);
2762              continue;
2763          }
2764  
2765          i++;
2766      }
2767      return 0;
2768  }
2769  
2770  /*
2771   * TODO: make sure that the short name is not matching *another* file
2772   */
2773  static int handle_commits(BDRVVVFATState* s)
2774  {
2775      int i, fail = 0;
2776  
2777      vvfat_close_current_file(s);
2778  
2779      for (i = 0; !fail && i < s->commits.next; i++) {
2780          commit_t* commit = array_get(&(s->commits), i);
2781          switch(commit->action) {
2782          case ACTION_RENAME: case ACTION_MKDIR:
2783              abort();
2784              fail = -2;
2785              break;
2786          case ACTION_WRITEOUT: {
2787  #ifndef NDEBUG
2788              /* these variables are only used by assert() below */
2789              direntry_t* entry = array_get(&(s->directory),
2790                      commit->param.writeout.dir_index);
2791              uint32_t begin = begin_of_direntry(entry);
2792              mapping_t* mapping = find_mapping_for_cluster(s, begin);
2793  #endif
2794  
2795              assert(mapping);
2796              assert(mapping->begin == begin);
2797              assert(commit->path == NULL);
2798  
2799              if (commit_one_file(s, commit->param.writeout.dir_index,
2800                          commit->param.writeout.modified_offset))
2801                  fail = -3;
2802  
2803              break;
2804          }
2805          case ACTION_NEW_FILE: {
2806              int begin = commit->param.new_file.first_cluster;
2807              mapping_t* mapping = find_mapping_for_cluster(s, begin);
2808              direntry_t* entry;
2809              int i;
2810  
2811              /* find direntry */
2812              for (i = 0; i < s->directory.next; i++) {
2813                  entry = array_get(&(s->directory), i);
2814                  if (is_file(entry) && begin_of_direntry(entry) == begin)
2815                      break;
2816              }
2817  
2818              if (i >= s->directory.next) {
2819                  fail = -6;
2820                  continue;
2821              }
2822  
2823              /* make sure there exists an initial mapping */
2824              if (mapping && mapping->begin != begin) {
2825                  mapping->end = begin;
2826                  mapping = NULL;
2827              }
2828              if (mapping == NULL) {
2829                  mapping = insert_mapping(s, begin, begin+1);
2830              }
2831              /* most members will be fixed in commit_mappings() */
2832              assert(commit->path);
2833              mapping->path = commit->path;
2834              mapping->read_only = 0;
2835              mapping->mode = MODE_NORMAL;
2836              mapping->info.file.offset = 0;
2837  
2838              if (commit_one_file(s, i, 0))
2839                  fail = -7;
2840  
2841              break;
2842          }
2843          default:
2844              abort();
2845          }
2846      }
2847      if (i > 0 && array_remove_slice(&(s->commits), 0, i))
2848          return -1;
2849      return fail;
2850  }
2851  
2852  static int handle_deletes(BDRVVVFATState* s)
2853  {
2854      int i, deferred = 1, deleted = 1;
2855  
2856      /* delete files corresponding to mappings marked as deleted */
2857      /* handle DELETEs and unused mappings (modified_fat_get(s, mapping->begin) == 0) */
2858      while (deferred && deleted) {
2859          deferred = 0;
2860          deleted = 0;
2861  
2862          for (i = 1; i < s->mapping.next; i++) {
2863              mapping_t* mapping = array_get(&(s->mapping), i);
2864              if (mapping->mode & MODE_DELETED) {
2865                  direntry_t* entry = array_get(&(s->directory),
2866                          mapping->dir_index);
2867  
2868                  if (is_free(entry)) {
2869                      /* remove file/directory */
2870                      if (mapping->mode & MODE_DIRECTORY) {
2871                          int j, next_dir_index = s->directory.next,
2872                          first_dir_index = mapping->info.dir.first_dir_index;
2873  
2874                          if (rmdir(mapping->path) < 0) {
2875                              if (errno == ENOTEMPTY) {
2876                                  deferred++;
2877                                  continue;
2878                              } else
2879                                  return -5;
2880                          }
2881  
2882                          for (j = 1; j < s->mapping.next; j++) {
2883                              mapping_t* m = array_get(&(s->mapping), j);
2884                              if (m->mode & MODE_DIRECTORY &&
2885                                      m->info.dir.first_dir_index >
2886                                      first_dir_index &&
2887                                      m->info.dir.first_dir_index <
2888                                      next_dir_index)
2889                                  next_dir_index =
2890                                      m->info.dir.first_dir_index;
2891                          }
2892                          remove_direntries(s, first_dir_index,
2893                                  next_dir_index - first_dir_index);
2894  
2895                          deleted++;
2896                      }
2897                  } else {
2898                      if (unlink(mapping->path))
2899                          return -4;
2900                      deleted++;
2901                  }
2902                  DLOG(fprintf(stderr, "DELETE (%d)\n", i); print_mapping(mapping); print_direntry(entry));
2903                  remove_mapping(s, i);
2904              }
2905          }
2906      }
2907  
2908      return 0;
2909  }
2910  
2911  /*
2912   * synchronize mapping with new state:
2913   *
2914   * - copy FAT (with bdrv_pread)
2915   * - mark all filenames corresponding to mappings as deleted
2916   * - recurse direntries from root (using bs->bdrv_pread)
2917   * - delete files corresponding to mappings marked as deleted
2918   */
2919  static int do_commit(BDRVVVFATState* s)
2920  {
2921      int ret = 0;
2922  
2923      /* the real meat are the commits. Nothing to do? Move along! */
2924      if (s->commits.next == 0)
2925          return 0;
2926  
2927      vvfat_close_current_file(s);
2928  
2929      ret = handle_renames_and_mkdirs(s);
2930      if (ret) {
2931          fprintf(stderr, "Error handling renames (%d)\n", ret);
2932          abort();
2933          return ret;
2934      }
2935  
2936      /* copy FAT (with bdrv_pread) */
2937      memcpy(s->fat.pointer, s->fat2, 0x200 * s->sectors_per_fat);
2938  
2939      /* recurse direntries from root (using bs->bdrv_pread) */
2940      ret = commit_direntries(s, 0, -1);
2941      if (ret) {
2942          fprintf(stderr, "Fatal: error while committing (%d)\n", ret);
2943          abort();
2944          return ret;
2945      }
2946  
2947      ret = handle_commits(s);
2948      if (ret) {
2949          fprintf(stderr, "Error handling commits (%d)\n", ret);
2950          abort();
2951          return ret;
2952      }
2953  
2954      ret = handle_deletes(s);
2955      if (ret) {
2956          fprintf(stderr, "Error deleting\n");
2957          abort();
2958          return ret;
2959      }
2960  
2961      bdrv_make_empty(s->qcow, NULL);
2962  
2963      memset(s->used_clusters, 0, sector2cluster(s, s->sector_count));
2964  
2965  DLOG(checkpoint());
2966      return 0;
2967  }
2968  
2969  static int try_commit(BDRVVVFATState* s)
2970  {
2971      vvfat_close_current_file(s);
2972  DLOG(checkpoint());
2973      if(!is_consistent(s))
2974          return -1;
2975      return do_commit(s);
2976  }
2977  
2978  static int 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_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
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          error_free(s->migration_blocker);
3242      }
3243  }
3244  
3245  static const char *const vvfat_strong_runtime_opts[] = {
3246      "dir",
3247      "fat-type",
3248      "floppy",
3249      "label",
3250      "rw",
3251  
3252      NULL
3253  };
3254  
3255  static BlockDriver bdrv_vvfat = {
3256      .format_name            = "vvfat",
3257      .protocol_name          = "fat",
3258      .instance_size          = sizeof(BDRVVVFATState),
3259  
3260      .bdrv_parse_filename    = vvfat_parse_filename,
3261      .bdrv_file_open         = vvfat_open,
3262      .bdrv_refresh_limits    = vvfat_refresh_limits,
3263      .bdrv_close             = vvfat_close,
3264      .bdrv_child_perm        = vvfat_child_perm,
3265  
3266      .bdrv_co_preadv         = vvfat_co_preadv,
3267      .bdrv_co_pwritev        = vvfat_co_pwritev,
3268      .bdrv_co_block_status   = vvfat_co_block_status,
3269  
3270      .strong_runtime_opts    = vvfat_strong_runtime_opts,
3271  };
3272  
3273  static void bdrv_vvfat_init(void)
3274  {
3275      child_vvfat_qcow = child_of_bds;
3276      child_vvfat_qcow.inherit_options = vvfat_qcow_options;
3277      bdrv_register(&bdrv_vvfat);
3278  }
3279  
3280  block_init(bdrv_vvfat_init);
3281  
3282  #ifdef DEBUG
3283  static void checkpoint(void)
3284  {
3285      assert(((mapping_t*)array_get(&(vvv->mapping), 0))->end == 2);
3286      check1(vvv);
3287      check2(vvv);
3288      assert(!vvv->current_mapping || vvv->current_fd || (vvv->current_mapping->mode & MODE_DIRECTORY));
3289  }
3290  #endif
3291