* [Qemu-devel] [PATCH V2] block: increased maximum size of vvfat devices
@ 2018-08-23 13:37 Arkasha
2018-08-31 9:34 ` Pavel Dovgalyuk
2018-09-11 17:20 ` аркадий иванов
0 siblings, 2 replies; 4+ messages in thread
From: Arkasha @ 2018-08-23 13:37 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf, mreitz, pavel.dovgaluk, Arkasha
This fixes the problem of the impossibility to create
FAT16 disks larger than 504 mb:
The change CHS made it possible to obtain a larger disk.
Also, auto-detection of disk parameters was added depending
on the volume of the connected files:
The size of all folders and files on the created disk is calculated
and the size of the FAT table is added.
This size allows to choose the future size of the FAT drive
from the standard limitations.
Signed-off-by: Arkasha <ivanovrkasha@gmail.com>
---
block/vvfat.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 86 insertions(+), 10 deletions(-)
diff --git a/block/vvfat.c b/block/vvfat.c
index fc41841..4409233 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -77,6 +77,47 @@ static void checkpoint(void);
#define DIR_KANJI_FAKE 0x05
#define DIR_FREE 0x00
+static bool check_size(uint32_t offset_to_bootsector, int cyls, int heads,
+ int secs, uint8_t sectors_per_cluster, int fat_type,
+ long int sum, long int size_disk)
+{
+ uint32_t sector_count = cyls * heads * secs - offset_to_bootsector;
+ int i = 1 + sectors_per_cluster * 0x200 * 8 / fat_type;
+ uint16_t sectors_per_fat = (sector_count + i) / i;
+ /*size + FAT1 and FAT2 table size*/
+ if ((sum + sectors_per_fat * 512 * 2) < size_disk) {
+ return true;
+ }
+ return false;
+}
+
+static long int find_size(const char *dirname, unsigned int cluster)
+{
+ long int sum = 0;
+ DIR *dir = opendir(dirname);
+ struct dirent *entry;
+ while ((entry = readdir(dir))) {
+ unsigned int length = strlen(dirname) + 2 + strlen(entry->d_name);
+ char *buffer;
+ struct stat st;
+ buffer = g_malloc(length);
+ snprintf(buffer, length, "%s/%s", dirname, entry->d_name);
+ if (stat(buffer, &st) < 0) {
+ g_free(buffer);
+ continue;
+ }
+ if (strcmp(entry->d_name, ".") && strcmp(entry->d_name, "..")
+ && S_ISDIR(st.st_mode)) {
+ sum += find_size(buffer, cluster);
+ }
+ g_free(buffer);
+ sum += (st.st_size + cluster - 1) / (cluster) * (cluster);
+ }
+ closedir(dir);
+ return sum;
+}
+
+
/* dynamic array functions */
typedef struct array_t {
char* pointer;
@@ -948,8 +988,6 @@ 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));
@@ -1154,12 +1192,12 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
{
BDRVVVFATState *s = bs->opaque;
int cyls, heads, secs;
+ long int size_disk;
bool floppy;
const char *dirname, *label;
QemuOpts *opts;
Error *local_err = NULL;
int ret;
-
#ifdef DEBUG
vvv = s;
#endif
@@ -1181,6 +1219,29 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
s->fat_type = qemu_opt_get_number(opts, "fat-type", 0);
floppy = qemu_opt_get_bool(opts, "floppy", false);
+ unsigned int cluster;
+ long int sum = 0;
+ if (floppy) {
+ if (!s->fat_type) {
+ s->sectors_per_cluster = 2;
+ } else {
+ s->sectors_per_cluster = 1;
+ }
+ } else if (s->fat_type == 12) {
+ s->offset_to_bootsector = 0x3f;
+ s->sectors_per_cluster = 0x10;
+ } else {
+ s->offset_to_bootsector = 0x3f;
+ /* LATER TODO: if FAT32, adjust */
+ s->sectors_per_cluster = 0x80;
+ }
+
+ cluster = s->sectors_per_cluster * 0x200;
+ sum += find_size(dirname, cluster);
+ /* TODO: if there are more entries, bootsector has to be adjusted! */
+ s->root_entries = 0x02 * 0x10 * s->sectors_per_cluster;
+ /*File size + boot sector size + root directory size*/
+ sum += 512 + s->root_entries * 32;
memset(s->volume_label, ' ', sizeof(s->volume_label));
label = qemu_opt_get(opts, "label");
@@ -1201,24 +1262,41 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
if (!s->fat_type) {
s->fat_type = 12;
secs = 36;
- s->sectors_per_cluster = 2;
} else {
secs = s->fat_type == 12 ? 18 : 36;
- s->sectors_per_cluster = 1;
}
cyls = 80;
heads = 2;
} else {
- /* 32MB or 504MB disk*/
if (!s->fat_type) {
s->fat_type = 16;
}
- s->offset_to_bootsector = 0x3f;
+ size_disk = 528482304;
cyls = s->fat_type == 12 ? 64 : 1024;
heads = 16;
secs = 63;
- }
+ if (!check_size(s->offset_to_bootsector, cyls, heads,
+ secs, s->sectors_per_cluster,
+ s->fat_type, sum, size_disk)) {
+ if (s->fat_type > 12) {
+ size_disk = 4294950912;
+ cyls = 8322;
+ heads = 16;
+ secs = 63;
+ } else {
+ fprintf(stderr, "Requires Fat16 or Fat32\n");
+ return -2;
+ }
+ if (!check_size(s->offset_to_bootsector, cyls, heads,
+ secs, s->sectors_per_cluster,
+ s->fat_type, sum, size_disk)) {
+ fprintf(stderr, "Folder is larger than %f GB\n",
+ (float)size_disk / 1073741824);
+ return -2;
+ }
+ }
+ }
switch (s->fat_type) {
case 32:
warn_report("FAT32 has not been tested. You are welcome to do so!");
@@ -1235,8 +1313,6 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
s->bs = bs;
- /* LATER TODO: if FAT32, adjust */
- s->sectors_per_cluster=0x10;
s->current_cluster=0xffffffff;
--
2.7.4
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [PATCH V2] block: increased maximum size of vvfat devices
2018-08-23 13:37 [Qemu-devel] [PATCH V2] block: increased maximum size of vvfat devices Arkasha
@ 2018-08-31 9:34 ` Pavel Dovgalyuk
2018-09-11 17:20 ` аркадий иванов
1 sibling, 0 replies; 4+ messages in thread
From: Pavel Dovgalyuk @ 2018-08-31 9:34 UTC (permalink / raw)
To: 'Arkasha', qemu-devel; +Cc: kwolf, mreitz, pavel.dovgaluk
I've tried this patch and it worked for me.
Small disk was created for the small folder, and it worked in MS-DOS.
Larger disk was automatically selected for the folder larger than 504Mb. It worked only under
Windows.
Pavel Dovgalyuk
> -----Original Message-----
> From: Arkasha [mailto:ivanovrkasha@gmail.com]
> Sent: Thursday, August 23, 2018 4:38 PM
> To: qemu-devel@nongnu.org
> Cc: kwolf@redhat.com; mreitz@redhat.com; pavel.dovgaluk@ispras.ru; Arkasha
> Subject: [PATCH V2] block: increased maximum size of vvfat devices
>
> This fixes the problem of the impossibility to create
> FAT16 disks larger than 504 mb:
> The change CHS made it possible to obtain a larger disk.
> Also, auto-detection of disk parameters was added depending
> on the volume of the connected files:
> The size of all folders and files on the created disk is calculated
> and the size of the FAT table is added.
> This size allows to choose the future size of the FAT drive
> from the standard limitations.
>
> Signed-off-by: Arkasha <ivanovrkasha@gmail.com>
> ---
> block/vvfat.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------
> 1 file changed, 86 insertions(+), 10 deletions(-)
>
> diff --git a/block/vvfat.c b/block/vvfat.c
> index fc41841..4409233 100644
> --- a/block/vvfat.c
> +++ b/block/vvfat.c
> @@ -77,6 +77,47 @@ static void checkpoint(void);
> #define DIR_KANJI_FAKE 0x05
> #define DIR_FREE 0x00
>
> +static bool check_size(uint32_t offset_to_bootsector, int cyls, int heads,
> + int secs, uint8_t sectors_per_cluster, int fat_type,
> + long int sum, long int size_disk)
> +{
> + uint32_t sector_count = cyls * heads * secs - offset_to_bootsector;
> + int i = 1 + sectors_per_cluster * 0x200 * 8 / fat_type;
> + uint16_t sectors_per_fat = (sector_count + i) / i;
> + /*size + FAT1 and FAT2 table size*/
> + if ((sum + sectors_per_fat * 512 * 2) < size_disk) {
> + return true;
> + }
> + return false;
> +}
> +
> +static long int find_size(const char *dirname, unsigned int cluster)
> +{
> + long int sum = 0;
> + DIR *dir = opendir(dirname);
> + struct dirent *entry;
> + while ((entry = readdir(dir))) {
> + unsigned int length = strlen(dirname) + 2 + strlen(entry->d_name);
> + char *buffer;
> + struct stat st;
> + buffer = g_malloc(length);
> + snprintf(buffer, length, "%s/%s", dirname, entry->d_name);
> + if (stat(buffer, &st) < 0) {
> + g_free(buffer);
> + continue;
> + }
> + if (strcmp(entry->d_name, ".") && strcmp(entry->d_name, "..")
> + && S_ISDIR(st.st_mode)) {
> + sum += find_size(buffer, cluster);
> + }
> + g_free(buffer);
> + sum += (st.st_size + cluster - 1) / (cluster) * (cluster);
> + }
> + closedir(dir);
> + return sum;
> +}
> +
> +
> /* dynamic array functions */
> typedef struct array_t {
> char* pointer;
> @@ -948,8 +988,6 @@ 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));
> @@ -1154,12 +1192,12 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
> {
> BDRVVVFATState *s = bs->opaque;
> int cyls, heads, secs;
> + long int size_disk;
> bool floppy;
> const char *dirname, *label;
> QemuOpts *opts;
> Error *local_err = NULL;
> int ret;
> -
> #ifdef DEBUG
> vvv = s;
> #endif
> @@ -1181,6 +1219,29 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
>
> s->fat_type = qemu_opt_get_number(opts, "fat-type", 0);
> floppy = qemu_opt_get_bool(opts, "floppy", false);
> + unsigned int cluster;
> + long int sum = 0;
> + if (floppy) {
> + if (!s->fat_type) {
> + s->sectors_per_cluster = 2;
> + } else {
> + s->sectors_per_cluster = 1;
> + }
> + } else if (s->fat_type == 12) {
> + s->offset_to_bootsector = 0x3f;
> + s->sectors_per_cluster = 0x10;
> + } else {
> + s->offset_to_bootsector = 0x3f;
> + /* LATER TODO: if FAT32, adjust */
> + s->sectors_per_cluster = 0x80;
> + }
> +
> + cluster = s->sectors_per_cluster * 0x200;
> + sum += find_size(dirname, cluster);
> + /* TODO: if there are more entries, bootsector has to be adjusted! */
> + s->root_entries = 0x02 * 0x10 * s->sectors_per_cluster;
> + /*File size + boot sector size + root directory size*/
> + sum += 512 + s->root_entries * 32;
>
> memset(s->volume_label, ' ', sizeof(s->volume_label));
> label = qemu_opt_get(opts, "label");
> @@ -1201,24 +1262,41 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
> if (!s->fat_type) {
> s->fat_type = 12;
> secs = 36;
> - s->sectors_per_cluster = 2;
> } else {
> secs = s->fat_type == 12 ? 18 : 36;
> - s->sectors_per_cluster = 1;
> }
> cyls = 80;
> heads = 2;
> } else {
> - /* 32MB or 504MB disk*/
> if (!s->fat_type) {
> s->fat_type = 16;
> }
> - s->offset_to_bootsector = 0x3f;
> + size_disk = 528482304;
> cyls = s->fat_type == 12 ? 64 : 1024;
> heads = 16;
> secs = 63;
> - }
> + if (!check_size(s->offset_to_bootsector, cyls, heads,
> + secs, s->sectors_per_cluster,
> + s->fat_type, sum, size_disk)) {
> + if (s->fat_type > 12) {
> + size_disk = 4294950912;
> + cyls = 8322;
> + heads = 16;
> + secs = 63;
>
> + } else {
> + fprintf(stderr, "Requires Fat16 or Fat32\n");
> + return -2;
> + }
> + if (!check_size(s->offset_to_bootsector, cyls, heads,
> + secs, s->sectors_per_cluster,
> + s->fat_type, sum, size_disk)) {
> + fprintf(stderr, "Folder is larger than %f GB\n",
> + (float)size_disk / 1073741824);
> + return -2;
> + }
> + }
> + }
> switch (s->fat_type) {
> case 32:
> warn_report("FAT32 has not been tested. You are welcome to do so!");
> @@ -1235,8 +1313,6 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
>
> s->bs = bs;
>
> - /* LATER TODO: if FAT32, adjust */
> - s->sectors_per_cluster=0x10;
>
> s->current_cluster=0xffffffff;
>
> --
> 2.7.4
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [PATCH V2] block: increased maximum size of vvfat devices
2018-08-23 13:37 [Qemu-devel] [PATCH V2] block: increased maximum size of vvfat devices Arkasha
2018-08-31 9:34 ` Pavel Dovgalyuk
@ 2018-09-11 17:20 ` аркадий иванов
2021-03-13 14:06 ` Philippe Mathieu-Daudé
1 sibling, 1 reply; 4+ messages in thread
From: аркадий иванов @ 2018-09-11 17:20 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf, mreitz, pavel.dovgaluk
Ping?
Thu, 23 Aug. 2018 at 16:37, Arkasha <ivanovrkasha@gmail.com>:
> This fixes the problem of the impossibility to create
> FAT16 disks larger than 504 mb:
> The change CHS made it possible to obtain a larger disk.
> Also, auto-detection of disk parameters was added depending
> on the volume of the connected files:
> The size of all folders and files on the created disk is calculated
> and the size of the FAT table is added.
> This size allows to choose the future size of the FAT drive
> from the standard limitations.
>
> Signed-off-by: Arkasha <ivanovrkasha@gmail.com>
> ---
> block/vvfat.c | 96
> ++++++++++++++++++++++++++++++++++++++++++++++++++++-------
> 1 file changed, 86 insertions(+), 10 deletions(-)
>
> diff --git a/block/vvfat.c b/block/vvfat.c
> index fc41841..4409233 100644
> --- a/block/vvfat.c
> +++ b/block/vvfat.c
> @@ -77,6 +77,47 @@ static void checkpoint(void);
> #define DIR_KANJI_FAKE 0x05
> #define DIR_FREE 0x00
>
> +static bool check_size(uint32_t offset_to_bootsector, int cyls, int heads,
> + int secs, uint8_t sectors_per_cluster, int fat_type,
> + long int sum, long int size_disk)
> +{
> + uint32_t sector_count = cyls * heads * secs - offset_to_bootsector;
> + int i = 1 + sectors_per_cluster * 0x200 * 8 / fat_type;
> + uint16_t sectors_per_fat = (sector_count + i) / i;
> + /*size + FAT1 and FAT2 table size*/
> + if ((sum + sectors_per_fat * 512 * 2) < size_disk) {
> + return true;
> + }
> + return false;
> +}
> +
> +static long int find_size(const char *dirname, unsigned int cluster)
> +{
> + long int sum = 0;
> + DIR *dir = opendir(dirname);
> + struct dirent *entry;
> + while ((entry = readdir(dir))) {
> + unsigned int length = strlen(dirname) + 2 + strlen(entry->d_name);
> + char *buffer;
> + struct stat st;
> + buffer = g_malloc(length);
> + snprintf(buffer, length, "%s/%s", dirname, entry->d_name);
> + if (stat(buffer, &st) < 0) {
> + g_free(buffer);
> + continue;
> + }
> + if (strcmp(entry->d_name, ".") && strcmp(entry->d_name, "..")
> + && S_ISDIR(st.st_mode)) {
> + sum += find_size(buffer, cluster);
> + }
> + g_free(buffer);
> + sum += (st.st_size + cluster - 1) / (cluster) * (cluster);
> + }
> + closedir(dir);
> + return sum;
> +}
> +
> +
> /* dynamic array functions */
> typedef struct array_t {
> char* pointer;
> @@ -948,8 +988,6 @@ 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));
> @@ -1154,12 +1192,12 @@ static int vvfat_open(BlockDriverState *bs, QDict
> *options, int flags,
> {
> BDRVVVFATState *s = bs->opaque;
> int cyls, heads, secs;
> + long int size_disk;
> bool floppy;
> const char *dirname, *label;
> QemuOpts *opts;
> Error *local_err = NULL;
> int ret;
> -
> #ifdef DEBUG
> vvv = s;
> #endif
> @@ -1181,6 +1219,29 @@ static int vvfat_open(BlockDriverState *bs, QDict
> *options, int flags,
>
> s->fat_type = qemu_opt_get_number(opts, "fat-type", 0);
> floppy = qemu_opt_get_bool(opts, "floppy", false);
> + unsigned int cluster;
> + long int sum = 0;
> + if (floppy) {
> + if (!s->fat_type) {
> + s->sectors_per_cluster = 2;
> + } else {
> + s->sectors_per_cluster = 1;
> + }
> + } else if (s->fat_type == 12) {
> + s->offset_to_bootsector = 0x3f;
> + s->sectors_per_cluster = 0x10;
> + } else {
> + s->offset_to_bootsector = 0x3f;
> + /* LATER TODO: if FAT32, adjust */
> + s->sectors_per_cluster = 0x80;
> + }
> +
> + cluster = s->sectors_per_cluster * 0x200;
> + sum += find_size(dirname, cluster);
> + /* TODO: if there are more entries, bootsector has to be adjusted! */
> + s->root_entries = 0x02 * 0x10 * s->sectors_per_cluster;
> + /*File size + boot sector size + root directory size*/
> + sum += 512 + s->root_entries * 32;
>
> memset(s->volume_label, ' ', sizeof(s->volume_label));
> label = qemu_opt_get(opts, "label");
> @@ -1201,24 +1262,41 @@ static int vvfat_open(BlockDriverState *bs, QDict
> *options, int flags,
> if (!s->fat_type) {
> s->fat_type = 12;
> secs = 36;
> - s->sectors_per_cluster = 2;
> } else {
> secs = s->fat_type == 12 ? 18 : 36;
> - s->sectors_per_cluster = 1;
> }
> cyls = 80;
> heads = 2;
> } else {
> - /* 32MB or 504MB disk*/
> if (!s->fat_type) {
> s->fat_type = 16;
> }
> - s->offset_to_bootsector = 0x3f;
> + size_disk = 528482304;
> cyls = s->fat_type == 12 ? 64 : 1024;
> heads = 16;
> secs = 63;
> - }
> + if (!check_size(s->offset_to_bootsector, cyls, heads,
> + secs, s->sectors_per_cluster,
> + s->fat_type, sum, size_disk)) {
> + if (s->fat_type > 12) {
> + size_disk = 4294950912;
> + cyls = 8322;
> + heads = 16;
> + secs = 63;
>
> + } else {
> + fprintf(stderr, "Requires Fat16 or Fat32\n");
> + return -2;
> + }
> + if (!check_size(s->offset_to_bootsector, cyls, heads,
> + secs, s->sectors_per_cluster,
> + s->fat_type, sum, size_disk)) {
> + fprintf(stderr, "Folder is larger than %f GB\n",
> + (float)size_disk / 1073741824);
> + return -2;
> + }
> + }
> + }
> switch (s->fat_type) {
> case 32:
> warn_report("FAT32 has not been tested. You are welcome to do
> so!");
> @@ -1235,8 +1313,6 @@ static int vvfat_open(BlockDriverState *bs, QDict
> *options, int flags,
>
> s->bs = bs;
>
> - /* LATER TODO: if FAT32, adjust */
> - s->sectors_per_cluster=0x10;
>
> s->current_cluster=0xffffffff;
>
> --
> 2.7.4
>
>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [PATCH V2] block: increased maximum size of vvfat devices
2018-09-11 17:20 ` аркадий иванов
@ 2021-03-13 14:06 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 4+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-03-13 14:06 UTC (permalink / raw)
To: аркадий иванов
Cc: Kevin Wolf, qemu-devel@nongnu.org Developers, Pavel Dovgalyuk,
Max Reitz
On Tue, Sep 11, 2018 at 7:22 PM аркадий иванов <ivanovrkasha@gmail.com> wrote:
>
> Ping?
I'm afraid your patch has fallen through the cracks... Can you rebase
and repost?
>
> Thu, 23 Aug. 2018 at 16:37, Arkasha <ivanovrkasha@gmail.com>:
>
> > This fixes the problem of the impossibility to create
> > FAT16 disks larger than 504 mb:
> > The change CHS made it possible to obtain a larger disk.
> > Also, auto-detection of disk parameters was added depending
> > on the volume of the connected files:
> > The size of all folders and files on the created disk is calculated
> > and the size of the FAT table is added.
> > This size allows to choose the future size of the FAT drive
> > from the standard limitations.
> >
> > Signed-off-by: Arkasha <ivanovrkasha@gmail.com>
> > ---
> > block/vvfat.c | 96
> > ++++++++++++++++++++++++++++++++++++++++++++++++++++-------
> > 1 file changed, 86 insertions(+), 10 deletions(-)
> >
> > diff --git a/block/vvfat.c b/block/vvfat.c
> > index fc41841..4409233 100644
> > --- a/block/vvfat.c
> > +++ b/block/vvfat.c
> > @@ -77,6 +77,47 @@ static void checkpoint(void);
> > #define DIR_KANJI_FAKE 0x05
> > #define DIR_FREE 0x00
> >
> > +static bool check_size(uint32_t offset_to_bootsector, int cyls, int heads,
> > + int secs, uint8_t sectors_per_cluster, int fat_type,
> > + long int sum, long int size_disk)
> > +{
> > + uint32_t sector_count = cyls * heads * secs - offset_to_bootsector;
> > + int i = 1 + sectors_per_cluster * 0x200 * 8 / fat_type;
> > + uint16_t sectors_per_fat = (sector_count + i) / i;
> > + /*size + FAT1 and FAT2 table size*/
> > + if ((sum + sectors_per_fat * 512 * 2) < size_disk) {
> > + return true;
> > + }
> > + return false;
> > +}
> > +
> > +static long int find_size(const char *dirname, unsigned int cluster)
> > +{
> > + long int sum = 0;
> > + DIR *dir = opendir(dirname);
> > + struct dirent *entry;
> > + while ((entry = readdir(dir))) {
> > + unsigned int length = strlen(dirname) + 2 + strlen(entry->d_name);
> > + char *buffer;
> > + struct stat st;
> > + buffer = g_malloc(length);
> > + snprintf(buffer, length, "%s/%s", dirname, entry->d_name);
> > + if (stat(buffer, &st) < 0) {
> > + g_free(buffer);
> > + continue;
> > + }
> > + if (strcmp(entry->d_name, ".") && strcmp(entry->d_name, "..")
> > + && S_ISDIR(st.st_mode)) {
> > + sum += find_size(buffer, cluster);
> > + }
> > + g_free(buffer);
> > + sum += (st.st_size + cluster - 1) / (cluster) * (cluster);
> > + }
> > + closedir(dir);
> > + return sum;
> > +}
> > +
> > +
> > /* dynamic array functions */
> > typedef struct array_t {
> > char* pointer;
> > @@ -948,8 +988,6 @@ 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));
> > @@ -1154,12 +1192,12 @@ static int vvfat_open(BlockDriverState *bs, QDict
> > *options, int flags,
> > {
> > BDRVVVFATState *s = bs->opaque;
> > int cyls, heads, secs;
> > + long int size_disk;
> > bool floppy;
> > const char *dirname, *label;
> > QemuOpts *opts;
> > Error *local_err = NULL;
> > int ret;
> > -
> > #ifdef DEBUG
> > vvv = s;
> > #endif
> > @@ -1181,6 +1219,29 @@ static int vvfat_open(BlockDriverState *bs, QDict
> > *options, int flags,
> >
> > s->fat_type = qemu_opt_get_number(opts, "fat-type", 0);
> > floppy = qemu_opt_get_bool(opts, "floppy", false);
> > + unsigned int cluster;
> > + long int sum = 0;
> > + if (floppy) {
> > + if (!s->fat_type) {
> > + s->sectors_per_cluster = 2;
> > + } else {
> > + s->sectors_per_cluster = 1;
> > + }
> > + } else if (s->fat_type == 12) {
> > + s->offset_to_bootsector = 0x3f;
> > + s->sectors_per_cluster = 0x10;
> > + } else {
> > + s->offset_to_bootsector = 0x3f;
> > + /* LATER TODO: if FAT32, adjust */
> > + s->sectors_per_cluster = 0x80;
> > + }
> > +
> > + cluster = s->sectors_per_cluster * 0x200;
> > + sum += find_size(dirname, cluster);
> > + /* TODO: if there are more entries, bootsector has to be adjusted! */
> > + s->root_entries = 0x02 * 0x10 * s->sectors_per_cluster;
> > + /*File size + boot sector size + root directory size*/
> > + sum += 512 + s->root_entries * 32;
> >
> > memset(s->volume_label, ' ', sizeof(s->volume_label));
> > label = qemu_opt_get(opts, "label");
> > @@ -1201,24 +1262,41 @@ static int vvfat_open(BlockDriverState *bs, QDict
> > *options, int flags,
> > if (!s->fat_type) {
> > s->fat_type = 12;
> > secs = 36;
> > - s->sectors_per_cluster = 2;
> > } else {
> > secs = s->fat_type == 12 ? 18 : 36;
> > - s->sectors_per_cluster = 1;
> > }
> > cyls = 80;
> > heads = 2;
> > } else {
> > - /* 32MB or 504MB disk*/
> > if (!s->fat_type) {
> > s->fat_type = 16;
> > }
> > - s->offset_to_bootsector = 0x3f;
> > + size_disk = 528482304;
> > cyls = s->fat_type == 12 ? 64 : 1024;
> > heads = 16;
> > secs = 63;
> > - }
> > + if (!check_size(s->offset_to_bootsector, cyls, heads,
> > + secs, s->sectors_per_cluster,
> > + s->fat_type, sum, size_disk)) {
> > + if (s->fat_type > 12) {
> > + size_disk = 4294950912;
> > + cyls = 8322;
> > + heads = 16;
> > + secs = 63;
> >
> > + } else {
> > + fprintf(stderr, "Requires Fat16 or Fat32\n");
> > + return -2;
> > + }
> > + if (!check_size(s->offset_to_bootsector, cyls, heads,
> > + secs, s->sectors_per_cluster,
> > + s->fat_type, sum, size_disk)) {
> > + fprintf(stderr, "Folder is larger than %f GB\n",
> > + (float)size_disk / 1073741824);
> > + return -2;
> > + }
> > + }
> > + }
> > switch (s->fat_type) {
> > case 32:
> > warn_report("FAT32 has not been tested. You are welcome to do
> > so!");
> > @@ -1235,8 +1313,6 @@ static int vvfat_open(BlockDriverState *bs, QDict
> > *options, int flags,
> >
> > s->bs = bs;
> >
> > - /* LATER TODO: if FAT32, adjust */
> > - s->sectors_per_cluster=0x10;
> >
> > s->current_cluster=0xffffffff;
> >
> > --
> > 2.7.4
> >
> >
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2021-03-13 14:07 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-08-23 13:37 [Qemu-devel] [PATCH V2] block: increased maximum size of vvfat devices Arkasha
2018-08-31 9:34 ` Pavel Dovgalyuk
2018-09-11 17:20 ` аркадий иванов
2021-03-13 14:06 ` Philippe Mathieu-Daudé
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).