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

Reply via email to