[sheepdog] [PATCH] cache: correct block size calculation for inode object
Liu Yuan
namei.unix at gmail.com
Thu Aug 8 05:43:24 CEST 2013
On Thu, Aug 08, 2013 at 12:33:23PM +0900, MORITA Kazutaka wrote:
> At Thu, 8 Aug 2013 10:02:59 +0800,
> Liu Yuan wrote:
> >
> > On Thu, Aug 08, 2013 at 06:51:22AM +0900, MORITA Kazutaka wrote:
> > > At Wed, 7 Aug 2013 16:10:01 +0800,
> > > Liu Yuan wrote:
> > > >
> > > > inode and data object have different sizes and thus cache block size is
> > > > different. Current code fail to get the right size for inode object when
> > > > its last bit of bmap is set with the fixed block size.
> > > >
> > > > This patch tries to get the dynamic block size based on the oid.
> > > >
> > > > Signed-off-by: Liu Yuan <namei.unix at gmail.com>
> > > > ---
> > > > sheep/object_cache.c | 36 ++++++++++++++++--------------------
> > > > 1 file changed, 16 insertions(+), 20 deletions(-)
> > > >
> > > > diff --git a/sheep/object_cache.c b/sheep/object_cache.c
> > > > index dcf6972..957b052 100644
> > > > --- a/sheep/object_cache.c
> > > > +++ b/sheep/object_cache.c
> > > > @@ -28,8 +28,6 @@
> > > >
> > > > #define CACHE_INDEX_MASK (CACHE_CREATE_BIT)
> > > >
> > > > -#define CACHE_BLOCK_SIZE ((UINT64_C(1) << 10) * 64) /* 64 KB */
> > > > -
> > > > #define CACHE_OBJECT_SIZE (SD_DATA_OBJ_SIZE / 1024 / 1024) /* M */
> > > >
> > > > /* Kick background pusher if dirty_count greater than it */
> > > > @@ -116,13 +114,19 @@ static inline bool idx_has_vdi_bit(uint32_t idx)
> > > > return !!(idx & CACHE_VDI_BIT);
> > > > }
> > > >
> > > > -static uint64_t calc_object_bmap(size_t len, off_t offset)
> > > > +static inline int get_cache_block_size(uint64_t oid)
> > > > +{
> > > > + return DIV_ROUND_UP(get_objsize(oid), sizeof(uint64_t) * BITS_PER_BYTE);
> > > > +}
> > >
> > > The size of cache block must be sector-aligned for O_DIRECT. I'd
> > > suggest rounding up to 4 KB boundary (the size of blocks for most
> > > filesystems) like as follows.
> > >
> > > static inline int get_cache_block_size(uint64_t oid)
> > > {
> > > int bsize = DIV_ROUND_UP(get_objsize(oid), sizeof(uint64_t) * BITS_PER_BYTE);
> > >
> > > return round_up(bsize, BLOCK_SIZE);
> > > }
> >
> > data object is aiglied, and inode object isn't. But this is problem since we
> > always drop O_DIRECT for inode object, no?
> >
> > If we round up size for inode object, we need much more code to handle last
> > block of inode object.
>
> Hmm, yes, but your code is already calling DIV_ROUND_UP(). Currently,
> it's not a problem because (get_obj_size() % 64) is always zero, but
> the size of object may change in future. Can you add some assert() to
> ensure the code correctness? I guess a better code looks like as
> follows.
>
> static inline int get_cache_block_size(uint64_t oid)
> {
> assert(get_objsize(oid) % (sizeof(uint64_t) * BITS_PER_BYTE) == 0);
This won't work. SD_INODE_SIZE can't divide 64. I think we can assume data
object is always aligned and handle partial last block of inode carefully.
Thanks
Yuan
More information about the sheepdog
mailing list