[U-Boot] [PATCH] fat32 root directory handling

Remy Bohmer linux at bohmer.net
Fri Mar 25 20:25:22 CET 2011


Hi Wolfgang,

2011/3/24 Erik Hansen <erik at makarta.com>:
> Fat directory handling didn't check reaching the end of the root directory. It
> relied on a stop condition based on a directory entry with a name starting with
> a '\0' character. This check in itself is wrong ('\0' indicates free entry, not
> end_of_directory) but outside the scope of this fix. For FAT32, the end of the
> rootdir is reached when the end of the cluster chain is reached. The code didn't
> check this condition and started to read an incorrect cluster. This caused a
> subsequent read request of a sector outside the range of the usb stick in
> use. On its turn, the usb stick protested with a stall handshake.
>
> Both FAT32 and non-FAT32 (FAT16/FAT12) end or rootdir checks have been put in.
>
> Signed-off-by: Erik Hansen <erik at makarta.com>
> ---
>  fs/fat/fat.c |   38 ++++++++++++++++++++++++--------------
>  1 files changed, 24 insertions(+), 14 deletions(-)
>
> diff --git a/fs/fat/fat.c b/fs/fat/fat.c
> index a75e4f2..2a3414f 100644
> --- a/fs/fat/fat.c
> +++ b/fs/fat/fat.c
> @@ -31,6 +31,7 @@
>  #include <asm/byteorder.h>
>  #include <part.h>
>
> +
>  /*
>  * Convert a string to lowercase.
>  */

Any objections if I pull this patch in the U-boot USB tree after
fixing this whitespace issue?
At least here here my Ack for the remainder of this patch

Acked-by: Remy Bohmer <linux at bohmer.net>

Kind regards,

Remy

> @@ -209,7 +210,7 @@ static __u32 get_fatent (fsdata *mydata, __u32 entry)
>
>        /* Read a new block of FAT entries into the cache. */
>        if (bufnum != mydata->fatbufnum) {
> -               int getsize = FATBUFSIZE / FS_BLOCK_SIZE;
> +               __u32 getsize = FATBUFSIZE / FS_BLOCK_SIZE;
>                __u8 *bufptr = mydata->fatbuf;
>                __u32 fatlength = mydata->fatlength;
>                __u32 startblock = bufnum * FATBUFBLOCKS;
> @@ -279,7 +280,7 @@ static int
>  get_cluster (fsdata *mydata, __u32 clustnum, __u8 *buffer,
>             unsigned long size)
>  {
> -       int idx = 0;
> +       __u32 idx = 0;
>        __u32 startsect;
>
>        if (clustnum > 0) {
> @@ -767,12 +768,13 @@ do_fat_read (const char *filename, void *buffer, unsigned long maxsize,
>        dir_entry *dentptr;
>        __u16 prevcksum = 0xffff;
>        char *subname = "";
> -       int cursect;
> +       __u32 cursect;
>        int idx, isdir = 0;
>        int files = 0, dirs = 0;
>        long ret = 0;
>        int firsttime;
> -       int root_cluster;
> +       __u32 root_cluster;
> +       int rootdir_size = 0;
>        int j;
>
>        if (read_bootsectandvi(&bs, &volinfo, &mydata->fatsize)) {
> @@ -798,8 +800,6 @@ do_fat_read (const char *filename, void *buffer, unsigned long maxsize,
>                mydata->data_begin = mydata->rootdir_sect -
>                                        (mydata->clust_size * 2);
>        } else {
> -               int rootdir_size;
> -
>                rootdir_size = ((bs.dir_entries[1]  * (int)256 +
>                                 bs.dir_entries[0]) *
>                                 sizeof(dir_entry)) /
> @@ -1006,20 +1006,18 @@ do_fat_read (const char *filename, void *buffer, unsigned long maxsize,
>                 * root directory clusters when a cluster has been
>                 * completely processed.
>                 */
> -               if ((mydata->fatsize == 32) && (++j == mydata->clust_size)) {
> -                       int nxtsect;
> -                       int nxt_clust;
> +               ++j;
> +               int fat32_end = 0;
> +               if ((mydata->fatsize == 32) && (j == mydata->clust_size)) {
> +                       int nxtsect = 0;
> +                       int nxt_clust = 0;
>
>                        nxt_clust = get_fatent(mydata, root_cluster);
> +                       fat32_end = CHECK_CLUST(nxt_clust, 32);
>
>                        nxtsect = mydata->data_begin +
>                                (nxt_clust * mydata->clust_size);
>
> -                       debug("END LOOP: sect=%d, root_clust=%d, "
> -                             "n_sect=%d, n_clust=%d\n",
> -                             cursect, root_cluster,
> -                             nxtsect, nxt_clust);
> -
>                        root_cluster = nxt_clust;
>
>                        cursect = nxtsect;
> @@ -1027,6 +1025,18 @@ do_fat_read (const char *filename, void *buffer, unsigned long maxsize,
>                } else {
>                        cursect++;
>                }
> +
> +               /* If end of rootdir reached */
> +               if ((mydata->fatsize == 32 && fat32_end) ||
> +                   (mydata->fatsize != 32 && j == rootdir_size)) {
> +                       if (dols == LS_ROOT) {
> +                               printf("\n%d file(s), %d dir(s)\n\n",
> +                                      files, dirs);
> +                               return 0;
> +                       } else {
> +                               return -1;
> +                       }
> +               }
>        }
>  rootdir_done:
>
> --
> 1.7.0.4
>
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
>


More information about the U-Boot mailing list