From: aleph Date: Sun, 8 May 2011 09:46:10 +0000 (+0000) Subject: New module: KBlock block size reducer X-Git-Tag: 2.7.0~85 X-Git-Url: https://codewiz.org/gitweb?a=commitdiff_plain;ds=sidebyside;h=2904768328f5d938e6c401efbcbedc24dce26958;p=bertos.git New module: KBlock block size reducer Allows access to a KBlock device using a smaller block size than the native one exported by the device. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@4881 38d2e660-2303-0410-9eaa-f027e97ec537 --- diff --git a/bertos/io/reblock.c b/bertos/io/reblock.c new file mode 100644 index 00000000..3c5009ca --- /dev/null +++ b/bertos/io/reblock.c @@ -0,0 +1,126 @@ +/** + * \file + * + * + * \brief KBlock block size reducer + * + * This module allows access to a KBlock device using a smaller block + * size than the native one exported by the device. + * Note that the device being remapped needs either to be opened in buffered + * mode or to support partial writes. + * + * \author Stefano Fedrigo + * + * $WIZ$ module_depends = "kblock" + */ + +#include "reblock.h" +#include /* memset */ + + +static size_t reblock_readDirect(struct KBlock *b, block_idx_t idx, void *buf, size_t offset, size_t size) +{ + Reblock *r = REBLOCK_CAST(b); + + offset += idx % (r->native_fd->blk_size / r->fd.blk_size) * r->fd.blk_size; + idx = idx / (r->native_fd->blk_size / r->fd.blk_size); + + return kblock_read(r->native_fd, idx, buf, offset, size); +} + + +static size_t reblock_writeDirect(struct KBlock *b, block_idx_t idx, const void *buf, size_t offset, size_t size) +{ + Reblock *r = REBLOCK_CAST(b); + + offset += idx % (r->native_fd->blk_size / r->fd.blk_size) * r->fd.blk_size; + idx = idx / (r->native_fd->blk_size / r->fd.blk_size); + + return kblock_write(r->native_fd, idx, buf, offset, size); +} + + +static int reblock_error(struct KBlock *b) +{ + return kblock_error(REBLOCK_CAST(b)->native_fd); +} + +static void reblock_clearerr(struct KBlock *b) +{ + kblock_clearerr(REBLOCK_CAST(b)->native_fd); +} + +static int reblock_close(struct KBlock *b) +{ + return kblock_close(REBLOCK_CAST(b)->native_fd); +} + + +static const KBlockVTable reblock_vt = +{ + .readDirect = reblock_readDirect, + .writeDirect = reblock_writeDirect, + + .error = reblock_error, + .clearerr = reblock_clearerr, + .close = reblock_close, +}; + + +/* + * Initialize reblock device. + * + * \param rbl kblock reblock device + * \param native_fd kblock descriptor of the reblocked device + * \param new_blk_size new block size to export + * + * \note new block size is required to be a submultiple of the + * native device block size. + */ +void reblock_init(Reblock *rbl, KBlock *native_fd, size_t new_blk_size) +{ + ASSERT(new_blk_size); + ASSERT(new_blk_size < native_fd->blk_size); + ASSERT(native_fd->blk_size % new_blk_size == 0); + ASSERT(kblock_buffered(native_fd) || kblock_partialWrite(native_fd)); + + memset(rbl, 0, sizeof(Reblock)); + + DB(rbl->fd.priv.type = KBT_REBLOCK); + + rbl->fd.blk_size = new_blk_size; + rbl->fd.blk_cnt = native_fd->blk_cnt * (native_fd->blk_size / new_blk_size); + + rbl->fd.priv.flags |= KB_PARTIAL_WRITE; + rbl->fd.priv.vt = &reblock_vt; + + rbl->native_fd = native_fd; +} diff --git a/bertos/io/reblock.h b/bertos/io/reblock.h new file mode 100644 index 00000000..c692ef19 --- /dev/null +++ b/bertos/io/reblock.h @@ -0,0 +1,61 @@ +/** + * \file + * + * + * \brief KBlock block size reducer + * + * \author Stefano Fedrigo + */ + +#ifndef REBLOCK_H +#define REBLOCK_H + +#include "kblock.h" + + +typedef struct Reblock +{ + KBlock fd; + KBlock *native_fd; +} Reblock; + +#define KBT_REBLOCK MAKE_ID('R', 'E', 'B', 'L') + + +INLINE Reblock *REBLOCK_CAST(KBlock *b) +{ + ASSERT(b->priv.type == KBT_REBLOCK); + return (Reblock *)b; +} + +void reblock_init(Reblock *rbl, KBlock *native_fd, size_t native_blk_size); + +#endif /* REBLOCK_H */