From mboxrd@z Thu Jan 1 00:00:00 1970 From: Lukasz Majewski Date: Mon, 12 Sep 2016 12:56:54 +0200 Subject: [U-Boot] [PATCH 2/4] fs/fat: Do not write unmodified fat entries to disk In-Reply-To: References: <20160911205142.4259-1-stefan.bruens@rwth-aachen.de> Message-ID: <20160912125654.22a0a0b1@amdc2363> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de 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 > --- > 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 -- Best regards, Lukasz Majewski Samsung R&D Institute Poland (SRPOL) | Linux Platform Group