From 66754b6bb7b736b987ea8bf2eef702f8f69cf329 Mon Sep 17 00:00:00 2001 From: Ryusuke Konishi Date: Sun, 25 Sep 2016 22:37:59 +0900 Subject: [PATCH] lib/segment: refactor file/block iterator Rewrite nilfs_file/nilfs_block structs and their iterators to clarify them. Signed-off-by: Ryusuke Konishi --- bin/dumpseg.c | 23 +++--- include/segment.h | 87 +++++++++++----------- lib/gc.c | 16 ++-- lib/segment.c | 181 +++++++++++++++++++++++++--------------------- 4 files changed, 163 insertions(+), 144 deletions(-) diff --git a/bin/dumpseg.c b/bin/dumpseg.c index d4b1123..0acd8a9 100644 --- a/bin/dumpseg.c +++ b/bin/dumpseg.c @@ -111,48 +111,49 @@ static void dumpseg_print_psegment_error(const struct nilfs_psegment *pseg, static void dumpseg_print_virtual_block(struct nilfs_block *blk) { - __le64 *binfo = blk->b_binfo; + __le64 *binfo = blk->binfo; if (nilfs_block_is_data(blk)) { printf(" vblocknr = %llu, blkoff = %llu, blocknr = %llu\n", (unsigned long long)le64_to_cpu(binfo[0]), (unsigned long long)le64_to_cpu(binfo[1]), - (unsigned long long)blk->b_blocknr); + (unsigned long long)blk->blocknr); } else { printf(" vblocknr = %llu, blocknr = %llu\n", (unsigned long long)le64_to_cpu(binfo[0]), - (unsigned long long)blk->b_blocknr); + (unsigned long long)blk->blocknr); } } static void dumpseg_print_real_block(struct nilfs_block *blk) { if (nilfs_block_is_data(blk)) { - __le64 *binfo = blk->b_binfo; + __le64 *binfo = blk->binfo; printf(" blkoff = %llu, blocknr = %llu\n", (unsigned long long)le64_to_cpu(binfo[0]), - (unsigned long long)blk->b_blocknr); + (unsigned long long)blk->blocknr); } else { - struct nilfs_binfo_dat *bid = blk->b_binfo; + struct nilfs_binfo_dat *bid = blk->binfo; printf(" blkoff = %llu, level = %d, blocknr = %llu\n", (unsigned long long)le64_to_cpu(bid->bi_blkoff), bid->bi_level, - (unsigned long long)blk->b_blocknr); + (unsigned long long)blk->blocknr); } } static void dumpseg_print_file(struct nilfs_file *file) { struct nilfs_block blk; + struct nilfs_finfo *finfo = file->finfo; printf(" finfo\n"); printf(" ino = %llu, cno = %llu, nblocks = %d, ndatblk = %d\n", - (unsigned long long)le64_to_cpu(file->f_finfo->fi_ino), - (unsigned long long)le64_to_cpu(file->f_finfo->fi_cno), - le32_to_cpu(file->f_finfo->fi_nblocks), - le32_to_cpu(file->f_finfo->fi_ndatablk)); + (unsigned long long)le64_to_cpu(finfo->fi_ino), + (unsigned long long)le64_to_cpu(finfo->fi_cno), + le32_to_cpu(finfo->fi_nblocks), + le32_to_cpu(finfo->fi_ndatablk)); if (!nilfs_file_use_real_blocknr(file)) { nilfs_block_for_each(&blk, file) { dumpseg_print_virtual_block(&blk); diff --git a/include/segment.h b/include/segment.h index 82c58c2..ef953d2 100644 --- a/include/segment.h +++ b/include/segment.h @@ -47,40 +47,46 @@ enum { /** * struct nilfs_file - file iterator - * @f_finfo: file information - * @f_blocknr: block number - * @f_offset: byte offset from the beginning of segment - * @f_index: index - * @f_psegment: partial segment + * @psegment: back pointer to nilfs_psegment struct + * @finfo: file information + * @blocknr: block number + * @offset: byte offset from the beginning of partial segment + * @index: index number of finfo + * @nfinfo: number of finfo structures contained in the partial segment + * @use_real_blocknr: flag to indicate that blocks are not tranlated with DAT */ struct nilfs_file { - struct nilfs_finfo *f_finfo; - sector_t f_blocknr; - - unsigned long f_offset; - int f_index; - const struct nilfs_psegment *f_psegment; + const struct nilfs_psegment *psegment; + struct nilfs_finfo *finfo; + sector_t blocknr; + __u32 offset; + __u32 index; + __u32 nfinfo; + unsigned int use_real_blocknr : 1; }; /** * struct nilfs_block - block iterator - * @b_binfo: block information - * @b_blocknr: block number - * @b_offset: byte offset from the beginning of segment - * @b_index: index - * @b_dsize: size of data block information - * @b_nsize: size of node block information - * @b_file: file + * @file: back pointer to nilfs_file struct + * @binfo: block information + * @blocknr: block number + * @offset: byte offset from the beginning of partial segment + * @index: index number of binfo + * @nbinfo: number of binfo structures contained in the file + * @nbinfo_data: number of binfos for data blocks + * @dsize: size of data block information + * @nsize: size of node block information */ struct nilfs_block { - void *b_binfo; - sector_t b_blocknr; - - unsigned long b_offset; - int b_index; - size_t b_dsize; - size_t b_nsize; - const struct nilfs_file *b_file; + const struct nilfs_file *file; + void *binfo; + sector_t blocknr; + __u32 offset; + __u32 index; + __u32 nbinfo; + __u32 nbinfo_data; + unsigned int dsize; + unsigned int nsize; }; /* virtual block number and block offset */ @@ -119,38 +125,37 @@ static inline int nilfs_psegment_is_error(const struct nilfs_psegment *pseg, } /* file iterator */ -void nilfs_file_init(struct nilfs_file *, const struct nilfs_psegment *); -int nilfs_file_is_end(const struct nilfs_file *); -void nilfs_file_next(struct nilfs_file *); +void nilfs_file_init(struct nilfs_file *file, + const struct nilfs_psegment *pseg); +int nilfs_file_is_end(struct nilfs_file *file); +void nilfs_file_next(struct nilfs_file *file); static inline int nilfs_file_use_real_blocknr(const struct nilfs_file *file) { - return le64_to_cpu(file->f_finfo->fi_ino) == NILFS_DAT_INO; + return file->use_real_blocknr; } -#define nilfs_file_for_each(file, pseg) \ - for (nilfs_file_init(file, pseg); \ - !nilfs_file_is_end(file); \ +#define nilfs_file_for_each(file, pseg) \ + for (nilfs_file_init(file, pseg); !nilfs_file_is_end(file); \ nilfs_file_next(file)) /* block iterator */ -void nilfs_block_init(struct nilfs_block *, const struct nilfs_file *); -int nilfs_block_is_end(const struct nilfs_block *); -void nilfs_block_next(struct nilfs_block *); +void nilfs_block_init(struct nilfs_block *blk, const struct nilfs_file *file); +int nilfs_block_is_end(const struct nilfs_block *blk); +void nilfs_block_next(struct nilfs_block *blk); static inline int nilfs_block_is_data(const struct nilfs_block *blk) { - return blk->b_index < le32_to_cpu(blk->b_file->f_finfo->fi_ndatablk); + return blk->index < blk->nbinfo_data; } static inline int nilfs_block_is_node(const struct nilfs_block *blk) { - return blk->b_index >= le32_to_cpu(blk->b_file->f_finfo->fi_ndatablk); + return blk->index >= blk->nbinfo_data; } -#define nilfs_block_for_each(blk, file) \ - for (nilfs_block_init(blk, file); \ - !nilfs_block_is_end(blk); \ +#define nilfs_block_for_each(blk, file) \ + for (nilfs_block_init(blk, file); !nilfs_block_is_end(blk); \ nilfs_block_next(blk)) diff --git a/lib/gc.c b/lib/gc.c index 1b0913b..50ad6cd 100644 --- a/lib/gc.c +++ b/lib/gc.c @@ -121,36 +121,36 @@ static int nilfs_acc_blocks_file(struct nilfs_file *file, ino_t ino; nilfs_cno_t cno; - ino = le64_to_cpu(file->f_finfo->fi_ino); + ino = le64_to_cpu(file->finfo->fi_ino); if (nilfs_file_use_real_blocknr(file)) { nilfs_block_for_each(&blk, file) { bdesc = nilfs_vector_get_new_element(bdescv); if (unlikely(bdesc == NULL)) return -1; bdesc->bd_ino = ino; - bdesc->bd_oblocknr = blk.b_blocknr; + bdesc->bd_oblocknr = blk.blocknr; if (nilfs_block_is_data(&blk)) { bdesc->bd_offset = - le64_to_cpu(*(__le64 *)blk.b_binfo); + le64_to_cpu(*(__le64 *)blk.binfo); bdesc->bd_level = 0; } else { - binfo = blk.b_binfo; + binfo = blk.binfo; bdesc->bd_offset = le64_to_cpu(binfo->bi_dat.bi_blkoff); bdesc->bd_level = binfo->bi_dat.bi_level; } } } else { - cno = le64_to_cpu(file->f_finfo->fi_cno); + cno = le64_to_cpu(file->finfo->fi_cno); nilfs_block_for_each(&blk, file) { vdesc = nilfs_vector_get_new_element(vdescv); if (unlikely(vdesc == NULL)) return -1; vdesc->vd_ino = ino; vdesc->vd_cno = cno; - vdesc->vd_blocknr = blk.b_blocknr; + vdesc->vd_blocknr = blk.blocknr; if (nilfs_block_is_data(&blk)) { - binfo = blk.b_binfo; + binfo = blk.binfo; vdesc->vd_vblocknr = le64_to_cpu(binfo->bi_v.bi_vblocknr); vdesc->vd_offset = @@ -158,7 +158,7 @@ static int nilfs_acc_blocks_file(struct nilfs_file *file, vdesc->vd_flags = 0; /* data */ } else { vdesc->vd_vblocknr = - le64_to_cpu(*(__le64 *)blk.b_binfo); + le64_to_cpu(*(__le64 *)blk.binfo); vdesc->vd_flags = 1; /* node */ } } diff --git a/lib/segment.c b/lib/segment.c index aa6f9a2..3cc8224 100644 --- a/lib/segment.c +++ b/lib/segment.c @@ -123,136 +123,149 @@ const char *nilfs_psegment_strerror(int errnum) } /* nilfs_file */ -void nilfs_file_init(struct nilfs_file *file, - const struct nilfs_psegment *pseg) +static int nilfs_finfo_use_real_blocknr(const struct nilfs_finfo *finfo) { - size_t blksize, rest, hdrsize; + return le64_to_cpu(finfo->fi_ino) == NILFS_DAT_INO; +} - file->f_psegment = pseg; - blksize = 1UL << pseg->blkbits; - hdrsize = le16_to_cpu(pseg->segsum->ss_bytes); +static void nilfs_file_adjust_finfo_position(struct nilfs_file *file, + __u32 blksize) +{ + __u32 rest = blksize - (file->offset & (blksize - 1)); - file->f_finfo = (void *)pseg->segsum + hdrsize; - file->f_blocknr = pseg->blocknr + - DIV_ROUND_UP(le32_to_cpu(pseg->segsum->ss_sumbytes), blksize); - file->f_index = 0; - file->f_offset = hdrsize; - - rest = blksize - file->f_offset % blksize; if (sizeof(struct nilfs_finfo) > rest) { - file->f_finfo = (void *)file->f_finfo + rest; - file->f_offset += rest; + file->finfo = (void *)file->finfo + rest; + file->offset += rest; } } -int nilfs_file_is_end(const struct nilfs_file *file) +void nilfs_file_init(struct nilfs_file *file, + const struct nilfs_psegment *pseg) { - return file->f_index >= - le32_to_cpu(file->f_psegment->segsum->ss_nfinfo); + const __u32 blksize = 1UL << pseg->blkbits; + unsigned int hdrsize; + + file->psegment = pseg; + file->blocknr = pseg->blocknr + + ((le32_to_cpu(pseg->segsum->ss_sumbytes) + blksize - 1) >> + pseg->blkbits); + file->index = 0; + file->nfinfo = le32_to_cpu(pseg->segsum->ss_nfinfo); + + hdrsize = le16_to_cpu(pseg->segsum->ss_bytes); + file->offset = hdrsize; + file->finfo = (void *)pseg->segsum + hdrsize; + nilfs_file_adjust_finfo_position(file, blksize); + + file->use_real_blocknr = nilfs_finfo_use_real_blocknr(file->finfo); } -static size_t nilfs_binfo_total_size(unsigned long offset, - size_t blksize, size_t bisize, size_t n) +int nilfs_file_is_end(struct nilfs_file *file) { - size_t binfo_per_block, rest = blksize - offset % blksize; + return file->index >= file->nfinfo; +} - if (bisize * n <= rest) - return bisize * n; +static size_t nilfs_binfo_total_size(size_t offset, __u32 blksize, + unsigned int binfosize, __u32 blkcnt) +{ + __u32 rest, binfo_per_block; - n -= rest / bisize; - binfo_per_block = blksize / bisize; - return rest + (n / binfo_per_block) * blksize + - (n % binfo_per_block) * bisize; + rest = blksize - (offset & (blksize - 1)); + if (binfosize * blkcnt <= rest) + return binfosize * blkcnt; + + blkcnt -= rest / binfosize; + binfo_per_block = blksize / binfosize; + return rest + (size_t)(blkcnt / binfo_per_block) * blksize + + (blkcnt % binfo_per_block) * binfosize; } void nilfs_file_next(struct nilfs_file *file) { - size_t blksize, rest, delta; - size_t dsize, nsize; - unsigned long ndatablk, nblocks; + const __u32 blksize = 1UL << file->psegment->blkbits; + const __u32 nblocks = le32_to_cpu(file->finfo->fi_nblocks); + unsigned int dsize, nsize; + __u32 ndatablk; + size_t delta; - blksize = 1UL << file->f_psegment->blkbits; + file->blocknr += nblocks; - if (!nilfs_file_use_real_blocknr(file)) { - dsize = NILFS_BINFO_DATA_SIZE; - nsize = NILFS_BINFO_NODE_SIZE; - } else { + if (file->use_real_blocknr) { dsize = NILFS_BINFO_DAT_DATA_SIZE; nsize = NILFS_BINFO_DAT_NODE_SIZE; + } else { + dsize = NILFS_BINFO_DATA_SIZE; + nsize = NILFS_BINFO_NODE_SIZE; } - nblocks = le32_to_cpu(file->f_finfo->fi_nblocks); - ndatablk = le32_to_cpu(file->f_finfo->fi_ndatablk); - + ndatablk = le32_to_cpu(file->finfo->fi_ndatablk); delta = sizeof(struct nilfs_finfo); - delta += nilfs_binfo_total_size(file->f_offset + delta, + delta += nilfs_binfo_total_size(file->offset + delta, blksize, dsize, ndatablk); - delta += nilfs_binfo_total_size(file->f_offset + delta, + delta += nilfs_binfo_total_size(file->offset + delta, blksize, nsize, nblocks - ndatablk); - file->f_blocknr += nblocks; - file->f_offset += delta; - file->f_finfo = (void *)file->f_finfo + delta; + file->offset += delta; + file->finfo = (void *)file->finfo + delta; + nilfs_file_adjust_finfo_position(file, blksize); - rest = blksize - file->f_offset % blksize; - if (sizeof(struct nilfs_finfo) > rest) { - file->f_offset += rest; - file->f_finfo = (void *)file->f_finfo + rest; - } - file->f_index++; + file->use_real_blocknr = nilfs_finfo_use_real_blocknr(file->finfo); + file->index++; } /* nilfs_block */ +static void nilfs_block_adjust_binfo_position(struct nilfs_block *blk, + __u32 blksize) +{ + unsigned int binfosize; + __u32 rest; + + rest = blksize - (blk->offset & (blksize - 1)); + binfosize = nilfs_block_is_data(blk) ? blk->dsize : blk->nsize; + if (binfosize > rest) { + blk->binfo += rest; + blk->offset += rest; + } +} + void nilfs_block_init(struct nilfs_block *blk, const struct nilfs_file *file) { - size_t blksize, bisize, rest; + const __u32 blksize = 1UL << file->psegment->blkbits; - blk->b_file = file; - blksize = 1UL << blk->b_file->f_psegment->blkbits; + blk->file = file; + blk->binfo = (void *)file->finfo + sizeof(struct nilfs_finfo); + blk->offset = file->offset + sizeof(struct nilfs_finfo); + blk->blocknr = file->blocknr; + blk->index = 0; + blk->nbinfo = le32_to_cpu(file->finfo->fi_nblocks); + blk->nbinfo_data = le32_to_cpu(file->finfo->fi_ndatablk); - blk->b_binfo = (void *)(file->f_finfo + 1); - blk->b_offset = file->f_offset + sizeof(struct nilfs_finfo); - blk->b_blocknr = file->f_blocknr; - blk->b_index = 0; - if (!nilfs_file_use_real_blocknr(file)) { - blk->b_dsize = NILFS_BINFO_DATA_SIZE; - blk->b_nsize = NILFS_BINFO_NODE_SIZE; + if (file->use_real_blocknr) { + blk->dsize = NILFS_BINFO_DAT_DATA_SIZE; + blk->nsize = NILFS_BINFO_DAT_NODE_SIZE; } else { - blk->b_dsize = NILFS_BINFO_DAT_DATA_SIZE; - blk->b_nsize = NILFS_BINFO_DAT_NODE_SIZE; + blk->dsize = NILFS_BINFO_DATA_SIZE; + blk->nsize = NILFS_BINFO_NODE_SIZE; } - bisize = nilfs_block_is_data(blk) ? blk->b_dsize : blk->b_nsize; - rest = blksize - blk->b_offset % blksize; - if (bisize > rest) { - blk->b_binfo += rest; - blk->b_offset += rest; - } + nilfs_block_adjust_binfo_position(blk, blksize); } int nilfs_block_is_end(const struct nilfs_block *blk) { - return blk->b_index >= le32_to_cpu(blk->b_file->f_finfo->fi_nblocks); + return blk->index >= blk->nbinfo; } void nilfs_block_next(struct nilfs_block *blk) { - size_t blksize, bisize, rest; + const __u32 blksize = 1UL << blk->file->psegment->blkbits; + unsigned int binfosize; - blksize = 1UL << blk->b_file->f_psegment->blkbits; + binfosize = nilfs_block_is_data(blk) ? blk->dsize : blk->nsize; + blk->binfo += binfosize; + blk->offset += binfosize; + blk->blocknr++; + blk->index++; - bisize = nilfs_block_is_data(blk) ? blk->b_dsize : blk->b_nsize; - blk->b_binfo += bisize; - blk->b_offset += bisize; - blk->b_index++; - - bisize = nilfs_block_is_data(blk) ? blk->b_dsize : blk->b_nsize; - rest = blksize - blk->b_offset % blksize; - if (bisize > rest) { - blk->b_binfo += rest; - blk->b_offset += rest; - } - - blk->b_blocknr++; + nilfs_block_adjust_binfo_position(blk, blksize); } -