lib/segment: refactor file/block iterator

Rewrite nilfs_file/nilfs_block structs and their iterators to clarify
them.

Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
This commit is contained in:
Ryusuke Konishi 2016-09-25 22:37:59 +09:00
parent f827e854bc
commit 66754b6bb7
4 changed files with 163 additions and 144 deletions

View File

@ -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);

View File

@ -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))

View File

@ -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 */
}
}

View File

@ -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);
}