gfs2-utils: RHEL7 - libgfs2: Remove UI fields from struct gfs2_sbd
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=26b7af33...
Commit: 26b7af3357ba6d81fad5096a0e594302502bcd5d
Parent: 3d1e4a29ff4776ffeecea3b55c79467bc6884e6a
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Wed May 7 13:02:55 2014 +0100
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Thu Jul 24 17:15:39 2014 +0100
libgfs2: Remove UI fields from struct gfs2_sbd
The 'override' field wasn't being used at all and the 'quiet' field was
only being used by gfs2_jadd. Remove them in favour of keeping user
interface options in the apps themselves.
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/libgfs2/libgfs2.h | 2 --
gfs2/mkfs/main_jadd.c | 13 +++++++------
2 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index b98d314..5fdf9af 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -277,8 +277,6 @@ struct gfs2_sbd {
unsigned int qcsize; /* Size of quota change files (in MB) */
int debug;
- int quiet;
- int override;
char device_name[PATH_MAX];
char *path_name;
diff --git a/gfs2/mkfs/main_jadd.c b/gfs2/mkfs/main_jadd.c
index 47af055..d01e3b3 100644
--- a/gfs2/mkfs/main_jadd.c
+++ b/gfs2/mkfs/main_jadd.c
@@ -27,6 +27,8 @@
#define BUF_SIZE 4096
#define RANDOM(values) ((values) * (random() / (RAND_MAX + 1.0)))
+static int quiet = 0;
+
static void
make_jdata(int fd, const char *value)
{
@@ -139,7 +141,7 @@ static void decode_arguments(int argc, char *argv[], struct gfs2_sbd *sdp)
sdp->md.journals = atoi(optarg);
break;
case 'q':
- sdp->quiet = TRUE;
+ quiet = 1;
break;
case 'V':
printf("gfs2_jadd %s (built %s %s)\n", VERSION,
@@ -166,7 +168,7 @@ static void decode_arguments(int argc, char *argv[], struct gfs2_sbd *sdp)
optind++;
} else
die( _("no path specified (try -h for help)\n"));
-
+
if (optind < argc)
die( _("Unrecognized argument: %s\n"), argv[optind]);
@@ -175,13 +177,12 @@ static void decode_arguments(int argc, char *argv[], struct gfs2_sbd *sdp)
printf(" qcsize = %u\n", sdp->qcsize);
printf(" jsize = %u\n", sdp->jsize);
printf(" journals = %u\n", sdp->md.journals);
- printf(" quiet = %d\n", sdp->quiet);
+ printf(" quiet = %d\n", quiet);
printf(" path = %s\n", sdp->path_name);
}
}
-static void
-verify_arguments(struct gfs2_sbd *sdp)
+static void verify_arguments(struct gfs2_sbd *sdp)
{
if (!sdp->md.journals)
die( _("no journals specified\n"));
@@ -201,7 +202,7 @@ static void print_results(struct gfs2_sbd *sdp)
{
if (sdp->debug)
printf("\n");
- else if (sdp->quiet)
+ else if (quiet)
return;
printf( _("Filesystem: %s\n"), sdp->path_name);
9 years, 8 months
gfs2-utils: RHEL7 - gfs2-utils: Expressly expunge 'expert mode'
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=3d1e4a29...
Commit: 3d1e4a29ff4776ffeecea3b55c79467bc6884e6a
Parent: 7ecd2f27dcfc43088d174d6559d6b06819fd12b6
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Tue Apr 8 14:39:34 2014 +0100
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Thu Jul 24 17:15:39 2014 +0100
gfs2-utils: Expressly expunge 'expert mode'
mkfs.gfs2 and gfs2_jadd used struct gfs2_sbd.expert to put them into an
undocumented 'expert mode' but didn't really do anything useful in that
mode. Remove that field and other 'expert' references.
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/libgfs2/libgfs2.h | 2 --
gfs2/mkfs/main_jadd.c | 15 ++++-----------
gfs2/mkfs/main_mkfs.c | 23 +++++++----------------
3 files changed, 11 insertions(+), 29 deletions(-)
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 3353f5f..b98d314 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -278,7 +278,6 @@ struct gfs2_sbd {
int debug;
int quiet;
- int expert;
int override;
char device_name[PATH_MAX];
@@ -352,7 +351,6 @@ struct metapath {
#define GFS2_MIN_GROW_SIZE (10)
#define GFS2_EXCESSIVE_RGS (10000)
-#define GFS2_EXP_MIN_RGSIZE (1)
#define GFS2_MIN_RGSIZE (32)
#define GFS2_MAX_RGSIZE (2048)
diff --git a/gfs2/mkfs/main_jadd.c b/gfs2/mkfs/main_jadd.c
index 815dd52..47af055 100644
--- a/gfs2/mkfs/main_jadd.c
+++ b/gfs2/mkfs/main_jadd.c
@@ -117,10 +117,10 @@ static void decode_arguments(int argc, char *argv[], struct gfs2_sbd *sdp)
{
int cont = TRUE;
int optchar;
-
+
while (cont) {
- optchar = getopt(argc, argv, "c:DhJ:j:qu:VX");
-
+ optchar = getopt(argc, argv, "c:DhJ:j:qu:V");
+
switch (optchar) {
case 'c':
sdp->qcsize = atoi(optarg);
@@ -147,9 +147,6 @@ static void decode_arguments(int argc, char *argv[], struct gfs2_sbd *sdp)
printf(REDHAT_COPYRIGHT "\n");
exit(0);
break;
- case 'X':
- sdp->expert = TRUE;
- break;
case ':':
case '?':
fprintf(stderr, _("Please use '-h' for help.\n"));
@@ -200,17 +197,13 @@ verify_arguments(struct gfs2_sbd *sdp)
*
*/
-static void
-print_results(struct gfs2_sbd *sdp)
+static void print_results(struct gfs2_sbd *sdp)
{
if (sdp->debug)
printf("\n");
else if (sdp->quiet)
return;
- if (sdp->expert)
- printf(_("Expert mode: on\n"));
-
printf( _("Filesystem: %s\n"), sdp->path_name);
printf( _("Old Journals: %u\n"), sdp->orig_journals);
printf( _("New Journals: %u\n"), sdp->md.journals);
diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c
index 26aeba2..31b1e62 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
@@ -146,7 +146,6 @@ struct mkfs_opts {
unsigned override:1;
unsigned quiet:1;
- unsigned expert:1;
unsigned debug:1;
unsigned confirm:1;
unsigned align:1;
@@ -294,7 +293,7 @@ static void opts_get(int argc, char *argv[], struct mkfs_opts *opts)
{
int c;
while (1) {
- c = getopt(argc, argv, "-b:c:DhJ:j:KOo:p:qr:t:VX");
+ c = getopt(argc, argv, "-b:c:DhJ:j:KOo:p:qr:t:V");
if (c == -1)
break;
@@ -351,9 +350,6 @@ static void opts_get(int argc, char *argv[], struct mkfs_opts *opts)
printf(REDHAT_COPYRIGHT "\n");
exit(EXIT_SUCCESS);
break;
- case 'X':
- opts->expert = 1;
- break;
case ':':
case '?':
fprintf(stderr, _("Please use '-h' for help.\n"));
@@ -511,17 +507,12 @@ static void opts_check(struct mkfs_opts *opts)
exit(1);
}
- if (!opts->expert)
- test_locking(opts->lockproto, opts->locktable);
- if (opts->expert) {
- if (GFS2_EXP_MIN_RGSIZE > opts->rgsize || opts->rgsize > GFS2_MAX_RGSIZE)
- /* Translators: gfs2 file systems are split into equal sized chunks called
- resource groups. We're checking that the user gave a valid size for them. */
- die( _("bad resource group size\n"));
- } else {
- if (GFS2_MIN_RGSIZE > opts->rgsize || opts->rgsize > GFS2_MAX_RGSIZE)
- die( _("bad resource group size\n"));
- }
+ test_locking(opts->lockproto, opts->locktable);
+
+ if (GFS2_MIN_RGSIZE > opts->rgsize || opts->rgsize > GFS2_MAX_RGSIZE)
+ /* Translators: gfs2 file systems are split into equal sized chunks called
+ resource groups. We're checking that the user gave a valid size for them. */
+ die( _("bad resource group size\n"));
if (!opts->journals)
die( _("no journals specified\n"));
9 years, 8 months
gfs2-utils: RHEL7 - fsck.gfs2: Log to syslog on start and exit
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=7ecd2f27...
Commit: 7ecd2f27dcfc43088d174d6559d6b06819fd12b6
Parent: a1ea077eae85983da1846e7ffbe8e4b515f80243
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Tue May 6 15:59:39 2014 +0100
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Thu Jul 24 17:15:39 2014 +0100
fsck.gfs2: Log to syslog on start and exit
In order to piece together the order in which fsck.gfs2 runs and
gfs2_edit savemeta were done it's useful to keep a log of the command
line options used and the fsck.gfs2 start and end times and exit status.
Log these to syslog.
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/fsck/main.c | 35 +++++++++++++++++++++++++++++++++++
gfs2/man/fsck.gfs2.8 | 2 ++
2 files changed, 37 insertions(+), 0 deletions(-)
diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c
index ae5ed42..6a6fcd9 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -14,6 +14,7 @@
#include <sys/time.h>
#include <time.h>
#define _(String) gettext(String)
+#include <syslog.h>
#include "copyright.cf"
#include "libgfs2.h"
@@ -276,6 +277,36 @@ static int fsck_pass(const struct fsck_pass *p, struct gfs2_sbd *sdp)
return 0;
}
+static void exitlog(int status, void *unused)
+{
+ syslog(LOG_INFO, "exit: %d", status);
+}
+
+static void startlog(int argc, char **argv)
+{
+ int i;
+ char *cmd, *p;
+ size_t len;
+
+ for (len = i = 0; i < argc; i++)
+ len += strlen(argv[i]);
+ len += argc; /* Add spaces and '\0' */
+
+ cmd = malloc(len);
+ if (cmd == NULL) {
+ perror(argv[0]);
+ exit(FSCK_ERROR);
+ }
+ p = cmd;
+ for (i = 0; i < argc; i++, p++) {
+ p = stpcpy(p, argv[i]);
+ *p = ' ';
+ }
+ *(--p) = '\0';
+ syslog(LOG_INFO, "started: %s", cmd);
+ free(cmd);
+}
+
int main(int argc, char **argv)
{
struct gfs2_sbd sb;
@@ -289,6 +320,10 @@ int main(int argc, char **argv)
setlocale(LC_ALL, "");
textdomain("gfs2-utils");
+ openlog("fsck.gfs2", LOG_CONS|LOG_PID, LOG_USER);
+ startlog(argc - 1, &argv[1]);
+ on_exit(exitlog, NULL);
+
memset(sdp, 0, sizeof(*sdp));
if ((error = read_cmdline(argc, argv, &opts)))
diff --git a/gfs2/man/fsck.gfs2.8 b/gfs2/man/fsck.gfs2.8
index 3ecfbe3..56dcddc 100644
--- a/gfs2/man/fsck.gfs2.8
+++ b/gfs2/man/fsck.gfs2.8
@@ -35,6 +35,8 @@ computer. Therefore, fsck.gfs2 will always check the file system unless
the -p (preen) option is used, in which case it follows special rules
(see below).
+fsck.gfs2 will log to the system log on start and exit to aid debugging and
+administration.
.SH OPTIONS
.TP
\fB-a\fP
9 years, 8 months
gfs2-utils: RHEL7 - gfs2_grow: Add stripe alignment
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=a1ea077e...
Commit: a1ea077eae85983da1846e7ffbe8e4b515f80243
Parent: d870184e3deb465e1f77e0e219dae11fa2cd97ae
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Thu Apr 3 07:18:08 2014 -0500
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Thu Jul 24 17:15:39 2014 +0100
gfs2_grow: Add stripe alignment
Wrap the calls to lgfs2_rgrps_init() in an rgrps_init() function which
uses libblkid to probe the alignment of the device before calling
lgfs2_rgrps_init().
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/mkfs/main_grow.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 49 insertions(+), 2 deletions(-)
diff --git a/gfs2/mkfs/main_grow.c b/gfs2/mkfs/main_grow.c
index 88a7f15..adceeef 100644
--- a/gfs2/mkfs/main_grow.c
+++ b/gfs2/mkfs/main_grow.c
@@ -19,6 +19,7 @@
#include <stdarg.h>
#include <linux/types.h>
#include <linux/falloc.h>
+#include <blkid.h>
#include <libintl.h>
#define _(String) gettext(String)
@@ -132,6 +133,52 @@ static void decode_arguments(int argc, char *argv[], struct gfs2_sbd *sdp)
}
}
+static lgfs2_rgrps_t rgrps_init(struct gfs2_sbd *sdp)
+{
+ int ret;
+ int error;
+ uint64_t al_base = 0;
+ uint64_t al_off = 0;
+ struct stat st;
+ blkid_probe pr = blkid_new_probe();
+ if (pr == NULL || blkid_probe_set_device(pr, sdp->device_fd, 0, 0) != 0
+ || blkid_probe_enable_superblocks(pr, TRUE) != 0
+ || blkid_probe_enable_partitions(pr, TRUE) != 0) {
+ fprintf(stderr, _("Failed to create probe\n"));
+ return NULL;
+ }
+
+ error = fstat(sdp->device_fd, &st);
+ if (error < 0) {
+ fprintf(stderr, _("fstat failed\n"));
+ return NULL;
+ }
+
+ if (!S_ISREG(st.st_mode) && blkid_probe_enable_topology(pr, TRUE) != 0) {
+ fprintf(stderr, _("Failed to create probe\n"));
+ return NULL;
+ }
+
+ ret = blkid_do_fullprobe(pr);
+ if (ret == 0 && !S_ISREG(st.st_mode)) {
+ blkid_topology tp = blkid_probe_get_topology(pr);
+ if (tp != NULL) {
+ unsigned long min_io_sz = blkid_topology_get_minimum_io_size(tp);
+ unsigned long opt_io_sz = blkid_topology_get_optimal_io_size(tp);
+ unsigned long phy_sector_sz = blkid_topology_get_physical_sector_size(tp);
+ if ((min_io_sz > phy_sector_sz) &&
+ (opt_io_sz > phy_sector_sz)) {
+ al_base = opt_io_sz / sdp->bsize;
+ al_off = min_io_sz / sdp->bsize;
+ }
+
+ }
+ }
+
+ blkid_free_probe(pr);
+ return lgfs2_rgrps_init(sdp->bsize, sdp->device.length, al_base, al_off);
+}
+
/**
* Calculate the size of the filesystem
* Reads the lists of resource groups in order to work out where the last block
@@ -363,7 +410,7 @@ void main_grow(int argc, char *argv[])
perror(_("Could not read master directory"));
exit(EXIT_FAILURE);
}
- rgs = lgfs2_rgrps_init(sdp->bsize, sdp->device.length, 0, 0);
+ rgs = rgrps_init(sdp);
if (rgs == NULL) {
perror(_("Could not initialise resource groups"));
error = -1;
@@ -388,7 +435,7 @@ void main_grow(int argc, char *argv[])
/* We're done with the old rgs now that we have the fssize and rg count */
lgfs2_rgrps_free(&rgs);
/* Now lets set up the new ones with alignment and all */
- rgs = lgfs2_rgrps_init(sdp->bsize, sdp->device.length, 0, 0);
+ rgs = rgrps_init(sdp);
if (rgs == NULL) {
perror(_("Could not initialise new resource groups"));
error = -1;
9 years, 8 months
gfs2-utils: RHEL7 - gfs2_grow: Migrate to the new resource group API
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=d870184e...
Commit: d870184e3deb465e1f77e0e219dae11fa2cd97ae
Parent: 309da48170e595d5a35d50ff64a47f07f419b5d6
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Thu Apr 3 07:09:21 2014 -0500
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Thu Jul 24 17:15:39 2014 +0100
gfs2_grow: Migrate to the new resource group API
Now that the foundations are in place, migrate gfs2_grow to the new
resource group API in libgfs2. This fixes the problem of gfs2_grow using
the last existing resource group's size as the size for all of the new
resource groups. It also allows us to remove more direct usage of
osi_tree.h structures and reduce usage of sdp->rgtree and sdp->rgcalc,
which should be removed from that structure at some point.
It should now be trivial to add RAID stripe alignment to gfs2_grow.
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/mkfs/gfs2_mkfs.h | 1 -
gfs2/mkfs/main_grow.c | 304 +++++++++++++++++++++++--------------------------
2 files changed, 140 insertions(+), 165 deletions(-)
diff --git a/gfs2/mkfs/gfs2_mkfs.h b/gfs2/mkfs/gfs2_mkfs.h
index 231f370..3c63858 100644
--- a/gfs2/mkfs/gfs2_mkfs.h
+++ b/gfs2/mkfs/gfs2_mkfs.h
@@ -8,7 +8,6 @@
/* main_grow */
extern void main_grow(int argc, char *argv[]);
-extern void debug_print_rgrps(struct gfs2_sbd *sdp, struct osi_root *rgtree);
/* main_jadd */
extern void main_jadd(int argc, char *argv[]);
diff --git a/gfs2/mkfs/main_grow.c b/gfs2/mkfs/main_grow.c
index 718bb30..88a7f15 100644
--- a/gfs2/mkfs/main_grow.c
+++ b/gfs2/mkfs/main_grow.c
@@ -133,137 +133,116 @@ static void decode_arguments(int argc, char *argv[], struct gfs2_sbd *sdp)
}
/**
- * filesystem_size - Calculate the size of the filesystem
- *
- * Reads the lists of resource groups in order to
- * work out where the last block of the filesystem is located.
- *
+ * Calculate the size of the filesystem
+ * Reads the lists of resource groups in order to work out where the last block
+ * of the filesystem is located.
* Returns: The calculated size
*/
-
-static uint64_t filesystem_size(struct gfs2_sbd *sdp)
+static uint64_t filesystem_size(lgfs2_rgrps_t rgs)
{
- struct osi_node *n, *next = NULL;
- struct rgrp_tree *rgl;
- uint64_t size = 0, extent;
-
- for (n = osi_first(&sdp->rgtree); n; n = next) {
- next = osi_next(n);
- rgl = (struct rgrp_tree *)n;
- extent = rgl->ri.ri_addr + rgl->ri.ri_length + rgl->ri.ri_data;
- if (extent > size)
- size = extent;
- }
- return size;
+ lgfs2_rgrp_t rg = lgfs2_rgrp_last(rgs);
+ const struct gfs2_rindex *ri = lgfs2_rgrp_index(rg);
+ return ri->ri_data0 + ri->ri_data;
}
/**
- * initialize_new_portion - Write the new rg information to disk buffers.
+ * Write the new rg information to disk.
*/
-static void initialize_new_portion(struct gfs2_sbd *sdp, int *old_rg_count)
+static unsigned initialize_new_portion(struct gfs2_sbd *sdp, lgfs2_rgrps_t rgs)
{
- struct osi_node *n, *next = NULL;
- uint64_t rgrp = 0;
- struct rgrp_tree *rl;
-
- *old_rg_count = 0;
- /* Delete the old RGs from the rglist */
- for (rgrp = 0, n = osi_first(&sdp->rgtree);
- n && rgrp < (sdp->rgrps - sdp->new_rgrps); n = next, rgrp++) {
- next = osi_next(n);
- (*old_rg_count)++;
- rl = (struct rgrp_tree *)n;
- osi_erase(&rl->node, &sdp->rgtree);
- free(rl);
- }
- /* Issue a discard ioctl for the new portion */
- rl = (struct rgrp_tree *)n;
- discard_blocks(sdp->device_fd, rl->start * sdp->bsize,
- (sdp->device.length - rl->start) * sdp->bsize);
+ unsigned rgcount = 0;
+ uint64_t rgaddr = fssize;
+
+ discard_blocks(sdp->device_fd, rgaddr * sdp->bsize, fsgrowth * sdp->bsize);
/* Build the remaining resource groups */
- if (build_rgrps(sdp, !test)) {
- fprintf(stderr, _("Failed to build resource groups\n"));
- exit(-1);
+ while (1) {
+ int err = 0;
+ lgfs2_rgrp_t rg;
+ struct gfs2_rindex ri;
+ rgaddr = lgfs2_rindex_entry_new(rgs, &ri, rgaddr, 0);
+ if (rgaddr == 0)
+ break;
+ rg = lgfs2_rgrps_append(rgs, &ri);
+ if (rg == NULL) {
+ perror(_("Failed to create resource group"));
+ return 0;
+ }
+ if (metafs_interrupted)
+ return 0;
+ if (sdp->debug)
+ printf(_("Writing resource group at %llu with size %"PRIu32"\n"),
+ ri.ri_addr, ri.ri_length + ri.ri_data);
+ if (!test)
+ err = lgfs2_rgrp_write(rgs, sdp->device_fd, rg);
+ if (err != 0) {
+ perror(_("Failed to write resource group"));
+ return 0;
+ }
+ rgcount++;
}
-
- inode_put(&sdp->md.riinode);
- inode_put(&sdp->master_dir);
-
- /* We're done with the libgfs portion, so commit it to disk. */
fsync(sdp->device_fd);
+ return rgcount;
}
-/**
- * fix_rindex - Add the new entries to the end of the rindex file.
- */
-static void fix_rindex(struct gfs2_sbd *sdp, int rindex_fd, int old_rg_count)
+static char *rindex_buffer(lgfs2_rgrps_t rgs, unsigned count)
{
- struct osi_node *n, *next = NULL;
- int count, rg;
- struct rgrp_tree *rl;
- char *buf, *bufptr;
- ssize_t writelen;
- struct stat statbuf;
+ lgfs2_rgrp_t rg;
+ unsigned i = 0;
+ char *buf;
- /* Count the number of new RGs. */
- rg = 0;
- for (n = osi_first(&sdp->rgtree); n; n = next) {
- next = osi_next(n);
- rg++;
- }
- log_info( _("%d new rindex entries.\n"), rg);
- writelen = rg * sizeof(struct gfs2_rindex);
- buf = calloc(1, writelen);
+ buf = calloc(count, sizeof(struct gfs2_rindex));
if (buf == NULL) {
perror(__FUNCTION__);
exit(EXIT_FAILURE);
}
- /* Now add the new rg entries to the rg index. Here we */
- /* need to use the gfs2 kernel code rather than the libgfs2 */
- /* code so we have a live update while mounted. */
- bufptr = buf;
- for (n = osi_first(&sdp->rgtree); n; n = next) {
- next = osi_next(n);
- rg++;
- rl = (struct rgrp_tree *)n;
- gfs2_rindex_out(&rl->ri, bufptr);
- bufptr += sizeof(struct gfs2_rindex);
+ for (rg = lgfs2_rgrp_first(rgs); rg; rg = lgfs2_rgrp_next(rg)) {
+ const struct gfs2_rindex *ri = lgfs2_rgrp_index(rg);
+ gfs2_rindex_out(ri, buf + (sizeof(*ri) * i));
+ i++;
}
- gfs2_rgrp_free(&sdp->rgtree);
- fsync(sdp->device_fd);
+ return buf;
+}
+
+/**
+ * fix_rindex - Add the new entries to the end of the rindex file.
+ */
+static void fix_rindex(int rindex_fd, lgfs2_rgrps_t rgs, unsigned old_rg_count, unsigned rgcount)
+{
+ char *buf;
+ ssize_t count;
+ ssize_t writelen;
+ const size_t entrysize = sizeof(struct gfs2_rindex);
+
+ log_info( _("%d new rindex entries.\n"), rgcount);
+ buf = rindex_buffer(rgs, rgcount);
+ writelen = rgcount * entrysize;
+
if (!test) {
- if (fstat(rindex_fd, &statbuf) != 0) {
- perror("rindex");
- goto out;
- }
- if (statbuf.st_size !=
- old_rg_count * sizeof(struct gfs2_rindex)) {
- log_crit(_("Incorrect rindex size. want %ld(%d resource groups), "
- "have %ld\n"),
- old_rg_count * sizeof(struct gfs2_rindex),
- old_rg_count, statbuf.st_size);
+ off_t rindex_size = lseek(rindex_fd, 0, SEEK_END);
+ if (rindex_size != old_rg_count * entrysize) {
+ log_crit(_("Incorrect rindex size. Want %ld (%d resource groups), have %ld\n"),
+ (old_rg_count * entrysize), old_rg_count, rindex_size);
goto out;
}
- /* Now write the new RGs to the end of the rindex */
- lseek(rindex_fd, 0, SEEK_END);
- count = write(rindex_fd, buf, sizeof(struct gfs2_rindex));
- if (count != sizeof(struct gfs2_rindex)) {
+ /* Write the first entry separately to ensure there's enough
+ space in the fs for the rest */
+ count = write(rindex_fd, buf, entrysize);
+ if (count != entrysize) {
log_crit(_("Error writing first new rindex entry; aborted.\n"));
if (count > 0)
goto trunc;
else
goto out;
}
- count = write(rindex_fd, buf + sizeof(struct gfs2_rindex),
- writelen - sizeof(struct gfs2_rindex));
- if (count != writelen - sizeof(struct gfs2_rindex)) {
+ count = write(rindex_fd, (buf + entrysize), (writelen - entrysize));
+ if (count != (writelen - entrysize)) {
log_crit(_("Error writing new rindex entries; aborted.\n"));
if (count > 0)
goto trunc;
else
goto out;
}
- if (fallocate(rindex_fd, FALLOC_FL_KEEP_SIZE, statbuf.st_size + writelen, sizeof(struct gfs2_rindex)) != 0)
+ if (fallocate(rindex_fd, FALLOC_FL_KEEP_SIZE, (rindex_size + writelen), entrysize) != 0)
perror("fallocate");
fsync(rindex_fd);
}
@@ -284,46 +263,38 @@ trunc:
*/
static void print_info(struct gfs2_sbd *sdp)
{
- log_notice("FS: %-22s%s\n", _("Mount point:"), sdp->path_name);
- log_notice("FS: %-22s%s\n", _("Device:"), sdp->device_name);
- log_notice("FS: %-22s%llu (0x%llx)\n", _("Size:"),
+ log_notice("FS: %-25s%s\n", _("Mount point:"), sdp->path_name);
+ log_notice("FS: %-25s%s\n", _("Device:"), sdp->device_name);
+ log_notice("FS: %-25s%llu (0x%llx)\n", _("Size:"),
(unsigned long long)fssize, (unsigned long long)fssize);
- log_notice("FS: %-22s%u (0x%x)\n", _("Resource group size:"), rgsize, rgsize);
- log_notice("DEV: %-22s%llu (0x%llx)\n", _("Length:"),
+ log_notice("FS: %-25s%u (0x%x)\n", _("New resource group size:"), rgsize, rgsize);
+ log_notice("DEV: %-24s%llu (0x%llx)\n", _("Length:"),
(unsigned long long)sdp->device.length,
(unsigned long long)sdp->device.length);
- log_notice(_("The file system grew by %lluMB.\n"),
- (unsigned long long)fsgrowth / MB);
+ log_notice(_("The file system will grow by %lluMB.\n"),
+ (unsigned long long)(fsgrowth * sdp->bsize) / MB);
}
-void debug_print_rgrps(struct gfs2_sbd *sdp, struct osi_root *rgtree)
+static void debug_print_rgrps(const char *banner, struct gfs2_sbd *sdp, lgfs2_rgrps_t rgs)
{
- struct osi_node *n, *next;
- struct rgrp_tree *rl;
+ lgfs2_rgrp_t r;
if (sdp->debug) {
- log_info("\n");
-
- for (n = osi_first(rgtree); n; n = next) {
- next = osi_next(n);
- rl = (struct rgrp_tree *)n;
- log_info("rg_o = %llu, rg_l = %llu\n",
- (unsigned long long)rl->start,
- (unsigned long long)rl->length);
+ log_info("%s\n", banner);
+
+ for (r = lgfs2_rgrp_first(rgs); r; r = lgfs2_rgrp_next(r)) {
+ const struct gfs2_rindex *ri = lgfs2_rgrp_index(r);
+ log_info("ri_addr = %llu, size = %llu\n",
+ (unsigned long long)ri->ri_addr,
+ (unsigned long long)(ri->ri_data0 + ri->ri_data - ri->ri_addr));
}
}
}
-/**
- * main_grow - do everything
- * @argc:
- * @argv:
- */
-void
-main_grow(int argc, char *argv[])
+void main_grow(int argc, char *argv[])
{
struct gfs2_sbd sbd, *sdp = &sbd;
- int rgcount, rindex_fd;
+ int rindex_fd;
char rindex_name[PATH_MAX];
int error = EXIT_SUCCESS;
int devflags = (test ? O_RDONLY : O_RDWR) | O_CLOEXEC;
@@ -337,9 +308,10 @@ main_grow(int argc, char *argv[])
decode_arguments(argc, argv, sdp);
for(; (argc - optind) > 0; optind++) {
- int sane;
struct mntent *mnt;
- struct rgrp_tree *last_rgrp;
+ unsigned rgcount;
+ unsigned old_rg_count;
+ lgfs2_rgrps_t rgs;
error = lgfs2_open_mnt(argv[optind], O_RDONLY|O_CLOEXEC, &sdp->path_fd,
devflags, &sdp->device_fd, &mnt);
@@ -358,10 +330,6 @@ main_grow(int argc, char *argv[])
perror(sdp->device_name);
exit(EXIT_FAILURE);
}
- log_info( _("Initializing lists...\n"));
- sdp->rgtree.osi_node = NULL;
- sdp->rgcalc.osi_node = NULL;
-
sdp->sd_sb.sb_bsize = GFS2_DEFAULT_BSIZE;
sdp->bsize = sdp->sd_sb.sb_bsize;
if (compute_constants(sdp)) {
@@ -395,59 +363,67 @@ main_grow(int argc, char *argv[])
perror(_("Could not read master directory"));
exit(EXIT_FAILURE);
}
- gfs2_lookupi(sdp->master_dir, "rindex", 6, &sdp->md.riinode);
+ rgs = lgfs2_rgrps_init(sdp->bsize, sdp->device.length, 0, 0);
+ if (rgs == NULL) {
+ perror(_("Could not initialise resource groups"));
+ error = -1;
+ goto out;
+ }
/* Fetch the rindex from disk. We aren't using gfs2 here, */
/* which means that the bitmaps will most likely be cached */
/* and therefore out of date. It shouldn't matter because */
/* we're only going to write out new RG information after */
/* the existing RGs, and only write to the index at EOF. */
- ri_update(sdp, rindex_fd, &rgcount, &sane);
+ log_info(_("Gathering resource group information for %s\n"), argv[optind]);
+ old_rg_count = lgfs2_rindex_read_fd(rindex_fd, rgs);
+ if (old_rg_count == 0) {
+ perror(_("Failed to scan existing resource groups"));
+ error = -EXIT_FAILURE;
+ goto out;
+ }
if (metafs_interrupted)
goto out;
- fssize = filesystem_size(sdp);
- if (!sdp->rgtree.osi_node) {
- log_err(_("Error: No resource groups found.\n"));
- error = -EXIT_FAILURE;
+ fssize = lgfs2_rgrp_align_addr(rgs, filesystem_size(rgs) + 1);
+ debug_print_rgrps(_("Existing resource groups"), sdp, rgs);
+ /* We're done with the old rgs now that we have the fssize and rg count */
+ lgfs2_rgrps_free(&rgs);
+ /* Now lets set up the new ones with alignment and all */
+ rgs = lgfs2_rgrps_init(sdp->bsize, sdp->device.length, 0, 0);
+ if (rgs == NULL) {
+ perror(_("Could not initialise new resource groups"));
+ error = -1;
goto out;
}
- last_rgrp = (struct rgrp_tree *)osi_last(&sdp->rgtree);
- sdp->rgsize = GFS2_DEFAULT_RGSIZE;
- rgsize = rgrp_size(last_rgrp);
- fsgrowth = ((sdp->device.length - fssize) * sdp->bsize);
- if (fsgrowth < rgsize * sdp->bsize) {
- log_err( _("Error: The device has grown by less than "
- "one resource group.\n"));
- log_err( _("The device grew by %lluMB. "),
- (unsigned long long)fsgrowth / MB);
- log_err( _("One resource group is %uMB for this file system.\n"),
- (rgsize * sdp->bsize) / MB);
- error = -EXIT_FAILURE;
+ fsgrowth = (sdp->device.length - fssize);
+ rgsize = lgfs2_rgrps_plan(rgs, fsgrowth, ((GFS2_MAX_RGSIZE << 20) / sdp->bsize));
+ if (rgsize < ((GFS2_MIN_RGSIZE << 20) / sdp->bsize)) {
+ log_err( _("The calculated resource group size is too small.\n"));
+ log_err( _("%s has not grown.\n"), argv[optind]);
+ error = -1;
goto out;
- } else {
- int old_rg_count;
-
- if (metafs_interrupted)
- goto out;
- compute_rgrp_layout(sdp, &sdp->rgtree, TRUE);
- if (metafs_interrupted)
- goto out;
- debug_print_rgrps(sdp, &sdp->rgtree);
- print_info(sdp);
- initialize_new_portion(sdp, &old_rg_count);
- if (metafs_interrupted)
- goto out;
- fix_rindex(sdp, rindex_fd, old_rg_count);
}
+ print_info(sdp);
+ rgcount = initialize_new_portion(sdp, rgs);
+ if (rgcount == 0 || metafs_interrupted)
+ goto out;
+ debug_print_rgrps(_("New resource groups"), sdp, rgs);
+ fsync(sdp->device_fd);
+ fix_rindex(rindex_fd, rgs, old_rg_count, rgcount);
out:
- /* Delete the remaining RGs from the rglist */
- gfs2_rgrp_free(&sdp->rgtree);
+ lgfs2_rgrps_free(&rgs);
close(rindex_fd);
cleanup_metafs(sdp);
close(sdp->device_fd);
+
+ if (metafs_interrupted)
+ break;
}
close(sdp->path_fd);
sync();
- if (!metafs_interrupted)
- log_notice( _("gfs2_grow complete.\n"));
+ if (metafs_interrupted) {
+ log_notice( _("gfs2_grow interrupted.\n"));
+ exit(1);
+ }
+ log_notice( _("gfs2_grow complete.\n"));
exit(error);
}
9 years, 8 months
gfs2-utils: RHEL7 - libgfs2: Stick to the (rgrp) plan in lgfs2_rindex_entry_new
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=309da481...
Commit: 309da48170e595d5a35d50ff64a47f07f419b5d6
Parent: 4980ba91fbbdd5ab9718112e42a0b71e57c98aec
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Thu Apr 3 06:30:07 2014 -0500
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Thu Jul 24 17:15:39 2014 +0100
libgfs2: Stick to the (rgrp) plan in lgfs2_rindex_entry_new
lgfs2_rindex_entry_new() was ignoring the plan any time len was not 0, even if
len matched the next rgrp length in the plan. This was causing problems in mkfs
when the journal-adjusted rgrp size was the same as the normal rgrp size.
Decrement the count of the appropriate rgrp size if the length matches.
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/libgfs2/rgrp.c | 21 ++++++++++++---------
1 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c
index d70dfc5..901a7bf 100644
--- a/gfs2/libgfs2/rgrp.c
+++ b/gfs2/libgfs2/rgrp.c
@@ -433,21 +433,24 @@ void lgfs2_rgrps_free(lgfs2_rgrps_t *rgs)
*/
uint64_t lgfs2_rindex_entry_new(lgfs2_rgrps_t rgs, struct gfs2_rindex *ri, uint64_t addr, uint32_t len)
{
+ int plan = -1;
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 (rgs->plan[0].num > 0)
+ plan = 0;
+ else if (rgs->plan[1].num > 0)
+ plan = 1;
+ else
+ return 0;
+
+ if (plan >= 0 && (len == 0 || len == rgs->plan[plan].len)) {
+ len = rgs->plan[plan].len;
+ rgs->plan[plan].num--;
}
+
if (addr + len > rgs->devlen)
return 0;
9 years, 8 months
gfs2-utils: RHEL7 - libgfs2: Fix off-by-one in lgfs2_rgrps_plan
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=4980ba91...
Commit: 4980ba91fbbdd5ab9718112e42a0b71e57c98aec
Parent: 2e09a76e3cf522b4fd85f8008af522670c072720
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Thu Apr 3 06:25:17 2014 -0500
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Thu Jul 24 17:15:39 2014 +0100
libgfs2: Fix off-by-one in lgfs2_rgrps_plan
We were making plans based on an extra resource group but not adding the extra
one to the count. Make sure the count is incremented appropriately.
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/libgfs2/rgrp.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c
index cae7a32..d70dfc5 100644
--- a/gfs2/libgfs2/rgrp.c
+++ b/gfs2/libgfs2/rgrp.c
@@ -299,7 +299,8 @@ uint32_t lgfs2_rgrps_plan(const lgfs2_rgrps_t rgs, uint64_t space, uint32_t tgts
/* Spread the adjustment required to fit a new rgrp at the end
over all of the rgrps so that we don't end with a single
tiny one. */
- while (((rgs->plan[0].len - adj) * (rgs->plan[0].num + 1)) >= space)
+ rgs->plan[0].num++;
+ while (((rgs->plan[0].len - adj) * (rgs->plan[0].num)) >= space)
rgs->plan[0].len -= adj;
/* We've adjusted the size of the rgrps down as far as we can
@@ -313,7 +314,7 @@ uint32_t lgfs2_rgrps_plan(const lgfs2_rgrps_t rgs, uint64_t space, uint32_t tgts
rgs->plan[1].num = 0;
while (((rgs->plan[0].len * rgs->plan[0].num) +
- (rgs->plan[1].len * rgs->plan[1].num)) > space) {
+ (rgs->plan[1].len * rgs->plan[1].num)) >= space) {
/* Total number of rgrps stays constant now. We just
need to shift some weight around */
rgs->plan[0].num--;
9 years, 8 months
gfs2-utils: RHEL7 - libgfs2: Const-ify the 'ri' argument to gfs2_rindex_out
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=2e09a76e...
Commit: 2e09a76e3cf522b4fd85f8008af522670c072720
Parent: 80a42f9698504cc82c137950f8cac6bf19373a0c
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Thu Apr 3 06:10:37 2014 -0500
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Thu Jul 24 17:15:39 2014 +0100
libgfs2: Const-ify the 'ri' argument to gfs2_rindex_out
This function shouldn't modify its ri argument and the const helps when we want
to pass it the return value of one of the newly-const lgfs2_rgrp_{index,rgrp}
functions (the rgrp arg to gfs2_rgrp_out is already const so no change needed).
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/libgfs2/libgfs2.h | 2 +-
gfs2/libgfs2/ondisk.c | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 455f01d..3353f5f 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -802,7 +802,7 @@ extern void gfs2_meta_header_out_bh(const struct gfs2_meta_header *mh,
extern void gfs2_sb_in(struct gfs2_sb *sb, struct gfs2_buffer_head *bh);
extern void gfs2_sb_out(const struct gfs2_sb *sb, char *buf);
extern void gfs2_rindex_in(struct gfs2_rindex *ri, char *buf);
-extern void gfs2_rindex_out(struct gfs2_rindex *ri, char *buf);
+extern void gfs2_rindex_out(const struct gfs2_rindex *ri, char *buf);
extern void gfs2_rgrp_in(struct gfs2_rgrp *rg, struct gfs2_buffer_head *bh);
extern void gfs2_rgrp_out(const struct gfs2_rgrp *rg, char *buf);
extern void gfs2_rgrp_out_bh(const struct gfs2_rgrp *rg, struct gfs2_buffer_head *bh);
diff --git a/gfs2/libgfs2/ondisk.c b/gfs2/libgfs2/ondisk.c
index 3fbc63f..1f81b5f 100644
--- a/gfs2/libgfs2/ondisk.c
+++ b/gfs2/libgfs2/ondisk.c
@@ -213,13 +213,13 @@ void gfs2_rindex_in(struct gfs2_rindex *ri, char *buf)
CPIN_08(ri, str, ri_reserved, 64);
}
-void gfs2_rindex_out(struct gfs2_rindex *ri, char *buf)
+void gfs2_rindex_out(const struct gfs2_rindex *ri, char *buf)
{
struct gfs2_rindex *str = (struct gfs2_rindex *)buf;
CPOUT_64(ri, str, ri_addr);
CPOUT_32(ri, str, ri_length);
- ri->__pad = 0;
+ str->__pad = 0;
CPOUT_64(ri, str, ri_data0);
CPOUT_32(ri, str, ri_data);
9 years, 8 months
gfs2-utils: RHEL7 - libgfs2: Add a lgfs2_rindex_read_fd() function
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=80a42f96...
Commit: 80a42f9698504cc82c137950f8cac6bf19373a0c
Parent: 466f6fe31302b0e90bbbaea51327f443b75cba54
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Wed Apr 2 11:47:17 2014 +0100
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Thu Jul 24 17:14:39 2014 +0100
libgfs2: Add a lgfs2_rindex_read_fd() function
gfs2_grow opens the rindex file through the metafs so it needs a way to
populate a lgfs2_rgrps_t with existing resource groups. Add
lgfs2_rindex_read_fd() to read in the rindex entries from a fd.
Also const-ify the return types of lgfs2_rgrp_index() and
lgfs2_rgrp_rgrp() to warn users that they shouldn't change the contents
of libgfs2-managed data.
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/libgfs2/libgfs2.h | 5 +++--
gfs2/libgfs2/rgrp.c | 43 +++++++++++++++++++++++++++++++++++++++----
2 files changed, 42 insertions(+), 6 deletions(-)
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index b70c36d..455f01d 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -192,14 +192,15 @@ 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 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);
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_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 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);
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 02ab450..cae7a32 100644
--- a/gfs2/libgfs2/rgrp.c
+++ b/gfs2/libgfs2/rgrp.c
@@ -275,8 +275,8 @@ uint32_t lgfs2_rgrp_align_len(const lgfs2_rgrps_t rgs, uint32_t len)
* rgs: The resource groups descriptor
* space: The number of remaining blocks to be allocated
* tgtsize: The target resource group size in blocks
- * Returns the larger of the calculated resource group sizes or 0 if the
- * smaller would be less than GFS2_MIN_RGSIZE.
+ * Returns the larger of the calculated resource group sizes, in blocks, or 0
+ * if the smaller would be less than GFS2_MIN_RGSIZE.
*/
uint32_t lgfs2_rgrps_plan(const lgfs2_rgrps_t rgs, uint64_t space, uint32_t tgtsize)
{
@@ -361,6 +361,41 @@ lgfs2_rgrps_t lgfs2_rgrps_init(unsigned bsize, uint64_t devlen, uint64_t align,
}
/**
+ * Populate a set of resource groups from a gfs2 rindex file.
+ * fd: An open file descriptor for the rindex file.
+ * rgs: The set of resource groups.
+ * Returns the number of resource groups added to the set or 0 on error with
+ * errno set.
+ */
+unsigned lgfs2_rindex_read_fd(int fd, lgfs2_rgrps_t rgs)
+{
+ unsigned count = 0;
+ char buf[sizeof(struct gfs2_rindex)];
+
+ errno = EINVAL;
+ if (fd < 0 || rgs == NULL)
+ return 0;
+
+ while (1) {
+ lgfs2_rgrp_t rg;
+ struct gfs2_rindex ri;
+ ssize_t ret = read(fd, buf, sizeof(struct gfs2_rindex));
+ if (ret == 0)
+ break;
+
+ if (ret != sizeof(struct gfs2_rindex))
+ return 0;
+
+ gfs2_rindex_in(&ri, buf);
+ rg = lgfs2_rgrps_append(rgs, &ri);
+ if (rg == NULL)
+ return 0;
+ count++;
+ }
+ return count;
+}
+
+/**
* Free a set of resource groups created with lgfs2_rgrps_append() etc. This
* does not write any dirty buffers to disk. See lgfs2_rgrp_write().
* rgs: A pointer to the set of resource groups to be freed.
@@ -428,7 +463,7 @@ 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.
*/
-struct gfs2_rindex *lgfs2_rgrp_index(lgfs2_rgrp_t rg)
+const struct gfs2_rindex *lgfs2_rgrp_index(lgfs2_rgrp_t rg)
{
return &rg->ri;
}
@@ -436,7 +471,7 @@ 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)
+const struct gfs2_rgrp *lgfs2_rgrp_rgrp(lgfs2_rgrp_t rg)
{
return &rg->rg;
}
9 years, 8 months
gfs2-utils: RHEL7 - libgfs2: Consolidate rgrp_tree and bitstruct allocations
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=466f6fe3...
Commit: 466f6fe31302b0e90bbbaea51327f443b75cba54
Parent: 965a4e9a7cb95d019239896f6f5c2b303f36b2ca
Author: Andrew Price <anprice(a)redhat.com>
AuthorDate: Sat Mar 29 19:35:11 2014 +0000
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Thu Jul 24 17:14:23 2014 +0100
libgfs2: Consolidate rgrp_tree and bitstruct allocations
rgrp_insert() and gfs2_compute_bitstructs() allocated separate chunks of
memory for the resource groups (struct rgrp_tree) and the bitmaps and
buffer pointers attached to them. This can be handled more efficiently
by allocating memory for the the whole thing in one go, so we now do
that in lgfs2_rgrps_append(). A new lgfs2_rgrps_free() function has been
added to free the memory allocated in this way. Calculation of the
bitmap structure fields has been simplified and separated out so that
lgfs2_rgrps_append() can share it with gfs2_compute_bitstructs() until
the latter can be removed.
Signed-off-by: Andrew Price <anprice(a)redhat.com>
---
gfs2/libgfs2/libgfs2.h | 1 +
gfs2/libgfs2/rgrp.c | 143 ++++++++++++++++++++++++++++++------------------
gfs2/mkfs/main_mkfs.c | 2 +-
3 files changed, 91 insertions(+), 55 deletions(-)
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 99f64fc..b70c36d 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -190,6 +190,7 @@ 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 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 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);
diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c
index 2ae3ed6..02ab450 100644
--- a/gfs2/libgfs2/rgrp.c
+++ b/gfs2/libgfs2/rgrp.c
@@ -10,6 +10,23 @@
#define RG_SYNC_TOLERANCE 1000
+static void compute_bitmaps(lgfs2_rgrp_t rg, const unsigned bsize)
+{
+ int x;
+
+ rg->bits[0].bi_offset = sizeof(struct gfs2_rgrp);
+ rg->bits[0].bi_start = 0;
+ rg->bits[0].bi_len = bsize - sizeof(struct gfs2_rgrp);
+
+ for (x = 1; x < rg->ri.ri_length; x++) {
+ rg->bits[x].bi_offset = sizeof(struct gfs2_meta_header);
+ rg->bits[x].bi_start = rg->bits[x - 1].bi_start + rg->bits[x - 1].bi_len;
+ rg->bits[x].bi_len = bsize - sizeof(struct gfs2_meta_header);
+ }
+ x--;
+ rg->bits[x].bi_len = rg->ri.ri_bitbytes - rg->bits[x].bi_start;
+}
+
/**
* gfs2_compute_bitstructs - Compute the bitmap sizes
* bsize: Block size
@@ -18,10 +35,9 @@
*/
int gfs2_compute_bitstructs(const uint32_t bsize, struct rgrp_tree *rgd)
{
- struct gfs2_bitmap *bits;
uint32_t length = rgd->ri.ri_length;
- uint32_t bytes_left, bytes;
- int x;
+ uint32_t bytes_left;
+ int ownbits = 0;
/* Max size of an rg is 2GB. A 2GB RG with (minimum) 512-byte blocks
has 4194304 blocks. We can represent 4 blocks in one bitmap byte.
@@ -29,63 +45,38 @@ int gfs2_compute_bitstructs(const uint32_t bsize, struct rgrp_tree *rgd)
Subtract a metadata header for each 512-byte block and we get
488 bytes of bitmap per block. Divide 1048576 by 488 and we can
be assured we should never have more than 2149 of them. */
+ errno = EINVAL;
if (length > 2149 || length == 0)
return -1;
- if(rgd->bits == NULL && !(rgd->bits = (struct gfs2_bitmap *)
- malloc(length * sizeof(struct gfs2_bitmap))))
- return -1;
- if(!memset(rgd->bits, 0, length * sizeof(struct gfs2_bitmap)))
- return -1;
-
- bytes_left = rgd->ri.ri_bitbytes;
- for (x = 0; x < length; x++){
- bits = &rgd->bits[x];
-
- if (length == 1){
- bytes = bytes_left;
- bits->bi_offset = sizeof(struct gfs2_rgrp);
- bits->bi_start = 0;
- bits->bi_len = bytes;
- }
- else if (x == 0){
- bytes = bsize - sizeof(struct gfs2_rgrp);
- bits->bi_offset = sizeof(struct gfs2_rgrp);
- bits->bi_start = 0;
- bits->bi_len = bytes;
- }
- else if (x + 1 == length){
- bytes = bytes_left;
- bits->bi_offset = sizeof(struct gfs2_meta_header);
- bits->bi_start = rgd->ri.ri_bitbytes - bytes_left;
- bits->bi_len = bytes;
- }
- else{
- bytes = bsize - sizeof(struct gfs2_meta_header);
- bits->bi_offset = sizeof(struct gfs2_meta_header);
- bits->bi_start = rgd->ri.ri_bitbytes - bytes_left;
- bits->bi_len = bytes;
- }
-
- bytes_left -= bytes;
+ if(rgd->bits == NULL) {
+ rgd->bits = calloc(length, sizeof(struct gfs2_bitmap));
+ if(rgd->bits == NULL)
+ return -1;
+ ownbits = 1;
}
+ compute_bitmaps(rgd, bsize);
+ bytes_left = rgd->ri.ri_bitbytes - (rgd->bits[rgd->ri.ri_length - 1].bi_start +
+ rgd->bits[rgd->ri.ri_length - 1].bi_len);
+ errno = EINVAL;
if(bytes_left)
- return -1;
+ goto errbits;
if((rgd->bits[length - 1].bi_start +
rgd->bits[length - 1].bi_len) * GFS2_NBBY != rgd->ri.ri_data)
- return -1;
-
- if (rgd->bh) /* If we already have a bh allocated */
- return 0; /* don't want to allocate another */
- if(!(rgd->bh = (struct gfs2_buffer_head **)
- malloc(length * sizeof(struct gfs2_buffer_head *))))
- return -1;
- if(!memset(rgd->bh, 0, length * sizeof(struct gfs2_buffer_head *)))
- return -1;
+ 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)
+ free(rgd->bits);
+ return -1;
}
@@ -370,6 +361,31 @@ lgfs2_rgrps_t lgfs2_rgrps_init(unsigned bsize, uint64_t devlen, uint64_t align,
}
/**
+ * Free a set of resource groups created with lgfs2_rgrps_append() etc. This
+ * does not write any dirty buffers to disk. See lgfs2_rgrp_write().
+ * rgs: A pointer to the set of resource groups to be freed.
+ */
+void lgfs2_rgrps_free(lgfs2_rgrps_t *rgs)
+{
+ lgfs2_rgrp_t rg;
+ struct osi_root *tree = &(*rgs)->root;
+
+ 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;
+ }
+ }
+ osi_erase(&rg->node, tree);
+ free(rg);
+ }
+ free(*rgs);
+ *rgs = NULL;
+}
+
+/**
* 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
@@ -452,22 +468,41 @@ struct osi_node *lgfs2_rgrps_root(lgfs2_rgrps_t rgs)
*/
lgfs2_rgrp_t lgfs2_rgrps_append(lgfs2_rgrps_t rgs, struct gfs2_rindex *entry)
{
- int err = 0;
lgfs2_rgrp_t rg;
+ lgfs2_rgrp_t lastrg = (lgfs2_rgrp_t)osi_last(&rgs->root);
+ struct osi_node **link = &rgs->root.osi_node;
+ struct osi_node *parent = NULL;
+
+ errno = EINVAL;
+ if (entry == NULL)
+ return NULL;
- rg = rgrp_insert(&rgs->root, entry->ri_addr);
+ if (lastrg != NULL) { /* Tree is not empty */
+ if (entry->ri_addr <= lastrg->ri.ri_addr)
+ return NULL; /* Appending with a lower address doesn't make sense */
+ parent = osi_parent(&lastrg->node);
+ 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 *)));
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);
+
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;
rg->rg.rg_free = rg->ri.ri_data;
- err = gfs2_compute_bitstructs(rgs->bsize, rg);
- if (err != 0)
- return NULL;
+ compute_bitmaps(rg, rgs->bsize);
return rg;
}
diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c
index 67850c8..26aeba2 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
@@ -907,7 +907,7 @@ void main_mkfs(int argc, char *argv[])
inode_put(&sbd.md.inum);
inode_put(&sbd.md.statfs);
- gfs2_rgrp_free(&sbd.rgtree);
+ lgfs2_rgrps_free(&rgs);
error = lgfs2_sb_write(&sb, opts.dev.fd, sbd.bsize);
if (error) {
9 years, 8 months