* [Cluster-devel] [gfs2-utils patch] gfs2_grow fails to grow a filesystem with less than 3 rgrps
[not found] <fc86251b-fb83-43f5-a81f-ca53c9000fcf@zmail06.collab.prod.int.phx2.redhat.com>
@ 2011-09-30 15:13 ` Bob Peterson
2011-09-30 15:25 ` Steven Whitehouse
0 siblings, 1 reply; 2+ messages in thread
From: Bob Peterson @ 2011-09-30 15:13 UTC (permalink / raw)
To: cluster-devel.redhat.com
Hi,
There's a problem with gfs2-utils whereby some of the utils
can't handle a small file system with one or two rgrps.
The biggest offender is gfs2_grow: you can't successfully
gfs2_grow a file system that is so small that it has only one
resource group. Also, "gfs2_edit savemeta" can't save it.
This patch is designed to remedy the problem by
creating a generic rgrp_size function in libgfs2
that calculates the size rather than judging its
distance from the previous rgrp.
Testing results (today's gfs2_grow versus patched):
# gfs2_grow /mnt/gfs2
Segmentation fault (core dumped)
# ./gfs2_grow /mnt/gfs2
FS: Mount Point: /mnt/gfs2
FS: Device: /dev/mapper/vg_gfs2-lv_gfs2
FS: Size: 127997 (0x1f3fd)
FS: RG size: 127980 (0x1f3ec)
DEV: Size: 256000 (0x3e800)
The file system grew by 500MB.
gfs2_grow complete.
Regards,
Bob Peterson
Red Hat File Systems
--
gfs2/edit/savemeta.c | 6 ++----
gfs2/libgfs2/fs_geometry.c | 6 +++---
gfs2/libgfs2/libgfs2.h | 5 +++++
gfs2/libgfs2/super.c | 4 ++--
gfs2/mkfs/main_grow.c | 27 +++++++++------------------
5 files changed, 21 insertions(+), 27 deletions(-)
diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
index 9e5d111..31af23d 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -637,7 +637,7 @@ void savemeta(char *out_fn, int saveoption, int gziplevel)
int rgcount;
uint64_t jindex_block;
struct gfs2_buffer_head *lbh;
- struct rgrp_tree *last_rgd, *prev_rgd;
+ struct rgrp_tree *last_rgd;
struct metafd mfd;
slow = (saveoption == 1);
@@ -715,9 +715,7 @@ void savemeta(char *out_fn, int saveoption, int gziplevel)
n = osi_last(&sbd.rgtree);
last_rgd = (struct rgrp_tree *)n;
n = osi_prev(n);
- prev_rgd = (struct rgrp_tree *)n;
- fssize = last_rgd->ri.ri_addr +
- (last_rgd->ri.ri_addr - prev_rgd->ri.ri_addr);
+ fssize = last_rgd->ri.ri_addr + rgrp_size(last_rgd);
last_fs_block = fssize;
fssize *= sbd.bsize;
printf("Done. File system size: %s\n\n",
diff --git a/gfs2/libgfs2/fs_geometry.c b/gfs2/libgfs2/fs_geometry.c
index 2b70f11..130331a 100644
--- a/gfs2/libgfs2/fs_geometry.c
+++ b/gfs2/libgfs2/fs_geometry.c
@@ -80,8 +80,8 @@ void compute_rgrp_layout(struct gfs2_sbd *sdp, struct osi_root *rgtree,
struct device *dev;
struct rgrp_tree *rl, *rlast = NULL, *rlast2 = NULL;
struct osi_node *n, *next = NULL;
- unsigned int rgrp = 0, nrgrp;
- uint64_t rglength, rgaddr;
+ unsigned int rgrp = 0, nrgrp, rglength;
+ uint64_t rgaddr;
sdp->new_rgrps = 0;
dev = &sdp->device;
@@ -113,7 +113,7 @@ void compute_rgrp_layout(struct gfs2_sbd *sdp, struct osi_root *rgtree,
rlast = rl;
}
rlast->start = rlast->ri.ri_addr;
- rglength = rlast->ri.ri_addr - rlast2->ri.ri_addr;
+ rglength = rgrp_size(rlast);
rlast->length = rglength;
old_length = rlast->ri.ri_addr + rglength;
new_chunk = dev->length - old_length;
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 53df6cd..77dfc29 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -708,6 +708,11 @@ extern void gfs2_rgrp_relse(struct rgrp_tree *rgd);
extern struct rgrp_tree *rgrp_insert(struct osi_root *rgtree,
uint64_t rgblock);
extern void gfs2_rgrp_free(struct osi_root *rgrp_tree);
+/* figure out the size of the given resource group, in blocks */
+static inline unsigned int rgrp_size(struct rgrp_tree *rgrp)
+{
+ return rgrp->ri.ri_data + rgrp->ri.ri_length;
+}
/* structures.c */
extern int build_master(struct gfs2_sbd *sdp);
diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c
index c354b07..c844287 100644
--- a/gfs2/libgfs2/super.c
+++ b/gfs2/libgfs2/super.c
@@ -194,7 +194,7 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *sane)
*sane = 0;
}
prev_length = rgd->start - prev_rgd->start;
- prev_rgd->length = prev_length;
+ prev_rgd->length = rgrp_size(prev_rgd);
}
if(gfs2_compute_bitstructs(sdp, rgd))
@@ -204,7 +204,7 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *sane)
prev_rgd = rgd;
}
if (prev_rgd)
- prev_rgd->length = prev_length;
+ prev_rgd->length = rgrp_size(prev_rgd);
return 0;
}
diff --git a/gfs2/mkfs/main_grow.c b/gfs2/mkfs/main_grow.c
index dc092ee..7a32d7e 100644
--- a/gfs2/mkfs/main_grow.c
+++ b/gfs2/mkfs/main_grow.c
@@ -122,23 +122,6 @@ static void decode_arguments(int argc, char *argv[], struct gfs2_sbd *sdp)
}
/**
- * figure_out_rgsize
- */
-static void figure_out_rgsize(struct gfs2_sbd *sdp, unsigned int *orgsize)
-{
- struct osi_node *n = osi_first(&sdp->rgtree), *next = NULL;
- struct rgrp_tree *r1, *r2;
-
- sdp->rgsize = GFS2_DEFAULT_RGSIZE;
- next = osi_next(n);
- r1 = (struct rgrp_tree *)next;
- next = osi_next(next);
- r2 = (struct rgrp_tree *)next;
-
- *orgsize = r2->ri.ri_addr - r1->ri.ri_addr;
-}
-
-/**
* filesystem_size - Calculate the size of the filesystem
*
* Reads the lists of resource groups in order to
@@ -324,6 +307,7 @@ main_grow(int argc, char *argv[])
while ((argc - optind) > 0) {
int sane;
+ struct rgrp_tree *last_rgrp;
sdp->path_name = argv[optind++];
sdp->path_fd = open(sdp->path_name, O_RDONLY | O_CLOEXEC);
@@ -391,7 +375,13 @@ main_grow(int argc, char *argv[])
/* the existing RGs, and only write to the index at EOF. */
ri_update(sdp, rindex_fd, &rgcount, &sane);
fssize = filesystem_size(sdp);
- figure_out_rgsize(sdp, &rgsize);
+ if (!sdp->rgtree.osi_node) {
+ log_err(_("Error: No resource groups found.\n"));
+ 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 "
@@ -409,6 +399,7 @@ main_grow(int argc, char *argv[])
initialize_new_portion(sdp, &old_rg_count);
fix_rindex(sdp, rindex_fd, old_rg_count);
}
+ out:
/* Delete the remaining RGs from the rglist */
gfs2_rgrp_free(&sdp->rgtree);
close(rindex_fd);
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [Cluster-devel] [gfs2-utils patch] gfs2_grow fails to grow a filesystem with less than 3 rgrps
2011-09-30 15:13 ` [Cluster-devel] [gfs2-utils patch] gfs2_grow fails to grow a filesystem with less than 3 rgrps Bob Peterson
@ 2011-09-30 15:25 ` Steven Whitehouse
0 siblings, 0 replies; 2+ messages in thread
From: Steven Whitehouse @ 2011-09-30 15:25 UTC (permalink / raw)
To: cluster-devel.redhat.com
Hi,
Looks good to me,
Steve.
On Fri, 2011-09-30 at 11:13 -0400, Bob Peterson wrote:
> Hi,
>
> There's a problem with gfs2-utils whereby some of the utils
> can't handle a small file system with one or two rgrps.
> The biggest offender is gfs2_grow: you can't successfully
> gfs2_grow a file system that is so small that it has only one
> resource group. Also, "gfs2_edit savemeta" can't save it.
>
> This patch is designed to remedy the problem by
> creating a generic rgrp_size function in libgfs2
> that calculates the size rather than judging its
> distance from the previous rgrp.
>
> Testing results (today's gfs2_grow versus patched):
> # gfs2_grow /mnt/gfs2
> Segmentation fault (core dumped)
> # ./gfs2_grow /mnt/gfs2
> FS: Mount Point: /mnt/gfs2
> FS: Device: /dev/mapper/vg_gfs2-lv_gfs2
> FS: Size: 127997 (0x1f3fd)
> FS: RG size: 127980 (0x1f3ec)
> DEV: Size: 256000 (0x3e800)
> The file system grew by 500MB.
> gfs2_grow complete.
>
> Regards,
>
> Bob Peterson
> Red Hat File Systems
> --
> gfs2/edit/savemeta.c | 6 ++----
> gfs2/libgfs2/fs_geometry.c | 6 +++---
> gfs2/libgfs2/libgfs2.h | 5 +++++
> gfs2/libgfs2/super.c | 4 ++--
> gfs2/mkfs/main_grow.c | 27 +++++++++------------------
> 5 files changed, 21 insertions(+), 27 deletions(-)
>
> diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
> index 9e5d111..31af23d 100644
> --- a/gfs2/edit/savemeta.c
> +++ b/gfs2/edit/savemeta.c
> @@ -637,7 +637,7 @@ void savemeta(char *out_fn, int saveoption, int gziplevel)
> int rgcount;
> uint64_t jindex_block;
> struct gfs2_buffer_head *lbh;
> - struct rgrp_tree *last_rgd, *prev_rgd;
> + struct rgrp_tree *last_rgd;
> struct metafd mfd;
>
> slow = (saveoption == 1);
> @@ -715,9 +715,7 @@ void savemeta(char *out_fn, int saveoption, int gziplevel)
> n = osi_last(&sbd.rgtree);
> last_rgd = (struct rgrp_tree *)n;
> n = osi_prev(n);
> - prev_rgd = (struct rgrp_tree *)n;
> - fssize = last_rgd->ri.ri_addr +
> - (last_rgd->ri.ri_addr - prev_rgd->ri.ri_addr);
> + fssize = last_rgd->ri.ri_addr + rgrp_size(last_rgd);
> last_fs_block = fssize;
> fssize *= sbd.bsize;
> printf("Done. File system size: %s\n\n",
> diff --git a/gfs2/libgfs2/fs_geometry.c b/gfs2/libgfs2/fs_geometry.c
> index 2b70f11..130331a 100644
> --- a/gfs2/libgfs2/fs_geometry.c
> +++ b/gfs2/libgfs2/fs_geometry.c
> @@ -80,8 +80,8 @@ void compute_rgrp_layout(struct gfs2_sbd *sdp, struct osi_root *rgtree,
> struct device *dev;
> struct rgrp_tree *rl, *rlast = NULL, *rlast2 = NULL;
> struct osi_node *n, *next = NULL;
> - unsigned int rgrp = 0, nrgrp;
> - uint64_t rglength, rgaddr;
> + unsigned int rgrp = 0, nrgrp, rglength;
> + uint64_t rgaddr;
>
> sdp->new_rgrps = 0;
> dev = &sdp->device;
> @@ -113,7 +113,7 @@ void compute_rgrp_layout(struct gfs2_sbd *sdp, struct osi_root *rgtree,
> rlast = rl;
> }
> rlast->start = rlast->ri.ri_addr;
> - rglength = rlast->ri.ri_addr - rlast2->ri.ri_addr;
> + rglength = rgrp_size(rlast);
> rlast->length = rglength;
> old_length = rlast->ri.ri_addr + rglength;
> new_chunk = dev->length - old_length;
> diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
> index 53df6cd..77dfc29 100644
> --- a/gfs2/libgfs2/libgfs2.h
> +++ b/gfs2/libgfs2/libgfs2.h
> @@ -708,6 +708,11 @@ extern void gfs2_rgrp_relse(struct rgrp_tree *rgd);
> extern struct rgrp_tree *rgrp_insert(struct osi_root *rgtree,
> uint64_t rgblock);
> extern void gfs2_rgrp_free(struct osi_root *rgrp_tree);
> +/* figure out the size of the given resource group, in blocks */
> +static inline unsigned int rgrp_size(struct rgrp_tree *rgrp)
> +{
> + return rgrp->ri.ri_data + rgrp->ri.ri_length;
> +}
>
> /* structures.c */
> extern int build_master(struct gfs2_sbd *sdp);
> diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c
> index c354b07..c844287 100644
> --- a/gfs2/libgfs2/super.c
> +++ b/gfs2/libgfs2/super.c
> @@ -194,7 +194,7 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *sane)
> *sane = 0;
> }
> prev_length = rgd->start - prev_rgd->start;
> - prev_rgd->length = prev_length;
> + prev_rgd->length = rgrp_size(prev_rgd);
> }
>
> if(gfs2_compute_bitstructs(sdp, rgd))
> @@ -204,7 +204,7 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *sane)
> prev_rgd = rgd;
> }
> if (prev_rgd)
> - prev_rgd->length = prev_length;
> + prev_rgd->length = rgrp_size(prev_rgd);
> return 0;
> }
>
> diff --git a/gfs2/mkfs/main_grow.c b/gfs2/mkfs/main_grow.c
> index dc092ee..7a32d7e 100644
> --- a/gfs2/mkfs/main_grow.c
> +++ b/gfs2/mkfs/main_grow.c
> @@ -122,23 +122,6 @@ static void decode_arguments(int argc, char *argv[], struct gfs2_sbd *sdp)
> }
>
> /**
> - * figure_out_rgsize
> - */
> -static void figure_out_rgsize(struct gfs2_sbd *sdp, unsigned int *orgsize)
> -{
> - struct osi_node *n = osi_first(&sdp->rgtree), *next = NULL;
> - struct rgrp_tree *r1, *r2;
> -
> - sdp->rgsize = GFS2_DEFAULT_RGSIZE;
> - next = osi_next(n);
> - r1 = (struct rgrp_tree *)next;
> - next = osi_next(next);
> - r2 = (struct rgrp_tree *)next;
> -
> - *orgsize = r2->ri.ri_addr - r1->ri.ri_addr;
> -}
> -
> -/**
> * filesystem_size - Calculate the size of the filesystem
> *
> * Reads the lists of resource groups in order to
> @@ -324,6 +307,7 @@ main_grow(int argc, char *argv[])
>
> while ((argc - optind) > 0) {
> int sane;
> + struct rgrp_tree *last_rgrp;
>
> sdp->path_name = argv[optind++];
> sdp->path_fd = open(sdp->path_name, O_RDONLY | O_CLOEXEC);
> @@ -391,7 +375,13 @@ main_grow(int argc, char *argv[])
> /* the existing RGs, and only write to the index at EOF. */
> ri_update(sdp, rindex_fd, &rgcount, &sane);
> fssize = filesystem_size(sdp);
> - figure_out_rgsize(sdp, &rgsize);
> + if (!sdp->rgtree.osi_node) {
> + log_err(_("Error: No resource groups found.\n"));
> + 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 "
> @@ -409,6 +399,7 @@ main_grow(int argc, char *argv[])
> initialize_new_portion(sdp, &old_rg_count);
> fix_rindex(sdp, rindex_fd, old_rg_count);
> }
> + out:
> /* Delete the remaining RGs from the rglist */
> gfs2_rgrp_free(&sdp->rgtree);
> close(rindex_fd);
>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2011-09-30 15:25 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <fc86251b-fb83-43f5-a81f-ca53c9000fcf@zmail06.collab.prod.int.phx2.redhat.com>
2011-09-30 15:13 ` [Cluster-devel] [gfs2-utils patch] gfs2_grow fails to grow a filesystem with less than 3 rgrps Bob Peterson
2011-09-30 15:25 ` Steven Whitehouse
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.