Add struct lgfs2_rbm, which is similar to struct gfs2_rbm in the kernel, in order to support the coming work on extent allocation in libgfs2.
This structure and its supporting functions are added to a new private header file rather than libgfs2.h until we have reason to export it. Signed-off-by: Andrew Price <anpr...@redhat.com> --- gfs2/libgfs2/Makefile.am | 2 +- gfs2/libgfs2/rgrp.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++ gfs2/libgfs2/rgrp.h | 29 +++++++++++++++++++++ 3 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 gfs2/libgfs2/rgrp.h diff --git a/gfs2/libgfs2/Makefile.am b/gfs2/libgfs2/Makefile.am index 4af27be..1ce8c13 100644 --- a/gfs2/libgfs2/Makefile.am +++ b/gfs2/libgfs2/Makefile.am @@ -5,7 +5,7 @@ BUILT_SOURCES = parser.h lexer.h AM_LFLAGS = --header-file=lexer.h AM_YFLAGS = -d -noinst_HEADERS = libgfs2.h lang.h config.h +noinst_HEADERS = libgfs2.h lang.h config.h rgrp.h noinst_LTLIBRARIES = libgfs2.la diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c index 56b73ae..dd8811b 100644 --- a/gfs2/libgfs2/rgrp.c +++ b/gfs2/libgfs2/rgrp.c @@ -1,12 +1,14 @@ #include "clusterautoconfig.h" #include <inttypes.h> +#include <limits.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include "libgfs2.h" +#include "rgrp.h" #define RG_SYNC_TOLERANCE 1000 @@ -589,3 +591,68 @@ lgfs2_rgrp_t lgfs2_rgrp_last(lgfs2_rgrps_t rgs) { return (lgfs2_rgrp_t)osi_last(&rgs->root); } + +/** + * gfs2_rbm_from_block - Set the rbm based upon rgd and block number + * @rbm: The rbm with rgd already set correctly + * @block: The block number (filesystem relative) + * + * This sets the bi and offset members of an rbm based on a + * resource group and a filesystem relative block number. The + * resource group must be set in the rbm on entry, the bi and + * offset members will be set by this function. + * + * Returns: 0 on success, or non-zero with errno set + */ +static int lgfs2_rbm_from_block(struct lgfs2_rbm *rbm, uint64_t block) +{ + uint64_t rblock = block - rbm->rgd->ri.ri_data0; + struct gfs2_sbd *sdp = rbm_bi(rbm)->bi_bh->sdp; + + if (rblock > UINT_MAX) { + errno = EINVAL; + return 1; + } + if (block >= rbm->rgd->ri.ri_data0 + rbm->rgd->ri.ri_data) { + errno = E2BIG; + return 1; + } + + rbm->bii = 0; + rbm->offset = (uint32_t)(rblock); + /* Check if the block is within the first block */ + if (rbm->offset < (rbm_bi(rbm)->bi_len * GFS2_NBBY)) + return 0; + + /* Adjust for the size diff between gfs2_meta_header and gfs2_rgrp */ + rbm->offset += (sizeof(struct gfs2_rgrp) - + sizeof(struct gfs2_meta_header)) * GFS2_NBBY; + rbm->bii = rbm->offset / sdp->sd_blocks_per_bitmap; + rbm->offset -= rbm->bii * sdp->sd_blocks_per_bitmap; + return 0; +} + +/** + * lgfs2_rbm_incr - increment an rbm structure + * @rbm: The rbm with rgd already set correctly + * + * This function takes an existing rbm structure and increments it to the next + * viable block offset. + * + * Returns: If incrementing the offset would cause the rbm to go past the + * end of the rgrp, true is returned, otherwise false. + * + */ +static int lgfs2_rbm_incr(struct lgfs2_rbm *rbm) +{ + if (rbm->offset + 1 < (rbm_bi(rbm)->bi_len * GFS2_NBBY)) { /* in the same bitmap */ + rbm->offset++; + return 0; + } + if (rbm->bii == rbm->rgd->ri.ri_length - 1) /* at the last bitmap */ + return 1; + + rbm->offset = 0; + rbm->bii++; + return 0; +} diff --git a/gfs2/libgfs2/rgrp.h b/gfs2/libgfs2/rgrp.h new file mode 100644 index 0000000..99c52d3 --- /dev/null +++ b/gfs2/libgfs2/rgrp.h @@ -0,0 +1,29 @@ +#ifndef __RGRP_DOT_H__ +#define __RGRP_DOT_H__ + +#include "libgfs2.h" + +struct lgfs2_rbm { + lgfs2_rgrp_t rgd; + uint32_t offset; /* The offset is bitmap relative */ + unsigned bii; /* Bitmap index */ +}; + +static inline struct gfs2_bitmap *rbm_bi(const struct lgfs2_rbm *rbm) +{ + return rbm->rgd->bits + rbm->bii; +} + +static inline uint64_t lgfs2_rbm_to_block(const struct lgfs2_rbm *rbm) +{ + return rbm->rgd->ri.ri_data0 + (rbm_bi(rbm)->bi_start * GFS2_NBBY) + + rbm->offset; +} + +static inline int lgfs2_rbm_eq(const struct lgfs2_rbm *rbm1, const struct lgfs2_rbm *rbm2) +{ + return (rbm1->rgd == rbm2->rgd) && (rbm1->bii == rbm2->bii) && + (rbm1->offset == rbm2->offset); +} + +#endif /* __RGRP_DOT_H__ */ -- 1.9.3