mirror of
https://github.com/nilfs-dev/nilfs-utils.git
synced 2026-01-26 13:43:15 +00:00
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:
parent
f827e854bc
commit
66754b6bb7
@ -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);
|
||||
|
||||
@ -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))
|
||||
|
||||
|
||||
|
||||
16
lib/gc.c
16
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 */
|
||||
}
|
||||
}
|
||||
|
||||
181
lib/segment.c
181
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);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user