From mboxrd@z Thu Jan 1 00:00:00 1970 From: Heinrich Schuchardt Date: Tue, 14 May 2019 19:26:58 +0200 Subject: [U-Boot] [PATCH 1/4] fs: fat: write to non-cluster-aligned root directory In-Reply-To: <20190513054927.17890-2-takahiro.akashi@linaro.org> References: <20190513054927.17890-1-takahiro.akashi@linaro.org> <20190513054927.17890-2-takahiro.akashi@linaro.org> Message-ID: List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de 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 > Cc: Anssi Hannula 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 > 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"); > >