[U-Boot] [PATCH 1/4] fs: fat: write to non-cluster-aligned root directory
Heinrich Schuchardt
xypron.glpk at gmx.de
Tue May 14 17:26:58 UTC 2019
On 5/13/19 7:49 AM, AKASHI Takahiro wrote:
> With the commit below, fat now correctly handles a file read under
> a non-cluster-aligned root directory of fat12/16.
> Write operation should be fixed in the same manner.
>
> Fixes: commit 9b18358dc05d ("fs: fat: fix reading non-cluster-aligned
> root directory")
> Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
> Cc: Anssi Hannula <anssi.hannula at bitwise.fi>
Thanks a lot for addressing this.
> ---
> fs/fat/fat.c | 15 ++++-----
> fs/fat/fat_write.c | 78 +++++++++++++++++++++++++++++++---------------
> 2 files changed, 61 insertions(+), 32 deletions(-)
>
> diff --git a/fs/fat/fat.c b/fs/fat/fat.c
> index c5997c21735f..fccaa385d187 100644
> --- a/fs/fat/fat.c
> +++ b/fs/fat/fat.c
> @@ -619,13 +619,14 @@ static int get_fs_info(fsdata *mydata)
> return -1;
> }
>
> - debug("FAT%d, fat_sect: %d, fatlength: %d\n",
> - mydata->fatsize, mydata->fat_sect, mydata->fatlength);
> - debug("Rootdir begins at cluster: %d, sector: %d, offset: %x\n"
> - "Data begins at: %d\n",
> - mydata->root_cluster,
> - mydata->rootdir_sect,
> - mydata->rootdir_sect * mydata->sect_size, mydata->data_begin);
> + debug("FAT%d, fat_sect: %d, fatlength: %d, num: %d\n",
> + mydata->fatsize, mydata->fat_sect, mydata->fatlength,
> + mydata->fats);
> + debug("Rootdir begins at cluster: %d, sector: %d, size: %x\n"
> + "Data begins at: %d\n",
> + mydata->root_cluster,
> + mydata->rootdir_sect,
> + mydata->rootdir_size * mydata->sect_size, mydata->data_begin);
This seems to be an unrelated change. It should be either in a separate
patch or the commit message should explain why it is related.
Tested-by: Heinrich Schuchardt <xypron.glpk at gmx.de>
> debug("Sector size: %d, cluster size: %d\n", mydata->sect_size,
> mydata->clust_size);
>
> diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c
> index 852f874e5817..3bc0dd637521 100644
> --- a/fs/fat/fat_write.c
> +++ b/fs/fat/fat_write.c
> @@ -388,29 +388,23 @@ static __u32 determine_fatent(fsdata *mydata, __u32 entry)
> }
>
> /**
> - * set_cluster() - write data to cluster
> + * set_sectors() - write data to sectors
> *
> - * Write 'size' bytes from 'buffer' into the specified cluster.
> + * Write 'size' bytes from 'buffer' into the specified sector.
> *
> * @mydata: data to be written
> - * @clustnum: cluster to be written to
> + * @startsect: sector to be written to
> * @buffer: data to be written
> * @size: bytes to be written (but not more than the size of a cluster)
> * Return: 0 on success, -1 otherwise
> */
> static int
> -set_cluster(fsdata *mydata, u32 clustnum, u8 *buffer, u32 size)
> +set_sectors(fsdata *mydata, u32 startsect, u8 *buffer, u32 size)
> {
> - u32 idx = 0;
> - u32 startsect;
> + u32 nsects = 0;
> int ret;
>
> - if (clustnum > 0)
> - startsect = clust_to_sect(mydata, clustnum);
> - else
> - startsect = mydata->rootdir_sect;
> -
> - debug("clustnum: %d, startsect: %d\n", clustnum, startsect);
> + debug("startsect: %d\n", startsect);
>
> if ((unsigned long)buffer & (ARCH_DMA_MINALIGN - 1)) {
> ALLOC_CACHE_ALIGN_BUFFER(__u8, tmpbuf, mydata->sect_size);
> @@ -429,17 +423,16 @@ set_cluster(fsdata *mydata, u32 clustnum, u8 *buffer, u32 size)
> size -= mydata->sect_size;
> }
> } else if (size >= mydata->sect_size) {
> - idx = size / mydata->sect_size;
> - ret = disk_write(startsect, idx, buffer);
> - if (ret != idx) {
> + nsects = size / mydata->sect_size;
> + ret = disk_write(startsect, nsects, buffer);
> + if (ret != nsects) {
> debug("Error writing data (got %d)\n", ret);
> return -1;
> }
>
> - startsect += idx;
> - idx *= mydata->sect_size;
> - buffer += idx;
> - size -= idx;
> + startsect += nsects;
> + buffer += nsects * mydata->sect_size;
> + size -= nsects * mydata->sect_size;
> }
>
> if (size) {
> @@ -457,6 +450,44 @@ set_cluster(fsdata *mydata, u32 clustnum, u8 *buffer, u32 size)
> return 0;
> }
>
> +/**
> + * set_cluster() - write data to cluster
> + *
> + * Write 'size' bytes from 'buffer' into the specified cluster.
> + *
> + * @mydata: data to be written
> + * @clustnum: cluster to be written to
> + * @buffer: data to be written
> + * @size: bytes to be written (but not more than the size of a cluster)
> + * Return: 0 on success, -1 otherwise
> + */
> +static int
> +set_cluster(fsdata *mydata, u32 clustnum, u8 *buffer, u32 size)
> +{
> + return set_sectors(mydata, clust_to_sect(mydata, clustnum),
> + buffer, size);
> +}
> +
> +static int
> +flush_dir(fat_itr *itr)
> +{
> + fsdata *mydata = itr->fsdata;
> + u32 startsect, sect_offset, nsects;
> +
> + if (!itr->is_root || mydata->fatsize == 32)
> + return set_cluster(mydata, itr->clust, itr->block,
> + mydata->clust_size * mydata->sect_size);
> +
> + sect_offset = itr->clust * mydata->clust_size;
> + startsect = mydata->rootdir_sect + sect_offset;
> + /* do not write past the end of rootdir */
> + nsects = min_t(u32, mydata->clust_size,
> + mydata->rootdir_size - sect_offset);
> +
> + return set_sectors(mydata, startsect, itr->block,
> + nsects * mydata->sect_size);
> +}
> +
> static __u8 tmpbuf_cluster[MAX_CLUSTSIZE] __aligned(ARCH_DMA_MINALIGN);
>
> /*
> @@ -1171,8 +1202,7 @@ int file_fat_write_at(const char *filename, loff_t pos, void *buffer,
> }
>
> /* Write directory table to device */
> - ret = set_cluster(mydata, itr->clust, itr->block,
> - mydata->clust_size * mydata->sect_size);
> + ret = flush_dir(itr);
> if (ret) {
> printf("Error: writing directory entry\n");
> ret = -EIO;
> @@ -1249,8 +1279,7 @@ static int delete_dentry(fat_itr *itr)
> memset(dentptr, 0, sizeof(*dentptr));
> dentptr->name[0] = 0xe5;
>
> - if (set_cluster(mydata, itr->clust, itr->block,
> - mydata->clust_size * mydata->sect_size) != 0) {
> + if (flush_dir(itr)) {
> printf("error: writing directory entry\n");
> return -EIO;
> }
> @@ -1452,8 +1481,7 @@ int fat_mkdir(const char *new_dirname)
> }
>
> /* Write directory table to device */
> - ret = set_cluster(mydata, itr->clust, itr->block,
> - mydata->clust_size * mydata->sect_size);
> + ret = flush_dir(itr);
> if (ret)
> printf("Error: writing directory entry\n");
>
>
More information about the U-Boot
mailing list