Gitweb:
http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=f1e26fad...
Commit: f1e26fadaaf4f79b09364f5304b0292f0116d1fe
Parent: 696eccf4447a9421f2706f5f4b554e098339422c
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Sat Mar 29 02:57:10 2014 +0000
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Sat Mar 29 23:20:29 2014 +0000
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(a)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;
}