From 706954ecdc8313eb3dd0a23190ae9d12cd4392a3 Mon Sep 17 00:00:00 2001 From: batt Date: Thu, 1 Jul 2010 16:25:33 +0000 Subject: [PATCH] Update BattFS in order to use the new kblock interface. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@3978 38d2e660-2303-0410-9eaa-f027e97ec537 --- bertos/fs/battfs.c | 321 +++++++++++++---------------- bertos/fs/battfs.h | 91 ++------- bertos/fs/battfs_test.c | 433 +++++++++++++++++++--------------------- test/run_tests.sh | 5 +- 4 files changed, 357 insertions(+), 493 deletions(-) diff --git a/bertos/fs/battfs.c b/bertos/fs/battfs.c index deef25cc..dbed5781 100644 --- a/bertos/fs/battfs.c +++ b/bertos/fs/battfs.c @@ -128,22 +128,6 @@ static fcs_t computeFcs(struct BattFsPageHeader *hdr) return cks; } -/** - * Read from disk. - * If available, the cache will be used. - * \return the number of bytes read. - */ -static size_t diskRead(struct BattFsSuper *disk, pgcnt_t page, pgaddr_t addr, void *buf, size_t size) -{ - /* Try to read from cache */ - if (page == disk->curr_page) - return disk->bufferRead(disk, addr, buf, size); - /* Read from disk */ - else - return disk->read(disk, page, addr, buf, size); -} - - /** * Read header of \a page in \a hdr. * \return true on success, false otherwise. @@ -151,12 +135,13 @@ static size_t diskRead(struct BattFsSuper *disk, pgcnt_t page, pgaddr_t addr, vo static bool readHdr(struct BattFsSuper *disk, pgcnt_t page, struct BattFsPageHeader *hdr) { uint8_t buf[BATTFS_HEADER_LEN]; + /* * Read header from disk. * Header is actually a footer, and so * resides at page end. */ - if (diskRead(disk, page, disk->data_size, buf, BATTFS_HEADER_LEN) + if (kblock_read(disk->dev, page, buf, disk->data_size, BATTFS_HEADER_LEN) != BATTFS_HEADER_LEN) { LOG_ERR("page[%d]\n", page); @@ -169,11 +154,7 @@ static bool readHdr(struct BattFsSuper *disk, pgcnt_t page, struct BattFsPageHea return true; } -/** - * Set header on current \a disk page buffer. - * \return true on success, false otherwise. - */ -static bool setBufferHdr(struct BattFsSuper *disk, struct BattFsPageHeader *hdr) +static bool writeHdr(struct BattFsSuper *disk, pgcnt_t page, struct BattFsPageHeader *hdr) { uint8_t buf[BATTFS_HEADER_LEN]; @@ -183,11 +164,11 @@ static bool setBufferHdr(struct BattFsSuper *disk, struct BattFsPageHeader *hdr) battfs_to_disk(hdr, buf); /* - * write header to buffer. + * write header to disk. * Header is actually a footer, and so * resides at page end. */ - if (disk->bufferWrite(disk, disk->data_size, buf, BATTFS_HEADER_LEN) + if (kblock_write(disk->dev, page, buf, disk->data_size, BATTFS_HEADER_LEN) != BATTFS_HEADER_LEN) { LOG_ERR("writing to buffer\n"); @@ -196,21 +177,6 @@ static bool setBufferHdr(struct BattFsSuper *disk, struct BattFsPageHeader *hdr) return true; } -static bool getBufferHdr(struct BattFsSuper *disk, struct BattFsPageHeader *hdr) -{ - uint8_t buf[BATTFS_HEADER_LEN]; - - if (disk->bufferRead(disk, disk->data_size, buf, BATTFS_HEADER_LEN) - != BATTFS_HEADER_LEN) - { - LOG_ERR("reading from buffer\n"); - return false; - } - - disk_to_battfs(buf, hdr); - - return true; -} /** * Count the number of pages from @@ -391,83 +357,34 @@ static bool fillPageArray(struct BattFsSuper *disk, pgoff_t *filelen_table) } -/** - * Flush the current \a disk buffer. - * \return true if ok, false on errors. - */ -static bool flushBuffer(struct BattFsSuper *disk) -{ - if (disk->cache_dirty) - { - LOG_INFO("Flushing to disk page %d\n", disk->curr_page); - - if (!(disk->erase(disk, disk->curr_page) - && disk->save(disk, disk->curr_page))) - return false; - - disk->cache_dirty = false; - } - return true; -} - -/** - * Load \a new_page from \a disk in disk page buffer. - * If a previuos page is still dirty in the buffer, will be - * flushed first. The new page header loaded will be put in \a new_hdr. - * \return true if ok, false on errors. - */ -static bool loadPage(struct BattFsSuper *disk, pgcnt_t new_page, BattFsPageHeader *new_hdr) -{ - if (disk->curr_page == new_page) - return getBufferHdr(disk, new_hdr); - - LOG_INFO("Loading page %d\n", new_page); - - if (!(flushBuffer(disk) - && disk->load(disk, new_page) - && getBufferHdr(disk, new_hdr))) - return false; - - disk->curr_page = new_page; - - return true; -} - - /** * Initialize and mount disk described by * \a disk. * \return false on errors, true otherwise. */ -bool battfs_mount(struct BattFsSuper *disk) +bool battfs_mount(struct BattFsSuper *disk, struct KBlock *dev, pgcnt_t *page_array, size_t array_size) { pgoff_t filelen_table[BATTFS_MAX_FILES]; - /* Disk open must set all of these */ - ASSERT(disk->read); - ASSERT(disk->load); - ASSERT(disk->bufferWrite); - ASSERT(disk->bufferRead); - ASSERT(disk->save); - ASSERT(disk->erase); - ASSERT(disk->close); + ASSERT(dev); + disk->dev = dev; + disk->page_size = dev->blk_size; + disk->page_count = dev->blk_cnt; + ASSERT(disk->page_size > BATTFS_HEADER_LEN); /* Fill page_size with the usable space */ disk->data_size = disk->page_size - BATTFS_HEADER_LEN; ASSERT(disk->page_count); ASSERT(disk->page_count < PAGE_UNSET_SENTINEL - 1); - ASSERT(disk->page_array); + ASSERT(page_array); + disk->page_array = page_array; + ASSERT(array_size >= disk->page_count * sizeof(pgcnt_t)); memset(filelen_table, 0, BATTFS_MAX_FILES * sizeof(pgoff_t)); disk->free_bytes = 0; disk->disk_size = (disk_size_t)disk->data_size * disk->page_count; - /* Initialize page buffer cache */ - disk->cache_dirty = false; - disk->curr_page = 0; - disk->load(disk, disk->curr_page); - /* Count pages per file */ if (!countDiskFilePages(disk, filelen_table)) { @@ -569,7 +486,7 @@ static int battfs_flush(struct KFile *fd) { BattFs *fdb = BATTFS_CAST(fd); - if (flushBuffer(fdb->disk)) + if (kblock_flush(fdb->disk->dev) == 0) return 0; else { @@ -595,17 +512,18 @@ static int battfs_fileclose(struct KFile *fd) return EOF; } +#define NO_SPACE PAGE_UNSET_SENTINEL -static bool getNewPage(struct BattFsSuper *disk, pgcnt_t new_pos, inode_t inode, pgoff_t pgoff, BattFsPageHeader *new_hdr) +static pgcnt_t allocateNewPage(struct BattFsSuper *disk, pgcnt_t new_pos, inode_t inode) { if (SPACE_OVER(disk)) { LOG_ERR("No disk space available!\n"); - return false; + return NO_SPACE; } - flushBuffer(disk); + LOG_INFO("Getting new page %d, pos %d\n", disk->page_array[disk->free_page_start], new_pos); - disk->curr_page = disk->page_array[disk->free_page_start++]; + pgcnt_t new_page = disk->page_array[disk->free_page_start++]; memmove(&disk->page_array[new_pos + 1], &disk->page_array[new_pos], (disk->free_page_start - new_pos - 1) * sizeof(pgcnt_t)); Node *n; @@ -620,14 +538,26 @@ static bool getNewPage(struct BattFsSuper *disk, pgcnt_t new_pos, inode_t inode, } } - disk->page_array[new_pos] = disk->curr_page; - disk->cache_dirty = true; + disk->page_array[new_pos] = new_page; + return new_page; +} + +static pgcnt_t renewPage(struct BattFsSuper *disk, pgcnt_t old_pos) +{ + if (SPACE_OVER(disk)) + { + LOG_ERR("No disk space available!\n"); + return PAGE_UNSET_SENTINEL; + } - new_hdr->inode = inode; - new_hdr->pgoff = pgoff; - new_hdr->fill = 0; - new_hdr->seq = 0; - return setBufferHdr(disk, new_hdr); + /* Get a free page */ + pgcnt_t new_page = disk->page_array[disk->free_page_start]; + movePages(disk, disk->free_page_start + 1, -1); + + /* Insert previous page in free blocks list */ + LOG_INFO("Setting page %d as free\n", old_pos); + disk->page_array[disk->page_count - 1] = old_pos; + return new_page; } /** @@ -645,6 +575,7 @@ static size_t battfs_write(struct KFile *fd, const void *_buf, size_t size) pgaddr_t addr_offset; pgaddr_t wr_len; BattFsPageHeader curr_hdr; + pgcnt_t new_page; if (fd->seek_pos < 0) { @@ -654,29 +585,42 @@ static size_t battfs_write(struct KFile *fd, const void *_buf, size_t size) if (fd->seek_pos > fd->size) { - /* Handle writing when seek pos if far over EOF */ - if (!loadPage(disk, fdb->start[fdb->max_off], &curr_hdr)) + 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) { - fdb->errors |= BATTFS_DISK_LOADPAGE_ERR; + 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; + /* Fill unused space of first page with 0s */ uint8_t dummy = 0; pgaddr_t zero_bytes = MIN(fd->seek_pos - fd->size, (kfile_off_t)(disk->data_size - curr_hdr.fill)); while (zero_bytes--) { - if (disk->bufferWrite(disk, curr_hdr.fill, &dummy, 1) != 1) + if (kblock_write(disk->dev, new_page, &dummy, curr_hdr.fill, 1) != 1) { - fdb->errors |= BATTFS_DISK_BUFFERWR_ERR; + fdb->errors |= BATTFS_DISK_WRITE_ERR; return total_write; } curr_hdr.fill++; fd->size++; disk->free_bytes--; - disk->cache_dirty = true; } - setBufferHdr(disk, &curr_hdr); + curr_hdr.seq++; + if (!writeHdr(disk, new_page, &curr_hdr)) + { + fdb->errors |= BATTFS_DISK_WRITE_ERR; + return total_write; + } /* Allocate the missing pages first. */ pgoff_t missing_pages = fd->seek_pos / disk->data_size - fdb->max_off; @@ -684,44 +628,45 @@ static size_t battfs_write(struct KFile *fd, const void *_buf, size_t size) if (missing_pages) { LOG_INFO("missing pages: %d\n", missing_pages); - flushBuffer(disk); - /* Fill page buffer with 0 to avoid filling unused pages with garbage */ - for (pgaddr_t off = 0; off < disk->data_size; off++) + while (missing_pages--) { - if (disk->bufferWrite(disk, off, &dummy, 1) != 1) + zero_bytes = MIN((kfile_off_t)disk->data_size, fd->seek_pos - fd->size); + + new_page = allocateNewPage(disk, (fdb->start - disk->page_array) + fdb->max_off + 1, fdb->inode); + if (new_page == NO_SPACE) { - fdb->errors |= BATTFS_DISK_BUFFERWR_ERR; + fdb->errors |= BATTFS_DISK_SPACEOVER_ERR; return total_write; } - } - while (missing_pages--) - { - zero_bytes = MIN((kfile_off_t)disk->data_size, fd->seek_pos - fd->size); - /* Get the new page needed */ - if (!getNewPage(disk, (fdb->start - disk->page_array) + fdb->max_off + 1, fdb->inode, fdb->max_off + 1, &curr_hdr)) + + /* Fill page buffer with 0 to avoid filling unused pages with garbage */ + for (pgaddr_t off = 0; off < disk->data_size; off++) + { + if (kblock_write(disk->dev, new_page, &dummy, off, 1) != 1) + { + fdb->errors |= BATTFS_DISK_WRITE_ERR; + return total_write; + } + } + curr_hdr.inode = fdb->inode; + curr_hdr.pgoff = ++fdb->max_off; + curr_hdr.fill = zero_bytes; + curr_hdr.seq = 0; + + if (!writeHdr(disk, new_page, &curr_hdr)) { - fdb->errors |= BATTFS_DISK_GETNEWPAGE_ERR; + fdb->errors |= BATTFS_DISK_WRITE_ERR; return total_write; } /* Update size and free space left */ fd->size += zero_bytes; disk->free_bytes -= zero_bytes; - - curr_hdr.fill = zero_bytes; - setBufferHdr(disk, &curr_hdr); - - fdb->max_off++; } } } - else if (!getBufferHdr(disk, &curr_hdr)) - { - fdb->errors |= BATTFS_DISK_BUFFERRD_ERR; - return total_write; - } while (size) { @@ -733,49 +678,50 @@ static size_t battfs_write(struct KFile *fd, const void *_buf, size_t size) if (pg_offset > fdb->max_off) { LOG_INFO("New page needed, pg_offset %d, pos %d\n", pg_offset, (int)((fdb->start - disk->page_array) + pg_offset)); - if (!getNewPage(disk, (fdb->start - disk->page_array) + pg_offset, fdb->inode, pg_offset, &curr_hdr)) + + new_page = allocateNewPage(disk, (fdb->start - disk->page_array) + pg_offset, fdb->inode); + if (new_page == NO_SPACE) { - fdb->errors |= BATTFS_DISK_GETNEWPAGE_ERR; + fdb->errors |= BATTFS_DISK_SPACEOVER_ERR; return total_write; } + curr_hdr.inode = fdb->inode; + curr_hdr.pgoff = pg_offset; + curr_hdr.fill = 0; + curr_hdr.seq = 0; fdb->max_off = pg_offset; } - /* Handle cache load of a new page*/ - else if (fdb->start[pg_offset] != disk->curr_page) + else { - if (SPACE_OVER(disk)) + if (!readHdr(disk, fdb->start[pg_offset], &curr_hdr)) { - LOG_ERR("No disk space available!\n"); - fdb->errors |= BATTFS_DISK_SPACEOVER_ERR; + fdb->errors |= BATTFS_DISK_READ_ERR; return total_write; } - LOG_INFO("Re-writing page %d to %d\n", fdb->start[pg_offset], disk->page_array[disk->free_page_start]); - if (!loadPage(disk, fdb->start[pg_offset], &curr_hdr)) + + new_page = renewPage(disk, fdb->start[pg_offset]); + if (new_page == NO_SPACE) { - fdb->errors |= BATTFS_DISK_LOADPAGE_ERR; + fdb->errors |= BATTFS_DISK_SPACEOVER_ERR; return total_write; } - /* Get a free page */ - disk->curr_page = disk->page_array[disk->free_page_start]; - movePages(disk, disk->free_page_start + 1, -1); - - /* Insert previous page in free blocks list */ - LOG_INFO("Setting page %d as free\n", fdb->start[pg_offset]); - disk->page_array[disk->page_count - 1] = fdb->start[pg_offset]; - /* Assign new page */ - fdb->start[pg_offset] = disk->curr_page; + 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; curr_hdr.seq++; } - //LOG_INFO("writing to buffer for page %d, offset %d, size %d\n", disk->curr_page, addr_offset, wr_len); - if (disk->bufferWrite(disk, addr_offset, buf, wr_len) != wr_len) + if (kblock_write(disk->dev, new_page, buf, addr_offset, wr_len) != wr_len) { - fdb->errors |= BATTFS_DISK_BUFFERWR_ERR; + fdb->errors |= BATTFS_DISK_WRITE_ERR; return total_write; } - disk->cache_dirty = true; size -= wr_len; fd->seek_pos += wr_len; @@ -786,9 +732,9 @@ static size_t battfs_write(struct KFile *fd, const void *_buf, size_t size) fd->size += fill_delta; curr_hdr.fill += fill_delta; - if (!setBufferHdr(disk, &curr_hdr)) + if (!writeHdr(disk, new_page, &curr_hdr)) { - fdb->errors |= BATTFS_DISK_BUFFERWR_ERR; + fdb->errors |= BATTFS_DISK_WRITE_ERR; return total_write; } @@ -829,7 +775,7 @@ static size_t battfs_read(struct KFile *fd, void *_buf, size_t size) //LOG_INFO("reading from page %d, offset %d, size %d\n", fdb->start[pg_offset], addr_offset, read_len); /* Read from disk */ - if (diskRead(disk, fdb->start[pg_offset], addr_offset, buf, read_len) != read_len) + if (kblock_read(disk->dev, fdb->start[pg_offset], buf, addr_offset, read_len) != read_len) { fdb->errors |= BATTFS_DISK_READ_ERR; return total_read; @@ -955,9 +901,20 @@ bool battfs_fileopen(BattFsSuper *disk, BattFs *fd, inode_t inode, filemode_t mo } /* Create the file */ BattFsPageHeader hdr; - if (!(getNewPage(disk, start_pos, inode, 0, &hdr))) + + if (allocateNewPage(disk, start_pos, inode) == NO_SPACE) + { + fd->errors |= BATTFS_DISK_SPACEOVER_ERR; + return false; + } + + hdr.inode = inode; + hdr.pgoff = 0; + hdr.fill = 0; + hdr.seq = 0; + if (!writeHdr(disk, disk->page_array[start_pos], &hdr)) { - fd->errors |= BATTFS_DISK_GETNEWPAGE_ERR; + fd->errors |= BATTFS_DISK_WRITE_ERR; return false; } } @@ -1021,32 +978,36 @@ bool battfs_umount(struct BattFsSuper *disk) } /* Close disk */ - return disk->close(disk) && (res == 0); + return (kblock_flush(disk->dev) == 0) && (kblock_close(disk->dev) == 0) && (res == 0); } #if UNIT_TEST -bool battfs_writeTestBlock(struct BattFsSuper *disk, pgcnt_t page, inode_t inode, seq_t seq, fill_t fill, pgoff_t pgoff) +void battfs_writeTestBlock(KBlock *dev, pgcnt_t page, inode_t inode, seq_t seq, fill_t fill, pgoff_t pgoff) { - BattFsPageHeader hdr; - - /* Reset page to all 0xff */ - uint8_t buf[disk->page_size]; - memset(buf, 0xFF, disk->page_size); - disk->bufferWrite(disk, 0, buf, disk->page_size); + uint8_t buf[BATTFS_HEADER_LEN]; + battfs_eraseBlock(dev, page); + BattFsPageHeader hdr; hdr.inode = inode; hdr.fill = fill; hdr.pgoff = pgoff; hdr.seq = seq; hdr.fcs = computeFcs(&hdr); - if (!(setBufferHdr(disk, &hdr) && disk->save(disk, page))) - { - LOG_ERR("error writing hdr\n"); - return false; - } + battfs_to_disk(&hdr, buf); - return true; + ASSERT(kblock_write(dev, page, buf, dev->blk_size - BATTFS_HEADER_LEN, BATTFS_HEADER_LEN) == BATTFS_HEADER_LEN); + ASSERT(kblock_flush(dev) == 0); } + +void battfs_eraseBlock(KBlock *dev, pgcnt_t page) +{ + /* Reset page to all 0xff */ + uint8_t buf[dev->blk_size]; + memset(buf, 0xFF, dev->blk_size); + ASSERT(kblock_write(dev, page, buf, 0, dev->blk_size) == dev->blk_size); + ASSERT(kblock_flush(dev) == 0); +} + #endif diff --git a/bertos/fs/battfs.h b/bertos/fs/battfs.h index 4c7e619d..93598fe8 100644 --- a/bertos/fs/battfs.h +++ b/bertos/fs/battfs.h @@ -50,6 +50,7 @@ #include #include #include +#include typedef uint16_t fill_t; ///< Type for keeping trace of space filled inside a page typedef fill_t pgaddr_t; ///< Type for addressing space inside a page @@ -114,64 +115,6 @@ struct BattFsSuper; */ #define PAGE_UNSET_SENTINEL ((pgcnt_t)((1L << (CPU_BITS_PER_CHAR * sizeof(pgcnt_t))) - 1)) -/** - * Type interface for disk page read function. - * \a page is the page address, \a addr the address inside the page, - * \a size the lenght to be read. - * \return the number of bytes read. - */ -typedef size_t (*disk_page_read_t) (struct BattFsSuper *d, pgcnt_t page, pgaddr_t addr, void *buf, size_t); - - -/** - * Type interface for disk page load function. - * The disk should supply a buffer used for loading/saving pages. - * This has to be done by the disk driver because it knows memory details - * (e.g. some memories can have the buffer inside the memory itself). - * \a page is the page to be loaded from the disk in the buffer. - * \return true if ok, false on errors. - */ -typedef bool (*disk_page_load_t) (struct BattFsSuper *d, pgcnt_t page); - -/** - * Type interface for disk pagebuffer write function. - * \a addr is the address inside the current loaded page, - * \a size the lenght to be written. - * \return the number of bytes written. - */ -typedef size_t (*disk_buffer_write_t) (struct BattFsSuper *d, pgaddr_t addr, const void *buf, size_t); - -/** - * Type interface for disk pagebuffer read function. - * \a addr is the address inside the current loaded page, - * \a size the lenght to be read. - * \return the number of bytes read. - */ -typedef size_t (*disk_buffer_read_t) (struct BattFsSuper *d, pgaddr_t addr, void *buf, size_t); - -/** - * Type interface for disk page save function. - * The disk should supply a buffer used for loading/saving pages. - * For details \see disk_page_load_t. - * \a page is the page where the buffer will be written. - * \return true if ok, false on errors. - */ -typedef bool (*disk_page_save_t) (struct BattFsSuper *d, pgcnt_t page); - -/** - * Type interface for disk page erase function. - * \a page is the page address. - * \return true if all is ok, false otherwise. - */ -typedef bool (*disk_page_erase_t) (struct BattFsSuper *d, pgcnt_t page); - -/** - * Type interface for disk deinit function. - * \return true if all is ok, false otherwise. - */ -typedef bool (*disk_close_t) (struct BattFsSuper *d); - - typedef uint32_t disk_size_t; ///< Type for disk sizes. /** @@ -181,19 +124,12 @@ typedef uint32_t disk_size_t; ///< Type for disk sizes. */ typedef struct BattFsSuper { - void *disk_ctx; ///< Disk context used by disk access functions. - disk_page_read_t read; ///< Page read. - disk_page_load_t load; ///< Page load. - disk_buffer_write_t bufferWrite; ///< Buffer write. - disk_buffer_read_t bufferRead; ///< Buffer read. - disk_page_save_t save; ///< Page save. - disk_page_erase_t erase; ///< Page erase. - disk_close_t close; ///< Disk deinit. + KBlock *dev; ///< Block device context (physical disk). pgaddr_t page_size; ///< Size of a memory page, in bytes. Used by disk low level driver. - pgaddr_t data_size; ///< Size of space usable for data in a disk page, in bytes. The rest is used by the page header. pgcnt_t page_count; ///< Number of pages on disk. + pgaddr_t data_size; ///< Size of space usable for data in a disk page, in bytes. The rest is used by the page header. /** * Page allocation array. * This array must be allocated somewhere and @@ -202,8 +138,6 @@ typedef struct BattFsSuper * the entire disk in memory. */ pgcnt_t *page_array; - pgcnt_t curr_page; ///< Current page loaded in disk buffer. - bool cache_dirty; ///< True if current cache is dirty (nneds to be flushed). /** * Lowest address, in page array, for free pages. @@ -241,14 +175,11 @@ typedef int32_t file_size_t; ///< Type for file sizes. * \{ */ #define BATTFS_NEGATIVE_SEEK_ERR BV(0) ///< Trying to read/write before file start. -#define BATTFS_DISK_READ_ERR BV(1) ///< Error reading from disk driver. -#define BATTFS_DISK_LOADPAGE_ERR BV(2) ///< Error loading a disk page in the buffer. -#define BATTFS_DISK_BUFFERWR_ERR BV(3) ///< Error writing in the disk page buffer. -#define BATTFS_DISK_GETNEWPAGE_ERR BV(4) ///< Error getting a free page. -#define BATTFS_DISK_BUFFERRD_ERR BV(6) ///< Error reading from the disk page buffer. -#define BATTFS_DISK_SPACEOVER_ERR BV(7) ///< No more disk space available. -#define BATTFS_DISK_FLUSHBUF_ERR BV(8) ///< Error flushing (writing) the current page to disk. -#define BATTFS_FILE_NOT_FOUND_ERR BV(9) ///< File not found on disk. +#define BATTFS_DISK_READ_ERR BV(1) ///< Error reading from disk device. +#define BATTFS_DISK_WRITE_ERR BV(2) ///< Error writing in the disk device. +#define BATTFS_DISK_SPACEOVER_ERR BV(3) ///< No more disk space available. +#define BATTFS_DISK_FLUSHBUF_ERR BV(4) ///< Error flushing (writing) the current page to disk. +#define BATTFS_FILE_NOT_FOUND_ERR BV(5) ///< File not found on disk. /*/}*/ /** @@ -281,11 +212,13 @@ INLINE BattFs * BATTFS_CAST(KFile *fd) return (BattFs *)fd; } -bool battfs_mount(struct BattFsSuper *d); +bool battfs_mount(struct BattFsSuper *disk, struct KBlock *dev, pgcnt_t *page_array, size_t array_size); bool battfs_fsck(struct BattFsSuper *disk); bool battfs_umount(struct BattFsSuper *disk); bool battfs_fileExists(BattFsSuper *disk, inode_t inode); bool battfs_fileopen(BattFsSuper *disk, BattFs *fd, inode_t inode, filemode_t mode); -bool battfs_writeTestBlock(struct BattFsSuper *disk, pgcnt_t page, inode_t inode, seq_t seq, fill_t fill, pgoff_t pgoff); + +void battfs_writeTestBlock(KBlock *dev, pgcnt_t page, inode_t inode, seq_t seq, fill_t fill, pgoff_t pgoff); +void battfs_eraseBlock(KBlock *dev, pgcnt_t page); #endif /* FS_BATTFS_H */ diff --git a/bertos/fs/battfs_test.c b/bertos/fs/battfs_test.c index 642e6d64..33b1f69f 100644 --- a/bertos/fs/battfs_test.c +++ b/bertos/fs/battfs_test.c @@ -36,6 +36,7 @@ */ #include +#include #include #include @@ -46,101 +47,19 @@ #define FILE_SIZE 32768 #define PAGE_SIZE 128 -#define PAGE_COUNT FILE_SIZE / PAGE_SIZE + +#define DATA_SIZE (PAGE_SIZE - BATTFS_HEADER_LEN) +#define PAGE_COUNT (FILE_SIZE / PAGE_SIZE) #if UNIT_TEST const char test_filename[]="battfs_disk.bin"; static uint8_t page_buffer[PAGE_SIZE]; - -static size_t disk_page_read(struct BattFsSuper *d, pgcnt_t page, pgaddr_t addr, void *buf, size_t size) -{ - //TRACEMSG("page:%d, addr:%d, size:%d", page, addr, size); - FILE *fp = (FILE *)d->disk_ctx; - fseek(fp, page * d->page_size + addr, SEEK_SET); - return fread(buf, 1, size, fp); -} - -static size_t disk_buffer_write(struct BattFsSuper *d, pgaddr_t addr, const void *buf, size_t size) -{ - //TRACEMSG("addr:%d, size:%d", addr, size); - ASSERT(addr + size <= d->page_size); - memcpy(&page_buffer[addr], buf, size); - - return size; -} - -static size_t disk_buffer_read(struct BattFsSuper *d, pgaddr_t addr, void *buf, size_t size) -{ - //TRACEMSG("addr:%d, size:%d", addr, size); - ASSERT(addr + size <= d->page_size); - memcpy(buf, &page_buffer[addr], size); - - return size; -} - -static bool disk_page_load(struct BattFsSuper *d, pgcnt_t page) -{ - FILE *fp = (FILE *)d->disk_ctx; - //TRACEMSG("page:%d", page); - fseek(fp, page * d->page_size, SEEK_SET); - return fread(page_buffer, 1, d->page_size, fp) == d->page_size; -} - -static bool disk_page_save(struct BattFsSuper *d, pgcnt_t page) -{ - FILE *fp = (FILE *)d->disk_ctx; - //TRACEMSG("page:%d", page); - fseek(fp, page * d->page_size, SEEK_SET); - return fwrite(page_buffer, 1, d->page_size, fp) == d->page_size; -} - -static bool disk_page_erase(struct BattFsSuper *d, pgcnt_t page) -{ - FILE *fp = (FILE *)d->disk_ctx; - //TRACEMSG("page:%d", page); - fseek(fp, page * d->page_size, SEEK_SET); - - for (int i = 0; i < d->page_size; i++) - if (fputc(0xff, fp) == EOF) - return false; - return true; -} - -static bool disk_close(struct BattFsSuper *d) -{ - FILE *fp = (FILE *)d->disk_ctx; - //TRACE; - free(d->page_array); - return (fclose(fp) != EOF); -} - -static bool disk_open(struct BattFsSuper *d) -{ - d->read = disk_page_read; - d->load = disk_page_load; - d->bufferWrite = disk_buffer_write; - d->bufferRead = disk_buffer_read; - d->save = disk_page_save; - d->erase = disk_page_erase; - d->close = disk_close; - - FILE *fp = fopen(test_filename, "r+b"); - ASSERT(fp); - d->disk_ctx = fp; - fseek(fp, 0, SEEK_END); - d->page_size = PAGE_SIZE; - d->page_count = ftell(fp) / d->page_size; - d->page_array = malloc(d->page_count * sizeof(pgcnt_t)); - //TRACEMSG("page_size:%d, page_count:%d\n", d->page_size, d->page_count); - return (fp && d->page_array); -} +static pgcnt_t page_array[PAGE_COUNT]; static void testCheck(BattFsSuper *disk, pgcnt_t *reference) { - ASSERT(disk_open(disk)); - ASSERT(battfs_mount(disk)); ASSERT(battfs_fsck(disk)); for (int i = 0; i < disk->page_count; i++) @@ -175,16 +94,21 @@ static void testCheck(BattFsSuper *disk, pgcnt_t *reference) static void diskNew(BattFsSuper *disk) { pgcnt_t ref[PAGE_COUNT]; + TRACEMSG("1: disk new\n"); FILE *fpt = fopen(test_filename, "w+"); for (int i = 0; i < FILE_SIZE; i++) fputc(0xff, fpt); - fclose(fpt); + for (int i = 0; i < PAGE_COUNT; i++) ref[i] = i; + KBlockFile f; + kblockfile_init(&f, fpt, page_buffer, PAGE_SIZE, PAGE_COUNT); + battfs_mount(disk, &f.b, page_array, sizeof(page_array)); + testCheck(disk, ref); TRACEMSG("1: passed\n"); } @@ -194,15 +118,20 @@ static void disk1File(BattFsSuper *disk) pgcnt_t ref[PAGE_COUNT]; TRACEMSG("2: disk full with 1 contiguos file\n"); - FILE *fp = fopen(test_filename, "w+"); + for (int i = 0; i < FILE_SIZE; i++) + fputc(0xff, fp); + + KBlockFile f; + kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, PAGE_COUNT); for (int i = 0; i < PAGE_COUNT; i++) { - battfs_writeTestBlock(disk, i, 0, 0, disk->data_size, i); + battfs_writeTestBlock(&f.b, i, 0, 0, DATA_SIZE, i); ref[i] = i; } - fclose(fp); + + battfs_mount(disk, &f.b, page_array, sizeof(page_array)); testCheck(disk, ref); TRACEMSG("2: passed\n"); @@ -216,22 +145,27 @@ static void diskHalfFile(BattFsSuper *disk) FILE *fp = fopen(test_filename, "w+"); + for (int i = 0; i < FILE_SIZE; i++) + fputc(0xff, fp); + + KBlockFile f; + kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, PAGE_COUNT); for (int i = 0; i < PAGE_COUNT / 2; i++) { - battfs_writeTestBlock(disk, i, 0, 0, disk->data_size, i); + battfs_writeTestBlock(&f.b, i, 0, 0, DATA_SIZE, i); ref[i] = i; } fseek(fp, FILE_SIZE / 2, SEEK_SET); for (int i = FILE_SIZE / 2; i < FILE_SIZE; i++) fputc(0xff, fp); - fclose(fp); for (int i = PAGE_COUNT / 2; i < PAGE_COUNT; i++) { ref[i] = i; } + battfs_mount(disk, &f.b, page_array, sizeof(page_array)); testCheck(disk, ref); TRACEMSG("3: passed\n"); @@ -243,21 +177,25 @@ static void oldSeq1(BattFsSuper *disk) pgcnt_t ref[4]; TRACEMSG("6: 1 file with 1 old seq num, 1 free block\n"); - FILE *fp = fopen(test_filename, "w+"); - // page, inode, seq, fill, pgoff - battfs_writeTestBlock(disk, 0, 0, 0, disk->data_size, 0); - battfs_writeTestBlock(disk, 1, 0, 0, disk->data_size, 1); - battfs_writeTestBlock(disk, 2, 0, 1, disk->data_size, 1); - disk->erase(disk, 3); + for (int i = 0; i < PAGE_SIZE * 4; i++) + fputc(0xff, fp); + KBlockFile f; + kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, 4); + // page, inode, seq, fill, pgoff + battfs_writeTestBlock(&f.b, 0, 0, 0, DATA_SIZE, 0); + battfs_writeTestBlock(&f.b, 1, 0, 0, DATA_SIZE, 1); + battfs_writeTestBlock(&f.b, 2, 0, 1, DATA_SIZE, 1); + battfs_eraseBlock(&f.b, 3); - fclose(fp); ref[0] = 0; ref[1] = 2; ref[2] = 1; ref[3] = 3; + battfs_mount(disk, &f.b, page_array, sizeof(page_array)); + testCheck(disk, ref); TRACEMSG("6: passed\n"); } @@ -267,20 +205,24 @@ static void oldSeq2(BattFsSuper *disk) pgcnt_t ref[4]; TRACEMSG("7: 1 file with 1 old seq num, 1 free block\n"); - FILE *fp = fopen(test_filename, "w+"); + for (int i = 0; i < PAGE_SIZE * 4; i++) + fputc(0xff, fp); + KBlockFile f; + kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, 4); + // page, inode, seq, fill, pgoff - battfs_writeTestBlock(disk, 0, 0, 0, disk->data_size, 0); - battfs_writeTestBlock(disk, 1, 0, 1, disk->data_size, 1); - battfs_writeTestBlock(disk, 2, 0, 0, disk->data_size, 1); - disk->erase(disk, 3); + battfs_writeTestBlock(&f.b, 0, 0, 0, DATA_SIZE, 0); + battfs_writeTestBlock(&f.b, 1, 0, 1, DATA_SIZE, 1); + battfs_writeTestBlock(&f.b, 2, 0, 0, DATA_SIZE, 1); + battfs_eraseBlock(&f.b, 3); - fclose(fp); ref[0] = 0; ref[1] = 1; ref[2] = 2; ref[3] = 3; + battfs_mount(disk, &f.b, page_array, sizeof(page_array)); testCheck(disk, ref); TRACEMSG("7: passed\n"); } @@ -292,20 +234,23 @@ static void oldSeq3(BattFsSuper *disk) FILE *fp = fopen(test_filename, "w+"); + for (int i = 0; i < PAGE_SIZE * 4; i++) + fputc(0xff, fp); + KBlockFile f; + kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, 4); // page, inode, seq, fill, pgoff - disk->erase(disk, 0); - battfs_writeTestBlock(disk, 1, 0, 0, disk->data_size, 0); - battfs_writeTestBlock(disk, 2, 0, 1, disk->data_size, 1); - battfs_writeTestBlock(disk, 3, 0, 0, disk->data_size, 1); - + battfs_eraseBlock(&f.b, 0); + battfs_writeTestBlock(&f.b, 1, 0, 0, DATA_SIZE, 0); + battfs_writeTestBlock(&f.b, 2, 0, 1, DATA_SIZE, 1); + battfs_writeTestBlock(&f.b, 3, 0, 0, DATA_SIZE, 1); - fclose(fp); ref[0] = 1; ref[1] = 2; ref[2] = 0; ref[3] = 3; + battfs_mount(disk, &f.b, page_array, sizeof(page_array)); testCheck(disk, ref); TRACEMSG("8: passed\n"); } @@ -317,19 +262,22 @@ static void oldSeq2File(BattFsSuper *disk) FILE *fp = fopen(test_filename, "w+"); + for (int i = 0; i < PAGE_SIZE * 8; i++) + fputc(0xff, fp); + KBlockFile f; + kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, 8); // page, inode, seq, fill, pgoff - disk->erase(disk, 0); - battfs_writeTestBlock(disk, 1, 0, 0, disk->data_size, 0); - battfs_writeTestBlock(disk, 2, 0, 3, disk->data_size, 1); - battfs_writeTestBlock(disk, 3, 0, 0, disk->data_size, 1); - disk->erase(disk, 4); - battfs_writeTestBlock(disk, 5, 4, 0, disk->data_size, 0); - battfs_writeTestBlock(disk, 6, 4, 1, disk->data_size, 1); - battfs_writeTestBlock(disk, 7, 4, 0, disk->data_size, 1); + battfs_eraseBlock(&f.b, 0); + battfs_writeTestBlock(&f.b, 1, 0, 0, DATA_SIZE, 0); + battfs_writeTestBlock(&f.b, 2, 0, 3, DATA_SIZE, 1); + battfs_writeTestBlock(&f.b, 3, 0, 0, DATA_SIZE, 1); + battfs_eraseBlock(&f.b, 4); + battfs_writeTestBlock(&f.b, 5, 4, 0, DATA_SIZE, 0); + battfs_writeTestBlock(&f.b, 6, 4, 1, DATA_SIZE, 1); + battfs_writeTestBlock(&f.b, 7, 4, 0, DATA_SIZE, 1); - fclose(fp); ref[0] = 1; ref[1] = 2; ref[2] = 5; @@ -339,6 +287,7 @@ static void oldSeq2File(BattFsSuper *disk) ref[6] = 4; ref[7] = 7; + battfs_mount(disk, &f.b, page_array, sizeof(page_array)); testCheck(disk, ref); TRACEMSG("9: passed\n"); } @@ -350,6 +299,11 @@ static void openFile(BattFsSuper *disk) TRACEMSG("10: open file test, inode 0 and inode 4\n"); FILE *fp = fopen(test_filename, "w+"); + for (int i = 0; i < PAGE_SIZE * 8; i++) + fputc(0xff, fp); + KBlockFile f; + kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, 8); + int PAGE_FILL = PAGE_SIZE - BATTFS_HEADER_LEN; inode_t INODE = 0; @@ -358,19 +312,16 @@ static void openFile(BattFsSuper *disk) unsigned int MODE = 0; // page, inode, seq, fill, pgoff - disk->erase(disk, 0); - battfs_writeTestBlock(disk, 1, INODE, 0, PAGE_FILL, 0); - battfs_writeTestBlock(disk, 2, INODE, 3, PAGE_FILL, 1); - battfs_writeTestBlock(disk, 3, INODE, 0, PAGE_FILL, 1); - disk->erase(disk, 4); - battfs_writeTestBlock(disk, 5, INODE2, 0, PAGE_FILL, 0); - battfs_writeTestBlock(disk, 6, INODE2, 1, PAGE_FILL, 1); - battfs_writeTestBlock(disk, 7, INODE2, 0, PAGE_FILL, 1); - - fclose(fp); - - ASSERT(disk_open(disk)); - ASSERT(battfs_mount(disk)); + battfs_eraseBlock(&f.b, 0); + battfs_writeTestBlock(&f.b, 1, INODE, 0, PAGE_FILL, 0); + battfs_writeTestBlock(&f.b, 2, INODE, 3, PAGE_FILL, 1); + battfs_writeTestBlock(&f.b, 3, INODE, 0, PAGE_FILL, 1); + battfs_eraseBlock(&f.b, 4); + battfs_writeTestBlock(&f.b, 5, INODE2, 0, PAGE_FILL, 0); + battfs_writeTestBlock(&f.b, 6, INODE2, 1, PAGE_FILL, 1); + battfs_writeTestBlock(&f.b, 7, INODE2, 0, PAGE_FILL, 1); + + ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array))); ASSERT(battfs_fsck(disk)); ASSERT(!battfs_fileExists(disk, INEXISTENT_INODE)); @@ -422,25 +373,27 @@ static void readFile(BattFsSuper *disk) TRACEMSG("11: read file test\n"); FILE *fp = fopen(test_filename, "w+"); + for (int i = 0; i < PAGE_SIZE * 8; i++) + fputc(0xff, fp); + KBlockFile f; + kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, 8); + unsigned int PAGE_FILL = PAGE_SIZE - BATTFS_HEADER_LEN; inode_t INODE = 0; inode_t INODE2 = 4; unsigned int MODE = 0; - disk->erase(disk, 0); - battfs_writeTestBlock(disk, 1, INODE, 0, PAGE_FILL, 0); - battfs_writeTestBlock(disk, 2, INODE, 3, PAGE_FILL, 1); - battfs_writeTestBlock(disk, 3, INODE, 0, PAGE_FILL, 1); - disk->erase(disk, 4); - battfs_writeTestBlock(disk, 5, INODE2, 0, PAGE_FILL, 0); - battfs_writeTestBlock(disk, 6, INODE2, 1, PAGE_FILL, 1); - battfs_writeTestBlock(disk, 7, INODE2, 0, PAGE_FILL, 1); + battfs_eraseBlock(&f.b, 0); + battfs_writeTestBlock(&f.b, 1, INODE, 0, PAGE_FILL, 0); + battfs_writeTestBlock(&f.b, 2, INODE, 3, PAGE_FILL, 1); + battfs_writeTestBlock(&f.b, 3, INODE, 0, PAGE_FILL, 1); + battfs_eraseBlock(&f.b, 4); + battfs_writeTestBlock(&f.b, 5, INODE2, 0, PAGE_FILL, 0); + battfs_writeTestBlock(&f.b, 6, INODE2, 1, PAGE_FILL, 1); + battfs_writeTestBlock(&f.b, 7, INODE2, 0, PAGE_FILL, 1); - fclose(fp); - - ASSERT(disk_open(disk)); - ASSERT(battfs_mount(disk)); + ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array))); ASSERT(battfs_fsck(disk)); ASSERT(battfs_fileopen(disk, &fd1, INODE, MODE)); ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == sizeof(buf)); @@ -463,25 +416,26 @@ static void readAcross(BattFsSuper *disk) TRACEMSG("12: read file test across page boundary and seek test\n"); FILE *fp = fopen(test_filename, "w+"); + for (int i = 0; i < PAGE_SIZE * 8; i++) + fputc(0xff, fp); + KBlockFile f; + kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, 8); const unsigned int PAGE_FILL = PAGE_SIZE - BATTFS_HEADER_LEN; inode_t INODE = 0; unsigned int MODE = 0; uint8_t buf[PAGE_FILL + BATTFS_HEADER_LEN / 2]; - disk->erase(disk, 0); - battfs_writeTestBlock(disk, 1, INODE, 0, PAGE_FILL, 0); - battfs_writeTestBlock(disk, 2, INODE, 3, PAGE_FILL, 1); - battfs_writeTestBlock(disk, 3, INODE, 0, PAGE_FILL, 1); - disk->erase(disk, 4); - battfs_writeTestBlock(disk, 5, INODE, 0, PAGE_FILL, 2); - battfs_writeTestBlock(disk, 6, INODE, 1, PAGE_FILL, 3); - battfs_writeTestBlock(disk, 7, INODE, 0, PAGE_FILL, 3); + battfs_eraseBlock(&f.b, 0); + battfs_writeTestBlock(&f.b, 1, INODE, 0, PAGE_FILL, 0); + battfs_writeTestBlock(&f.b, 2, INODE, 3, PAGE_FILL, 1); + battfs_writeTestBlock(&f.b, 3, INODE, 0, PAGE_FILL, 1); + battfs_eraseBlock(&f.b, 4); + battfs_writeTestBlock(&f.b, 5, INODE, 0, PAGE_FILL, 2); + battfs_writeTestBlock(&f.b, 6, INODE, 1, PAGE_FILL, 3); + battfs_writeTestBlock(&f.b, 7, INODE, 0, PAGE_FILL, 3); - fclose(fp); - - ASSERT(disk_open(disk)); - ASSERT(battfs_mount(disk)); + ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array))); ASSERT(battfs_fsck(disk)); ASSERT(battfs_fileopen(disk, &fd1, INODE, MODE)); @@ -528,28 +482,30 @@ static void writeFile(BattFsSuper *disk) TRACEMSG("13: write file test\n"); FILE *fp = fopen(test_filename, "w+"); + for (int i = 0; i < PAGE_SIZE * 8; i++) + fputc(0xff, fp); + KBlockFile f; + kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, 8); + unsigned int PAGE_FILL = PAGE_SIZE - BATTFS_HEADER_LEN; inode_t INODE = 0; inode_t INODE2 = 4; unsigned int MODE = 0; - disk->erase(disk, 0); - battfs_writeTestBlock(disk, 1, INODE, 0, PAGE_FILL, 0); - battfs_writeTestBlock(disk, 2, INODE, 3, PAGE_FILL, 1); - battfs_writeTestBlock(disk, 3, INODE, 0, PAGE_FILL, 1); - disk->erase(disk, 4); - battfs_writeTestBlock(disk, 5, INODE2, 0, PAGE_FILL, 0); - battfs_writeTestBlock(disk, 6, INODE2, 1, PAGE_FILL, 1); - battfs_writeTestBlock(disk, 7, INODE2, 0, PAGE_FILL, 1); - - fclose(fp); + battfs_eraseBlock(&f.b, 0); + battfs_writeTestBlock(&f.b, 1, INODE, 0, PAGE_FILL, 0); + battfs_writeTestBlock(&f.b, 2, INODE, 3, PAGE_FILL, 1); + battfs_writeTestBlock(&f.b, 3, INODE, 0, PAGE_FILL, 1); + battfs_eraseBlock(&f.b, 4); + battfs_writeTestBlock(&f.b, 5, INODE2, 0, PAGE_FILL, 0); + battfs_writeTestBlock(&f.b, 6, INODE2, 1, PAGE_FILL, 1); + battfs_writeTestBlock(&f.b, 7, INODE2, 0, PAGE_FILL, 1); for (size_t i = 0; i < sizeof(buf); i++) buf[i] = i; - ASSERT(disk_open(disk)); - ASSERT(battfs_mount(disk)); + ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array))); ASSERT(battfs_fsck(disk)); ASSERT(battfs_fileopen(disk, &fd1, INODE, MODE)); ASSERT(kfile_write(&fd1.fd, buf, sizeof(buf)) == sizeof(buf)); @@ -577,25 +533,26 @@ static void writeAcross(BattFsSuper *disk) TRACEMSG("14: write file test across page boundary and seek test\n"); FILE *fp = fopen(test_filename, "w+"); + for (int i = 0; i < PAGE_SIZE * 8; i++) + fputc(0xff, fp); + KBlockFile f; + kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, 8); const unsigned int PAGE_FILL = PAGE_SIZE - BATTFS_HEADER_LEN; inode_t INODE = 0; unsigned int MODE = 0; uint8_t buf[PAGE_FILL + BATTFS_HEADER_LEN / 2]; - disk->erase(disk, 0); - battfs_writeTestBlock(disk, 1, INODE, 0, PAGE_FILL, 0); - battfs_writeTestBlock(disk, 2, INODE, 3, PAGE_FILL, 1); - battfs_writeTestBlock(disk, 3, INODE, 0, PAGE_FILL, 1); - disk->erase(disk, 4); - battfs_writeTestBlock(disk, 5, INODE, 0, PAGE_FILL, 2); - battfs_writeTestBlock(disk, 6, INODE, 1, PAGE_FILL, 3); - battfs_writeTestBlock(disk, 7, INODE, 0, PAGE_FILL, 3); + battfs_eraseBlock(&f.b, 0); + battfs_writeTestBlock(&f.b, 1, INODE, 0, PAGE_FILL, 0); + battfs_writeTestBlock(&f.b, 2, INODE, 3, PAGE_FILL, 1); + battfs_writeTestBlock(&f.b, 3, INODE, 0, PAGE_FILL, 1); + battfs_eraseBlock(&f.b, 4); + battfs_writeTestBlock(&f.b, 5, INODE, 0, PAGE_FILL, 2); + battfs_writeTestBlock(&f.b, 6, INODE, 1, PAGE_FILL, 3); + battfs_writeTestBlock(&f.b, 7, INODE, 0, PAGE_FILL, 3); - fclose(fp); - - ASSERT(disk_open(disk)); - ASSERT(battfs_mount(disk)); + ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array))); ASSERT(battfs_fsck(disk)); ASSERT(battfs_fileopen(disk, &fd1, INODE, MODE)); @@ -649,17 +606,16 @@ static void createFile(BattFsSuper *disk) TRACEMSG("15: file creation on new disk\n"); FILE *fpt = fopen(test_filename, "w+"); - for (int i = 0; i < FILE_SIZE; i++) fputc(0xff, fpt); - fclose(fpt); + KBlockFile f; + kblockfile_init(&f, fpt, page_buffer, PAGE_SIZE, PAGE_COUNT); BattFs fd1; inode_t INODE = 0; unsigned int MODE = BATTFS_CREATE; - ASSERT(disk_open(disk)); - ASSERT(battfs_mount(disk)); + ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array))); ASSERT(battfs_fsck(disk)); ASSERT(battfs_fileopen(disk, &fd1, INODE, MODE)); for (int i = 0; i < FILE_SIZE / 2; i++) @@ -672,8 +628,10 @@ static void createFile(BattFsSuper *disk) ASSERT(battfs_fsck(disk)); ASSERT(battfs_umount(disk)); - ASSERT(disk_open(disk)); - ASSERT(battfs_mount(disk)); + fpt = fopen(test_filename, "r+"); + kblockfile_init(&f, fpt, page_buffer, PAGE_SIZE, PAGE_COUNT); + + ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array))); ASSERT(battfs_fsck(disk)); ASSERT(battfs_fileopen(disk, &fd1, INODE, 0)); ASSERT(fd1.fd.size == FILE_SIZE / 2); @@ -701,18 +659,18 @@ static void multipleWrite(BattFsSuper *disk) TRACEMSG("16: multiple write on file\n"); FILE *fpt = fopen(test_filename, "w+"); - for (int i = 0; i < FILE_SIZE; i++) fputc(0xff, fpt); - fclose(fpt); + KBlockFile f; + kblockfile_init(&f, fpt, page_buffer, PAGE_SIZE, PAGE_COUNT); + BattFs fd1; inode_t INODE = 0; unsigned int MODE = BATTFS_CREATE; uint8_t buf[1000]; - ASSERT(disk_open(disk)); - ASSERT(battfs_mount(disk)); + ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array))); ASSERT(battfs_fsck(disk)); ASSERT(battfs_fileopen(disk, &fd1, INODE, MODE)); @@ -739,8 +697,10 @@ static void multipleWrite(BattFsSuper *disk) ASSERT(battfs_fsck(disk)); ASSERT(battfs_umount(disk)); - ASSERT(disk_open(disk)); - ASSERT(battfs_mount(disk)); + fpt = fopen(test_filename, "r+"); + kblockfile_init(&f, fpt, page_buffer, PAGE_SIZE, PAGE_COUNT); + + ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array))); ASSERT(battfs_fsck(disk)); ASSERT(disk->free_bytes == disk->disk_size - sizeof(buf)); ASSERT(battfs_fileopen(disk, &fd1, INODE, 0)); @@ -763,18 +723,19 @@ static void increaseFile(BattFsSuper *disk) TRACEMSG("17: increasing dimension of a file with multiple open files.\n"); FILE *fpt = fopen(test_filename, "w+"); - for (int i = 0; i < FILE_SIZE / 10; i++) fputc(0xff, fpt); - fclose(fpt); + + KBlockFile f; + kblockfile_init(&f, fpt, page_buffer, PAGE_SIZE, PAGE_COUNT / 10); + BattFs fd1,fd2; inode_t INODE1 = 1, INODE2 = 2; unsigned int MODE = BATTFS_CREATE; uint8_t buf[1000]; - ASSERT(disk_open(disk)); - ASSERT(battfs_mount(disk)); + ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array))); ASSERT(battfs_fsck(disk)); ASSERT(battfs_fileopen(disk, &fd1, INODE1, MODE)); ASSERT(battfs_fileopen(disk, &fd2, INODE2, MODE)); @@ -815,25 +776,27 @@ static void readEOF(BattFsSuper *disk) TRACEMSG("18: reading over EOF test\n"); FILE *fp = fopen(test_filename, "w+"); + for (int i = 0; i < PAGE_SIZE * 8; i++) + fputc(0xff, fp); + KBlockFile f; + kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, 8); + unsigned int PAGE_FILL = PAGE_SIZE - BATTFS_HEADER_LEN; inode_t INODE = 0; inode_t INODE2 = 4; unsigned int MODE = 0; - disk->erase(disk, 0); - battfs_writeTestBlock(disk, 1, INODE, 0, PAGE_FILL, 0); - battfs_writeTestBlock(disk, 2, INODE, 3, PAGE_FILL, 1); - battfs_writeTestBlock(disk, 3, INODE, 0, PAGE_FILL, 1); - disk->erase(disk, 4); - battfs_writeTestBlock(disk, 5, INODE2, 0, PAGE_FILL, 0); - battfs_writeTestBlock(disk, 6, INODE2, 1, PAGE_FILL, 1); - battfs_writeTestBlock(disk, 7, INODE2, 0, PAGE_FILL, 1); - - fclose(fp); + battfs_eraseBlock(&f.b, 0); + battfs_writeTestBlock(&f.b, 1, INODE, 0, PAGE_FILL, 0); + battfs_writeTestBlock(&f.b, 2, INODE, 3, PAGE_FILL, 1); + battfs_writeTestBlock(&f.b, 3, INODE, 0, PAGE_FILL, 1); + battfs_eraseBlock(&f.b, 4); + battfs_writeTestBlock(&f.b, 5, INODE2, 0, PAGE_FILL, 0); + battfs_writeTestBlock(&f.b, 6, INODE2, 1, PAGE_FILL, 1); + battfs_writeTestBlock(&f.b, 7, INODE2, 0, PAGE_FILL, 1); - ASSERT(disk_open(disk)); - ASSERT(battfs_mount(disk)); + ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array))); ASSERT(battfs_fsck(disk)); ASSERT(battfs_fileopen(disk, &fd1, INODE, MODE)); ASSERT(kfile_seek(&fd1.fd, fd1.fd.size + 10, SEEK_SET) == fd1.fd.size + 10); @@ -853,10 +816,10 @@ static void writeEOF(BattFsSuper *disk) TRACEMSG("19: writing over EOF test\n"); FILE *fpt = fopen(test_filename, "w+"); - for (int i = 0; i < FILE_SIZE / 5; i++) fputc(0xff, fpt); - fclose(fpt); + KBlockFile f; + kblockfile_init(&f, fpt, page_buffer, PAGE_SIZE, PAGE_COUNT / 5); BattFs fd1; inode_t INODE = 0; @@ -866,8 +829,7 @@ static void writeEOF(BattFsSuper *disk) for (int i = 0; i < 2; i++) buf[i] = i; - ASSERT(disk_open(disk)); - ASSERT(battfs_mount(disk)); + ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array))); ASSERT(battfs_fsck(disk)); disk_size_t prev_free = disk->free_bytes; ASSERT(battfs_fileopen(disk, &fd1, INODE, MODE)); @@ -938,19 +900,21 @@ static void endOfSpace(BattFsSuper *disk) uint8_t buf[(PAGE_SIZE - BATTFS_HEADER_LEN) * 5]; FILE *fp = fopen(test_filename, "w+"); + for (int i = 0; i < PAGE_SIZE * 4; i++) + fputc(0xff, fp); + KBlockFile f; + kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, 4); unsigned int PAGE_FILL = PAGE_SIZE - BATTFS_HEADER_LEN; inode_t INODE = 0; unsigned int MODE = BATTFS_CREATE; - disk->erase(disk, 0); - disk->erase(disk, 1); - disk->erase(disk, 2); - disk->erase(disk, 3); - fclose(fp); + battfs_eraseBlock(&f.b, 0); + battfs_eraseBlock(&f.b, 1); + battfs_eraseBlock(&f.b, 2); + battfs_eraseBlock(&f.b, 3); - ASSERT(disk_open(disk)); - ASSERT(battfs_mount(disk)); + ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array))); ASSERT(battfs_fsck(disk)); ASSERT(battfs_fileopen(disk, &fd1, INODE, MODE)); ASSERT(kfile_write(&fd1.fd, buf, sizeof(buf)) == PAGE_FILL * 4); @@ -959,7 +923,7 @@ static void endOfSpace(BattFsSuper *disk) ASSERT(disk->free_bytes == 0); ASSERT(kfile_close(&fd1.fd) == 0); - ASSERT(kfile_error(&fd1.fd) == BATTFS_DISK_GETNEWPAGE_ERR); + ASSERT(kfile_error(&fd1.fd) == BATTFS_DISK_SPACEOVER_ERR); ASSERT(battfs_fsck(disk)); ASSERT(battfs_umount(disk)); @@ -972,18 +936,17 @@ static void multipleFilesRW(BattFsSuper *disk) TRACEMSG("21: multiple files read/write test\n"); FILE *fpt = fopen(test_filename, "w+"); - for (int i = 0; i < FILE_SIZE; i++) fputc(0xff, fpt); - fclose(fpt); + KBlockFile f; + kblockfile_init(&f, fpt, page_buffer, PAGE_SIZE, PAGE_COUNT); #define N_FILES 10 BattFs fd[N_FILES]; unsigned int MODE = BATTFS_CREATE; uint32_t buf[FILE_SIZE / (4 * N_FILES * sizeof(uint32_t))]; - ASSERT(disk_open(disk)); - ASSERT(battfs_mount(disk)); + ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array))); ASSERT(battfs_fsck(disk)); for (inode_t i = 0; i < N_FILES; i++) ASSERT(battfs_fileopen(disk, &fd[i], i, MODE)); @@ -1021,8 +984,10 @@ static void multipleFilesRW(BattFsSuper *disk) ASSERT(battfs_fsck(disk)); ASSERT(battfs_umount(disk)); - ASSERT(disk_open(disk)); - ASSERT(battfs_mount(disk)); + fpt = fopen(test_filename, "r+"); + kblockfile_init(&f, fpt, page_buffer, PAGE_SIZE, PAGE_COUNT); + + ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array))); ASSERT(battfs_fsck(disk)); for (inode_t i = 0; i < N_FILES; i++) @@ -1057,16 +1022,15 @@ static void openAllFiles(BattFsSuper *disk) TRACEMSG("22: try to open a lot of files\n"); FILE *fpt = fopen(test_filename, "w+"); - for (int i = 0; i < FILE_SIZE; i++) fputc(0xff, fpt); - fclose(fpt); + KBlockFile f; + kblockfile_init(&f, fpt, page_buffer, PAGE_SIZE, PAGE_COUNT); BattFs fd[BATTFS_MAX_FILES]; unsigned int MODE = BATTFS_CREATE; - ASSERT(disk_open(disk)); - ASSERT(battfs_mount(disk)); + ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array))); ASSERT(battfs_fsck(disk)); for (unsigned i = 0; i < countof(fd); i++) ASSERT(battfs_fileopen(disk, &fd[i], i, MODE)); @@ -1082,8 +1046,11 @@ static void openAllFiles(BattFsSuper *disk) ASSERT(battfs_fsck(disk)); ASSERT(battfs_umount(disk)); - ASSERT(disk_open(disk)); - ASSERT(battfs_mount(disk)); + + fpt = fopen(test_filename, "r+"); + kblockfile_init(&f, fpt, page_buffer, PAGE_SIZE, PAGE_COUNT); + + ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array))); ASSERT(battfs_fsck(disk)); diff --git a/test/run_tests.sh b/test/run_tests.sh index 916be6ba..be0ed430 100755 --- a/test/run_tests.sh +++ b/test/run_tests.sh @@ -33,7 +33,6 @@ SRC_LIST=" bertos/algo/ramp.c bertos/drv/kdebug.c bertos/drv/timer.c - bertos/fs/battfs.c bertos/kern/kfile.c bertos/kern/monitor.c bertos/kern/proc.c @@ -51,6 +50,7 @@ SRC_LIST=" bertos/fs/fatfs/ff.c bertos/emul/diskio_emul.c bertos/fs/fat.c + bertos/fs/battfs.c bertos/emul/switch_ctx_emul.S bertos/mware/ini_reader.c bertos/emul/kfile_posix.c @@ -62,6 +62,9 @@ SRC_LIST=" bertos/net/nmeap/src/nmeap01.c bertos/net/nmea.c bertos/cfg/kfile_debug.c + bertos/io/kblock.c + bertos/io/kblock_ram.c + bertos/io/kblock_file.c " buildout='/dev/null' -- 2.25.1