[U-Boot] [PATCH 2/4] fs/fat: Do not write unmodified fat entries to disk
Lukasz Majewski
l.majewski at samsung.com
Mon Sep 12 12:56:54 CEST 2016
Hi Stefan,
> The code caches 6 sectors of the FAT. On FAT traversal, the old
> contents needs to be flushed to disk, but only if any FAT entries had
> been modified. Explicitly flag the buffer on modification.
>
> Currently, creating a new file traverses the whole FAT up to the first
> free cluster and rewrites the on-disk blocks.
>
> Signed-off-by: Stefan Brüns <stefan.bruens at rwth-aachen.de>
> ---
> fs/fat/fat.c | 1 +
> fs/fat/fat_write.c | 31 +++++++++++++++++++------------
> include/fat.h | 1 +
> 3 files changed, 21 insertions(+), 12 deletions(-)
>
> diff --git a/fs/fat/fat.c b/fs/fat/fat.c
> index 826bd85..df9f2b5 100644
> --- a/fs/fat/fat.c
> +++ b/fs/fat/fat.c
> @@ -876,6 +876,7 @@ int do_fat_read_at(const char *filename, loff_t
> pos, void *buffer, }
>
> mydata->fatbufnum = -1;
> + mydata->fat_dirty = 0;
> mydata->fatbuf = memalign(ARCH_DMA_MINALIGN, FATBUFSIZE);
> if (mydata->fatbuf == NULL) {
> debug("Error: allocating memory\n");
> diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c
> index 961ccd8..babe9c8 100644
> --- a/fs/fat/fat_write.c
> +++ b/fs/fat/fat_write.c
> @@ -104,13 +104,19 @@ static __u8 num_of_fats;
> /*
> * Write fat buffer into block device
> */
> -static int flush_fat_buffer(fsdata *mydata)
> +static int flush_dirty_fat_buffer(fsdata *mydata)
> {
> int getsize = FATBUFBLOCKS;
> __u32 fatlength = mydata->fatlength;
> __u8 *bufptr = mydata->fatbuf;
> __u32 startblock = mydata->fatbufnum * FATBUFBLOCKS;
>
> + debug("debug: evicting %d, dirty: %d\n", mydata->fatbufnum,
> + (int)mydata->fat_dirty);
> +
> + if ((!mydata->fat_dirty) || (mydata->fatbufnum == -1))
> + return 0;
> +
> startblock += mydata->fat_sect;
>
> if (getsize > fatlength)
> @@ -130,6 +136,7 @@ static int flush_fat_buffer(fsdata *mydata)
> return -1;
> }
> }
> + mydata->fat_dirty = 0;
>
> return 0;
> }
> @@ -186,10 +193,8 @@ static __u32 get_fatent_value(fsdata *mydata,
> __u32 entry) startblock += mydata->fat_sect; /* Offset from
> start of disk */
> /* Write back the fatbuf to the disk */
> - if (mydata->fatbufnum != -1) {
> - if (flush_fat_buffer(mydata) < 0)
> - return -1;
> - }
> + if (flush_dirty_fat_buffer(mydata) < 0)
> + return -1;
>
> if (disk_read(startblock, getsize, bufptr) < 0) {
> debug("Error reading FAT blocks\n");
> @@ -494,10 +499,8 @@ static int set_fatent_value(fsdata *mydata,
> __u32 entry, __u32 entry_value) if (getsize > fatlength)
> getsize = fatlength;
>
> - if (mydata->fatbufnum != -1) {
> - if (flush_fat_buffer(mydata) < 0)
> - return -1;
> - }
> + if (flush_dirty_fat_buffer(mydata) < 0)
> + return -1;
>
> if (disk_read(startblock, getsize, bufptr) < 0) {
> debug("Error reading FAT blocks\n");
> @@ -506,6 +509,9 @@ static int set_fatent_value(fsdata *mydata, __u32
> entry, __u32 entry_value) mydata->fatbufnum = bufnum;
> }
>
> + /* Mark as dirty */
> + mydata->fat_dirty = 1;
> +
> /* Set the actual entry */
> switch (mydata->fatsize) {
> case 32:
> @@ -645,7 +651,7 @@ static void flush_dir_table(fsdata *mydata,
> dir_entry **dentptr)
> dir_curclust = dir_newclust;
>
> - if (flush_fat_buffer(mydata) < 0)
> + if (flush_dirty_fat_buffer(mydata) < 0)
> return;
>
> memset(get_dentfromdir_block, 0x00,
> @@ -675,7 +681,7 @@ static int clear_fatent(fsdata *mydata, __u32
> entry) }
>
> /* Flush fat buffer */
> - if (flush_fat_buffer(mydata) < 0)
> + if (flush_dirty_fat_buffer(mydata) < 0)
> return -1;
>
> return 0;
> @@ -1011,6 +1017,7 @@ static int do_fat_write(const char *filename,
> void *buffer, loff_t size, }
>
> mydata->fatbufnum = -1;
> + mydata->fat_dirty = 0;
> mydata->fatbuf = memalign(ARCH_DMA_MINALIGN, FATBUFSIZE);
> if (mydata->fatbuf == NULL) {
> debug("Error: allocating memory\n");
> @@ -1111,7 +1118,7 @@ static int do_fat_write(const char *filename,
> void *buffer, loff_t size, debug("attempt to write 0x%llx bytes\n",
> *actwrite);
> /* Flush fat buffer */
> - ret = flush_fat_buffer(mydata);
> + ret = flush_dirty_fat_buffer(mydata);
> if (ret) {
> printf("Error: flush fat buffer\n");
> goto exit;
> diff --git a/include/fat.h b/include/fat.h
> index 9d053e6..8ec91cd 100644
> --- a/include/fat.h
> +++ b/include/fat.h
> @@ -169,6 +169,7 @@ typedef struct {
> int fatsize; /* Size of FAT in bits */
> __u32 fatlength; /* Length of FAT in sectors */
> __u16 fat_sect; /* Starting sector of the FAT
> */
> + __u8 fat_dirty; /* Set if fatbuf has been
> modified */ __u32 rootdir_sect; /* Start sector of root
> directory */ __u16 sect_size; /* Size of sectors in
> bytes */ __u16 clust_size; /* Size of clusters in
> sectors */
Reviewed-by: Lukasz Majewski <l.majewski at samsung.com>
--
Best regards,
Lukasz Majewski
Samsung R&D Institute Poland (SRPOL) | Linux Platform Group
More information about the U-Boot
mailing list