[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