nilfs-utils/include/segment.h
Ryusuke Konishi 66754b6bb7 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>
2016-09-25 22:37:59 +09:00

163 lines
4.4 KiB
C

/*
* segment.h - NILFS segment i/o routines
*
* Licensed under LGPLv2: the complete text of the GNU Lesser General
* Public License can be found in COPYING file of the nilfs-utils
* package.
*/
#ifndef NILFS_SEGMENT_H
#define NILFS_SEGMENT_H
#include <linux/types.h>
#include "compat.h"
#include "nilfs2_ondisk.h"
#include "util.h"
typedef __u64 sector_t;
/**
* struct nilfs_psegment - partial segment iterator
* @segment: pointer to segment object
* @segsum: pointer to segment summary of the partial segment
* @blocknr: block number of the partial segment
* @blkcnt: count of remaining blocks
* @blkbits: bit shift for block size
* @error: error code
*/
struct nilfs_psegment {
const struct nilfs_segment *segment;
struct nilfs_segment_summary *segsum;
sector_t blocknr;
__u32 blkcnt;
unsigned int blkbits;
int error;
};
/* Error code of psegment iterator */
enum {
NILFS_PSEGMENT_SUCCESS = 0,
NILFS_PSEGMENT_ERROR_ALIGNMENT, /* Bad alignment */
NILFS_PSEGMENT_ERROR_BIGPSEG, /* Too big partial segment */
NILFS_PSEGMENT_ERROR_BIGHDR, /* Too big summary header */
NILFS_PSEGMENT_ERROR_BIGSUM, /* Too big summary info */
__NR_NILFS_PSEGMENT_ERROR,
};
/**
* struct nilfs_file - file iterator
* @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 {
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
* @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 {
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 */
#define NILFS_BINFO_DATA_SIZE sizeof(struct nilfs_binfo_v)
/* virtual block number */
#define NILFS_BINFO_NODE_SIZE sizeof(__le64)
/* block offset */
#define NILFS_BINFO_DAT_DATA_SIZE sizeof(__le64)
/* block offset and level */
#define NILFS_BINFO_DAT_NODE_SIZE sizeof(struct nilfs_binfo_dat)
struct nilfs;
struct nilfs_segment;
/* partial segment iterator */
void nilfs_psegment_init(struct nilfs_psegment *pseg,
const struct nilfs_segment *segment, __u32 blkcnt);
int nilfs_psegment_is_end(struct nilfs_psegment *pseg);
void nilfs_psegment_next(struct nilfs_psegment *pseg);
const char *nilfs_psegment_strerror(int errnum);
#define nilfs_psegment_for_each(pseg, seg, blkcnt) \
for (nilfs_psegment_init(pseg, seg, blkcnt); \
!nilfs_psegment_is_end(pseg); nilfs_psegment_next(pseg)) \
static inline int nilfs_psegment_is_error(const struct nilfs_psegment *pseg,
const char **errstr)
{
if (unlikely(pseg->error)) {
if (errstr != NULL)
*errstr = nilfs_psegment_strerror(pseg->error);
return 1;
}
return 0;
}
/* file iterator */
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 file->use_real_blocknr;
}
#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 *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->index < blk->nbinfo_data;
}
static inline int nilfs_block_is_node(const struct nilfs_block *blk)
{
return blk->index >= blk->nbinfo_data;
}
#define nilfs_block_for_each(blk, file) \
for (nilfs_block_init(blk, file); !nilfs_block_is_end(blk); \
nilfs_block_next(blk))
#endif /* NILFS_SEGMENT_H */