* [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.