gfs2_grow and libgfs2 rgrp API improvements
cover gfs2_grow and libgfs2 rgrp API improvements
Hi,
This patch set aims to do three main things:
- Improve and simplify libgfs2's rgrp APIs, bringing them closer to being proper library code
- Improve gfs2_grow using the new rgrp APIs for rgrp alignment and size calculation, larger rgrps by default, etc.
- Fix problems in libgfs2 and the utils uncovered along the way
These patches take us closer to being able to hide the implementation of the rgrp lists (currently using osi_tree.h) within libgfs2 and decoupling so that many resource group sets (lgfs2_rgrps_t's) can be manipulated independently. Bookkeeping will eventually be done by the applications instead of keeping application-specific data in the gfs2_sbd structure so this takes us closer to being able to remove sbd.rgtree and sbd.rgcalc.
Although the net diff is 284 insertions, that will be offset significantly once the old rgrp functions in libgfs2 can be removed (when fsck, convert and edit no longer use them).
I've thrown various tests at this set and added one to the in-tree test suite. Static analysis with coverity shows 1 defect fixed and 0 added.
Please review,
Andy
Andrew Price (14):
mkfs.gfs2: Make dev a member of mkfs_opts
libgfs2: Add lgfs2_space_for_data()
libgfs2: Don't try to read more than IOV_MAX iovecs mkfs.gfs2: Fix the resource group layout strategy, again
libgfs2: Don't call gfs2_blk2rgrpd in gfs2_set_bitmap
libgfs2: Add abstractions for rgrp tree traversal
libgfs2: Split out the rindex calculation from lgfs2_rgrp_append
libgfs2: Consolidate rgrp_tree and bitstruct allocations
libgfs2: Add a lgfs2_rindex_read_fd() function
libgfs2: Const-ify the 'ri' argument to gfs2_rindex_out
libgfs2: Fix off-by-one in lgfs2_rgrps_plan
libgfs2: Stick to the (rgrp) plan in lgfs2_rindex_entry_new
gfs2_grow: Migrate to the new resource group API
gfs2_grow: Add stripe alignment
gfs2/edit/hexedit.c | 2 +- gfs2/fsck/metawalk.c | 2 +- gfs2/fsck/pass5.c | 6 +- gfs2/libgfs2/buf.c | 57 ++++--- gfs2/libgfs2/fs_bits.c | 5 +- gfs2/libgfs2/fs_ops.c | 30 +++- gfs2/libgfs2/libgfs2.h | 31 ++-- gfs2/libgfs2/ondisk.c | 4 +- gfs2/libgfs2/rgrp.c | 422 +++++++++++++++++++++++++++++++++++-------------- gfs2/mkfs/gfs2_mkfs.h | 1 - gfs2/mkfs/main_grow.c | 351 +++++++++++++++++++++------------------- gfs2/mkfs/main_mkfs.c | 227 +++++++++++++++----------- tests/mkfs.at | 4 + 13 files changed, 713 insertions(+), 429 deletions(-)
Signature · 1 line
1.8.5.3
PATCH 1/14 mkfs.gfs2: Make dev a member of mkfs_opts
As most of the functions which accept a struct mkfs_dev* also require a struct mkfs_opts* it makes sense to move the device path string into the mkfs_dev and add a struct mkfs_dev member to the struct mkfs_opts.
Nothing much to see here, just refactoring.
--- gfs2/mkfs/main_mkfs.c | 125 +++++++++++++++++++++++++------------------------- 1 file changed, 62 insertions(+), 63 deletions(-)
gfs2/mkfs/main_mkfs.c +62 -63
@@ -96,6 +96,28 @@ static void print_ext_opts(void) } } +/** +* Values probed by libblkid: +* alignment_offset: offset, in bytes, of the start of the dev from its natural alignment +* logical_sector_size: smallest addressable unit +* minimum_io_size: device's preferred unit of I/O. RAID stripe unit. +* optimal_io_size: biggest I/O we can submit without incurring a penalty. RAID stripe width. +* physical_sector_size: the smallest unit we can write atomically +*/ +struct mkfs_dev { +int fd; +const char *path; +struct stat stat; +uint64_t size; +unsigned long alignment_offset; +unsigned long logical_sector_size; +unsigned long minimum_io_size; +unsigned long optimal_io_size; +unsigned long physical_sector_size; + +unsigned int got_topol:1 ; +}; +struct mkfs_opts {unsigned bsize;unsigned qcsize;
@@ -107,7 +129,7 @@ struct mkfs_opts {uint32_t journals;const char *lockproto;const char *locktable; -const char *device; +struct mkfs_dev dev; unsigned discard:1; unsigned got_bsize:1;
@@ -130,27 +152,6 @@ struct mkfs_opts { unsigned align:1; }; -/** -* Values probed by libblkid: -* alignment_offset: offset, in bytes, of the start of the dev from its natural alignment -* logical_sector_size: smallest addressable unit -* minimum_io_size: device's preferred unit of I/O. RAID stripe unit. -* optimal_io_size: biggest I/O we can submit without incurring a penalty. RAID stripe width. -* physical_sector_size: the smallest unit we can write atomically -*/ -struct mkfs_dev { -int fd; -struct stat stat; -uint64_t size; -unsigned long alignment_offset; -unsigned long logical_sector_size; -unsigned long minimum_io_size; -unsigned long optimal_io_size; -unsigned long physical_sector_size; - -unsigned int got_topol:1 ; -}; -static void opts_init (struct mkfs_opts *opts) {memset (opts,0 ,sizeof (*opts));
@@ -362,7 +363,7 @@ static void opts_get(int argc, char *argv[], struct mkfs_opts *opts)if (strcmp (optarg,"gfs2" ) ==0 )continue ;if (!opts->got_device) { - opts->device = optarg; + opts->dev.path = optarg; opts->got_device =1 ; }else if (!opts->got_fssize &&isdigit (optarg[0 ])) { opts->fssize =atol (optarg);
@@ -457,10 +458,11 @@ static void are_you_sure(void)free (line); } -static unsigned choose_blocksize (struct mkfs_opts *opts,const struct mkfs_dev *dev) +static unsigned choose_blocksize (struct mkfs_opts *opts) {unsigned int x;unsigned int bsize = opts->bsize; +struct mkfs_dev *dev = &opts->dev;if (dev->got_topol && opts->debug) {printf ("alignment_offset: %lu\n" , dev->alignment_offset);
@@ -536,15 +538,14 @@ static void opts_check(struct mkfs_opts *opts) } } -static void print_results (struct gfs2_sb *sb,struct mkfs_dev *dev,struct mkfs_opts *opts, -uint64_t rgrps,uint64_t fssize) +static void print_results (struct gfs2_sb *sb,struct mkfs_opts *opts,uint64_t rgrps,uint64_t fssize) { -printf ("%-27s%s\n" ,_ ("Device:" ), opts->device); +printf ("%-27s%s\n" ,_ ("Device:" ), opts->dev.path);printf ("%-27s%u\n" ,_ ("Block size:" ), sb->sb_bsize);printf ("%-27s%.2f %s (%" PRIu64" %s)\n" ,_ ("Device size:" ),/* Translators: "GB" here means "gigabytes" */ - (dev->size / ((float )(1 <<30 ))),_ ("GB" ), - (dev->size / sb->sb_bsize),_ ("blocks" )); + (opts->dev.size / ((float )(1 <<30 ))),_ ("GB" ), + (opts->dev.size / sb->sb_bsize),_ ("blocks" ));printf ("%-27s%.2f %s (%" PRIu64" %s)\n" ,_ ("Filesystem size:" ), (fssize / ((float )(1 <<30 )) * sb->sb_bsize),_ ("GB" ), fssize,_ ("blocks" ));printf ("%-27s%u\n" ,_ ("Journals:" ), opts->journals);
@@ -580,7 +581,7 @@ static void warn_of_destruction(const char *path)free (abspath); } -static lgfs2_rgrps_t rgs_init (struct mkfs_opts *opts,struct mkfs_dev *dev,struct gfs2_sbd *sdp) +static lgfs2_rgrps_t rgs_init (struct mkfs_opts *opts,struct gfs2_sbd *sdp) {uint64_t rgsize = (opts->rgsize <<20 ) / sdp->bsize;struct lgfs2_rgrp_align align = {.base =0 , .offset =0 };
@@ -600,10 +601,10 @@ static lgfs2_rgrps_t rgs_init(struct mkfs_opts *opts, struct mkfs_dev *dev, stru align.offset = opts->sunit / sdp->bsize; } }else if (opts->align) { -if ((dev->minimum_io_size > dev->physical_sector_size) && - (dev->optimal_io_size > dev->physical_sector_size)) { - align.base = dev->optimal_io_size / sdp->bsize; - align.offset = dev->minimum_io_size / sdp->bsize; +if ((opts->dev.minimum_io_size > opts->dev.physical_sector_size) && + (opts->dev.optimal_io_size > opts->dev.physical_sector_size)) { + align.base = opts->dev.optimal_io_size / sdp->bsize; + align.offset = opts->dev.minimum_io_size / sdp->bsize; } }
@@ -624,7 +625,7 @@ static lgfs2_rgrps_t rgs_init(struct mkfs_opts *opts, struct mkfs_dev *dev, strureturn rgs; } -static uint64_t place_rgrps (struct gfs2_sbd *sdp,lgfs2_rgrps_t rgs,struct mkfs_opts *opts,const struct mkfs_dev *dev) +static uint64_t place_rgrps (struct gfs2_sbd *sdp,lgfs2_rgrps_t rgs,struct mkfs_opts *opts) {int err =0 ;lgfs2_rgrp_t rg =NULL ;
@@ -656,7 +657,7 @@ static uint64_t place_rgrps(struct gfs2_sbd *sdp, lgfs2_rgrps_t rgs, struct mkfsreturn ri->ri_data0 + ri->ri_data; } -static void sbd_init (struct gfs2_sbd *sdp,struct mkfs_opts *opts,struct mkfs_dev *dev,unsigned bsize) +static void sbd_init (struct gfs2_sbd *sdp,struct mkfs_opts *opts,unsigned bsize) {memset (sdp,0 ,sizeof (struct gfs2_sbd )); sdp->time =time (NULL );
@@ -665,20 +666,20 @@ static void sbd_init(struct gfs2_sbd *sdp, struct mkfs_opts *opts, struct mkfs_d sdp->qcsize = opts->qcsize; sdp->jsize = opts->jsize; sdp->md.journals = opts->journals; - sdp->device_fd = dev->fd; + sdp->device_fd = opts->dev.fd; sdp->bsize = bsize;if (compute_constants (sdp)) {perror (_ ("Failed to compute file system constants" ));exit (1 ); } - sdp->device.length = dev->size / sdp->bsize; + sdp->device.length = opts->dev.size / sdp->bsize;if (opts->got_fssize) {if (opts->fssize > sdp->device.length) {fprintf (stderr,_ ("Specified size is bigger than the device." ));die ("%s %.2f %s (%" PRIu64" %s)\n" ,_ ("Device size:" ), - dev->size / ((float )(1 <<30 )),_ ("GB" ), - dev->size / sdp->bsize,_ ("blocks" )); + opts->dev.size / ((float )(1 <<30 )),_ ("GB" ), + opts->dev.size / sdp->bsize,_ ("blocks" )); }/* TODO: Check if the fssize is too small, somehow */ sdp->device.length = opts->fssize;
@@ -733,20 +734,19 @@ static int probe_contents(struct mkfs_dev *dev)return 0 ; } -static void open_dev (const char *path,struct mkfs_dev *dev) +static void open_dev (struct mkfs_dev *dev) {int error; -memset (dev,0 ,sizeof (*dev)); - dev->fd =open (path,O_RDWR |O_CLOEXEC ); + dev->fd =open (dev->path,O_RDWR |O_CLOEXEC );if (dev->fd <0 ) { -perror (path); +perror (dev->path);exit (1 ); } error =fstat (dev->fd, &dev->stat);if (error <0 ) { -perror (path); +perror (dev->path);exit (1 ); }
@@ -755,11 +755,11 @@ static void open_dev(const char *path, struct mkfs_dev *dev) }else if (S_ISBLK (dev->stat.st_mode)) { dev->size =lseek (dev->fd,0 ,SEEK_END );if (dev->size <1 ) { -fprintf (stderr,_ ("Device '%s' is too small\n" ), path); +fprintf (stderr,_ ("Device '%s' is too small\n" ), dev->path);exit (1 ); } }else { -fprintf (stderr,_ ("'%s' is not a block device or regular file\n" ), path); +fprintf (stderr,_ ("'%s' is not a block device or regular file\n" ), dev->path);exit (1 ); }
@@ -773,7 +773,6 @@ void main_mkfs(int argc, char *argv[])struct gfs2_sbd sbd;struct gfs2_sb sb;struct mkfs_opts opts; -struct mkfs_dev dev;lgfs2_rgrps_t rgs;int error;unsigned bsize;
@@ -782,14 +781,14 @@ void main_mkfs(int argc, char *argv[])opts_get (argc, argv, &opts);opts_check (&opts); -open_dev (opts.device, &dev); - bsize =choose_blocksize (&opts, &dev); +open_dev (&opts.dev); + bsize =choose_blocksize (&opts); -if (S_ISREG (dev.stat.st_mode)) { +if (S_ISREG (opts.dev.stat.st_mode)) { opts.got_bsize =1 ;/* Use default block size for regular files */ } -sbd_init (&sbd, &opts, &dev, bsize); +sbd_init (&sbd, &opts, bsize);lgfs2_sb_init (&sb, bsize);if (opts.debug) {printf (_ ("File system options:\n" ));
@@ -804,16 +803,16 @@ void main_mkfs(int argc, char *argv[])printf (" sunit = %lu\n" , opts.sunit);printf (" swidth = %lu\n" , opts.swidth); } - rgs =rgs_init (&opts, &dev, &sbd); -warn_of_destruction (opts.device); + rgs =rgs_init (&opts, &sbd); +warn_of_destruction (opts.dev.path);if (opts.confirm && !opts.override)are_you_sure (); -if (!S_ISREG (dev.stat.st_mode) && opts.discard) -discard_blocks (dev.fd, dev.size, opts.debug); +if (!S_ISREG (opts.dev.stat.st_mode) && opts.discard) +discard_blocks (opts.dev.fd, opts.dev.size, opts.debug); - sbd.fssize =place_rgrps (&sbd, rgs, &opts, &dev); + sbd.fssize =place_rgrps (&sbd, rgs, &opts);if (sbd.fssize ==0 ) {fprintf (stderr,_ ("Failed to build resource groups\n" ));exit (1 );
@@ -872,24 +871,24 @@ void main_mkfs(int argc, char *argv[])gfs2_rgrp_free (&sbd.rgtree); - error =lgfs2_sb_write (&sb, dev.fd, sbd.bsize); + error =lgfs2_sb_write (&sb, opts.dev.fd, sbd.bsize);if (error) {perror (_ ("Failed to write superblock\n" ));exit (EXIT_FAILURE ); } - error =fsync (dev.fd); + error =fsync (opts.dev.fd);if (error){ -perror (opts.device); +perror (opts.dev.path);exit (EXIT_FAILURE ); } - error =close (dev.fd); + error =close (opts.dev.fd);if (error){ -perror (opts.device); +perror (opts.dev.path);exit (EXIT_FAILURE ); }if (!opts.quiet) -print_results (&sb, &dev, &opts, sbd.rgrps, sbd.fssize); +print_results (&sb, &opts, sbd.rgrps, sbd.fssize); }
Signature · 1 line
1.8.5.3
PATCH 2/14 libgfs2: Add lgfs2_space_for_data()
In reply to Andrew PriceAdd a function which calculates the total number of blocks required for a file given the size of its contents.
--- gfs2/libgfs2/fs_ops.c | 18 ++++++++++++++++++ gfs2/libgfs2/libgfs2.h | 2 ++ 2 files changed, 20 insertions(+)
gfs2/libgfs2/fs_ops.c +18 -0
@@ -273,6 +273,24 @@ void unstuff_dinode(struct gfs2_inode *ip) ip->i_di.di_height =1 ; } +/** +* Calculate the total number of blocks required by a file containing 'bytes' bytes of data. +*/ +uint64_t lgfs2_space_for_data (const struct gfs2_sbd *sdp,const unsigned bsize,const uint64_t bytes) +{ +uint64_t blks = (bytes + bsize -1 ) / bsize; +uint64_t ptrs = blks; + +if (bytes <= bsize -sizeof (struct gfs2_dinode )) +return 1 ; + +while (ptrs > sdp->sd_diptrs) { + ptrs = (ptrs + sdp->sd_inptrs -1 ) / sdp->sd_inptrs; + blks += ptrs; + } +return blks +1 ; +} +unsigned int calc_tree_height (struct gfs2_inode *ip,uint64_t size) {struct gfs2_sbd *sdp = ip->i_sbd;
gfs2/libgfs2/libgfs2.h +2 -0
@@ -450,6 +450,8 @@ extern void inode_put(struct gfs2_inode **ip);extern uint64_t data_alloc (struct gfs2_inode *ip);extern int lgfs2_meta_alloc (struct gfs2_inode *ip,uint64_t *blkno);extern int lgfs2_dinode_alloc (struct gfs2_sbd *sdp,const uint64_t blksreq,uint64_t *blkno); +extern uint64_t lgfs2_space_for_data (const struct gfs2_sbd *sdp,unsigned bsize,uint64_t bytes); +extern int gfs2_readi (struct gfs2_inode *ip,void *buf,uint64_t offset,unsigned int size);#define gfs2_writei (ip, buf, offset, size) \
Signature · 1 line
1.8.5.3
PATCH 3/14 libgfs2: Don't try to read more than IOV_MAX iovecs
In reply to Andrew PriceReading large collections of blocks, as gfs2_rgrp_read may do with large rgrps and small block sizes, can cause preadv() to fail with EINVAL in breadm(). This patch splits large reads into IOV_MAX chunks to avoid reads failing in that way. It also includes a test to exercise these changes.
--- gfs2/libgfs2/buf.c | 57 ++++++++++++++++++++++++++++++++---------------------- tests/mkfs.at | 4 ++++ 2 files changed, 38 insertions(+), 23 deletions(-)
gfs2/libgfs2/buf.c +34 -23
@@ -15,6 +15,14 @@#include "libgfs2.h" +#ifndef IOV_MAX +#ifdef UIO_MAXIOV +#define IOV_MAX UIO_MAXIOV +#else +#define IOV_MAX (1024) +#endif +#endif +struct gfs2_buffer_head *bget (struct gfs2_sbd *sdp,uint64_t num) {struct gfs2_buffer_head *bh;
@@ -34,31 +42,34 @@ struct gfs2_buffer_head *bget(struct gfs2_sbd *sdp, uint64_t num)int __breadm (struct gfs2_sbd *sdp,struct gfs2_buffer_head **bhs,size_t n,uint64_t block,int line,const char *caller) { -struct iovec *iov =alloca (n *sizeof (struct iovec )); +size_t v = (n <IOV_MAX ) ? n :IOV_MAX ; +struct iovec *iov =alloca (v *sizeof (struct iovec ));struct iovec *iovbase = iov; -uint64_t b = block; -size_t size =0 ; -size_t i; -int ret; - -for (i =0 ; i < n; i++) { - bhs[i] =bget (sdp, b++); -if (bhs[i] ==NULL ) -return -1 ; - *iov++ = bhs[i]->iov; - size += bhs[i]->iov.iov_len; +size_t i =0 ; + +while (i < n) { +int j; +ssize_t ret; +ssize_t size =0 ; + +for (j =0 ; (i + j < n) && (j <IOV_MAX ); j++) { + bhs[i + j] =bget (sdp, block + i + j); +if (bhs[i + j] ==NULL ) +return -1 ; + iov[j] = bhs[i + j]->iov; + size += bhs[i + j]->iov.iov_len; + } + + ret =preadv (sdp->device_fd, iovbase, j, (block + i) * sdp->bsize); +if (ret != size) { +fprintf (stderr,"bad read: %s from %s:%d: block %llu (0x%llx) " +"count: %d size: %zd ret: %zd\n" ,strerror (errno), + caller, line, (unsigned long long )block, + (unsigned long long )block, j, size, ret); +exit (-1 ); + } + i += j; } - - ret =preadv (sdp->device_fd, iovbase, n, block * sdp->bsize); - -if (ret != size) { -fprintf (stderr,"bad read: %s from %s:%d: block " -"%llu (0x%llx)\n" ,strerror (errno), - caller, line, (unsigned long long )block, - (unsigned long long )block); -exit (-1 ); - } -return 0 ; }
tests/mkfs.at +4 -0
@@ -54,6 +54,10 @@ AT_SETUP([Min. resource group size]) GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -r 32 $GFS_TGT]) AT_CLEANUP +AT_SETUP([Max. resource group size, min. block size]) +GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -r 2048 -b 512 $GFS_TGT]) +AT_CLEANUP + AT_SETUP([Max. journal size]) GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -J 1024 $GFS_TGT]) AT_CLEANUP
Signature · 1 line
1.8.5.3
PATCH 4/14 mkfs.gfs2: Fix the resource group layout strategy, again
In reply to Andrew PriceThe previous attempt at improving the resource group layout and alignment fell somewhat short of the mark and left some issues, such as the possibility of leaving a small resource group at the end of the device which gfs2_grow could wrongly use as the file system's resource group size.
The core of this patch is the new lgfs2_rgrps_plan() function which calculates a sensible resource group size given a target maximum (which we now default to 2GB instead of 256MB). In order to avoid leaving a gap or a small rgrp at the end of the device, we adjust the rgrp length down until a further adjustment would leave a gap, then apply a constant adjustment to the size of a subset of the resource groups.
The rest of the patch aims to clean up libgfs2's resource group API and give more control to the application rather than storing a lot of the resource group layout parameters in the lgfs2_rgrps_t. This should make it easier to use the same functions in gfs2_grow, fsck.gfs2 and any other tools which might need to manipulate resource groups.
--- gfs2/libgfs2/libgfs2.h | 16 ++-- gfs2/libgfs2/rgrp.c | 206 ++++++++++++++++++++++++++++++++++--------------- gfs2/mkfs/main_mkfs.c | 104 +++++++++++++++++-------- 3 files changed, 218 insertions(+), 108 deletions(-)
gfs2/libgfs2/libgfs2.h +6 -10
@@ -186,19 +186,16 @@ struct rgrp_tree {struct gfs2_buffer_head **bh; }; -struct lgfs2_rgrp_align { -uint64_t base; -uint64_t offset; -}; -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 start,uint64_t devlen,uint32_t rglen,struct lgfs2_rgrp_align *al); +extern lgfs2_rgrps_t lgfs2_rgrps_init (unsigned bsize,uint64_t devlen,uint64_t align,uint64_t offset); +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 lgfs2_rgrp_t lgfs2_rgrp_append (lgfs2_rgrps_t rgs,uint32_t rglen,int expand); -extern int lgfs2_rgrp_write (int fd,lgfs2_rgrp_t rg,unsigned bsize); -extern int lgfs2_rgrps_end (lgfs2_rgrps_t rgs); +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 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);// Temporary function to aid API migration extern struct osi_node *lgfs2_rgrps_root (lgfs2_rgrps_t rgs) __attribute__((deprecated));
@@ -350,7 +347,6 @@ struct metapath {#define GFS2_EXP_MIN_RGSIZE (1)#define GFS2_MIN_RGSIZE (32) -/* Look at this! Why can't we go bigger than 2GB? */ #define GFS2_MAX_RGSIZE (2048)/* meta.c */
gfs2/libgfs2/rgrp.c +142 -64
282 lines not on this page · raw message
gfs2/mkfs/main_mkfs.c +70 -34
161 lines not on this page · raw message
Signature · 1 line
1.8.5.3
PATCH 5/14 libgfs2: Don't call gfs2_blk2rgrpd in gfs2_set_bitmap
In reply to Andrew Pricegfs2_set_bitmap was calling gfs2_blk2rgrpd even when callers already have the resource group to hand. This changes that function to accept the resource group instead and calls to gfs2_blk2rgrpd have been moved outside.
--- gfs2/edit/hexedit.c | 2 +- gfs2/fsck/metawalk.c | 2 +- gfs2/fsck/pass5.c | 6 ++++-- gfs2/libgfs2/fs_bits.c | 5 +---- gfs2/libgfs2/fs_ops.c | 12 +++++------- gfs2/libgfs2/libgfs2.h | 2 +- 6 files changed, 13 insertions(+), 16 deletions(-)
gfs2/edit/hexedit.c +1 -1
@@ -2045,7 +2045,7 @@ static void find_change_block_alloc(int *newval)if (rgd) {gfs2_rgrp_read (&sbd, rgd);if (newval) { -if (gfs2_set_bitmap (&sbd, ablock, *newval)) +if (gfs2_set_bitmap (rgd, ablock, *newval))printf ("-1 (block invalid or part of an rgrp).\n" );else printf ("%d\n" , *newval);
gfs2/fsck/metawalk.c +1 -1
@@ -73,7 +73,7 @@ int check_n_fix_bitmap(struct gfs2_sbd *sdp, uint64_t blk, int error_on_dinode,subtract to the free space. If the type changed from dinode to data or data to dinode, no change in free space. */ -gfs2_set_bitmap (sdp, blk, new_bitmap_state); +gfs2_set_bitmap (rgd, blk, new_bitmap_state);if (new_bitmap_state ==GFS2_BLKST_FREE ) {/* If we're freeing a dinode, get rid of the hash table entries for it. */
gfs2/fsck/pass5.c +4 -2
@@ -148,7 +148,8 @@ static int check_block_status(struct gfs2_sbd *sdp, char *buffer, (unsigned long long)block);if (query (_ ("Do you want to reclaim the block? " "(y/n) " ))) { -if (gfs2_set_bitmap (sdp, block, block_status)) +lgfs2_rgrp_t rg =gfs2_blk2rgrpd (sdp, block); +if (gfs2_set_bitmap (rg, block, block_status)) log_err(_("Unlinked block %llu " "(0x%llx) bitmap not fixed." "\n"),
@@ -182,7 +183,8 @@ static int check_block_status(struct gfs2_sbd *sdp, char *buffer,if (query (_ ("Fix bitmap for block %llu (0x%llx) ? (y/n) " ), (unsigned long long )block, (unsigned long long )block)) { -if (gfs2_set_bitmap (sdp, block, block_status)) +lgfs2_rgrp_t rg =gfs2_blk2rgrpd (sdp, block); +if (gfs2_set_bitmap (rg, block, block_status))log_err (_ ("Repair failed.\n" ));else log_err (_ ("Fixed.\n" ));
gfs2/libgfs2/fs_bits.c +1 -4
@@ -124,12 +124,11 @@ int gfs2_check_range(struct gfs2_sbd *sdp, uint64_t blkno)* * Returns: 0 on success, -1 on error */ -int gfs2_set_bitmap (struct gfs2_sbd *sdp,uint64_t blkno,int state) +int gfs2_set_bitmap (lgfs2_rgrp_t rgd,uint64_t blkno,int state) {int buf;uint32_t rgrp_block;struct gfs2_bitmap *bits =NULL ; -struct rgrp_tree *rgd;unsigned char *byte, cur_state;unsigned int bit;
@@ -137,8 +136,6 @@ int gfs2_set_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, int state)if ((state <GFS2_BLKST_FREE ) || (state >GFS2_BLKST_DINODE ))return -1 ; - rgd =gfs2_blk2rgrpd (sdp, blkno); -if (!rgd || blkno < rgd->ri.ri_data0)return -1 ;
gfs2/libgfs2/fs_ops.c +5 -7
@@ -141,7 +141,7 @@ static int blk_alloc_in_rg(struct gfs2_sbd *sdp, unsigned state, struct rgrp_treif (blkno ==0 )return -1 ; -if (gfs2_set_bitmap (sdp, blkno, state)) +if (gfs2_set_bitmap (rgd, blkno, state))return -1 ;if (state ==GFS2_BLKST_DINODE )
@@ -1763,7 +1763,7 @@ void gfs2_free_block(struct gfs2_sbd *sdp, uint64_t block)/* Adjust the free space count for the freed block */ rgd =gfs2_blk2rgrpd (sdp, block);/* find the rg for indir block */ if (rgd) { -gfs2_set_bitmap (sdp, block,GFS2_BLKST_FREE ); +gfs2_set_bitmap (rgd, block,GFS2_BLKST_FREE ); rgd->rg.rg_free++;/* adjust the free count */ if (sdp->gfs1)gfs_rgrp_out ((struct gfs_rgrp *)&rgd->rg, rgd->bh[0 ]);
@@ -1826,16 +1826,14 @@ int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t diblock) } } } -/* Set the bitmap type for inode to free space: */ -gfs2_set_bitmap (sdp, ip->i_di.di_num.no_addr,GFS2_BLKST_FREE ); + rgd =gfs2_blk2rgrpd (sdp, diblock); +gfs2_set_bitmap (rgd, diblock,GFS2_BLKST_FREE );inode_put (&ip);/* inode_put deallocated the extra block used by the disk inode, */ /* so adjust it in the superblock struct */ sdp->blks_alloced--; -/* Now we have to adjust the rg freespace count and inode count: */ - rgd =gfs2_blk2rgrpd (sdp, diblock); rgd->rg.rg_free++; - rgd->rg.rg_dinodes--;/* one less inode in use */ + rgd->rg.rg_dinodes--;if (sdp->gfs1)gfs_rgrp_out ((struct gfs_rgrp *)&rgd->rg, rgd->bh[0 ]);else
gfs2/libgfs2/libgfs2.h +1 -1
@@ -418,7 +418,7 @@ extern int gfs2_check_range(struct gfs2_sbd *sdp, uint64_t blkno);/* functions with blk #'s that are file system relative */ extern int lgfs2_get_bitmap (struct gfs2_sbd *sdp,uint64_t blkno,struct rgrp_tree *rgd); -extern int gfs2_set_bitmap (struct gfs2_sbd *sdp,uint64_t blkno,int state); +extern int gfs2_set_bitmap (lgfs2_rgrp_t rg,uint64_t blkno,int state);/* fs_geometry.c */ extern uint32_t rgblocks2bitblocks(const unsigned int bsize, const uint32_t rgblocks,
Signature · 1 line
1.8.5.3
PATCH 6/14 libgfs2: Add abstractions for rgrp tree traversal
In reply to Andrew PriceUsers of libgfs2 are required to include the gfs2-utils-specific osi_tree.h in order to make use of the resource groups. With this patch we introduce functions which wrap the osi_first and osi_next functions so that we can hide the implementation of the resource group tree behind the lgfs2_rgrp_t type. Converting users of the osi_tree.h functions to the new rgrp APIs will be done later and gradually.
--- gfs2/libgfs2/libgfs2.h | 3 +++ gfs2/libgfs2/rgrp.c | 15 +++++++++++++++ 2 files changed, 18 insertions(+)
gfs2/libgfs2/libgfs2.h +3 -0
@@ -197,6 +197,9 @@ extern uint32_t lgfs2_rgrps_plan(const lgfs2_rgrps_t rgs, uint64_t space, uint32extern lgfs2_rgrp_t lgfs2_rgrp_append (lgfs2_rgrps_t rgs,uint64_t addr,uint32_t rglen,uint64_t *nextaddr);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 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);// Temporary function to aid API migration extern struct osi_node *lgfs2_rgrps_root (lgfs2_rgrps_t rgs) __attribute__((deprecated));
gfs2/libgfs2/rgrp.c +15 -0
@@ -479,3 +479,18 @@ int lgfs2_rgrp_write(const lgfs2_rgrps_t rgs, int fd, const lgfs2_rgrp_t rg)free (buff);return 0 ; } + +lgfs2_rgrp_t lgfs2_rgrp_first (lgfs2_rgrps_t rgs) +{ +return (lgfs2_rgrp_t )osi_first (&rgs->root); +} + +lgfs2_rgrp_t lgfs2_rgrp_next (lgfs2_rgrp_t rg) +{ +return (lgfs2_rgrp_t )osi_next (&rg->node); +} + +lgfs2_rgrp_t lgfs2_rgrp_last (lgfs2_rgrps_t rgs) +{ +return (lgfs2_rgrp_t )osi_last (&rgs->root); +}
Signature · 1 line
1.8.5.3
PATCH 7/14 libgfs2: Split out the rindex calculation from lgfs2_rgrp_append
In reply to Andrew PriceIn 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.
--- gfs2/libgfs2/libgfs2.h | 4 ++- gfs2/libgfs2/rgrp.c | 83 ++++++++++++++++++++++++++++++++------------------ gfs2/mkfs/main_mkfs.c | 26 ++++++++-------- 3 files changed, 70 insertions(+), 43 deletions(-)
gfs2/libgfs2/libgfs2.h +3 -1
@@ -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);
gfs2/libgfs2/rgrp.c +53 -30
117 lines not on this page · raw message
gfs2/mkfs/main_mkfs.c +14 -12
@@ -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 ; }
Signature · 1 line
1.8.5.3
PATCH 8/14 libgfs2: Consolidate rgrp_tree and bitstruct allocations
In reply to Andrew Pricergrp_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.
--- gfs2/libgfs2/libgfs2.h | 1 + gfs2/libgfs2/rgrp.c | 143 ++++++++++++++++++++++++++++++------------------- gfs2/mkfs/main_mkfs.c | 2 +- 3 files changed, 91 insertions(+), 55 deletions(-)
gfs2/libgfs2/libgfs2.h +1 -0
@@ -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);
gfs2/libgfs2/rgrp.c +89 -54
196 lines not on this page · raw message
gfs2/mkfs/main_mkfs.c +1 -1
@@ -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) {
Signature · 1 line
1.8.5.3
PATCH 9/14 libgfs2: Add a lgfs2_rindex_read_fd() function
In reply to Andrew Pricegfs2_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.
--- gfs2/libgfs2/libgfs2.h | 5 +++-- gfs2/libgfs2/rgrp.c | 43 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 42 insertions(+), 6 deletions(-)
gfs2/libgfs2/libgfs2.h +3 -2
@@ -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);
gfs2/libgfs2/rgrp.c +39 -4
67 lines not on this page · raw message
Signature · 1 line
1.8.5.3
PATCH 10/14 libgfs2: Const-ify the 'ri' argument to gfs2_rindex_out
In reply to Andrew PriceThis 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).
--- gfs2/libgfs2/libgfs2.h | 2 +- gfs2/libgfs2/ondisk.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-)
gfs2/libgfs2/libgfs2.h +1 -1
@@ -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);
gfs2/libgfs2/ondisk.c +2 -2
@@ -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);
Signature · 1 line
1.8.5.3
PATCH 11/14 libgfs2: Fix off-by-one in lgfs2_rgrps_plan
In reply to Andrew PriceWe 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.
--- gfs2/libgfs2/rgrp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
gfs2/libgfs2/rgrp.c +3 -2
@@ -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--;
Signature · 1 line
1.8.5.3
PATCH 12/14 libgfs2: Stick to the (rgrp) plan in lgfs2_rindex_entry_new
In reply to Andrew Pricelgfs2_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.
--- gfs2/libgfs2/rgrp.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-)
gfs2/libgfs2/rgrp.c +12 -9
@@ -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 ;
Signature · 1 line
1.8.5.3
PATCH 13/14 gfs2_grow: Migrate to the new resource group API
In reply to Andrew PriceNow 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.
--- gfs2/mkfs/gfs2_mkfs.h | 1 - gfs2/mkfs/main_grow.c | 304 +++++++++++++++++++++++--------------------------- 2 files changed, 140 insertions(+), 165 deletions(-)
gfs2/mkfs/gfs2_mkfs.h +0 -1
@@ -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[]);
gfs2/mkfs/main_grow.c +140 -164
401 lines not on this page · raw message
Signature · 1 line
1.8.5.3
PATCH 14/14 gfs2_grow: Add stripe alignment
In reply to Andrew PriceWrap 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().
--- gfs2/mkfs/main_grow.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-)
gfs2/mkfs/main_grow.c +49 -2
@@ -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 ;
Signature · 1 line
1.8.5.3
cover gfs2_grow and libgfs2 rgrp API improvements
In reply to Andrew Price----- Original Message -----
Quoted 59 lines
Hi,
This patch set aims to do three main things:
- Improve and simplify libgfs2's rgrp APIs, bringing them closer to being proper library code
- Improvegfs2_growusing the new rgrp APIs for rgrp alignment and size calculation, larger rgrps by default, etc.
- Fix problems in libgfs2 and the utils uncovered along the wayThese patches take us closer to being able to hide the implementation of the rgrp lists (currently using
osi_tree.h) within libgfs2 and decoupling so that many resource group sets (lgfs2_rgrps_t's) can be manipulated independently. Bookkeeping will eventually be done by the applications instead of keeping application-specific data in thegfs2_sbdstructure so this takes us closer to being able to remove sbd.rgtree and sbd.rgcalc.Although the net diff is 284 insertions, that will be offset significantly once the old rgrp functions in libgfs2 can be removed (when fsck, convert and edit no longer use them).
I've thrown various tests at this set and added one to the in-tree test suite. Static analysis with coverity shows 1 defect fixed and 0 added.
Please review,
AndyAndrew Price (14):
mkfs.gfs2: Make dev a member ofmkfs_opts
libgfs2: Addlgfs2_space_for_data()
libgfs2: Don't try to read more thanIOV_MAXiovecs mkfs.gfs2: Fix the resource group layout strategy, again
libgfs2: Don't callgfs2_blk2rgrpdingfs2_set_bitmap
libgfs2: Add abstractions for rgrp tree traversal
libgfs2: Split out the rindex calculation fromlgfs2_rgrp_append
libgfs2: Consolidatergrp_treeand bitstruct allocations
libgfs2: Add algfs2_rindex_read_fd()function
libgfs2: Const-ify the 'ri' argument togfs2_rindex_out
libgfs2: Fix off-by-one inlgfs2_rgrps_plan
libgfs2: Stick to the (rgrp) plan inlgfs2_rindex_entry_new
gfs2_grow: Migrate to the new resource group API
gfs2_grow: Add stripe alignmentgfs2/edit/hexedit.c | 2 +- gfs2/fsck/metawalk.c | 2 +- gfs2/fsck/pass5.c | 6 +- gfs2/libgfs2/buf.c | 57 ++++--- gfs2/libgfs2/fs_bits.c | 5 +- gfs2/libgfs2/fs_ops.c | 30 +++- gfs2/libgfs2/libgfs2.h | 31 ++-- gfs2/libgfs2/ondisk.c | 4 +- gfs2/libgfs2/rgrp.c | 422 +++++++++++++++++++++++++++++++++++-------------- gfs2/mkfs/gfs2_mkfs.h | 1 - gfs2/mkfs/main_grow.c | 351 +++++++++++++++++++++------------------- gfs2/mkfs/main_mkfs.c | 227 +++++++++++++++----------- tests/mkfs.at | 4 + 13 files changed, 713 insertions(+), 429 deletions(-)
Quoted 4 lines
--
1.8.5.3
Hi,
I can't say I followed it all, but it looks like a good approach. Good job.
Regards,
Bob Peterson
Red Hat File Systems