qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH V2] block: increased maximum size of vvfat devic


From: Philippe Mathieu-Daudé
Subject: Re: [Qemu-devel] [PATCH V2] block: increased maximum size of vvfat devices
Date: Sat, 13 Mar 2021 15:06:07 +0100

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
> >
> >



reply via email to

[Prev in Thread] Current Thread [Next in Thread]