From 4dd083e8c2f06f7a06b3ed782cfb16ae84c76960 Mon Sep 17 00:00:00 2001 From: batt Date: Sat, 3 Jul 2010 13:34:52 +0000 Subject: [PATCH] Use new cache accessors to increase performances. A common pattern is to write on a file one byte at a time. Since consecutive writes are mostly on the same block, BattFS would allocate a new block each time to avoid burning the sector. This is very inefficient, and since we have a cache, we can avoid re-writing the block by using it. This patch does not rewrite a block if it is cached, and use the cache efficiently. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@3994 38d2e660-2303-0410-9eaa-f027e97ec537 --- bertos/fs/battfs.c | 58 +++++++++++++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 19 deletions(-) diff --git a/bertos/fs/battfs.c b/bertos/fs/battfs.c index 35f348f0..4877fc62 100644 --- a/bertos/fs/battfs.c +++ b/bertos/fs/battfs.c @@ -366,6 +366,7 @@ bool battfs_mount(struct BattFsSuper *disk, struct KBlock *dev, pgcnt_t *page_ar pgoff_t filelen_table[BATTFS_MAX_FILES]; ASSERT(dev); + ASSERT(kblock_buffered(dev)); disk->dev = dev; ASSERT(disk->dev->blk_size > BATTFS_HEADER_LEN); @@ -582,22 +583,32 @@ static size_t battfs_write(struct KFile *fd, const void *_buf, size_t size) if (fd->seek_pos > fd->size) { - // TODO: renew this last page only if needed if (!readHdr(disk, fdb->start[fdb->max_off], &curr_hdr)) { fdb->errors |= BATTFS_DISK_READ_ERR; return total_write; } - new_page = renewPage(disk, fdb->start[fdb->max_off]); - if (new_page == NO_SPACE) + /* + * Renew page only if is not in cache. + * This avoids rewriting the same page continuously + * if the user code keeps writing in the same portion + * of the file. + */ + if ((fdb->start[fdb->max_off] != kblock_cachedBlock(disk->dev)) || !kblock_cacheDirty(disk->dev)) { - fdb->errors |= BATTFS_DISK_SPACEOVER_ERR; - return total_write; - } + new_page = renewPage(disk, fdb->start[fdb->max_off]); + if (new_page == NO_SPACE) + { + fdb->errors |= BATTFS_DISK_SPACEOVER_ERR; + return total_write; + } - kblock_copy(disk->dev, fdb->start[fdb->max_off], new_page); - fdb->start[fdb->max_off] = new_page; + kblock_copy(disk->dev, fdb->start[fdb->max_off], new_page); + fdb->start[fdb->max_off] = new_page; + } + else + new_page = fdb->start[fdb->max_off]; /* Fill unused space of first page with 0s */ uint8_t dummy = 0; @@ -691,27 +702,36 @@ static size_t battfs_write(struct KFile *fd, const void *_buf, size_t size) } else { - // TODO: do not renew page if its cached if (!readHdr(disk, fdb->start[pg_offset], &curr_hdr)) { fdb->errors |= BATTFS_DISK_READ_ERR; return total_write; } - new_page = renewPage(disk, fdb->start[pg_offset]); - if (new_page == NO_SPACE) + /* Renew page only if is not in cache. */ + if ((fdb->start[fdb->max_off] != kblock_cachedBlock(disk->dev)) || !kblock_cacheDirty(disk->dev)) { - fdb->errors |= BATTFS_DISK_SPACEOVER_ERR; - return total_write; - } + new_page = renewPage(disk, fdb->start[pg_offset]); + if (new_page == NO_SPACE) + { + fdb->errors |= BATTFS_DISK_SPACEOVER_ERR; + return total_write; + } - LOG_INFO("Re-writing page %d to %d\n", fdb->start[pg_offset], new_page); - if (kblock_copy(disk->dev, fdb->start[pg_offset], new_page) != 0) + LOG_INFO("Re-writing page %d to %d\n", fdb->start[pg_offset], new_page); + if (kblock_copy(disk->dev, fdb->start[pg_offset], new_page) != 0) + { + fdb->errors |= BATTFS_DISK_WRITE_ERR; + return total_write; + } + fdb->start[pg_offset] = new_page; + } + else { - fdb->errors |= BATTFS_DISK_WRITE_ERR; - return total_write; + LOG_INFO("Using cached block %d\n", fdb->start[pg_offset]); + new_page = fdb->start[pg_offset]; } - fdb->start[pg_offset] = new_page; + curr_hdr.seq++; } //LOG_INFO("writing to buffer for page %d, offset %d, size %d\n", disk->curr_page, addr_offset, wr_len); -- 2.25.1