* [Cluster-devel] [PATCH 1/5] mkfs.gfs2: Make dev a member of mkfs_opts
@ 2014-03-20 14:46 Andrew Price
2014-03-20 14:46 ` [Cluster-devel] [PATCH 2/5] libgfs2: Add lgfs2_space_for_data() Andrew Price
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Andrew Price @ 2014-03-20 14:46 UTC (permalink / raw)
To: cluster-devel.redhat.com
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.
Signed-off-by: Andrew Price <anprice@redhat.com>
---
gfs2/mkfs/main_mkfs.c | 125 +++++++++++++++++++++++++-------------------------
1 file changed, 62 insertions(+), 63 deletions(-)
diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c
index e58de68..40f4766 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
@@ -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, stru
return 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 mkfs
return 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);
}
--
1.8.5.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [Cluster-devel] [PATCH 2/5] libgfs2: Add lgfs2_space_for_data()
2014-03-20 14:46 [Cluster-devel] [PATCH 1/5] mkfs.gfs2: Make dev a member of mkfs_opts Andrew Price
@ 2014-03-20 14:46 ` Andrew Price
2014-03-20 14:46 ` [Cluster-devel] [PATCH 3/5] libgfs2: Don't try to read more than IOV_MAX iovecs Andrew Price
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Andrew Price @ 2014-03-20 14:46 UTC (permalink / raw)
To: cluster-devel.redhat.com
Add a function which calculates the total number of blocks required for
a file given the size of its contents.
Signed-off-by: Andrew Price <anprice@redhat.com>
---
gfs2/libgfs2/fs_ops.c | 18 ++++++++++++++++++
gfs2/libgfs2/libgfs2.h | 2 ++
2 files changed, 20 insertions(+)
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index 198f6eb..b95f2ed 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -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;
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 6248e4b..ce51e8c 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -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) \
--
1.8.5.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [Cluster-devel] [PATCH 3/5] libgfs2: Don't try to read more than IOV_MAX iovecs
2014-03-20 14:46 [Cluster-devel] [PATCH 1/5] mkfs.gfs2: Make dev a member of mkfs_opts Andrew Price
2014-03-20 14:46 ` [Cluster-devel] [PATCH 2/5] libgfs2: Add lgfs2_space_for_data() Andrew Price
@ 2014-03-20 14:46 ` Andrew Price
2014-03-20 14:46 ` [Cluster-devel] [PATCH 4/5] mkfs.gfs2: Fix the resource group layout strategy, again Andrew Price
2014-03-20 14:46 ` [Cluster-devel] [PATCH 5/5] libgfs2: Don't call gfs2_blk2rgrpd in gfs2_set_bitmap Andrew Price
3 siblings, 0 replies; 5+ messages in thread
From: Andrew Price @ 2014-03-20 14:46 UTC (permalink / raw)
To: cluster-devel.redhat.com
Reading 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.
Signed-off-by: Andrew Price <anprice@redhat.com>
---
gfs2/libgfs2/buf.c | 57 ++++++++++++++++++++++++++++++++----------------------
tests/mkfs.at | 4 ++++
2 files changed, 38 insertions(+), 23 deletions(-)
diff --git a/gfs2/libgfs2/buf.c b/gfs2/libgfs2/buf.c
index 6fcdd17..92cd393 100644
--- a/gfs2/libgfs2/buf.c
+++ b/gfs2/libgfs2/buf.c
@@ -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;
}
diff --git a/tests/mkfs.at b/tests/mkfs.at
index 2616109..ff99bb1 100644
--- a/tests/mkfs.at
+++ b/tests/mkfs.at
@@ -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
--
1.8.5.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [Cluster-devel] [PATCH 4/5] mkfs.gfs2: Fix the resource group layout strategy, again
2014-03-20 14:46 [Cluster-devel] [PATCH 1/5] mkfs.gfs2: Make dev a member of mkfs_opts Andrew Price
2014-03-20 14:46 ` [Cluster-devel] [PATCH 2/5] libgfs2: Add lgfs2_space_for_data() Andrew Price
2014-03-20 14:46 ` [Cluster-devel] [PATCH 3/5] libgfs2: Don't try to read more than IOV_MAX iovecs Andrew Price
@ 2014-03-20 14:46 ` Andrew Price
2014-03-20 14:46 ` [Cluster-devel] [PATCH 5/5] libgfs2: Don't call gfs2_blk2rgrpd in gfs2_set_bitmap Andrew Price
3 siblings, 0 replies; 5+ messages in thread
From: Andrew Price @ 2014-03-20 14:46 UTC (permalink / raw)
To: cluster-devel.redhat.com
The 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.
Signed-off-by: Andrew Price <anprice@redhat.com>
---
gfs2/libgfs2/libgfs2.h | 16 ++--
gfs2/libgfs2/rgrp.c | 206 ++++++++++++++++++++++++++++++++++---------------
gfs2/mkfs/main_mkfs.c | 104 +++++++++++++++++--------
3 files changed, 218 insertions(+), 108 deletions(-)
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index ce51e8c..24947c2 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -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 */
diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c
index 0752772..1242385 100644
--- a/gfs2/libgfs2/rgrp.c
+++ b/gfs2/libgfs2/rgrp.c
@@ -223,6 +223,11 @@ void gfs2_rgrp_free(struct osi_root *rgrp_tree)
}
}
+struct rgplan {
+ uint32_t num;
+ uint32_t len;
+};
+
/**
* This structure is defined in libgfs2.h as an opaque type. It stores the
* constants and context required for creating resource groups from any point
@@ -230,17 +235,11 @@ void gfs2_rgrp_free(struct osi_root *rgrp_tree)
*/
struct _lgfs2_rgrps {
struct osi_root root;
- uint64_t nextaddr;
+ struct rgplan plan[2];
unsigned bsize;
unsigned long align;
unsigned long align_off;
- unsigned long curr_offset;
- uint64_t maxrgsz;
- uint64_t minrgsz;
uint64_t devlen;
- uint64_t count;
- uint64_t blks_total;
- uint32_t rgsize;
};
static uint64_t align_block(const uint64_t base, const uint64_t align)
@@ -251,29 +250,121 @@ static uint64_t align_block(const uint64_t base, const uint64_t align)
}
/**
+ * Calculate the aligned block address of a resource group.
+ * rgs: The resource groups handle
+ * base: The base address of the first resource group address, in blocks
+ * Returns the aligned address of the first resource group.
+ */
+uint64_t lgfs2_rgrp_align_addr(const lgfs2_rgrps_t rgs, uint64_t addr)
+{
+ return align_block(addr, rgs->align);
+}
+
+/**
+ * Calculate the aligned relative address of the next resource group (and thus
+ * the aligned length of this one).
+ * rgs: The resource groups handle
+ * base: The base length of the current resource group, in blocks
+ * Returns the length of the resource group (the aligned relative address of
+ * the next one)
+ */
+uint32_t lgfs2_rgrp_align_len(const lgfs2_rgrps_t rgs, uint32_t len)
+{
+ return align_block(len, rgs->align) + rgs->align_off;
+}
+
+/**
+ * Plan the sizes of resource groups for remaining free space, based on a
+ * target maximum size. In order to make best use of the space while keeping
+ * the resource groups aligned appropriately we need to either reduce the
+ * length of every resource group or of a subset of the resource groups, so
+ * we're left with either one or two resource group sizes. We keep track of
+ * both of these and the numbers of each size of resource group inside the
+ * resource groups descriptor.
+ * 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.
+ */
+uint32_t lgfs2_rgrps_plan(const lgfs2_rgrps_t rgs, uint64_t space, uint32_t tgtsize)
+{
+ uint32_t maxlen = (GFS2_MAX_RGSIZE << 20) / rgs->bsize;
+ uint32_t minlen = (GFS2_MIN_RGSIZE << 20) / rgs->bsize;
+
+ /* Apps should already have checked that the rg size is <=
+ GFS2_MAX_RGSIZE but just in case alignment pushes it over we clamp
+ it back down while calculating the initial rgrp length. */
+ do {
+ rgs->plan[0].len = lgfs2_rgrp_align_len(rgs, tgtsize);
+ tgtsize -= (rgs->align + 1);
+ } while (rgs->plan[0].len > maxlen);
+
+ rgs->plan[0].num = space / rgs->plan[0].len;
+
+ if ((space - (rgs->plan[0].num * rgs->plan[0].len)) > rgs->align) {
+ unsigned adj = (rgs->align > 0) ? rgs->align : 1;
+
+ /* 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].len -= adj;
+
+ /* We've adjusted the size of the rgrps down as far as we can
+ without leaving a large gap at the end of the device now,
+ but we still need to reduce the size of some rgrps in order
+ to make everything fit, so we use the second rgplan to
+ specify a second length for a subset of the resource groups.
+ If plan[0].len already divides the space with no remainder,
+ plan[1].num will stay 0 and it won't be used. */
+ rgs->plan[1].len = rgs->plan[0].len - adj;
+ rgs->plan[1].num = 0;
+
+ while (((rgs->plan[0].len * rgs->plan[0].num) +
+ (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--;
+ rgs->plan[1].num++;
+ }
+ }
+
+ /* Once we've reached this point,
+ (plan[0].num * plan[0].len) + (plan[1].num * plan[1].len)
+ will be less than one adjustment smaller than 'space'. */
+
+ if (rgs->plan[0].len < minlen)
+ return 0;
+
+ return rgs->plan[0].len;
+}
+
+/**
* Create and initialise an empty set of resource groups
* bsize: The block size of the fs
- * start: The block address of the first resource group
* devlen: The length of the device, in fs blocks
- * rglen: Default rg size, in blocks
- * al: The required alignment of the resource groups
+ * align: The required stripe alignment of the resource groups. Must be a multiple of 'offset'.
+ * offset: The required stripe offset of the resource groups
* Returns an initialised lgfs2_rgrps_t or NULL if unsuccessful with errno set
*/
-lgfs2_rgrps_t lgfs2_rgrps_init(unsigned bsize, uint64_t start, uint64_t devlen, uint32_t rglen, struct lgfs2_rgrp_align *al)
+lgfs2_rgrps_t lgfs2_rgrps_init(unsigned bsize, uint64_t devlen, uint64_t align, uint64_t offset)
{
- lgfs2_rgrps_t rgs = calloc(1, sizeof(*rgs));
+ lgfs2_rgrps_t rgs;
+
+ errno = EINVAL;
+ if (offset != 0 && (align % offset) != 0)
+ return NULL;
+
+ rgs = calloc(1, sizeof(*rgs));
if (rgs == NULL)
return NULL;
rgs->bsize = bsize;
- rgs->maxrgsz = (GFS2_MAX_RGSIZE << 20) / bsize;
- rgs->minrgsz = (GFS2_MIN_RGSIZE << 20) / bsize;
- rgs->rgsize = rglen;
rgs->devlen = devlen;
- rgs->align = al->base;
- rgs->align_off = al->offset;
+ rgs->align = align;
+ rgs->align_off = offset;
memset(&rgs->root, 0, sizeof(rgs->root));
- rgs->nextaddr = align_block(start, rgs->align);
return rgs;
}
@@ -287,14 +378,6 @@ struct gfs2_rindex *lgfs2_rgrp_index(lgfs2_rgrp_t rg)
}
/**
- * Return non-zero if there is space left for more resource groups or zero if not
- */
-int lgfs2_rgrps_end(lgfs2_rgrps_t rgs)
-{
- return (rgs->nextaddr == 0);
-}
-
-/**
* Returns the total resource group size, in blocks, required to give blksreq data blocks
*/
unsigned lgfs2_rgsize_for_data(uint64_t blksreq, unsigned bsize)
@@ -316,43 +399,38 @@ struct osi_node *lgfs2_rgrps_root(lgfs2_rgrps_t rgs)
/**
* Create a new resource group after the last resource group in a set.
* rgs: The set of resource groups
- * rglen: The required length of the resource group. If its is 0 the default rgsize
- * passed to lgfs2_rgrps_init() is used.
- * expand: Whether to expand the resource group when alignment would leave a gap.
- * Returns the new resource group on success or NULL on failure.
+ * addr: The address at which to place this resource group
+ * rglen: The required length of the resource group, in fs blocks.
+ * Returns the new resource group on success or NULL on failure with errno set.
+ * If errno is ENOSPC on a NULL return from this function, it could be
+ * interpreted as 'finished' unless you expected there to be enough space on
+ * the device for the resource group.
*/
-lgfs2_rgrp_t lgfs2_rgrp_append(lgfs2_rgrps_t rgs, uint32_t rglen, int expand)
+lgfs2_rgrp_t lgfs2_rgrp_append(lgfs2_rgrps_t rgs, uint64_t addr, uint32_t rglen, uint64_t *nextaddr)
{
int err = 0;
- lgfs2_rgrp_t rg = rgrp_insert(&rgs->root, rgs->nextaddr);
- if (rg == NULL)
- return NULL;
-
- rgs->curr_offset += rgs->align_off;
- if (rgs->curr_offset >= rgs->align)
- rgs->curr_offset = 0;
-
- if (rgs->rgsize > rglen)
- rglen = rgs->rgsize;
-
- rgs->nextaddr = align_block(rg->ri.ri_addr + rgs->rgsize, rgs->align) + rgs->curr_offset;
- /* Use up gap left by alignment if possible */
- if (expand && ((rgs->nextaddr - rg->ri.ri_addr) <= rgs->maxrgsz))
- rglen = rgs->nextaddr - rg->ri.ri_addr;
-
- if ((rgs->nextaddr + rgs->rgsize) > rgs->devlen) {
- /* Squeeze the last 1 or 2 rgs into the remaining space */
- if ((rgs->nextaddr < rgs->devlen) && ((rgs->devlen - rgs->nextaddr) >= rgs->minrgsz)) {
- rgs->rgsize = rgs->devlen - rgs->nextaddr;
+ lgfs2_rgrp_t rg;
+
+ if (rglen == 0) {
+ if (rgs->plan[0].num > 0) {
+ rglen = rgs->plan[0].len;
+ rgs->plan[0].num--;
+ } else if (rgs->plan[1].num > 0) {
+ rglen = rgs->plan[1].len;
+ rgs->plan[1].num--;
} else {
- if (rgs->devlen - rg->ri.ri_addr <= rgs->maxrgsz)
- rglen = rgs->devlen - rg->ri.ri_addr;
- else
- rglen = rgs->maxrgsz;
- /* This is the last rg */
- rgs->nextaddr = 0;
+ errno = ENOSPC;
+ return NULL;
}
}
+ if (addr + rglen > rgs->devlen) {
+ errno = ENOSPC;
+ return NULL;
+ }
+
+ rg = rgrp_insert(&rgs->root, addr);
+ if (rg == NULL)
+ return NULL;
rg->ri.ri_length = rgblocks2bitblocks(rgs->bsize, rglen, &rg->ri.ri_data);
rg->ri.ri_data0 = rg->ri.ri_addr + rg->ri.ri_length;
@@ -361,12 +439,12 @@ lgfs2_rgrp_t lgfs2_rgrp_append(lgfs2_rgrps_t rgs, uint32_t rglen, int expand)
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;
- rgs->blks_total += rg->ri.ri_data;
- rgs->count++;
+
+ if (nextaddr)
+ *nextaddr = rg->ri.ri_addr + rglen;
return rg;
}
@@ -374,10 +452,10 @@ lgfs2_rgrp_t lgfs2_rgrp_append(lgfs2_rgrps_t rgs, uint32_t rglen, int expand)
* Write a resource group to a file descriptor.
* Returns 0 on success or non-zero on failure with errno set
*/
-int lgfs2_rgrp_write(int fd, lgfs2_rgrp_t rg, unsigned bsize)
+int lgfs2_rgrp_write(const lgfs2_rgrps_t rgs, int fd, const lgfs2_rgrp_t rg)
{
ssize_t ret = 0;
- size_t len = rg->ri.ri_length * bsize;
+ size_t len = rg->ri.ri_length * rgs->bsize;
unsigned int i;
const struct gfs2_meta_header bmh = {
.mh_magic = GFS2_MAGIC,
@@ -390,9 +468,9 @@ int lgfs2_rgrp_write(int fd, lgfs2_rgrp_t rg, unsigned bsize)
gfs2_rgrp_out(&rg->rg, buff);
for (i = 1; i < rg->ri.ri_length; i++)
- gfs2_meta_header_out(&bmh, buff + (i * bsize));
+ gfs2_meta_header_out(&bmh, buff + (i * rgs->bsize));
- ret = pwrite(fd, buff, len, rg->ri.ri_addr * bsize);
+ ret = pwrite(fd, buff, len, rg->ri.ri_addr * rgs->bsize);
if (ret != len) {
free(buff);
return -1;
diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c
index 40f4766..ae82c9f 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
@@ -160,7 +160,7 @@ static void opts_init(struct mkfs_opts *opts)
opts->bsize = GFS2_DEFAULT_BSIZE;
opts->jsize = GFS2_DEFAULT_JSIZE;
opts->qcsize = GFS2_DEFAULT_QCSIZE;
- opts->rgsize = GFS2_DEFAULT_RGSIZE;
+ opts->rgsize = GFS2_MAX_RGSIZE;
opts->lockproto = "lock_dlm";
opts->locktable = "";
opts->confirm = 1;
@@ -583,9 +583,9 @@ static void warn_of_destruction(const char *path)
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};
lgfs2_rgrps_t rgs;
+ uint64_t al_base = 0;
+ uint64_t al_off = 0;
if (opts->align && opts->got_sunit) {
if ((opts->sunit % sdp->bsize) != 0) {
@@ -597,18 +597,18 @@ static lgfs2_rgrps_t rgs_init(struct mkfs_opts *opts, struct gfs2_sbd *sdp)
opts->swidth, opts->sunit);
exit(1);
} else {
- align.base = opts->swidth / sdp->bsize;
- align.offset = opts->sunit / sdp->bsize;
+ al_base = opts->swidth / sdp->bsize;
+ al_off = opts->sunit / sdp->bsize;
}
} else if (opts->align) {
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;
+ al_base = opts->dev.optimal_io_size / sdp->bsize;
+ al_off = opts->dev.minimum_io_size / sdp->bsize;
}
}
- rgs = lgfs2_rgrps_init(sdp->bsize, sdp->sb_addr + 1, sdp->device.length, rgsize, &align);
+ rgs = lgfs2_rgrps_init(sdp->bsize, sdp->device.length, al_base, al_off);
if (rgs == NULL) {
perror(_("Could not initialise resource groups"));
exit(-1);
@@ -617,7 +617,7 @@ static lgfs2_rgrps_t rgs_init(struct mkfs_opts *opts, struct gfs2_sbd *sdp)
if (opts->debug) {
printf(" rgrp align = ");
if (opts->align)
- printf("%lu+%lu blocks\n", align.base, align.offset);
+ printf("%lu+%lu blocks\n", al_base, al_off);
else
printf("(disabled)\n");
}
@@ -625,36 +625,71 @@ static lgfs2_rgrps_t rgs_init(struct mkfs_opts *opts, struct gfs2_sbd *sdp)
return rgs;
}
-static uint64_t place_rgrps(struct gfs2_sbd *sdp, lgfs2_rgrps_t rgs, struct mkfs_opts *opts)
+static int place_rgrp(struct gfs2_sbd *sdp, lgfs2_rgrps_t rgs, uint64_t rgaddr, uint32_t len, uint64_t *next)
{
int err = 0;
lgfs2_rgrp_t rg = NULL;
struct gfs2_rindex *ri = NULL;
- while (!lgfs2_rgrps_end(rgs)) {
- rg = lgfs2_rgrp_append(rgs, 0, !opts->got_rgsize);
- if (rg == NULL) {
- perror(_("Failed to create resource group"));
- return 0;
- }
- err = lgfs2_rgrp_write(sdp->device_fd, rg, sdp->bsize);
- if (err != 0) {
- perror(_("Failed to write resource group"));
- return 0;
- }
- ri = lgfs2_rgrp_index(rg);
- if (opts->debug) {
- gfs2_rindex_print(ri);
- printf("\n");
- }
- sdp->blks_total += ri->ri_data;
- sdp->rgrps++;
+ rg = lgfs2_rgrp_append(rgs, rgaddr, len, next);
+ if (rg == NULL) {
+ if (errno == ENOSPC)
+ return 1;
+ perror(_("Failed to create resource group"));
+ return -1;
+ }
+ err = lgfs2_rgrp_write(rgs, sdp->device_fd, rg);
+ if (err != 0) {
+ perror(_("Failed to write resource group"));
+ return -1;
+ }
+ ri = lgfs2_rgrp_index(rg);
+ if (sdp->debug) {
+ gfs2_rindex_print(ri);
+ printf("\n");
}
+ sdp->blks_total += ri->ri_data;
+ sdp->fssize = ri->ri_data0 + ri->ri_data;
+ sdp->rgrps++;
+ return 0;
+}
- if (ri == NULL)
- return 0;
- else
- return ri->ri_data0 + ri->ri_data;
+static int place_rgrps(struct gfs2_sbd *sdp, lgfs2_rgrps_t rgs, struct mkfs_opts *opts)
+{
+ 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);
+ uint32_t rgsize = lgfs2_rgrps_plan(rgs, sdp->device.length - rgaddr, ((opts->rgsize << 20) / sdp->bsize));
+ unsigned j;
+
+ if (rgsize >= jrgsize)
+ jrgsize = rgsize;
+
+ if (rgsize < ((GFS2_MIN_RGSIZE << 20) / sdp->bsize)) {
+ fprintf(stderr, _("Resource group size is too small\n"));
+ return -1;
+ } else if (rgsize < ((GFS2_DEFAULT_RGSIZE << 20) / sdp->bsize)) {
+ fprintf(stderr, _("Warning: small resource group size could impact performance\n"));
+ }
+
+ for (j = 0; j < opts->journals; j++) {
+ int result = place_rgrp(sdp, rgs, rgaddr, jrgsize, NULL);
+ 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)
+ break; /* Done */
+ }
+ return 0;
}
static void sbd_init(struct gfs2_sbd *sdp, struct mkfs_opts *opts, unsigned bsize)
@@ -668,6 +703,7 @@ static void sbd_init(struct gfs2_sbd *sdp, struct mkfs_opts *opts, unsigned bsiz
sdp->md.journals = opts->journals;
sdp->device_fd = opts->dev.fd;
sdp->bsize = bsize;
+ sdp->debug = opts->debug;
if (compute_constants(sdp)) {
perror(_("Failed to compute file system constants"));
@@ -812,8 +848,8 @@ void main_mkfs(int argc, char *argv[])
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);
- if (sbd.fssize == 0) {
+ error = place_rgrps(&sbd, rgs, &opts);
+ if (error) {
fprintf(stderr, _("Failed to build resource groups\n"));
exit(1);
}
--
1.8.5.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [Cluster-devel] [PATCH 5/5] libgfs2: Don't call gfs2_blk2rgrpd in gfs2_set_bitmap
2014-03-20 14:46 [Cluster-devel] [PATCH 1/5] mkfs.gfs2: Make dev a member of mkfs_opts Andrew Price
` (2 preceding siblings ...)
2014-03-20 14:46 ` [Cluster-devel] [PATCH 4/5] mkfs.gfs2: Fix the resource group layout strategy, again Andrew Price
@ 2014-03-20 14:46 ` Andrew Price
3 siblings, 0 replies; 5+ messages in thread
From: Andrew Price @ 2014-03-20 14:46 UTC (permalink / raw)
To: cluster-devel.redhat.com
gfs2_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.
Signed-off-by: Andrew Price <anprice@redhat.com>
---
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(-)
diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c
index bc3ca35..53a816d 100644
--- a/gfs2/edit/hexedit.c
+++ b/gfs2/edit/hexedit.c
@@ -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);
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 15cba56..594fbfa 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -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. */
diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c
index 92861a1..49ab682 100644
--- a/gfs2/fsck/pass5.c
+++ b/gfs2/fsck/pass5.c
@@ -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"));
diff --git a/gfs2/libgfs2/fs_bits.c b/gfs2/libgfs2/fs_bits.c
index e4b5505..7194949 100644
--- a/gfs2/libgfs2/fs_bits.c
+++ b/gfs2/libgfs2/fs_bits.c
@@ -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;
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index b95f2ed..fdd4438 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -141,7 +141,7 @@ static int blk_alloc_in_rg(struct gfs2_sbd *sdp, unsigned state, struct rgrp_tre
if (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
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 24947c2..b2f6bc3 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -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,
--
1.8.5.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2014-03-20 14:46 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-03-20 14:46 [Cluster-devel] [PATCH 1/5] mkfs.gfs2: Make dev a member of mkfs_opts Andrew Price
2014-03-20 14:46 ` [Cluster-devel] [PATCH 2/5] libgfs2: Add lgfs2_space_for_data() Andrew Price
2014-03-20 14:46 ` [Cluster-devel] [PATCH 3/5] libgfs2: Don't try to read more than IOV_MAX iovecs Andrew Price
2014-03-20 14:46 ` [Cluster-devel] [PATCH 4/5] mkfs.gfs2: Fix the resource group layout strategy, again Andrew Price
2014-03-20 14:46 ` [Cluster-devel] [PATCH 5/5] libgfs2: Don't call gfs2_blk2rgrpd in gfs2_set_bitmap Andrew Price
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.