All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 00/13] vvfat: misc fixes for read-only mode
@ 2017-05-22 21:11 Hervé Poussineau
  2017-05-22 21:11 ` [Qemu-devel] [PATCH v2 01/13] vvfat: fix qemu-img map and qemu-img convert Hervé Poussineau
                   ` (14 more replies)
  0 siblings, 15 replies; 29+ messages in thread
From: Hervé Poussineau @ 2017-05-22 21:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kevin Wolf, Max Reitz, qemu-block, Hervé Poussineau

Hi,

This patchset fixes some of issues I encountered when trying to use vvfat, and fixes
bug #1599539: https://bugs.launchpad.net/qemu/+bug/1599539

Patch 1 fixes a crash when using 'qemu-img convert'.
Patches 2 to 6 are code cleanup. No functionnal changes.
Patches 7 to 13 fix problems detected by disk checking utilities in read-only mode.

With these patches, vvfat creates valid FAT volumes and can be used with QEMU disk utilities.

Read-write mode is still buggy after this patchset, but at least, I was not
able to crash QEMU anymore.

Note that patch 2 doesn't pass checkpatch.pl, as it changes indentation only.

Hervé

Changes v1->v2:
- small changes following Kevin remarks (patches 3, 5, 6)
- use g_utf8_* functions instead of ad-hock code (patches 8 and 9)
- fix a bug with filenames starting with a dot (patch 9)

Hervé Poussineau (13):
  vvfat: fix qemu-img map and qemu-img convert
  vvfat: replace tabs by 8 spaces
  vvfat: fix typos
  vvfat: rename useless enumeration values
  vvfat: introduce offset_to_bootsector, offset_to_fat and
    offset_to_root_dir
  vvfat: fix field names in FAT12/FAT16 and FAT32 boot sectors
  vvfat: always create . and .. entries at first and in that order
  vvfat: correctly create long names for non-ASCII filenames
  vvfat: correctly create base short names for non-ASCII filenames
  vvfat: correctly generate numeric-tail of short file names
  vvfat: limit number of entries in root directory in FAT12/FAT16
  vvfat: handle KANJI lead byte 0xe5
  vvfat: change OEM name to 'MSWIN4.1'

 block/vvfat.c | 2306 ++++++++++++++++++++++++++++++---------------------------
 1 file changed, 1198 insertions(+), 1108 deletions(-)

-- 
2.11.0

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH v2 01/13] vvfat: fix qemu-img map and qemu-img convert
  2017-05-22 21:11 [Qemu-devel] [PATCH v2 00/13] vvfat: misc fixes for read-only mode Hervé Poussineau
@ 2017-05-22 21:11 ` Hervé Poussineau
  2017-05-22 21:17   ` [Qemu-devel] [Qemu-block] " Eric Blake
  2017-05-22 21:11 ` [Qemu-devel] [PATCH v2 02/13] vvfat: replace tabs by 8 spaces Hervé Poussineau
                   ` (13 subsequent siblings)
  14 siblings, 1 reply; 29+ messages in thread
From: Hervé Poussineau @ 2017-05-22 21:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kevin Wolf, Max Reitz, qemu-block, Hervé Poussineau

- bs->total_sectors is the number of sectors of the whole disk
- s->sector_count is the number of sectors of the FAT partition

This fixes the following assert in qemu-img map:
qemu-img.c:2641: get_block_status: Assertion `nb_sectors' failed.

This also fixes an infinite loop in qemu-img convert.

Fixes: 4480e0f924a42e1db8b8cfcac4d0634dd1bb27a0
Fixes: https://bugs.launchpad.net/qemu/+bug/1599539
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
---
 block/vvfat.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/block/vvfat.c b/block/vvfat.c
index 9c82371360..df24091bf6 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -2969,8 +2969,7 @@ vvfat_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
 static int64_t coroutine_fn vvfat_co_get_block_status(BlockDriverState *bs,
 	int64_t sector_num, int nb_sectors, int *n, BlockDriverState **file)
 {
-    BDRVVVFATState* s = bs->opaque;
-    *n = s->sector_count - sector_num;
+    *n = bs->total_sectors - sector_num;
     if (*n > nb_sectors) {
         *n = nb_sectors;
     } else if (*n < 0) {
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH v2 02/13] vvfat: replace tabs by 8 spaces
  2017-05-22 21:11 [Qemu-devel] [PATCH v2 00/13] vvfat: misc fixes for read-only mode Hervé Poussineau
  2017-05-22 21:11 ` [Qemu-devel] [PATCH v2 01/13] vvfat: fix qemu-img map and qemu-img convert Hervé Poussineau
@ 2017-05-22 21:11 ` Hervé Poussineau
  2017-05-22 21:11 ` [Qemu-devel] [PATCH v2 03/13] vvfat: fix typos Hervé Poussineau
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 29+ messages in thread
From: Hervé Poussineau @ 2017-05-22 21:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kevin Wolf, Max Reitz, qemu-block, Hervé Poussineau

This was a complete mess. On 2299 indented lines:
- 1329 were with spaces only
- 617 with tabulations only
- 353 with spaces and tabulations

Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
---
 block/vvfat.c | 2054 ++++++++++++++++++++++++++++-----------------------------
 1 file changed, 1027 insertions(+), 1027 deletions(-)

diff --git a/block/vvfat.c b/block/vvfat.c
index df24091bf6..d3afb731b6 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -101,12 +101,12 @@ static inline void* array_get(array_t* array,unsigned int index) {
 static inline int array_ensure_allocated(array_t* array, int index)
 {
     if((index + 1) * array->item_size > array->size) {
-	int new_size = (index + 32) * array->item_size;
-	array->pointer = g_realloc(array->pointer, new_size);
-	if (!array->pointer)
-	    return -1;
-	array->size = new_size;
-	array->next = index + 1;
+        int new_size = (index + 32) * array->item_size;
+        array->pointer = g_realloc(array->pointer, new_size);
+        if (!array->pointer)
+            return -1;
+        array->size = new_size;
+        array->next = index + 1;
     }
 
     return 0;
@@ -116,7 +116,7 @@ static inline void* array_get_next(array_t* array) {
     unsigned int next = array->next;
 
     if (array_ensure_allocated(array, next) < 0)
-	return NULL;
+        return NULL;
 
     array->next = next + 1;
     return array_get(array, next);
@@ -124,15 +124,15 @@ static inline void* array_get_next(array_t* array) {
 
 static inline void* array_insert(array_t* array,unsigned int index,unsigned int count) {
     if((array->next+count)*array->item_size>array->size) {
-	int increment=count*array->item_size;
-	array->pointer=g_realloc(array->pointer,array->size+increment);
-	if(!array->pointer)
+        int increment=count*array->item_size;
+        array->pointer=g_realloc(array->pointer,array->size+increment);
+        if(!array->pointer)
             return NULL;
-	array->size+=increment;
+        array->size+=increment;
     }
     memmove(array->pointer+(index+count)*array->item_size,
-		array->pointer+index*array->item_size,
-		(array->next-index)*array->item_size);
+                array->pointer+index*array->item_size,
+                (array->next-index)*array->item_size);
     array->next+=count;
     return array->pointer+index*array->item_size;
 }
@@ -147,12 +147,12 @@ static inline int array_roll(array_t* array,int index_to,int index_from,int coun
     int is;
 
     if(!array ||
-	    index_to<0 || index_to>=array->next ||
-	    index_from<0 || index_from>=array->next)
-	return -1;
+            index_to<0 || index_to>=array->next ||
+            index_from<0 || index_from>=array->next)
+        return -1;
 
     if(index_to==index_from)
-	return 0;
+        return 0;
 
     is=array->item_size;
     from=array->pointer+index_from*is;
@@ -161,9 +161,9 @@ static inline int array_roll(array_t* array,int index_to,int index_from,int coun
     memcpy(buf,from,is*count);
 
     if(index_to<index_from)
-	memmove(to+is*count,to,from-to);
+        memmove(to+is*count,to,from-to);
     else
-	memmove(from,from+is*count,to-from);
+        memmove(from,from+is*count,to-from);
 
     memcpy(to,buf,is*count);
 
@@ -178,7 +178,7 @@ static inline int array_remove_slice(array_t* array,int index, int count)
     assert(count > 0);
     assert(index + count <= array->next);
     if(array_roll(array,array->next-1,index,count))
-	return -1;
+        return -1;
     array->next -= count;
     return 0;
 }
@@ -217,21 +217,21 @@ typedef struct bootsector_t {
     uint32_t total_sectors;
     union {
         struct {
-	    uint8_t drive_number;
-	    uint8_t current_head;
-	    uint8_t signature;
-	    uint32_t id;
-	    uint8_t volume_label[11];
-	} QEMU_PACKED fat16;
-	struct {
-	    uint32_t sectors_per_fat;
-	    uint16_t flags;
-	    uint8_t major,minor;
-	    uint32_t first_cluster_of_root_directory;
-	    uint16_t info_sector;
-	    uint16_t backup_boot_sector;
-	    uint16_t ignored;
-	} QEMU_PACKED fat32;
+            uint8_t drive_number;
+            uint8_t current_head;
+            uint8_t signature;
+            uint32_t id;
+            uint8_t volume_label[11];
+        } QEMU_PACKED fat16;
+        struct {
+            uint32_t sectors_per_fat;
+            uint16_t flags;
+            uint8_t major,minor;
+            uint32_t first_cluster_of_root_directory;
+            uint16_t info_sector;
+            uint16_t backup_boot_sector;
+            uint16_t ignored;
+        } QEMU_PACKED fat32;
     } u;
     uint8_t fat_type[8];
     uint8_t ignored[0x1c0];
@@ -285,25 +285,25 @@ typedef struct mapping_t {
     /* the clusters of a file may be in any order; this points to the first */
     int first_mapping_index;
     union {
-	/* offset is
-	 * - the offset in the file (in clusters) for a file, or
-	 * - the next cluster of the directory for a directory, and
-	 * - the address of the buffer for a faked entry
-	 */
-	struct {
-	    uint32_t offset;
-	} file;
-	struct {
-	    int parent_mapping_index;
-	    int first_dir_index;
-	} dir;
+        /* offset is
+         * - the offset in the file (in clusters) for a file, or
+         * - the next cluster of the directory for a directory, and
+         * - the address of the buffer for a faked entry
+         */
+        struct {
+            uint32_t offset;
+        } file;
+        struct {
+            int parent_mapping_index;
+            int first_dir_index;
+        } dir;
     } info;
     /* path contains the full path, i.e. it always starts with s->path */
     char* path;
 
     enum { MODE_UNDEFINED = 0, MODE_NORMAL = 1, MODE_MODIFIED = 2,
-	MODE_DIRECTORY = 4, MODE_FAKED = 8,
-	MODE_DELETED = 16, MODE_RENAMED = 32 } mode;
+        MODE_DIRECTORY = 4, MODE_FAKED = 8,
+        MODE_DELETED = 16, MODE_RENAMED = 32 } mode;
     int read_only;
 } mapping_t;
 
@@ -420,12 +420,12 @@ static inline int short2long_name(char* dest,const char* src)
     int len;
     for(i=0;i<129 && src[i];i++) {
         dest[2*i]=src[i];
-	dest[2*i+1]=0;
+        dest[2*i+1]=0;
     }
     len=2*i;
     dest[2*i]=dest[2*i+1]=0;
     for(i=2*i+2;(i%26);i++)
-	dest[i]=0xff;
+        dest[i]=0xff;
     return len;
 }
 
@@ -437,19 +437,19 @@ static inline direntry_t* create_long_filename(BDRVVVFATState* s,const char* fil
     direntry_t* entry;
 
     for(i=0;i<number_of_entries;i++) {
-	entry=array_get_next(&(s->directory));
-	entry->attributes=0xf;
-	entry->reserved[0]=0;
-	entry->begin=0;
-	entry->name[0]=(number_of_entries-i)|(i==0?0x40:0);
+        entry=array_get_next(&(s->directory));
+        entry->attributes=0xf;
+        entry->reserved[0]=0;
+        entry->begin=0;
+        entry->name[0]=(number_of_entries-i)|(i==0?0x40:0);
     }
     for(i=0;i<26*number_of_entries;i++) {
-	int offset=(i%26);
-	if(offset<10) offset=1+offset;
-	else if(offset<22) offset=14+offset-10;
-	else offset=28+offset-22;
-	entry=array_get(&(s->directory),s->directory.next-1-(i/26));
-	entry->name[offset]=buffer[i];
+        int offset=(i%26);
+        if(offset<10) offset=1+offset;
+        else if(offset<22) offset=14+offset-10;
+        else offset=28+offset-22;
+        entry=array_get(&(s->directory),s->directory.next-1-(i/26));
+        entry->name[offset]=buffer[i];
     }
     return array_get(&(s->directory),s->directory.next-number_of_entries);
 }
@@ -472,7 +472,7 @@ static char is_long_name(const direntry_t* direntry)
 static char is_short_name(const direntry_t* direntry)
 {
     return !is_volume_label(direntry) && !is_long_name(direntry)
-	&& !is_free(direntry);
+        && !is_free(direntry);
 }
 
 static char is_directory(const direntry_t* direntry)
@@ -528,73 +528,73 @@ static uint16_t fat_datetime(time_t time,int return_time) {
     t = &t1;
     localtime_r(&time,t);
     if(return_time)
-	return cpu_to_le16((t->tm_sec/2)|(t->tm_min<<5)|(t->tm_hour<<11));
+        return cpu_to_le16((t->tm_sec/2)|(t->tm_min<<5)|(t->tm_hour<<11));
     return cpu_to_le16((t->tm_mday)|((t->tm_mon+1)<<5)|((t->tm_year-80)<<9));
 }
 
 static inline void fat_set(BDRVVVFATState* s,unsigned int cluster,uint32_t value)
 {
     if(s->fat_type==32) {
-	uint32_t* entry=array_get(&(s->fat),cluster);
-	*entry=cpu_to_le32(value);
+        uint32_t* entry=array_get(&(s->fat),cluster);
+        *entry=cpu_to_le32(value);
     } else if(s->fat_type==16) {
-	uint16_t* entry=array_get(&(s->fat),cluster);
-	*entry=cpu_to_le16(value&0xffff);
+        uint16_t* entry=array_get(&(s->fat),cluster);
+        *entry=cpu_to_le16(value&0xffff);
     } else {
-	int offset = (cluster*3/2);
-	unsigned char* p = array_get(&(s->fat), offset);
+        int offset = (cluster*3/2);
+        unsigned char* p = array_get(&(s->fat), offset);
         switch (cluster&1) {
-	case 0:
-		p[0] = value&0xff;
-		p[1] = (p[1]&0xf0) | ((value>>8)&0xf);
-		break;
-	case 1:
-		p[0] = (p[0]&0xf) | ((value&0xf)<<4);
-		p[1] = (value>>4);
-		break;
-	}
+        case 0:
+                p[0] = value&0xff;
+                p[1] = (p[1]&0xf0) | ((value>>8)&0xf);
+                break;
+        case 1:
+                p[0] = (p[0]&0xf) | ((value&0xf)<<4);
+                p[1] = (value>>4);
+                break;
+        }
     }
 }
 
 static inline uint32_t fat_get(BDRVVVFATState* s,unsigned int cluster)
 {
     if(s->fat_type==32) {
-	uint32_t* entry=array_get(&(s->fat),cluster);
-	return le32_to_cpu(*entry);
+        uint32_t* entry=array_get(&(s->fat),cluster);
+        return le32_to_cpu(*entry);
     } else if(s->fat_type==16) {
-	uint16_t* entry=array_get(&(s->fat),cluster);
-	return le16_to_cpu(*entry);
+        uint16_t* entry=array_get(&(s->fat),cluster);
+        return le16_to_cpu(*entry);
     } else {
-	const uint8_t* x=(uint8_t*)(s->fat.pointer)+cluster*3/2;
-	return ((x[0]|(x[1]<<8))>>(cluster&1?4:0))&0x0fff;
+        const uint8_t* x=(uint8_t*)(s->fat.pointer)+cluster*3/2;
+        return ((x[0]|(x[1]<<8))>>(cluster&1?4:0))&0x0fff;
     }
 }
 
 static inline int fat_eof(BDRVVVFATState* s,uint32_t fat_entry)
 {
     if(fat_entry>s->max_fat_value-8)
-	return -1;
+        return -1;
     return 0;
 }
 
 static inline void init_fat(BDRVVVFATState* s)
 {
     if (s->fat_type == 12) {
-	array_init(&(s->fat),1);
-	array_ensure_allocated(&(s->fat),
-		s->sectors_per_fat * 0x200 * 3 / 2 - 1);
+        array_init(&(s->fat),1);
+        array_ensure_allocated(&(s->fat),
+                s->sectors_per_fat * 0x200 * 3 / 2 - 1);
     } else {
-	array_init(&(s->fat),(s->fat_type==32?4:2));
-	array_ensure_allocated(&(s->fat),
-		s->sectors_per_fat * 0x200 / s->fat.item_size - 1);
+        array_init(&(s->fat),(s->fat_type==32?4:2));
+        array_ensure_allocated(&(s->fat),
+                s->sectors_per_fat * 0x200 / s->fat.item_size - 1);
     }
     memset(s->fat.pointer,0,s->fat.size);
 
     switch(s->fat_type) {
-	case 12: s->max_fat_value=0xfff; break;
-	case 16: s->max_fat_value=0xffff; break;
-	case 32: s->max_fat_value=0x0fffffff; break;
-	default: s->max_fat_value=0; /* error... */
+        case 12: s->max_fat_value=0xfff; break;
+        case 16: s->max_fat_value=0xffff; break;
+        case 32: s->max_fat_value=0x0fffffff; break;
+        default: s->max_fat_value=0; /* error... */
     }
 
 }
@@ -602,17 +602,17 @@ static inline void init_fat(BDRVVVFATState* s)
 /* TODO: in create_short_filename, 0xe5->0x05 is not yet handled! */
 /* TODO: in parse_short_filename, 0x05->0xe5 is not yet handled! */
 static inline direntry_t* create_short_and_long_name(BDRVVVFATState* s,
-	unsigned int directory_start, const char* filename, int is_dot)
+        unsigned int directory_start, const char* filename, int is_dot)
 {
     int i,j,long_index=s->directory.next;
     direntry_t* entry = NULL;
     direntry_t* entry_long = NULL;
 
     if(is_dot) {
-	entry=array_get_next(&(s->directory));
+        entry=array_get_next(&(s->directory));
         memset(entry->name, 0x20, sizeof(entry->name));
-	memcpy(entry->name,filename,strlen(filename));
-	return entry;
+        memcpy(entry->name,filename,strlen(filename));
+        return entry;
     }
 
     entry_long=create_long_filename(s,filename);
@@ -620,9 +620,9 @@ static inline direntry_t* create_short_and_long_name(BDRVVVFATState* s,
     i = strlen(filename);
     for(j = i - 1; j>0  && filename[j]!='.';j--);
     if (j > 0)
-	i = (j > 8 ? 8 : j);
+        i = (j > 8 ? 8 : j);
     else if (i > 8)
-	i = 8;
+        i = 8;
 
     entry=array_get_next(&(s->directory));
     memset(entry->name, 0x20, sizeof(entry->name));
@@ -636,53 +636,53 @@ static inline direntry_t* create_short_and_long_name(BDRVVVFATState* s,
 
     /* upcase & remove unwanted characters */
     for(i=10;i>=0;i--) {
-	if(i==10 || i==7) for(;i>0 && entry->name[i]==' ';i--);
-	if(entry->name[i]<=' ' || entry->name[i]>0x7f
-		|| strchr(".*?<>|\":/\\[];,+='",entry->name[i]))
-	    entry->name[i]='_';
+        if(i==10 || i==7) for(;i>0 && entry->name[i]==' ';i--);
+        if(entry->name[i]<=' ' || entry->name[i]>0x7f
+                || strchr(".*?<>|\":/\\[];,+='",entry->name[i]))
+            entry->name[i]='_';
         else if(entry->name[i]>='a' && entry->name[i]<='z')
             entry->name[i]+='A'-'a';
     }
 
     /* mangle duplicates */
     while(1) {
-	direntry_t* entry1=array_get(&(s->directory),directory_start);
-	int j;
-
-	for(;entry1<entry;entry1++)
-	    if(!is_long_name(entry1) && !memcmp(entry1->name,entry->name,11))
-		break; /* found dupe */
-	if(entry1==entry) /* no dupe found */
-	    break;
-
-	/* use all 8 characters of name */
-	if(entry->name[7]==' ') {
-	    int j;
-	    for(j=6;j>0 && entry->name[j]==' ';j--)
-		entry->name[j]='~';
-	}
-
-	/* increment number */
-	for(j=7;j>0 && entry->name[j]=='9';j--)
-	    entry->name[j]='0';
-	if(j>0) {
-	    if(entry->name[j]<'0' || entry->name[j]>'9')
-	        entry->name[j]='0';
-	    else
-	        entry->name[j]++;
-	}
+        direntry_t* entry1=array_get(&(s->directory),directory_start);
+        int j;
+
+        for(;entry1<entry;entry1++)
+            if(!is_long_name(entry1) && !memcmp(entry1->name,entry->name,11))
+                break; /* found dupe */
+        if(entry1==entry) /* no dupe found */
+            break;
+
+        /* use all 8 characters of name */
+        if(entry->name[7]==' ') {
+            int j;
+            for(j=6;j>0 && entry->name[j]==' ';j--)
+                entry->name[j]='~';
+        }
+
+        /* increment number */
+        for(j=7;j>0 && entry->name[j]=='9';j--)
+            entry->name[j]='0';
+        if(j>0) {
+            if(entry->name[j]<'0' || entry->name[j]>'9')
+                entry->name[j]='0';
+            else
+                entry->name[j]++;
+        }
     }
 
     /* calculate checksum; propagate to long name */
     if(entry_long) {
         uint8_t chksum=fat_chksum(entry);
 
-	/* calculate anew, because realloc could have taken place */
-	entry_long=array_get(&(s->directory),long_index);
-	while(entry_long<entry && is_long_name(entry_long)) {
-	    entry_long->reserved[1]=chksum;
-	    entry_long++;
-	}
+        /* calculate anew, because realloc could have taken place */
+        entry_long=array_get(&(s->directory),long_index);
+        while(entry_long<entry && is_long_name(entry_long)) {
+            entry_long->reserved[1]=chksum;
+            entry_long++;
+        }
     }
 
     return entry;
@@ -709,80 +709,80 @@ static int read_directory(BDRVVVFATState* s, int mapping_index)
     assert(mapping->mode & MODE_DIRECTORY);
 
     if(!dir) {
-	mapping->end = mapping->begin;
-	return -1;
+        mapping->end = mapping->begin;
+        return -1;
     }
 
     i = mapping->info.dir.first_dir_index =
-	    first_cluster == 0 ? 0 : s->directory.next;
+            first_cluster == 0 ? 0 : s->directory.next;
 
     /* actually read the directory, and allocate the mappings */
     while((entry=readdir(dir))) {
-	unsigned int length=strlen(dirname)+2+strlen(entry->d_name);
+        unsigned int length=strlen(dirname)+2+strlen(entry->d_name);
         char* buffer;
-	direntry_t* direntry;
+        direntry_t* direntry;
         struct stat st;
-	int is_dot=!strcmp(entry->d_name,".");
-	int is_dotdot=!strcmp(entry->d_name,"..");
+        int is_dot=!strcmp(entry->d_name,".");
+        int is_dotdot=!strcmp(entry->d_name,"..");
 
-	if(first_cluster == 0 && (is_dotdot || is_dot))
-	    continue;
+        if(first_cluster == 0 && (is_dotdot || is_dot))
+            continue;
 
-	buffer = g_malloc(length);
-	snprintf(buffer,length,"%s/%s",dirname,entry->d_name);
+        buffer = g_malloc(length);
+        snprintf(buffer,length,"%s/%s",dirname,entry->d_name);
 
-	if(stat(buffer,&st)<0) {
+        if(stat(buffer,&st)<0) {
             g_free(buffer);
             continue;
-	}
-
-	/* create directory entry for this file */
-	direntry=create_short_and_long_name(s, i, entry->d_name,
-		is_dot || is_dotdot);
-	direntry->attributes=(S_ISDIR(st.st_mode)?0x10:0x20);
-	direntry->reserved[0]=direntry->reserved[1]=0;
-	direntry->ctime=fat_datetime(st.st_ctime,1);
-	direntry->cdate=fat_datetime(st.st_ctime,0);
-	direntry->adate=fat_datetime(st.st_atime,0);
-	direntry->begin_hi=0;
-	direntry->mtime=fat_datetime(st.st_mtime,1);
-	direntry->mdate=fat_datetime(st.st_mtime,0);
-	if(is_dotdot)
-	    set_begin_of_direntry(direntry, first_cluster_of_parent);
-	else if(is_dot)
-	    set_begin_of_direntry(direntry, first_cluster);
-	else
-	    direntry->begin=0; /* do that later */
+        }
+
+        /* create directory entry for this file */
+        direntry=create_short_and_long_name(s, i, entry->d_name,
+                is_dot || is_dotdot);
+        direntry->attributes=(S_ISDIR(st.st_mode)?0x10:0x20);
+        direntry->reserved[0]=direntry->reserved[1]=0;
+        direntry->ctime=fat_datetime(st.st_ctime,1);
+        direntry->cdate=fat_datetime(st.st_ctime,0);
+        direntry->adate=fat_datetime(st.st_atime,0);
+        direntry->begin_hi=0;
+        direntry->mtime=fat_datetime(st.st_mtime,1);
+        direntry->mdate=fat_datetime(st.st_mtime,0);
+        if(is_dotdot)
+            set_begin_of_direntry(direntry, first_cluster_of_parent);
+        else if(is_dot)
+            set_begin_of_direntry(direntry, first_cluster);
+        else
+            direntry->begin=0; /* do that later */
         if (st.st_size > 0x7fffffff) {
-	    fprintf(stderr, "File %s is larger than 2GB\n", buffer);
+            fprintf(stderr, "File %s is larger than 2GB\n", buffer);
             g_free(buffer);
             closedir(dir);
-	    return -2;
+            return -2;
         }
-	direntry->size=cpu_to_le32(S_ISDIR(st.st_mode)?0:st.st_size);
-
-	/* create mapping for this file */
-	if(!is_dot && !is_dotdot && (S_ISDIR(st.st_mode) || st.st_size)) {
-	    s->current_mapping = array_get_next(&(s->mapping));
-	    s->current_mapping->begin=0;
-	    s->current_mapping->end=st.st_size;
-	    /*
-	     * we get the direntry of the most recent direntry, which
-	     * contains the short name and all the relevant information.
-	     */
-	    s->current_mapping->dir_index=s->directory.next-1;
-	    s->current_mapping->first_mapping_index = -1;
-	    if (S_ISDIR(st.st_mode)) {
-		s->current_mapping->mode = MODE_DIRECTORY;
-		s->current_mapping->info.dir.parent_mapping_index =
-		    mapping_index;
-	    } else {
-		s->current_mapping->mode = MODE_UNDEFINED;
-		s->current_mapping->info.file.offset = 0;
-	    }
-	    s->current_mapping->path=buffer;
-	    s->current_mapping->read_only =
-		(st.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)) == 0;
+        direntry->size=cpu_to_le32(S_ISDIR(st.st_mode)?0:st.st_size);
+
+        /* create mapping for this file */
+        if(!is_dot && !is_dotdot && (S_ISDIR(st.st_mode) || st.st_size)) {
+            s->current_mapping = array_get_next(&(s->mapping));
+            s->current_mapping->begin=0;
+            s->current_mapping->end=st.st_size;
+            /*
+             * we get the direntry of the most recent direntry, which
+             * contains the short name and all the relevant information.
+             */
+            s->current_mapping->dir_index=s->directory.next-1;
+            s->current_mapping->first_mapping_index = -1;
+            if (S_ISDIR(st.st_mode)) {
+                s->current_mapping->mode = MODE_DIRECTORY;
+                s->current_mapping->info.dir.parent_mapping_index =
+                    mapping_index;
+            } else {
+                s->current_mapping->mode = MODE_UNDEFINED;
+                s->current_mapping->info.file.offset = 0;
+            }
+            s->current_mapping->path=buffer;
+            s->current_mapping->read_only =
+                (st.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)) == 0;
         } else {
             g_free(buffer);
         }
@@ -791,25 +791,25 @@ static int read_directory(BDRVVVFATState* s, int mapping_index)
 
     /* fill with zeroes up to the end of the cluster */
     while(s->directory.next%(0x10*s->sectors_per_cluster)) {
-	direntry_t* direntry=array_get_next(&(s->directory));
-	memset(direntry,0,sizeof(direntry_t));
+        direntry_t* direntry=array_get_next(&(s->directory));
+        memset(direntry,0,sizeof(direntry_t));
     }
 
 /* TODO: if there are more entries, bootsector has to be adjusted! */
 #define ROOT_ENTRIES (0x02 * 0x10 * s->sectors_per_cluster)
     if (mapping_index == 0 && s->directory.next < ROOT_ENTRIES) {
-	/* root directory */
-	int cur = s->directory.next;
-	array_ensure_allocated(&(s->directory), ROOT_ENTRIES - 1);
-	s->directory.next = ROOT_ENTRIES;
-	memset(array_get(&(s->directory), cur), 0,
-		(ROOT_ENTRIES - cur) * sizeof(direntry_t));
+        /* root directory */
+        int cur = s->directory.next;
+        array_ensure_allocated(&(s->directory), ROOT_ENTRIES - 1);
+        s->directory.next = ROOT_ENTRIES;
+        memset(array_get(&(s->directory), cur), 0,
+                (ROOT_ENTRIES - cur) * sizeof(direntry_t));
     }
 
      /* reget the mapping, since s->mapping was possibly realloc()ed */
     mapping = array_get(&(s->mapping), mapping_index);
     first_cluster += (s->directory.next - mapping->info.dir.first_dir_index)
-	* 0x20 / s->cluster_size;
+        * 0x20 / s->cluster_size;
     mapping->end = first_cluster;
 
     direntry = array_get(&(s->directory), mapping->dir_index);
@@ -857,8 +857,8 @@ static int init_directories(BDRVVVFATState* s,
 
     /* add volume label */
     {
-	direntry_t* entry=array_get_next(&(s->directory));
-	entry->attributes=0x28; /* archive | volume label */
+        direntry_t* entry=array_get_next(&(s->directory));
+        entry->attributes=0x28; /* archive | volume label */
         memcpy(entry->name, s->volume_label, sizeof(entry->name));
     }
 
@@ -876,61 +876,61 @@ static int init_directories(BDRVVVFATState* s,
     mapping->path = g_strdup(dirname);
     i = strlen(mapping->path);
     if (i > 0 && mapping->path[i - 1] == '/')
-	mapping->path[i - 1] = '\0';
+        mapping->path[i - 1] = '\0';
     mapping->mode = MODE_DIRECTORY;
     mapping->read_only = 0;
     s->path = mapping->path;
 
     for (i = 0, cluster = 0; i < s->mapping.next; i++) {
-	/* MS-DOS expects the FAT to be 0 for the root directory
-	 * (except for the media byte). */
-	/* LATER TODO: still true for FAT32? */
-	int fix_fat = (i != 0);
-	mapping = array_get(&(s->mapping), i);
+        /* MS-DOS expects the FAT to be 0 for the root directory
+         * (except for the media byte). */
+        /* LATER TODO: still true for FAT32? */
+        int fix_fat = (i != 0);
+        mapping = array_get(&(s->mapping), i);
 
         if (mapping->mode & MODE_DIRECTORY) {
-	    mapping->begin = cluster;
-	    if(read_directory(s, i)) {
+            mapping->begin = cluster;
+            if(read_directory(s, i)) {
                 error_setg(errp, "Could not read directory %s",
                            mapping->path);
-		return -1;
-	    }
-	    mapping = array_get(&(s->mapping), i);
-	} else {
-	    assert(mapping->mode == MODE_UNDEFINED);
-	    mapping->mode=MODE_NORMAL;
-	    mapping->begin = cluster;
-	    if (mapping->end > 0) {
-		direntry_t* direntry = array_get(&(s->directory),
-			mapping->dir_index);
-
-		mapping->end = cluster + 1 + (mapping->end-1)/s->cluster_size;
-		set_begin_of_direntry(direntry, mapping->begin);
-	    } else {
-		mapping->end = cluster + 1;
-		fix_fat = 0;
-	    }
-	}
-
-	assert(mapping->begin < mapping->end);
-
-	/* next free cluster */
-	cluster = mapping->end;
-
-	if(cluster > s->cluster_count) {
+                return -1;
+            }
+            mapping = array_get(&(s->mapping), i);
+        } else {
+            assert(mapping->mode == MODE_UNDEFINED);
+            mapping->mode=MODE_NORMAL;
+            mapping->begin = cluster;
+            if (mapping->end > 0) {
+                direntry_t* direntry = array_get(&(s->directory),
+                        mapping->dir_index);
+
+                mapping->end = cluster + 1 + (mapping->end-1)/s->cluster_size;
+                set_begin_of_direntry(direntry, mapping->begin);
+            } else {
+                mapping->end = cluster + 1;
+                fix_fat = 0;
+            }
+        }
+
+        assert(mapping->begin < mapping->end);
+
+        /* next free cluster */
+        cluster = mapping->end;
+
+        if(cluster > s->cluster_count) {
             error_setg(errp,
                        "Directory does not fit in FAT%d (capacity %.2f MB)",
                        s->fat_type, s->sector_count / 2000.0);
             return -1;
-	}
+        }
 
-	/* fix fat for entry */
-	if (fix_fat) {
-	    int j;
-	    for(j = mapping->begin; j < mapping->end - 1; j++)
-		fat_set(s, j, j+1);
-	    fat_set(s, mapping->end - 1, s->max_fat_value);
-	}
+        /* fix fat for entry */
+        if (fix_fat) {
+            int j;
+            for(j = mapping->begin; j < mapping->end - 1; j++)
+                fat_set(s, j, j+1);
+            fat_set(s, mapping->end - 1, s->max_fat_value);
+        }
     }
 
     mapping = array_get(&(s->mapping), 0);
@@ -1136,7 +1136,7 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
 
     switch (s->fat_type) {
     case 32:
-	    fprintf(stderr, "Big fat greek warning: FAT32 has not been tested. "
+            fprintf(stderr, "Big fat greek warning: FAT32 has not been tested. "
                 "You are welcome to do so!\n");
         break;
     case 16:
@@ -1230,11 +1230,11 @@ static void vvfat_refresh_limits(BlockDriverState *bs, Error **errp)
 static inline void vvfat_close_current_file(BDRVVVFATState *s)
 {
     if(s->current_mapping) {
-	s->current_mapping = NULL;
-	if (s->current_fd) {
-		qemu_close(s->current_fd);
-		s->current_fd = 0;
-	}
+        s->current_mapping = NULL;
+        if (s->current_fd) {
+                qemu_close(s->current_fd);
+                s->current_fd = 0;
+        }
     }
     s->current_cluster = -1;
 }
@@ -1246,26 +1246,26 @@ static inline int find_mapping_for_cluster_aux(BDRVVVFATState* s,int cluster_num
 {
     while(1) {
         int index3;
-	mapping_t* mapping;
-	index3=(index1+index2)/2;
-	mapping=array_get(&(s->mapping),index3);
-	assert(mapping->begin < mapping->end);
-	if(mapping->begin>=cluster_num) {
-	    assert(index2!=index3 || index2==0);
-	    if(index2==index3)
-		return index1;
-	    index2=index3;
-	} else {
-	    if(index1==index3)
-		return mapping->end<=cluster_num ? index2 : index1;
-	    index1=index3;
-	}
-	assert(index1<=index2);
-	DLOG(mapping=array_get(&(s->mapping),index1);
-	assert(mapping->begin<=cluster_num);
-	assert(index2 >= s->mapping.next ||
-		((mapping = array_get(&(s->mapping),index2)) &&
-		mapping->end>cluster_num)));
+        mapping_t* mapping;
+        index3=(index1+index2)/2;
+        mapping=array_get(&(s->mapping),index3);
+        assert(mapping->begin < mapping->end);
+        if(mapping->begin>=cluster_num) {
+            assert(index2!=index3 || index2==0);
+            if(index2==index3)
+                return index1;
+            index2=index3;
+        } else {
+            if(index1==index3)
+                return mapping->end<=cluster_num ? index2 : index1;
+            index1=index3;
+        }
+        assert(index1<=index2);
+        DLOG(mapping=array_get(&(s->mapping),index1);
+        assert(mapping->begin<=cluster_num);
+        assert(index2 >= s->mapping.next ||
+                ((mapping = array_get(&(s->mapping),index2)) &&
+                mapping->end>cluster_num)));
     }
 }
 
@@ -1285,16 +1285,16 @@ static inline mapping_t* find_mapping_for_cluster(BDRVVVFATState* s,int cluster_
 static int open_file(BDRVVVFATState* s,mapping_t* mapping)
 {
     if(!mapping)
-	return -1;
+        return -1;
     if(!s->current_mapping ||
-	    strcmp(s->current_mapping->path,mapping->path)) {
-	/* open file */
-	int fd = qemu_open(mapping->path, O_RDONLY | O_BINARY | O_LARGEFILE);
-	if(fd<0)
-	    return -1;
-	vvfat_close_current_file(s);
-	s->current_fd = fd;
-	s->current_mapping = mapping;
+            strcmp(s->current_mapping->path,mapping->path)) {
+        /* open file */
+        int fd = qemu_open(mapping->path, O_RDONLY | O_BINARY | O_LARGEFILE);
+        if(fd<0)
+            return -1;
+        vvfat_close_current_file(s);
+        s->current_fd = fd;
+        s->current_mapping = mapping;
     }
     return 0;
 }
@@ -1302,47 +1302,47 @@ static int open_file(BDRVVVFATState* s,mapping_t* mapping)
 static inline int read_cluster(BDRVVVFATState *s,int cluster_num)
 {
     if(s->current_cluster != cluster_num) {
-	int result=0;
-	off_t offset;
-	assert(!s->current_mapping || s->current_fd || (s->current_mapping->mode & MODE_DIRECTORY));
-	if(!s->current_mapping
-		|| s->current_mapping->begin>cluster_num
-		|| s->current_mapping->end<=cluster_num) {
-	    /* binary search of mappings for file */
-	    mapping_t* mapping=find_mapping_for_cluster(s,cluster_num);
-
-	    assert(!mapping || (cluster_num>=mapping->begin && cluster_num<mapping->end));
-
-	    if (mapping && mapping->mode & MODE_DIRECTORY) {
-		vvfat_close_current_file(s);
-		s->current_mapping = mapping;
+        int result=0;
+        off_t offset;
+        assert(!s->current_mapping || s->current_fd || (s->current_mapping->mode & MODE_DIRECTORY));
+        if(!s->current_mapping
+                || s->current_mapping->begin>cluster_num
+                || s->current_mapping->end<=cluster_num) {
+            /* binary search of mappings for file */
+            mapping_t* mapping=find_mapping_for_cluster(s,cluster_num);
+
+            assert(!mapping || (cluster_num>=mapping->begin && cluster_num<mapping->end));
+
+            if (mapping && mapping->mode & MODE_DIRECTORY) {
+                vvfat_close_current_file(s);
+                s->current_mapping = mapping;
 read_cluster_directory:
-		offset = s->cluster_size*(cluster_num-s->current_mapping->begin);
-		s->cluster = (unsigned char*)s->directory.pointer+offset
-			+ 0x20*s->current_mapping->info.dir.first_dir_index;
-		assert(((s->cluster-(unsigned char*)s->directory.pointer)%s->cluster_size)==0);
-		assert((char*)s->cluster+s->cluster_size <= s->directory.pointer+s->directory.next*s->directory.item_size);
-		s->current_cluster = cluster_num;
-		return 0;
-	    }
-
-	    if(open_file(s,mapping))
-		return -2;
-	} else if (s->current_mapping->mode & MODE_DIRECTORY)
-	    goto read_cluster_directory;
-
-	assert(s->current_fd);
-
-	offset=s->cluster_size*(cluster_num-s->current_mapping->begin)+s->current_mapping->info.file.offset;
-	if(lseek(s->current_fd, offset, SEEK_SET)!=offset)
-	    return -3;
-	s->cluster=s->cluster_buffer;
-	result=read(s->current_fd,s->cluster,s->cluster_size);
-	if(result<0) {
-	    s->current_cluster = -1;
-	    return -1;
-	}
-	s->current_cluster = cluster_num;
+                offset = s->cluster_size*(cluster_num-s->current_mapping->begin);
+                s->cluster = (unsigned char*)s->directory.pointer+offset
+                        + 0x20*s->current_mapping->info.dir.first_dir_index;
+                assert(((s->cluster-(unsigned char*)s->directory.pointer)%s->cluster_size)==0);
+                assert((char*)s->cluster+s->cluster_size <= s->directory.pointer+s->directory.next*s->directory.item_size);
+                s->current_cluster = cluster_num;
+                return 0;
+            }
+
+            if(open_file(s,mapping))
+                return -2;
+        } else if (s->current_mapping->mode & MODE_DIRECTORY)
+            goto read_cluster_directory;
+
+        assert(s->current_fd);
+
+        offset=s->cluster_size*(cluster_num-s->current_mapping->begin)+s->current_mapping->info.file.offset;
+        if(lseek(s->current_fd, offset, SEEK_SET)!=offset)
+            return -3;
+        s->cluster=s->cluster_buffer;
+        result=read(s->current_fd,s->cluster,s->cluster_size);
+        if(result<0) {
+            s->current_cluster = -1;
+            return -1;
+        }
+        s->current_cluster = cluster_num;
     }
     return 0;
 }
@@ -1355,28 +1355,28 @@ static void print_direntry(const direntry_t* direntry)
 
     fprintf(stderr, "direntry %p: ", direntry);
     if(!direntry)
-	return;
+        return;
     if(is_long_name(direntry)) {
-	unsigned char* c=(unsigned char*)direntry;
-	int i;
-	for(i=1;i<11 && c[i] && c[i]!=0xff;i+=2)
+        unsigned char* c=(unsigned char*)direntry;
+        int i;
+        for(i=1;i<11 && c[i] && c[i]!=0xff;i+=2)
 #define ADD_CHAR(c) {buffer[j] = (c); if (buffer[j] < ' ') buffer[j] = 0xb0; j++;}
-	    ADD_CHAR(c[i]);
-	for(i=14;i<26 && c[i] && c[i]!=0xff;i+=2)
-	    ADD_CHAR(c[i]);
-	for(i=28;i<32 && c[i] && c[i]!=0xff;i+=2)
-	    ADD_CHAR(c[i]);
-	buffer[j] = 0;
-	fprintf(stderr, "%s\n", buffer);
+            ADD_CHAR(c[i]);
+        for(i=14;i<26 && c[i] && c[i]!=0xff;i+=2)
+            ADD_CHAR(c[i]);
+        for(i=28;i<32 && c[i] && c[i]!=0xff;i+=2)
+            ADD_CHAR(c[i]);
+        buffer[j] = 0;
+        fprintf(stderr, "%s\n", buffer);
     } else {
-	int i;
-	for(i=0;i<11;i++)
-	    ADD_CHAR(direntry->name[i]);
-	buffer[j] = 0;
-	fprintf(stderr,"%s attributes=0x%02x begin=%d size=%d\n",
-		buffer,
-		direntry->attributes,
-		begin_of_direntry(direntry),le32_to_cpu(direntry->size));
+        int i;
+        for(i=0;i<11;i++)
+            ADD_CHAR(direntry->name[i]);
+        buffer[j] = 0;
+        fprintf(stderr,"%s attributes=0x%02x begin=%d size=%d\n",
+                buffer,
+                direntry->attributes,
+                begin_of_direntry(direntry),le32_to_cpu(direntry->size));
     }
 }
 
@@ -1388,9 +1388,9 @@ static void print_mapping(const mapping_t* mapping)
         mapping->first_mapping_index, mapping->path, mapping->mode);
 
     if (mapping->mode & MODE_DIRECTORY)
-	fprintf(stderr, "parent_mapping_index = %d, first_dir_index = %d\n", mapping->info.dir.parent_mapping_index, mapping->info.dir.first_dir_index);
+        fprintf(stderr, "parent_mapping_index = %d, first_dir_index = %d\n", mapping->info.dir.parent_mapping_index, mapping->info.dir.first_dir_index);
     else
-	fprintf(stderr, "offset = %d\n", mapping->info.file.offset);
+        fprintf(stderr, "offset = %d\n", mapping->info.file.offset);
 }
 #endif
 
@@ -1401,10 +1401,10 @@ static int vvfat_read(BlockDriverState *bs, int64_t sector_num,
     int i;
 
     for(i=0;i<nb_sectors;i++,sector_num++) {
-	if (sector_num >= bs->total_sectors)
-	   return -1;
-	if (s->qcow) {
-	    int n;
+        if (sector_num >= bs->total_sectors)
+           return -1;
+        if (s->qcow) {
+            int n;
             int ret;
             ret = bdrv_is_allocated(s->qcow->bs, sector_num,
                                     nb_sectors - i, &n);
@@ -1422,25 +1422,25 @@ static int vvfat_read(BlockDriverState *bs, int64_t sector_num,
                 continue;
             }
 DLOG(fprintf(stderr, "sector %d not allocated\n", (int)sector_num));
-	}
-	if(sector_num<s->faked_sectors) {
-	    if(sector_num<s->first_sectors_number)
-		memcpy(buf+i*0x200,&(s->first_sectors[sector_num*0x200]),0x200);
-	    else if(sector_num-s->first_sectors_number<s->sectors_per_fat)
-		memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number)*0x200]),0x200);
-	    else if(sector_num-s->first_sectors_number-s->sectors_per_fat<s->sectors_per_fat)
-		memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number-s->sectors_per_fat)*0x200]),0x200);
-	} else {
-	    uint32_t sector=sector_num-s->faked_sectors,
-	    sector_offset_in_cluster=(sector%s->sectors_per_cluster),
-	    cluster_num=sector/s->sectors_per_cluster;
-	    if(cluster_num > s->cluster_count || read_cluster(s, cluster_num) != 0) {
-		/* LATER TODO: strict: return -1; */
-		memset(buf+i*0x200,0,0x200);
-		continue;
-	    }
-	    memcpy(buf+i*0x200,s->cluster+sector_offset_in_cluster*0x200,0x200);
-	}
+        }
+        if(sector_num<s->faked_sectors) {
+            if(sector_num<s->first_sectors_number)
+                memcpy(buf+i*0x200,&(s->first_sectors[sector_num*0x200]),0x200);
+            else if(sector_num-s->first_sectors_number<s->sectors_per_fat)
+                memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number)*0x200]),0x200);
+            else if(sector_num-s->first_sectors_number-s->sectors_per_fat<s->sectors_per_fat)
+                memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number-s->sectors_per_fat)*0x200]),0x200);
+        } else {
+            uint32_t sector=sector_num-s->faked_sectors,
+            sector_offset_in_cluster=(sector%s->sectors_per_cluster),
+            cluster_num=sector/s->sectors_per_cluster;
+            if(cluster_num > s->cluster_count || read_cluster(s, cluster_num) != 0) {
+                /* LATER TODO: strict: return -1; */
+                memset(buf+i*0x200,0,0x200);
+                continue;
+            }
+            memcpy(buf+i*0x200,s->cluster+sector_offset_in_cluster*0x200,0x200);
+        }
     }
     return 0;
 }
@@ -1498,14 +1498,14 @@ vvfat_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
 typedef struct commit_t {
     char* path;
     union {
-	struct { uint32_t cluster; } rename;
-	struct { int dir_index; uint32_t modified_offset; } writeout;
-	struct { uint32_t first_cluster; } new_file;
-	struct { uint32_t cluster; } mkdir;
+        struct { uint32_t cluster; } rename;
+        struct { int dir_index; uint32_t modified_offset; } writeout;
+        struct { uint32_t first_cluster; } new_file;
+        struct { uint32_t cluster; } mkdir;
     } param;
     /* DELETEs and RMDIRs are handled differently: see handle_deletes() */
     enum {
-	ACTION_RENAME, ACTION_WRITEOUT, ACTION_NEW_FILE, ACTION_MKDIR
+        ACTION_RENAME, ACTION_WRITEOUT, ACTION_NEW_FILE, ACTION_MKDIR
     } action;
 } commit_t;
 
@@ -1514,19 +1514,19 @@ static void clear_commits(BDRVVVFATState* s)
     int i;
 DLOG(fprintf(stderr, "clear_commits (%d commits)\n", s->commits.next));
     for (i = 0; i < s->commits.next; i++) {
-	commit_t* commit = array_get(&(s->commits), i);
-	assert(commit->path || commit->action == ACTION_WRITEOUT);
-	if (commit->action != ACTION_WRITEOUT) {
-	    assert(commit->path);
+        commit_t* commit = array_get(&(s->commits), i);
+        assert(commit->path || commit->action == ACTION_WRITEOUT);
+        if (commit->action != ACTION_WRITEOUT) {
+            assert(commit->path);
             g_free(commit->path);
-	} else
-	    assert(commit->path == NULL);
+        } else
+            assert(commit->path == NULL);
     }
     s->commits.next = 0;
 }
 
 static void schedule_rename(BDRVVVFATState* s,
-	uint32_t cluster, char* new_path)
+        uint32_t cluster, char* new_path)
 {
     commit_t* commit = array_get_next(&(s->commits));
     commit->path = new_path;
@@ -1535,7 +1535,7 @@ static void schedule_rename(BDRVVVFATState* s,
 }
 
 static void schedule_writeout(BDRVVVFATState* s,
-	int dir_index, uint32_t modified_offset)
+        int dir_index, uint32_t modified_offset)
 {
     commit_t* commit = array_get_next(&(s->commits));
     commit->path = NULL;
@@ -1545,7 +1545,7 @@ static void schedule_writeout(BDRVVVFATState* s,
 }
 
 static void schedule_new_file(BDRVVVFATState* s,
-	char* path, uint32_t first_cluster)
+        char* path, uint32_t first_cluster)
 {
     commit_t* commit = array_get_next(&(s->commits));
     commit->path = path;
@@ -1580,72 +1580,72 @@ static void lfn_init(long_file_name* lfn)
 
 /* return 0 if parsed successfully, > 0 if no long name, < 0 if error */
 static int parse_long_name(long_file_name* lfn,
-	const direntry_t* direntry)
+        const direntry_t* direntry)
 {
     int i, j, offset;
     const unsigned char* pointer = (const unsigned char*)direntry;
 
     if (!is_long_name(direntry))
-	return 1;
+        return 1;
 
     if (pointer[0] & 0x40) {
-	lfn->sequence_number = pointer[0] & 0x3f;
-	lfn->checksum = pointer[13];
-	lfn->name[0] = 0;
-	lfn->name[lfn->sequence_number * 13] = 0;
+        lfn->sequence_number = pointer[0] & 0x3f;
+        lfn->checksum = pointer[13];
+        lfn->name[0] = 0;
+        lfn->name[lfn->sequence_number * 13] = 0;
     } else if ((pointer[0] & 0x3f) != --lfn->sequence_number)
-	return -1;
+        return -1;
     else if (pointer[13] != lfn->checksum)
-	return -2;
+        return -2;
     else if (pointer[12] || pointer[26] || pointer[27])
-	return -3;
+        return -3;
 
     offset = 13 * (lfn->sequence_number - 1);
     for (i = 0, j = 1; i < 13; i++, j+=2) {
-	if (j == 11)
-	    j = 14;
-	else if (j == 26)
-	    j = 28;
+        if (j == 11)
+            j = 14;
+        else if (j == 26)
+            j = 28;
 
-	if (pointer[j+1] == 0)
-	    lfn->name[offset + i] = pointer[j];
-	else if (pointer[j+1] != 0xff || (pointer[0] & 0x40) == 0)
-	    return -4;
-	else
-	    lfn->name[offset + i] = 0;
+        if (pointer[j+1] == 0)
+            lfn->name[offset + i] = pointer[j];
+        else if (pointer[j+1] != 0xff || (pointer[0] & 0x40) == 0)
+            return -4;
+        else
+            lfn->name[offset + i] = 0;
     }
 
     if (pointer[0] & 0x40)
-	lfn->len = offset + strlen((char*)lfn->name + offset);
+        lfn->len = offset + strlen((char*)lfn->name + offset);
 
     return 0;
 }
 
 /* returns 0 if successful, >0 if no short_name, and <0 on error */
 static int parse_short_name(BDRVVVFATState* s,
-	long_file_name* lfn, direntry_t* direntry)
+        long_file_name* lfn, direntry_t* direntry)
 {
     int i, j;
 
     if (!is_short_name(direntry))
-	return 1;
+        return 1;
 
     for (j = 7; j >= 0 && direntry->name[j] == ' '; j--);
     for (i = 0; i <= j; i++) {
-	if (direntry->name[i] <= ' ' || direntry->name[i] > 0x7f)
-	    return -1;
-	else if (s->downcase_short_names)
-	    lfn->name[i] = qemu_tolower(direntry->name[i]);
-	else
-	    lfn->name[i] = direntry->name[i];
+        if (direntry->name[i] <= ' ' || direntry->name[i] > 0x7f)
+            return -1;
+        else if (s->downcase_short_names)
+            lfn->name[i] = qemu_tolower(direntry->name[i]);
+        else
+            lfn->name[i] = direntry->name[i];
     }
 
     for (j = 2; j >= 0 && direntry->name[8 + j] == ' '; j--) {
     }
     if (j >= 0) {
-	lfn->name[i++] = '.';
-	lfn->name[i + j + 1] = '\0';
-	for (;j >= 0; j--) {
+        lfn->name[i++] = '.';
+        lfn->name[i + j + 1] = '\0';
+        for (;j >= 0; j--) {
             uint8_t c = direntry->name[8 + j];
             if (c <= ' ' || c > 0x7f) {
                 return -2;
@@ -1654,9 +1654,9 @@ static int parse_short_name(BDRVVVFATState* s,
             } else {
                 lfn->name[i + j] = c;
             }
-	}
+        }
     } else
-	lfn->name[i + j + 1] = '\0';
+        lfn->name[i + j + 1] = '\0';
 
     lfn->len = strlen((char*)lfn->name);
 
@@ -1664,13 +1664,13 @@ static int parse_short_name(BDRVVVFATState* s,
 }
 
 static inline uint32_t modified_fat_get(BDRVVVFATState* s,
-	unsigned int cluster)
+        unsigned int cluster)
 {
     if (cluster < s->last_cluster_of_root_directory) {
-	if (cluster + 1 == s->last_cluster_of_root_directory)
-	    return s->max_fat_value;
-	else
-	    return cluster + 1;
+        if (cluster + 1 == s->last_cluster_of_root_directory)
+            return s->max_fat_value;
+        else
+            return cluster + 1;
     }
 
     if (s->fat_type==32) {
@@ -1714,9 +1714,9 @@ static const char* get_basename(const char* path)
 {
     char* basename = strrchr(path, '/');
     if (basename == NULL)
-	return path;
+        return path;
     else
-	return basename + 1; /* strip '/' */
+        return basename + 1; /* strip '/' */
 }
 
 /*
@@ -1741,7 +1741,7 @@ typedef enum {
  * assumed to be *not* deleted (and *only* those).
  */
 static uint32_t get_cluster_count_for_direntry(BDRVVVFATState* s,
-	direntry_t* direntry, const char* path)
+        direntry_t* direntry, const char* path)
 {
     /*
      * This is a little bit tricky:
@@ -1774,85 +1774,85 @@ static uint32_t get_cluster_count_for_direntry(BDRVVVFATState* s,
 
     /* the root directory */
     if (cluster_num == 0)
-	return 0;
+        return 0;
 
     /* write support */
     if (s->qcow) {
-	basename2 = get_basename(path);
+        basename2 = get_basename(path);
 
-	mapping = find_mapping_for_cluster(s, cluster_num);
+        mapping = find_mapping_for_cluster(s, cluster_num);
 
-	if (mapping) {
-	    const char* basename;
+        if (mapping) {
+            const char* basename;
 
-	    assert(mapping->mode & MODE_DELETED);
-	    mapping->mode &= ~MODE_DELETED;
+            assert(mapping->mode & MODE_DELETED);
+            mapping->mode &= ~MODE_DELETED;
 
-	    basename = get_basename(mapping->path);
+            basename = get_basename(mapping->path);
 
-	    assert(mapping->mode & MODE_NORMAL);
+            assert(mapping->mode & MODE_NORMAL);
 
-	    /* rename */
-	    if (strcmp(basename, basename2))
-		schedule_rename(s, cluster_num, g_strdup(path));
-	} else if (is_file(direntry))
-	    /* new file */
-	    schedule_new_file(s, g_strdup(path), cluster_num);
-	else {
+            /* rename */
+            if (strcmp(basename, basename2))
+                schedule_rename(s, cluster_num, g_strdup(path));
+        } else if (is_file(direntry))
+            /* new file */
+            schedule_new_file(s, g_strdup(path), cluster_num);
+        else {
             abort();
-	    return 0;
-	}
+            return 0;
+        }
     }
 
     while(1) {
-	if (s->qcow) {
-	    if (!copy_it && cluster_was_modified(s, cluster_num)) {
-		if (mapping == NULL ||
-			mapping->begin > cluster_num ||
-			mapping->end <= cluster_num)
-		mapping = find_mapping_for_cluster(s, cluster_num);
+        if (s->qcow) {
+            if (!copy_it && cluster_was_modified(s, cluster_num)) {
+                if (mapping == NULL ||
+                        mapping->begin > cluster_num ||
+                        mapping->end <= cluster_num)
+                mapping = find_mapping_for_cluster(s, cluster_num);
 
 
-		if (mapping &&
-			(mapping->mode & MODE_DIRECTORY) == 0) {
+                if (mapping &&
+                        (mapping->mode & MODE_DIRECTORY) == 0) {
 
-		    /* was modified in qcow */
-		    if (offset != mapping->info.file.offset + s->cluster_size
-			    * (cluster_num - mapping->begin)) {
-			/* offset of this cluster in file chain has changed */
+                    /* was modified in qcow */
+                    if (offset != mapping->info.file.offset + s->cluster_size
+                            * (cluster_num - mapping->begin)) {
+                        /* offset of this cluster in file chain has changed */
                         abort();
-			copy_it = 1;
-		    } else if (offset == 0) {
-			const char* basename = get_basename(mapping->path);
+                        copy_it = 1;
+                    } else if (offset == 0) {
+                        const char* basename = get_basename(mapping->path);
 
-			if (strcmp(basename, basename2))
-			    copy_it = 1;
-			first_mapping_index = array_index(&(s->mapping), mapping);
-		    }
+                        if (strcmp(basename, basename2))
+                            copy_it = 1;
+                        first_mapping_index = array_index(&(s->mapping), mapping);
+                    }
 
-		    if (mapping->first_mapping_index != first_mapping_index
-			    && mapping->info.file.offset > 0) {
+                    if (mapping->first_mapping_index != first_mapping_index
+                            && mapping->info.file.offset > 0) {
                         abort();
-			copy_it = 1;
-		    }
-
-		    /* need to write out? */
-		    if (!was_modified && is_file(direntry)) {
-			was_modified = 1;
-			schedule_writeout(s, mapping->dir_index, offset);
-		    }
-		}
-	    }
-
-	    if (copy_it) {
-		int i, dummy;
-		/*
-		 * This is horribly inefficient, but that is okay, since
-		 * it is rarely executed, if at all.
-		 */
-		int64_t offset = cluster2sector(s, cluster_num);
-
-		vvfat_close_current_file(s);
+                        copy_it = 1;
+                    }
+
+                    /* need to write out? */
+                    if (!was_modified && is_file(direntry)) {
+                        was_modified = 1;
+                        schedule_writeout(s, mapping->dir_index, offset);
+                    }
+                }
+            }
+
+            if (copy_it) {
+                int i, dummy;
+                /*
+                 * This is horribly inefficient, but that is okay, since
+                 * it is rarely executed, if at all.
+                 */
+                int64_t offset = cluster2sector(s, cluster_num);
+
+                vvfat_close_current_file(s);
                 for (i = 0; i < s->sectors_per_cluster; i++) {
                     int res;
 
@@ -1871,22 +1871,22 @@ static uint32_t get_cluster_count_for_direntry(BDRVVVFATState* s,
                         }
                     }
                 }
-	    }
-	}
+            }
+        }
 
-	ret++;
-	if (s->used_clusters[cluster_num] & USED_ANY)
-	    return 0;
-	s->used_clusters[cluster_num] = USED_FILE;
+        ret++;
+        if (s->used_clusters[cluster_num] & USED_ANY)
+            return 0;
+        s->used_clusters[cluster_num] = USED_FILE;
 
-	cluster_num = modified_fat_get(s, cluster_num);
+        cluster_num = modified_fat_get(s, cluster_num);
 
-	if (fat_eof(s, cluster_num))
-	    return ret;
-	else if (cluster_num < 2 || cluster_num > s->max_fat_value - 16)
-	    return -1;
+        if (fat_eof(s, cluster_num))
+            return ret;
+        else if (cluster_num < 2 || cluster_num > s->max_fat_value - 16)
+            return -1;
 
-	offset += s->cluster_size;
+        offset += s->cluster_size;
     }
 }
 
@@ -1896,7 +1896,7 @@ static uint32_t get_cluster_count_for_direntry(BDRVVVFATState* s,
  * used by the directory, its subdirectories and their files.
  */
 static int check_directory_consistency(BDRVVVFATState *s,
-	int cluster_num, const char* path)
+        int cluster_num, const char* path)
 {
     int ret = 0;
     unsigned char* cluster = g_malloc(s->cluster_size);
@@ -1913,104 +1913,104 @@ static int check_directory_consistency(BDRVVVFATState *s,
     path2[path_len + 1] = '\0';
 
     if (mapping) {
-	const char* basename = get_basename(mapping->path);
-	const char* basename2 = get_basename(path);
+        const char* basename = get_basename(mapping->path);
+        const char* basename2 = get_basename(path);
 
-	assert(mapping->mode & MODE_DIRECTORY);
+        assert(mapping->mode & MODE_DIRECTORY);
 
-	assert(mapping->mode & MODE_DELETED);
-	mapping->mode &= ~MODE_DELETED;
+        assert(mapping->mode & MODE_DELETED);
+        mapping->mode &= ~MODE_DELETED;
 
-	if (strcmp(basename, basename2))
-	    schedule_rename(s, cluster_num, g_strdup(path));
+        if (strcmp(basename, basename2))
+            schedule_rename(s, cluster_num, g_strdup(path));
     } else
-	/* new directory */
-	schedule_mkdir(s, cluster_num, g_strdup(path));
+        /* new directory */
+        schedule_mkdir(s, cluster_num, g_strdup(path));
 
     lfn_init(&lfn);
     do {
-	int i;
-	int subret = 0;
+        int i;
+        int subret = 0;
 
-	ret++;
+        ret++;
 
-	if (s->used_clusters[cluster_num] & USED_ANY) {
-	    fprintf(stderr, "cluster %d used more than once\n", (int)cluster_num);
+        if (s->used_clusters[cluster_num] & USED_ANY) {
+            fprintf(stderr, "cluster %d used more than once\n", (int)cluster_num);
             goto fail;
-	}
-	s->used_clusters[cluster_num] = USED_DIRECTORY;
+        }
+        s->used_clusters[cluster_num] = USED_DIRECTORY;
 
 DLOG(fprintf(stderr, "read cluster %d (sector %d)\n", (int)cluster_num, (int)cluster2sector(s, cluster_num)));
-	subret = vvfat_read(s->bs, cluster2sector(s, cluster_num), cluster,
-		s->sectors_per_cluster);
-	if (subret) {
-	    fprintf(stderr, "Error fetching direntries\n");
-	fail:
+        subret = vvfat_read(s->bs, cluster2sector(s, cluster_num), cluster,
+                s->sectors_per_cluster);
+        if (subret) {
+            fprintf(stderr, "Error fetching direntries\n");
+        fail:
             g_free(cluster);
-	    return 0;
-	}
+            return 0;
+        }
 
-	for (i = 0; i < 0x10 * s->sectors_per_cluster; i++) {
-	    int cluster_count = 0;
+        for (i = 0; i < 0x10 * s->sectors_per_cluster; i++) {
+            int cluster_count = 0;
 
 DLOG(fprintf(stderr, "check direntry %d:\n", i); print_direntry(direntries + i));
-	    if (is_volume_label(direntries + i) || is_dot(direntries + i) ||
-		    is_free(direntries + i))
-		continue;
-
-	    subret = parse_long_name(&lfn, direntries + i);
-	    if (subret < 0) {
-		fprintf(stderr, "Error in long name\n");
-		goto fail;
-	    }
-	    if (subret == 0 || is_free(direntries + i))
-		continue;
-
-	    if (fat_chksum(direntries+i) != lfn.checksum) {
-		subret = parse_short_name(s, &lfn, direntries + i);
-		if (subret < 0) {
-		    fprintf(stderr, "Error in short name (%d)\n", subret);
-		    goto fail;
-		}
-		if (subret > 0 || !strcmp((char*)lfn.name, ".")
-			|| !strcmp((char*)lfn.name, ".."))
-		    continue;
-	    }
-	    lfn.checksum = 0x100; /* cannot use long name twice */
-
-	    if (path_len + 1 + lfn.len >= PATH_MAX) {
-		fprintf(stderr, "Name too long: %s/%s\n", path, lfn.name);
-		goto fail;
-	    }
+            if (is_volume_label(direntries + i) || is_dot(direntries + i) ||
+                    is_free(direntries + i))
+                continue;
+
+            subret = parse_long_name(&lfn, direntries + i);
+            if (subret < 0) {
+                fprintf(stderr, "Error in long name\n");
+                goto fail;
+            }
+            if (subret == 0 || is_free(direntries + i))
+                continue;
+
+            if (fat_chksum(direntries+i) != lfn.checksum) {
+                subret = parse_short_name(s, &lfn, direntries + i);
+                if (subret < 0) {
+                    fprintf(stderr, "Error in short name (%d)\n", subret);
+                    goto fail;
+                }
+                if (subret > 0 || !strcmp((char*)lfn.name, ".")
+                        || !strcmp((char*)lfn.name, ".."))
+                    continue;
+            }
+            lfn.checksum = 0x100; /* cannot use long name twice */
+
+            if (path_len + 1 + lfn.len >= PATH_MAX) {
+                fprintf(stderr, "Name too long: %s/%s\n", path, lfn.name);
+                goto fail;
+            }
             pstrcpy(path2 + path_len + 1, sizeof(path2) - path_len - 1,
                     (char*)lfn.name);
 
-	    if (is_directory(direntries + i)) {
-		if (begin_of_direntry(direntries + i) == 0) {
-		    DLOG(fprintf(stderr, "invalid begin for directory: %s\n", path2); print_direntry(direntries + i));
-		    goto fail;
-		}
-		cluster_count = check_directory_consistency(s,
-			begin_of_direntry(direntries + i), path2);
-		if (cluster_count == 0) {
-		    DLOG(fprintf(stderr, "problem in directory %s:\n", path2); print_direntry(direntries + i));
-		    goto fail;
-		}
-	    } else if (is_file(direntries + i)) {
-		/* check file size with FAT */
-		cluster_count = get_cluster_count_for_direntry(s, direntries + i, path2);
-		if (cluster_count !=
+            if (is_directory(direntries + i)) {
+                if (begin_of_direntry(direntries + i) == 0) {
+                    DLOG(fprintf(stderr, "invalid begin for directory: %s\n", path2); print_direntry(direntries + i));
+                    goto fail;
+                }
+                cluster_count = check_directory_consistency(s,
+                        begin_of_direntry(direntries + i), path2);
+                if (cluster_count == 0) {
+                    DLOG(fprintf(stderr, "problem in directory %s:\n", path2); print_direntry(direntries + i));
+                    goto fail;
+                }
+            } else if (is_file(direntries + i)) {
+                /* check file size with FAT */
+                cluster_count = get_cluster_count_for_direntry(s, direntries + i, path2);
+                if (cluster_count !=
             DIV_ROUND_UP(le32_to_cpu(direntries[i].size), s->cluster_size)) {
-		    DLOG(fprintf(stderr, "Cluster count mismatch\n"));
-		    goto fail;
-		}
-	    } else
+                    DLOG(fprintf(stderr, "Cluster count mismatch\n"));
+                    goto fail;
+                }
+            } else
                 abort(); /* cluster_count = 0; */
 
-	    ret += cluster_count;
-	}
+            ret += cluster_count;
+        }
 
-	cluster_num = modified_fat_get(s, cluster_num);
+        cluster_num = modified_fat_get(s, cluster_num);
     } while(!fat_eof(s, cluster_num));
 
     g_free(cluster);
@@ -2038,81 +2038,81 @@ DLOG(checkpoint());
      * - if all is fine, return number of used clusters
      */
     if (s->fat2 == NULL) {
-	int size = 0x200 * s->sectors_per_fat;
-	s->fat2 = g_malloc(size);
-	memcpy(s->fat2, s->fat.pointer, size);
+        int size = 0x200 * s->sectors_per_fat;
+        s->fat2 = g_malloc(size);
+        memcpy(s->fat2, s->fat.pointer, size);
     }
     check = vvfat_read(s->bs,
-	    s->first_sectors_number, s->fat2, s->sectors_per_fat);
+            s->first_sectors_number, s->fat2, s->sectors_per_fat);
     if (check) {
-	fprintf(stderr, "Could not copy fat\n");
-	return 0;
+        fprintf(stderr, "Could not copy fat\n");
+        return 0;
     }
     assert (s->used_clusters);
     for (i = 0; i < sector2cluster(s, s->sector_count); i++)
-	s->used_clusters[i] &= ~USED_ANY;
+        s->used_clusters[i] &= ~USED_ANY;
 
     clear_commits(s);
 
     /* mark every mapped file/directory as deleted.
      * (check_directory_consistency() will unmark those still present). */
     if (s->qcow)
-	for (i = 0; i < s->mapping.next; i++) {
-	    mapping_t* mapping = array_get(&(s->mapping), i);
-	    if (mapping->first_mapping_index < 0)
-		mapping->mode |= MODE_DELETED;
-	}
+        for (i = 0; i < s->mapping.next; i++) {
+            mapping_t* mapping = array_get(&(s->mapping), i);
+            if (mapping->first_mapping_index < 0)
+                mapping->mode |= MODE_DELETED;
+        }
 
     used_clusters_count = check_directory_consistency(s, 0, s->path);
     if (used_clusters_count <= 0) {
-	DLOG(fprintf(stderr, "problem in directory\n"));
-	return 0;
+        DLOG(fprintf(stderr, "problem in directory\n"));
+        return 0;
     }
 
     check = s->last_cluster_of_root_directory;
     for (i = check; i < sector2cluster(s, s->sector_count); i++) {
-	if (modified_fat_get(s, i)) {
-	    if(!s->used_clusters[i]) {
-		DLOG(fprintf(stderr, "FAT was modified (%d), but cluster is not used?\n", i));
-		return 0;
-	    }
-	    check++;
-	}
+        if (modified_fat_get(s, i)) {
+            if(!s->used_clusters[i]) {
+                DLOG(fprintf(stderr, "FAT was modified (%d), but cluster is not used?\n", i));
+                return 0;
+            }
+            check++;
+        }
 
-	if (s->used_clusters[i] == USED_ALLOCATED) {
-	    /* allocated, but not used... */
-	    DLOG(fprintf(stderr, "unused, modified cluster: %d\n", i));
-	    return 0;
-	}
+        if (s->used_clusters[i] == USED_ALLOCATED) {
+            /* allocated, but not used... */
+            DLOG(fprintf(stderr, "unused, modified cluster: %d\n", i));
+            return 0;
+        }
     }
 
     if (check != used_clusters_count)
-	return 0;
+        return 0;
 
     return used_clusters_count;
 }
 
 static inline void adjust_mapping_indices(BDRVVVFATState* s,
-	int offset, int adjust)
+        int offset, int adjust)
 {
     int i;
 
     for (i = 0; i < s->mapping.next; i++) {
-	mapping_t* mapping = array_get(&(s->mapping), i);
+        mapping_t* mapping = array_get(&(s->mapping), i);
 
 #define ADJUST_MAPPING_INDEX(name) \
-	if (mapping->name >= offset) \
-	    mapping->name += adjust
+        if (mapping->name >= offset) \
+            mapping->name += adjust
 
-	ADJUST_MAPPING_INDEX(first_mapping_index);
-	if (mapping->mode & MODE_DIRECTORY)
-	    ADJUST_MAPPING_INDEX(info.dir.parent_mapping_index);
+        ADJUST_MAPPING_INDEX(first_mapping_index);
+        if (mapping->mode & MODE_DIRECTORY)
+            ADJUST_MAPPING_INDEX(info.dir.parent_mapping_index);
     }
 }
 
 /* insert or update mapping */
 static mapping_t* insert_mapping(BDRVVVFATState* s,
-	uint32_t begin, uint32_t end)
+        uint32_t begin, uint32_t end)
 {
     /*
      * - find mapping where mapping->begin >= begin,
@@ -2126,15 +2126,15 @@ static mapping_t* insert_mapping(BDRVVVFATState* s,
     mapping_t* first_mapping = array_get(&(s->mapping), 0);
 
     if (index < s->mapping.next && (mapping = array_get(&(s->mapping), index))
-	    && mapping->begin < begin) {
-	mapping->end = begin;
-	index++;
-	mapping = array_get(&(s->mapping), index);
+            && mapping->begin < begin) {
+        mapping->end = begin;
+        index++;
+        mapping = array_get(&(s->mapping), index);
     }
     if (index >= s->mapping.next || mapping->begin > begin) {
-	mapping = array_insert(&(s->mapping), index, 1);
-	mapping->path = NULL;
-	adjust_mapping_indices(s, index, +1);
+        mapping = array_insert(&(s->mapping), index, 1);
+        mapping->path = NULL;
+        adjust_mapping_indices(s, index, +1);
     }
 
     mapping->begin = begin;
@@ -2146,8 +2146,8 @@ assert(index + 1 >= s->mapping.next ||
  next_mapping->begin >= end)));
 
     if (s->current_mapping && first_mapping != (mapping_t*)s->mapping.pointer)
-	s->current_mapping = array_get(&(s->mapping),
-		s->current_mapping - first_mapping);
+        s->current_mapping = array_get(&(s->mapping),
+                s->current_mapping - first_mapping);
 
     return mapping;
 }
@@ -2169,8 +2169,8 @@ static int remove_mapping(BDRVVVFATState* s, int mapping_index)
     adjust_mapping_indices(s, mapping_index, -1);
 
     if (s->current_mapping && first_mapping != (mapping_t*)s->mapping.pointer)
-	s->current_mapping = array_get(&(s->mapping),
-		s->current_mapping - first_mapping);
+        s->current_mapping = array_get(&(s->mapping),
+                s->current_mapping - first_mapping);
 
     return 0;
 }
@@ -2179,17 +2179,17 @@ static void adjust_dirindices(BDRVVVFATState* s, int offset, int adjust)
 {
     int i;
     for (i = 0; i < s->mapping.next; i++) {
-	mapping_t* mapping = array_get(&(s->mapping), i);
-	if (mapping->dir_index >= offset)
-	    mapping->dir_index += adjust;
-	if ((mapping->mode & MODE_DIRECTORY) &&
-		mapping->info.dir.first_dir_index >= offset)
-	    mapping->info.dir.first_dir_index += adjust;
+        mapping_t* mapping = array_get(&(s->mapping), i);
+        if (mapping->dir_index >= offset)
+            mapping->dir_index += adjust;
+        if ((mapping->mode & MODE_DIRECTORY) &&
+                mapping->info.dir.first_dir_index >= offset)
+            mapping->info.dir.first_dir_index += adjust;
     }
 }
 
 static direntry_t* insert_direntries(BDRVVVFATState* s,
-	int dir_index, int count)
+        int dir_index, int count)
 {
     /*
      * make room in s->directory,
@@ -2197,7 +2197,7 @@ static direntry_t* insert_direntries(BDRVVVFATState* s,
      */
     direntry_t* result = array_insert(&(s->directory), dir_index, count);
     if (result == NULL)
-	return NULL;
+        return NULL;
     adjust_dirindices(s, dir_index, count);
     return result;
 }
@@ -2206,7 +2206,7 @@ static int remove_direntries(BDRVVVFATState* s, int dir_index, int count)
 {
     int ret = array_remove_slice(&(s->directory), dir_index, count);
     if (ret)
-	return ret;
+        return ret;
     adjust_dirindices(s, dir_index, -count);
     return 0;
 }
@@ -2218,7 +2218,7 @@ static int remove_direntries(BDRVVVFATState* s, int dir_index, int count)
  * adjusted)
  */
 static int commit_mappings(BDRVVVFATState* s,
-	uint32_t first_cluster, int dir_index)
+        uint32_t first_cluster, int dir_index)
 {
     mapping_t* mapping = find_mapping_for_cluster(s, first_cluster);
     direntry_t* direntry = array_get(&(s->directory), dir_index);
@@ -2231,71 +2231,71 @@ static int commit_mappings(BDRVVVFATState* s,
     mapping->first_mapping_index = -1;
     mapping->dir_index = dir_index;
     mapping->mode = (dir_index <= 0 || is_directory(direntry)) ?
-	MODE_DIRECTORY : MODE_NORMAL;
+        MODE_DIRECTORY : MODE_NORMAL;
 
     while (!fat_eof(s, cluster)) {
-	uint32_t c, c1;
-
-	for (c = cluster, c1 = modified_fat_get(s, c); c + 1 == c1;
-		c = c1, c1 = modified_fat_get(s, c1));
-
-	c++;
-	if (c > mapping->end) {
-	    int index = array_index(&(s->mapping), mapping);
-	    int i, max_i = s->mapping.next - index;
-	    for (i = 1; i < max_i && mapping[i].begin < c; i++);
-	    while (--i > 0)
-		remove_mapping(s, index + 1);
-	}
-	assert(mapping == array_get(&(s->mapping), s->mapping.next - 1)
-		|| mapping[1].begin >= c);
-	mapping->end = c;
-
-	if (!fat_eof(s, c1)) {
-	    int i = find_mapping_for_cluster_aux(s, c1, 0, s->mapping.next);
-	    mapping_t* next_mapping = i >= s->mapping.next ? NULL :
-		array_get(&(s->mapping), i);
-
-	    if (next_mapping == NULL || next_mapping->begin > c1) {
-		int i1 = array_index(&(s->mapping), mapping);
-
-		next_mapping = insert_mapping(s, c1, c1+1);
-
-		if (c1 < c)
-		    i1++;
-		mapping = array_get(&(s->mapping), i1);
-	    }
-
-	    next_mapping->dir_index = mapping->dir_index;
-	    next_mapping->first_mapping_index =
-		mapping->first_mapping_index < 0 ?
-		array_index(&(s->mapping), mapping) :
-		mapping->first_mapping_index;
-	    next_mapping->path = mapping->path;
-	    next_mapping->mode = mapping->mode;
-	    next_mapping->read_only = mapping->read_only;
-	    if (mapping->mode & MODE_DIRECTORY) {
-		next_mapping->info.dir.parent_mapping_index =
-			mapping->info.dir.parent_mapping_index;
-		next_mapping->info.dir.first_dir_index =
-			mapping->info.dir.first_dir_index +
-			0x10 * s->sectors_per_cluster *
-			(mapping->end - mapping->begin);
-	    } else
-		next_mapping->info.file.offset = mapping->info.file.offset +
-			mapping->end - mapping->begin;
-
-	    mapping = next_mapping;
-	}
-
-	cluster = c1;
+        uint32_t c, c1;
+
+        for (c = cluster, c1 = modified_fat_get(s, c); c + 1 == c1;
+                c = c1, c1 = modified_fat_get(s, c1));
+
+        c++;
+        if (c > mapping->end) {
+            int index = array_index(&(s->mapping), mapping);
+            int i, max_i = s->mapping.next - index;
+            for (i = 1; i < max_i && mapping[i].begin < c; i++);
+            while (--i > 0)
+                remove_mapping(s, index + 1);
+        }
+        assert(mapping == array_get(&(s->mapping), s->mapping.next - 1)
+                || mapping[1].begin >= c);
+        mapping->end = c;
+
+        if (!fat_eof(s, c1)) {
+            int i = find_mapping_for_cluster_aux(s, c1, 0, s->mapping.next);
+            mapping_t* next_mapping = i >= s->mapping.next ? NULL :
+                array_get(&(s->mapping), i);
+
+            if (next_mapping == NULL || next_mapping->begin > c1) {
+                int i1 = array_index(&(s->mapping), mapping);
+
+                next_mapping = insert_mapping(s, c1, c1+1);
+
+                if (c1 < c)
+                    i1++;
+                mapping = array_get(&(s->mapping), i1);
+            }
+
+            next_mapping->dir_index = mapping->dir_index;
+            next_mapping->first_mapping_index =
+                mapping->first_mapping_index < 0 ?
+                array_index(&(s->mapping), mapping) :
+                mapping->first_mapping_index;
+            next_mapping->path = mapping->path;
+            next_mapping->mode = mapping->mode;
+            next_mapping->read_only = mapping->read_only;
+            if (mapping->mode & MODE_DIRECTORY) {
+                next_mapping->info.dir.parent_mapping_index =
+                        mapping->info.dir.parent_mapping_index;
+                next_mapping->info.dir.first_dir_index =
+                        mapping->info.dir.first_dir_index +
+                        0x10 * s->sectors_per_cluster *
+                        (mapping->end - mapping->begin);
+            } else
+                next_mapping->info.file.offset = mapping->info.file.offset +
+                        mapping->end - mapping->begin;
+
+            mapping = next_mapping;
+        }
+
+        cluster = c1;
     }
 
     return 0;
 }
 
 static int commit_direntries(BDRVVVFATState* s,
-	int dir_index, int parent_mapping_index)
+        int dir_index, int parent_mapping_index)
 {
     direntry_t* direntry = array_get(&(s->directory), dir_index);
     uint32_t first_cluster = dir_index == 0 ? 0 : begin_of_direntry(direntry);
@@ -2320,58 +2320,58 @@ DLOG(fprintf(stderr, "commit_direntries for %s, parent_mapping_index %d\n", mapp
     mapping->info.dir.parent_mapping_index = parent_mapping_index;
 
     if (first_cluster == 0) {
-	old_cluster_count = new_cluster_count =
-	    s->last_cluster_of_root_directory;
+        old_cluster_count = new_cluster_count =
+            s->last_cluster_of_root_directory;
     } else {
-	for (old_cluster_count = 0, c = first_cluster; !fat_eof(s, c);
-		c = fat_get(s, c))
-	    old_cluster_count++;
+        for (old_cluster_count = 0, c = first_cluster; !fat_eof(s, c);
+                c = fat_get(s, c))
+            old_cluster_count++;
 
-	for (new_cluster_count = 0, c = first_cluster; !fat_eof(s, c);
-		c = modified_fat_get(s, c))
-	    new_cluster_count++;
+        for (new_cluster_count = 0, c = first_cluster; !fat_eof(s, c);
+                c = modified_fat_get(s, c))
+            new_cluster_count++;
     }
 
     if (new_cluster_count > old_cluster_count) {
-	if (insert_direntries(s,
-		current_dir_index + factor * old_cluster_count,
-		factor * (new_cluster_count - old_cluster_count)) == NULL)
-	    return -1;
+        if (insert_direntries(s,
+                current_dir_index + factor * old_cluster_count,
+                factor * (new_cluster_count - old_cluster_count)) == NULL)
+            return -1;
     } else if (new_cluster_count < old_cluster_count)
-	remove_direntries(s,
-		current_dir_index + factor * new_cluster_count,
-		factor * (old_cluster_count - new_cluster_count));
+        remove_direntries(s,
+                current_dir_index + factor * new_cluster_count,
+                factor * (old_cluster_count - new_cluster_count));
 
     for (c = first_cluster; !fat_eof(s, c); c = modified_fat_get(s, c)) {
         direntry_t *first_direntry;
-	void* direntry = array_get(&(s->directory), current_dir_index);
-	int ret = vvfat_read(s->bs, cluster2sector(s, c), direntry,
-		s->sectors_per_cluster);
-	if (ret)
-	    return ret;
+        void* direntry = array_get(&(s->directory), current_dir_index);
+        int ret = vvfat_read(s->bs, cluster2sector(s, c), direntry,
+                s->sectors_per_cluster);
+        if (ret)
+            return ret;
 
         /* The first directory entry on the filesystem is the volume name */
         first_direntry = (direntry_t*) s->directory.pointer;
         assert(!memcmp(first_direntry->name, s->volume_label, 11));
 
-	current_dir_index += factor;
+        current_dir_index += factor;
     }
 
     ret = commit_mappings(s, first_cluster, dir_index);
     if (ret)
-	return ret;
+        return ret;
 
     /* recurse */
     for (i = 0; i < factor * new_cluster_count; i++) {
-	direntry = array_get(&(s->directory), first_dir_index + i);
-	if (is_directory(direntry) && !is_dot(direntry)) {
-	    mapping = find_mapping_for_cluster(s, first_cluster);
-	    assert(mapping->mode & MODE_DIRECTORY);
-	    ret = commit_direntries(s, first_dir_index + i,
-		array_index(&(s->mapping), mapping));
-	    if (ret)
-		return ret;
-	}
+        direntry = array_get(&(s->directory), first_dir_index + i);
+        if (is_directory(direntry) && !is_dot(direntry)) {
+            mapping = find_mapping_for_cluster(s, first_cluster);
+            assert(mapping->mode & MODE_DIRECTORY);
+            ret = commit_direntries(s, first_dir_index + i,
+                array_index(&(s->mapping), mapping));
+            if (ret)
+                return ret;
+        }
     }
 
     return 0;
@@ -2380,7 +2380,7 @@ DLOG(fprintf(stderr, "commit_direntries for %s, parent_mapping_index %d\n", mapp
 /* commit one file (adjust contents, adjust mapping),
    return first_mapping_index */
 static int commit_one_file(BDRVVVFATState* s,
-	int dir_index, uint32_t offset)
+        int dir_index, uint32_t offset)
 {
     direntry_t* direntry = array_get(&(s->directory), dir_index);
     uint32_t c = begin_of_direntry(direntry);
@@ -2395,14 +2395,14 @@ static int commit_one_file(BDRVVVFATState* s,
     assert((offset % s->cluster_size) == 0);
 
     for (i = s->cluster_size; i < offset; i += s->cluster_size)
-	c = modified_fat_get(s, c);
+        c = modified_fat_get(s, c);
 
     fd = qemu_open(mapping->path, O_RDWR | O_CREAT | O_BINARY, 0666);
     if (fd < 0) {
-	fprintf(stderr, "Could not open %s... (%s, %d)\n", mapping->path,
-		strerror(errno), errno);
+        fprintf(stderr, "Could not open %s... (%s, %d)\n", mapping->path,
+                strerror(errno), errno);
         g_free(cluster);
-	return fd;
+        return fd;
     }
     if (offset > 0) {
         if (lseek(fd, offset, SEEK_SET) != offset) {
@@ -2413,18 +2413,18 @@ static int commit_one_file(BDRVVVFATState* s,
     }
 
     while (offset < size) {
-	uint32_t c1;
-	int rest_size = (size - offset > s->cluster_size ?
-		s->cluster_size : size - offset);
-	int ret;
+        uint32_t c1;
+        int rest_size = (size - offset > s->cluster_size ?
+                s->cluster_size : size - offset);
+        int ret;
 
-	c1 = modified_fat_get(s, c);
+        c1 = modified_fat_get(s, c);
 
-	assert((size - offset == 0 && fat_eof(s, c)) ||
-		(size > offset && c >=2 && !fat_eof(s, c)));
+        assert((size - offset == 0 && fat_eof(s, c)) ||
+                (size > offset && c >=2 && !fat_eof(s, c)));
 
-	ret = vvfat_read(s->bs, cluster2sector(s, c),
-	    (uint8_t*)cluster, (rest_size + 0x1ff) / 0x200);
+        ret = vvfat_read(s->bs, cluster2sector(s, c),
+            (uint8_t*)cluster, (rest_size + 0x1ff) / 0x200);
 
         if (ret < 0) {
             qemu_close(fd);
@@ -2438,8 +2438,8 @@ static int commit_one_file(BDRVVVFATState* s,
             return -2;
         }
 
-	offset += rest_size;
-	c = c1;
+        offset += rest_size;
+        c = c1;
     }
 
     if (ftruncate(fd, size)) {
@@ -2460,18 +2460,18 @@ static void check1(BDRVVVFATState* s)
 {
     int i;
     for (i = 0; i < s->mapping.next; i++) {
-	mapping_t* mapping = array_get(&(s->mapping), i);
-	if (mapping->mode & MODE_DELETED) {
-	    fprintf(stderr, "deleted\n");
-	    continue;
-	}
-	assert(mapping->dir_index < s->directory.next);
-	direntry_t* direntry = array_get(&(s->directory), mapping->dir_index);
-	assert(mapping->begin == begin_of_direntry(direntry) || mapping->first_mapping_index >= 0);
-	if (mapping->mode & MODE_DIRECTORY) {
-	    assert(mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster * (mapping->end - mapping->begin) <= s->directory.next);
-	    assert((mapping->info.dir.first_dir_index % (0x10 * s->sectors_per_cluster)) == 0);
-	}
+        mapping_t* mapping = array_get(&(s->mapping), i);
+        if (mapping->mode & MODE_DELETED) {
+            fprintf(stderr, "deleted\n");
+            continue;
+        }
+        assert(mapping->dir_index < s->directory.next);
+        direntry_t* direntry = array_get(&(s->directory), mapping->dir_index);
+        assert(mapping->begin == begin_of_direntry(direntry) || mapping->first_mapping_index >= 0);
+        if (mapping->mode & MODE_DIRECTORY) {
+            assert(mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster * (mapping->end - mapping->begin) <= s->directory.next);
+            assert((mapping->info.dir.first_dir_index % (0x10 * s->sectors_per_cluster)) == 0);
+        }
     }
 }
 
@@ -2482,43 +2482,43 @@ static void check2(BDRVVVFATState* s)
     int first_mapping = -1;
 
     for (i = 0; i < s->directory.next; i++) {
-	direntry_t* direntry = array_get(&(s->directory), i);
-
-	if (is_short_name(direntry) && begin_of_direntry(direntry)) {
-	    mapping_t* mapping = find_mapping_for_cluster(s, begin_of_direntry(direntry));
-	    assert(mapping);
-	    assert(mapping->dir_index == i || is_dot(direntry));
-	    assert(mapping->begin == begin_of_direntry(direntry) || is_dot(direntry));
-	}
-
-	if ((i % (0x10 * s->sectors_per_cluster)) == 0) {
-	    /* cluster start */
-	    int j, count = 0;
-
-	    for (j = 0; j < s->mapping.next; j++) {
-		mapping_t* mapping = array_get(&(s->mapping), j);
-		if (mapping->mode & MODE_DELETED)
-		    continue;
-		if (mapping->mode & MODE_DIRECTORY) {
-		    if (mapping->info.dir.first_dir_index <= i && mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster > i) {
-			assert(++count == 1);
-			if (mapping->first_mapping_index == -1)
-			    first_mapping = array_index(&(s->mapping), mapping);
-			else
-			    assert(first_mapping == mapping->first_mapping_index);
-			if (mapping->info.dir.parent_mapping_index < 0)
-			    assert(j == 0);
-			else {
-			    mapping_t* parent = array_get(&(s->mapping), mapping->info.dir.parent_mapping_index);
-			    assert(parent->mode & MODE_DIRECTORY);
-			    assert(parent->info.dir.first_dir_index < mapping->info.dir.first_dir_index);
-			}
-		    }
-		}
-	    }
-	    if (count == 0)
-		first_mapping = -1;
-	}
+        direntry_t* direntry = array_get(&(s->directory), i);
+
+        if (is_short_name(direntry) && begin_of_direntry(direntry)) {
+            mapping_t* mapping = find_mapping_for_cluster(s, begin_of_direntry(direntry));
+            assert(mapping);
+            assert(mapping->dir_index == i || is_dot(direntry));
+            assert(mapping->begin == begin_of_direntry(direntry) || is_dot(direntry));
+        }
+
+        if ((i % (0x10 * s->sectors_per_cluster)) == 0) {
+            /* cluster start */
+            int j, count = 0;
+
+            for (j = 0; j < s->mapping.next; j++) {
+                mapping_t* mapping = array_get(&(s->mapping), j);
+                if (mapping->mode & MODE_DELETED)
+                    continue;
+                if (mapping->mode & MODE_DIRECTORY) {
+                    if (mapping->info.dir.first_dir_index <= i && mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster > i) {
+                        assert(++count == 1);
+                        if (mapping->first_mapping_index == -1)
+                            first_mapping = array_index(&(s->mapping), mapping);
+                        else
+                            assert(first_mapping == mapping->first_mapping_index);
+                        if (mapping->info.dir.parent_mapping_index < 0)
+                            assert(j == 0);
+                        else {
+                            mapping_t* parent = array_get(&(s->mapping), mapping->info.dir.parent_mapping_index);
+                            assert(parent->mode & MODE_DIRECTORY);
+                            assert(parent->info.dir.first_dir_index < mapping->info.dir.first_dir_index);
+                        }
+                    }
+                }
+            }
+            if (count == 0)
+                first_mapping = -1;
+        }
     }
 }
 #endif
@@ -2530,63 +2530,63 @@ static int handle_renames_and_mkdirs(BDRVVVFATState* s)
 #ifdef DEBUG
     fprintf(stderr, "handle_renames\n");
     for (i = 0; i < s->commits.next; i++) {
-	commit_t* commit = array_get(&(s->commits), i);
-	fprintf(stderr, "%d, %s (%d, %d)\n", i, commit->path ? commit->path : "(null)", commit->param.rename.cluster, commit->action);
+        commit_t* commit = array_get(&(s->commits), i);
+        fprintf(stderr, "%d, %s (%d, %d)\n", i, commit->path ? commit->path : "(null)", commit->param.rename.cluster, commit->action);
     }
 #endif
 
     for (i = 0; i < s->commits.next;) {
-	commit_t* commit = array_get(&(s->commits), i);
-	if (commit->action == ACTION_RENAME) {
-	    mapping_t* mapping = find_mapping_for_cluster(s,
-		    commit->param.rename.cluster);
-	    char* old_path = mapping->path;
-
-	    assert(commit->path);
-	    mapping->path = commit->path;
-	    if (rename(old_path, mapping->path))
-		return -2;
-
-	    if (mapping->mode & MODE_DIRECTORY) {
-		int l1 = strlen(mapping->path);
-		int l2 = strlen(old_path);
-		int diff = l1 - l2;
-		direntry_t* direntry = array_get(&(s->directory),
-			mapping->info.dir.first_dir_index);
-		uint32_t c = mapping->begin;
-		int i = 0;
-
-		/* recurse */
-		while (!fat_eof(s, c)) {
-		    do {
-			direntry_t* d = direntry + i;
-
-			if (is_file(d) || (is_directory(d) && !is_dot(d))) {
-			    mapping_t* m = find_mapping_for_cluster(s,
-				    begin_of_direntry(d));
-			    int l = strlen(m->path);
-			    char* new_path = g_malloc(l + diff + 1);
-
-			    assert(!strncmp(m->path, mapping->path, l2));
+        commit_t* commit = array_get(&(s->commits), i);
+        if (commit->action == ACTION_RENAME) {
+            mapping_t* mapping = find_mapping_for_cluster(s,
+                    commit->param.rename.cluster);
+            char* old_path = mapping->path;
+
+            assert(commit->path);
+            mapping->path = commit->path;
+            if (rename(old_path, mapping->path))
+                return -2;
+
+            if (mapping->mode & MODE_DIRECTORY) {
+                int l1 = strlen(mapping->path);
+                int l2 = strlen(old_path);
+                int diff = l1 - l2;
+                direntry_t* direntry = array_get(&(s->directory),
+                        mapping->info.dir.first_dir_index);
+                uint32_t c = mapping->begin;
+                int i = 0;
+
+                /* recurse */
+                while (!fat_eof(s, c)) {
+                    do {
+                        direntry_t* d = direntry + i;
+
+                        if (is_file(d) || (is_directory(d) && !is_dot(d))) {
+                            mapping_t* m = find_mapping_for_cluster(s,
+                                    begin_of_direntry(d));
+                            int l = strlen(m->path);
+                            char* new_path = g_malloc(l + diff + 1);
+
+                            assert(!strncmp(m->path, mapping->path, l2));
 
                             pstrcpy(new_path, l + diff + 1, mapping->path);
                             pstrcpy(new_path + l1, l + diff + 1 - l1,
                                     m->path + l2);
 
-			    schedule_rename(s, m->begin, new_path);
-			}
-			i++;
-		    } while((i % (0x10 * s->sectors_per_cluster)) != 0);
-		    c = fat_get(s, c);
-		}
-	    }
+                            schedule_rename(s, m->begin, new_path);
+                        }
+                        i++;
+                    } while((i % (0x10 * s->sectors_per_cluster)) != 0);
+                    c = fat_get(s, c);
+                }
+            }
 
             g_free(old_path);
-	    array_remove(&(s->commits), i);
-	    continue;
-	} else if (commit->action == ACTION_MKDIR) {
-	    mapping_t* mapping;
-	    int j, parent_path_len;
+            array_remove(&(s->commits), i);
+            continue;
+        } else if (commit->action == ACTION_MKDIR) {
+            mapping_t* mapping;
+            int j, parent_path_len;
 
 #ifdef __MINGW32__
             if (mkdir(commit->path))
@@ -2596,37 +2596,37 @@ static int handle_renames_and_mkdirs(BDRVVVFATState* s)
                 return -5;
 #endif
 
-	    mapping = insert_mapping(s, commit->param.mkdir.cluster,
-		    commit->param.mkdir.cluster + 1);
-	    if (mapping == NULL)
-		return -6;
-
-	    mapping->mode = MODE_DIRECTORY;
-	    mapping->read_only = 0;
-	    mapping->path = commit->path;
-	    j = s->directory.next;
-	    assert(j);
-	    insert_direntries(s, s->directory.next,
-		    0x10 * s->sectors_per_cluster);
-	    mapping->info.dir.first_dir_index = j;
-
-	    parent_path_len = strlen(commit->path)
-		- strlen(get_basename(commit->path)) - 1;
-	    for (j = 0; j < s->mapping.next; j++) {
-		mapping_t* m = array_get(&(s->mapping), j);
-		if (m->first_mapping_index < 0 && m != mapping &&
-			!strncmp(m->path, mapping->path, parent_path_len) &&
-			strlen(m->path) == parent_path_len)
-		    break;
-	    }
-	    assert(j < s->mapping.next);
-	    mapping->info.dir.parent_mapping_index = j;
-
-	    array_remove(&(s->commits), i);
-	    continue;
-	}
-
-	i++;
+            mapping = insert_mapping(s, commit->param.mkdir.cluster,
+                    commit->param.mkdir.cluster + 1);
+            if (mapping == NULL)
+                return -6;
+
+            mapping->mode = MODE_DIRECTORY;
+            mapping->read_only = 0;
+            mapping->path = commit->path;
+            j = s->directory.next;
+            assert(j);
+            insert_direntries(s, s->directory.next,
+                    0x10 * s->sectors_per_cluster);
+            mapping->info.dir.first_dir_index = j;
+
+            parent_path_len = strlen(commit->path)
+                - strlen(get_basename(commit->path)) - 1;
+            for (j = 0; j < s->mapping.next; j++) {
+                mapping_t* m = array_get(&(s->mapping), j);
+                if (m->first_mapping_index < 0 && m != mapping &&
+                        !strncmp(m->path, mapping->path, parent_path_len) &&
+                        strlen(m->path) == parent_path_len)
+                    break;
+            }
+            assert(j < s->mapping.next);
+            mapping->info.dir.parent_mapping_index = j;
+
+            array_remove(&(s->commits), i);
+            continue;
+        }
+
+        i++;
     }
     return 0;
 }
@@ -2641,75 +2641,75 @@ static int handle_commits(BDRVVVFATState* s)
     vvfat_close_current_file(s);
 
     for (i = 0; !fail && i < s->commits.next; i++) {
-	commit_t* commit = array_get(&(s->commits), i);
-	switch(commit->action) {
-	case ACTION_RENAME: case ACTION_MKDIR:
+        commit_t* commit = array_get(&(s->commits), i);
+        switch(commit->action) {
+        case ACTION_RENAME: case ACTION_MKDIR:
             abort();
-	    fail = -2;
-	    break;
-	case ACTION_WRITEOUT: {
+            fail = -2;
+            break;
+        case ACTION_WRITEOUT: {
 #ifndef NDEBUG
             /* these variables are only used by assert() below */
-	    direntry_t* entry = array_get(&(s->directory),
-		    commit->param.writeout.dir_index);
-	    uint32_t begin = begin_of_direntry(entry);
-	    mapping_t* mapping = find_mapping_for_cluster(s, begin);
+            direntry_t* entry = array_get(&(s->directory),
+                    commit->param.writeout.dir_index);
+            uint32_t begin = begin_of_direntry(entry);
+            mapping_t* mapping = find_mapping_for_cluster(s, begin);
 #endif
 
-	    assert(mapping);
-	    assert(mapping->begin == begin);
-	    assert(commit->path == NULL);
-
-	    if (commit_one_file(s, commit->param.writeout.dir_index,
-			commit->param.writeout.modified_offset))
-		fail = -3;
-
-	    break;
-	}
-	case ACTION_NEW_FILE: {
-	    int begin = commit->param.new_file.first_cluster;
-	    mapping_t* mapping = find_mapping_for_cluster(s, begin);
-	    direntry_t* entry;
-	    int i;
-
-	    /* find direntry */
-	    for (i = 0; i < s->directory.next; i++) {
-		entry = array_get(&(s->directory), i);
-		if (is_file(entry) && begin_of_direntry(entry) == begin)
-		    break;
-	    }
-
-	    if (i >= s->directory.next) {
-		fail = -6;
-		continue;
-	    }
-
-	    /* make sure there exists an initial mapping */
-	    if (mapping && mapping->begin != begin) {
-		mapping->end = begin;
-		mapping = NULL;
-	    }
-	    if (mapping == NULL) {
-		mapping = insert_mapping(s, begin, begin+1);
-	    }
-	    /* most members will be fixed in commit_mappings() */
-	    assert(commit->path);
-	    mapping->path = commit->path;
-	    mapping->read_only = 0;
-	    mapping->mode = MODE_NORMAL;
-	    mapping->info.file.offset = 0;
-
-	    if (commit_one_file(s, i, 0))
-		fail = -7;
-
-	    break;
-	}
-	default:
+            assert(mapping);
+            assert(mapping->begin == begin);
+            assert(commit->path == NULL);
+
+            if (commit_one_file(s, commit->param.writeout.dir_index,
+                        commit->param.writeout.modified_offset))
+                fail = -3;
+
+            break;
+        }
+        case ACTION_NEW_FILE: {
+            int begin = commit->param.new_file.first_cluster;
+            mapping_t* mapping = find_mapping_for_cluster(s, begin);
+            direntry_t* entry;
+            int i;
+
+            /* find direntry */
+            for (i = 0; i < s->directory.next; i++) {
+                entry = array_get(&(s->directory), i);
+                if (is_file(entry) && begin_of_direntry(entry) == begin)
+                    break;
+            }
+
+            if (i >= s->directory.next) {
+                fail = -6;
+                continue;
+            }
+
+            /* make sure there exists an initial mapping */
+            if (mapping && mapping->begin != begin) {
+                mapping->end = begin;
+                mapping = NULL;
+            }
+            if (mapping == NULL) {
+                mapping = insert_mapping(s, begin, begin+1);
+            }
+            /* most members will be fixed in commit_mappings() */
+            assert(commit->path);
+            mapping->path = commit->path;
+            mapping->read_only = 0;
+            mapping->mode = MODE_NORMAL;
+            mapping->info.file.offset = 0;
+
+            if (commit_one_file(s, i, 0))
+                fail = -7;
+
+            break;
+        }
+        default:
             abort();
-	}
+        }
     }
     if (i > 0 && array_remove_slice(&(s->commits), 0, i))
-	return -1;
+        return -1;
     return fail;
 }
 
@@ -2720,53 +2720,53 @@ static int handle_deletes(BDRVVVFATState* s)
     /* delete files corresponding to mappings marked as deleted */
     /* handle DELETEs and unused mappings (modified_fat_get(s, mapping->begin) == 0) */
     while (deferred && deleted) {
-	deferred = 0;
-	deleted = 0;
-
-	for (i = 1; i < s->mapping.next; i++) {
-	    mapping_t* mapping = array_get(&(s->mapping), i);
-	    if (mapping->mode & MODE_DELETED) {
-		direntry_t* entry = array_get(&(s->directory),
-			mapping->dir_index);
-
-		if (is_free(entry)) {
-		    /* remove file/directory */
-		    if (mapping->mode & MODE_DIRECTORY) {
-			int j, next_dir_index = s->directory.next,
-			first_dir_index = mapping->info.dir.first_dir_index;
-
-			if (rmdir(mapping->path) < 0) {
-			    if (errno == ENOTEMPTY) {
-				deferred++;
-				continue;
-			    } else
-				return -5;
-			}
-
-			for (j = 1; j < s->mapping.next; j++) {
-			    mapping_t* m = array_get(&(s->mapping), j);
-			    if (m->mode & MODE_DIRECTORY &&
-				    m->info.dir.first_dir_index >
-				    first_dir_index &&
-				    m->info.dir.first_dir_index <
-				    next_dir_index)
-				next_dir_index =
-				    m->info.dir.first_dir_index;
-			}
-			remove_direntries(s, first_dir_index,
-				next_dir_index - first_dir_index);
-
-			deleted++;
-		    }
-		} else {
-		    if (unlink(mapping->path))
-			return -4;
-		    deleted++;
-		}
-		DLOG(fprintf(stderr, "DELETE (%d)\n", i); print_mapping(mapping); print_direntry(entry));
-		remove_mapping(s, i);
-	    }
-	}
+        deferred = 0;
+        deleted = 0;
+
+        for (i = 1; i < s->mapping.next; i++) {
+            mapping_t* mapping = array_get(&(s->mapping), i);
+            if (mapping->mode & MODE_DELETED) {
+                direntry_t* entry = array_get(&(s->directory),
+                        mapping->dir_index);
+
+                if (is_free(entry)) {
+                    /* remove file/directory */
+                    if (mapping->mode & MODE_DIRECTORY) {
+                        int j, next_dir_index = s->directory.next,
+                        first_dir_index = mapping->info.dir.first_dir_index;
+
+                        if (rmdir(mapping->path) < 0) {
+                            if (errno == ENOTEMPTY) {
+                                deferred++;
+                                continue;
+                            } else
+                                return -5;
+                        }
+
+                        for (j = 1; j < s->mapping.next; j++) {
+                            mapping_t* m = array_get(&(s->mapping), j);
+                            if (m->mode & MODE_DIRECTORY &&
+                                    m->info.dir.first_dir_index >
+                                    first_dir_index &&
+                                    m->info.dir.first_dir_index <
+                                    next_dir_index)
+                                next_dir_index =
+                                    m->info.dir.first_dir_index;
+                        }
+                        remove_direntries(s, first_dir_index,
+                                next_dir_index - first_dir_index);
+
+                        deleted++;
+                    }
+                } else {
+                    if (unlink(mapping->path))
+                        return -4;
+                    deleted++;
+                }
+                DLOG(fprintf(stderr, "DELETE (%d)\n", i); print_mapping(mapping); print_direntry(entry));
+                remove_mapping(s, i);
+            }
+        }
     }
 
     return 0;
@@ -2786,15 +2786,15 @@ static int do_commit(BDRVVVFATState* s)
 
     /* the real meat are the commits. Nothing to do? Move along! */
     if (s->commits.next == 0)
-	return 0;
+        return 0;
 
     vvfat_close_current_file(s);
 
     ret = handle_renames_and_mkdirs(s);
     if (ret) {
-	fprintf(stderr, "Error handling renames (%d)\n", ret);
+        fprintf(stderr, "Error handling renames (%d)\n", ret);
         abort();
-	return ret;
+        return ret;
     }
 
     /* copy FAT (with bdrv_read) */
@@ -2803,23 +2803,23 @@ static int do_commit(BDRVVVFATState* s)
     /* recurse direntries from root (using bs->bdrv_read) */
     ret = commit_direntries(s, 0, -1);
     if (ret) {
-	fprintf(stderr, "Fatal: error while committing (%d)\n", ret);
+        fprintf(stderr, "Fatal: error while committing (%d)\n", ret);
         abort();
-	return ret;
+        return ret;
     }
 
     ret = handle_commits(s);
     if (ret) {
-	fprintf(stderr, "Error handling commits (%d)\n", ret);
+        fprintf(stderr, "Error handling commits (%d)\n", ret);
         abort();
-	return ret;
+        return ret;
     }
 
     ret = handle_deletes(s);
     if (ret) {
-	fprintf(stderr, "Error deleting\n");
+        fprintf(stderr, "Error deleting\n");
         abort();
-	return ret;
+        return ret;
     }
 
     if (s->qcow->bs->drv->bdrv_make_empty) {
@@ -2837,7 +2837,7 @@ static int try_commit(BDRVVVFATState* s)
     vvfat_close_current_file(s);
 DLOG(checkpoint());
     if(!is_consistent(s))
-	return -1;
+        return -1;
     return do_commit(s);
 }
 
@@ -2863,56 +2863,56 @@ DLOG(checkpoint());
      */
 
     if (sector_num < s->first_sectors_number)
-	return -1;
+        return -1;
 
     for (i = sector2cluster(s, sector_num);
-	    i <= sector2cluster(s, sector_num + nb_sectors - 1);) {
-	mapping_t* mapping = find_mapping_for_cluster(s, i);
-	if (mapping) {
-	    if (mapping->read_only) {
-		fprintf(stderr, "Tried to write to write-protected file %s\n",
-			mapping->path);
-		return -1;
-	    }
-
-	    if (mapping->mode & MODE_DIRECTORY) {
-		int begin = cluster2sector(s, i);
-		int end = begin + s->sectors_per_cluster, k;
-		int dir_index;
-		const direntry_t* direntries;
-		long_file_name lfn;
-
-		lfn_init(&lfn);
-
-		if (begin < sector_num)
-		    begin = sector_num;
-		if (end > sector_num + nb_sectors)
-		    end = sector_num + nb_sectors;
-		dir_index  = mapping->dir_index +
-		    0x10 * (begin - mapping->begin * s->sectors_per_cluster);
-		direntries = (direntry_t*)(buf + 0x200 * (begin - sector_num));
-
-		for (k = 0; k < (end - begin) * 0x10; k++) {
-		    /* do not allow non-ASCII filenames */
-		    if (parse_long_name(&lfn, direntries + k) < 0) {
-			fprintf(stderr, "Warning: non-ASCII filename\n");
-			return -1;
-		    }
-		    /* no access to the direntry of a read-only file */
-		    else if (is_short_name(direntries+k) &&
-			    (direntries[k].attributes & 1)) {
-			if (memcmp(direntries + k,
-				    array_get(&(s->directory), dir_index + k),
-				    sizeof(direntry_t))) {
-			    fprintf(stderr, "Warning: tried to write to write-protected file\n");
-			    return -1;
-			}
-		    }
-		}
-	    }
-	    i = mapping->end;
-	} else
-	    i++;
+            i <= sector2cluster(s, sector_num + nb_sectors - 1);) {
+        mapping_t* mapping = find_mapping_for_cluster(s, i);
+        if (mapping) {
+            if (mapping->read_only) {
+                fprintf(stderr, "Tried to write to write-protected file %s\n",
+                        mapping->path);
+                return -1;
+            }
+
+            if (mapping->mode & MODE_DIRECTORY) {
+                int begin = cluster2sector(s, i);
+                int end = begin + s->sectors_per_cluster, k;
+                int dir_index;
+                const direntry_t* direntries;
+                long_file_name lfn;
+
+                lfn_init(&lfn);
+
+                if (begin < sector_num)
+                    begin = sector_num;
+                if (end > sector_num + nb_sectors)
+                    end = sector_num + nb_sectors;
+                dir_index  = mapping->dir_index +
+                    0x10 * (begin - mapping->begin * s->sectors_per_cluster);
+                direntries = (direntry_t*)(buf + 0x200 * (begin - sector_num));
+
+                for (k = 0; k < (end - begin) * 0x10; k++) {
+                    /* do not allow non-ASCII filenames */
+                    if (parse_long_name(&lfn, direntries + k) < 0) {
+                        fprintf(stderr, "Warning: non-ASCII filename\n");
+                        return -1;
+                    }
+                    /* no access to the direntry of a read-only file */
+                    else if (is_short_name(direntries+k) &&
+                            (direntries[k].attributes & 1)) {
+                        if (memcmp(direntries + k,
+                                    array_get(&(s->directory), dir_index + k),
+                                    sizeof(direntry_t))) {
+                            fprintf(stderr, "Warning: tried to write to write-protected file\n");
+                            return -1;
+                        }
+                    }
+                }
+            }
+            i = mapping->end;
+        } else
+            i++;
     }
 
     /*
@@ -2921,14 +2921,14 @@ DLOG(checkpoint());
 DLOG(fprintf(stderr, "Write to qcow backend: %d + %d\n", (int)sector_num, nb_sectors));
     ret = bdrv_write(s->qcow, sector_num, buf, nb_sectors);
     if (ret < 0) {
-	fprintf(stderr, "Error writing to qcow backend\n");
-	return ret;
+        fprintf(stderr, "Error writing to qcow backend\n");
+        return ret;
     }
 
     for (i = sector2cluster(s, sector_num);
-	    i <= sector2cluster(s, sector_num + nb_sectors - 1); i++)
-	if (i >= 0)
-	    s->used_clusters[i] |= USED_ALLOCATED;
+            i <= sector2cluster(s, sector_num + nb_sectors - 1); i++)
+        if (i >= 0)
+            s->used_clusters[i] |= USED_ALLOCATED;
 
 DLOG(checkpoint());
     /* TODO: add timeout */
@@ -2967,7 +2967,7 @@ vvfat_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
 }
 
 static int64_t coroutine_fn vvfat_co_get_block_status(BlockDriverState *bs,
-	int64_t sector_num, int nb_sectors, int *n, BlockDriverState **file)
+        int64_t sector_num, int nb_sectors, int *n, BlockDriverState **file)
 {
     *n = bs->total_sectors - sector_num;
     if (*n > nb_sectors) {
@@ -3146,13 +3146,13 @@ static void checkpoint(void) {
     assert(!vvv->current_mapping || vvv->current_fd || (vvv->current_mapping->mode & MODE_DIRECTORY));
 #if 0
     if (((direntry_t*)vvv->directory.pointer)[1].attributes != 0xf)
-	fprintf(stderr, "Nonono!\n");
+        fprintf(stderr, "Nonono!\n");
     mapping_t* mapping;
     direntry_t* direntry;
     assert(vvv->mapping.size >= vvv->mapping.item_size * vvv->mapping.next);
     assert(vvv->directory.size >= vvv->directory.item_size * vvv->directory.next);
     if (vvv->mapping.next<47)
-	return;
+        return;
     assert((mapping = array_get(&(vvv->mapping), 47)));
     assert(mapping->dir_index < vvv->directory.next);
     direntry = array_get(&(vvv->directory), mapping->dir_index);
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH v2 03/13] vvfat: fix typos
  2017-05-22 21:11 [Qemu-devel] [PATCH v2 00/13] vvfat: misc fixes for read-only mode Hervé Poussineau
  2017-05-22 21:11 ` [Qemu-devel] [PATCH v2 01/13] vvfat: fix qemu-img map and qemu-img convert Hervé Poussineau
  2017-05-22 21:11 ` [Qemu-devel] [PATCH v2 02/13] vvfat: replace tabs by 8 spaces Hervé Poussineau
@ 2017-05-22 21:11 ` Hervé Poussineau
  2017-05-22 21:11 ` [Qemu-devel] [PATCH v2 04/13] vvfat: rename useless enumeration values Hervé Poussineau
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 29+ messages in thread
From: Hervé Poussineau @ 2017-05-22 21:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kevin Wolf, Max Reitz, qemu-block, Hervé Poussineau

Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
---
 block/vvfat.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/block/vvfat.c b/block/vvfat.c
index d3afb731b6..8b5f53ad26 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -404,9 +404,9 @@ static void init_mbr(BDRVVVFATState *s, int cyls, int heads, int secs)
     /* FAT12/FAT16/FAT32 */
     /* DOS uses different types when partition is LBA,
        probably to prevent older versions from using CHS on them */
-    partition->fs_type= s->fat_type==12 ? 0x1:
-                        s->fat_type==16 ? (lba?0xe:0x06):
-                         /*fat_tyoe==32*/ (lba?0xc:0x0b);
+    partition->fs_type = s->fat_type == 12 ? 0x1 :
+                         s->fat_type == 16 ? (lba ? 0xe : 0x06) :
+                       /*s->fat_type == 32*/ (lba ? 0xc : 0x0b);
 
     real_mbr->magic[0]=0x55; real_mbr->magic[1]=0xaa;
 }
@@ -806,7 +806,7 @@ static int read_directory(BDRVVVFATState* s, int mapping_index)
                 (ROOT_ENTRIES - cur) * sizeof(direntry_t));
     }
 
-     /* reget the mapping, since s->mapping was possibly realloc()ed */
+    /* re-get the mapping, since s->mapping was possibly realloc()ed */
     mapping = array_get(&(s->mapping), mapping_index);
     first_cluster += (s->directory.next - mapping->info.dir.first_dir_index)
         * 0x20 / s->cluster_size;
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH v2 04/13] vvfat: rename useless enumeration values
  2017-05-22 21:11 [Qemu-devel] [PATCH v2 00/13] vvfat: misc fixes for read-only mode Hervé Poussineau
                   ` (2 preceding siblings ...)
  2017-05-22 21:11 ` [Qemu-devel] [PATCH v2 03/13] vvfat: fix typos Hervé Poussineau
@ 2017-05-22 21:11 ` Hervé Poussineau
  2017-05-22 21:11 ` [Qemu-devel] [PATCH v2 05/13] vvfat: introduce offset_to_bootsector, offset_to_fat and offset_to_root_dir Hervé Poussineau
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 29+ messages in thread
From: Hervé Poussineau @ 2017-05-22 21:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kevin Wolf, Max Reitz, qemu-block, Hervé Poussineau

MODE_FAKED and MODE_RENAMED are not and were never used.

Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
---
 block/vvfat.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/block/vvfat.c b/block/vvfat.c
index 8b5f53ad26..6a36d4f7fa 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -287,8 +287,7 @@ typedef struct mapping_t {
     union {
         /* offset is
          * - the offset in the file (in clusters) for a file, or
-         * - the next cluster of the directory for a directory, and
-         * - the address of the buffer for a faked entry
+         * - the next cluster of the directory for a directory
          */
         struct {
             uint32_t offset;
@@ -301,9 +300,13 @@ typedef struct mapping_t {
     /* path contains the full path, i.e. it always starts with s->path */
     char* path;
 
-    enum { MODE_UNDEFINED = 0, MODE_NORMAL = 1, MODE_MODIFIED = 2,
-        MODE_DIRECTORY = 4, MODE_FAKED = 8,
-        MODE_DELETED = 16, MODE_RENAMED = 32 } mode;
+    enum {
+        MODE_UNDEFINED = 0,
+        MODE_NORMAL = 1,
+        MODE_MODIFIED = 2,
+        MODE_DIRECTORY = 4,
+        MODE_DELETED = 8,
+    } mode;
     int read_only;
 } mapping_t;
 
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH v2 05/13] vvfat: introduce offset_to_bootsector, offset_to_fat and offset_to_root_dir
  2017-05-22 21:11 [Qemu-devel] [PATCH v2 00/13] vvfat: misc fixes for read-only mode Hervé Poussineau
                   ` (3 preceding siblings ...)
  2017-05-22 21:11 ` [Qemu-devel] [PATCH v2 04/13] vvfat: rename useless enumeration values Hervé Poussineau
@ 2017-05-22 21:11 ` Hervé Poussineau
  2017-05-24  4:10   ` Philippe Mathieu-Daudé
  2017-05-22 21:11 ` [Qemu-devel] [PATCH v2 06/13] vvfat: fix field names in FAT12/FAT16 and FAT32 boot sectors Hervé Poussineau
                   ` (9 subsequent siblings)
  14 siblings, 1 reply; 29+ messages in thread
From: Hervé Poussineau @ 2017-05-22 21:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kevin Wolf, Max Reitz, qemu-block, Hervé Poussineau

- offset_to_bootsector is the number of sectors up to FAT bootsector
- offset_to_fat is the number of sectors up to first File Allocation Table
- offset_to_root_dir is the number of sectors up to root directory sector

Replace first_sectors_number - 1 by offset_to_bootsector.
Replace first_sectors_number by offset_to_fat.
Replace faked_sectors by offset_to_rootdir.

Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
---
 block/vvfat.c | 70 ++++++++++++++++++++++++++++++++++++-----------------------
 1 file changed, 43 insertions(+), 27 deletions(-)

diff --git a/block/vvfat.c b/block/vvfat.c
index 6a36d4f7fa..e694d82df4 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -320,22 +320,24 @@ static void print_mapping(const struct mapping_t* mapping);
 typedef struct BDRVVVFATState {
     CoMutex lock;
     BlockDriverState* bs; /* pointer to parent */
-    unsigned int first_sectors_number; /* 1 for a single partition, 0x40 for a disk with partition table */
     unsigned char first_sectors[0x40*0x200];
 
     int fat_type; /* 16 or 32 */
     array_t fat,directory,mapping;
     char volume_label[11];
 
+    uint32_t offset_to_bootsector; /* 0 for floppy, 0x3f for disk */
+
     unsigned int cluster_size;
     unsigned int sectors_per_cluster;
     unsigned int sectors_per_fat;
     unsigned int sectors_of_root_directory;
     uint32_t last_cluster_of_root_directory;
-    unsigned int faked_sectors; /* how many sectors are faked before file data */
     uint32_t sector_count; /* total number of sectors of the partition */
     uint32_t cluster_count; /* total number of clusters of this partition */
     uint32_t max_fat_value;
+    uint32_t offset_to_fat;
+    uint32_t offset_to_root_dir;
 
     int current_fd;
     mapping_t* current_mapping;
@@ -394,15 +396,15 @@ static void init_mbr(BDRVVVFATState *s, int cyls, int heads, int secs)
     partition->attributes=0x80; /* bootable */
 
     /* LBA is used when partition is outside the CHS geometry */
-    lba  = sector2CHS(&partition->start_CHS, s->first_sectors_number - 1,
+    lba  = sector2CHS(&partition->start_CHS, s->offset_to_bootsector,
                      cyls, heads, secs);
     lba |= sector2CHS(&partition->end_CHS,   s->bs->total_sectors - 1,
                      cyls, heads, secs);
 
     /*LBA partitions are identified only by start/length_sector_long not by CHS*/
-    partition->start_sector_long  = cpu_to_le32(s->first_sectors_number - 1);
+    partition->start_sector_long  = cpu_to_le32(s->offset_to_bootsector);
     partition->length_sector_long = cpu_to_le32(s->bs->total_sectors
-                                                - s->first_sectors_number + 1);
+                                                - s->offset_to_bootsector);
 
     /* FAT12/FAT16/FAT32 */
     /* DOS uses different types when partition is LBA,
@@ -823,12 +825,12 @@ static int read_directory(BDRVVVFATState* s, int mapping_index)
 
 static inline uint32_t sector2cluster(BDRVVVFATState* s,off_t sector_num)
 {
-    return (sector_num-s->faked_sectors)/s->sectors_per_cluster;
+    return (sector_num - s->offset_to_root_dir) / s->sectors_per_cluster;
 }
 
 static inline off_t cluster2sector(BDRVVVFATState* s, uint32_t cluster_num)
 {
-    return s->faked_sectors + s->sectors_per_cluster * cluster_num;
+    return s->offset_to_root_dir + s->sectors_per_cluster * cluster_num;
 }
 
 static int init_directories(BDRVVVFATState* s,
@@ -855,6 +857,9 @@ static int init_directories(BDRVVVFATState* s,
     i = 1+s->sectors_per_cluster*0x200*8/s->fat_type;
     s->sectors_per_fat=(s->sector_count+i)/i; /* round up */
 
+    s->offset_to_fat = s->offset_to_bootsector + 1;
+    s->offset_to_root_dir = s->offset_to_fat + s->sectors_per_fat * 2;
+
     array_init(&(s->mapping),sizeof(mapping_t));
     array_init(&(s->directory),sizeof(direntry_t));
 
@@ -868,7 +873,6 @@ static int init_directories(BDRVVVFATState* s,
     /* Now build FAT, and write back information into directory */
     init_fat(s);
 
-    s->faked_sectors=s->first_sectors_number+s->sectors_per_fat*2;
     s->cluster_count=sector2cluster(s, s->sector_count);
 
     mapping = array_get_next(&(s->mapping));
@@ -946,7 +950,8 @@ static int init_directories(BDRVVVFATState* s,
 
     s->current_mapping = NULL;
 
-    bootsector=(bootsector_t*)(s->first_sectors+(s->first_sectors_number-1)*0x200);
+    bootsector = (bootsector_t *)(s->first_sectors
+                                  + s->offset_to_bootsector * 0x200);
     bootsector->jump[0]=0xeb;
     bootsector->jump[1]=0x3e;
     bootsector->jump[2]=0x90;
@@ -957,16 +962,18 @@ static int init_directories(BDRVVVFATState* s,
     bootsector->number_of_fats=0x2; /* number of FATs */
     bootsector->root_entries=cpu_to_le16(s->sectors_of_root_directory*0x10);
     bootsector->total_sectors16=s->sector_count>0xffff?0:cpu_to_le16(s->sector_count);
-    bootsector->media_type=(s->first_sectors_number>1?0xf8:0xf0); /* media descriptor (f8=hd, f0=3.5 fd)*/
+    /* media descriptor: hard disk=0xf8, floppy=0xf0 */
+    bootsector->media_type = (s->offset_to_bootsector > 0 ? 0xf8 : 0xf0);
     s->fat.pointer[0] = bootsector->media_type;
     bootsector->sectors_per_fat=cpu_to_le16(s->sectors_per_fat);
     bootsector->sectors_per_track = cpu_to_le16(secs);
     bootsector->number_of_heads = cpu_to_le16(heads);
-    bootsector->hidden_sectors=cpu_to_le32(s->first_sectors_number==1?0:0x3f);
+    bootsector->hidden_sectors = cpu_to_le32(s->offset_to_bootsector);
     bootsector->total_sectors=cpu_to_le32(s->sector_count>0xffff?s->sector_count:0);
 
     /* LATER TODO: if FAT32, this is wrong */
-    bootsector->u.fat16.drive_number=s->first_sectors_number==1?0:0x80; /* fda=0, hda=0x80 */
+    /* drive_number: fda=0, hda=0x80 */
+    bootsector->u.fat16.drive_number = s->offset_to_bootsector == 0 ? 0 : 0x80;
     bootsector->u.fat16.current_head=0;
     bootsector->u.fat16.signature=0x29;
     bootsector->u.fat16.id=cpu_to_le32(0xfabe1afd);
@@ -1123,7 +1130,6 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
             secs = s->fat_type == 12 ? 18 : 36;
             s->sectors_per_cluster = 1;
         }
-        s->first_sectors_number = 1;
         cyls = 80;
         heads = 2;
     } else {
@@ -1131,7 +1137,7 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
         if (!s->fat_type) {
             s->fat_type = 16;
         }
-        s->first_sectors_number = 0x40;
+        s->offset_to_bootsector = 0x3f;
         cyls = s->fat_type == 12 ? 64 : 1024;
         heads = 16;
         secs = 63;
@@ -1167,7 +1173,7 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
     fprintf(stderr, "vvfat %s chs %d,%d,%d\n",
             dirname, cyls, heads, secs);
 
-    s->sector_count = cyls * heads * secs - (s->first_sectors_number - 1);
+    s->sector_count = cyls * heads * secs - s->offset_to_bootsector;
 
     if (qemu_opt_get_bool(opts, "rw", false)) {
         if (!bdrv_is_read_only(bs)) {
@@ -1197,7 +1203,8 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
         goto fail;
     }
 
-    s->sector_count = s->faked_sectors + s->sectors_per_cluster*s->cluster_count;
+    s->sector_count = s->offset_to_root_dir
+                    + s->sectors_per_cluster * s->cluster_count;
 
     /* Disable migration when vvfat is used rw */
     if (s->qcow) {
@@ -1213,7 +1220,7 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
         }
     }
 
-    if (s->first_sectors_number == 0x40) {
+    if (s->offset_to_bootsector > 0) {
         init_mbr(s, cyls, heads, secs);
     }
 
@@ -1426,15 +1433,24 @@ static int vvfat_read(BlockDriverState *bs, int64_t sector_num,
             }
 DLOG(fprintf(stderr, "sector %d not allocated\n", (int)sector_num));
         }
-        if(sector_num<s->faked_sectors) {
-            if(sector_num<s->first_sectors_number)
-                memcpy(buf+i*0x200,&(s->first_sectors[sector_num*0x200]),0x200);
-            else if(sector_num-s->first_sectors_number<s->sectors_per_fat)
-                memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number)*0x200]),0x200);
-            else if(sector_num-s->first_sectors_number-s->sectors_per_fat<s->sectors_per_fat)
-                memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number-s->sectors_per_fat)*0x200]),0x200);
+        if (sector_num < s->offset_to_root_dir) {
+            if (sector_num < s->offset_to_fat) {
+                memcpy(buf + i * 0x200,
+                       &(s->first_sectors[sector_num * 0x200]),
+                       0x200);
+            } else if (sector_num < s->offset_to_fat + s->sectors_per_fat) {
+                memcpy(buf + i * 0x200,
+                       &(s->fat.pointer[(sector_num
+                                       - s->offset_to_fat) * 0x200]),
+                       0x200);
+            } else if (sector_num < s->offset_to_root_dir) {
+                memcpy(buf + i * 0x200,
+                       &(s->fat.pointer[(sector_num - s->offset_to_fat
+                                       - s->sectors_per_fat) * 0x200]),
+                       0x200);
+            }
         } else {
-            uint32_t sector=sector_num-s->faked_sectors,
+            uint32_t sector = sector_num - s->offset_to_root_dir,
             sector_offset_in_cluster=(sector%s->sectors_per_cluster),
             cluster_num=sector/s->sectors_per_cluster;
             if(cluster_num > s->cluster_count || read_cluster(s, cluster_num) != 0) {
@@ -2046,7 +2062,7 @@ DLOG(checkpoint());
         memcpy(s->fat2, s->fat.pointer, size);
     }
     check = vvfat_read(s->bs,
-            s->first_sectors_number, s->fat2, s->sectors_per_fat);
+            s->offset_to_fat, s->fat2, s->sectors_per_fat);
     if (check) {
         fprintf(stderr, "Could not copy fat\n");
         return 0;
@@ -2865,7 +2881,7 @@ DLOG(checkpoint());
      * - do not allow to write non-ASCII filenames
      */
 
-    if (sector_num < s->first_sectors_number)
+    if (sector_num < s->offset_to_fat)
         return -1;
 
     for (i = sector2cluster(s, sector_num);
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH v2 06/13] vvfat: fix field names in FAT12/FAT16 and FAT32 boot sectors
  2017-05-22 21:11 [Qemu-devel] [PATCH v2 00/13] vvfat: misc fixes for read-only mode Hervé Poussineau
                   ` (4 preceding siblings ...)
  2017-05-22 21:11 ` [Qemu-devel] [PATCH v2 05/13] vvfat: introduce offset_to_bootsector, offset_to_fat and offset_to_root_dir Hervé Poussineau
@ 2017-05-22 21:11 ` Hervé Poussineau
  2017-05-22 21:11 ` [Qemu-devel] [PATCH v2 07/13] vvfat: always create . and .. entries at first and in that order Hervé Poussineau
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 29+ messages in thread
From: Hervé Poussineau @ 2017-05-22 21:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kevin Wolf, Max Reitz, qemu-block, Hervé Poussineau

Specification: "FAT: General overview of on-disk format" v1.03, pages 11-13
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
---
 block/vvfat.c | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/block/vvfat.c b/block/vvfat.c
index e694d82df4..c1034cdd1f 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -218,23 +218,30 @@ typedef struct bootsector_t {
     union {
         struct {
             uint8_t drive_number;
-            uint8_t current_head;
+            uint8_t reserved1;
             uint8_t signature;
             uint32_t id;
             uint8_t volume_label[11];
+            uint8_t fat_type[8];
+            uint8_t ignored[0x1c0];
         } QEMU_PACKED fat16;
         struct {
             uint32_t sectors_per_fat;
             uint16_t flags;
             uint8_t major,minor;
-            uint32_t first_cluster_of_root_directory;
+            uint32_t first_cluster_of_root_dir;
             uint16_t info_sector;
             uint16_t backup_boot_sector;
-            uint16_t ignored;
+            uint8_t reserved[12];
+            uint8_t drive_number;
+            uint8_t reserved1;
+            uint8_t signature;
+            uint32_t id;
+            uint8_t volume_label[11];
+            uint8_t fat_type[8];
+            uint8_t ignored[0x1a4];
         } QEMU_PACKED fat32;
     } u;
-    uint8_t fat_type[8];
-    uint8_t ignored[0x1c0];
     uint8_t magic[2];
 } QEMU_PACKED bootsector_t;
 
@@ -974,13 +981,13 @@ static int init_directories(BDRVVVFATState* s,
     /* LATER TODO: if FAT32, this is wrong */
     /* drive_number: fda=0, hda=0x80 */
     bootsector->u.fat16.drive_number = s->offset_to_bootsector == 0 ? 0 : 0x80;
-    bootsector->u.fat16.current_head=0;
     bootsector->u.fat16.signature=0x29;
     bootsector->u.fat16.id=cpu_to_le32(0xfabe1afd);
 
     memcpy(bootsector->u.fat16.volume_label, s->volume_label,
            sizeof(bootsector->u.fat16.volume_label));
-    memcpy(bootsector->fat_type,(s->fat_type==12?"FAT12   ":s->fat_type==16?"FAT16   ":"FAT32   "),8);
+    memcpy(bootsector->u.fat16.fat_type,
+           s->fat_type == 12 ? "FAT12   " : "FAT16   ", 8);
     bootsector->magic[0]=0x55; bootsector->magic[1]=0xaa;
 
     return 0;
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH v2 07/13] vvfat: always create . and .. entries at first and in that order
  2017-05-22 21:11 [Qemu-devel] [PATCH v2 00/13] vvfat: misc fixes for read-only mode Hervé Poussineau
                   ` (5 preceding siblings ...)
  2017-05-22 21:11 ` [Qemu-devel] [PATCH v2 06/13] vvfat: fix field names in FAT12/FAT16 and FAT32 boot sectors Hervé Poussineau
@ 2017-05-22 21:11 ` Hervé Poussineau
  2017-05-22 21:12 ` [Qemu-devel] [PATCH v2 08/13] vvfat: correctly create long names for non-ASCII filenames Hervé Poussineau
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 29+ messages in thread
From: Hervé Poussineau @ 2017-05-22 21:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kevin Wolf, Max Reitz, qemu-block, Hervé Poussineau

readdir() doesn't always return . and .. entries at first and in that order.
This leads to not creating them at first in the directory, which raises some
errors on file system checking utilities like MS-DOS Scandisk.

Specification: "FAT: General overview of on-disk format" v1.03, page 25

Fixes: https://bugs.launchpad.net/qemu/+bug/1599539
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
---
 block/vvfat.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/block/vvfat.c b/block/vvfat.c
index c1034cdd1f..d4664c531b 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -728,6 +728,12 @@ static int read_directory(BDRVVVFATState* s, int mapping_index)
     i = mapping->info.dir.first_dir_index =
             first_cluster == 0 ? 0 : s->directory.next;
 
+    if (first_cluster != 0) {
+        /* create the top entries of a subdirectory */
+        (void)create_short_and_long_name(s, i, ".", 1);
+        (void)create_short_and_long_name(s, i, "..", 1);
+    }
+
     /* actually read the directory, and allocate the mappings */
     while((entry=readdir(dir))) {
         unsigned int length=strlen(dirname)+2+strlen(entry->d_name);
@@ -749,8 +755,11 @@ static int read_directory(BDRVVVFATState* s, int mapping_index)
         }
 
         /* create directory entry for this file */
-        direntry=create_short_and_long_name(s, i, entry->d_name,
-                is_dot || is_dotdot);
+        if (!is_dot && !is_dotdot) {
+            direntry = create_short_and_long_name(s, i, entry->d_name, 0);
+        } else {
+            direntry = array_get(&(s->directory), is_dot ? i : i + 1);
+        }
         direntry->attributes=(S_ISDIR(st.st_mode)?0x10:0x20);
         direntry->reserved[0]=direntry->reserved[1]=0;
         direntry->ctime=fat_datetime(st.st_ctime,1);
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH v2 08/13] vvfat: correctly create long names for non-ASCII filenames
  2017-05-22 21:11 [Qemu-devel] [PATCH v2 00/13] vvfat: misc fixes for read-only mode Hervé Poussineau
                   ` (6 preceding siblings ...)
  2017-05-22 21:11 ` [Qemu-devel] [PATCH v2 07/13] vvfat: always create . and .. entries at first and in that order Hervé Poussineau
@ 2017-05-22 21:12 ` Hervé Poussineau
  2017-05-22 21:12 ` [Qemu-devel] [PATCH v2 09/13] vvfat: correctly create base short " Hervé Poussineau
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 29+ messages in thread
From: Hervé Poussineau @ 2017-05-22 21:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kevin Wolf, Max Reitz, qemu-block, Hervé Poussineau

Assume that input filename is encoded as UTF-8, so correctly create UTF-16 encoding.

Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
---
 block/vvfat.c | 38 ++++++++++++++++++--------------------
 1 file changed, 18 insertions(+), 20 deletions(-)

diff --git a/block/vvfat.c b/block/vvfat.c
index d4664c531b..d34241da17 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -425,28 +425,19 @@ static void init_mbr(BDRVVVFATState *s, int cyls, int heads, int secs)
 
 /* direntry functions */
 
-/* dest is assumed to hold 258 bytes, and pads with 0xffff up to next multiple of 26 */
-static inline int short2long_name(char* dest,const char* src)
+static direntry_t *create_long_filename(BDRVVVFATState *s, const char *filename)
 {
-    int i;
-    int len;
-    for(i=0;i<129 && src[i];i++) {
-        dest[2*i]=src[i];
-        dest[2*i+1]=0;
+    int number_of_entries, i;
+    glong length;
+    direntry_t *entry;
+
+    gunichar2 *longname = g_utf8_to_utf16(filename, -1, NULL, &length, NULL);
+    if (!longname) {
+        fprintf(stderr, "vvfat: invalid UTF-8 name: %s\n", filename);
+        return NULL;
     }
-    len=2*i;
-    dest[2*i]=dest[2*i+1]=0;
-    for(i=2*i+2;(i%26);i++)
-        dest[i]=0xff;
-    return len;
-}
 
-static inline direntry_t* create_long_filename(BDRVVVFATState* s,const char* filename)
-{
-    char buffer[258];
-    int length=short2long_name(buffer,filename),
-        number_of_entries=(length+25)/26,i;
-    direntry_t* entry;
+    number_of_entries = (length * 2 + 25) / 26;
 
     for(i=0;i<number_of_entries;i++) {
         entry=array_get_next(&(s->directory));
@@ -461,8 +452,15 @@ static inline direntry_t* create_long_filename(BDRVVVFATState* s,const char* fil
         else if(offset<22) offset=14+offset-10;
         else offset=28+offset-22;
         entry=array_get(&(s->directory),s->directory.next-1-(i/26));
-        entry->name[offset]=buffer[i];
+        if (i >= 2 * length + 2) {
+            entry->name[offset] = 0xff;
+        } else if (i % 2 == 0) {
+            entry->name[offset] = longname[i / 2] & 0xff;
+        } else {
+            entry->name[offset] = longname[i / 2] >> 8;
+        }
     }
+    g_free(longname);
     return array_get(&(s->directory),s->directory.next-number_of_entries);
 }
 
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH v2 09/13] vvfat: correctly create base short names for non-ASCII filenames
  2017-05-22 21:11 [Qemu-devel] [PATCH v2 00/13] vvfat: misc fixes for read-only mode Hervé Poussineau
                   ` (7 preceding siblings ...)
  2017-05-22 21:12 ` [Qemu-devel] [PATCH v2 08/13] vvfat: correctly create long names for non-ASCII filenames Hervé Poussineau
@ 2017-05-22 21:12 ` Hervé Poussineau
  2017-05-24  4:17   ` Philippe Mathieu-Daudé
  2017-05-22 21:12 ` [Qemu-devel] [PATCH v2 10/13] vvfat: correctly generate numeric-tail of short file names Hervé Poussineau
                   ` (5 subsequent siblings)
  14 siblings, 1 reply; 29+ messages in thread
From: Hervé Poussineau @ 2017-05-22 21:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kevin Wolf, Max Reitz, qemu-block, Hervé Poussineau

More specifically, create short name from filename and change blacklist of
invalid chars to whitelist of valid chars.

Windows 9x also now correctly see long file names of filenames containing a space,
but Scandisk still complains about mismatch between SFN and LFN.

Specification: "FAT: General overview of on-disk format" v1.03, pages 30-31
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
---
 block/vvfat.c | 105 ++++++++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 77 insertions(+), 28 deletions(-)

diff --git a/block/vvfat.c b/block/vvfat.c
index d34241da17..3cb65493cd 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -516,6 +516,81 @@ static void set_begin_of_direntry(direntry_t* direntry, uint32_t begin)
     direntry->begin_hi = cpu_to_le16((begin >> 16) & 0xffff);
 }
 
+static uint8_t to_valid_short_char(gunichar c)
+{
+    c = g_unichar_toupper(c);
+    if ((c >= '0' && c <= '9') ||
+        (c >= 'A' && c <= 'Z') ||
+        strchr("$%'-_@~`!(){}^#&", c) != 0) {
+        return c;
+    } else {
+        return 0;
+    }
+}
+
+static direntry_t *create_short_filename(BDRVVVFATState *s,
+                                         const char *filename)
+{
+    int i, j = 0;
+    direntry_t *entry = array_get_next(&(s->directory));
+    const gchar *p, *last_dot = NULL;
+    gunichar c;
+    bool lossy_conversion = false;
+    char tail[11];
+
+    if (!entry) {
+        return NULL;
+    }
+    memset(entry->name, 0x20, sizeof(entry->name));
+
+    /* copy filename and search last dot */
+    for (p = filename; ; p = g_utf8_next_char(p)) {
+        c = g_utf8_get_char(p);
+        if (c == '\0') {
+            break;
+        } else if (c == '.') {
+            if (j == 0) {
+                /* '.' at start of filename */
+                lossy_conversion = true;
+            } else {
+                if (last_dot) {
+                    lossy_conversion = true;
+                }
+                last_dot = p;
+            }
+        } else if (!last_dot) {
+            /* first part of the name; copy it */
+            uint8_t v = to_valid_short_char(c);
+            if (j < 8 && v) {
+                entry->name[j++] = v;
+            } else {
+                lossy_conversion = true;
+            }
+        }
+    }
+
+    /* copy extension (if any) */
+    if (last_dot) {
+        j = 0;
+        for (p = g_utf8_next_char(last_dot); ; p = g_utf8_next_char(p)) {
+            c = g_utf8_get_char(p);
+            if (c == '\0') {
+                break;
+            } else {
+                /* extension; copy it */
+                uint8_t v = to_valid_short_char(c);
+                if (j < 3 && v) {
+                    entry->name[8 + (j++)] = v;
+                } else {
+                    lossy_conversion = true;
+                }
+            }
+        }
+    }
+    (void)lossy_conversion;
+    return entry;
+}
+
 /* fat functions */
 
 static inline uint8_t fat_chksum(const direntry_t* entry)
@@ -614,7 +689,7 @@ static inline void init_fat(BDRVVVFATState* s)
 static inline direntry_t* create_short_and_long_name(BDRVVVFATState* s,
         unsigned int directory_start, const char* filename, int is_dot)
 {
-    int i,j,long_index=s->directory.next;
+    int long_index = s->directory.next;
     direntry_t* entry = NULL;
     direntry_t* entry_long = NULL;
 
@@ -626,33 +701,7 @@ static inline direntry_t* create_short_and_long_name(BDRVVVFATState* s,
     }
 
     entry_long=create_long_filename(s,filename);
-
-    i = strlen(filename);
-    for(j = i - 1; j>0  && filename[j]!='.';j--);
-    if (j > 0)
-        i = (j > 8 ? 8 : j);
-    else if (i > 8)
-        i = 8;
-
-    entry=array_get_next(&(s->directory));
-    memset(entry->name, 0x20, sizeof(entry->name));
-    memcpy(entry->name, filename, i);
-
-    if (j > 0) {
-        for (i = 0; i < 3 && filename[j + 1 + i]; i++) {
-            entry->name[8 + i] = filename[j + 1 + i];
-        }
-    }
-
-    /* upcase & remove unwanted characters */
-    for(i=10;i>=0;i--) {
-        if(i==10 || i==7) for(;i>0 && entry->name[i]==' ';i--);
-        if(entry->name[i]<=' ' || entry->name[i]>0x7f
-                || strchr(".*?<>|\":/\\[];,+='",entry->name[i]))
-            entry->name[i]='_';
-        else if(entry->name[i]>='a' && entry->name[i]<='z')
-            entry->name[i]+='A'-'a';
-    }
+    entry = create_short_filename(s, filename);
 
     /* mangle duplicates */
     while(1) {
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH v2 10/13] vvfat: correctly generate numeric-tail of short file names
  2017-05-22 21:11 [Qemu-devel] [PATCH v2 00/13] vvfat: misc fixes for read-only mode Hervé Poussineau
                   ` (8 preceding siblings ...)
  2017-05-22 21:12 ` [Qemu-devel] [PATCH v2 09/13] vvfat: correctly create base short " Hervé Poussineau
@ 2017-05-22 21:12 ` Hervé Poussineau
  2017-08-05 18:52   ` Pranith Kumar
  2017-05-22 21:12 ` [Qemu-devel] [PATCH v2 11/13] vvfat: limit number of entries in root directory in FAT12/FAT16 Hervé Poussineau
                   ` (4 subsequent siblings)
  14 siblings, 1 reply; 29+ messages in thread
From: Hervé Poussineau @ 2017-05-22 21:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kevin Wolf, Max Reitz, qemu-block, Hervé Poussineau

More specifically:
- try without numeric-tail only if LFN didn't have invalid short chars
- start at ~1 (instead of ~0)
- handle case if numeric tail is more than one char (ie > 10)

Windows 9x Scandisk doesn't see anymore mismatches between short file names and
long file names for non-ASCII filenames.

Specification: "FAT: General overview of on-disk format" v1.03, page 31
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
---
 block/vvfat.c | 62 ++++++++++++++++++++++++++++-------------------------------
 1 file changed, 29 insertions(+), 33 deletions(-)

diff --git a/block/vvfat.c b/block/vvfat.c
index 3cb65493cd..414bca6dee 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -529,7 +529,8 @@ static uint8_t to_valid_short_char(gunichar c)
 }
 
 static direntry_t *create_short_filename(BDRVVVFATState *s,
-                                         const char *filename)
+                                         const char *filename,
+                                         unsigned int directory_start)
 {
     int i, j = 0;
     direntry_t *entry = array_get_next(&(s->directory));
@@ -587,8 +588,32 @@ static direntry_t *create_short_filename(BDRVVVFATState *s,
             }
         }
     }
-    (void)lossy_conversion;
-    return entry;
+
+    /* numeric-tail generation */
+    for (j = 0; j < 8; j++) {
+        if (entry->name[j] == ' ') {
+            break;
+        }
+    }
+    for (i = lossy_conversion ? 1 : 0; i < 999999; i++) {
+        direntry_t *entry1;
+        if (i > 0) {
+            int len = sprintf(tail, "~%d", i);
+            memcpy(entry->name + MIN(j, 8 - len), tail, len);
+        }
+        for (entry1 = array_get(&(s->directory), directory_start);
+             entry1 < entry; entry1++) {
+            if (!is_long_name(entry1) &&
+                !memcmp(entry1->name, entry->name, 11)) {
+                break; /* found dupe */
+            }
+        }
+        if (entry1 == entry) {
+            /* no dupe found */
+            return entry;
+        }
+    }
+    return NULL;
 }
 
 /* fat functions */
@@ -701,36 +726,7 @@ static inline direntry_t* create_short_and_long_name(BDRVVVFATState* s,
     }
 
     entry_long=create_long_filename(s,filename);
-    entry = create_short_filename(s, filename);
-
-    /* mangle duplicates */
-    while(1) {
-        direntry_t* entry1=array_get(&(s->directory),directory_start);
-        int j;
-
-        for(;entry1<entry;entry1++)
-            if(!is_long_name(entry1) && !memcmp(entry1->name,entry->name,11))
-                break; /* found dupe */
-        if(entry1==entry) /* no dupe found */
-            break;
-
-        /* use all 8 characters of name */
-        if(entry->name[7]==' ') {
-            int j;
-            for(j=6;j>0 && entry->name[j]==' ';j--)
-                entry->name[j]='~';
-        }
-
-        /* increment number */
-        for(j=7;j>0 && entry->name[j]=='9';j--)
-            entry->name[j]='0';
-        if(j>0) {
-            if(entry->name[j]<'0' || entry->name[j]>'9')
-                entry->name[j]='0';
-            else
-                entry->name[j]++;
-        }
-    }
+    entry = create_short_filename(s, filename, directory_start);
 
     /* calculate checksum; propagate to long name */
     if(entry_long) {
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH v2 11/13] vvfat: limit number of entries in root directory in FAT12/FAT16
  2017-05-22 21:11 [Qemu-devel] [PATCH v2 00/13] vvfat: misc fixes for read-only mode Hervé Poussineau
                   ` (9 preceding siblings ...)
  2017-05-22 21:12 ` [Qemu-devel] [PATCH v2 10/13] vvfat: correctly generate numeric-tail of short file names Hervé Poussineau
@ 2017-05-22 21:12 ` Hervé Poussineau
  2017-05-22 21:12 ` [Qemu-devel] [PATCH v2 12/13] vvfat: handle KANJI lead byte 0xe5 Hervé Poussineau
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 29+ messages in thread
From: Hervé Poussineau @ 2017-05-22 21:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kevin Wolf, Max Reitz, qemu-block, Hervé Poussineau

FAT12/FAT16 root directory is two sectors in size, which allows only 512 directory entries.
Prevent QEMU startup if too much files exist, instead of overflowing root directory.

Also introduce variable root_entries, which will be required for FAT32.

Fixes: https://bugs.launchpad.net/qemu/+bug/1599539/comments/4
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
---
 block/vvfat.c | 26 +++++++++++++++++---------
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/block/vvfat.c b/block/vvfat.c
index 414bca6dee..5376659010 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -338,8 +338,9 @@ typedef struct BDRVVVFATState {
     unsigned int cluster_size;
     unsigned int sectors_per_cluster;
     unsigned int sectors_per_fat;
-    unsigned int sectors_of_root_directory;
     uint32_t last_cluster_of_root_directory;
+    /* how many entries are available in root directory (0 for FAT32) */
+    uint16_t root_entries;
     uint32_t sector_count; /* total number of sectors of the partition */
     uint32_t cluster_count; /* total number of clusters of this partition */
     uint32_t max_fat_value;
@@ -786,6 +787,12 @@ static int read_directory(BDRVVVFATState* s, int mapping_index)
         int is_dot=!strcmp(entry->d_name,".");
         int is_dotdot=!strcmp(entry->d_name,"..");
 
+        if (first_cluster == 0 && s->directory.next >= s->root_entries - 1) {
+            fprintf(stderr, "Too many entries in root directory\n");
+            closedir(dir);
+            return -2;
+        }
+
         if(first_cluster == 0 && (is_dotdot || is_dot))
             continue;
 
@@ -859,15 +866,15 @@ static int read_directory(BDRVVVFATState* s, int mapping_index)
         memset(direntry,0,sizeof(direntry_t));
     }
 
-/* TODO: if there are more entries, bootsector has to be adjusted! */
-#define ROOT_ENTRIES (0x02 * 0x10 * s->sectors_per_cluster)
-    if (mapping_index == 0 && s->directory.next < ROOT_ENTRIES) {
+    if (s->fat_type != 32 &&
+        mapping_index == 0 &&
+        s->directory.next < s->root_entries) {
         /* root directory */
         int cur = s->directory.next;
-        array_ensure_allocated(&(s->directory), ROOT_ENTRIES - 1);
-        s->directory.next = ROOT_ENTRIES;
+        array_ensure_allocated(&(s->directory), s->root_entries - 1);
+        s->directory.next = s->root_entries;
         memset(array_get(&(s->directory), cur), 0,
-                (ROOT_ENTRIES - cur) * sizeof(direntry_t));
+                (s->root_entries - cur) * sizeof(direntry_t));
     }
 
     /* re-get the mapping, since s->mapping was possibly realloc()ed */
@@ -932,6 +939,8 @@ static int init_directories(BDRVVVFATState* s,
     /* Now build FAT, and write back information into directory */
     init_fat(s);
 
+    /* TODO: if there are more entries, bootsector has to be adjusted! */
+    s->root_entries = 0x02 * 0x10 * s->sectors_per_cluster;
     s->cluster_count=sector2cluster(s, s->sector_count);
 
     mapping = array_get_next(&(s->mapping));
@@ -1000,7 +1009,6 @@ static int init_directories(BDRVVVFATState* s,
     }
 
     mapping = array_get(&(s->mapping), 0);
-    s->sectors_of_root_directory = mapping->end * s->sectors_per_cluster;
     s->last_cluster_of_root_directory = mapping->end;
 
     /* the FAT signature */
@@ -1019,7 +1027,7 @@ static int init_directories(BDRVVVFATState* s,
     bootsector->sectors_per_cluster=s->sectors_per_cluster;
     bootsector->reserved_sectors=cpu_to_le16(1);
     bootsector->number_of_fats=0x2; /* number of FATs */
-    bootsector->root_entries=cpu_to_le16(s->sectors_of_root_directory*0x10);
+    bootsector->root_entries = cpu_to_le16(s->root_entries);
     bootsector->total_sectors16=s->sector_count>0xffff?0:cpu_to_le16(s->sector_count);
     /* media descriptor: hard disk=0xf8, floppy=0xf0 */
     bootsector->media_type = (s->offset_to_bootsector > 0 ? 0xf8 : 0xf0);
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH v2 12/13] vvfat: handle KANJI lead byte 0xe5
  2017-05-22 21:11 [Qemu-devel] [PATCH v2 00/13] vvfat: misc fixes for read-only mode Hervé Poussineau
                   ` (10 preceding siblings ...)
  2017-05-22 21:12 ` [Qemu-devel] [PATCH v2 11/13] vvfat: limit number of entries in root directory in FAT12/FAT16 Hervé Poussineau
@ 2017-05-22 21:12 ` Hervé Poussineau
  2017-05-24  4:20   ` Philippe Mathieu-Daudé
  2017-05-22 21:12 ` [Qemu-devel] [PATCH v2 13/13] vvfat: change OEM name to 'MSWIN4.1' Hervé Poussineau
                   ` (2 subsequent siblings)
  14 siblings, 1 reply; 29+ messages in thread
From: Hervé Poussineau @ 2017-05-22 21:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kevin Wolf, Max Reitz, qemu-block, Hervé Poussineau

Specification: "FAT: General overview of on-disk format" v1.03, page 23
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
---
 block/vvfat.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/block/vvfat.c b/block/vvfat.c
index 5376659010..53e8faa54c 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -590,6 +590,10 @@ static direntry_t *create_short_filename(BDRVVVFATState *s,
         }
     }
 
+    if (entry->name[0] == 0xe5) {
+        entry->name[0] = 0x05;
+    }
+
     /* numeric-tail generation */
     for (j = 0; j < 8; j++) {
         if (entry->name[j] == ' ') {
@@ -710,8 +714,6 @@ static inline void init_fat(BDRVVVFATState* s)
 
 }
 
-/* TODO: in create_short_filename, 0xe5->0x05 is not yet handled! */
-/* TODO: in parse_short_filename, 0x05->0xe5 is not yet handled! */
 static inline direntry_t* create_short_and_long_name(BDRVVVFATState* s,
         unsigned int directory_start, const char* filename, int is_dot)
 {
@@ -1744,6 +1746,9 @@ static int parse_short_name(BDRVVVFATState* s,
     } else
         lfn->name[i + j + 1] = '\0';
 
+    if (lfn->name[0] == 0x05) {
+        lfn->name[0] = 0xe5;
+    }
     lfn->len = strlen((char*)lfn->name);
 
     return 0;
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH v2 13/13] vvfat: change OEM name to 'MSWIN4.1'
  2017-05-22 21:11 [Qemu-devel] [PATCH v2 00/13] vvfat: misc fixes for read-only mode Hervé Poussineau
                   ` (11 preceding siblings ...)
  2017-05-22 21:12 ` [Qemu-devel] [PATCH v2 12/13] vvfat: handle KANJI lead byte 0xe5 Hervé Poussineau
@ 2017-05-22 21:12 ` Hervé Poussineau
  2017-05-23  4:23   ` Philippe Mathieu-Daudé
  2017-05-22 22:38 ` [Qemu-devel] [PATCH v2 00/13] vvfat: misc fixes for read-only mode no-reply
  2017-07-03 16:50 ` Kevin Wolf
  14 siblings, 1 reply; 29+ messages in thread
From: Hervé Poussineau @ 2017-05-22 21:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kevin Wolf, Max Reitz, qemu-block, Hervé Poussineau

According to specification:
"'MSWIN4.1' is the recommanded setting, because it is the setting least likely
to cause compatibility problems. If you want to put something else in here,
that is your option, but the result may be that some FAT drivers might not
recognize the volume."

Specification: "FAT: General overview of on-disk format" v1.03, page 9
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
---
 block/vvfat.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/block/vvfat.c b/block/vvfat.c
index 53e8faa54c..1f7f46ecea 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -1024,7 +1024,7 @@ static int init_directories(BDRVVVFATState* s,
     bootsector->jump[0]=0xeb;
     bootsector->jump[1]=0x3e;
     bootsector->jump[2]=0x90;
-    memcpy(bootsector->name,"QEMU    ",8);
+    memcpy(bootsector->name, "MSWIN4.1", 8);
     bootsector->sector_size=cpu_to_le16(0x200);
     bootsector->sectors_per_cluster=s->sectors_per_cluster;
     bootsector->reserved_sectors=cpu_to_le16(1);
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [Qemu-block] [PATCH v2 01/13] vvfat: fix qemu-img map and qemu-img convert
  2017-05-22 21:11 ` [Qemu-devel] [PATCH v2 01/13] vvfat: fix qemu-img map and qemu-img convert Hervé Poussineau
@ 2017-05-22 21:17   ` Eric Blake
  0 siblings, 0 replies; 29+ messages in thread
From: Eric Blake @ 2017-05-22 21:17 UTC (permalink / raw)
  To: Hervé Poussineau, qemu-devel
  Cc: Kevin Wolf, qemu-block, Max Reitz, qemu-stable

[-- Attachment #1: Type: text/plain, Size: 1051 bytes --]

On 05/22/2017 04:11 PM, Hervé Poussineau wrote:
> - bs->total_sectors is the number of sectors of the whole disk
> - s->sector_count is the number of sectors of the FAT partition
> 
> This fixes the following assert in qemu-img map:
> qemu-img.c:2641: get_block_status: Assertion `nb_sectors' failed.
> 
> This also fixes an infinite loop in qemu-img convert.
> 
> Fixes: 4480e0f924a42e1db8b8cfcac4d0634dd1bb27a0
> Fixes: https://bugs.launchpad.net/qemu/+bug/1599539
> Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
> ---
>  block/vvfat.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)

I gave Reviewed-by: on version 1, and suggested that this be cc'd to
qemu-stable:
https://lists.gnu.org/archive/html/qemu-devel/2017-05/msg03622.html

It helps to add that into the commit message for v2, to make it clear
that you haven't changed anything in this commit since that review.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [PATCH v2 00/13] vvfat: misc fixes for read-only mode
  2017-05-22 21:11 [Qemu-devel] [PATCH v2 00/13] vvfat: misc fixes for read-only mode Hervé Poussineau
                   ` (12 preceding siblings ...)
  2017-05-22 21:12 ` [Qemu-devel] [PATCH v2 13/13] vvfat: change OEM name to 'MSWIN4.1' Hervé Poussineau
@ 2017-05-22 22:38 ` no-reply
  2017-07-03 16:50 ` Kevin Wolf
  14 siblings, 0 replies; 29+ messages in thread
From: no-reply @ 2017-05-22 22:38 UTC (permalink / raw)
  To: hpoussin; +Cc: famz, qemu-devel, kwolf, qemu-block, mreitz

Hi,

This series seems to have some coding style problems. See output below for
more information:

Message-id: 20170522211205.14265-1-hpoussin@reactos.org
Subject: [Qemu-devel] [PATCH v2 00/13] vvfat: misc fixes for read-only mode
Type: series

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

git config --local diff.renamelimit 0
git config --local diff.renames True

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
    echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
    if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
        failed=1
        echo
    fi
    n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
a44e0b9 vvfat: change OEM name to 'MSWIN4.1'
ff2c35b vvfat: handle KANJI lead byte 0xe5
6e11c6c vvfat: limit number of entries in root directory in FAT12/FAT16
e5687f8 vvfat: correctly generate numeric-tail of short file names
20780e0 vvfat: correctly create base short names for non-ASCII filenames
2d4bf63 vvfat: correctly create long names for non-ASCII filenames
48accbf vvfat: always create . and .. entries at first and in that order
3105081 vvfat: fix field names in FAT12/FAT16 and FAT32 boot sectors
6f108da vvfat: introduce offset_to_bootsector, offset_to_fat and offset_to_root_dir
a4cbca8 vvfat: rename useless enumeration values
663af27 vvfat: fix typos
76286f8 vvfat: replace tabs by 8 spaces
e4e4ff3 vvfat: fix qemu-img map and qemu-img convert

=== OUTPUT BEGIN ===
Checking PATCH 1/13: vvfat: fix qemu-img map and qemu-img convert...
Checking PATCH 2/13: vvfat: replace tabs by 8 spaces...
ERROR: braces {} are necessary for all arms of this statement
#33: FILE: block/vvfat.c:106:
+        if (!array->pointer)
[...]

ERROR: spaces required around that '=' (ctx:VxV)
#56: FILE: block/vvfat.c:127:
+        int increment=count*array->item_size;
                      ^

ERROR: spaces required around that '*' (ctx:VxV)
#56: FILE: block/vvfat.c:127:
+        int increment=count*array->item_size;
                            ^

ERROR: spaces required around that '=' (ctx:VxV)
#57: FILE: block/vvfat.c:128:
+        array->pointer=g_realloc(array->pointer,array->size+increment);
                       ^

ERROR: space required after that ',' (ctx:VxV)
#57: FILE: block/vvfat.c:128:
+        array->pointer=g_realloc(array->pointer,array->size+increment);
                                                ^

ERROR: spaces required around that '+' (ctx:VxV)
#57: FILE: block/vvfat.c:128:
+        array->pointer=g_realloc(array->pointer,array->size+increment);
                                                            ^

ERROR: space required before the open parenthesis '('
#58: FILE: block/vvfat.c:129:
+        if(!array->pointer)

ERROR: braces {} are necessary for all arms of this statement
#58: FILE: block/vvfat.c:129:
+        if(!array->pointer)
[...]

ERROR: spaces required around that '+=' (ctx:VxV)
#61: FILE: block/vvfat.c:131:
+        array->size+=increment;
                    ^

ERROR: spaces required around that '+' (ctx:VxV)
#66: FILE: block/vvfat.c:134:
+                array->pointer+index*array->item_size,
                               ^

ERROR: spaces required around that '*' (ctx:VxV)
#66: FILE: block/vvfat.c:134:
+                array->pointer+index*array->item_size,
                                     ^

ERROR: spaces required around that '-' (ctx:VxV)
#67: FILE: block/vvfat.c:135:
+                (array->next-index)*array->item_size);
                             ^

ERROR: spaces required around that '*' (ctx:VxV)
#67: FILE: block/vvfat.c:135:
+                (array->next-index)*array->item_size);
                                    ^

ERROR: spaces required around that '<' (ctx:VxV)
#78: FILE: block/vvfat.c:150:
+            index_to<0 || index_to>=array->next ||
                     ^

ERROR: spaces required around that '>=' (ctx:VxV)
#78: FILE: block/vvfat.c:150:
+            index_to<0 || index_to>=array->next ||
                                   ^

ERROR: spaces required around that '<' (ctx:VxV)
#79: FILE: block/vvfat.c:151:
+            index_from<0 || index_from>=array->next)
                       ^

ERROR: spaces required around that '>=' (ctx:VxV)
#79: FILE: block/vvfat.c:151:
+            index_from<0 || index_from>=array->next)
                                       ^

ERROR: spaces required around that '+' (ctx:VxV)
#93: FILE: block/vvfat.c:164:
+        memmove(to+is*count,to,from-to);
                   ^

ERROR: spaces required around that '*' (ctx:VxV)
#93: FILE: block/vvfat.c:164:
+        memmove(to+is*count,to,from-to);
                      ^

ERROR: space required after that ',' (ctx:VxV)
#93: FILE: block/vvfat.c:164:
+        memmove(to+is*count,to,from-to);
                            ^

ERROR: space required after that ',' (ctx:VxV)
#93: FILE: block/vvfat.c:164:
+        memmove(to+is*count,to,from-to);
                               ^

ERROR: spaces required around that '-' (ctx:VxV)
#93: FILE: block/vvfat.c:164:
+        memmove(to+is*count,to,from-to);
                                    ^

ERROR: space required after that ',' (ctx:VxV)
#96: FILE: block/vvfat.c:166:
+        memmove(from,from+is*count,to-from);
                     ^

ERROR: spaces required around that '+' (ctx:VxV)
#96: FILE: block/vvfat.c:166:
+        memmove(from,from+is*count,to-from);
                          ^

ERROR: spaces required around that '*' (ctx:VxV)
#96: FILE: block/vvfat.c:166:
+        memmove(from,from+is*count,to-from);
                             ^

ERROR: space required after that ',' (ctx:VxV)
#96: FILE: block/vvfat.c:166:
+        memmove(from,from+is*count,to-from);
                                   ^

ERROR: spaces required around that '-' (ctx:VxV)
#96: FILE: block/vvfat.c:166:
+        memmove(from,from+is*count,to-from);
                                      ^

ERROR: space required after that ',' (ctx:VxV)
#137: FILE: block/vvfat.c:229:
+            uint8_t major,minor;
                          ^

ERROR: spaces required around that '*' (ctx:VxV)
#191: FILE: block/vvfat.c:423:
+        dest[2*i+1]=0;
               ^

ERROR: spaces required around that '+' (ctx:VxV)
#191: FILE: block/vvfat.c:423:
+        dest[2*i+1]=0;
                 ^

ERROR: spaces required around that '=' (ctx:VxV)
#191: FILE: block/vvfat.c:423:
+        dest[2*i+1]=0;
                    ^

ERROR: spaces required around that '=' (ctx:VxV)
#197: FILE: block/vvfat.c:428:
+        dest[i]=0xff;
                ^

ERROR: spaces required around that '=' (ctx:VxV)
#210: FILE: block/vvfat.c:440:
+        entry=array_get_next(&(s->directory));
              ^

ERROR: spaces required around that '=' (ctx:VxV)
#211: FILE: block/vvfat.c:441:
+        entry->attributes=0xf;
                          ^

ERROR: spaces required around that '=' (ctx:VxV)
#212: FILE: block/vvfat.c:442:
+        entry->reserved[0]=0;
                           ^

ERROR: spaces required around that '=' (ctx:VxV)
#213: FILE: block/vvfat.c:443:
+        entry->begin=0;
                     ^

ERROR: spaces required around that '=' (ctx:VxV)
#214: FILE: block/vvfat.c:444:
+        entry->name[0]=(number_of_entries-i)|(i==0?0x40:0);
                       ^

ERROR: spaces required around that '-' (ctx:VxV)
#214: FILE: block/vvfat.c:444:
+        entry->name[0]=(number_of_entries-i)|(i==0?0x40:0);
                                          ^

ERROR: spaces required around that '|' (ctx:VxV)
#214: FILE: block/vvfat.c:444:
+        entry->name[0]=(number_of_entries-i)|(i==0?0x40:0);
                                             ^

ERROR: spaces required around that '==' (ctx:VxV)
#214: FILE: block/vvfat.c:444:
+        entry->name[0]=(number_of_entries-i)|(i==0?0x40:0);
                                                ^

ERROR: spaces required around that '?' (ctx:VxV)
#214: FILE: block/vvfat.c:444:
+        entry->name[0]=(number_of_entries-i)|(i==0?0x40:0);
                                                   ^

ERROR: spaces required around that ':' (ctx:VxV)
#214: FILE: block/vvfat.c:444:
+        entry->name[0]=(number_of_entries-i)|(i==0?0x40:0);
                                                        ^

ERROR: spaces required around that '=' (ctx:VxV)
#223: FILE: block/vvfat.c:447:
+        int offset=(i%26);
                   ^

ERROR: spaces required around that '%' (ctx:VxV)
#223: FILE: block/vvfat.c:447:
+        int offset=(i%26);
                      ^

ERROR: spaces required around that '<' (ctx:VxV)
#224: FILE: block/vvfat.c:448:
+        if(offset<10) offset=1+offset;
                  ^

ERROR: spaces required around that '=' (ctx:VxV)
#224: FILE: block/vvfat.c:448:
+        if(offset<10) offset=1+offset;
                             ^

ERROR: spaces required around that '+' (ctx:VxV)
#224: FILE: block/vvfat.c:448:
+        if(offset<10) offset=1+offset;
                               ^

ERROR: space required before the open parenthesis '('
#224: FILE: block/vvfat.c:448:
+        if(offset<10) offset=1+offset;

ERROR: trailing statements should be on next line
#224: FILE: block/vvfat.c:448:
+        if(offset<10) offset=1+offset;

ERROR: braces {} are necessary for all arms of this statement
#224: FILE: block/vvfat.c:448:
+        if(offset<10) offset=1+offset;
[...]
+        else if(offset<22) offset=14+offset-10;
[...]
+        else offset=28+offset-22;
[...]

ERROR: spaces required around that '<' (ctx:VxV)
#225: FILE: block/vvfat.c:449:
+        else if(offset<22) offset=14+offset-10;
                       ^

ERROR: spaces required around that '=' (ctx:VxV)
#225: FILE: block/vvfat.c:449:
+        else if(offset<22) offset=14+offset-10;
                                  ^

ERROR: spaces required around that '+' (ctx:VxV)
#225: FILE: block/vvfat.c:449:
+        else if(offset<22) offset=14+offset-10;
                                     ^

ERROR: spaces required around that '-' (ctx:VxV)
#225: FILE: block/vvfat.c:449:
+        else if(offset<22) offset=14+offset-10;
                                            ^

ERROR: space required before the open parenthesis '('
#225: FILE: block/vvfat.c:449:
+        else if(offset<22) offset=14+offset-10;

ERROR: trailing statements should be on next line
#225: FILE: block/vvfat.c:449:
+        else if(offset<22) offset=14+offset-10;

ERROR: braces {} are necessary for all arms of this statement
#225: FILE: block/vvfat.c:449:
+        else if(offset<22) offset=14+offset-10;
[...]
+        else offset=28+offset-22;
[...]

ERROR: spaces required around that '=' (ctx:VxV)
#226: FILE: block/vvfat.c:450:
+        else offset=28+offset-22;
                    ^

ERROR: spaces required around that '+' (ctx:VxV)
#226: FILE: block/vvfat.c:450:
+        else offset=28+offset-22;
                       ^

ERROR: spaces required around that '-' (ctx:VxV)
#226: FILE: block/vvfat.c:450:
+        else offset=28+offset-22;
                              ^

ERROR: trailing statements should be on next line
#226: FILE: block/vvfat.c:450:
+        else offset=28+offset-22;

ERROR: spaces required around that '=' (ctx:VxV)
#227: FILE: block/vvfat.c:451:
+        entry=array_get(&(s->directory),s->directory.next-1-(i/26));
              ^

ERROR: space required after that ',' (ctx:VxV)
#227: FILE: block/vvfat.c:451:
+        entry=array_get(&(s->directory),s->directory.next-1-(i/26));
                                        ^

ERROR: spaces required around that '-' (ctx:VxV)
#227: FILE: block/vvfat.c:451:
+        entry=array_get(&(s->directory),s->directory.next-1-(i/26));
                                                          ^

ERROR: spaces required around that '-' (ctx:VxV)
#227: FILE: block/vvfat.c:451:
+        entry=array_get(&(s->directory),s->directory.next-1-(i/26));
                                                            ^

ERROR: spaces required around that '/' (ctx:VxV)
#227: FILE: block/vvfat.c:451:
+        entry=array_get(&(s->directory),s->directory.next-1-(i/26));
                                                               ^

ERROR: spaces required around that '=' (ctx:VxV)
#228: FILE: block/vvfat.c:452:
+        entry->name[offset]=buffer[i];
                            ^

ERROR: spaces required around that '/' (ctx:VxV)
#246: FILE: block/vvfat.c:531:
+        return cpu_to_le16((t->tm_sec/2)|(t->tm_min<<5)|(t->tm_hour<<11));
                                      ^

ERROR: spaces required around that '|' (ctx:VxV)
#246: FILE: block/vvfat.c:531:
+        return cpu_to_le16((t->tm_sec/2)|(t->tm_min<<5)|(t->tm_hour<<11));
                                         ^

ERROR: spaces required around that '<<' (ctx:VxV)
#246: FILE: block/vvfat.c:531:
+        return cpu_to_le16((t->tm_sec/2)|(t->tm_min<<5)|(t->tm_hour<<11));
                                                    ^

ERROR: spaces required around that '|' (ctx:VxV)
#246: FILE: block/vvfat.c:531:
+        return cpu_to_le16((t->tm_sec/2)|(t->tm_min<<5)|(t->tm_hour<<11));
                                                        ^

ERROR: spaces required around that '<<' (ctx:VxV)
#246: FILE: block/vvfat.c:531:
+        return cpu_to_le16((t->tm_sec/2)|(t->tm_min<<5)|(t->tm_hour<<11));
                                                                    ^

ERROR: "foo* bar" should be "foo *bar"
#255: FILE: block/vvfat.c:538:
+        uint32_t* entry=array_get(&(s->fat),cluster);

ERROR: spaces required around that '=' (ctx:VxV)
#255: FILE: block/vvfat.c:538:
+        uint32_t* entry=array_get(&(s->fat),cluster);
                        ^

ERROR: space required after that ',' (ctx:VxV)
#255: FILE: block/vvfat.c:538:
+        uint32_t* entry=array_get(&(s->fat),cluster);
                                            ^

ERROR: spaces required around that '=' (ctx:VxV)
#256: FILE: block/vvfat.c:539:
+        *entry=cpu_to_le32(value);
               ^

ERROR: "foo* bar" should be "foo *bar"
#260: FILE: block/vvfat.c:541:
+        uint16_t* entry=array_get(&(s->fat),cluster);

ERROR: spaces required around that '=' (ctx:VxV)
#260: FILE: block/vvfat.c:541:
+        uint16_t* entry=array_get(&(s->fat),cluster);
                        ^

ERROR: space required after that ',' (ctx:VxV)
#260: FILE: block/vvfat.c:541:
+        uint16_t* entry=array_get(&(s->fat),cluster);
                                            ^

ERROR: spaces required around that '=' (ctx:VxV)
#261: FILE: block/vvfat.c:542:
+        *entry=cpu_to_le16(value&0xffff);
               ^

ERROR: spaces required around that '&' (ctx:VxV)
#261: FILE: block/vvfat.c:542:
+        *entry=cpu_to_le16(value&0xffff);
                                 ^

ERROR: spaces required around that '*' (ctx:VxV)
#265: FILE: block/vvfat.c:544:
+        int offset = (cluster*3/2);
                              ^

ERROR: spaces required around that '/' (ctx:VxV)
#265: FILE: block/vvfat.c:544:
+        int offset = (cluster*3/2);
                                ^

ERROR: "foo* bar" should be "foo *bar"
#266: FILE: block/vvfat.c:545:
+        unsigned char* p = array_get(&(s->fat), offset);

ERROR: spaces required around that '&' (ctx:VxV)
#278: FILE: block/vvfat.c:548:
+                p[0] = value&0xff;
                             ^

ERROR: spaces required around that '&' (ctx:VxV)
#279: FILE: block/vvfat.c:549:
+                p[1] = (p[1]&0xf0) | ((value>>8)&0xf);
                             ^

ERROR: spaces required around that '>>' (ctx:VxV)
#279: FILE: block/vvfat.c:549:
+                p[1] = (p[1]&0xf0) | ((value>>8)&0xf);
                                             ^

ERROR: spaces required around that '&' (ctx:VxV)
#279: FILE: block/vvfat.c:549:
+                p[1] = (p[1]&0xf0) | ((value>>8)&0xf);
                                                 ^

ERROR: spaces required around that '&' (ctx:VxV)
#282: FILE: block/vvfat.c:552:
+                p[0] = (p[0]&0xf) | ((value&0xf)<<4);
                             ^

ERROR: spaces required around that '&' (ctx:VxV)
#282: FILE: block/vvfat.c:552:
+                p[0] = (p[0]&0xf) | ((value&0xf)<<4);
                                            ^

ERROR: spaces required around that '<<' (ctx:VxV)
#282: FILE: block/vvfat.c:552:
+                p[0] = (p[0]&0xf) | ((value&0xf)<<4);
                                                 ^

ERROR: spaces required around that '>>' (ctx:VxV)
#283: FILE: block/vvfat.c:553:
+                p[1] = (value>>4);
                              ^

ERROR: "foo* bar" should be "foo *bar"
#294: FILE: block/vvfat.c:562:
+        uint32_t* entry=array_get(&(s->fat),cluster);

ERROR: spaces required around that '=' (ctx:VxV)
#294: FILE: block/vvfat.c:562:
+        uint32_t* entry=array_get(&(s->fat),cluster);
                        ^

ERROR: space required after that ',' (ctx:VxV)
#294: FILE: block/vvfat.c:562:
+        uint32_t* entry=array_get(&(s->fat),cluster);
                                            ^

ERROR: "foo* bar" should be "foo *bar"
#299: FILE: block/vvfat.c:565:
+        uint16_t* entry=array_get(&(s->fat),cluster);

ERROR: spaces required around that '=' (ctx:VxV)
#299: FILE: block/vvfat.c:565:
+        uint16_t* entry=array_get(&(s->fat),cluster);
                        ^

ERROR: space required after that ',' (ctx:VxV)
#299: FILE: block/vvfat.c:565:
+        uint16_t* entry=array_get(&(s->fat),cluster);
                                            ^

ERROR: "(foo*)" should be "(foo *)"
#304: FILE: block/vvfat.c:568:
+        const uint8_t* x=(uint8_t*)(s->fat.pointer)+cluster*3/2;

ERROR: spaces required around that '=' (ctx:VxV)
#304: FILE: block/vvfat.c:568:
+        const uint8_t* x=(uint8_t*)(s->fat.pointer)+cluster*3/2;
                         ^

ERROR: spaces required around that '+' (ctx:VxV)
#304: FILE: block/vvfat.c:568:
+        const uint8_t* x=(uint8_t*)(s->fat.pointer)+cluster*3/2;
                                                    ^

ERROR: spaces required around that '*' (ctx:VxV)
#304: FILE: block/vvfat.c:568:
+        const uint8_t* x=(uint8_t*)(s->fat.pointer)+cluster*3/2;
                                                            ^

ERROR: spaces required around that '/' (ctx:VxV)
#304: FILE: block/vvfat.c:568:
+        const uint8_t* x=(uint8_t*)(s->fat.pointer)+cluster*3/2;
                                                              ^

ERROR: spaces required around that '|' (ctx:VxV)
#305: FILE: block/vvfat.c:569:
+        return ((x[0]|(x[1]<<8))>>(cluster&1?4:0))&0x0fff;
                      ^

ERROR: spaces required around that '<<' (ctx:VxV)
#305: FILE: block/vvfat.c:569:
+        return ((x[0]|(x[1]<<8))>>(cluster&1?4:0))&0x0fff;
                            ^

ERROR: spaces required around that '>>' (ctx:VxV)
#305: FILE: block/vvfat.c:569:
+        return ((x[0]|(x[1]<<8))>>(cluster&1?4:0))&0x0fff;
                                 ^

ERROR: spaces required around that '&' (ctx:VxV)
#305: FILE: block/vvfat.c:569:
+        return ((x[0]|(x[1]<<8))>>(cluster&1?4:0))&0x0fff;
                                           ^

ERROR: spaces required around that '?' (ctx:VxV)
#305: FILE: block/vvfat.c:569:
+        return ((x[0]|(x[1]<<8))>>(cluster&1?4:0))&0x0fff;
                                             ^

ERROR: spaces required around that ':' (ctx:VxV)
#305: FILE: block/vvfat.c:569:
+        return ((x[0]|(x[1]<<8))>>(cluster&1?4:0))&0x0fff;
                                               ^

ERROR: spaces required around that '&' (ctx:VxV)
#305: FILE: block/vvfat.c:569:
+        return ((x[0]|(x[1]<<8))>>(cluster&1?4:0))&0x0fff;
                                                   ^

ERROR: space required after that ',' (ctx:VxV)
#323: FILE: block/vvfat.c:583:
+        array_init(&(s->fat),1);
                             ^

ERROR: space required after that ',' (ctx:VxV)
#330: FILE: block/vvfat.c:587:
+        array_init(&(s->fat),(s->fat_type==32?4:2));
                             ^

ERROR: spaces required around that '==' (ctx:VxV)
#330: FILE: block/vvfat.c:587:
+        array_init(&(s->fat),(s->fat_type==32?4:2));
                                          ^

ERROR: spaces required around that '?' (ctx:VxV)
#330: FILE: block/vvfat.c:587:
+        array_init(&(s->fat),(s->fat_type==32?4:2));
                                              ^

ERROR: spaces required around that ':' (ctx:VxV)
#330: FILE: block/vvfat.c:587:
+        array_init(&(s->fat),(s->fat_type==32?4:2));
                                                ^

ERROR: switch and case should be at the same indent
#336: FILE: block/vvfat.c:593:
     switch(s->fat_type) {
+        case 12: s->max_fat_value=0xfff; break;
+        case 16: s->max_fat_value=0xffff; break;
+        case 32: s->max_fat_value=0x0fffffff; break;
+        default: s->max_fat_value=0; /* error... */

ERROR: spaces required around that '=' (ctx:VxV)
#341: FILE: block/vvfat.c:594:
+        case 12: s->max_fat_value=0xfff; break;
                                  ^

ERROR: trailing statements should be on next line
#341: FILE: block/vvfat.c:594:
+        case 12: s->max_fat_value=0xfff; break;

ERROR: spaces required around that '=' (ctx:VxV)
#342: FILE: block/vvfat.c:595:
+        case 16: s->max_fat_value=0xffff; break;
                                  ^

ERROR: trailing statements should be on next line
#342: FILE: block/vvfat.c:595:
+        case 16: s->max_fat_value=0xffff; break;

ERROR: spaces required around that '=' (ctx:VxV)
#343: FILE: block/vvfat.c:596:
+        case 32: s->max_fat_value=0x0fffffff; break;
                                  ^

ERROR: trailing statements should be on next line
#343: FILE: block/vvfat.c:596:
+        case 32: s->max_fat_value=0x0fffffff; break;

ERROR: spaces required around that '=' (ctx:VxV)
#344: FILE: block/vvfat.c:597:
+        default: s->max_fat_value=0; /* error... */
                                  ^

ERROR: trailing statements should be on next line
#344: FILE: block/vvfat.c:597:
+        default: s->max_fat_value=0; /* error... */

ERROR: "foo* bar" should be "foo *bar"
#353: FILE: block/vvfat.c:605:
+        unsigned int directory_start, const char* filename, int is_dot)

ERROR: spaces required around that '=' (ctx:VxV)
#361: FILE: block/vvfat.c:612:
+        entry=array_get_next(&(s->directory));
              ^

ERROR: space required after that ',' (ctx:VxV)
#365: FILE: block/vvfat.c:614:
+        memcpy(entry->name,filename,strlen(filename));
                           ^

ERROR: space required after that ',' (ctx:VxV)
#365: FILE: block/vvfat.c:614:
+        memcpy(entry->name,filename,strlen(filename));
                                    ^

ERROR: spaces required around that '==' (ctx:VxV)
#390: FILE: block/vvfat.c:639:
+        if(i==10 || i==7) for(;i>0 && entry->name[i]==' ';i--);
             ^

ERROR: spaces required around that '==' (ctx:VxV)
#390: FILE: block/vvfat.c:639:
+        if(i==10 || i==7) for(;i>0 && entry->name[i]==' ';i--);
                      ^

ERROR: space required after that ';' (ctx:BxV)
#390: FILE: block/vvfat.c:639:
+        if(i==10 || i==7) for(;i>0 && entry->name[i]==' ';i--);
                               ^

ERROR: spaces required around that '>' (ctx:VxV)
#390: FILE: block/vvfat.c:639:
+        if(i==10 || i==7) for(;i>0 && entry->name[i]==' ';i--);
                                 ^

ERROR: spaces required around that '==' (ctx:VxV)
#390: FILE: block/vvfat.c:639:
+        if(i==10 || i==7) for(;i>0 && entry->name[i]==' ';i--);
                                                     ^

ERROR: space required after that ';' (ctx:VxV)
#390: FILE: block/vvfat.c:639:
+        if(i==10 || i==7) for(;i>0 && entry->name[i]==' ';i--);
                                                          ^

ERROR: space required before the open parenthesis '('
#390: FILE: block/vvfat.c:639:
+        if(i==10 || i==7) for(;i>0 && entry->name[i]==' ';i--);

ERROR: trailing statements should be on next line
#390: FILE: block/vvfat.c:639:
+        if(i==10 || i==7) for(;i>0 && entry->name[i]==' ';i--);

ERROR: braces {} are necessary for all arms of this statement
#390: FILE: block/vvfat.c:639:
+        if(i==10 || i==7) for(;i>0 && entry->name[i]==' ';i--);
[...]

ERROR: spaces required around that '<=' (ctx:VxV)
#391: FILE: block/vvfat.c:640:
+        if(entry->name[i]<=' ' || entry->name[i]>0x7f
                          ^

ERROR: spaces required around that '>' (ctx:VxV)
#391: FILE: block/vvfat.c:640:
+        if(entry->name[i]<=' ' || entry->name[i]>0x7f
                                                 ^

ERROR: space required before the open parenthesis '('
#391: FILE: block/vvfat.c:640:
+        if(entry->name[i]<=' ' || entry->name[i]>0x7f

ERROR: braces {} are necessary for all arms of this statement
#391: FILE: block/vvfat.c:640:
+        if(entry->name[i]<=' ' || entry->name[i]>0x7f
[...]
         else if(entry->name[i]>='a' && entry->name[i]<='z')
[...]

ERROR: space required after that ',' (ctx:VxV)
#392: FILE: block/vvfat.c:641:
+                || strchr(".*?<>|\":/\\[];,+='",entry->name[i]))
                                                ^

ERROR: spaces required around that '=' (ctx:VxV)
#393: FILE: block/vvfat.c:642:
+            entry->name[i]='_';
                           ^

ERROR: "foo* bar" should be "foo *bar"
#425: FILE: block/vvfat.c:649:
+        direntry_t* entry1=array_get(&(s->directory),directory_start);

ERROR: spaces required around that '=' (ctx:VxV)
#425: FILE: block/vvfat.c:649:
+        direntry_t* entry1=array_get(&(s->directory),directory_start);
                           ^

ERROR: space required after that ',' (ctx:VxV)
#425: FILE: block/vvfat.c:649:
+        direntry_t* entry1=array_get(&(s->directory),directory_start);
                                                     ^

ERROR: space required after that ';' (ctx:BxV)
#428: FILE: block/vvfat.c:652:
+        for(;entry1<entry;entry1++)
             ^

ERROR: spaces required around that '<' (ctx:VxV)
#428: FILE: block/vvfat.c:652:
+        for(;entry1<entry;entry1++)
                    ^

ERROR: space required after that ';' (ctx:VxV)
#428: FILE: block/vvfat.c:652:
+        for(;entry1<entry;entry1++)
                          ^

ERROR: space required before the open parenthesis '('
#428: FILE: block/vvfat.c:652:
+        for(;entry1<entry;entry1++)

ERROR: space required after that ',' (ctx:VxV)
#429: FILE: block/vvfat.c:653:
+            if(!is_long_name(entry1) && !memcmp(entry1->name,entry->name,11))
                                                             ^

ERROR: space required after that ',' (ctx:VxV)
#429: FILE: block/vvfat.c:653:
+            if(!is_long_name(entry1) && !memcmp(entry1->name,entry->name,11))
                                                                         ^

ERROR: space required before the open parenthesis '('
#429: FILE: block/vvfat.c:653:
+            if(!is_long_name(entry1) && !memcmp(entry1->name,entry->name,11))

ERROR: braces {} are necessary for all arms of this statement
#429: FILE: block/vvfat.c:653:
+            if(!is_long_name(entry1) && !memcmp(entry1->name,entry->name,11))
[...]

ERROR: spaces required around that '==' (ctx:VxV)
#431: FILE: block/vvfat.c:655:
+        if(entry1==entry) /* no dupe found */
                  ^

ERROR: space required before the open parenthesis '('
#431: FILE: block/vvfat.c:655:
+        if(entry1==entry) /* no dupe found */

ERROR: braces {} are necessary for all arms of this statement
#431: FILE: block/vvfat.c:655:
+        if(entry1==entry) /* no dupe found */
[...]

ERROR: spaces required around that '==' (ctx:VxV)
#435: FILE: block/vvfat.c:659:
+        if(entry->name[7]==' ') {
                          ^

ERROR: space required before the open parenthesis '('
#435: FILE: block/vvfat.c:659:
+        if(entry->name[7]==' ') {

ERROR: spaces required around that '=' (ctx:VxV)
#437: FILE: block/vvfat.c:661:
+            for(j=6;j>0 && entry->name[j]==' ';j--)
                  ^

ERROR: space required after that ';' (ctx:VxV)
#437: FILE: block/vvfat.c:661:
+            for(j=6;j>0 && entry->name[j]==' ';j--)
                    ^

ERROR: spaces required around that '>' (ctx:VxV)
#437: FILE: block/vvfat.c:661:
+            for(j=6;j>0 && entry->name[j]==' ';j--)
                      ^

ERROR: spaces required around that '==' (ctx:VxV)
#437: FILE: block/vvfat.c:661:
+            for(j=6;j>0 && entry->name[j]==' ';j--)
                                          ^

ERROR: space required after that ';' (ctx:VxV)
#437: FILE: block/vvfat.c:661:
+            for(j=6;j>0 && entry->name[j]==' ';j--)
                                               ^

ERROR: space required before the open parenthesis '('
#437: FILE: block/vvfat.c:661:
+            for(j=6;j>0 && entry->name[j]==' ';j--)

ERROR: braces {} are necessary even for single statement blocks
#437: FILE: block/vvfat.c:661:
+            for(j=6;j>0 && entry->name[j]==' ';j--)
+                entry->name[j]='~';

ERROR: spaces required around that '=' (ctx:VxV)
#438: FILE: block/vvfat.c:662:
+                entry->name[j]='~';
                               ^

ERROR: spaces required around that '=' (ctx:VxV)
#442: FILE: block/vvfat.c:666:
+        for(j=7;j>0 && entry->name[j]=='9';j--)
              ^

ERROR: space required after that ';' (ctx:VxV)
#442: FILE: block/vvfat.c:666:
+        for(j=7;j>0 && entry->name[j]=='9';j--)
                ^

ERROR: spaces required around that '>' (ctx:VxV)
#442: FILE: block/vvfat.c:666:
+        for(j=7;j>0 && entry->name[j]=='9';j--)
                  ^

ERROR: spaces required around that '==' (ctx:VxV)
#442: FILE: block/vvfat.c:666:
+        for(j=7;j>0 && entry->name[j]=='9';j--)
                                      ^

ERROR: space required after that ';' (ctx:VxV)
#442: FILE: block/vvfat.c:666:
+        for(j=7;j>0 && entry->name[j]=='9';j--)
                                           ^

ERROR: space required before the open parenthesis '('
#442: FILE: block/vvfat.c:666:
+        for(j=7;j>0 && entry->name[j]=='9';j--)

ERROR: braces {} are necessary even for single statement blocks
#442: FILE: block/vvfat.c:666:
+        for(j=7;j>0 && entry->name[j]=='9';j--)
+            entry->name[j]='0';

ERROR: spaces required around that '=' (ctx:VxV)
#443: FILE: block/vvfat.c:667:
+            entry->name[j]='0';
                           ^

ERROR: spaces required around that '>' (ctx:VxV)
#444: FILE: block/vvfat.c:668:
+        if(j>0) {
             ^

ERROR: space required before the open parenthesis '('
#444: FILE: block/vvfat.c:668:
+        if(j>0) {

ERROR: spaces required around that '<' (ctx:VxV)
#445: FILE: block/vvfat.c:669:
+            if(entry->name[j]<'0' || entry->name[j]>'9')
                              ^

ERROR: spaces required around that '>' (ctx:VxV)
#445: FILE: block/vvfat.c:669:
+            if(entry->name[j]<'0' || entry->name[j]>'9')
                                                    ^

ERROR: space required before the open parenthesis '('
#445: FILE: block/vvfat.c:669:
+            if(entry->name[j]<'0' || entry->name[j]>'9')

ERROR: braces {} are necessary for all arms of this statement
#445: FILE: block/vvfat.c:669:
+            if(entry->name[j]<'0' || entry->name[j]>'9')
[...]
+            else
[...]

ERROR: spaces required around that '=' (ctx:VxV)
#446: FILE: block/vvfat.c:670:
+                entry->name[j]='0';
                               ^

ERROR: spaces required around that '=' (ctx:VxV)
#463: FILE: block/vvfat.c:681:
+        entry_long=array_get(&(s->directory),long_index);
                   ^

ERROR: space required after that ',' (ctx:VxV)
#463: FILE: block/vvfat.c:681:
+        entry_long=array_get(&(s->directory),long_index);
                                             ^

ERROR: spaces required around that '<' (ctx:VxV)
#464: FILE: block/vvfat.c:682:
+        while(entry_long<entry && is_long_name(entry_long)) {
                         ^

ERROR: space required before the open parenthesis '('
#464: FILE: block/vvfat.c:682:
+        while(entry_long<entry && is_long_name(entry_long)) {

ERROR: spaces required around that '=' (ctx:VxV)
#465: FILE: block/vvfat.c:683:
+            entry_long->reserved[1]=chksum;
                                    ^

ERROR: spaces required around that '=' (ctx:VxV)
#488: FILE: block/vvfat.c:721:
+        unsigned int length=strlen(dirname)+2+strlen(entry->d_name);
                            ^

ERROR: spaces required around that '+' (ctx:VxV)
#488: FILE: block/vvfat.c:721:
+        unsigned int length=strlen(dirname)+2+strlen(entry->d_name);
                                            ^

ERROR: spaces required around that '+' (ctx:VxV)
#488: FILE: block/vvfat.c:721:
+        unsigned int length=strlen(dirname)+2+strlen(entry->d_name);
                                              ^

ERROR: "foo* bar" should be "foo *bar"
#491: FILE: block/vvfat.c:723:
+        direntry_t* direntry;

ERROR: spaces required around that '=' (ctx:VxO)
#495: FILE: block/vvfat.c:725:
+        int is_dot=!strcmp(entry->d_name,".");
                   ^

ERROR: space required before that '!' (ctx:OxV)
#495: FILE: block/vvfat.c:725:
+        int is_dot=!strcmp(entry->d_name,".");
                    ^

ERROR: space required after that ',' (ctx:VxV)
#495: FILE: block/vvfat.c:725:
+        int is_dot=!strcmp(entry->d_name,".");
                                         ^

ERROR: spaces required around that '=' (ctx:VxO)
#496: FILE: block/vvfat.c:726:
+        int is_dotdot=!strcmp(entry->d_name,"..");
                      ^

ERROR: space required before that '!' (ctx:OxV)
#496: FILE: block/vvfat.c:726:
+        int is_dotdot=!strcmp(entry->d_name,"..");
                       ^

ERROR: space required after that ',' (ctx:VxV)
#496: FILE: block/vvfat.c:726:
+        int is_dotdot=!strcmp(entry->d_name,"..");
                                            ^

ERROR: space required before the open parenthesis '('
#500: FILE: block/vvfat.c:728:
+        if(first_cluster == 0 && (is_dotdot || is_dot))

ERROR: braces {} are necessary for all arms of this statement
#500: FILE: block/vvfat.c:728:
+        if(first_cluster == 0 && (is_dotdot || is_dot))
[...]

ERROR: space required after that ',' (ctx:VxV)
#506: FILE: block/vvfat.c:732:
+        snprintf(buffer,length,"%s/%s",dirname,entry->d_name);
                        ^

ERROR: space required after that ',' (ctx:VxV)
#506: FILE: block/vvfat.c:732:
+        snprintf(buffer,length,"%s/%s",dirname,entry->d_name);
                               ^

ERROR: space required after that ',' (ctx:VxV)
#506: FILE: block/vvfat.c:732:
+        snprintf(buffer,length,"%s/%s",dirname,entry->d_name);
                                       ^

ERROR: space required after that ',' (ctx:VxV)
#506: FILE: block/vvfat.c:732:
+        snprintf(buffer,length,"%s/%s",dirname,entry->d_name);
                                               ^

ERROR: space required after that ',' (ctx:VxO)
#509: FILE: block/vvfat.c:734:
+        if(stat(buffer,&st)<0) {
                       ^

ERROR: space required before that '&' (ctx:OxV)
#509: FILE: block/vvfat.c:734:
+        if(stat(buffer,&st)<0) {
                        ^

ERROR: spaces required around that '<' (ctx:VxV)
#509: FILE: block/vvfat.c:734:
+        if(stat(buffer,&st)<0) {
                            ^

ERROR: space required before the open parenthesis '('
#509: FILE: block/vvfat.c:734:
+        if(stat(buffer,&st)<0) {

ERROR: spaces required around that '=' (ctx:VxV)
#534: FILE: block/vvfat.c:740:
+        direntry=create_short_and_long_name(s, i, entry->d_name,
                 ^

ERROR: spaces required around that '=' (ctx:VxV)
#536: FILE: block/vvfat.c:742:
+        direntry->attributes=(S_ISDIR(st.st_mode)?0x10:0x20);
                             ^

ERROR: spaces required around that '?' (ctx:VxV)
#536: FILE: block/vvfat.c:742:
+        direntry->attributes=(S_ISDIR(st.st_mode)?0x10:0x20);
                                                  ^

ERROR: spaces required around that ':' (ctx:VxV)
#536: FILE: block/vvfat.c:742:
+        direntry->attributes=(S_ISDIR(st.st_mode)?0x10:0x20);
                                                       ^

ERROR: spaces required around that '=' (ctx:VxV)
#537: FILE: block/vvfat.c:743:
+        direntry->reserved[0]=direntry->reserved[1]=0;
                              ^

ERROR: spaces required around that '=' (ctx:VxV)
#537: FILE: block/vvfat.c:743:
+        direntry->reserved[0]=direntry->reserved[1]=0;
                                                    ^

ERROR: spaces required around that '=' (ctx:VxV)
#538: FILE: block/vvfat.c:744:
+        direntry->ctime=fat_datetime(st.st_ctime,1);
                        ^

ERROR: space required after that ',' (ctx:VxV)
#538: FILE: block/vvfat.c:744:
+        direntry->ctime=fat_datetime(st.st_ctime,1);
                                                 ^

ERROR: spaces required around that '=' (ctx:VxV)
#539: FILE: block/vvfat.c:745:
+        direntry->cdate=fat_datetime(st.st_ctime,0);
                        ^

ERROR: space required after that ',' (ctx:VxV)
#539: FILE: block/vvfat.c:745:
+        direntry->cdate=fat_datetime(st.st_ctime,0);
                                                 ^

ERROR: spaces required around that '=' (ctx:VxV)
#540: FILE: block/vvfat.c:746:
+        direntry->adate=fat_datetime(st.st_atime,0);
                        ^

ERROR: space required after that ',' (ctx:VxV)
#540: FILE: block/vvfat.c:746:
+        direntry->adate=fat_datetime(st.st_atime,0);
                                                 ^

ERROR: spaces required around that '=' (ctx:VxV)
#541: FILE: block/vvfat.c:747:
+        direntry->begin_hi=0;
                           ^

ERROR: spaces required around that '=' (ctx:VxV)
#542: FILE: block/vvfat.c:748:
+        direntry->mtime=fat_datetime(st.st_mtime,1);
                        ^

ERROR: space required after that ',' (ctx:VxV)
#542: FILE: block/vvfat.c:748:
+        direntry->mtime=fat_datetime(st.st_mtime,1);
                                                 ^

ERROR: spaces required around that '=' (ctx:VxV)
#543: FILE: block/vvfat.c:749:
+        direntry->mdate=fat_datetime(st.st_mtime,0);
                        ^

ERROR: space required after that ',' (ctx:VxV)
#543: FILE: block/vvfat.c:749:
+        direntry->mdate=fat_datetime(st.st_mtime,0);
                                                 ^

ERROR: space required before the open parenthesis '('
#544: FILE: block/vvfat.c:750:
+        if(is_dotdot)

ERROR: braces {} are necessary for all arms of this statement
#544: FILE: block/vvfat.c:750:
+        if(is_dotdot)
[...]
+        else if(is_dot)
[...]
+        else
[...]

ERROR: space required before the open parenthesis '('
#546: FILE: block/vvfat.c:752:
+        else if(is_dot)

ERROR: braces {} are necessary for all arms of this statement
#546: FILE: block/vvfat.c:752:
+        else if(is_dot)
[...]
+        else
[...]

ERROR: spaces required around that '=' (ctx:VxV)
#549: FILE: block/vvfat.c:755:
+            direntry->begin=0; /* do that later */
                            ^

ERROR: spaces required around that '=' (ctx:VxV)
#582: FILE: block/vvfat.c:762:
+        direntry->size=cpu_to_le32(S_ISDIR(st.st_mode)?0:st.st_size);
                       ^

ERROR: spaces required around that '?' (ctx:VxV)
#582: FILE: block/vvfat.c:762:
+        direntry->size=cpu_to_le32(S_ISDIR(st.st_mode)?0:st.st_size);
                                                       ^

ERROR: spaces required around that ':' (ctx:VxV)
#582: FILE: block/vvfat.c:762:
+        direntry->size=cpu_to_le32(S_ISDIR(st.st_mode)?0:st.st_size);
                                                         ^

ERROR: space required before the open parenthesis '('
#585: FILE: block/vvfat.c:765:
+        if(!is_dot && !is_dotdot && (S_ISDIR(st.st_mode) || st.st_size)) {

ERROR: spaces required around that '=' (ctx:VxV)
#587: FILE: block/vvfat.c:767:
+            s->current_mapping->begin=0;
                                      ^

ERROR: spaces required around that '=' (ctx:VxV)
#588: FILE: block/vvfat.c:768:
+            s->current_mapping->end=st.st_size;
                                    ^

ERROR: spaces required around that '=' (ctx:VxV)
#593: FILE: block/vvfat.c:773:
+            s->current_mapping->dir_index=s->directory.next-1;
                                          ^

ERROR: spaces required around that '-' (ctx:VxV)
#593: FILE: block/vvfat.c:773:
+            s->current_mapping->dir_index=s->directory.next-1;
                                                            ^

ERROR: spaces required around that '=' (ctx:VxV)
#603: FILE: block/vvfat.c:783:
+            s->current_mapping->path=buffer;
                                     ^

ERROR: "foo* bar" should be "foo *bar"
#615: FILE: block/vvfat.c:794:
+        direntry_t* direntry=array_get_next(&(s->directory));

ERROR: spaces required around that '=' (ctx:VxV)
#615: FILE: block/vvfat.c:794:
+        direntry_t* direntry=array_get_next(&(s->directory));
                             ^

ERROR: space required after that ',' (ctx:VxV)
#616: FILE: block/vvfat.c:795:
+        memset(direntry,0,sizeof(direntry_t));
                        ^

ERROR: space required after that ',' (ctx:VxV)
#616: FILE: block/vvfat.c:795:
+        memset(direntry,0,sizeof(direntry_t));
                          ^

ERROR: "foo* bar" should be "foo *bar"
#650: FILE: block/vvfat.c:860:
+        direntry_t* entry=array_get_next(&(s->directory));

ERROR: spaces required around that '=' (ctx:VxV)
#650: FILE: block/vvfat.c:860:
+        direntry_t* entry=array_get_next(&(s->directory));
                          ^

ERROR: spaces required around that '=' (ctx:VxV)
#651: FILE: block/vvfat.c:861:
+        entry->attributes=0x28; /* archive | volume label */
                          ^

ERROR: space required before the open parenthesis '('
#681: FILE: block/vvfat.c:893:
+            if(read_directory(s, i)) {

ERROR: spaces required around that '=' (ctx:VxV)
#714: FILE: block/vvfat.c:901:
+            mapping->mode=MODE_NORMAL;
                          ^

ERROR: "foo* bar" should be "foo *bar"
#717: FILE: block/vvfat.c:904:
+                direntry_t* direntry = array_get(&(s->directory),

ERROR: spaces required around that '-' (ctx:VxV)
#720: FILE: block/vvfat.c:907:
+                mapping->end = cluster + 1 + (mapping->end-1)/s->cluster_size;
                                                           ^

ERROR: spaces required around that '/' (ctx:VxV)
#720: FILE: block/vvfat.c:907:
+                mapping->end = cluster + 1 + (mapping->end-1)/s->cluster_size;
                                                              ^

ERROR: space required before the open parenthesis '('
#733: FILE: block/vvfat.c:920:
+        if(cluster > s->cluster_count) {

ERROR: space required before the open parenthesis '('
#751: FILE: block/vvfat.c:930:
+            for(j = mapping->begin; j < mapping->end - 1; j++)

ERROR: braces {} are necessary even for single statement blocks
#751: FILE: block/vvfat.c:930:
+            for(j = mapping->begin; j < mapping->end - 1; j++)
+                fat_set(s, j, j+1);

ERROR: spaces required around that '+' (ctx:VxV)
#752: FILE: block/vvfat.c:931:
+                fat_set(s, j, j+1);
                                ^

ERROR: "foo* bar" should be "foo *bar"
#808: FILE: block/vvfat.c:1249:
+        mapping_t* mapping;

ERROR: spaces required around that '=' (ctx:VxV)
#809: FILE: block/vvfat.c:1250:
+        index3=(index1+index2)/2;
               ^

ERROR: spaces required around that '+' (ctx:VxV)
#809: FILE: block/vvfat.c:1250:
+        index3=(index1+index2)/2;
                       ^

ERROR: spaces required around that '/' (ctx:VxV)
#809: FILE: block/vvfat.c:1250:
+        index3=(index1+index2)/2;
                               ^

ERROR: spaces required around that '=' (ctx:VxV)
#810: FILE: block/vvfat.c:1251:
+        mapping=array_get(&(s->mapping),index3);
                ^

ERROR: space required after that ',' (ctx:VxV)
#810: FILE: block/vvfat.c:1251:
+        mapping=array_get(&(s->mapping),index3);
                                        ^

ERROR: spaces required around that '>=' (ctx:VxV)
#812: FILE: block/vvfat.c:1253:
+        if(mapping->begin>=cluster_num) {
                          ^

ERROR: space required before the open parenthesis '('
#812: FILE: block/vvfat.c:1253:
+        if(mapping->begin>=cluster_num) {

ERROR: spaces required around that '!=' (ctx:VxV)
#813: FILE: block/vvfat.c:1254:
+            assert(index2!=index3 || index2==0);
                          ^

ERROR: spaces required around that '==' (ctx:VxV)
#813: FILE: block/vvfat.c:1254:
+            assert(index2!=index3 || index2==0);
                                            ^

ERROR: spaces required around that '==' (ctx:VxV)
#814: FILE: block/vvfat.c:1255:
+            if(index2==index3)
                      ^

ERROR: space required before the open parenthesis '('
#814: FILE: block/vvfat.c:1255:
+            if(index2==index3)

ERROR: braces {} are necessary for all arms of this statement
#814: FILE: block/vvfat.c:1255:
+            if(index2==index3)
[...]

ERROR: spaces required around that '=' (ctx:VxV)
#816: FILE: block/vvfat.c:1257:
+            index2=index3;
                   ^

ERROR: spaces required around that '==' (ctx:VxV)
#818: FILE: block/vvfat.c:1259:
+            if(index1==index3)
                      ^

ERROR: space required before the open parenthesis '('
#818: FILE: block/vvfat.c:1259:
+            if(index1==index3)

ERROR: braces {} are necessary for all arms of this statement
#818: FILE: block/vvfat.c:1259:
+            if(index1==index3)
[...]

ERROR: spaces required around that '<=' (ctx:VxV)
#819: FILE: block/vvfat.c:1260:
+                return mapping->end<=cluster_num ? index2 : index1;
                                    ^

ERROR: spaces required around that '=' (ctx:VxV)
#820: FILE: block/vvfat.c:1261:
+            index1=index3;
                   ^

ERROR: spaces required around that '<=' (ctx:VxV)
#822: FILE: block/vvfat.c:1263:
+        assert(index1<=index2);
                      ^

ERROR: spaces required around that '=' (ctx:VxV)
#823: FILE: block/vvfat.c:1264:
+        DLOG(mapping=array_get(&(s->mapping),index1);
                     ^

ERROR: space required after that ',' (ctx:VxV)
#823: FILE: block/vvfat.c:1264:
+        DLOG(mapping=array_get(&(s->mapping),index1);
                                             ^

ERROR: spaces required around that '<=' (ctx:VxV)
#824: FILE: block/vvfat.c:1265:
+        assert(mapping->begin<=cluster_num);
                              ^

ERROR: space required after that ',' (ctx:VxV)
#826: FILE: block/vvfat.c:1267:
+                ((mapping = array_get(&(s->mapping),index2)) &&
                                                    ^

ERROR: spaces required around that '>' (ctx:VxV)
#827: FILE: block/vvfat.c:1268:
+                mapping->end>cluster_num)));
                             ^

ERROR: space required after that ',' (ctx:VxV)
#846: FILE: block/vvfat.c:1290:
+            strcmp(s->current_mapping->path,mapping->path)) {
                                            ^

ERROR: spaces required around that '<' (ctx:VxV)
#849: FILE: block/vvfat.c:1293:
+        if(fd<0)
              ^

ERROR: space required before the open parenthesis '('
#849: FILE: block/vvfat.c:1293:
+        if(fd<0)

ERROR: braces {} are necessary for all arms of this statement
#849: FILE: block/vvfat.c:1293:
+        if(fd<0)
[...]

ERROR: spaces required around that '=' (ctx:VxV)
#875: FILE: block/vvfat.c:1305:
+        int result=0;
                   ^

ERROR: line over 90 characters
#877: FILE: block/vvfat.c:1307:
+        assert(!s->current_mapping || s->current_fd || (s->current_mapping->mode & MODE_DIRECTORY));

ERROR: space required before the open parenthesis '('
#878: FILE: block/vvfat.c:1308:
+        if(!s->current_mapping

ERROR: braces {} are necessary for all arms of this statement
#878: FILE: block/vvfat.c:1308:
+        if(!s->current_mapping
[...]
-	} else if (s->current_mapping->mode & MODE_DIRECTORY)
[...]

ERROR: spaces required around that '>' (ctx:VxV)
#879: FILE: block/vvfat.c:1309:
+                || s->current_mapping->begin>cluster_num
                                             ^

ERROR: spaces required around that '<=' (ctx:VxV)
#880: FILE: block/vvfat.c:1310:
+                || s->current_mapping->end<=cluster_num) {
                                           ^

ERROR: "foo* bar" should be "foo *bar"
#882: FILE: block/vvfat.c:1312:
+            mapping_t* mapping=find_mapping_for_cluster(s,cluster_num);

ERROR: spaces required around that '=' (ctx:VxV)
#882: FILE: block/vvfat.c:1312:
+            mapping_t* mapping=find_mapping_for_cluster(s,cluster_num);
                               ^

ERROR: space required after that ',' (ctx:VxV)
#882: FILE: block/vvfat.c:1312:
+            mapping_t* mapping=find_mapping_for_cluster(s,cluster_num);
                                                          ^

WARNING: line over 80 characters
#884: FILE: block/vvfat.c:1314:
+            assert(!mapping || (cluster_num>=mapping->begin && cluster_num<mapping->end));

ERROR: spaces required around that '>=' (ctx:VxV)
#884: FILE: block/vvfat.c:1314:
+            assert(!mapping || (cluster_num>=mapping->begin && cluster_num<mapping->end));
                                            ^

ERROR: spaces required around that '<' (ctx:VxV)
#884: FILE: block/vvfat.c:1314:
+            assert(!mapping || (cluster_num>=mapping->begin && cluster_num<mapping->end));
                                                                           ^

WARNING: line over 80 characters
#916: FILE: block/vvfat.c:1320:
+                offset = s->cluster_size*(cluster_num-s->current_mapping->begin);

ERROR: spaces required around that '*' (ctx:VxV)
#916: FILE: block/vvfat.c:1320:
+                offset = s->cluster_size*(cluster_num-s->current_mapping->begin);
                                         ^

ERROR: spaces required around that '-' (ctx:VxV)
#916: FILE: block/vvfat.c:1320:
+                offset = s->cluster_size*(cluster_num-s->current_mapping->begin);
                                                      ^

ERROR: "(foo*)" should be "(foo *)"
#917: FILE: block/vvfat.c:1321:
+                s->cluster = (unsigned char*)s->directory.pointer+offset

ERROR: spaces required around that '+' (ctx:VxV)
#917: FILE: block/vvfat.c:1321:
+                s->cluster = (unsigned char*)s->directory.pointer+offset
                                                                  ^

ERROR: spaces required around that '*' (ctx:VxV)
#918: FILE: block/vvfat.c:1322:
+                        + 0x20*s->current_mapping->info.dir.first_dir_index;
                               ^

ERROR: line over 90 characters
#919: FILE: block/vvfat.c:1323:
+                assert(((s->cluster-(unsigned char*)s->directory.pointer)%s->cluster_size)==0);

ERROR: "(foo*)" should be "(foo *)"
#919: FILE: block/vvfat.c:1323:
+                assert(((s->cluster-(unsigned char*)s->directory.pointer)%s->cluster_size)==0);

ERROR: spaces required around that '-' (ctx:VxV)
#919: FILE: block/vvfat.c:1323:
+                assert(((s->cluster-(unsigned char*)s->directory.pointer)%s->cluster_size)==0);
                                    ^

ERROR: spaces required around that '%' (ctx:VxV)
#919: FILE: block/vvfat.c:1323:
+                assert(((s->cluster-(unsigned char*)s->directory.pointer)%s->cluster_size)==0);
                                                                          ^

ERROR: spaces required around that '==' (ctx:VxV)
#919: FILE: block/vvfat.c:1323:
+                assert(((s->cluster-(unsigned char*)s->directory.pointer)%s->cluster_size)==0);
                                                                                           ^

ERROR: line over 90 characters
#920: FILE: block/vvfat.c:1324:
+                assert((char*)s->cluster+s->cluster_size <= s->directory.pointer+s->directory.next*s->directory.item_size);

ERROR: "(foo*)" should be "(foo *)"
#920: FILE: block/vvfat.c:1324:
+                assert((char*)s->cluster+s->cluster_size <= s->directory.pointer+s->directory.next*s->directory.item_size);

ERROR: spaces required around that '+' (ctx:VxV)
#920: FILE: block/vvfat.c:1324:
+                assert((char*)s->cluster+s->cluster_size <= s->directory.pointer+s->directory.next*s->directory.item_size);
                                         ^

ERROR: spaces required around that '+' (ctx:VxV)
#920: FILE: block/vvfat.c:1324:
+                assert((char*)s->cluster+s->cluster_size <= s->directory.pointer+s->directory.next*s->directory.item_size);
                                                                                 ^

ERROR: spaces required around that '*' (ctx:VxV)
#920: FILE: block/vvfat.c:1324:
+                assert((char*)s->cluster+s->cluster_size <= s->directory.pointer+s->directory.next*s->directory.item_size);
                                                                                                   ^

ERROR: space required after that ',' (ctx:VxV)
#925: FILE: block/vvfat.c:1329:
+            if(open_file(s,mapping))
                           ^

ERROR: space required before the open parenthesis '('
#925: FILE: block/vvfat.c:1329:
+            if(open_file(s,mapping))

ERROR: braces {} are necessary for all arms of this statement
#925: FILE: block/vvfat.c:1329:
+            if(open_file(s,mapping))
[...]

ERROR: braces {} are necessary for all arms of this statement
#927: FILE: block/vvfat.c:1331:
+        } else if (s->current_mapping->mode & MODE_DIRECTORY)
[...]

ERROR: line over 90 characters
#932: FILE: block/vvfat.c:1336:
+        offset=s->cluster_size*(cluster_num-s->current_mapping->begin)+s->current_mapping->info.file.offset;

ERROR: spaces required around that '=' (ctx:VxV)
#932: FILE: block/vvfat.c:1336:
+        offset=s->cluster_size*(cluster_num-s->current_mapping->begin)+s->current_mapping->info.file.offset;
               ^

ERROR: spaces required around that '*' (ctx:VxV)
#932: FILE: block/vvfat.c:1336:
+        offset=s->cluster_size*(cluster_num-s->current_mapping->begin)+s->current_mapping->info.file.offset;
                               ^

ERROR: spaces required around that '-' (ctx:VxV)
#932: FILE: block/vvfat.c:1336:
+        offset=s->cluster_size*(cluster_num-s->current_mapping->begin)+s->current_mapping->info.file.offset;
                                            ^

ERROR: spaces required around that '+' (ctx:VxV)
#932: FILE: block/vvfat.c:1336:
+        offset=s->cluster_size*(cluster_num-s->current_mapping->begin)+s->current_mapping->info.file.offset;
                                                                       ^

ERROR: spaces required around that '!=' (ctx:VxV)
#933: FILE: block/vvfat.c:1337:
+        if(lseek(s->current_fd, offset, SEEK_SET)!=offset)
                                                  ^

ERROR: space required before the open parenthesis '('
#933: FILE: block/vvfat.c:1337:
+        if(lseek(s->current_fd, offset, SEEK_SET)!=offset)

ERROR: braces {} are necessary for all arms of this statement
#933: FILE: block/vvfat.c:1337:
+        if(lseek(s->current_fd, offset, SEEK_SET)!=offset)
[...]

ERROR: spaces required around that '=' (ctx:VxV)
#935: FILE: block/vvfat.c:1339:
+        s->cluster=s->cluster_buffer;
                   ^

ERROR: spaces required around that '=' (ctx:VxV)
#936: FILE: block/vvfat.c:1340:
+        result=read(s->current_fd,s->cluster,s->cluster_size);
               ^

ERROR: space required after that ',' (ctx:VxV)
#936: FILE: block/vvfat.c:1340:
+        result=read(s->current_fd,s->cluster,s->cluster_size);
                                  ^

ERROR: space required after that ',' (ctx:VxV)
#936: FILE: block/vvfat.c:1340:
+        result=read(s->current_fd,s->cluster,s->cluster_size);
                                             ^

ERROR: spaces required around that '<' (ctx:VxV)
#937: FILE: block/vvfat.c:1341:
+        if(result<0) {
                  ^

ERROR: space required before the open parenthesis '('
#937: FILE: block/vvfat.c:1341:
+        if(result<0) {

ERROR: "(foo*)" should be "(foo *)"
#955: FILE: block/vvfat.c:1360:
+        unsigned char* c=(unsigned char*)direntry;

ERROR: spaces required around that '=' (ctx:VxV)
#955: FILE: block/vvfat.c:1360:
+        unsigned char* c=(unsigned char*)direntry;
                         ^

ERROR: suspect code indent for conditional statements (8, 0)
#957: FILE: block/vvfat.c:1362:
+        for(i=1;i<11 && c[i] && c[i]!=0xff;i+=2)
 #define ADD_CHAR(c) {buffer[j] = (c); if (buffer[j] < ' ') buffer[j] = 0xb0; j++;}

ERROR: spaces required around that '=' (ctx:VxV)
#957: FILE: block/vvfat.c:1362:
+        for(i=1;i<11 && c[i] && c[i]!=0xff;i+=2)
              ^

ERROR: space required after that ';' (ctx:VxV)
#957: FILE: block/vvfat.c:1362:
+        for(i=1;i<11 && c[i] && c[i]!=0xff;i+=2)
                ^

ERROR: spaces required around that '<' (ctx:VxV)
#957: FILE: block/vvfat.c:1362:
+        for(i=1;i<11 && c[i] && c[i]!=0xff;i+=2)
                  ^

ERROR: spaces required around that '!=' (ctx:VxV)
#957: FILE: block/vvfat.c:1362:
+        for(i=1;i<11 && c[i] && c[i]!=0xff;i+=2)
                                     ^

ERROR: space required after that ';' (ctx:VxV)
#957: FILE: block/vvfat.c:1362:
+        for(i=1;i<11 && c[i] && c[i]!=0xff;i+=2)
                                           ^

ERROR: spaces required around that '+=' (ctx:VxV)
#957: FILE: block/vvfat.c:1362:
+        for(i=1;i<11 && c[i] && c[i]!=0xff;i+=2)
                                             ^

ERROR: space required before the open parenthesis '('
#957: FILE: block/vvfat.c:1362:
+        for(i=1;i<11 && c[i] && c[i]!=0xff;i+=2)

ERROR: spaces required around that '=' (ctx:VxV)
#967: FILE: block/vvfat.c:1365:
+        for(i=14;i<26 && c[i] && c[i]!=0xff;i+=2)
              ^

ERROR: space required after that ';' (ctx:VxV)
#967: FILE: block/vvfat.c:1365:
+        for(i=14;i<26 && c[i] && c[i]!=0xff;i+=2)
                 ^

ERROR: spaces required around that '<' (ctx:VxV)
#967: FILE: block/vvfat.c:1365:
+        for(i=14;i<26 && c[i] && c[i]!=0xff;i+=2)
                   ^

ERROR: spaces required around that '!=' (ctx:VxV)
#967: FILE: block/vvfat.c:1365:
+        for(i=14;i<26 && c[i] && c[i]!=0xff;i+=2)
                                      ^

ERROR: space required after that ';' (ctx:VxV)
#967: FILE: block/vvfat.c:1365:
+        for(i=14;i<26 && c[i] && c[i]!=0xff;i+=2)
                                            ^

ERROR: spaces required around that '+=' (ctx:VxV)
#967: FILE: block/vvfat.c:1365:
+        for(i=14;i<26 && c[i] && c[i]!=0xff;i+=2)
                                              ^

ERROR: space required before the open parenthesis '('
#967: FILE: block/vvfat.c:1365:
+        for(i=14;i<26 && c[i] && c[i]!=0xff;i+=2)

ERROR: braces {} are necessary even for single statement blocks
#967: FILE: block/vvfat.c:1365:
+        for(i=14;i<26 && c[i] && c[i]!=0xff;i+=2)
+            ADD_CHAR(c[i]);

ERROR: spaces required around that '=' (ctx:VxV)
#969: FILE: block/vvfat.c:1367:
+        for(i=28;i<32 && c[i] && c[i]!=0xff;i+=2)
              ^

ERROR: space required after that ';' (ctx:VxV)
#969: FILE: block/vvfat.c:1367:
+        for(i=28;i<32 && c[i] && c[i]!=0xff;i+=2)
                 ^

ERROR: spaces required around that '<' (ctx:VxV)
#969: FILE: block/vvfat.c:1367:
+        for(i=28;i<32 && c[i] && c[i]!=0xff;i+=2)
                   ^

ERROR: spaces required around that '!=' (ctx:VxV)
#969: FILE: block/vvfat.c:1367:
+        for(i=28;i<32 && c[i] && c[i]!=0xff;i+=2)
                                      ^

ERROR: space required after that ';' (ctx:VxV)
#969: FILE: block/vvfat.c:1367:
+        for(i=28;i<32 && c[i] && c[i]!=0xff;i+=2)
                                            ^

ERROR: spaces required around that '+=' (ctx:VxV)
#969: FILE: block/vvfat.c:1367:
+        for(i=28;i<32 && c[i] && c[i]!=0xff;i+=2)
                                              ^

ERROR: space required before the open parenthesis '('
#969: FILE: block/vvfat.c:1367:
+        for(i=28;i<32 && c[i] && c[i]!=0xff;i+=2)

ERROR: braces {} are necessary even for single statement blocks
#969: FILE: block/vvfat.c:1367:
+        for(i=28;i<32 && c[i] && c[i]!=0xff;i+=2)
+            ADD_CHAR(c[i]);

ERROR: spaces required around that '=' (ctx:VxV)
#983: FILE: block/vvfat.c:1373:
+        for(i=0;i<11;i++)
              ^

ERROR: space required after that ';' (ctx:VxV)
#983: FILE: block/vvfat.c:1373:
+        for(i=0;i<11;i++)
                ^

ERROR: spaces required around that '<' (ctx:VxV)
#983: FILE: block/vvfat.c:1373:
+        for(i=0;i<11;i++)
                  ^

ERROR: space required after that ';' (ctx:VxV)
#983: FILE: block/vvfat.c:1373:
+        for(i=0;i<11;i++)
                     ^

ERROR: space required before the open parenthesis '('
#983: FILE: block/vvfat.c:1373:
+        for(i=0;i<11;i++)

ERROR: braces {} are necessary even for single statement blocks
#983: FILE: block/vvfat.c:1373:
+        for(i=0;i<11;i++)
+            ADD_CHAR(direntry->name[i]);

ERROR: space required after that ',' (ctx:VxV)
#986: FILE: block/vvfat.c:1376:
+        fprintf(stderr,"%s attributes=0x%02x begin=%d size=%d\n",
                       ^

ERROR: space required after that ',' (ctx:VxV)
#989: FILE: block/vvfat.c:1379:
+                begin_of_direntry(direntry),le32_to_cpu(direntry->size));
                                            ^

ERROR: line over 90 characters
#998: FILE: block/vvfat.c:1391:
+        fprintf(stderr, "parent_mapping_index = %d, first_dir_index = %d\n", mapping->info.dir.parent_mapping_index, mapping->info.dir.first_dir_index);

ERROR: suspect code indent for conditional statements (8, 11)
#1013: FILE: block/vvfat.c:1404:
+        if (sector_num >= bs->total_sectors)
+           return -1;

ERROR: spaces required around that '<' (ctx:VxV)
#1044: FILE: block/vvfat.c:1426:
+        if(sector_num<s->faked_sectors) {
                      ^

ERROR: space required before the open parenthesis '('
#1044: FILE: block/vvfat.c:1426:
+        if(sector_num<s->faked_sectors) {

ERROR: spaces required around that '<' (ctx:VxV)
#1045: FILE: block/vvfat.c:1427:
+            if(sector_num<s->first_sectors_number)
                          ^

ERROR: space required before the open parenthesis '('
#1045: FILE: block/vvfat.c:1427:
+            if(sector_num<s->first_sectors_number)

ERROR: braces {} are necessary for all arms of this statement
#1045: FILE: block/vvfat.c:1427:
+            if(sector_num<s->first_sectors_number)
[...]
+            else if(sector_num-s->first_sectors_number<s->sectors_per_fat)
[...]
+            else if(sector_num-s->first_sectors_number-s->sectors_per_fat<s->sectors_per_fat)
[...]

ERROR: spaces required around that '+' (ctx:VxV)
#1046: FILE: block/vvfat.c:1428:
+                memcpy(buf+i*0x200,&(s->first_sectors[sector_num*0x200]),0x200);
                           ^

ERROR: spaces required around that '*' (ctx:VxV)
#1046: FILE: block/vvfat.c:1428:
+                memcpy(buf+i*0x200,&(s->first_sectors[sector_num*0x200]),0x200);
                             ^

ERROR: space required after that ',' (ctx:VxO)
#1046: FILE: block/vvfat.c:1428:
+                memcpy(buf+i*0x200,&(s->first_sectors[sector_num*0x200]),0x200);
                                   ^

ERROR: space required before that '&' (ctx:OxV)
#1046: FILE: block/vvfat.c:1428:
+                memcpy(buf+i*0x200,&(s->first_sectors[sector_num*0x200]),0x200);
                                    ^

ERROR: spaces required around that '*' (ctx:VxV)
#1046: FILE: block/vvfat.c:1428:
+                memcpy(buf+i*0x200,&(s->first_sectors[sector_num*0x200]),0x200);
                                                                 ^

ERROR: space required after that ',' (ctx:VxV)
#1046: FILE: block/vvfat.c:1428:
+                memcpy(buf+i*0x200,&(s->first_sectors[sector_num*0x200]),0x200);
                                                                         ^

ERROR: spaces required around that '-' (ctx:VxV)
#1047: FILE: block/vvfat.c:1429:
+            else if(sector_num-s->first_sectors_number<s->sectors_per_fat)
                               ^

ERROR: spaces required around that '<' (ctx:VxV)
#1047: FILE: block/vvfat.c:1429:
+            else if(sector_num-s->first_sectors_number<s->sectors_per_fat)
                                                       ^

ERROR: space required before the open parenthesis '('
#1047: FILE: block/vvfat.c:1429:
+            else if(sector_num-s->first_sectors_number<s->sectors_per_fat)

ERROR: braces {} are necessary for all arms of this statement
#1047: FILE: block/vvfat.c:1429:
+            else if(sector_num-s->first_sectors_number<s->sectors_per_fat)
[...]
+            else if(sector_num-s->first_sectors_number-s->sectors_per_fat<s->sectors_per_fat)
[...]

ERROR: line over 90 characters
#1048: FILE: block/vvfat.c:1430:
+                memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number)*0x200]),0x200);

ERROR: spaces required around that '+' (ctx:VxV)
#1048: FILE: block/vvfat.c:1430:
+                memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number)*0x200]),0x200);
                           ^

ERROR: spaces required around that '*' (ctx:VxV)
#1048: FILE: block/vvfat.c:1430:
+                memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number)*0x200]),0x200);
                             ^

ERROR: space required after that ',' (ctx:VxO)
#1048: FILE: block/vvfat.c:1430:
+                memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number)*0x200]),0x200);
                                   ^

ERROR: space required before that '&' (ctx:OxV)
#1048: FILE: block/vvfat.c:1430:
+                memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number)*0x200]),0x200);
                                    ^

ERROR: spaces required around that '-' (ctx:VxV)
#1048: FILE: block/vvfat.c:1430:
+                memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number)*0x200]),0x200);
                                                                ^

ERROR: spaces required around that '*' (ctx:VxV)
#1048: FILE: block/vvfat.c:1430:
+                memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number)*0x200]),0x200);
                                                                                         ^

ERROR: space required after that ',' (ctx:VxV)
#1048: FILE: block/vvfat.c:1430:
+                memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number)*0x200]),0x200);
                                                                                                 ^

ERROR: line over 90 characters
#1049: FILE: block/vvfat.c:1431:
+            else if(sector_num-s->first_sectors_number-s->sectors_per_fat<s->sectors_per_fat)

ERROR: spaces required around that '-' (ctx:VxV)
#1049: FILE: block/vvfat.c:1431:
+            else if(sector_num-s->first_sectors_number-s->sectors_per_fat<s->sectors_per_fat)
                               ^

ERROR: spaces required around that '-' (ctx:VxV)
#1049: FILE: block/vvfat.c:1431:
+            else if(sector_num-s->first_sectors_number-s->sectors_per_fat<s->sectors_per_fat)
                                                       ^

ERROR: spaces required around that '<' (ctx:VxV)
#1049: FILE: block/vvfat.c:1431:
+            else if(sector_num-s->first_sectors_number-s->sectors_per_fat<s->sectors_per_fat)
                                                                          ^

ERROR: space required before the open parenthesis '('
#1049: FILE: block/vvfat.c:1431:
+            else if(sector_num-s->first_sectors_number-s->sectors_per_fat<s->sectors_per_fat)

ERROR: braces {} are necessary for all arms of this statement
#1049: FILE: block/vvfat.c:1431:
+            else if(sector_num-s->first_sectors_number-s->sectors_per_fat<s->sectors_per_fat)
[...]

ERROR: line over 90 characters
#1050: FILE: block/vvfat.c:1432:
+                memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number-s->sectors_per_fat)*0x200]),0x200);

ERROR: spaces required around that '+' (ctx:VxV)
#1050: FILE: block/vvfat.c:1432:
+                memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number-s->sectors_per_fat)*0x200]),0x200);
                           ^

ERROR: spaces required around that '*' (ctx:VxV)
#1050: FILE: block/vvfat.c:1432:
+                memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number-s->sectors_per_fat)*0x200]),0x200);
                             ^

ERROR: space required after that ',' (ctx:VxO)
#1050: FILE: block/vvfat.c:1432:
+                memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number-s->sectors_per_fat)*0x200]),0x200);
                                   ^

ERROR: space required before that '&' (ctx:OxV)
#1050: FILE: block/vvfat.c:1432:
+                memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number-s->sectors_per_fat)*0x200]),0x200);
                                    ^

ERROR: spaces required around that '-' (ctx:VxV)
#1050: FILE: block/vvfat.c:1432:
+                memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number-s->sectors_per_fat)*0x200]),0x200);
                                                                ^

ERROR: spaces required around that '-' (ctx:VxV)
#1050: FILE: block/vvfat.c:1432:
+                memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number-s->sectors_per_fat)*0x200]),0x200);
                                                                                        ^

ERROR: spaces required around that '*' (ctx:VxV)
#1050: FILE: block/vvfat.c:1432:
+                memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number-s->sectors_per_fat)*0x200]),0x200);
                                                                                                            ^

ERROR: space required after that ',' (ctx:VxV)
#1050: FILE: block/vvfat.c:1432:
+                memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number-s->sectors_per_fat)*0x200]),0x200);
                                                                                                                    ^

ERROR: spaces required around that '=' (ctx:VxV)
#1052: FILE: block/vvfat.c:1434:
+            uint32_t sector=sector_num-s->faked_sectors,
                            ^

ERROR: spaces required around that '-' (ctx:VxV)
#1052: FILE: block/vvfat.c:1434:
+            uint32_t sector=sector_num-s->faked_sectors,
                                       ^

ERROR: spaces required around that '=' (ctx:VxV)
#1053: FILE: block/vvfat.c:1435:
+            sector_offset_in_cluster=(sector%s->sectors_per_cluster),
                                     ^

ERROR: spaces required around that '%' (ctx:VxV)
#1053: FILE: block/vvfat.c:1435:
+            sector_offset_in_cluster=(sector%s->sectors_per_cluster),
                                             ^

ERROR: spaces required around that '=' (ctx:VxV)
#1054: FILE: block/vvfat.c:1436:
+            cluster_num=sector/s->sectors_per_cluster;
                        ^

ERROR: spaces required around that '/' (ctx:VxV)
#1054: FILE: block/vvfat.c:1436:
+            cluster_num=sector/s->sectors_per_cluster;
                               ^

WARNING: line over 80 characters
#1055: FILE: block/vvfat.c:1437:
+            if(cluster_num > s->cluster_count || read_cluster(s, cluster_num) != 0) {

ERROR: space required before the open parenthesis '('
#1055: FILE: block/vvfat.c:1437:
+            if(cluster_num > s->cluster_count || read_cluster(s, cluster_num) != 0) {

ERROR: spaces required around that '+' (ctx:VxV)
#1057: FILE: block/vvfat.c:1439:
+                memset(buf+i*0x200,0,0x200);
                           ^

ERROR: spaces required around that '*' (ctx:VxV)
#1057: FILE: block/vvfat.c:1439:
+                memset(buf+i*0x200,0,0x200);
                             ^

ERROR: space required after that ',' (ctx:VxV)
#1057: FILE: block/vvfat.c:1439:
+                memset(buf+i*0x200,0,0x200);
                                   ^

ERROR: space required after that ',' (ctx:VxV)
#1057: FILE: block/vvfat.c:1439:
+                memset(buf+i*0x200,0,0x200);
                                     ^

ERROR: spaces required around that '+' (ctx:VxV)
#1060: FILE: block/vvfat.c:1442:
+            memcpy(buf+i*0x200,s->cluster+sector_offset_in_cluster*0x200,0x200);
                       ^

ERROR: spaces required around that '*' (ctx:VxV)
#1060: FILE: block/vvfat.c:1442:
+            memcpy(buf+i*0x200,s->cluster+sector_offset_in_cluster*0x200,0x200);
                         ^

ERROR: space required after that ',' (ctx:VxV)
#1060: FILE: block/vvfat.c:1442:
+            memcpy(buf+i*0x200,s->cluster+sector_offset_in_cluster*0x200,0x200);
                               ^

ERROR: spaces required around that '+' (ctx:VxV)
#1060: FILE: block/vvfat.c:1442:
+            memcpy(buf+i*0x200,s->cluster+sector_offset_in_cluster*0x200,0x200);
                                          ^

ERROR: spaces required around that '*' (ctx:VxV)
#1060: FILE: block/vvfat.c:1442:
+            memcpy(buf+i*0x200,s->cluster+sector_offset_in_cluster*0x200,0x200);
                                                                   ^

ERROR: space required after that ',' (ctx:VxV)
#1060: FILE: block/vvfat.c:1442:
+            memcpy(buf+i*0x200,s->cluster+sector_offset_in_cluster*0x200,0x200);
                                                                         ^

ERROR: "foo* bar" should be "foo *bar"
#1093: FILE: block/vvfat.c:1517:
+        commit_t* commit = array_get(&(s->commits), i);

ERROR: braces {} are necessary for all arms of this statement
#1095: FILE: block/vvfat.c:1519:
+        if (commit->action != ACTION_WRITEOUT) {
[...]
-	} else
[...]

ERROR: braces {} are necessary even for single statement blocks
#1100: FILE: block/vvfat.c:1522:
+        } else
+            assert(commit->path == NULL);

ERROR: "foo* bar" should be "foo *bar"
#1108: FILE: block/vvfat.c:1529:
+        uint32_t cluster, char* new_path)

ERROR: "foo* bar" should be "foo *bar"
#1126: FILE: block/vvfat.c:1548:
+        char* path, uint32_t first_cluster)

ERROR: "foo* bar" should be "foo *bar"
#1135: FILE: block/vvfat.c:1583:
+        const direntry_t* direntry)

ERROR: braces {} are necessary for all arms of this statement
#1169: FILE: block/vvfat.c:1605:
+        if (j == 11)
[...]
+        else if (j == 26)
[...]

ERROR: braces {} are necessary for all arms of this statement
#1171: FILE: block/vvfat.c:1607:
+        else if (j == 26)
[...]

ERROR: spaces required around that '+' (ctx:VxV)
#1180: FILE: block/vvfat.c:1610:
+        if (pointer[j+1] == 0)
                      ^

ERROR: braces {} are necessary for all arms of this statement
#1180: FILE: block/vvfat.c:1610:
+        if (pointer[j+1] == 0)
[...]
+        else if (pointer[j+1] != 0xff || (pointer[0] & 0x40) == 0)
[...]
+        else
[...]

ERROR: spaces required around that '+' (ctx:VxV)
#1182: FILE: block/vvfat.c:1612:
+        else if (pointer[j+1] != 0xff || (pointer[0] & 0x40) == 0)
                           ^

ERROR: braces {} are necessary for all arms of this statement
#1182: FILE: block/vvfat.c:1612:
+        else if (pointer[j+1] != 0xff || (pointer[0] & 0x40) == 0)
[...]
+        else
[...]

ERROR: "(foo*)" should be "(foo *)"
#1190: FILE: block/vvfat.c:1619:
+        lfn->len = offset + strlen((char*)lfn->name + offset);

ERROR: "foo* bar" should be "foo *bar"
#1198: FILE: block/vvfat.c:1626:
+        long_file_name* lfn, direntry_t* direntry)

ERROR: braces {} are necessary for all arms of this statement
#1214: FILE: block/vvfat.c:1635:
+        if (direntry->name[i] <= ' ' || direntry->name[i] > 0x7f)
[...]
+        else if (s->downcase_short_names)
[...]
+        else
[...]

ERROR: braces {} are necessary for all arms of this statement
#1216: FILE: block/vvfat.c:1637:
+        else if (s->downcase_short_names)
[...]
+        else
[...]

ERROR: space required after that ';' (ctx:BxV)
#1230: FILE: block/vvfat.c:1648:
+        for (;j >= 0; j--) {
              ^

ERROR: "foo* bar" should be "foo *bar"
#1282: FILE: block/vvfat.c:1744:
+        direntry_t* direntry, const char* path)

ERROR: "foo* bar" should be "foo *bar"
#1304: FILE: block/vvfat.c:1786:
+            const char* basename;

ERROR: braces {} are necessary for all arms of this statement
#1325: FILE: block/vvfat.c:1796:
+            if (strcmp(basename, basename2))
[...]

ERROR: braces {} are necessary for all arms of this statement
#1327: FILE: block/vvfat.c:1798:
+        } else if (is_file(direntry))
[...]

ERROR: suspect code indent for conditional statements (16, 16)
#1347: FILE: block/vvfat.c:1810:
+                if (mapping == NULL ||
[...]
+                mapping = find_mapping_for_cluster(s, cluster_num);

ERROR: braces {} are necessary for all arms of this statement
#1347: FILE: block/vvfat.c:1810:
+                if (mapping == NULL ||
[...]

ERROR: "foo* bar" should be "foo *bar"
#1372: FILE: block/vvfat.c:1826:
+                        const char* basename = get_basename(mapping->path);

ERROR: braces {} are necessary for all arms of this statement
#1378: FILE: block/vvfat.c:1828:
+                        if (strcmp(basename, basename2))
[...]

WARNING: line over 80 characters
#1380: FILE: block/vvfat.c:1830:
+                        first_mapping_index = array_index(&(s->mapping), mapping);

ERROR: braces {} are necessary for all arms of this statement
#1445: FILE: block/vvfat.c:1878:
+        if (s->used_clusters[cluster_num] & USED_ANY)
[...]

ERROR: braces {} are necessary for all arms of this statement
#1456: FILE: block/vvfat.c:1884:
+        if (fat_eof(s, cluster_num))
[...]
+        else if (cluster_num < 2 || cluster_num > s->max_fat_value - 16)
[...]

ERROR: braces {} are necessary for all arms of this statement
#1458: FILE: block/vvfat.c:1886:
+        else if (cluster_num < 2 || cluster_num > s->max_fat_value - 16)
[...]

ERROR: "foo* bar" should be "foo *bar"
#1471: FILE: block/vvfat.c:1899:
+        int cluster_num, const char* path)

ERROR: "foo* bar" should be "foo *bar"
#1481: FILE: block/vvfat.c:1916:
+        const char* basename = get_basename(mapping->path);

ERROR: "foo* bar" should be "foo *bar"
#1482: FILE: block/vvfat.c:1917:
+        const char* basename2 = get_basename(path);

ERROR: braces {} are necessary for all arms of this statement
#1494: FILE: block/vvfat.c:1924:
+        if (strcmp(basename, basename2))
[...]

WARNING: line over 80 characters
#1515: FILE: block/vvfat.c:1938:
+            fprintf(stderr, "cluster %d used more than once\n", (int)cluster_num);

ERROR: braces {} are necessary for all arms of this statement
#1573: FILE: block/vvfat.c:1957:
+            if (is_volume_label(direntries + i) || is_dot(direntries + i) ||
[...]

ERROR: braces {} are necessary for all arms of this statement
#1582: FILE: block/vvfat.c:1966:
+            if (subret == 0 || is_free(direntries + i))
[...]

ERROR: spaces required around that '+' (ctx:VxV)
#1585: FILE: block/vvfat.c:1969:
+            if (fat_chksum(direntries+i) != lfn.checksum) {
                                      ^

ERROR: "(foo*)" should be "(foo *)"
#1591: FILE: block/vvfat.c:1975:
+                if (subret > 0 || !strcmp((char*)lfn.name, ".")

ERROR: braces {} are necessary for all arms of this statement
#1591: FILE: block/vvfat.c:1975:
+                if (subret > 0 || !strcmp((char*)lfn.name, ".")
[...]

ERROR: "(foo*)" should be "(foo *)"
#1592: FILE: block/vvfat.c:1976:
+                        || !strcmp((char*)lfn.name, ".."))

ERROR: braces {} are necessary for all arms of this statement
#1619: FILE: block/vvfat.c:1988:
+            if (is_directory(direntries + i)) {
[...]
+            } else if (is_file(direntries + i)) {
[...]
-	    } else
[...]

ERROR: line over 90 characters
#1621: FILE: block/vvfat.c:1990:
+                    DLOG(fprintf(stderr, "invalid begin for directory: %s\n", path2); print_direntry(direntries + i));

ERROR: line over 90 characters
#1627: FILE: block/vvfat.c:1996:
+                    DLOG(fprintf(stderr, "problem in directory %s:\n", path2); print_direntry(direntries + i));

WARNING: line over 80 characters
#1632: FILE: block/vvfat.c:2001:
+                cluster_count = get_cluster_count_for_direntry(s, direntries + i, path2);

ERROR: braces {} are necessary even for single statement blocks
#1642: FILE: block/vvfat.c:2007:
+            } else
                 abort(); /* cluster_count = 0; */

ERROR: "foo* bar" should be "foo *bar"
#1691: FILE: block/vvfat.c:2061:
+            mapping_t* mapping = array_get(&(s->mapping), i);

ERROR: braces {} are necessary for all arms of this statement
#1692: FILE: block/vvfat.c:2062:
+            if (mapping->first_mapping_index < 0)
[...]

ERROR: space required before the open parenthesis '('
#1714: FILE: block/vvfat.c:2075:
+            if(!s->used_clusters[i]) {

ERROR: line over 90 characters
#1715: FILE: block/vvfat.c:2076:
+                DLOG(fprintf(stderr, "FAT was modified (%d), but cluster is not used?\n", i));

ERROR: "foo* bar" should be "foo *bar"
#1748: FILE: block/vvfat.c:2101:
+        mapping_t* mapping = array_get(&(s->mapping), i);

ERROR: braces {} are necessary for all arms of this statement
#1753: FILE: block/vvfat.c:2104:
+        if (mapping->name >= offset) \
[...]

ERROR: spaces required around that '+' (ctx:WxV)
#1791: FILE: block/vvfat.c:2137:
+        adjust_mapping_indices(s, index, +1);
                                          ^

ERROR: "foo* bar" should be "foo *bar"
#1827: FILE: block/vvfat.c:2182:
+        mapping_t* mapping = array_get(&(s->mapping), i);

ERROR: braces {} are necessary for all arms of this statement
#1828: FILE: block/vvfat.c:2183:
+        if (mapping->dir_index >= offset)
[...]

ERROR: trailing statements should be on next line
#1934: FILE: block/vvfat.c:2239:
+        for (c = cluster, c1 = modified_fat_get(s, c); c + 1 == c1;
+                c = c1, c1 = modified_fat_get(s, c1));

ERROR: trailing statements should be on next line
#1941: FILE: block/vvfat.c:2246:
+            for (i = 1; i < max_i && mapping[i].begin < c; i++);

ERROR: braces {} are necessary even for single statement blocks
#1941: FILE: block/vvfat.c:2246:
+            for (i = 1; i < max_i && mapping[i].begin < c; i++);

ERROR: braces {} are necessary even for single statement blocks
#1942: FILE: block/vvfat.c:2247:
+            while (--i > 0)
+                remove_mapping(s, index + 1);

ERROR: "foo* bar" should be "foo *bar"
#1951: FILE: block/vvfat.c:2256:
+            mapping_t* next_mapping = i >= s->mapping.next ? NULL :

ERROR: spaces required around that '+' (ctx:VxV)
#1957: FILE: block/vvfat.c:2262:
+                next_mapping = insert_mapping(s, c1, c1+1);
                                                        ^

ERROR: braces {} are necessary for all arms of this statement
#1959: FILE: block/vvfat.c:2264:
+                if (c1 < c)
[...]

ERROR: braces {} are necessary for all arms of this statement
#1972: FILE: block/vvfat.c:2277:
+            if (mapping->mode & MODE_DIRECTORY) {
[...]
+            } else
[...]

ERROR: braces {} are necessary for all arms of this statement
#2027: FILE: block/vvfat.c:2336:
+        if (insert_direntries(s,
[...]

ERROR: "foo* bar" should be "foo *bar"
#2046: FILE: block/vvfat.c:2347:
+        void* direntry = array_get(&(s->directory), current_dir_index);

ERROR: braces {} are necessary for all arms of this statement
#2049: FILE: block/vvfat.c:2350:
+        if (ret)
[...]

ERROR: braces {} are necessary for all arms of this statement
#2082: FILE: block/vvfat.c:2372:
+            if (ret)
[...]

ERROR: spaces required around that '>=' (ctx:WxV)
#2135: FILE: block/vvfat.c:2424:
+                (size > offset && c >=2 && !fat_eof(s, c)));
                                     ^

ERROR: "(foo*)" should be "(foo *)"
#2140: FILE: block/vvfat.c:2427:
+            (uint8_t*)cluster, (rest_size + 0x1ff) / 0x200);

ERROR: "foo* bar" should be "foo *bar"
#2171: FILE: block/vvfat.c:2463:
+        mapping_t* mapping = array_get(&(s->mapping), i);

ERROR: "foo* bar" should be "foo *bar"
#2177: FILE: block/vvfat.c:2469:
+        direntry_t* direntry = array_get(&(s->directory), mapping->dir_index);

ERROR: line over 90 characters
#2178: FILE: block/vvfat.c:2470:
+        assert(mapping->begin == begin_of_direntry(direntry) || mapping->first_mapping_index >= 0);

ERROR: line over 90 characters
#2180: FILE: block/vvfat.c:2472:
+            assert(mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster * (mapping->end - mapping->begin) <= s->directory.next);

ERROR: line over 90 characters
#2181: FILE: block/vvfat.c:2473:
+            assert((mapping->info.dir.first_dir_index % (0x10 * s->sectors_per_cluster)) == 0);

ERROR: "foo* bar" should be "foo *bar"
#2227: FILE: block/vvfat.c:2485:
+        direntry_t* direntry = array_get(&(s->directory), i);

WARNING: line over 80 characters
#2230: FILE: block/vvfat.c:2488:
+            mapping_t* mapping = find_mapping_for_cluster(s, begin_of_direntry(direntry));

ERROR: "foo* bar" should be "foo *bar"
#2230: FILE: block/vvfat.c:2488:
+            mapping_t* mapping = find_mapping_for_cluster(s, begin_of_direntry(direntry));

WARNING: line over 80 characters
#2233: FILE: block/vvfat.c:2491:
+            assert(mapping->begin == begin_of_direntry(direntry) || is_dot(direntry));

ERROR: "foo* bar" should be "foo *bar"
#2241: FILE: block/vvfat.c:2499:
+                mapping_t* mapping = array_get(&(s->mapping), j);

ERROR: braces {} are necessary for all arms of this statement
#2242: FILE: block/vvfat.c:2500:
+                if (mapping->mode & MODE_DELETED)
[...]

ERROR: line over 90 characters
#2245: FILE: block/vvfat.c:2503:
+                    if (mapping->info.dir.first_dir_index <= i && mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster > i) {

ERROR: braces {} are necessary for all arms of this statement
#2247: FILE: block/vvfat.c:2505:
+                        if (mapping->first_mapping_index == -1)
[...]
+                        else
[...]

WARNING: line over 80 characters
#2250: FILE: block/vvfat.c:2508:
+                            assert(first_mapping == mapping->first_mapping_index);

ERROR: braces {} are necessary for all arms of this statement
#2251: FILE: block/vvfat.c:2509:
+                        if (mapping->info.dir.parent_mapping_index < 0)
[...]
+                        else {
[...]

ERROR: line over 90 characters
#2254: FILE: block/vvfat.c:2512:
+                            mapping_t* parent = array_get(&(s->mapping), mapping->info.dir.parent_mapping_index);

ERROR: "foo* bar" should be "foo *bar"
#2254: FILE: block/vvfat.c:2512:
+                            mapping_t* parent = array_get(&(s->mapping), mapping->info.dir.parent_mapping_index);

ERROR: line over 90 characters
#2256: FILE: block/vvfat.c:2514:
+                            assert(parent->info.dir.first_dir_index < mapping->info.dir.first_dir_index);

ERROR: braces {} are necessary for all arms of this statement
#2261: FILE: block/vvfat.c:2519:
+            if (count == 0)
[...]

ERROR: "foo* bar" should be "foo *bar"
#2273: FILE: block/vvfat.c:2533:
+        commit_t* commit = array_get(&(s->commits), i);

ERROR: line over 90 characters
#2274: FILE: block/vvfat.c:2534:
+        fprintf(stderr, "%d, %s (%d, %d)\n", i, commit->path ? commit->path : "(null)", commit->param.rename.cluster, commit->action);

ERROR: "foo* bar" should be "foo *bar"
#2311: FILE: block/vvfat.c:2539:
+        commit_t* commit = array_get(&(s->commits), i);

ERROR: "foo* bar" should be "foo *bar"
#2313: FILE: block/vvfat.c:2541:
+            mapping_t* mapping = find_mapping_for_cluster(s,

ERROR: "foo* bar" should be "foo *bar"
#2315: FILE: block/vvfat.c:2543:
+            char* old_path = mapping->path;

ERROR: braces {} are necessary for all arms of this statement
#2319: FILE: block/vvfat.c:2547:
+            if (rename(old_path, mapping->path))
[...]

ERROR: "foo* bar" should be "foo *bar"
#2326: FILE: block/vvfat.c:2554:
+                direntry_t* direntry = array_get(&(s->directory),

ERROR: "foo* bar" should be "foo *bar"
#2334: FILE: block/vvfat.c:2562:
+                        direntry_t* d = direntry + i;

ERROR: "foo* bar" should be "foo *bar"
#2337: FILE: block/vvfat.c:2565:
+                            mapping_t* m = find_mapping_for_cluster(s,

ERROR: "foo* bar" should be "foo *bar"
#2340: FILE: block/vvfat.c:2568:
+                            char* new_path = g_malloc(l + diff + 1);

ERROR: space required before the open parenthesis '('
#2358: FILE: block/vvfat.c:2579:
+                    } while((i % (0x10 * s->sectors_per_cluster)) != 0);

ERROR: "foo* bar" should be "foo *bar"
#2372: FILE: block/vvfat.c:2588:
+            mapping_t* mapping;

ERROR: braces {} are necessary for all arms of this statement
#2414: FILE: block/vvfat.c:2601:
+            if (mapping == NULL)
[...]

ERROR: "foo* bar" should be "foo *bar"
#2429: FILE: block/vvfat.c:2616:
+                mapping_t* m = array_get(&(s->mapping), j);

ERROR: braces {} are necessary for all arms of this statement
#2430: FILE: block/vvfat.c:2617:
+                if (m->first_mapping_index < 0 && m != mapping &&
[...]

ERROR: "foo* bar" should be "foo *bar"
#2453: FILE: block/vvfat.c:2644:
+        commit_t* commit = array_get(&(s->commits), i);

ERROR: space required before the open parenthesis '('
#2454: FILE: block/vvfat.c:2645:
+        switch(commit->action) {

ERROR: "foo* bar" should be "foo *bar"
#2469: FILE: block/vvfat.c:2653:
+            direntry_t* entry = array_get(&(s->directory),

ERROR: "foo* bar" should be "foo *bar"
#2472: FILE: block/vvfat.c:2656:
+            mapping_t* mapping = find_mapping_for_cluster(s, begin);

ERROR: braces {} are necessary for all arms of this statement
#2528: FILE: block/vvfat.c:2663:
+            if (commit_one_file(s, commit->param.writeout.dir_index,
[...]

ERROR: "foo* bar" should be "foo *bar"
#2536: FILE: block/vvfat.c:2671:
+            mapping_t* mapping = find_mapping_for_cluster(s, begin);

ERROR: "foo* bar" should be "foo *bar"
#2537: FILE: block/vvfat.c:2672:
+            direntry_t* entry;

ERROR: braces {} are necessary for all arms of this statement
#2543: FILE: block/vvfat.c:2678:
+                if (is_file(entry) && begin_of_direntry(entry) == begin)
[...]

ERROR: spaces required around that '+' (ctx:VxV)
#2558: FILE: block/vvfat.c:2693:
+                mapping = insert_mapping(s, begin, begin+1);
                                                         ^

ERROR: braces {} are necessary for all arms of this statement
#2567: FILE: block/vvfat.c:2702:
+            if (commit_one_file(s, i, 0))
[...]

ERROR: "foo* bar" should be "foo *bar"
#2638: FILE: block/vvfat.c:2727:
+            mapping_t* mapping = array_get(&(s->mapping), i);

ERROR: "foo* bar" should be "foo *bar"
#2640: FILE: block/vvfat.c:2729:
+                direntry_t* entry = array_get(&(s->directory),

ERROR: braces {} are necessary for all arms of this statement
#2650: FILE: block/vvfat.c:2739:
+                            if (errno == ENOTEMPTY) {
[...]
+                            } else
[...]

ERROR: "foo* bar" should be "foo *bar"
#2658: FILE: block/vvfat.c:2747:
+                            mapping_t* m = array_get(&(s->mapping), j);

ERROR: braces {} are necessary for all arms of this statement
#2659: FILE: block/vvfat.c:2748:
+                            if (m->mode & MODE_DIRECTORY &&
[...]

ERROR: braces {} are necessary for all arms of this statement
#2673: FILE: block/vvfat.c:2762:
+                    if (unlink(mapping->path))
[...]

ERROR: line over 90 characters
#2677: FILE: block/vvfat.c:2766:
+                DLOG(fprintf(stderr, "DELETE (%d)\n", i); print_mapping(mapping); print_direntry(entry));

ERROR: "foo* bar" should be "foo *bar"
#2798: FILE: block/vvfat.c:2870:
+        mapping_t* mapping = find_mapping_for_cluster(s, i);

ERROR: braces {} are necessary for all arms of this statement
#2799: FILE: block/vvfat.c:2871:
+        if (mapping) {
[...]
+        } else
[...]

ERROR: "foo* bar" should be "foo *bar"
#2810: FILE: block/vvfat.c:2882:
+                const direntry_t* direntries;

ERROR: braces {} are necessary for all arms of this statement
#2815: FILE: block/vvfat.c:2887:
+                if (begin < sector_num)
[...]

ERROR: braces {} are necessary for all arms of this statement
#2817: FILE: block/vvfat.c:2889:
+                if (end > sector_num + nb_sectors)
[...]

ERROR: "(foo*)" should be "(foo *)"
#2821: FILE: block/vvfat.c:2893:
+                direntries = (direntry_t*)(buf + 0x200 * (begin - sector_num));

ERROR: spaces required around that '+' (ctx:VxV)
#2830: FILE: block/vvfat.c:2902:
+                    else if (is_short_name(direntries+k) &&
                                                      ^

ERROR: line over 90 characters
#2835: FILE: block/vvfat.c:2907:
+                            fprintf(stderr, "Warning: tried to write to write-protected file\n");

ERROR: braces {} are necessary for all arms of this statement
#2862: FILE: block/vvfat.c:2930:
+        if (i >= 0)
[...]

total: 540 errors, 9 warnings, 2803 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 3/13: vvfat: fix typos...
Checking PATCH 4/13: vvfat: rename useless enumeration values...
Checking PATCH 5/13: vvfat: introduce offset_to_bootsector, offset_to_fat and offset_to_root_dir...
Checking PATCH 6/13: vvfat: fix field names in FAT12/FAT16 and FAT32 boot sectors...
Checking PATCH 7/13: vvfat: always create . and .. entries at first and in that order...
Checking PATCH 8/13: vvfat: correctly create long names for non-ASCII filenames...
Checking PATCH 9/13: vvfat: correctly create base short names for non-ASCII filenames...
Checking PATCH 10/13: vvfat: correctly generate numeric-tail of short file names...
Checking PATCH 11/13: vvfat: limit number of entries in root directory in FAT12/FAT16...
Checking PATCH 12/13: vvfat: handle KANJI lead byte 0xe5...
Checking PATCH 13/13: vvfat: change OEM name to 'MSWIN4.1'...
=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@freelists.org

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [PATCH v2 13/13] vvfat: change OEM name to 'MSWIN4.1'
  2017-05-22 21:12 ` [Qemu-devel] [PATCH v2 13/13] vvfat: change OEM name to 'MSWIN4.1' Hervé Poussineau
@ 2017-05-23  4:23   ` Philippe Mathieu-Daudé
  2017-05-23 19:41     ` Hervé Poussineau
  0 siblings, 1 reply; 29+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-05-23  4:23 UTC (permalink / raw)
  To: Hervé Poussineau, qemu-devel; +Cc: Kevin Wolf, qemu-block, Max Reitz

Hi Hervé,

On 05/22/2017 06:12 PM, Hervé Poussineau wrote:
> According to specification:
> "'MSWIN4.1' is the recommanded setting, because it is the setting least likely
> to cause compatibility problems. If you want to put something else in here,
> that is your option, but the result may be that some FAT drivers might not
> recognize the volume."

It also says "Typically this is some indication of what system formatted
the volume."

 From https://technet.microsoft.com/en-us/library/cc976796.aspx:

"Following the jump instruction is the 8-byte OEM ID, a string of 
characters that identifies the name and version number of the operating 
system that formatted the volume. To preserve compatibility with MS-DOS, 
Windows 2000 records "MSDOS5.0" in this field on FAT16 and FAT32 disks. 
On NTFS disks, Windows 2000 records "NTFS."
You may also see the OEM ID "MSWIN4.0" on disks formatted by Windows 95 
and "MSWIN4.1" on disks formatted by Windows 95 OSR2 and Windows 98. 
Windows 2000 does not use the OEM ID field in the boot sector except for 
verifying NTFS volumes."

I'm curious which one is the most up-to-date, the specification v1.03 or 
a Windows 2000. Do you have an idea if there is more MSDOS/W2K vs W95/98 
users? Hopefully W95 is a Long time no see to me.

You think having "QEMU" OEM does more harm than good?

>
> Specification: "FAT: General overview of on-disk format" v1.03, page 9
> Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
> ---
>  block/vvfat.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/block/vvfat.c b/block/vvfat.c
> index 53e8faa54c..1f7f46ecea 100644
> --- a/block/vvfat.c
> +++ b/block/vvfat.c
> @@ -1024,7 +1024,7 @@ static int init_directories(BDRVVVFATState* s,
>      bootsector->jump[0]=0xeb;
>      bootsector->jump[1]=0x3e;
>      bootsector->jump[2]=0x90;
> -    memcpy(bootsector->name,"QEMU    ",8);
> +    memcpy(bootsector->name, "MSWIN4.1", 8);
>      bootsector->sector_size=cpu_to_le16(0x200);
>      bootsector->sectors_per_cluster=s->sectors_per_cluster;
>      bootsector->reserved_sectors=cpu_to_le16(1);
>

Regards,

Phil.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [PATCH v2 13/13] vvfat: change OEM name to 'MSWIN4.1'
  2017-05-23  4:23   ` Philippe Mathieu-Daudé
@ 2017-05-23 19:41     ` Hervé Poussineau
  2017-05-24  4:27       ` Philippe Mathieu-Daudé
  0 siblings, 1 reply; 29+ messages in thread
From: Hervé Poussineau @ 2017-05-23 19:41 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel; +Cc: Kevin Wolf, qemu-block, Max Reitz

Hi Philippe,

Le 23/05/2017 à 06:23, Philippe Mathieu-Daudé a écrit :
> Hi Hervé,
>
> On 05/22/2017 06:12 PM, Hervé Poussineau wrote:
>> According to specification:
>> "'MSWIN4.1' is the recommanded setting, because it is the setting least likely
>> to cause compatibility problems. If you want to put something else in here,
>> that is your option, but the result may be that some FAT drivers might not
>> recognize the volume."
>
> It also says "Typically this is some indication of what system formatted
> the volume."
>
> From https://technet.microsoft.com/en-us/library/cc976796.aspx:
>
> "Following the jump instruction is the 8-byte OEM ID, a string of characters that identifies the name and version number of the operating system that formatted the volume. To preserve compatibility
> with MS-DOS, Windows 2000 records "MSDOS5.0" in this field on FAT16 and FAT32 disks. On NTFS disks, Windows 2000 records "NTFS."
> You may also see the OEM ID "MSWIN4.0" on disks formatted by Windows 95 and "MSWIN4.1" on disks formatted by Windows 95 OSR2 and Windows 98. Windows 2000 does not use the OEM ID field in the boot
> sector except for verifying NTFS volumes."
>
> I'm curious which one is the most up-to-date, the specification v1.03 or a Windows 2000. Do you have an idea if there is more MSDOS/W2K vs W95/98 users? Hopefully W95 is a Long time no see to me.
>
> You think having "QEMU" OEM does more harm than good?

That's complicated. Indeed, OEM ID should be the name of the OS/tool which formatted the partition.
However, some FAT drivers take different paths according to OEM ID.
See for example:
https://jdebp.eu/FGA/volume-boot-block-oem-name-field.html
http://seasip.info./Misc/oemid.html

So, in my opinion, it should be better to stick to some specification for the whole FAT format, so we have a reference document to know if there is a bug in the code or not.
FAT specification 1.03 is dated December 6, 2000, while Windows 2000 has been released December 15, 1999, so both are around the same date.
FAT specification gives all details about all disk structures, so I think that's better to stick to what it says.

So to answer your question, and knowing the tricks played with OEM ID, I think that's better to use "MSWIN4.1" than "QEMU".

Regards,

Hervé

>
>>
>> Specification: "FAT: General overview of on-disk format" v1.03, page 9
>> Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
>> ---
>>  block/vvfat.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/block/vvfat.c b/block/vvfat.c
>> index 53e8faa54c..1f7f46ecea 100644
>> --- a/block/vvfat.c
>> +++ b/block/vvfat.c
>> @@ -1024,7 +1024,7 @@ static int init_directories(BDRVVVFATState* s,
>>      bootsector->jump[0]=0xeb;
>>      bootsector->jump[1]=0x3e;
>>      bootsector->jump[2]=0x90;
>> -    memcpy(bootsector->name,"QEMU    ",8);
>> +    memcpy(bootsector->name, "MSWIN4.1", 8);
>>      bootsector->sector_size=cpu_to_le16(0x200);
>>      bootsector->sectors_per_cluster=s->sectors_per_cluster;
>>      bootsector->reserved_sectors=cpu_to_le16(1);
>>
>
> Regards,
>
> Phil.
>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [PATCH v2 05/13] vvfat: introduce offset_to_bootsector, offset_to_fat and offset_to_root_dir
  2017-05-22 21:11 ` [Qemu-devel] [PATCH v2 05/13] vvfat: introduce offset_to_bootsector, offset_to_fat and offset_to_root_dir Hervé Poussineau
@ 2017-05-24  4:10   ` Philippe Mathieu-Daudé
  2017-05-24 13:34     ` Eric Blake
  0 siblings, 1 reply; 29+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-05-24  4:10 UTC (permalink / raw)
  To: Hervé Poussineau, qemu-devel; +Cc: Kevin Wolf, qemu-block, Max Reitz

Hi Hervé,

On 05/22/2017 06:11 PM, Hervé Poussineau wrote:
> - offset_to_bootsector is the number of sectors up to FAT bootsector
> - offset_to_fat is the number of sectors up to first File Allocation Table
> - offset_to_root_dir is the number of sectors up to root directory sector

Eventually your commit description can end here, adding the 3 following 
lines below the "---" separator.

> Replace first_sectors_number - 1 by offset_to_bootsector.
> Replace first_sectors_number by offset_to_fat.
> Replace faked_sectors by offset_to_rootdir.

This is "offset_to_root_dir"

>
> Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
> ---

   ^-- separator

>  block/vvfat.c | 70 ++++++++++++++++++++++++++++++++++++-----------------------
>  1 file changed, 43 insertions(+), 27 deletions(-)
>
> diff --git a/block/vvfat.c b/block/vvfat.c
> index 6a36d4f7fa..e694d82df4 100644
> --- a/block/vvfat.c
> +++ b/block/vvfat.c
> @@ -320,22 +320,24 @@ static void print_mapping(const struct mapping_t* mapping);
>  typedef struct BDRVVVFATState {
>      CoMutex lock;
>      BlockDriverState* bs; /* pointer to parent */
> -    unsigned int first_sectors_number; /* 1 for a single partition, 0x40 for a disk with partition table */
>      unsigned char first_sectors[0x40*0x200];
>
>      int fat_type; /* 16 or 32 */
>      array_t fat,directory,mapping;
>      char volume_label[11];
>
> +    uint32_t offset_to_bootsector; /* 0 for floppy, 0x3f for disk */
> +
>      unsigned int cluster_size;
>      unsigned int sectors_per_cluster;
>      unsigned int sectors_per_fat;
>      unsigned int sectors_of_root_directory;
>      uint32_t last_cluster_of_root_directory;
> -    unsigned int faked_sectors; /* how many sectors are faked before file data */
>      uint32_t sector_count; /* total number of sectors of the partition */
>      uint32_t cluster_count; /* total number of clusters of this partition */
>      uint32_t max_fat_value;
> +    uint32_t offset_to_fat;
> +    uint32_t offset_to_root_dir;
>
>      int current_fd;
>      mapping_t* current_mapping;
> @@ -394,15 +396,15 @@ static void init_mbr(BDRVVVFATState *s, int cyls, int heads, int secs)
>      partition->attributes=0x80; /* bootable */
>
>      /* LBA is used when partition is outside the CHS geometry */
> -    lba  = sector2CHS(&partition->start_CHS, s->first_sectors_number - 1,
> +    lba  = sector2CHS(&partition->start_CHS, s->offset_to_bootsector,
>                       cyls, heads, secs);
>      lba |= sector2CHS(&partition->end_CHS,   s->bs->total_sectors - 1,
>                       cyls, heads, secs);
>
>      /*LBA partitions are identified only by start/length_sector_long not by CHS*/
> -    partition->start_sector_long  = cpu_to_le32(s->first_sectors_number - 1);
> +    partition->start_sector_long  = cpu_to_le32(s->offset_to_bootsector);
>      partition->length_sector_long = cpu_to_le32(s->bs->total_sectors
> -                                                - s->first_sectors_number + 1);
> +                                                - s->offset_to_bootsector);
>
>      /* FAT12/FAT16/FAT32 */
>      /* DOS uses different types when partition is LBA,
> @@ -823,12 +825,12 @@ static int read_directory(BDRVVVFATState* s, int mapping_index)
>
>  static inline uint32_t sector2cluster(BDRVVVFATState* s,off_t sector_num)
>  {
> -    return (sector_num-s->faked_sectors)/s->sectors_per_cluster;
> +    return (sector_num - s->offset_to_root_dir) / s->sectors_per_cluster;
>  }
>
>  static inline off_t cluster2sector(BDRVVVFATState* s, uint32_t cluster_num)
>  {
> -    return s->faked_sectors + s->sectors_per_cluster * cluster_num;
> +    return s->offset_to_root_dir + s->sectors_per_cluster * cluster_num;
>  }
>
>  static int init_directories(BDRVVVFATState* s,
> @@ -855,6 +857,9 @@ static int init_directories(BDRVVVFATState* s,
>      i = 1+s->sectors_per_cluster*0x200*8/s->fat_type;
>      s->sectors_per_fat=(s->sector_count+i)/i; /* round up */
>
> +    s->offset_to_fat = s->offset_to_bootsector + 1;
> +    s->offset_to_root_dir = s->offset_to_fat + s->sectors_per_fat * 2;
> +
>      array_init(&(s->mapping),sizeof(mapping_t));
>      array_init(&(s->directory),sizeof(direntry_t));
>
> @@ -868,7 +873,6 @@ static int init_directories(BDRVVVFATState* s,
>      /* Now build FAT, and write back information into directory */
>      init_fat(s);
>
> -    s->faked_sectors=s->first_sectors_number+s->sectors_per_fat*2;
>      s->cluster_count=sector2cluster(s, s->sector_count);
>
>      mapping = array_get_next(&(s->mapping));
> @@ -946,7 +950,8 @@ static int init_directories(BDRVVVFATState* s,
>
>      s->current_mapping = NULL;
>
> -    bootsector=(bootsector_t*)(s->first_sectors+(s->first_sectors_number-1)*0x200);
> +    bootsector = (bootsector_t *)(s->first_sectors
> +                                  + s->offset_to_bootsector * 0x200);
>      bootsector->jump[0]=0xeb;
>      bootsector->jump[1]=0x3e;
>      bootsector->jump[2]=0x90;
> @@ -957,16 +962,18 @@ static int init_directories(BDRVVVFATState* s,
>      bootsector->number_of_fats=0x2; /* number of FATs */
>      bootsector->root_entries=cpu_to_le16(s->sectors_of_root_directory*0x10);
>      bootsector->total_sectors16=s->sector_count>0xffff?0:cpu_to_le16(s->sector_count);
> -    bootsector->media_type=(s->first_sectors_number>1?0xf8:0xf0); /* media descriptor (f8=hd, f0=3.5 fd)*/
> +    /* media descriptor: hard disk=0xf8, floppy=0xf0 */

Can you move this comment in the struct BDRVVVFATState definition, and 
add defines/enum for the values? Maybe use an inline function like 
"media_type(BDRVVVFATState *)".

> +    bootsector->media_type = (s->offset_to_bootsector > 0 ? 0xf8 : 0xf0);
>      s->fat.pointer[0] = bootsector->media_type;
>      bootsector->sectors_per_fat=cpu_to_le16(s->sectors_per_fat);
>      bootsector->sectors_per_track = cpu_to_le16(secs);
>      bootsector->number_of_heads = cpu_to_le16(heads);
> -    bootsector->hidden_sectors=cpu_to_le32(s->first_sectors_number==1?0:0x3f);
> +    bootsector->hidden_sectors = cpu_to_le32(s->offset_to_bootsector);

I understood this change after reading backward:
"uint32_t offset_to_bootsector; /* 0 for floppy, 0x3f for disk */"

>      bootsector->total_sectors=cpu_to_le32(s->sector_count>0xffff?s->sector_count:0);
>
>      /* LATER TODO: if FAT32, this is wrong */
> -    bootsector->u.fat16.drive_number=s->first_sectors_number==1?0:0x80; /* fda=0, hda=0x80 */
> +    /* drive_number: fda=0, hda=0x80 */
> +    bootsector->u.fat16.drive_number = s->offset_to_bootsector == 0 ? 0 : 0x80;
>      bootsector->u.fat16.current_head=0;
>      bootsector->u.fat16.signature=0x29;
>      bootsector->u.fat16.id=cpu_to_le32(0xfabe1afd);
> @@ -1123,7 +1130,6 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
>              secs = s->fat_type == 12 ? 18 : 36;
>              s->sectors_per_cluster = 1;
>          }
> -        s->first_sectors_number = 1;
>          cyls = 80;
>          heads = 2;
>      } else {
> @@ -1131,7 +1137,7 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
>          if (!s->fat_type) {
>              s->fat_type = 16;
>          }
> -        s->first_sectors_number = 0x40;
> +        s->offset_to_bootsector = 0x3f;
>          cyls = s->fat_type == 12 ? 64 : 1024;
>          heads = 16;
>          secs = 63;
> @@ -1167,7 +1173,7 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
>      fprintf(stderr, "vvfat %s chs %d,%d,%d\n",
>              dirname, cyls, heads, secs);
>
> -    s->sector_count = cyls * heads * secs - (s->first_sectors_number - 1);
> +    s->sector_count = cyls * heads * secs - s->offset_to_bootsector;
>
>      if (qemu_opt_get_bool(opts, "rw", false)) {
>          if (!bdrv_is_read_only(bs)) {
> @@ -1197,7 +1203,8 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
>          goto fail;
>      }
>
> -    s->sector_count = s->faked_sectors + s->sectors_per_cluster*s->cluster_count;
> +    s->sector_count = s->offset_to_root_dir
> +                    + s->sectors_per_cluster * s->cluster_count;
>
>      /* Disable migration when vvfat is used rw */
>      if (s->qcow) {
> @@ -1213,7 +1220,7 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
>          }
>      }
>
> -    if (s->first_sectors_number == 0x40) {
> +    if (s->offset_to_bootsector > 0) {
>          init_mbr(s, cyls, heads, secs);
>      }
>
> @@ -1426,15 +1433,24 @@ static int vvfat_read(BlockDriverState *bs, int64_t sector_num,
>              }
>  DLOG(fprintf(stderr, "sector %d not allocated\n", (int)sector_num));
>          }
> -        if(sector_num<s->faked_sectors) {
> -            if(sector_num<s->first_sectors_number)
> -                memcpy(buf+i*0x200,&(s->first_sectors[sector_num*0x200]),0x200);
> -            else if(sector_num-s->first_sectors_number<s->sectors_per_fat)
> -                memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number)*0x200]),0x200);
> -            else if(sector_num-s->first_sectors_number-s->sectors_per_fat<s->sectors_per_fat)
> -                memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number-s->sectors_per_fat)*0x200]),0x200);
> +        if (sector_num < s->offset_to_root_dir) {
> +            if (sector_num < s->offset_to_fat) {
> +                memcpy(buf + i * 0x200,
> +                       &(s->first_sectors[sector_num * 0x200]),
> +                       0x200);
> +            } else if (sector_num < s->offset_to_fat + s->sectors_per_fat) {
> +                memcpy(buf + i * 0x200,
> +                       &(s->fat.pointer[(sector_num
> +                                       - s->offset_to_fat) * 0x200]),
> +                       0x200);
> +            } else if (sector_num < s->offset_to_root_dir) {
> +                memcpy(buf + i * 0x200,
> +                       &(s->fat.pointer[(sector_num - s->offset_to_fat
> +                                       - s->sectors_per_fat) * 0x200]),
> +                       0x200);
> +            }
>          } else {
> -            uint32_t sector=sector_num-s->faked_sectors,
> +            uint32_t sector = sector_num - s->offset_to_root_dir,
>              sector_offset_in_cluster=(sector%s->sectors_per_cluster),
>              cluster_num=sector/s->sectors_per_cluster;
>              if(cluster_num > s->cluster_count || read_cluster(s, cluster_num) != 0) {
> @@ -2046,7 +2062,7 @@ DLOG(checkpoint());
>          memcpy(s->fat2, s->fat.pointer, size);
>      }
>      check = vvfat_read(s->bs,
> -            s->first_sectors_number, s->fat2, s->sectors_per_fat);
> +            s->offset_to_fat, s->fat2, s->sectors_per_fat);
>      if (check) {
>          fprintf(stderr, "Could not copy fat\n");
>          return 0;
> @@ -2865,7 +2881,7 @@ DLOG(checkpoint());
>       * - do not allow to write non-ASCII filenames
>       */
>
> -    if (sector_num < s->first_sectors_number)
> +    if (sector_num < s->offset_to_fat)
>          return -1;
>
>      for (i = sector2cluster(s, sector_num);
>

Except those style comment, this patch is Ok to me.

Regards,

Phil.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [PATCH v2 09/13] vvfat: correctly create base short names for non-ASCII filenames
  2017-05-22 21:12 ` [Qemu-devel] [PATCH v2 09/13] vvfat: correctly create base short " Hervé Poussineau
@ 2017-05-24  4:17   ` Philippe Mathieu-Daudé
  2017-05-24  5:43     ` Hervé Poussineau
  0 siblings, 1 reply; 29+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-05-24  4:17 UTC (permalink / raw)
  To: Hervé Poussineau, qemu-devel; +Cc: Kevin Wolf, qemu-block, Max Reitz

Hi Hervé,

On 05/22/2017 06:12 PM, Hervé Poussineau wrote:
> More specifically, create short name from filename and change blacklist of
> invalid chars to whitelist of valid chars.
>
> Windows 9x also now correctly see long file names of filenames containing a space,
> but Scandisk still complains about mismatch between SFN and LFN.
>
> Specification: "FAT: General overview of on-disk format" v1.03, pages 30-31
> Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
> ---
>  block/vvfat.c | 105 ++++++++++++++++++++++++++++++++++++++++++----------------
>  1 file changed, 77 insertions(+), 28 deletions(-)
>
> diff --git a/block/vvfat.c b/block/vvfat.c
> index d34241da17..3cb65493cd 100644
> --- a/block/vvfat.c
> +++ b/block/vvfat.c
> @@ -516,6 +516,81 @@ static void set_begin_of_direntry(direntry_t* direntry, uint32_t begin)
>      direntry->begin_hi = cpu_to_le16((begin >> 16) & 0xffff);
>  }
>
> +static uint8_t to_valid_short_char(gunichar c)
> +{
> +    c = g_unichar_toupper(c);
> +    if ((c >= '0' && c <= '9') ||
> +        (c >= 'A' && c <= 'Z') ||
> +        strchr("$%'-_@~`!(){}^#&", c) != 0) {
> +        return c;
> +    } else {
> +        return 0;
> +    }
> +}
> +
> +static direntry_t *create_short_filename(BDRVVVFATState *s,
> +                                         const char *filename)
> +{
> +    int i, j = 0;
> +    direntry_t *entry = array_get_next(&(s->directory));
> +    const gchar *p, *last_dot = NULL;
> +    gunichar c;
> +    bool lossy_conversion = false;

What is the purpose of this variable? Do you plan to use it later or it 
is just for debugging?

> +    char tail[11];

This also looks like old debug code...

> +
> +    if (!entry) {
> +        return NULL;
> +    }
> +    memset(entry->name, 0x20, sizeof(entry->name));
> +
> +    /* copy filename and search last dot */
> +    for (p = filename; ; p = g_utf8_next_char(p)) {
> +        c = g_utf8_get_char(p);
> +        if (c == '\0') {
> +            break;
> +        } else if (c == '.') {
> +            if (j == 0) {
> +                /* '.' at start of filename */
> +                lossy_conversion = true;
> +            } else {
> +                if (last_dot) {
> +                    lossy_conversion = true;
> +                }
> +                last_dot = p;
> +            }
> +        } else if (!last_dot) {
> +            /* first part of the name; copy it */
> +            uint8_t v = to_valid_short_char(c);
> +            if (j < 8 && v) {
> +                entry->name[j++] = v;
> +            } else {
> +                lossy_conversion = true;
> +            }
> +        }
> +    }
> +
> +    /* copy extension (if any) */
> +    if (last_dot) {
> +        j = 0;
> +        for (p = g_utf8_next_char(last_dot); ; p = g_utf8_next_char(p)) {
> +            c = g_utf8_get_char(p);
> +            if (c == '\0') {
> +                break;
> +            } else {
> +                /* extension; copy it */
> +                uint8_t v = to_valid_short_char(c);
> +                if (j < 3 && v) {
> +                    entry->name[8 + (j++)] = v;
> +                } else {
> +                    lossy_conversion = true;
> +                }
> +            }
> +        }
> +    }
> +    (void)lossy_conversion;
> +    return entry;
> +}
> +
>  /* fat functions */
>
>  static inline uint8_t fat_chksum(const direntry_t* entry)
> @@ -614,7 +689,7 @@ static inline void init_fat(BDRVVVFATState* s)
>  static inline direntry_t* create_short_and_long_name(BDRVVVFATState* s,
>          unsigned int directory_start, const char* filename, int is_dot)
>  {
> -    int i,j,long_index=s->directory.next;
> +    int long_index = s->directory.next;
>      direntry_t* entry = NULL;
>      direntry_t* entry_long = NULL;
>
> @@ -626,33 +701,7 @@ static inline direntry_t* create_short_and_long_name(BDRVVVFATState* s,
>      }
>
>      entry_long=create_long_filename(s,filename);
> -
> -    i = strlen(filename);
> -    for(j = i - 1; j>0  && filename[j]!='.';j--);
> -    if (j > 0)
> -        i = (j > 8 ? 8 : j);
> -    else if (i > 8)
> -        i = 8;
> -
> -    entry=array_get_next(&(s->directory));
> -    memset(entry->name, 0x20, sizeof(entry->name));
> -    memcpy(entry->name, filename, i);
> -
> -    if (j > 0) {
> -        for (i = 0; i < 3 && filename[j + 1 + i]; i++) {
> -            entry->name[8 + i] = filename[j + 1 + i];
> -        }
> -    }
> -
> -    /* upcase & remove unwanted characters */
> -    for(i=10;i>=0;i--) {
> -        if(i==10 || i==7) for(;i>0 && entry->name[i]==' ';i--);
> -        if(entry->name[i]<=' ' || entry->name[i]>0x7f
> -                || strchr(".*?<>|\":/\\[];,+='",entry->name[i]))
> -            entry->name[i]='_';
> -        else if(entry->name[i]>='a' && entry->name[i]<='z')
> -            entry->name[i]+='A'-'a';
> -    }
> +    entry = create_short_filename(s, filename);
>
>      /* mangle duplicates */
>      while(1) {
>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [PATCH v2 12/13] vvfat: handle KANJI lead byte 0xe5
  2017-05-22 21:12 ` [Qemu-devel] [PATCH v2 12/13] vvfat: handle KANJI lead byte 0xe5 Hervé Poussineau
@ 2017-05-24  4:20   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 29+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-05-24  4:20 UTC (permalink / raw)
  To: Hervé Poussineau, qemu-devel; +Cc: Kevin Wolf, qemu-block, Max Reitz

Hi Hervé,

You explained in the cover "fix problems detected by disk checking 
utilities in read-only mode", do you think it would be doable to have 
unit-tests for those corner cases?

On 05/22/2017 06:12 PM, Hervé Poussineau wrote:
> Specification: "FAT: General overview of on-disk format" v1.03, page 23
> Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
> ---
>  block/vvfat.c | 9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/block/vvfat.c b/block/vvfat.c
> index 5376659010..53e8faa54c 100644
> --- a/block/vvfat.c
> +++ b/block/vvfat.c
> @@ -590,6 +590,10 @@ static direntry_t *create_short_filename(BDRVVVFATState *s,
>          }
>      }
>
> +    if (entry->name[0] == 0xe5) {

This deserves a comment, and a #define would also be welcomed.

> +        entry->name[0] = 0x05;
> +    }
> +
>      /* numeric-tail generation */
>      for (j = 0; j < 8; j++) {
>          if (entry->name[j] == ' ') {
> @@ -710,8 +714,6 @@ static inline void init_fat(BDRVVVFATState* s)
>
>  }
>
> -/* TODO: in create_short_filename, 0xe5->0x05 is not yet handled! */
> -/* TODO: in parse_short_filename, 0x05->0xe5 is not yet handled! */
>  static inline direntry_t* create_short_and_long_name(BDRVVVFATState* s,
>          unsigned int directory_start, const char* filename, int is_dot)
>  {
> @@ -1744,6 +1746,9 @@ static int parse_short_name(BDRVVVFATState* s,
>      } else
>          lfn->name[i + j + 1] = '\0';
>
> +    if (lfn->name[0] == 0x05) {
> +        lfn->name[0] = 0xe5;
> +    }
>      lfn->len = strlen((char*)lfn->name);
>
>      return 0;
>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [PATCH v2 13/13] vvfat: change OEM name to 'MSWIN4.1'
  2017-05-23 19:41     ` Hervé Poussineau
@ 2017-05-24  4:27       ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 29+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-05-24  4:27 UTC (permalink / raw)
  To: Hervé Poussineau, qemu-devel; +Cc: Kevin Wolf, qemu-block, Max Reitz

On 05/23/2017 04:41 PM, Hervé Poussineau wrote:
> Hi Philippe,
>
> Le 23/05/2017 à 06:23, Philippe Mathieu-Daudé a écrit :
>> Hi Hervé,
>>
>> On 05/22/2017 06:12 PM, Hervé Poussineau wrote:
>>> According to specification:
>>> "'MSWIN4.1' is the recommanded setting, because it is the setting
>>> least likely
>>> to cause compatibility problems. If you want to put something else in
>>> here,
>>> that is your option, but the result may be that some FAT drivers
>>> might not
>>> recognize the volume."
>>
>> It also says "Typically this is some indication of what system formatted
>> the volume."
>>
>> From https://technet.microsoft.com/en-us/library/cc976796.aspx:
>>
>> "Following the jump instruction is the 8-byte OEM ID, a string of
>> characters that identifies the name and version number of the
>> operating system that formatted the volume. To preserve compatibility
>> with MS-DOS, Windows 2000 records "MSDOS5.0" in this field on FAT16
>> and FAT32 disks. On NTFS disks, Windows 2000 records "NTFS."
>> You may also see the OEM ID "MSWIN4.0" on disks formatted by Windows
>> 95 and "MSWIN4.1" on disks formatted by Windows 95 OSR2 and Windows
>> 98. Windows 2000 does not use the OEM ID field in the boot
>> sector except for verifying NTFS volumes."
>>
>> I'm curious which one is the most up-to-date, the specification v1.03
>> or a Windows 2000. Do you have an idea if there is more MSDOS/W2K vs
>> W95/98 users? Hopefully W95 is a Long time no see to me.
>>
>> You think having "QEMU" OEM does more harm than good?
>
> That's complicated. Indeed, OEM ID should be the name of the OS/tool
> which formatted the partition.
> However, some FAT drivers take different paths according to OEM ID.
> See for example:
> https://jdebp.eu/FGA/volume-boot-block-oem-name-field.html

"Linux (util-linux up to at least version 2.12) ... [first characters 
are QEMU] Treat the volume as unformatted" :facepalm:

> http://seasip.info./Misc/oemid.html
>
> So, in my opinion, it should be better to stick to some specification
> for the whole FAT format, so we have a reference document to know if
> there is a bug in the code or not.

Once explained, that's fine :) Can you add those references in the code? 
Eventually add a #define VOLUME_BOOT_BLOCKS_OEM_NAME with a fast 
explanation and those urls.

With that:
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

> FAT specification 1.03 is dated December 6, 2000, while Windows 2000 has
> been released December 15, 1999, so both are around the same date.
> FAT specification gives all details about all disk structures, so I
> think that's better to stick to what it says.
>
> So to answer your question, and knowing the tricks played with OEM ID, I
> think that's better to use "MSWIN4.1" than "QEMU".
>
> Regards,
>
> Hervé
>
>>
>>>
>>> Specification: "FAT: General overview of on-disk format" v1.03, page 9
>>> Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
>>> ---
>>>  block/vvfat.c | 2 +-
>>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/block/vvfat.c b/block/vvfat.c
>>> index 53e8faa54c..1f7f46ecea 100644
>>> --- a/block/vvfat.c
>>> +++ b/block/vvfat.c
>>> @@ -1024,7 +1024,7 @@ static int init_directories(BDRVVVFATState* s,
>>>      bootsector->jump[0]=0xeb;
>>>      bootsector->jump[1]=0x3e;
>>>      bootsector->jump[2]=0x90;
>>> -    memcpy(bootsector->name,"QEMU    ",8);
>>> +    memcpy(bootsector->name, "MSWIN4.1", 8);
>>>      bootsector->sector_size=cpu_to_le16(0x200);
>>>      bootsector->sectors_per_cluster=s->sectors_per_cluster;
>>>      bootsector->reserved_sectors=cpu_to_le16(1);
>>>
>>
>> Regards,
>>
>> Phil.
>>
>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [PATCH v2 09/13] vvfat: correctly create base short names for non-ASCII filenames
  2017-05-24  4:17   ` Philippe Mathieu-Daudé
@ 2017-05-24  5:43     ` Hervé Poussineau
  0 siblings, 0 replies; 29+ messages in thread
From: Hervé Poussineau @ 2017-05-24  5:43 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel; +Cc: Kevin Wolf, qemu-block, Max Reitz

Hi Philippe,

Le 24/05/2017 à 06:17, Philippe Mathieu-Daudé a écrit :
> Hi Hervé,
>
> On 05/22/2017 06:12 PM, Hervé Poussineau wrote:
>> More specifically, create short name from filename and change blacklist of
>> invalid chars to whitelist of valid chars.
>>
>> Windows 9x also now correctly see long file names of filenames containing a space,
>> but Scandisk still complains about mismatch between SFN and LFN.
>>
>> Specification: "FAT: General overview of on-disk format" v1.03, pages 30-31
>> Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
>> ---
>>  block/vvfat.c | 105 ++++++++++++++++++++++++++++++++++++++++++----------------
>>  1 file changed, 77 insertions(+), 28 deletions(-)
>>
>> diff --git a/block/vvfat.c b/block/vvfat.c
>> index d34241da17..3cb65493cd 100644
>> --- a/block/vvfat.c
>> +++ b/block/vvfat.c
>> @@ -516,6 +516,81 @@ static void set_begin_of_direntry(direntry_t* direntry, uint32_t begin)
>>      direntry->begin_hi = cpu_to_le16((begin >> 16) & 0xffff);
>>  }
>>
>> +static uint8_t to_valid_short_char(gunichar c)
>> +{
>> +    c = g_unichar_toupper(c);
>> +    if ((c >= '0' && c <= '9') ||
>> +        (c >= 'A' && c <= 'Z') ||
>> +        strchr("$%'-_@~`!(){}^#&", c) != 0) {
>> +        return c;
>> +    } else {
>> +        return 0;
>> +    }
>> +}
>> +
>> +static direntry_t *create_short_filename(BDRVVVFATState *s,
>> +                                         const char *filename)
>> +{
>> +    int i, j = 0;
>> +    direntry_t *entry = array_get_next(&(s->directory));
>> +    const gchar *p, *last_dot = NULL;
>> +    gunichar c;
>> +    bool lossy_conversion = false;
>
> What is the purpose of this variable? Do you plan to use it later or it is just for debugging?

I will use it later in patch 10/13, when generating numeric-tails of short names (~1, ~2...)

>
>> +    char tail[11];
>
> This also looks like old debug code...

Yes, good catch! I will remove it. Compiler didn't warn me.

>
>> +
>> +    if (!entry) {
>> +        return NULL;
>> +    }
>> +    memset(entry->name, 0x20, sizeof(entry->name));
>> +
>> +    /* copy filename and search last dot */
>> +    for (p = filename; ; p = g_utf8_next_char(p)) {
>> +        c = g_utf8_get_char(p);
>> +        if (c == '\0') {
>> +            break;
>> +        } else if (c == '.') {
>> +            if (j == 0) {
>> +                /* '.' at start of filename */
>> +                lossy_conversion = true;
>> +            } else {
>> +                if (last_dot) {
>> +                    lossy_conversion = true;
>> +                }
>> +                last_dot = p;
>> +            }
>> +        } else if (!last_dot) {
>> +            /* first part of the name; copy it */
>> +            uint8_t v = to_valid_short_char(c);
>> +            if (j < 8 && v) {
>> +                entry->name[j++] = v;
>> +            } else {
>> +                lossy_conversion = true;
>> +            }
>> +        }
>> +    }
>> +
>> +    /* copy extension (if any) */
>> +    if (last_dot) {
>> +        j = 0;
>> +        for (p = g_utf8_next_char(last_dot); ; p = g_utf8_next_char(p)) {
>> +            c = g_utf8_get_char(p);
>> +            if (c == '\0') {
>> +                break;
>> +            } else {
>> +                /* extension; copy it */
>> +                uint8_t v = to_valid_short_char(c);
>> +                if (j < 3 && v) {
>> +                    entry->name[8 + (j++)] = v;
>> +                } else {
>> +                    lossy_conversion = true;
>> +                }
>> +            }
>> +        }
>> +    }

>> +    (void)lossy_conversion;
>> +    return entry;

See the (void)lossy_conversion, which was put on purpose. Those two lines will be replaced in patch 10/13.

>> +}
>> +
>>  /* fat functions */
>>
>>  static inline uint8_t fat_chksum(const direntry_t* entry)
>> @@ -614,7 +689,7 @@ static inline void init_fat(BDRVVVFATState* s)
>>  static inline direntry_t* create_short_and_long_name(BDRVVVFATState* s,
>>          unsigned int directory_start, const char* filename, int is_dot)
>>  {
>> -    int i,j,long_index=s->directory.next;
>> +    int long_index = s->directory.next;
>>      direntry_t* entry = NULL;
>>      direntry_t* entry_long = NULL;
>>
>> @@ -626,33 +701,7 @@ static inline direntry_t* create_short_and_long_name(BDRVVVFATState* s,
>>      }
>>
>>      entry_long=create_long_filename(s,filename);
>> -
>> -    i = strlen(filename);
>> -    for(j = i - 1; j>0  && filename[j]!='.';j--);
>> -    if (j > 0)
>> -        i = (j > 8 ? 8 : j);
>> -    else if (i > 8)
>> -        i = 8;
>> -
>> -    entry=array_get_next(&(s->directory));
>> -    memset(entry->name, 0x20, sizeof(entry->name));
>> -    memcpy(entry->name, filename, i);
>> -
>> -    if (j > 0) {
>> -        for (i = 0; i < 3 && filename[j + 1 + i]; i++) {
>> -            entry->name[8 + i] = filename[j + 1 + i];
>> -        }
>> -    }
>> -
>> -    /* upcase & remove unwanted characters */
>> -    for(i=10;i>=0;i--) {
>> -        if(i==10 || i==7) for(;i>0 && entry->name[i]==' ';i--);
>> -        if(entry->name[i]<=' ' || entry->name[i]>0x7f
>> -                || strchr(".*?<>|\":/\\[];,+='",entry->name[i]))
>> -            entry->name[i]='_';
>> -        else if(entry->name[i]>='a' && entry->name[i]<='z')
>> -            entry->name[i]+='A'-'a';
>> -    }
>> +    entry = create_short_filename(s, filename);
>>
>>      /* mangle duplicates */
>>      while(1) {
>>
>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [PATCH v2 05/13] vvfat: introduce offset_to_bootsector, offset_to_fat and offset_to_root_dir
  2017-05-24  4:10   ` Philippe Mathieu-Daudé
@ 2017-05-24 13:34     ` Eric Blake
  0 siblings, 0 replies; 29+ messages in thread
From: Eric Blake @ 2017-05-24 13:34 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, Hervé Poussineau, qemu-devel
  Cc: Kevin Wolf, qemu-block, Max Reitz

[-- Attachment #1: Type: text/plain, Size: 956 bytes --]

On 05/23/2017 11:10 PM, Philippe Mathieu-Daudé wrote:
> Hi Hervé,
> 
> On 05/22/2017 06:11 PM, Hervé Poussineau wrote:
>> - offset_to_bootsector is the number of sectors up to FAT bootsector
>> - offset_to_fat is the number of sectors up to first File Allocation
>> Table
>> - offset_to_root_dir is the number of sectors up to root directory sector
> 
> Eventually your commit description can end here, adding the 3 following
> lines below the "---" separator.

No. Stuff after the --- is intended for things that are useful to
reviewers, but not helpful in the long run.  But in this case:

> 
>> Replace first_sectors_number - 1 by offset_to_bootsector.

Knowing the conversion that was made DOES make it easier to read this
patch, even in the long run.  So this information belongs before the ---.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [PATCH v2 00/13] vvfat: misc fixes for read-only mode
  2017-05-22 21:11 [Qemu-devel] [PATCH v2 00/13] vvfat: misc fixes for read-only mode Hervé Poussineau
                   ` (13 preceding siblings ...)
  2017-05-22 22:38 ` [Qemu-devel] [PATCH v2 00/13] vvfat: misc fixes for read-only mode no-reply
@ 2017-07-03 16:50 ` Kevin Wolf
  2017-07-06  5:27   ` Hervé Poussineau
  14 siblings, 1 reply; 29+ messages in thread
From: Kevin Wolf @ 2017-07-03 16:50 UTC (permalink / raw)
  To: Hervé Poussineau; +Cc: qemu-devel, qemu-block, Max Reitz

Am 22.05.2017 um 23:11 hat Hervé Poussineau geschrieben:
> Hi,
> 
> This patchset fixes some of issues I encountered when trying to use vvfat, and fixes
> bug #1599539: https://bugs.launchpad.net/qemu/+bug/1599539
> 
> Patch 1 fixes a crash when using 'qemu-img convert'.
> Patches 2 to 6 are code cleanup. No functionnal changes.
> Patches 7 to 13 fix problems detected by disk checking utilities in read-only mode.
> 
> With these patches, vvfat creates valid FAT volumes and can be used with QEMU disk utilities.
> 
> Read-write mode is still buggy after this patchset, but at least, I was not
> able to crash QEMU anymore.
> 
> Note that patch 2 doesn't pass checkpatch.pl, as it changes indentation only.

Thanks, fixed the build error in patch 9 (yet unused variables) and
applied to the block branch.

There were a few more minor comments for this series, but it has been on
the list for long enough and I figured that they can be addressed on
top.

Kevin

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [PATCH v2 00/13] vvfat: misc fixes for read-only mode
  2017-07-03 16:50 ` Kevin Wolf
@ 2017-07-06  5:27   ` Hervé Poussineau
  0 siblings, 0 replies; 29+ messages in thread
From: Hervé Poussineau @ 2017-07-06  5:27 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: qemu-devel, qemu-block, Max Reitz

Hi,

Thanks to have taken this patch series.

However, I already have in my repository the v3 patch series, whose changelog is:

Changes v2->v3:
- added patches 5, 12, 16
- fixed warning (unused variable) (patch 11)
- added #defines for constants for deleted byte following Philippe remarks (patch 14)
- added #define and explanations for OEM name following Philippe remarks (patch 15)

Changes v1->v2:
- small changes following Kevin remarks (patches 3, 5, 6)
- use g_utf8_* functions instead of ad-hock code (patches 8 and 9)
- fix a bug with filenames starting with a dot (patch 9)

Hervé Poussineau (16):
   vvfat: fix qemu-img map and qemu-img convert
   vvfat: replace tabs by 8 spaces
   vvfat: fix typos
   vvfat: rename useless enumeration values
   vvfat: add constants for special values of name[0]
   vvfat: introduce offset_to_bootsector, offset_to_fat and
     offset_to_root_dir
   vvfat: fix field names in FAT12/FAT16 and FAT32 boot sectors
   vvfat: always create . and .. entries at first and in that order
   vvfat: correctly create long names for non-ASCII filenames
   vvfat: correctly create base short names for non-ASCII filenames
   vvfat: correctly generate numeric-tail of short file names
   vvfat: correctly parse non-ASCII short and long file names
   vvfat: limit number of entries in root directory in FAT12/FAT16
   vvfat: handle KANJI lead byte 0xe5
   vvfat: change OEM name to 'MSWIN4.1'
   vvfat: initialize memory after allocating it

Should I rebase on top of your branch, or should I send the v3 as is?

It fixes the last random errors I had in Win9x Scandisk (uninitialized memory).

Regards,

Hervé

Le 03/07/2017 à 18:50, Kevin Wolf a écrit :
> Am 22.05.2017 um 23:11 hat Hervé Poussineau geschrieben:
>> Hi,
>>
>> This patchset fixes some of issues I encountered when trying to use vvfat, and fixes
>> bug #1599539: https://bugs.launchpad.net/qemu/+bug/1599539
>>
>> Patch 1 fixes a crash when using 'qemu-img convert'.
>> Patches 2 to 6 are code cleanup. No functionnal changes.
>> Patches 7 to 13 fix problems detected by disk checking utilities in read-only mode.
>>
>> With these patches, vvfat creates valid FAT volumes and can be used with QEMU disk utilities.
>>
>> Read-write mode is still buggy after this patchset, but at least, I was not
>> able to crash QEMU anymore.
>>
>> Note that patch 2 doesn't pass checkpatch.pl, as it changes indentation only.
>
> Thanks, fixed the build error in patch 9 (yet unused variables) and
> applied to the block branch.
>
> There were a few more minor comments for this series, but it has been on
> the list for long enough and I figured that they can be addressed on
> top.
>
> Kevin
>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [PATCH v2 10/13] vvfat: correctly generate numeric-tail of short file names
  2017-05-22 21:12 ` [Qemu-devel] [PATCH v2 10/13] vvfat: correctly generate numeric-tail of short file names Hervé Poussineau
@ 2017-08-05 18:52   ` Pranith Kumar
  2017-08-07 11:07     ` Eric Blake
  0 siblings, 1 reply; 29+ messages in thread
From: Pranith Kumar @ 2017-08-05 18:52 UTC (permalink / raw)
  To: Hervé Poussineau
  Cc: qemu-devel, Kevin Wolf, open list:Block I/O path, Max Reitz

FYI,

This commit breaks the build with gcc-7:

  CC      block/vvfat.o
qemu/block/vvfat.c: In function ‘read_directory’:
qemu/block/vvfat.c:605:37: error: ‘__builtin___sprintf_chk’ may write
a terminating nul past the end of the destination
[-Werror=format-overflow=]
             int len = sprintf(tail, "~%d", i);
                                     ^~~~~
In file included from /usr/include/stdio.h:938:0,
                 from qemu/include/qemu/osdep.h:68,
                 from qemu/block/vvfat.c:25:
/usr/include/x86_64-linux-gnu/bits/stdio2.h:33:10: note:
‘__builtin___sprintf_chk’ output between 3 and 12 bytes into a
destination of size 11
   return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1,
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       __bos (__s), __fmt, __va_arg_pack ());
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
qemu/rules.mak:66: recipe for target 'block/vvfat.o' failed
make: *** [block/vvfat.o] Error 1


Thanks,

On Mon, May 22, 2017 at 5:12 PM, Hervé Poussineau <hpoussin@reactos.org> wrote:
> More specifically:
> - try without numeric-tail only if LFN didn't have invalid short chars
> - start at ~1 (instead of ~0)
> - handle case if numeric tail is more than one char (ie > 10)
>
> Windows 9x Scandisk doesn't see anymore mismatches between short file names and
> long file names for non-ASCII filenames.
>
> Specification: "FAT: General overview of on-disk format" v1.03, page 31
> Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
> ---
>  block/vvfat.c | 62 ++++++++++++++++++++++++++++-------------------------------
>  1 file changed, 29 insertions(+), 33 deletions(-)
>
> diff --git a/block/vvfat.c b/block/vvfat.c
> index 3cb65493cd..414bca6dee 100644
> --- a/block/vvfat.c
> +++ b/block/vvfat.c
> @@ -529,7 +529,8 @@ static uint8_t to_valid_short_char(gunichar c)
>  }
>
>  static direntry_t *create_short_filename(BDRVVVFATState *s,
> -                                         const char *filename)
> +                                         const char *filename,
> +                                         unsigned int directory_start)
>  {
>      int i, j = 0;
>      direntry_t *entry = array_get_next(&(s->directory));
> @@ -587,8 +588,32 @@ static direntry_t *create_short_filename(BDRVVVFATState *s,
>              }
>          }
>      }
> -    (void)lossy_conversion;
> -    return entry;
> +
> +    /* numeric-tail generation */
> +    for (j = 0; j < 8; j++) {
> +        if (entry->name[j] == ' ') {
> +            break;
> +        }
> +    }
> +    for (i = lossy_conversion ? 1 : 0; i < 999999; i++) {
> +        direntry_t *entry1;
> +        if (i > 0) {
> +            int len = sprintf(tail, "~%d", i);
> +            memcpy(entry->name + MIN(j, 8 - len), tail, len);
> +        }
> +        for (entry1 = array_get(&(s->directory), directory_start);
> +             entry1 < entry; entry1++) {
> +            if (!is_long_name(entry1) &&
> +                !memcmp(entry1->name, entry->name, 11)) {
> +                break; /* found dupe */
> +            }
> +        }
> +        if (entry1 == entry) {
> +            /* no dupe found */
> +            return entry;
> +        }
> +    }
> +    return NULL;
>  }
>
>  /* fat functions */
> @@ -701,36 +726,7 @@ static inline direntry_t* create_short_and_long_name(BDRVVVFATState* s,
>      }
>
>      entry_long=create_long_filename(s,filename);
> -    entry = create_short_filename(s, filename);
> -
> -    /* mangle duplicates */
> -    while(1) {
> -        direntry_t* entry1=array_get(&(s->directory),directory_start);
> -        int j;
> -
> -        for(;entry1<entry;entry1++)
> -            if(!is_long_name(entry1) && !memcmp(entry1->name,entry->name,11))
> -                break; /* found dupe */
> -        if(entry1==entry) /* no dupe found */
> -            break;
> -
> -        /* use all 8 characters of name */
> -        if(entry->name[7]==' ') {
> -            int j;
> -            for(j=6;j>0 && entry->name[j]==' ';j--)
> -                entry->name[j]='~';
> -        }
> -
> -        /* increment number */
> -        for(j=7;j>0 && entry->name[j]=='9';j--)
> -            entry->name[j]='0';
> -        if(j>0) {
> -            if(entry->name[j]<'0' || entry->name[j]>'9')
> -                entry->name[j]='0';
> -            else
> -                entry->name[j]++;
> -        }
> -    }
> +    entry = create_short_filename(s, filename, directory_start);
>
>      /* calculate checksum; propagate to long name */
>      if(entry_long) {
> --
> 2.11.0
>
>

-- 
Pranith

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [PATCH v2 10/13] vvfat: correctly generate numeric-tail of short file names
  2017-08-05 18:52   ` Pranith Kumar
@ 2017-08-07 11:07     ` Eric Blake
  2017-08-08 23:31       ` Pranith Kumar
  0 siblings, 1 reply; 29+ messages in thread
From: Eric Blake @ 2017-08-07 11:07 UTC (permalink / raw)
  To: Pranith Kumar, Hervé Poussineau
  Cc: Kevin Wolf, qemu-devel, open list:Block I/O path, Max Reitz

[-- Attachment #1: Type: text/plain, Size: 619 bytes --]

On 08/05/2017 01:52 PM, Pranith Kumar wrote:
> FYI,
> 
> This commit breaks the build with gcc-7:
> 
>   CC      block/vvfat.o
> qemu/block/vvfat.c: In function ‘read_directory’:
> qemu/block/vvfat.c:605:37: error: ‘__builtin___sprintf_chk’ may write
> a terminating nul past the end of the destination
> [-Werror=format-overflow=]
>              int len = sprintf(tail, "~%d", i);
>                                      ^~~~~

Doesn't commit 7c8730d45f6 fix that?

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 619 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [PATCH v2 10/13] vvfat: correctly generate numeric-tail of short file names
  2017-08-07 11:07     ` Eric Blake
@ 2017-08-08 23:31       ` Pranith Kumar
  0 siblings, 0 replies; 29+ messages in thread
From: Pranith Kumar @ 2017-08-08 23:31 UTC (permalink / raw)
  To: Eric Blake
  Cc: Hervé Poussineau, Kevin Wolf, qemu-devel,
	open list:Block I/O path, Max Reitz

On Mon, Aug 7, 2017 at 7:07 AM, Eric Blake <eblake@redhat.com> wrote:
> On 08/05/2017 01:52 PM, Pranith Kumar wrote:
>> FYI,
>>
>> This commit breaks the build with gcc-7:
>>
>>   CC      block/vvfat.o
>> qemu/block/vvfat.c: In function ‘read_directory’:
>> qemu/block/vvfat.c:605:37: error: ‘__builtin___sprintf_chk’ may write
>> a terminating nul past the end of the destination
>> [-Werror=format-overflow=]
>>              int len = sprintf(tail, "~%d", i);
>>                                      ^~~~~
>
> Doesn't commit 7c8730d45f6 fix that?

Indeed it does. I hadn't rebased my branch before reporting. Sorry for
the noise!

-- 
Pranith

^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2017-08-08 23:31 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-22 21:11 [Qemu-devel] [PATCH v2 00/13] vvfat: misc fixes for read-only mode Hervé Poussineau
2017-05-22 21:11 ` [Qemu-devel] [PATCH v2 01/13] vvfat: fix qemu-img map and qemu-img convert Hervé Poussineau
2017-05-22 21:17   ` [Qemu-devel] [Qemu-block] " Eric Blake
2017-05-22 21:11 ` [Qemu-devel] [PATCH v2 02/13] vvfat: replace tabs by 8 spaces Hervé Poussineau
2017-05-22 21:11 ` [Qemu-devel] [PATCH v2 03/13] vvfat: fix typos Hervé Poussineau
2017-05-22 21:11 ` [Qemu-devel] [PATCH v2 04/13] vvfat: rename useless enumeration values Hervé Poussineau
2017-05-22 21:11 ` [Qemu-devel] [PATCH v2 05/13] vvfat: introduce offset_to_bootsector, offset_to_fat and offset_to_root_dir Hervé Poussineau
2017-05-24  4:10   ` Philippe Mathieu-Daudé
2017-05-24 13:34     ` Eric Blake
2017-05-22 21:11 ` [Qemu-devel] [PATCH v2 06/13] vvfat: fix field names in FAT12/FAT16 and FAT32 boot sectors Hervé Poussineau
2017-05-22 21:11 ` [Qemu-devel] [PATCH v2 07/13] vvfat: always create . and .. entries at first and in that order Hervé Poussineau
2017-05-22 21:12 ` [Qemu-devel] [PATCH v2 08/13] vvfat: correctly create long names for non-ASCII filenames Hervé Poussineau
2017-05-22 21:12 ` [Qemu-devel] [PATCH v2 09/13] vvfat: correctly create base short " Hervé Poussineau
2017-05-24  4:17   ` Philippe Mathieu-Daudé
2017-05-24  5:43     ` Hervé Poussineau
2017-05-22 21:12 ` [Qemu-devel] [PATCH v2 10/13] vvfat: correctly generate numeric-tail of short file names Hervé Poussineau
2017-08-05 18:52   ` Pranith Kumar
2017-08-07 11:07     ` Eric Blake
2017-08-08 23:31       ` Pranith Kumar
2017-05-22 21:12 ` [Qemu-devel] [PATCH v2 11/13] vvfat: limit number of entries in root directory in FAT12/FAT16 Hervé Poussineau
2017-05-22 21:12 ` [Qemu-devel] [PATCH v2 12/13] vvfat: handle KANJI lead byte 0xe5 Hervé Poussineau
2017-05-24  4:20   ` Philippe Mathieu-Daudé
2017-05-22 21:12 ` [Qemu-devel] [PATCH v2 13/13] vvfat: change OEM name to 'MSWIN4.1' Hervé Poussineau
2017-05-23  4:23   ` Philippe Mathieu-Daudé
2017-05-23 19:41     ` Hervé Poussineau
2017-05-24  4:27       ` Philippe Mathieu-Daudé
2017-05-22 22:38 ` [Qemu-devel] [PATCH v2 00/13] vvfat: misc fixes for read-only mode no-reply
2017-07-03 16:50 ` Kevin Wolf
2017-07-06  5:27   ` Hervé Poussineau

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.