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