cluster-devel.redhat.com archive mirror
 help / color / mirror / Atom feed
From: Andrew Price <anprice@redhat.com>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] [PATCH 07/14] libgfs2: Split out the rindex calculation from lgfs2_rgrp_append
Date: Thu,  3 Apr 2014 16:12:40 +0100	[thread overview]
Message-ID: <1396537967-12399-8-git-send-email-anprice@redhat.com> (raw)
In-Reply-To: <1396537967-12399-1-git-send-email-anprice@redhat.com>

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@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;
 }
-- 
1.8.5.3



  parent reply	other threads:[~2014-04-03 15:12 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-04-03 15:12 [Cluster-devel] [PATCH 00/14] gfs2_grow and libgfs2 rgrp API improvements Andrew Price
2014-04-03 15:12 ` [Cluster-devel] [PATCH 01/14] mkfs.gfs2: Make dev a member of mkfs_opts Andrew Price
2014-04-03 15:12 ` [Cluster-devel] [PATCH 02/14] libgfs2: Add lgfs2_space_for_data() Andrew Price
2014-04-03 15:12 ` [Cluster-devel] [PATCH 03/14] libgfs2: Don't try to read more than IOV_MAX iovecs Andrew Price
2014-04-03 15:12 ` [Cluster-devel] [PATCH 04/14] mkfs.gfs2: Fix the resource group layout strategy, again Andrew Price
2014-04-03 15:12 ` [Cluster-devel] [PATCH 05/14] libgfs2: Don't call gfs2_blk2rgrpd in gfs2_set_bitmap Andrew Price
2014-04-03 15:12 ` [Cluster-devel] [PATCH 06/14] libgfs2: Add abstractions for rgrp tree traversal Andrew Price
2014-04-03 15:12 ` Andrew Price [this message]
2014-04-03 15:12 ` [Cluster-devel] [PATCH 08/14] libgfs2: Consolidate rgrp_tree and bitstruct allocations Andrew Price
2014-04-03 15:12 ` [Cluster-devel] [PATCH 09/14] libgfs2: Add a lgfs2_rindex_read_fd() function Andrew Price
2014-04-03 15:12 ` [Cluster-devel] [PATCH 10/14] libgfs2: Const-ify the 'ri' argument to gfs2_rindex_out Andrew Price
2014-04-03 15:12 ` [Cluster-devel] [PATCH 11/14] libgfs2: Fix off-by-one in lgfs2_rgrps_plan Andrew Price
2014-04-03 15:12 ` [Cluster-devel] [PATCH 12/14] libgfs2: Stick to the (rgrp) plan in lgfs2_rindex_entry_new Andrew Price
2014-04-03 15:12 ` [Cluster-devel] [PATCH 13/14] gfs2_grow: Migrate to the new resource group API Andrew Price
2014-04-03 15:12 ` [Cluster-devel] [PATCH 14/14] gfs2_grow: Add stripe alignment Andrew Price
2014-04-07 15:15 ` [Cluster-devel] [PATCH 00/14] gfs2_grow and libgfs2 rgrp API improvements Bob Peterson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1396537967-12399-8-git-send-email-anprice@redhat.com \
    --to=anprice@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).