gfs2-utils: RHEL7 - libgfs2: Split out the rindex calculation from lgfs2_rgrp_append

Andrew Price andyp at fedoraproject.org
Mon Sep 8 17:33:23 UTC 2014


Gitweb:        http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=965a4e9a7cb95d019239896f6f5c2b303f36b2ca
Commit:        965a4e9a7cb95d019239896f6f5c2b303f36b2ca
Parent:        a0a6c1ed7c74cd25b51f4a8558d11d7d2e13194b
Author:        Andrew Price <anprice at redhat.com>
AuthorDate:    Sat Mar 29 02:57:10 2014 +0000
Committer:     Andrew Price <anprice at redhat.com>
CommitterDate: Thu Jul 24 17:14:23 2014 +0100

libgfs2: Split out the rindex calculation from lgfs2_rgrp_append

In order to better support gfs2_grow the new resource group API needs to
expose rindex entry calculation and lightweight scanning of existing
resource groups (i.e. only read the rindex and forget each entry when
done). This patch takes care of the former by adding a
lgfs2_rindex_entry_new() function which calculates an rindex entry only
and not the whole lgfs2_rgrp_t structure. Now we can calculate the rgrp
geometry as early as possible and avoid passing around address+length
arguments where a rindex would be more appropriate.

Signed-off-by: Andrew Price <anprice at redhat.com>
---
 gfs2/libgfs2/libgfs2.h |    4 ++-
 gfs2/libgfs2/rgrp.c    |   83 ++++++++++++++++++++++++++++++-----------------
 gfs2/mkfs/main_mkfs.c  |   26 ++++++++-------
 3 files changed, 70 insertions(+), 43 deletions(-)

diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 3eeb04d..99f64fc 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -190,13 +190,15 @@ 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 uint64_t lgfs2_rindex_entry_new(lgfs2_rgrps_t rgs, struct gfs2_rindex *entry, uint64_t addr, uint32_t len);
 extern uint64_t lgfs2_rgrp_align_addr(const lgfs2_rgrps_t rgs, uint64_t addr);
 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_rgrp_append(lgfs2_rgrps_t rgs, uint64_t addr, uint32_t rglen, uint64_t *nextaddr);
+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 struct gfs2_rindex *lgfs2_rgrp_index(lgfs2_rgrp_t rg);
+extern struct gfs2_rgrp *lgfs2_rgrp_rgrp(lgfs2_rgrp_t rg);
 extern lgfs2_rgrp_t lgfs2_rgrp_first(lgfs2_rgrps_t rgs);
 extern lgfs2_rgrp_t lgfs2_rgrp_last(lgfs2_rgrps_t rgs);
 extern lgfs2_rgrp_t lgfs2_rgrp_next(lgfs2_rgrp_t rg);
diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c
index fb2b115..2ae3ed6 100644
--- a/gfs2/libgfs2/rgrp.c
+++ b/gfs2/libgfs2/rgrp.c
@@ -370,6 +370,46 @@ lgfs2_rgrps_t lgfs2_rgrps_init(unsigned bsize, uint64_t devlen, uint64_t align,
 }
 
 /**
+ * Calculate the fields for a new entry in the resource group index.
+ * ri: A pointer to the resource group index entry to be calculated.
+ * addr: The address at which to place this resource group
+ * len: The required length of the resource group, in fs blocks.
+ *        If rglen is 0, geometry previously calculated by lgfs2_rgrps_plan() will be used.
+ * Returns the calculated address of the next resource group or 0 with errno set:
+ *   EINVAL - The entry pointer is NULL
+ *   ENOSPC - This rgrp would extend past the end of the device
+ */
+uint64_t lgfs2_rindex_entry_new(lgfs2_rgrps_t rgs, struct gfs2_rindex *ri, uint64_t addr, uint32_t len)
+{
+	errno = EINVAL;
+	if (!ri)
+		return 0;
+
+	errno = ENOSPC;
+	if (len == 0) {
+		if (rgs->plan[0].num > 0) {
+			len = rgs->plan[0].len;
+			rgs->plan[0].num--;
+		} else if (rgs->plan[1].num > 0) {
+			len = rgs->plan[1].len;
+			rgs->plan[1].num--;
+		} else
+			return 0;
+	}
+	if (addr + len > rgs->devlen)
+		return 0;
+
+	ri->ri_addr = addr;
+	ri->ri_length = rgblocks2bitblocks(rgs->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;
+	memset(&ri->ri_reserved, 0, sizeof(ri->ri_reserved));
+
+	return ri->ri_addr + len;
+}
+
+/**
  * Return the rindex structure relating to a a resource group.
  */
 struct gfs2_rindex *lgfs2_rgrp_index(lgfs2_rgrp_t rg)
@@ -378,6 +418,14 @@ struct gfs2_rindex *lgfs2_rgrp_index(lgfs2_rgrp_t rg)
 }
 
 /**
+ * Return the rgrp structure relating to a a resource group.
+ */
+struct gfs2_rgrp *lgfs2_rgrp_rgrp(lgfs2_rgrp_t rg)
+{
+	return &rg->rg;
+}
+
+/**
  * Returns the total resource group size, in blocks, required to give blksreq data blocks
  */
 unsigned lgfs2_rgsize_for_data(uint64_t blksreq, unsigned bsize)
@@ -397,44 +445,21 @@ struct osi_node *lgfs2_rgrps_root(lgfs2_rgrps_t rgs)
 }
 
 /**
- * Create a new resource group after the last resource group in a set.
+ * Insert a new resource group after the last resource group in a set.
  * rgs: The set of resource groups
- * addr: The address at which to place this resource group
- * rglen: The required length of the resource group, in fs blocks.
+ * entry: The entry to be added
  * Returns the new resource group on success or NULL on failure with errno set.
- * If errno is ENOSPC on a NULL return from this function, it could be
- * interpreted as 'finished' unless you expected there to be enough space on
- * the device for the resource group.
  */
-lgfs2_rgrp_t lgfs2_rgrp_append(lgfs2_rgrps_t rgs, uint64_t addr, uint32_t rglen, uint64_t *nextaddr)
+lgfs2_rgrp_t lgfs2_rgrps_append(lgfs2_rgrps_t rgs, struct gfs2_rindex *entry)
 {
 	int err = 0;
 	lgfs2_rgrp_t rg;
 
-	if (rglen == 0) {
-		if (rgs->plan[0].num > 0) {
-			rglen = rgs->plan[0].len;
-			rgs->plan[0].num--;
-		} else if (rgs->plan[1].num > 0) {
-			rglen = rgs->plan[1].len;
-			rgs->plan[1].num--;
-		} else {
-			errno = ENOSPC;
-			return NULL;
-		}
-	}
-	if (addr + rglen > rgs->devlen) {
-		errno = ENOSPC;
-		return NULL;
-	}
-
-	rg = rgrp_insert(&rgs->root, addr);
+	rg = rgrp_insert(&rgs->root, entry->ri_addr);
 	if (rg == NULL)
 		return NULL;
 
-	rg->ri.ri_length = rgblocks2bitblocks(rgs->bsize, rglen, &rg->ri.ri_data);
-	rg->ri.ri_data0 = rg->ri.ri_addr + rg->ri.ri_length;
-	rg->ri.ri_bitbytes = rg->ri.ri_data / GFS2_NBBY;
+	memcpy(&rg->ri, entry, sizeof(struct gfs2_rindex));
 	rg->rg.rg_header.mh_magic = GFS2_MAGIC;
 	rg->rg.rg_header.mh_type = GFS2_METATYPE_RG;
 	rg->rg.rg_header.mh_format = GFS2_FORMAT_RG;
@@ -443,8 +468,6 @@ lgfs2_rgrp_t lgfs2_rgrp_append(lgfs2_rgrps_t rgs, uint64_t addr, uint32_t rglen,
 	if (err != 0)
 		return NULL;
 
-	if (nextaddr)
-		*nextaddr = rg->ri.ri_addr + rglen;
 	return rg;
 }
 
diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c
index ae82c9f..67850c8 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
@@ -625,16 +625,13 @@ static lgfs2_rgrps_t rgs_init(struct mkfs_opts *opts, struct gfs2_sbd *sdp)
 	return rgs;
 }
 
-static int place_rgrp(struct gfs2_sbd *sdp, lgfs2_rgrps_t rgs, uint64_t rgaddr, uint32_t len, uint64_t *next)
+static int place_rgrp(struct gfs2_sbd *sdp, lgfs2_rgrps_t rgs, struct gfs2_rindex *ri)
 {
 	int err = 0;
 	lgfs2_rgrp_t rg = NULL;
-	struct gfs2_rindex *ri = NULL;
 
-	rg = lgfs2_rgrp_append(rgs, rgaddr, len, next);
+	rg = lgfs2_rgrps_append(rgs, ri);
 	if (rg == NULL) {
-		if (errno == ENOSPC)
-			return 1;
 		perror(_("Failed to create resource group"));
 		return -1;
 	}
@@ -643,7 +640,6 @@ static int place_rgrp(struct gfs2_sbd *sdp, lgfs2_rgrps_t rgs, uint64_t rgaddr,
 		perror(_("Failed to write resource group"));
 		return -1;
 	}
-	ri = lgfs2_rgrp_index(rg);
 	if (sdp->debug) {
 		gfs2_rindex_print(ri);
 		printf("\n");
@@ -656,6 +652,7 @@ static int place_rgrp(struct gfs2_sbd *sdp, lgfs2_rgrps_t rgs, uint64_t rgaddr,
 
 static int place_rgrps(struct gfs2_sbd *sdp, lgfs2_rgrps_t rgs, struct mkfs_opts *opts)
 {
+	struct gfs2_rindex ri;
 	uint64_t jfsize = lgfs2_space_for_data(sdp, sdp->bsize, opts->jsize << 20);
 	uint32_t jrgsize = lgfs2_rgsize_for_data(jfsize, sdp->bsize);
 	uint64_t rgaddr = lgfs2_rgrp_align_addr(rgs, sdp->sb_addr + 1);
@@ -673,21 +670,26 @@ static int place_rgrps(struct gfs2_sbd *sdp, lgfs2_rgrps_t rgs, struct mkfs_opts
 	}
 
 	for (j = 0; j < opts->journals; j++) {
-		int result = place_rgrp(sdp, rgs, rgaddr, jrgsize, NULL);
+		int result;
+		rgaddr = lgfs2_rindex_entry_new(rgs, &ri, rgaddr, jrgsize);
+		if (rgaddr == 0) /* Reached the end when we still have journals to write */
+			return 1;
+		result = place_rgrp(sdp, rgs, &ri);
 		if (result != 0)
 			return result;
-		rgaddr = rgaddr + jrgsize;
 	}
 
 	if (rgsize != jrgsize)
 		lgfs2_rgrps_plan(rgs, sdp->device.length - rgaddr, ((opts->rgsize << 20) / sdp->bsize));
 
 	while (1) {
-		int result = place_rgrp(sdp, rgs, rgaddr, 0, &rgaddr);
-		if (result < 0)
-			return result;
-		if (result > 0)
+		int result;
+		rgaddr = lgfs2_rindex_entry_new(rgs, &ri, rgaddr, 0);
+		if (rgaddr == 0)
 			break; /* Done */
+		result = place_rgrp(sdp, rgs, &ri);
+		if (result)
+			return result;
 	}
 	return 0;
 }


More information about the cluster-commits mailing list