gfs2-utils: RHEL7 - libgfs2: Add back-pointer to rgrps in lgfs2_rgrp_t
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=080e886c...
Commit: 080e886c3188adb63a0d5cfeed37bd488b9ebb0e
Parent: 49b82ed70345c20df233fa3b0a2f7d7eeae9012d
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Wed Jul 9 12:46:26 2014 +0100
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Fri Sep 5 14:57:46 2014 +0100
libgfs2: Add back-pointer to rgrps in lgfs2_rgrp_t
Keep a pointer from a resource group to the resource group set it
belongs to for convenience and also to make lgfs2_rgrp_write a more
sensible interface.
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/libgfs2/libgfs2.h | 5 +++--
gfs2/libgfs2/rgrp.c | 4 +++-
gfs2/mkfs/main_grow.c | 2 +-
gfs2/mkfs/main_mkfs.c | 2 +-
4 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index b996be9..fca90b0 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -177,6 +177,7 @@ struct gfs2_bitmap
};
struct gfs2_sbd;
+typedef struct _lgfs2_rgrps *lgfs2_rgrps_t;
struct rgrp_tree {
struct osi_node node;
@@ -186,10 +187,10 @@ struct rgrp_tree {
struct gfs2_rindex ri;
struct gfs2_rgrp rg;
struct gfs2_bitmap *bits;
+ lgfs2_rgrps_t rgrps;
};
typedef struct rgrp_tree *lgfs2_rgrp_t;
-typedef struct _lgfs2_rgrps *lgfs2_rgrps_t;
extern lgfs2_rgrps_t lgfs2_rgrps_init(struct gfs2_sbd *sdp, uint64_t align, uint64_t offset);
extern void lgfs2_rgrps_free(lgfs2_rgrps_t *rgs);
@@ -200,7 +201,7 @@ extern uint32_t lgfs2_rgrp_align_len(const lgfs2_rgrps_t rgs, uint32_t len);
extern unsigned lgfs2_rgsize_for_data(uint64_t blksreq, unsigned bsize);
extern uint32_t lgfs2_rgrps_plan(const lgfs2_rgrps_t rgs, uint64_t space, uint32_t tgtsize);
extern lgfs2_rgrp_t lgfs2_rgrps_append(lgfs2_rgrps_t rgs, struct gfs2_rindex *entry);
-extern int lgfs2_rgrp_write(lgfs2_rgrps_t rgs, int fd, lgfs2_rgrp_t rg);
+extern int lgfs2_rgrp_write(int fd, lgfs2_rgrp_t rg);
extern const struct gfs2_rindex *lgfs2_rgrp_index(lgfs2_rgrp_t rg);
extern const struct gfs2_rgrp *lgfs2_rgrp_rgrp(lgfs2_rgrp_t rg);
extern lgfs2_rgrp_t lgfs2_rgrp_first(lgfs2_rgrps_t rgs);
diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c
index f780e00..a3fa1a4 100644
--- a/gfs2/libgfs2/rgrp.c
+++ b/gfs2/libgfs2/rgrp.c
@@ -528,6 +528,7 @@ lgfs2_rgrp_t lgfs2_rgrps_append(lgfs2_rgrps_t rgs, struct gfs2_rindex *entry)
rg->rg.rg_free = rg->ri.ri_data;
compute_bitmaps(rg, rgs->sdp->bsize);
+ rg->rgrps = rgs;
return rg;
}
@@ -535,9 +536,10 @@ lgfs2_rgrp_t lgfs2_rgrps_append(lgfs2_rgrps_t rgs, struct gfs2_rindex *entry)
* Write a resource group to a file descriptor.
* Returns 0 on success or non-zero on failure with errno set
*/
-int lgfs2_rgrp_write(const lgfs2_rgrps_t rgs, int fd, const lgfs2_rgrp_t rg)
+int lgfs2_rgrp_write(int fd, const lgfs2_rgrp_t rg)
{
ssize_t ret = 0;
+ lgfs2_rgrps_t rgs = rg->rgrps;
size_t len = rg->ri.ri_length * rgs->sdp->bsize;
unsigned int i;
const struct gfs2_meta_header bmh = {
diff --git a/gfs2/mkfs/main_grow.c b/gfs2/mkfs/main_grow.c
index 95fbd1d..c4f5055 100644
--- a/gfs2/mkfs/main_grow.c
+++ b/gfs2/mkfs/main_grow.c
@@ -219,7 +219,7 @@ static unsigned initialize_new_portion(struct gfs2_sbd *sdp, lgfs2_rgrps_t rgs)
if (metafs_interrupted)
return 0;
if (!test)
- err = lgfs2_rgrp_write(rgs, sdp->device_fd, rg);
+ err = lgfs2_rgrp_write(sdp->device_fd, rg);
if (err != 0) {
perror(_("Failed to write resource group"));
return 0;
diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c
index bf7c9cd..39b9609 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
@@ -627,7 +627,7 @@ static int place_rgrp(struct gfs2_sbd *sdp, lgfs2_rgrps_t rgs, struct gfs2_rinde
perror(_("Failed to create resource group"));
return -1;
}
- err = lgfs2_rgrp_write(rgs, sdp->device_fd, rg);
+ err = lgfs2_rgrp_write(sdp->device_fd, rg);
if (err != 0) {
perror(_("Failed to write resource group"));
return -1;
9 years, 8 months
gfs2-utils: RHEL7 - libgfs2: Ignore an empty rgrp plan if a length is specified
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=49b82ed7...
Commit: 49b82ed70345c20df233fa3b0a2f7d7eeae9012d
Parent: 26805ae36207c447b84f10853300d49d93745f30
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Thu Aug 21 15:36:58 2014 +0100
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Fri Sep 5 14:57:46 2014 +0100
libgfs2: Ignore an empty rgrp plan if a length is specified
lgfs2_rindex_entry_new previously failed if the rgrp layout plan was
empty even if the caller specified an rgrp length.
Also tidy up a couple of function comments.
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/libgfs2/rgrp.c | 10 +++++++---
1 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c
index 7063288..f780e00 100644
--- a/gfs2/libgfs2/rgrp.c
+++ b/gfs2/libgfs2/rgrp.c
@@ -428,7 +428,7 @@ uint64_t lgfs2_rindex_entry_new(lgfs2_rgrps_t rgs, struct gfs2_rindex *ri, uint6
plan = 0;
else if (rgs->plan[1].num > 0)
plan = 1;
- else
+ else if (len == 0)
return 0;
if (plan >= 0 && (len == 0 || len == rgs->plan[plan].len)) {
@@ -450,7 +450,9 @@ uint64_t lgfs2_rindex_entry_new(lgfs2_rgrps_t rgs, struct gfs2_rindex *ri, uint6
}
/**
- * Return the rindex structure relating to a a resource group.
+ * Return the rindex structure relating to a resource group.
+ * The return type is const to advise callers that making changes to this
+ * structure directly isn't wise. libgfs2 functions should be used instead.
*/
const struct gfs2_rindex *lgfs2_rgrp_index(lgfs2_rgrp_t rg)
{
@@ -458,7 +460,9 @@ const struct gfs2_rindex *lgfs2_rgrp_index(lgfs2_rgrp_t rg)
}
/**
- * Return the rgrp structure relating to a a resource group.
+ * Return the rgrp structure relating to a resource group.
+ * The return type is const to advise callers that making changes to this
+ * structure directly isn't wise. libgfs2 functions should be used instead.
*/
const struct gfs2_rgrp *lgfs2_rgrp_rgrp(lgfs2_rgrp_t rg)
{
9 years, 8 months
gfs2-utils: RHEL7 - tests: Add unit tests for the new extent search functions
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=26805ae3...
Commit: 26805ae36207c447b84f10853300d49d93745f30
Parent: 8d4893c837d476308f508a7f2e1c867a3cfefdb9
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Thu Aug 21 15:26:14 2014 +0100
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Fri Sep 5 14:57:46 2014 +0100
tests: Add unit tests for the new extent search functions
The rbm search functions added by the previous commit added a certain
amount of complexity. These unit tests go a long way to making sure
they're doing what they're meant to do, and also demonstrate how the new
rgrp functions work without any i/o required.
The unit test sources have also been reorganised to match the names of
the libgfs2 source files they test.
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
.gitignore | 3 +-
tests/Makefile.am | 33 ++++++++----
tests/check_rgrp.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++++
tests/libgfs2.at | 8 ++-
4 files changed, 173 insertions(+), 14 deletions(-)
diff --git a/.gitignore b/.gitignore
index ae72f2b..4ffdb71 100644
--- a/.gitignore
+++ b/.gitignore
@@ -42,7 +42,8 @@ gfs2/fsck/fsck.gfs2
gfs2/mkfs/mkfs.gfs2
gfs2/tune/tunegfs2
test-driver
-tests/check_libgfs2
+tests/check_meta
+tests/check_rgrp
tests/testvol
tests/testsuite.log
tests/testsuite.dir
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 5f02d3a..70e77ef 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -3,20 +3,28 @@ DISTCLEANFILES = atlocal atconfig
CLEANFILES = testvol
if BUILD_TESTS
-check_PROGRAMS = check_libgfs2
-
-check_libgfs2_SOURCES = \
- check_meta.c \
+UNIT_TESTS = \
+ check_meta \
+ check_rgrp
+UNIT_SOURCES = \
$(top_srcdir)/gfs2/libgfs2/libgfs2.h
-
-check_libgfs2_CFLAGS = \
+UNIT_CFLAGS = \
-I$(top_srcdir)/gfs2/libgfs2 \
-I$(top_srcdir)/gfs2/include \
@check_CFLAGS@
-
-check_libgfs2_LDADD = \
+UNIT_LDADD = \
$(top_builddir)/gfs2/libgfs2/libgfs2.la \
@check_LIBS@
+
+check_PROGRAMS = $(UNIT_TESTS)
+
+check_meta_SOURCES = $(UNIT_SOURCES) check_meta.c
+check_meta_CFLAGS = $(UNIT_CFLAGS)
+check_meta_LDADD = $(UNIT_LDADD)
+
+check_rgrp_SOURCES = $(UNIT_SOURCES) check_rgrp.c
+check_rgrp_CFLAGS = $(UNIT_CFLAGS)
+check_rgrp_LDADD = $(UNIT_LDADD)
endif
# The `:;' works around a Bash 3.2 bug when the output is not writable.
@@ -41,8 +49,11 @@ TESTSUITE_AT = \
testsuite.at \
mkfs.at \
fsck.at \
- edit.at \
- libgfs2.at
+ edit.at
+
+if BUILD_TESTS
+TESTSUITE_AT += libgfs2.at
+endif
TESTSUITE = $(srcdir)/testsuite
@@ -61,6 +72,6 @@ atconfig: $(top_builddir)/config.status
AUTOM4TE = $(SHELL) $(top_srcdir)/missing --run autom4te
AUTOTEST = $(AUTOM4TE) --language=autotest
-$(TESTSUITE): $(TESTSUITE_AT) package.m4
+$(TESTSUITE): $(TESTSUITE_AT) package.m4 $(UNIT_TESTS)
$(AUTOTEST) -I '$(srcdir)' -o $@.tmp $@.at
mv $@.tmp $@
diff --git a/tests/check_rgrp.c b/tests/check_rgrp.c
new file mode 100644
index 0000000..d113846
--- /dev/null
+++ b/tests/check_rgrp.c
@@ -0,0 +1,143 @@
+#include <check.h>
+#include <libgfs2.h>
+#include <rgrp.h> /* Private header libgfs2/rgrp.h for convenience */
+
+// TODO: Remove this when the extern is removed from libgfs2
+void print_it(const char *label, const char *fmt, const char *fmt2, ...) {}
+
+static lgfs2_rgrps_t mockup_rgrp(void)
+{
+ struct gfs2_sbd *sdp;
+ lgfs2_rgrps_t rgs;
+ unsigned i;
+ uint64_t addr;
+ struct gfs2_rindex ri = {0};
+ lgfs2_rgrp_t rg;
+ uint32_t rgsize = (1024 << 20) / 4096;
+
+ sdp = calloc(1, sizeof(*sdp));
+ ck_assert_ptr_ne(sdp, NULL);
+
+ sdp->device.length = rgsize + 20;
+ sdp->device_fd = -1;
+ sdp->bsize = sdp->sd_sb.sb_bsize = 4096;
+ compute_constants(sdp);
+
+ rgs = lgfs2_rgrps_init(sdp, 0, 0);
+ ck_assert_ptr_ne(rgs, NULL);
+
+ lgfs2_rgrps_plan(rgs, sdp->device.length - 16, rgsize);
+
+ addr = lgfs2_rindex_entry_new(rgs, &ri, 16, rgsize);
+ ck_assert(addr != 0);
+
+ rg = lgfs2_rgrps_append(rgs, &ri);
+ ck_assert_ptr_ne(rg, NULL);
+
+ for (i = 0; i < rg->ri.ri_length; i++) {
+ rg->bits[i].bi_bh = bget(sdp, rg->ri.ri_addr + i);
+ ck_assert_ptr_ne(rg->bits[i].bi_bh, NULL);
+ }
+ return rgs;
+}
+
+START_TEST(test_mockup_rgrp)
+{
+ lgfs2_rgrps_t rgs = mockup_rgrp();
+ ck_assert_ptr_ne(rgs, NULL);
+}
+END_TEST
+
+START_TEST(test_rbm_find_good)
+{
+ uint32_t minext;
+ struct lgfs2_rbm rbm = {0};
+ lgfs2_rgrps_t rgs = mockup_rgrp();
+ rbm.rgd = lgfs2_rgrp_first(rgs);
+
+ /* Check that extent sizes up to the whole rg can be found */
+ for (minext = 1; minext <= rbm.rgd->ri.ri_data; minext++) {
+ int err;
+ uint64_t addr;
+
+ rbm.offset = rbm.bii = 0;
+
+ err = lgfs2_rbm_find(&rbm, GFS2_BLKST_FREE, &minext);
+ ck_assert_int_eq(err, 0);
+
+ addr = lgfs2_rbm_to_block(&rbm);
+ ck_assert_uint_eq(addr, rbm.rgd->ri.ri_data0);
+ }
+}
+END_TEST
+
+START_TEST(test_rbm_find_bad)
+{
+ int err;
+ uint32_t minext;
+ struct lgfs2_rbm rbm = {0};
+ lgfs2_rgrps_t rgs = mockup_rgrp();
+
+ rbm.rgd = lgfs2_rgrp_first(rgs);
+ minext = rbm.rgd->ri.ri_data + 1;
+
+ err = lgfs2_rbm_find(&rbm, GFS2_BLKST_FREE, &minext);
+ ck_assert_int_eq(err, 1);
+}
+END_TEST
+
+START_TEST(test_rbm_find_lastblock)
+{
+ int err;
+ unsigned i;
+ uint64_t addr;
+ uint32_t minext = 1; /* Only looking for one block */
+ struct lgfs2_rbm rbm = {0};
+ lgfs2_rgrp_t rg;
+ lgfs2_rgrps_t rgs = mockup_rgrp();
+
+ rbm.rgd = rg = lgfs2_rgrp_first(rgs);
+
+ /* Flag all blocks as allocated... */
+ for (i = 0; i < rg->ri.ri_length; i++)
+ memset(rg->bits[i].bi_bh->b_data, 0xff, rgs->sdp->bsize);
+
+ /* ...except the final one */
+ err = gfs2_set_bitmap(rg, rg->ri.ri_data0 + rg->ri.ri_data - 1, GFS2_BLKST_FREE);
+ ck_assert_int_eq(err, 0);
+
+ err = lgfs2_rbm_find(&rbm, GFS2_BLKST_FREE, &minext);
+ ck_assert_int_eq(err, 0);
+
+ addr = lgfs2_rbm_to_block(&rbm);
+ ck_assert_uint_eq(addr, rg->ri.ri_data0 + rg->ri.ri_data - 1);
+}
+END_TEST
+
+static Suite * libgfs2_suite(void)
+{
+
+ Suite *s = suite_create("libgfs2");
+
+ TCase *tc_rgrp = tcase_create("rgrp");
+
+ tcase_add_test(tc_rgrp, test_mockup_rgrp);
+ tcase_add_test(tc_rgrp, test_rbm_find_good);
+ tcase_add_test(tc_rgrp, test_rbm_find_bad);
+ tcase_add_test(tc_rgrp, test_rbm_find_lastblock);
+ tcase_set_timeout(tc_rgrp, 60);
+ suite_add_tcase(s, tc_rgrp);
+
+ return s;
+}
+
+int main(void)
+{
+ int failures;
+ Suite *s = libgfs2_suite();
+ SRunner *sr = srunner_create(s);
+ srunner_run_all(sr, CK_NORMAL);
+ failures = srunner_ntests_failed(sr);
+ srunner_free(sr);
+ return failures ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/tests/libgfs2.at b/tests/libgfs2.at
index a6b478a..8c44cdd 100644
--- a/tests/libgfs2.at
+++ b/tests/libgfs2.at
@@ -1,5 +1,9 @@
AT_BANNER([libgfs2 unit tests])
-AT_SETUP([Metadata check])
-AT_CHECK([check_libgfs2], 0, [ignore], [ignore])
+AT_SETUP([meta.c])
+AT_CHECK([check_meta], 0, [ignore], [ignore])
+AT_CLEANUP
+
+AT_SETUP([rgrp.c])
+AT_CHECK([check_rgrp], 0, [ignore], [ignore])
AT_CLEANUP
9 years, 8 months
gfs2-utils: RHEL7 - libgfs2: Add functions for finding free extents
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=8d4893c8...
Commit: 8d4893c837d476308f508a7f2e1c867a3cfefdb9
Parent: 03f9c9281e656c9fd0b05dab155b9097b5a5072f
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Fri Jun 20 23:07:47 2014 +0100
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Fri Sep 5 14:57:46 2014 +0100
libgfs2: Add functions for finding free extents
Port gfs2_rbm_find and some functions which it depends on from the gfs2
kernel code. This will set the base for allocation of single-extent
files. The functions have been simplified where possible as libgfs2
doesn't have a concept of reservations for the time being.
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/libgfs2/rgrp.c | 197 +++++++++++++++++++++++++++++++++++++++++++++++++++
gfs2/libgfs2/rgrp.h | 2 +
2 files changed, 199 insertions(+), 0 deletions(-)
diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c
index 0f36b86..7063288 100644
--- a/gfs2/libgfs2/rgrp.c
+++ b/gfs2/libgfs2/rgrp.c
@@ -638,3 +638,200 @@ static int lgfs2_rbm_incr(struct lgfs2_rbm *rbm)
rbm->bii++;
return 0;
}
+
+/**
+ * lgfs2_testbit - test a bit in the bitmaps
+ * @rbm: The bit to test
+ *
+ * Returns: The two bit block state of the requested bit
+ */
+static inline uint8_t lgfs2_testbit(const struct lgfs2_rbm *rbm)
+{
+ struct gfs2_bitmap *bi = rbm_bi(rbm);
+ const uint8_t *buffer = (uint8_t *)bi->bi_bh->b_data + bi->bi_offset;
+ const uint8_t *byte;
+ unsigned int bit;
+
+ byte = buffer + (rbm->offset / GFS2_NBBY);
+ bit = (rbm->offset % GFS2_NBBY) * GFS2_BIT_SIZE;
+
+ return (*byte >> bit) & GFS2_BIT_MASK;
+}
+
+/**
+ * lgfs2_unaligned_extlen - Look for free blocks which are not byte aligned
+ * @rbm: Position to search (value/result)
+ * @n_unaligned: Number of unaligned blocks to check
+ * @len: Decremented for each block found (terminate on zero)
+ *
+ * Returns: true if a non-free block is encountered
+ */
+static int lgfs2_unaligned_extlen(struct lgfs2_rbm *rbm, uint32_t n_unaligned, uint32_t *len)
+{
+ uint32_t n;
+ uint8_t res;
+
+ for (n = 0; n < n_unaligned; n++) {
+ res = lgfs2_testbit(rbm);
+ if (res != GFS2_BLKST_FREE)
+ return 1;
+ (*len)--;
+ if (*len == 0)
+ return 1;
+ if (lgfs2_rbm_incr(rbm))
+ return 1;
+ }
+
+ return 0;
+}
+
+static uint8_t *check_bytes8(const uint8_t *start, uint8_t value, unsigned bytes)
+{
+ while (bytes) {
+ if (*start != value)
+ return (void *)start;
+ start++;
+ bytes--;
+ }
+ return NULL;
+}
+
+/**
+ * lgfs2_free_extlen - Return extent length of free blocks
+ * @rbm: Starting position
+ * @len: Max length to check
+ *
+ * Starting at the block specified by the rbm, see how many free blocks
+ * there are, not reading more than len blocks ahead. This can be done
+ * using check_bytes8 when the blocks are byte aligned, but has to be done
+ * on a block by block basis in case of unaligned blocks. Also this
+ * function can cope with bitmap boundaries (although it must stop on
+ * a resource group boundary)
+ *
+ * Returns: Number of free blocks in the extent
+ */
+static uint32_t lgfs2_free_extlen(const struct lgfs2_rbm *rrbm, uint32_t len)
+{
+ struct lgfs2_rbm rbm = *rrbm;
+ uint32_t n_unaligned = rbm.offset & 3;
+ uint32_t size = len;
+ uint32_t bytes;
+ uint32_t chunk_size;
+ uint8_t *ptr, *start, *end;
+ uint64_t block;
+ struct gfs2_bitmap *bi;
+
+ if (n_unaligned &&
+ lgfs2_unaligned_extlen(&rbm, 4 - n_unaligned, &len))
+ goto out;
+
+ n_unaligned = len & 3;
+ /* Start is now byte aligned */
+ while (len > 3) {
+ bi = rbm_bi(&rbm);
+ start = (uint8_t *)bi->bi_bh->b_data;
+ end = start + bi->bi_bh->sdp->bsize;
+ start += bi->bi_offset;
+ start += (rbm.offset / GFS2_NBBY);
+ bytes = (len / GFS2_NBBY) < (end - start) ? (len / GFS2_NBBY):(end - start);
+ ptr = check_bytes8(start, 0, bytes);
+ chunk_size = ((ptr == NULL) ? bytes : (ptr - start));
+ chunk_size *= GFS2_NBBY;
+ len -= chunk_size;
+ block = lgfs2_rbm_to_block(&rbm);
+ if (lgfs2_rbm_from_block(&rbm, block + chunk_size)) {
+ n_unaligned = 0;
+ break;
+ }
+ if (ptr) {
+ n_unaligned = 3;
+ break;
+ }
+ n_unaligned = len & 3;
+ }
+
+ /* Deal with any bits left over at the end */
+ if (n_unaligned)
+ lgfs2_unaligned_extlen(&rbm, n_unaligned, &len);
+out:
+ return size - len;
+}
+
+/**
+ * gfs2_rbm_find - Look for blocks of a particular state
+ * @rbm: Value/result starting position and final position
+ * @state: The state which we want to find
+ * @minext: Pointer to the requested extent length (NULL for a single block)
+ * This is updated to be the actual reservation size.
+ *
+ * Returns: 0 on success, non-zero with errno == ENOSPC if there is no block of the requested state
+ */
+int lgfs2_rbm_find(struct lgfs2_rbm *rbm, uint8_t state, uint32_t *minext)
+{
+ int initial_bii;
+ uint32_t offset;
+ int n = 0;
+ int iters = rbm->rgd->ri.ri_length;
+ uint32_t extlen;
+
+ /* If we are not starting at the beginning of a bitmap, then we
+ * need to add one to the bitmap count to ensure that we search
+ * the starting bitmap twice.
+ */
+ if (rbm->offset != 0)
+ iters++;
+
+ for (n = 0; n < iters; n++) {
+ struct gfs2_bitmap *bi = rbm_bi(rbm);
+ struct gfs2_buffer_head *bh = bi->bi_bh;
+ uint8_t *buf = (uint8_t *)bh->b_data + bi->bi_offset;
+ uint64_t block;
+ int ret;
+
+ if ((rbm->rgd->rg.rg_free < *minext) && (state == GFS2_BLKST_FREE))
+ goto next_bitmap;
+
+ offset = gfs2_bitfit(buf, bi->bi_len, rbm->offset, state);
+ if (offset == BFITNOENT)
+ goto next_bitmap;
+
+ rbm->offset = offset;
+ initial_bii = rbm->bii;
+ block = lgfs2_rbm_to_block(rbm);
+ extlen = 1;
+
+ if (*minext != 0)
+ extlen = lgfs2_free_extlen(rbm, *minext);
+
+ if (extlen >= *minext)
+ return 0;
+
+ ret = lgfs2_rbm_from_block(rbm, block + extlen);
+ if (ret == 0) {
+ n += (rbm->bii - initial_bii);
+ continue;
+ }
+
+ if (errno == E2BIG) {
+ rbm->bii = 0;
+ rbm->offset = 0;
+ n += (rbm->bii - initial_bii);
+ goto res_covered_end_of_rgrp;
+ }
+
+ return ret;
+
+next_bitmap: /* Find next bitmap in the rgrp */
+ rbm->offset = 0;
+ rbm->bii++;
+ if (rbm->bii == rbm->rgd->ri.ri_length)
+ rbm->bii = 0;
+
+res_covered_end_of_rgrp:
+ if (rbm->bii == 0)
+ break;
+ }
+
+ errno = ENOSPC;
+ return 1;
+}
diff --git a/gfs2/libgfs2/rgrp.h b/gfs2/libgfs2/rgrp.h
index 384231e..1634fbc 100644
--- a/gfs2/libgfs2/rgrp.h
+++ b/gfs2/libgfs2/rgrp.h
@@ -44,4 +44,6 @@ static inline int lgfs2_rbm_eq(const struct lgfs2_rbm *rbm1, const struct lgfs2_
(rbm1->offset == rbm2->offset);
}
+extern int lgfs2_rbm_find(struct lgfs2_rbm *rbm, uint8_t state, uint32_t *minext);
+
#endif /* __RGRP_DOT_H__ */
9 years, 8 months
gfs2-utils: RHEL7 - libgfs2: Move struct _lgfs2_rgrps into rgrp.h
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=03f9c928...
Commit: 03f9c9281e656c9fd0b05dab155b9097b5a5072f
Parent: ad1c17b046b97ec617c83489e77cede8152b9132
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Fri Jun 20 22:24:13 2014 +0100
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Fri Sep 5 14:57:46 2014 +0100
libgfs2: Move struct _lgfs2_rgrps into rgrp.h
Other parts of libgfs2 will need to know the struct behind lgfs2_rgrps_t
in future patches so move it into rgrp.h. Also make its sdp field
non-const as the struct it points to will be modified.
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/libgfs2/libgfs2.h | 2 +-
gfs2/libgfs2/rgrp.c | 20 +-------------------
gfs2/libgfs2/rgrp.h | 18 ++++++++++++++++++
3 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 71da81e..b996be9 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -191,7 +191,7 @@ struct rgrp_tree {
typedef struct rgrp_tree *lgfs2_rgrp_t;
typedef struct _lgfs2_rgrps *lgfs2_rgrps_t;
-extern lgfs2_rgrps_t lgfs2_rgrps_init(const struct gfs2_sbd *sdp, uint64_t align, uint64_t offset);
+extern lgfs2_rgrps_t lgfs2_rgrps_init(struct gfs2_sbd *sdp, uint64_t align, uint64_t offset);
extern void lgfs2_rgrps_free(lgfs2_rgrps_t *rgs);
extern uint64_t lgfs2_rindex_entry_new(lgfs2_rgrps_t rgs, struct gfs2_rindex *entry, uint64_t addr, uint32_t len);
extern unsigned lgfs2_rindex_read_fd(int fd, lgfs2_rgrps_t rgs);
diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c
index dd8811b..0f36b86 100644
--- a/gfs2/libgfs2/rgrp.c
+++ b/gfs2/libgfs2/rgrp.c
@@ -219,24 +219,6 @@ void gfs2_rgrp_free(struct osi_root *rgrp_tree)
}
}
-struct rgplan {
- uint32_t num;
- uint32_t len;
-};
-
-/**
- * This structure is defined in libgfs2.h as an opaque type. It stores the
- * constants and context required for creating resource groups from any point
- * in an application.
- */
-struct _lgfs2_rgrps {
- struct osi_root root;
- struct rgplan plan[2];
- const struct gfs2_sbd *sdp;
- unsigned long align;
- unsigned long align_off;
-};
-
static uint64_t align_block(const uint64_t base, const uint64_t align)
{
if ((align > 0) && ((base % align) > 0))
@@ -344,7 +326,7 @@ uint32_t lgfs2_rgrps_plan(const lgfs2_rgrps_t rgs, uint64_t space, uint32_t tgts
* offset: The required stripe offset of the resource groups
* Returns an initialised lgfs2_rgrps_t or NULL if unsuccessful with errno set
*/
-lgfs2_rgrps_t lgfs2_rgrps_init(const struct gfs2_sbd *sdp, uint64_t align, uint64_t offset)
+lgfs2_rgrps_t lgfs2_rgrps_init(struct gfs2_sbd *sdp, uint64_t align, uint64_t offset)
{
lgfs2_rgrps_t rgs;
diff --git a/gfs2/libgfs2/rgrp.h b/gfs2/libgfs2/rgrp.h
index 99c52d3..384231e 100644
--- a/gfs2/libgfs2/rgrp.h
+++ b/gfs2/libgfs2/rgrp.h
@@ -3,6 +3,24 @@
#include "libgfs2.h"
+struct rgplan {
+ uint32_t num;
+ uint32_t len;
+};
+
+/**
+ * This structure is defined in libgfs2.h as an opaque type. It stores the
+ * constants and context required for creating resource groups from any point
+ * in an application.
+ */
+struct _lgfs2_rgrps {
+ struct osi_root root;
+ struct rgplan plan[2];
+ struct gfs2_sbd *sdp;
+ unsigned long align;
+ unsigned long align_off;
+};
+
struct lgfs2_rbm {
lgfs2_rgrp_t rgd;
uint32_t offset; /* The offset is bitmap relative */
9 years, 8 months
gfs2-utils: RHEL7 - libgfs2: Introduce struct lgfs2_rbm
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=ad1c17b0...
Commit: ad1c17b046b97ec617c83489e77cede8152b9132
Parent: f072015b16d4a28b3fa9c7512794af7602500f0b
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Fri Jun 13 15:45:07 2014 +0100
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Fri Sep 5 14:57:46 2014 +0100
libgfs2: Introduce struct lgfs2_rbm
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 <anprice(a)redhat.com>
---
gfs2/libgfs2/Makefile.am | 2 +-
gfs2/libgfs2/rgrp.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++
gfs2/libgfs2/rgrp.h | 29 ++++++++++++++++++++
3 files changed, 97 insertions(+), 1 deletions(-)
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__ */
9 years, 8 months
gfs2-utils: RHEL7 - libgfs2: Fix an impossible loop condition in gfs2_rgrp_read
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=f072015b...
Commit: f072015b16d4a28b3fa9c7512794af7602500f0b
Parent: e42a9392ecd663ea82903e9a3a86952ad9fc0af0
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Sat Aug 30 00:06:28 2014 +0100
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Fri Sep 5 14:57:46 2014 +0100
libgfs2: Fix an impossible loop condition in gfs2_rgrp_read
Correct a loop which expects an unsigned int to become negative.
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/libgfs2/rgrp.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c
index e929846..56b73ae 100644
--- a/gfs2/libgfs2/rgrp.c
+++ b/gfs2/libgfs2/rgrp.c
@@ -131,10 +131,10 @@ uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_tree *rgd)
bi->bi_bh = bhs[x];
if (gfs2_check_meta(bi->bi_bh, mtype)) {
unsigned err = x;
- for (; x >= 0; x--) {
+ do {
brelse(rgd->bits[x].bi_bh);
rgd->bits[x].bi_bh = NULL;
- }
+ } while (x-- != 0);
free(bhs);
return rgd->ri.ri_addr + err;
}
9 years, 8 months
gfs2-utils: RHEL7 - libgfs2: Move bitmap buffers inside struct gfs2_bitmap
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=e42a9392...
Commit: e42a9392ecd663ea82903e9a3a86952ad9fc0af0
Parent: 8e3a9dfa499956d55ee96ffd618aceb6dd7a7434
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Thu Jun 12 03:54:15 2014 +0100
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Fri Sep 5 14:57:46 2014 +0100
libgfs2: Move bitmap buffers inside struct gfs2_bitmap
Keeping an array of buffers alongside the array of bitmaps meant some
extra management and bookkeeping for arrays of buffer pointers. Move the
buffer pointers into the bitmap structures.
The only downside to this is that reading resource groups gets a little
more complicated and an intermediate array of buffer pointers is created
in gfs2_rgrp_read to make sure we can still use vector i/o. Fortunately
this doesn't cause any noticeable slowdown.
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/convert/gfs2_convert.c | 42 +++++++++++---------------
gfs2/edit/journal.c | 6 ++--
gfs2/fsck/fs_recovery.c | 2 +-
gfs2/fsck/initialize.c | 15 ++++-----
gfs2/fsck/metawalk.c | 10 ++----
gfs2/fsck/pass5.c | 9 ++---
gfs2/fsck/rgrepair.c | 14 ++++-----
gfs2/fsck/util.c | 2 +-
gfs2/libgfs2/fs_bits.c | 10 ++++--
gfs2/libgfs2/fs_geometry.c | 6 ++--
gfs2/libgfs2/fs_ops.c | 16 +++++-----
gfs2/libgfs2/libgfs2.h | 2 +-
gfs2/libgfs2/rgrp.c | 70 +++++++++++++++++++++---------------------
gfs2/libgfs2/structures.c | 2 +-
14 files changed, 98 insertions(+), 108 deletions(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index 87bec8c..61ed320 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -142,16 +142,18 @@ static void convert_bitmaps(struct gfs2_sbd *sdp, struct rgrp_tree *rg)
ri = &rg->ri;
for (blk = 0; blk < ri->ri_length; blk++) {
+ struct gfs2_bitmap *bi;
x = (blk) ? sizeof(struct gfs2_meta_header) :
sizeof(struct gfs2_rgrp);
+ bi = &rg->bits[blk];
for (; x < sdp->bsize; x++)
for (y = 0; y < GFS2_NBBY; y++) {
- state = (rg->bh[blk]->b_data[x] >>
+ state = (bi->bi_bh->b_data[x] >>
(GFS2_BIT_SIZE * y)) & 0x03;
if (state == 0x02) {/* unallocated metadata state invalid */
- rg->bh[blk]->b_data[x] &= ~(0x02 << (GFS2_BIT_SIZE * y));
- bmodified(rg->bh[blk]);
+ bi->bi_bh->b_data[x] &= ~(0x02 << (GFS2_BIT_SIZE * y));
+ bmodified(bi->bi_bh);
}
}
}
@@ -188,7 +190,7 @@ static int convert_rgs(struct gfs2_sbd *sbp)
sbp->dinodes_alloced += rgd1->rg_useddi;
convert_bitmaps(sbp, rgd);
/* Write the updated rgrp to the gfs2 buffer */
- gfs2_rgrp_out_bh(&rgd->rg, rgd->bh[0]);
+ gfs2_rgrp_out_bh(&rgd->rg, rgd->bits[0].bi_bh);
rgs++;
if (rgs % 100 == 0) {
printf(".");
@@ -969,8 +971,8 @@ static int next_rg_meta(struct rgrp_tree *rgd, uint64_t *block, int first)
}
for (; i < length; i++){
bits = &rgd->bits[i];
- blk = gfs2_bitfit((unsigned char *)rgd->bh[i]->b_data +
- bits->bi_offset, bits->bi_len, blk, GFS2_BLKST_DINODE);
+ blk = gfs2_bitfit((uint8_t *)bits->bi_bh->b_data + bits->bi_offset,
+ bits->bi_len, blk, GFS2_BLKST_DINODE);
if(blk != BFITNOENT){
*block = blk + (bits->bi_start * GFS2_NBBY) +
rgd->ri.ri_data0;
@@ -1073,16 +1075,17 @@ static int inode_renumber(struct gfs2_sbd *sbp, uint64_t root_inode_addr, osi_li
byte_bit = (block - rgd->ri.ri_data0) % GFS2_NBBY;
/* Now figure out which bitmap block the byte is on */
for (blk = 0; blk < rgd->ri.ri_length; blk++) {
+ struct gfs2_bitmap *bi = &rgd->bits[blk];
/* figure out offset of first bitmap byte for this map: */
buf_offset = (blk) ? sizeof(struct gfs2_meta_header) :
sizeof(struct gfs2_rgrp);
/* if it's on this page */
if (buf_offset + bitmap_byte < sbp->bsize) {
- rgd->bh[blk]->b_data[buf_offset + bitmap_byte] &=
+ bi->bi_bh->b_data[buf_offset + bitmap_byte] &=
~(0x03 << (GFS2_BIT_SIZE * byte_bit));
- rgd->bh[blk]->b_data[buf_offset + bitmap_byte] |=
+ bi->bi_bh->b_data[buf_offset + bitmap_byte] |=
(0x01 << (GFS2_BIT_SIZE * byte_bit));
- bmodified(rgd->bh[blk]);
+ bmodified(bi->bi_bh);
break;
}
bitmap_byte -= (sbp->bsize - buf_offset);
@@ -1854,29 +1857,20 @@ static int journ_space_to_rg(struct gfs2_sbd *sdp)
rgd->rg.rg_free = rgd->ri.ri_data;
rgd->ri.ri_bitbytes = rgd->ri.ri_data / GFS2_NBBY;
- if(!(rgd->bh = (struct gfs2_buffer_head **)
- malloc(rgd->ri.ri_length *
- sizeof(struct gfs2_buffer_head *))))
- return -1;
- if(!memset(rgd->bh, 0, rgd->ri.ri_length *
- sizeof(struct gfs2_buffer_head *))) {
- free(rgd->bh);
- return -1;
- }
- for (x = 0; x < rgd->ri.ri_length; x++) {
- rgd->bh[x] = bget(sdp, rgd->ri.ri_addr + x);
- memset(rgd->bh[x]->b_data, 0, sdp->bsize);
- }
if (gfs2_compute_bitstructs(sdp->sd_sb.sb_bsize, rgd)) {
log_crit(_("gfs2_convert: Error converting bitmaps.\n"));
exit(-1);
}
+
+ for (x = 0; x < rgd->ri.ri_length; x++)
+ rgd->bits[x].bi_bh = bget(sdp, rgd->ri.ri_addr + x);
+
convert_bitmaps(sdp, rgd);
for (x = 0; x < rgd->ri.ri_length; x++) {
if (x)
- gfs2_meta_header_out_bh(&mh, rgd->bh[x]);
+ gfs2_meta_header_out_bh(&mh, rgd->bits[x].bi_bh);
else
- gfs2_rgrp_out_bh(&rgd->rg, rgd->bh[x]);
+ gfs2_rgrp_out_bh(&rgd->rg, rgd->bits[x].bi_bh);
}
} /* for each journal */
return error;
diff --git a/gfs2/edit/journal.c b/gfs2/edit/journal.c
index a72a044..5b824a4 100644
--- a/gfs2/edit/journal.c
+++ b/gfs2/edit/journal.c
@@ -259,14 +259,14 @@ static int print_ld_blks(const uint64_t *b, const char *end, int start_line,
sizeof(struct gfs2_meta_header))
* GFS2_NBBY;
bmap = o / sbd.sd_blocks_per_bitmap;
- save_bh = rgd->bh[bmap];
+ save_bh = rgd->bits[bmap].bi_bh;
j_bmap_bh = bread(&sbd, abs_block +
bcount);
- rgd->bh[bmap] = j_bmap_bh;
+ rgd->bits[bmap].bi_bh = j_bmap_bh;
type = lgfs2_get_bitmap(&sbd, tblk,
rgd);
brelse(j_bmap_bh);
- rgd->bh[bmap] = save_bh;
+ rgd->bits[bmap].bi_bh = save_bh;
print_gfs2("bit for blk 0x%llx is %d "
"(%s)",
(unsigned long long)tblk,
diff --git a/gfs2/fsck/fs_recovery.c b/gfs2/fsck/fs_recovery.c
index a052487..bc4210d 100644
--- a/gfs2/fsck/fs_recovery.c
+++ b/gfs2/fsck/fs_recovery.c
@@ -652,7 +652,7 @@ int replay_journals(struct gfs2_sbd *sdp, int preen, int force_check,
* don't segfault. */
rgd.start = sdp->sb_addr + 1;
rgd.length = 1;
- rgd.bh = NULL;
+ bits.bi_bh = NULL;
bits.bi_start = 0;
bits.bi_len = sdp->fssize / GFS2_NBBY;
rgd.bits = &bits;
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index f7ea45f..02ecd3f 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -222,7 +222,7 @@ static void check_rgrp_integrity(struct gfs2_sbd *sdp, struct rgrp_tree *rgd,
for (x = 0; x < bytes_to_check; x++) {
unsigned char *byte;
- byte = (unsigned char *)&rgd->bh[rgb]->b_data[off + x];
+ byte = (unsigned char *)&rgd->bits[rgb].bi_bh->b_data[off + x];
if (*byte == 0x55) {
diblock += GFS2_NBBY;
continue;
@@ -277,7 +277,7 @@ static void check_rgrp_integrity(struct gfs2_sbd *sdp, struct rgrp_tree *rgd,
}
*byte &= ~(GFS2_BIT_MASK <<
(GFS2_BIT_SIZE * y));
- bmodified(rgd->bh[rgb]);
+ bmodified(rgd->bits[rgb].bi_bh);
rg_reclaimed++;
rg_free++;
rgd->rg.rg_free++;
@@ -314,9 +314,9 @@ static void check_rgrp_integrity(struct gfs2_sbd *sdp, struct rgrp_tree *rgd,
will be reported. */
if (rg_reclaimed && *fixit) {
if (sdp->gfs1)
- gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg, rgd->bh[0]);
+ gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg, rgd->bits[0].bi_bh);
else
- gfs2_rgrp_out_bh(&rgd->rg, rgd->bh[0]);
+ gfs2_rgrp_out_bh(&rgd->rg, rgd->bits[0].bi_bh);
*this_rg_cleaned = 1;
log_info( _("The rgrp at %lld (0x%llx) was cleaned of %d "
"free metadata blocks.\n"),
@@ -335,10 +335,9 @@ static void check_rgrp_integrity(struct gfs2_sbd *sdp, struct rgrp_tree *rgd,
if (query( _("Fix the rgrp free blocks count? (y/n)"))) {
rgd->rg.rg_free = rg_free;
if (sdp->gfs1)
- gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg,
- rgd->bh[0]);
+ gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg, rgd->bits[0].bi_bh);
else
- gfs2_rgrp_out_bh(&rgd->rg, rgd->bh[0]);
+ gfs2_rgrp_out_bh(&rgd->rg, rgd->bits[0].bi_bh);
*this_rg_fixed = 1;
log_err( _("The rgrp was fixed.\n"));
} else
@@ -354,7 +353,7 @@ static void check_rgrp_integrity(struct gfs2_sbd *sdp, struct rgrp_tree *rgd,
gfs1rg->rg_freemeta, rg_unlinked);
if (query( _("Fix the rgrp free meta blocks count? (y/n)"))) {
gfs1rg->rg_freemeta = rg_unlinked;
- gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg, rgd->bh[0]);
+ gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg, rgd->bits[0].bi_bh);
*this_rg_fixed = 1;
log_err( _("The rgrp was fixed.\n"));
} else
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 8da17c6..329fc3b 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -91,17 +91,15 @@ int check_n_fix_bitmap(struct gfs2_sbd *sdp, uint64_t blk, int error_on_dinode,
}
rgd->rg.rg_free++;
if (sdp->gfs1)
- gfs_rgrp_out((struct gfs_rgrp *)
- &rgd->rg, rgd->bh[0]);
+ gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg, rgd->bits[0].bi_bh);
else
- gfs2_rgrp_out_bh(&rgd->rg, rgd->bh[0]);
+ gfs2_rgrp_out_bh(&rgd->rg, rgd->bits[0].bi_bh);
} else if (old_bitmap_state == GFS2_BLKST_FREE) {
rgd->rg.rg_free--;
if (sdp->gfs1)
- gfs_rgrp_out((struct gfs_rgrp *)
- &rgd->rg, rgd->bh[0]);
+ gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg, rgd->bits[0].bi_bh);
else
- gfs2_rgrp_out_bh(&rgd->rg, rgd->bh[0]);
+ gfs2_rgrp_out_bh(&rgd->rg, rgd->bits[0].bi_bh);
}
log_err( _("The bitmap was fixed.\n"));
} else {
diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c
index 68b1373..b2e8adf 100644
--- a/gfs2/fsck/pass5.c
+++ b/gfs2/fsck/pass5.c
@@ -218,9 +218,8 @@ static void update_rgrp(struct gfs2_sbd *sdp, struct rgrp_tree *rgp,
bits = &rgp->bits[i];
/* update the bitmaps */
- if (check_block_status(sdp, rgp->bh[i]->b_data +
- bits->bi_offset, bits->bi_len,
- &rg_block, rgp->ri.ri_data0, count))
+ if (check_block_status(sdp, bits->bi_bh->b_data + bits->bi_offset,
+ bits->bi_len, &rg_block, rgp->ri.ri_data0, count))
return;
if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
return;
@@ -275,9 +274,9 @@ static void update_rgrp(struct gfs2_sbd *sdp, struct rgrp_tree *rgp,
log_warn( _("Resource group counts updated\n"));
/* write out the rgrp */
if (sdp->gfs1)
- gfs_rgrp_out(gfs1rg, rgp->bh[0]);
+ gfs_rgrp_out(gfs1rg, rgp->bits[0].bi_bh);
else
- gfs2_rgrp_out_bh(&rgp->rg, rgp->bh[0]);
+ gfs2_rgrp_out_bh(&rgp->rg, rgp->bits[0].bi_bh);
} else
log_err( _("Resource group counts left inconsistent\n"));
}
diff --git a/gfs2/fsck/rgrepair.c b/gfs2/fsck/rgrepair.c
index 0466dd8..dd197d6 100644
--- a/gfs2/fsck/rgrepair.c
+++ b/gfs2/fsck/rgrepair.c
@@ -658,14 +658,14 @@ static int rewrite_rg_block(struct gfs2_sbd *sdp, struct rgrp_tree *rg,
(int)x+1, (int)rg->ri.ri_length, typedesc);
if (query( _("Fix the Resource Group? (y/n)"))) {
log_err( _("Attempting to repair the rgrp.\n"));
- rg->bh[x] = bread(sdp, rg->ri.ri_addr + x);
+ rg->bits[x].bi_bh = bread(sdp, rg->ri.ri_addr + x);
if (x) {
struct gfs2_meta_header mh;
mh.mh_magic = GFS2_MAGIC;
mh.mh_type = GFS2_METATYPE_RB;
mh.mh_format = GFS2_FORMAT_RB;
- gfs2_meta_header_out_bh(&mh, rg->bh[x]);
+ gfs2_meta_header_out_bh(&mh, rg->bits[x].bi_bh);
} else {
if (sdp->gfs1)
memset(&rg->rg, 0, sizeof(struct gfs_rgrp));
@@ -676,13 +676,12 @@ static int rewrite_rg_block(struct gfs2_sbd *sdp, struct rgrp_tree *rg,
rg->rg.rg_header.mh_format = GFS2_FORMAT_RG;
rg->rg.rg_free = rg->ri.ri_data;
if (sdp->gfs1)
- gfs_rgrp_out((struct gfs_rgrp *)&rg->rg,
- rg->bh[x]);
+ gfs_rgrp_out((struct gfs_rgrp *)&rg->rg, rg->bits[x].bi_bh);
else
- gfs2_rgrp_out_bh(&rg->rg, rg->bh[x]);
+ gfs2_rgrp_out_bh(&rg->rg, rg->bits[x].bi_bh);
}
- brelse(rg->bh[x]);
- rg->bh[x] = NULL;
+ brelse(rg->bits[x].bi_bh);
+ rg->bits[x].bi_bh = NULL;
return 0;
}
return 1;
@@ -712,7 +711,6 @@ static int expect_rindex_sanity(struct gfs2_sbd *sdp, int *num_rgs)
memcpy(&exp->ri, &rgd->ri, sizeof(exp->ri));
memcpy(&exp->rg, &rgd->rg, sizeof(exp->rg));
exp->bits = NULL;
- exp->bh = NULL;
gfs2_compute_bitstructs(sdp->sd_sb.sb_bsize, exp);
}
sdp->rgrps = *num_rgs;
diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
index 8b439a9..a0f6009 100644
--- a/gfs2/fsck/util.c
+++ b/gfs2/fsck/util.c
@@ -680,7 +680,7 @@ uint64_t find_free_blk(struct gfs2_sbd *sdp)
rg = &rl->rg;
for (block = 0; block < ri->ri_length; block++) {
- bh = rl->bh[block];
+ bh = rl->bits[block].bi_bh;
x = (block) ? sizeof(struct gfs2_meta_header) : sizeof(struct gfs2_rgrp);
for (; x < sdp->bsize; x++)
diff --git a/gfs2/libgfs2/fs_bits.c b/gfs2/libgfs2/fs_bits.c
index 7194949..93ddc13 100644
--- a/gfs2/libgfs2/fs_bits.c
+++ b/gfs2/libgfs2/fs_bits.c
@@ -148,7 +148,7 @@ int gfs2_set_bitmap(lgfs2_rgrp_t rgd, uint64_t blkno, int state)
if (bits == NULL)
return -1;
- byte = (unsigned char *)(rgd->bh[buf]->b_data + bits->bi_offset) +
+ byte = (unsigned char *)(bits->bi_bh->b_data + bits->bi_offset) +
(rgrp_block/GFS2_NBBY - bits->bi_start);
bit = (rgrp_block % GFS2_NBBY) * GFS2_BIT_SIZE;
@@ -156,7 +156,7 @@ int gfs2_set_bitmap(lgfs2_rgrp_t rgd, uint64_t blkno, int state)
*byte ^= cur_state << bit;
*byte |= state << bit;
- bmodified(rgd->bh[buf]);
+ bmodified(bits->bi_bh);
return 0;
}
@@ -181,6 +181,7 @@ int lgfs2_get_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, struct rgrp_tree *rgd
uint32_t i = 0;
char *byte;
unsigned int bit;
+ struct gfs2_bitmap *bi;
if (rgd == NULL) {
rgd = gfs2_blk2rgrpd(sdp, blkno);
@@ -205,10 +206,11 @@ int lgfs2_get_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, struct rgrp_tree *rgd
offset -= i * sdp->sd_blocks_per_bitmap;
}
- if (!rgd->bh || !rgd->bh[i])
+ bi = &rgd->bits[i];
+ if (!bi->bi_bh)
return GFS2_BLKST_FREE;
- byte = (rgd->bh[i]->b_data + rgd->bits[i].bi_offset) + (offset/GFS2_NBBY);
+ byte = (bi->bi_bh->b_data + bi->bi_offset) + (offset/GFS2_NBBY);
bit = (offset % GFS2_NBBY) * GFS2_BIT_SIZE;
return (*byte >> bit) & GFS2_BIT_MASK;
diff --git a/gfs2/libgfs2/fs_geometry.c b/gfs2/libgfs2/fs_geometry.c
index 587ceb8..c378dba 100644
--- a/gfs2/libgfs2/fs_geometry.c
+++ b/gfs2/libgfs2/fs_geometry.c
@@ -213,11 +213,11 @@ int build_rgrps(struct gfs2_sbd *sdp, int do_write)
if (do_write) {
for (x = 0; x < bitblocks; x++) {
- rl->bh[x] = bget(sdp, rl->start + x);
+ rl->bits[x].bi_bh = bget(sdp, rl->start + x);
if (x)
- gfs2_meta_header_out_bh(&mh, rl->bh[x]);
+ gfs2_meta_header_out_bh(&mh, rl->bits[x].bi_bh);
else
- gfs2_rgrp_out_bh(&rl->rg, rl->bh[x]);
+ gfs2_rgrp_out_bh(&rl->rg, rl->bits[x].bi_bh);
}
}
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index 015b974..aa95aa8 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -126,7 +126,7 @@ static uint64_t find_free_block(struct rgrp_tree *rgd)
unsigned long blk = 0;
struct gfs2_bitmap *bits = &rgd->bits[bm];
- blk = gfs2_bitfit((unsigned char *)rgd->bh[bm]->b_data + bits->bi_offset,
+ blk = gfs2_bitfit((uint8_t *)bits->bi_bh->b_data + bits->bi_offset,
bits->bi_len, blk, GFS2_BLKST_FREE);
if (blk != BFITNOENT) {
blkno = blk + (bits->bi_start * GFS2_NBBY) + rgd->ri.ri_data0;
@@ -149,9 +149,9 @@ static int blk_alloc_in_rg(struct gfs2_sbd *sdp, unsigned state, struct rgrp_tre
rgd->rg.rg_free--;
if (sdp->gfs1)
- gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg, rgd->bh[0]);
+ gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg, rgd->bits[0].bi_bh);
else
- gfs2_rgrp_out_bh(&rgd->rg, rgd->bh[0]);
+ gfs2_rgrp_out_bh(&rgd->rg, rgd->bits[0].bi_bh);
sdp->blks_alloced++;
return 0;
@@ -178,7 +178,7 @@ static int block_alloc(struct gfs2_sbd *sdp, const uint64_t blksreq, int state,
if (rgt == NULL)
return -1;
- if (rgt->bh[0] == NULL) {
+ if (rgt->bits[0].bi_bh == NULL) {
if (gfs2_rgrp_read(sdp, rgt))
return -1;
release = 1;
@@ -1767,9 +1767,9 @@ void gfs2_free_block(struct gfs2_sbd *sdp, uint64_t block)
gfs2_set_bitmap(rgd, block, GFS2_BLKST_FREE);
rgd->rg.rg_free++; /* adjust the free count */
if (sdp->gfs1)
- gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg, rgd->bh[0]);
+ gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg, rgd->bits[0].bi_bh);
else
- gfs2_rgrp_out_bh(&rgd->rg, rgd->bh[0]);
+ gfs2_rgrp_out_bh(&rgd->rg, rgd->bits[0].bi_bh);
sdp->blks_alloced--;
}
}
@@ -1836,9 +1836,9 @@ int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t diblock)
rgd->rg.rg_free++;
rgd->rg.rg_dinodes--;
if (sdp->gfs1)
- gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg, rgd->bh[0]);
+ gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg, rgd->bits[0].bi_bh);
else
- gfs2_rgrp_out_bh(&rgd->rg, rgd->bh[0]);
+ gfs2_rgrp_out_bh(&rgd->rg, rgd->bits[0].bi_bh);
sdp->dinodes_alloced--;
return 0;
}
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 2ba97d6..71da81e 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -170,6 +170,7 @@ struct device {
struct gfs2_bitmap
{
+ struct gfs2_buffer_head *bi_bh;
uint32_t bi_offset; /* The offset in the buffer of the first byte */
uint32_t bi_start; /* The position of the first byte in this block */
uint32_t bi_len; /* The number of bytes in this block */
@@ -185,7 +186,6 @@ struct rgrp_tree {
struct gfs2_rindex ri;
struct gfs2_rgrp rg;
struct gfs2_bitmap *bits;
- struct gfs2_buffer_head **bh;
};
typedef struct rgrp_tree *lgfs2_rgrp_t;
diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c
index c529594..e929846 100644
--- a/gfs2/libgfs2/rgrp.c
+++ b/gfs2/libgfs2/rgrp.c
@@ -67,11 +67,6 @@ int gfs2_compute_bitstructs(const uint32_t bsize, struct rgrp_tree *rgd)
rgd->bits[length - 1].bi_len) * GFS2_NBBY != rgd->ri.ri_data)
goto errbits;
- if (rgd->bh == NULL) {
- rgd->bh = calloc(length, sizeof(struct gfs2_buffer_head *));
- if (rgd->bh == NULL)
- goto errbits;
- }
return 0;
errbits:
if (ownbits)
@@ -108,8 +103,9 @@ struct rgrp_tree *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, uint64_t blk)
*/
uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_tree *rgd)
{
- int x, length = rgd->ri.ri_length;
+ unsigned x, length = rgd->ri.ri_length;
uint64_t max_rgrp_bitbytes, max_rgrp_len;
+ struct gfs2_buffer_head **bhs;
/* Max size of an rgrp is 2GB. Figure out how many blocks that is: */
max_rgrp_bitbytes = ((2147483648 / sdp->bsize) / GFS2_NBBY);
@@ -118,27 +114,38 @@ uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_tree *rgd)
return -1;
if (gfs2_check_range(sdp, rgd->ri.ri_addr))
return -1;
- if (breadm(sdp, rgd->bh, length, rgd->ri.ri_addr))
+
+ bhs = calloc(length, sizeof(struct gfs2_buffer_head *));
+ if (bhs == NULL)
+ return -1;
+
+ if (breadm(sdp, bhs, length, rgd->ri.ri_addr)) {
+ free(bhs);
return -1;
- for (x = 0; x < length; x++){
- if(gfs2_check_meta(rgd->bh[x], (x) ? GFS2_METATYPE_RB : GFS2_METATYPE_RG))
- {
- uint64_t error;
+ }
+
+ for (x = 0; x < length; x++) {
+ struct gfs2_bitmap *bi = &rgd->bits[x];
+ int mtype = (x ? GFS2_METATYPE_RB : GFS2_METATYPE_RG);
- error = rgd->ri.ri_addr + x;
+ bi->bi_bh = bhs[x];
+ if (gfs2_check_meta(bi->bi_bh, mtype)) {
+ unsigned err = x;
for (; x >= 0; x--) {
- brelse(rgd->bh[x]);
- rgd->bh[x] = NULL;
+ brelse(rgd->bits[x].bi_bh);
+ rgd->bits[x].bi_bh = NULL;
}
- return error;
+ free(bhs);
+ return rgd->ri.ri_addr + err;
}
}
- if (rgd->bh && rgd->bh[0]) {
+ if (x > 0) {
if (sdp->gfs1)
- gfs_rgrp_in((struct gfs_rgrp *)&rgd->rg, rgd->bh[0]);
+ gfs_rgrp_in((struct gfs_rgrp *)&rgd->rg, rgd->bits[0].bi_bh);
else
- gfs2_rgrp_in(&rgd->rg, rgd->bh[0]);
+ gfs2_rgrp_in(&rgd->rg, rgd->bits[0].bi_bh);
}
+ free(bhs);
return 0;
}
@@ -147,10 +154,9 @@ void gfs2_rgrp_relse(struct rgrp_tree *rgd)
int x, length = rgd->ri.ri_length;
for (x = 0; x < length; x++) {
- if (rgd->bh) {
- if (rgd->bh[x])
- brelse(rgd->bh[x]);
- rgd->bh[x] = NULL;
+ if (rgd->bits[x].bi_bh) {
+ brelse(rgd->bits[x].bi_bh);
+ rgd->bits[x].bi_bh = NULL;
}
}
}
@@ -193,11 +199,12 @@ void gfs2_rgrp_free(struct osi_root *rgrp_tree)
while ((n = osi_first(rgrp_tree))) {
rgd = (struct rgrp_tree *)n;
- if (rgd->bh && rgd->bh[0]) { /* if a buffer exists */
+
+ if (rgd->bits[0].bi_bh) { /* if a buffer exists */
rgs_since_sync++;
if (rgs_since_sync >= RG_SYNC_TOLERANCE) {
if (!sdp)
- sdp = rgd->bh[0]->sdp;
+ sdp = rgd->bits[0].bi_bh->sdp;
fsync(sdp->device_fd);
rgs_since_sync = 0;
}
@@ -205,10 +212,6 @@ void gfs2_rgrp_free(struct osi_root *rgrp_tree)
}
if(rgd->bits)
free(rgd->bits);
- if(rgd->bh) {
- free(rgd->bh);
- rgd->bh = NULL;
- }
osi_erase(&rgd->node, rgrp_tree);
free(rgd);
}
@@ -407,9 +410,9 @@ void lgfs2_rgrps_free(lgfs2_rgrps_t *rgs)
while ((rg = (struct rgrp_tree *)osi_first(tree))) {
int i;
for (i = 0; i < rg->ri.ri_length; i++) {
- if (rg->bh[i] != NULL) {
- free(rg->bh[i]);
- rg->bh[i] = NULL;
+ if (rg->bits[i].bi_bh != NULL) {
+ free(rg->bits[i].bi_bh);
+ rg->bits[i].bi_bh = NULL;
}
}
osi_erase(&rg->node, tree);
@@ -521,14 +524,11 @@ lgfs2_rgrp_t lgfs2_rgrps_append(lgfs2_rgrps_t rgs, struct gfs2_rindex *entry)
link = &lastrg->node.osi_right;
}
- rg = calloc(1, sizeof(*rg) +
- (entry->ri_length * sizeof(struct gfs2_bitmap)) +
- (entry->ri_length * sizeof(struct gfs2_buffer_head *)));
+ rg = calloc(1, sizeof(*rg) + (entry->ri_length * sizeof(struct gfs2_bitmap)));
if (rg == NULL)
return NULL;
rg->bits = (struct gfs2_bitmap *)(rg + 1);
- rg->bh = (struct gfs2_buffer_head **)(rg->bits + entry->ri_length);
osi_link_node(&rg->node, parent, link);
osi_insert_color(&rg->node, &rgs->root);
diff --git a/gfs2/libgfs2/structures.c b/gfs2/libgfs2/structures.c
index ee49dce..9d90657 100644
--- a/gfs2/libgfs2/structures.c
+++ b/gfs2/libgfs2/structures.c
@@ -560,7 +560,7 @@ unsigned lgfs2_bm_scan(struct rgrp_tree *rgd, unsigned idx, uint64_t *buf, uint8
uint32_t blk = 0;
while(blk < (bi->bi_len * GFS2_NBBY)) {
- blk = gfs2_bitfit((const unsigned char *)rgd->bh[idx]->b_data + bi->bi_offset,
+ blk = gfs2_bitfit((uint8_t *)bi->bi_bh->b_data + bi->bi_offset,
bi->bi_len, blk, state);
if (blk == BFITNOENT)
break;
9 years, 8 months
gfs2-utils: RHEL7 - libgfs2: Keep a pointer to the sbd in lgfs2_rgrps_t
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=8e3a9dfa...
Commit: 8e3a9dfa499956d55ee96ffd618aceb6dd7a7434
Parent: 34eddb6449ccd1896a5dbea27028c48a6dc2a11f
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Fri Apr 4 02:10:17 2014 +0100
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Fri Sep 5 14:57:46 2014 +0100
libgfs2: Keep a pointer to the sbd in lgfs2_rgrps_t
As a set of resource groups is tied to a particular file system (block
size, device length...) it makes sense to keep a reference to the file
system in the lgfs2_rgrps_t type. This allows us to avoid duplication of
the bsize and device length fields, reduces parameter counts and
provides a convenient way to access file system-specific values in
resource group-related functions.
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/libgfs2/libgfs2.h | 5 +++--
gfs2/libgfs2/rgrp.c | 24 +++++++++++-------------
gfs2/mkfs/main_grow.c | 2 +-
gfs2/mkfs/main_mkfs.c | 2 +-
4 files changed, 16 insertions(+), 17 deletions(-)
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 041e5fd..2ba97d6 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -175,6 +175,8 @@ struct gfs2_bitmap
uint32_t bi_len; /* The number of bytes in this block */
};
+struct gfs2_sbd;
+
struct rgrp_tree {
struct osi_node node;
uint64_t start; /* The offset of the beginning of this resource group */
@@ -189,7 +191,7 @@ struct rgrp_tree {
typedef struct rgrp_tree *lgfs2_rgrp_t;
typedef struct _lgfs2_rgrps *lgfs2_rgrps_t;
-extern lgfs2_rgrps_t lgfs2_rgrps_init(unsigned bsize, uint64_t devlen, uint64_t align, uint64_t offset);
+extern lgfs2_rgrps_t lgfs2_rgrps_init(const struct gfs2_sbd *sdp, uint64_t align, uint64_t offset);
extern void lgfs2_rgrps_free(lgfs2_rgrps_t *rgs);
extern uint64_t lgfs2_rindex_entry_new(lgfs2_rgrps_t rgs, struct gfs2_rindex *entry, uint64_t addr, uint32_t len);
extern unsigned lgfs2_rindex_read_fd(int fd, lgfs2_rgrps_t rgs);
@@ -223,7 +225,6 @@ struct special_blocks {
uint64_t block;
};
-struct gfs2_sbd;
struct gfs2_inode {
int bh_owned; /* Is this bh owned, iow, should we release it later? */
struct gfs2_dinode i_di;
diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c
index 901a7bf..c529594 100644
--- a/gfs2/libgfs2/rgrp.c
+++ b/gfs2/libgfs2/rgrp.c
@@ -227,10 +227,9 @@ struct rgplan {
struct _lgfs2_rgrps {
struct osi_root root;
struct rgplan plan[2];
- unsigned bsize;
+ const struct gfs2_sbd *sdp;
unsigned long align;
unsigned long align_off;
- uint64_t devlen;
};
static uint64_t align_block(const uint64_t base, const uint64_t align)
@@ -280,8 +279,8 @@ uint32_t lgfs2_rgrp_align_len(const lgfs2_rgrps_t rgs, uint32_t len)
*/
uint32_t lgfs2_rgrps_plan(const lgfs2_rgrps_t rgs, uint64_t space, uint32_t tgtsize)
{
- uint32_t maxlen = (GFS2_MAX_RGSIZE << 20) / rgs->bsize;
- uint32_t minlen = (GFS2_MIN_RGSIZE << 20) / rgs->bsize;
+ uint32_t maxlen = (GFS2_MAX_RGSIZE << 20) / rgs->sdp->bsize;
+ uint32_t minlen = (GFS2_MIN_RGSIZE << 20) / rgs->sdp->bsize;
/* Apps should already have checked that the rg size is <=
GFS2_MAX_RGSIZE but just in case alignment pushes it over we clamp
@@ -340,7 +339,7 @@ uint32_t lgfs2_rgrps_plan(const lgfs2_rgrps_t rgs, uint64_t space, uint32_t tgts
* offset: The required stripe offset of the resource groups
* Returns an initialised lgfs2_rgrps_t or NULL if unsuccessful with errno set
*/
-lgfs2_rgrps_t lgfs2_rgrps_init(unsigned bsize, uint64_t devlen, uint64_t align, uint64_t offset)
+lgfs2_rgrps_t lgfs2_rgrps_init(const struct gfs2_sbd *sdp, uint64_t align, uint64_t offset)
{
lgfs2_rgrps_t rgs;
@@ -352,8 +351,7 @@ lgfs2_rgrps_t lgfs2_rgrps_init(unsigned bsize, uint64_t devlen, uint64_t align,
if (rgs == NULL)
return NULL;
- rgs->bsize = bsize;
- rgs->devlen = devlen;
+ rgs->sdp = sdp;
rgs->align = align;
rgs->align_off = offset;
memset(&rgs->root, 0, sizeof(rgs->root));
@@ -451,11 +449,11 @@ uint64_t lgfs2_rindex_entry_new(lgfs2_rgrps_t rgs, struct gfs2_rindex *ri, uint6
rgs->plan[plan].num--;
}
- if (addr + len > rgs->devlen)
+ if (addr + len > rgs->sdp->device.length)
return 0;
ri->ri_addr = addr;
- ri->ri_length = rgblocks2bitblocks(rgs->bsize, len, &ri->ri_data);
+ ri->ri_length = rgblocks2bitblocks(rgs->sdp->bsize, len, &ri->ri_data);
ri->__pad = 0;
ri->ri_data0 = ri->ri_addr + ri->ri_length;
ri->ri_bitbytes = ri->ri_data / GFS2_NBBY;
@@ -541,7 +539,7 @@ lgfs2_rgrp_t lgfs2_rgrps_append(lgfs2_rgrps_t rgs, struct gfs2_rindex *entry)
rg->rg.rg_header.mh_format = GFS2_FORMAT_RG;
rg->rg.rg_free = rg->ri.ri_data;
- compute_bitmaps(rg, rgs->bsize);
+ compute_bitmaps(rg, rgs->sdp->bsize);
return rg;
}
@@ -552,7 +550,7 @@ lgfs2_rgrp_t lgfs2_rgrps_append(lgfs2_rgrps_t rgs, struct gfs2_rindex *entry)
int lgfs2_rgrp_write(const lgfs2_rgrps_t rgs, int fd, const lgfs2_rgrp_t rg)
{
ssize_t ret = 0;
- size_t len = rg->ri.ri_length * rgs->bsize;
+ size_t len = rg->ri.ri_length * rgs->sdp->bsize;
unsigned int i;
const struct gfs2_meta_header bmh = {
.mh_magic = GFS2_MAGIC,
@@ -565,9 +563,9 @@ int lgfs2_rgrp_write(const lgfs2_rgrps_t rgs, int fd, const lgfs2_rgrp_t rg)
gfs2_rgrp_out(&rg->rg, buff);
for (i = 1; i < rg->ri.ri_length; i++)
- gfs2_meta_header_out(&bmh, buff + (i * rgs->bsize));
+ gfs2_meta_header_out(&bmh, buff + (i * rgs->sdp->bsize));
- ret = pwrite(fd, buff, len, rg->ri.ri_addr * rgs->bsize);
+ ret = pwrite(fd, buff, len, rg->ri.ri_addr * rgs->sdp->bsize);
if (ret != len) {
free(buff);
return -1;
diff --git a/gfs2/mkfs/main_grow.c b/gfs2/mkfs/main_grow.c
index 5da809a..95fbd1d 100644
--- a/gfs2/mkfs/main_grow.c
+++ b/gfs2/mkfs/main_grow.c
@@ -178,7 +178,7 @@ static lgfs2_rgrps_t rgrps_init(struct gfs2_sbd *sdp)
}
blkid_free_probe(pr);
- return lgfs2_rgrps_init(sdp->bsize, sdp->device.length, al_base, al_off);
+ return lgfs2_rgrps_init(sdp, al_base, al_off);
}
/**
diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c
index f778e8d..bf7c9cd 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
@@ -600,7 +600,7 @@ static lgfs2_rgrps_t rgs_init(struct mkfs_opts *opts, struct gfs2_sbd *sdp)
}
}
- rgs = lgfs2_rgrps_init(sdp->bsize, sdp->device.length, al_base, al_off);
+ rgs = lgfs2_rgrps_init(sdp, al_base, al_off);
if (rgs == NULL) {
perror(_("Could not initialise resource groups"));
exit(-1);
9 years, 8 months
gfs2-utils: RHEL7 - gfs2_edit: Print block types with log descriptors
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=34eddb64...
Commit: 34eddb6449ccd1896a5dbea27028c48a6dc2a11f
Parent: 674b743c39a6582b124634557f9c2850b9b19c63
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Wed Jun 11 12:07:46 2014 -0500
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Thu Jul 24 17:21:52 2014 +0100
gfs2_edit: Print block types with log descriptors
This patch makes gfs2_edit's journal print function print the metadata
block type along side the block number in its log descriptor output.
For example: In the past, when a log descriptor was printed, it looked
like this:
0x8200 (j+ 163): Log descriptor, type 300 (Metadata) len:504, data1: 503 (503)
0x70eb772 0x70df987 0x70dc7a1 0x70eb574
0x70dc5a3 0x70eb376 0x70dc3a5 0x70eb178
0x70dc1a7 0x70eaf7a 0x70dbfa9 0x70ead7c
With this patch, the output is more useful:
0x8200 (j+ 163): Log descriptor, type 300 (Metadata) len:504, data1: 503 (503)
0x70eb772 in 0x70df987 rb 0x70dc7a1 in 0x70eb574 in
0x70dc5a3 in 0x70eb376 in 0x70dc3a5 in 0x70eb178 in
0x70dc1a7 in 0x70eaf7a in 0x70dbfa9 in 0x70ead7c in
In this case, "in" indicates indirect blocks, and "rb" indicates a rgrp bitmap.
This is useful for getting a bigger picture of what that journal descriptor
contains and represents.
---
gfs2/edit/hexedit.h | 1 +
gfs2/edit/journal.c | 15 ++++++++++++---
2 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/gfs2/edit/hexedit.h b/gfs2/edit/hexedit.h
index 541684a..f23c581 100644
--- a/gfs2/edit/hexedit.h
+++ b/gfs2/edit/hexedit.h
@@ -27,6 +27,7 @@ enum dsp_mode { HEX_MODE = 0, GFS2_MODE = 1, EXTENDED_MODE = 2, INIT_MODE = 3 };
#define RGLIST_DUMMY_BLOCK -2
#define JOURNALS_DUMMY_BLOCK -3
+extern const char *mtypes[];
extern struct gfs2_sb sb;
extern uint64_t block;
extern int blockhist;
diff --git a/gfs2/edit/journal.c b/gfs2/edit/journal.c
index bb56649..a72a044 100644
--- a/gfs2/edit/journal.c
+++ b/gfs2/edit/journal.c
@@ -202,6 +202,7 @@ static int print_ld_blks(const uint64_t *b, const char *end, int start_line,
{
int bcount = 0, found_tblk = 0, found_bblk = 0;
static char str[256];
+ struct gfs2_buffer_head *j_bmap_bh;
if (tblk_off)
*tblk_off = 0;
@@ -218,8 +219,17 @@ static int print_ld_blks(const uint64_t *b, const char *end, int start_line,
}
bcount++;
if (prnt) {
- sprintf(str, "0x%llx",
- (unsigned long long)be64_to_cpu(*b));
+ if (is_meta_ld) {
+ j_bmap_bh = bread(&sbd, abs_block +
+ bcount);
+ sprintf(str, "0x%llx %2s",
+ (unsigned long long)be64_to_cpu(*b),
+ mtypes[lgfs2_get_block_type(j_bmap_bh)]);
+ brelse(j_bmap_bh);
+ } else {
+ sprintf(str, "0x%llx",
+ (unsigned long long)be64_to_cpu(*b));
+ }
print_gfs2("%-18.18s ", str);
}
if (!found_tblk && tblk_off)
@@ -237,7 +247,6 @@ static int print_ld_blks(const uint64_t *b, const char *end, int start_line,
int type, bmap = 0;
uint64_t o;
struct gfs2_buffer_head *save_bh;
- struct gfs2_buffer_head *j_bmap_bh;
found_bblk = 1;
print_gfs2("<-------------------------");
9 years, 8 months