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 }