reblock.c
Go to the documentation of this file.
00001
00045 #include "reblock.h"
00046 #include <string.h> /* memset */
00047
00048
00049 static size_t reblock_readDirect(struct KBlock *b, block_idx_t idx, void *buf, size_t offset, size_t size)
00050 {
00051     Reblock *r = REBLOCK_CAST(b);
00052
00053     offset += idx % (r->native_fd->blk_size / r->fd.blk_size) * r->fd.blk_size;
00054     idx    =  idx / (r->native_fd->blk_size / r->fd.blk_size);
00055
00056     return kblock_read(r->native_fd, idx, buf, offset, size);
00057 }
00058
00059
00060 static size_t reblock_writeDirect(struct KBlock *b, block_idx_t idx, const void *buf, size_t offset, size_t size)
00061 {
00062     Reblock *r = REBLOCK_CAST(b);
00063
00064     offset += idx % (r->native_fd->blk_size / r->fd.blk_size) * r->fd.blk_size;
00065     idx    =  idx / (r->native_fd->blk_size / r->fd.blk_size);
00066
00067     return kblock_write(r->native_fd, idx, buf, offset, size);
00068 }
00069
00070
00071 static int reblock_error(struct KBlock *b)
00072 {
00073     return kblock_error(REBLOCK_CAST(b)->native_fd);
00074 }
00075
00076 static void reblock_clearerr(struct KBlock *b)
00077 {
00078     kblock_clearerr(REBLOCK_CAST(b)->native_fd);
00079 }
00080
00081 static int reblock_close(struct KBlock *b)
00082 {
00083     return kblock_close(REBLOCK_CAST(b)->native_fd);
00084 }
00085
00086
00087 static const KBlockVTable reblock_vt =
00088 {
00089     .readDirect = reblock_readDirect,
00090     .writeDirect = reblock_writeDirect,
00091
00092     .error = reblock_error,
00093     .clearerr = reblock_clearerr,
00094     .close = reblock_close,
00095 };
00096
00097
00098 /*
00099  * Initialize reblock device.
00100  *
00101  * \param rbl           kblock reblock device
00102  * \param native_fd     kblock descriptor of the reblocked device
00103  * \param new_blk_size  new block size to export
00104  *
00105  * \note new block size is required to be a submultiple of the
00106  *       native device block size.
00107  */
00108 void reblock_init(Reblock *rbl, KBlock *native_fd, size_t new_blk_size)
00109 {
00110     ASSERT(new_blk_size);
00111     ASSERT(new_blk_size < native_fd->blk_size);
00112     ASSERT(native_fd->blk_size % new_blk_size == 0);
00113     ASSERT(kblock_buffered(native_fd) || kblock_partialWrite(native_fd));
00114
00115     memset(rbl, 0, sizeof(Reblock));
00116
00117     DB(rbl->fd.priv.type = KBT_REBLOCK);
00118
00119     rbl->fd.blk_size = new_blk_size;
00120     rbl->fd.blk_cnt = native_fd->blk_cnt * (native_fd->blk_size / new_blk_size);
00121
00122     rbl->fd.priv.flags |= KB_PARTIAL_WRITE;
00123     rbl->fd.priv.vt = &reblock_vt;
00124
00125     rbl->native_fd = native_fd;
00126 }