#define DATA_SIZE (PAGE_SIZE - BATTFS_HEADER_LEN)
#define PAGE_COUNT (FILE_SIZE / PAGE_SIZE)
+#define HW_PAGEBUF false
#if UNIT_TEST
const char test_filename[]="battfs_disk.bin";
ref[i] = i;
KBlockFile f;
- kblockfile_init(&f, fpt, page_buffer, PAGE_SIZE, PAGE_COUNT);
+ kblockfile_init(&f, fpt, HW_PAGEBUF, page_buffer, PAGE_SIZE, PAGE_COUNT);
battfs_mount(disk, &f.b, page_array, sizeof(page_array));
testCheck(disk, ref);
fputc(0xff, fp);
KBlockFile f;
- kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, PAGE_COUNT);
+ kblockfile_init(&f, fp, HW_PAGEBUF, page_buffer, PAGE_SIZE, PAGE_COUNT);
for (int i = 0; i < PAGE_COUNT; i++)
{
fputc(0xff, fp);
KBlockFile f;
- kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, PAGE_COUNT);
+ kblockfile_init(&f, fp, HW_PAGEBUF, page_buffer, PAGE_SIZE, PAGE_COUNT);
for (int i = 0; i < PAGE_COUNT / 2; i++)
{
for (int i = 0; i < PAGE_SIZE * 4; i++)
fputc(0xff, fp);
KBlockFile f;
- kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, 4);
+ kblockfile_init(&f, fp, HW_PAGEBUF, page_buffer, PAGE_SIZE, 4);
// page, inode, seq, fill, pgoff
battfs_writeTestBlock(&f.b, 0, 0, 0, DATA_SIZE, 0);
for (int i = 0; i < PAGE_SIZE * 4; i++)
fputc(0xff, fp);
KBlockFile f;
- kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, 4);
+ kblockfile_init(&f, fp, HW_PAGEBUF, page_buffer, PAGE_SIZE, 4);
// page, inode, seq, fill, pgoff
battfs_writeTestBlock(&f.b, 0, 0, 0, DATA_SIZE, 0);
for (int i = 0; i < PAGE_SIZE * 4; i++)
fputc(0xff, fp);
KBlockFile f;
- kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, 4);
+ kblockfile_init(&f, fp, HW_PAGEBUF, page_buffer, PAGE_SIZE, 4);
// page, inode, seq, fill, pgoff
battfs_eraseBlock(&f.b, 0);
for (int i = 0; i < PAGE_SIZE * 8; i++)
fputc(0xff, fp);
KBlockFile f;
- kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, 8);
+ kblockfile_init(&f, fp, HW_PAGEBUF, page_buffer, PAGE_SIZE, 8);
// page, inode, seq, fill, pgoff
battfs_eraseBlock(&f.b, 0);
for (int i = 0; i < PAGE_SIZE * 8; i++)
fputc(0xff, fp);
KBlockFile f;
- kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, 8);
+ kblockfile_init(&f, fp, HW_PAGEBUF, page_buffer, PAGE_SIZE, 8);
int PAGE_FILL = PAGE_SIZE - BATTFS_HEADER_LEN;
for (int i = 0; i < PAGE_SIZE * 8; i++)
fputc(0xff, fp);
KBlockFile f;
- kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, 8);
+ kblockfile_init(&f, fp, HW_PAGEBUF, page_buffer, PAGE_SIZE, 8);
unsigned int PAGE_FILL = PAGE_SIZE - BATTFS_HEADER_LEN;
for (int i = 0; i < PAGE_SIZE * 8; i++)
fputc(0xff, fp);
KBlockFile f;
- kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, 8);
+ kblockfile_init(&f, fp, HW_PAGEBUF, page_buffer, PAGE_SIZE, 8);
const unsigned int PAGE_FILL = PAGE_SIZE - BATTFS_HEADER_LEN;
inode_t INODE = 0;
for (int i = 0; i < PAGE_SIZE * 8; i++)
fputc(0xff, fp);
KBlockFile f;
- kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, 8);
+ kblockfile_init(&f, fp, HW_PAGEBUF, page_buffer, PAGE_SIZE, 8);
unsigned int PAGE_FILL = PAGE_SIZE - BATTFS_HEADER_LEN;
for (int i = 0; i < PAGE_SIZE * 8; i++)
fputc(0xff, fp);
KBlockFile f;
- kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, 8);
+ kblockfile_init(&f, fp, HW_PAGEBUF, page_buffer, PAGE_SIZE, 8);
const unsigned int PAGE_FILL = PAGE_SIZE - BATTFS_HEADER_LEN;
inode_t INODE = 0;
for (int i = 0; i < FILE_SIZE; i++)
fputc(0xff, fpt);
KBlockFile f;
- kblockfile_init(&f, fpt, page_buffer, PAGE_SIZE, PAGE_COUNT);
+ kblockfile_init(&f, fpt, HW_PAGEBUF, page_buffer, PAGE_SIZE, PAGE_COUNT);
BattFs fd1;
inode_t INODE = 0;
ASSERT(battfs_umount(disk));
fpt = fopen(test_filename, "r+");
- kblockfile_init(&f, fpt, page_buffer, PAGE_SIZE, PAGE_COUNT);
+ kblockfile_init(&f, fpt, HW_PAGEBUF, page_buffer, PAGE_SIZE, PAGE_COUNT);
ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array)));
ASSERT(battfs_fsck(disk));
for (int i = 0; i < FILE_SIZE; i++)
fputc(0xff, fpt);
KBlockFile f;
- kblockfile_init(&f, fpt, page_buffer, PAGE_SIZE, PAGE_COUNT);
+ kblockfile_init(&f, fpt, HW_PAGEBUF, page_buffer, PAGE_SIZE, PAGE_COUNT);
BattFs fd1;
ASSERT(battfs_umount(disk));
fpt = fopen(test_filename, "r+");
- kblockfile_init(&f, fpt, page_buffer, PAGE_SIZE, PAGE_COUNT);
+ kblockfile_init(&f, fpt, HW_PAGEBUF, page_buffer, PAGE_SIZE, PAGE_COUNT);
ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array)));
ASSERT(battfs_fsck(disk));
fputc(0xff, fpt);
KBlockFile f;
- kblockfile_init(&f, fpt, page_buffer, PAGE_SIZE, PAGE_COUNT / 10);
+ kblockfile_init(&f, fpt, HW_PAGEBUF, page_buffer, PAGE_SIZE, PAGE_COUNT / 10);
BattFs fd1,fd2;
for (int i = 0; i < PAGE_SIZE * 8; i++)
fputc(0xff, fp);
KBlockFile f;
- kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, 8);
+ kblockfile_init(&f, fp, HW_PAGEBUF, page_buffer, PAGE_SIZE, 8);
unsigned int PAGE_FILL = PAGE_SIZE - BATTFS_HEADER_LEN;
for (int i = 0; i < FILE_SIZE / 5; i++)
fputc(0xff, fpt);
KBlockFile f;
- kblockfile_init(&f, fpt, page_buffer, PAGE_SIZE, PAGE_COUNT / 5);
+ kblockfile_init(&f, fpt, HW_PAGEBUF, page_buffer, PAGE_SIZE, PAGE_COUNT / 5);
BattFs fd1;
inode_t INODE = 0;
for (int i = 0; i < PAGE_SIZE * 4; i++)
fputc(0xff, fp);
KBlockFile f;
- kblockfile_init(&f, fp, page_buffer, PAGE_SIZE, 4);
+ kblockfile_init(&f, fp, HW_PAGEBUF, page_buffer, PAGE_SIZE, 4);
unsigned int PAGE_FILL = PAGE_SIZE - BATTFS_HEADER_LEN;
inode_t INODE = 0;
for (int i = 0; i < FILE_SIZE; i++)
fputc(0xff, fpt);
KBlockFile f;
- kblockfile_init(&f, fpt, page_buffer, PAGE_SIZE, PAGE_COUNT);
+ kblockfile_init(&f, fpt, HW_PAGEBUF, page_buffer, PAGE_SIZE, PAGE_COUNT);
#define N_FILES 10
BattFs fd[N_FILES];
ASSERT(battfs_umount(disk));
fpt = fopen(test_filename, "r+");
- kblockfile_init(&f, fpt, page_buffer, PAGE_SIZE, PAGE_COUNT);
+ kblockfile_init(&f, fpt, HW_PAGEBUF, page_buffer, PAGE_SIZE, PAGE_COUNT);
ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array)));
ASSERT(battfs_fsck(disk));
for (int i = 0; i < FILE_SIZE; i++)
fputc(0xff, fpt);
KBlockFile f;
- kblockfile_init(&f, fpt, page_buffer, PAGE_SIZE, PAGE_COUNT);
+ kblockfile_init(&f, fpt, HW_PAGEBUF, page_buffer, PAGE_SIZE, PAGE_COUNT);
BattFs fd[BATTFS_MAX_FILES];
unsigned int MODE = BATTFS_CREATE;
fpt = fopen(test_filename, "r+");
- kblockfile_init(&f, fpt, page_buffer, PAGE_SIZE, PAGE_COUNT);
+ kblockfile_init(&f, fpt, HW_PAGEBUF, page_buffer, PAGE_SIZE, PAGE_COUNT);
ASSERT(battfs_mount(disk, &f.b, page_array, sizeof(page_array)));
ASSERT(battfs_fsck(disk));
{
KBlockFile *f = KBLOCKFILE_CAST(b);
fseek(f->fp, index * b->blk_size, SEEK_SET);
- return (fread(f->pagebuf, 1, b->blk_size, f->fp) == b->blk_size) ? 0 : EOF;
+ return (fread(f->b.priv.buf, 1, b->blk_size, f->fp) == b->blk_size) ? 0 : EOF;
}
static int kblockfile_store(struct KBlock *b, block_idx_t index)
{
KBlockFile *f = KBLOCKFILE_CAST(b);
fseek(f->fp, index * b->blk_size, SEEK_SET);
- return (fwrite(f->pagebuf, 1, b->blk_size, f->fp) == b->blk_size) ? 0 : EOF;
+ return (fwrite(f->b.priv.buf, 1, b->blk_size, f->fp) == b->blk_size) ? 0 : EOF;
}
static size_t kblockfile_readBuf(struct KBlock *b, void *buf, size_t offset, size_t size)
{
KBlockFile *f = KBLOCKFILE_CAST(b);
- memcpy(buf, f->pagebuf + offset, size);
+ memcpy(buf, (uint8_t *)f->b.priv.buf + offset, size);
return size;
}
static size_t kblockfile_writeBuf(struct KBlock *b, const void *buf, size_t offset, size_t size)
{
KBlockFile *f = KBLOCKFILE_CAST(b);
- memcpy(f->pagebuf + offset, buf, size);
+ memcpy((uint8_t *)f->b.priv.buf + offset, buf, size);
return size;
}
+static int kblockfile_writeBlock(struct KBlock *b, block_idx_t index, const void *buf)
+{
+ KBlockFile *f = KBLOCKFILE_CAST(b);
+ ASSERT(buf);
+ ASSERT(index < b->blk_cnt);
+ fseek(f->fp, index * b->blk_size, SEEK_SET);
+ return (fwrite(f->b.priv.buf, 1, b->blk_size, f->fp) == b->blk_size) ? 0 : EOF;
+}
+
+static int kblockfile_readBlock(struct KBlock *b, block_idx_t index, void *buf)
+{
+ KBlockFile *f = KBLOCKFILE_CAST(b);
+ ASSERT(buf);
+ ASSERT(index < b->blk_cnt);
+ fseek(f->fp, index * b->blk_size, SEEK_SET);
+ return (fread(f->b.priv.buf, 1, b->blk_size, f->fp) == b->blk_size) ? 0 : EOF;
+}
+
static int kblockfile_error(struct KBlock *b)
{
KBlockFile *f = KBLOCKFILE_CAST(b);
}
-static KBlockVTable kblockfile_vt =
+static const KBlockVTable kblockfile_hwbuffered_vt =
{
.readDirect = kblockfile_readDirect,
.readBuf = kblockfile_readBuf,
.writeBuf = kblockfile_writeBuf,
.load = kblockfile_load,
.store = kblockfile_store,
+
+ .readBlock = kblock_swReadBlock,
+ .writeBlock = kblock_swWriteBlock,
+
+ .error = kblockfile_error,
+ .clearerr = kblockfile_claererr,
+ .close = kblockfile_close,
+};
+
+static const KBlockVTable kblockfile_swbuffered_vt =
+{
+ .readDirect = kblock_swReadDirect,
+ .readBuf = kblock_swReadBuf,
+ .writeBuf = kblock_swWriteBuf,
+ .load = kblock_swLoad,
+ .store = kblock_swStore,
+
+ .readBlock = kblockfile_readBlock,
+ .writeBlock =kblockfile_writeBlock,
+
+ .error = kblockfile_error,
+ .clearerr = kblockfile_claererr,
+ .close = kblockfile_close,
+};
+
+static const KBlockVTable kblockfile_unbuffered_vt =
+{
+ .readBlock = kblockfile_readBlock,
+ .writeBlock =kblockfile_writeBlock,
.error = kblockfile_error,
.clearerr = kblockfile_claererr,
};
-void kblockfile_init(KBlockFile *f, FILE *fp, void *buf, size_t block_size, block_idx_t block_count)
+
+void kblockfile_init(KBlockFile *f, FILE *fp, bool hwbuf, void *buf, size_t block_size, block_idx_t block_count)
{
ASSERT(f);
ASSERT(fp);
- ASSERT(buf);
ASSERT(block_size);
memset(f, 0, sizeof(*f));
DB(f->b.priv.type = KBT_KBLOCKFILE);
f->fp = fp;
- f->pagebuf = buf;
f->b.blk_size = block_size;
f->b.blk_cnt = block_count;
- f->b.priv.vt = &kblockfile_vt;
- kblockfile_load(&f->b, 0);
- f->b.priv.curr_blk = 0;
- f->b.priv.cache_dirty = false;
+
+ if (buf)
+ {
+ f->b.priv.flags |= KB_BUFFERED;
+ f->b.priv.buf = buf;
+ if (hwbuf)
+ f->b.priv.vt = &kblockfile_hwbuffered_vt;
+ else
+ f->b.priv.vt = &kblockfile_swbuffered_vt;
+ kblockfile_load(&f->b, 0);
+ f->b.priv.curr_blk = 0;
+ f->b.priv.cache_dirty = false;
+ }
+ else
+ f->b.priv.vt = &kblockfile_unbuffered_vt;
}
{
KBlock b;
FILE *fp;
- uint8_t *pagebuf;
} KBlockFile;
#define KBT_KBLOCKFILE MAKE_ID('K', 'B', 'F', 'L')
return (KBlockFile *)b;
}
-void kblockfile_init(KBlockFile *f, FILE *fp, void *buf, size_t block_size, block_idx_t block_count);
+void kblockfile_init(KBlockFile *f, FILE *fp, bool hwbuf, void *buf, size_t block_size, block_idx_t block_count);
#endif /* KBLOCK_FILE_H */
static int kblockram_load(KBlock *b, block_idx_t index)
{
KBlockRam *r = KBLOCKRAM_CAST(b);
- memcpy(r->pagebuf, r->membuf + index * r->b.blk_size, r->b.blk_size);
+ memcpy(r->b.priv.buf, r->membuf + index * r->b.blk_size, r->b.blk_size);
return 0;
}
static int kblockram_store(struct KBlock *b, block_idx_t index)
{
KBlockRam *r = KBLOCKRAM_CAST(b);
- memcpy(r->membuf + index * r->b.blk_size, r->pagebuf, r->b.blk_size);
+ memcpy(r->membuf + index * r->b.blk_size, r->b.priv.buf, r->b.blk_size);
return 0;
}
static size_t kblockram_readBuf(struct KBlock *b, void *buf, size_t offset, size_t size)
{
KBlockRam *r = KBLOCKRAM_CAST(b);
- memcpy(buf, r->pagebuf + offset, size);
+ memcpy(buf, (uint8_t *)r->b.priv.buf + offset, size);
return size;
}
static size_t kblockram_writeBuf(struct KBlock *b, const void *buf, size_t offset, size_t size)
{
KBlockRam *r = KBLOCKRAM_CAST(b);
- memcpy(r->pagebuf + offset, buf, size);
+ memcpy((uint8_t *)r->b.priv.buf + offset, buf, size);
return size;
}
-static int kblockram_error(struct KBlock *b)
+static int kblockram_writeBlock(struct KBlock *b, block_idx_t index, const void *buf)
{
- return b->priv.flags;
+ KBlockRam *r = KBLOCKRAM_CAST(b);
+ ASSERT(buf);
+ ASSERT(index < b->blk_cnt);
+
+ memcpy(r->membuf + index * r->b.blk_size, buf, r->b.blk_size);
+ return 0;
+}
+
+static int kblockram_readBlock(struct KBlock *b, block_idx_t index, void *buf)
+{
+ KBlockRam *r = KBLOCKRAM_CAST(b);
+ ASSERT(buf);
+ ASSERT(index < b->blk_cnt);
+
+ memcpy(buf, r->membuf + index * r->b.blk_size, r->b.blk_size);
+ return 0;
}
static int kblockram_dummy(UNUSED_ARG(struct KBlock *,b))
return 0;
}
-static KBlockVTable kblockram_vt =
+static const KBlockVTable kblockram_hwbuffered_vt =
{
.readDirect = kblockram_readDirect,
.readBuf = kblockram_readBuf,
.writeBuf = kblockram_writeBuf,
.load = kblockram_load,
.store = kblockram_store,
+
+ .readBlock = kblock_swReadBlock,
+ .writeBlock = kblock_swWriteBlock,
+
+ .error = kblockram_dummy,
+ .clearerr = kblockram_dummy,
+ .close = kblockram_dummy,
+};
+
+
+static const KBlockVTable kblockram_swbuffered_vt =
+{
+ .readDirect = kblock_swReadDirect,
+ .readBuf = kblock_swReadBuf,
+ .writeBuf = kblock_swWriteBuf,
+ .load = kblock_swLoad,
+ .store = kblock_swStore,
+
+ .readBlock = kblockram_readBlock,
+ .writeBlock = kblockram_writeBlock,
+
+ .error = kblockram_dummy,
+ .clearerr = kblockram_dummy,
+ .close = kblockram_dummy,
+};
- .error = kblockram_error,
+static const KBlockVTable kblockram_unbuffered_vt =
+{
+ .readBlock = kblockram_readBlock,
+ .writeBlock = kblockram_writeBlock,
+
+ .error = kblockram_dummy,
.clearerr = kblockram_dummy,
.close = kblockram_dummy,
};
-void kblockram_init(KBlockRam *ram, void *buf, size_t size, size_t block_size)
+void kblockram_init(KBlockRam *ram, void *buf, size_t size, size_t block_size, bool buffered, bool hwbuffered)
{
ASSERT(buf);
ASSERT(size);
memset(ram, 0, sizeof(*ram));
DB(ram->b.priv.type = KBT_KBLOCKRAM);
-
- // First page used as page buffer
- ram->b.blk_cnt = (size / block_size) - 1;
- ram->pagebuf = (uint8_t *)buf;
- ram->membuf = (uint8_t *)buf + block_size;
ram->b.blk_size = block_size;
- ram->b.priv.vt = &kblockram_vt;
- kblockram_load(&ram->b, 0);
+
+ if (buffered)
+ {
+ ram->b.priv.flags |= KB_BUFFERED;
+ ram->b.blk_cnt = (size / block_size) - 1;
+ ram->b.priv.buf = buf;
+ // First page used as page buffer
+ ram->membuf = (uint8_t *)buf + block_size;
+
+ if (hwbuffered)
+ ram->b.priv.vt = &kblockram_hwbuffered_vt;
+ else
+ ram->b.priv.vt = &kblockram_swbuffered_vt;
+
+ kblockram_load(&ram->b, 0);
+ }
+ else
+ {
+ ram->b.blk_cnt = (size / block_size);
+ ram->membuf = (uint8_t *)buf;
+ ram->b.priv.vt = &kblockram_unbuffered_vt;
+ }
}
typedef struct KBlockRam
{
KBlock b;
- uint8_t *pagebuf;
uint8_t *membuf;
} KBlockRam;
return (KBlockRam *)b;
}
-void kblockram_init(KBlockRam *ram, void *buf, size_t size, size_t block_size);
+void kblockram_init(KBlockRam *ram, void *buf, size_t size, size_t block_size, bool buffered, bool hwbuffered);
#endif /* KBLOCK_RAM_H */