gfs2-utils: master - fsck: Clean up pass1 inode iteration code
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=761a035c...
Commit: 761a035c6ec0ad2b33676da63c2799b10f276a2f
Parent: a4aceaded44d1f00597ad3b2d6a86f8e7adde2a2
Author: Steven Whitehouse <swhiteho(a)redhat.com>
AuthorDate: Fri Feb 22 12:08:03 2013 +0000
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Fri Feb 22 12:54:21 2013 +0000
fsck: Clean up pass1 inode iteration code
The original version of this patch, including readahead for the
inodes only appears to deliver a performance improvement in some
particular cases, and slows down other cases. So this patch is
fairly similar in that it includes the clean ups from the previous
attempt, however the readahead has been left out for the time
being until the problem is better understood, and can be fixed.
This clean up still has the advantage of better code structure
around the main loop, and in addition it also reduced the number
of read requests which are generated too.
Signed-off-by: Steven Whitehouse <swhiteho(a)redhat.com>
---
gfs2/fsck/pass1.c | 238 ++++++++++++++++++++++++---------------------
gfs2/libgfs2/libgfs2.h | 4 +-
gfs2/libgfs2/structures.c | 23 ++++-
3 files changed, 147 insertions(+), 118 deletions(-)
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 540f2a9..9a34e97 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -14,6 +14,7 @@
#include <unistd.h>
#include <string.h>
#include <time.h>
+#include <fcntl.h>
#include <sys/ioctl.h>
#include <inttypes.h>
#include <libintl.h>
@@ -1547,6 +1548,128 @@ static int check_system_inodes(struct gfs2_sbd *sdp)
return 0;
}
+static int pass1_process_bitmap(struct gfs2_sbd *sdp, struct rgrp_tree *rgd, uint64_t *ibuf, unsigned n)
+{
+ struct gfs2_buffer_head *bh;
+ unsigned i;
+ uint64_t block;
+
+ for (i = 0; i < n; i++) {
+ block = ibuf[i];
+
+ /* skip gfs1 rindex indirect blocks */
+ if (sdp->gfs1 && blockfind(&gfs1_rindex_blks, block)) {
+ log_debug(_("Skipping rindex indir block "
+ "%lld (0x%llx)\n"),
+ (unsigned long long)block,
+ (unsigned long long)block);
+ continue;
+ }
+ warm_fuzzy_stuff(block);
+
+ if (fsck_abort) { /* if asked to abort */
+ gfs2_special_free(&gfs1_rindex_blks);
+ return FSCK_OK;
+ }
+ if (skip_this_pass) {
+ printf( _("Skipping pass 1 is not a good idea.\n"));
+ skip_this_pass = FALSE;
+ fflush(stdout);
+ }
+ if (fsck_system_inode(sdp, block)) {
+ log_debug(_("Already processed system inode "
+ "%lld (0x%llx)\n"),
+ (unsigned long long)block,
+ (unsigned long long)block);
+ continue;
+ }
+ bh = bread(sdp, block);
+
+ if (gfs2_check_meta(bh, GFS2_METATYPE_DI)) {
+ /* In gfs2, a bitmap mark of 2 means an inode,
+ but in gfs1 it means any metadata. So if
+ this is gfs1 and not an inode, it may be
+ okay. If it's non-dinode metadata, it will
+ be referenced by an inode, so we need to
+ skip it here and it will be sorted out
+ when the referencing inode is checked. */
+ if (sdp->gfs1) {
+ uint32_t check_magic;
+
+ check_magic = ((struct gfs2_meta_header *)
+ (bh->b_data))->mh_magic;
+ if (be32_to_cpu(check_magic) == GFS2_MAGIC) {
+ log_debug( _("Deferring GFS1 "
+ "metadata block #"
+ "%" PRIu64" (0x%"
+ PRIx64 ")\n"),
+ block, block);
+ brelse(bh);
+ continue;
+ }
+ }
+ log_err( _("Found invalid inode at block #"
+ "%llu (0x%llx)\n"),
+ (unsigned long long)block,
+ (unsigned long long)block);
+ if (gfs2_blockmap_set(bl, block, gfs2_block_free)) {
+ stack;
+ brelse(bh);
+ gfs2_special_free(&gfs1_rindex_blks);
+ return FSCK_ERROR;
+ }
+ check_n_fix_bitmap(sdp, block, gfs2_block_free);
+ } else if (handle_di(sdp, bh) < 0) {
+ stack;
+ brelse(bh);
+ gfs2_special_free(&gfs1_rindex_blks);
+ return FSCK_ERROR;
+ }
+ /* Ignore everything else - they should be hit by the
+ handle_di step. Don't check NONE either, because
+ check_meta passes everything if GFS2_METATYPE_NONE
+ is specified. Hopefully, other metadata types such
+ as indirect blocks will be handled when the inode
+ itself is processed, and if it's not, it should be
+ caught in pass5. */
+ brelse(bh);
+ }
+
+ return 0;
+}
+
+static int pass1_process_rgrp(struct gfs2_sbd *sdp, struct rgrp_tree *rgd)
+{
+ unsigned k, n, i;
+ uint64_t *ibuf = malloc(sdp->bsize * GFS2_NBBY * sizeof(uint64_t));
+ int ret;
+
+ for (k = 0; k < rgd->ri.ri_length; k++) {
+ n = lgfs2_bm_scan(rgd, k, ibuf, GFS2_BLKST_DINODE);
+
+ if (n) {
+ ret = pass1_process_bitmap(sdp, rgd, ibuf, n);
+ if (ret)
+ return ret;
+ }
+
+ /*
+ For GFS1, we have to count the "free meta" blocks in the
+ resource group and mark them specially so we can count them
+ properly in pass5.
+ */
+ if (!sdp->gfs1)
+ continue;
+
+ n = lgfs2_bm_scan(rgd, k, ibuf, GFS2_BLKST_UNLINKED);
+ for (i = 0; i < n; i++)
+ gfs2_blockmap_set(bl, ibuf[i], gfs2_freemeta);
+ }
+
+ free(ibuf);
+ return 0;
+}
+
/**
* pass1 - walk through inodes and check inode state
*
@@ -1563,12 +1686,10 @@ static int check_system_inodes(struct gfs2_sbd *sdp)
int pass1(struct gfs2_sbd *sdp)
{
struct osi_node *n, *next = NULL;
- struct gfs2_buffer_head *bh;
- uint64_t block = 0;
struct rgrp_tree *rgd;
- int first;
uint64_t i;
uint64_t rg_count = 0;
+ int ret;
osi_list_init(&gfs1_rindex_blks.list);
@@ -1611,115 +1732,10 @@ int pass1(struct gfs2_sbd *sdp)
gfs2_meta_rgrp);*/
}
- first = 1;
+ ret = pass1_process_rgrp(sdp, rgd);
+ if (ret)
+ return ret;
- while (1) {
- /* "block" is relative to the entire file system */
- /* Get the next dinode in the file system, according
- to the bitmap. This should ONLY be dinodes unless
- it's GFS1, in which case it can be any metadata. */
- if (gfs2_next_rg_meta(rgd, &block, first))
- break;
- /* skip gfs1 rindex indirect blocks */
- if (sdp->gfs1 && blockfind(&gfs1_rindex_blks, block)) {
- log_debug(_("Skipping rindex indir block "
- "%lld (0x%llx)\n"),
- (unsigned long long)block,
- (unsigned long long)block);
- first = 0;
- continue;
- }
- warm_fuzzy_stuff(block);
-
- if (fsck_abort) { /* if asked to abort */
- gfs2_special_free(&gfs1_rindex_blks);
- return FSCK_OK;
- }
- if (skip_this_pass) {
- printf( _("Skipping pass 1 is not a good idea.\n"));
- skip_this_pass = FALSE;
- fflush(stdout);
- }
- if (fsck_system_inode(sdp, block)) {
- log_debug(_("Already processed system inode "
- "%lld (0x%llx)\n"),
- (unsigned long long)block,
- (unsigned long long)block);
- first = 0;
- continue;
- }
- bh = bread(sdp, block);
-
- /*log_debug( _("Checking metadata block #%" PRIu64
- " (0x%" PRIx64 ")\n"), block, block);*/
-
- if (gfs2_check_meta(bh, GFS2_METATYPE_DI)) {
- /* In gfs2, a bitmap mark of 2 means an inode,
- but in gfs1 it means any metadata. So if
- this is gfs1 and not an inode, it may be
- okay. If it's non-dinode metadata, it will
- be referenced by an inode, so we need to
- skip it here and it will be sorted out
- when the referencing inode is checked. */
- if (sdp->gfs1) {
- uint32_t check_magic;
-
- check_magic = ((struct
- gfs2_meta_header *)
- (bh->b_data))->mh_magic;
- if (be32_to_cpu(check_magic) ==
- GFS2_MAGIC) {
- log_debug( _("Deferring GFS1 "
- "metadata block #"
- "%" PRIu64" (0x%"
- PRIx64 ")\n"),
- block, block);
- brelse(bh);
- first = 0;
- continue;
- }
- }
- log_err( _("Found invalid inode at block #"
- "%llu (0x%llx)\n"),
- (unsigned long long)block,
- (unsigned long long)block);
- if (gfs2_blockmap_set(bl, block,
- gfs2_block_free)) {
- stack;
- brelse(bh);
- gfs2_special_free(&gfs1_rindex_blks);
- return FSCK_ERROR;
- }
- check_n_fix_bitmap(sdp, block,
- gfs2_block_free);
- } else if (handle_di(sdp, bh) < 0) {
- stack;
- brelse(bh);
- gfs2_special_free(&gfs1_rindex_blks);
- return FSCK_ERROR;
- }
- /* Ignore everything else - they should be hit by the
- handle_di step. Don't check NONE either, because
- check_meta passes everything if GFS2_METATYPE_NONE
- is specified. Hopefully, other metadata types such
- as indirect blocks will be handled when the inode
- itself is processed, and if it's not, it should be
- caught in pass5. */
- brelse(bh);
- first = 0;
- }
- /*
- For GFS1, we have to count the "free meta" blocks in the
- resource group and mark them specially so we can count them
- properly in pass5.
- */
- if (!sdp->gfs1)
- continue;
- first = 1;
- while (gfs2_next_rg_freemeta(rgd, &block, first) == 0) {
- gfs2_blockmap_set(bl, block, gfs2_freemeta);
- first = 0;
- }
}
gfs2_special_free(&gfs1_rindex_blks);
return FSCK_OK;
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 46d4d67..db31a6c 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -757,12 +757,12 @@ extern int build_root(struct gfs2_sbd *sdp);
extern int do_init_inum(struct gfs2_sbd *sdp);
extern int do_init_statfs(struct gfs2_sbd *sdp);
extern int gfs2_check_meta(struct gfs2_buffer_head *bh, int type);
+extern unsigned lgfs2_bm_scan(struct rgrp_tree *rgd, unsigned idx,
+ uint64_t *buf, uint8_t state);
extern int gfs2_next_rg_meta(struct rgrp_tree *rgd, uint64_t *block,
int first);
extern int gfs2_next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_tree *rgd,
uint64_t *block, uint32_t type, int first);
-extern int gfs2_next_rg_freemeta(struct rgrp_tree *rgd, uint64_t *block,
- int first);
/* super.c */
extern int check_sb(struct gfs2_sb *sb);
diff --git a/gfs2/libgfs2/structures.c b/gfs2/libgfs2/structures.c
index 645c45a..f9231ca 100644
--- a/gfs2/libgfs2/structures.c
+++ b/gfs2/libgfs2/structures.c
@@ -495,6 +495,24 @@ int gfs2_check_meta(struct gfs2_buffer_head *bh, int type)
return 0;
}
+unsigned lgfs2_bm_scan(struct rgrp_tree *rgd, unsigned idx, uint64_t *buf, uint8_t state)
+{
+ struct gfs2_bitmap *bi = &rgd->bits[idx];
+ unsigned n = 0;
+ uint32_t blk = 0;
+
+ while(blk < (bi->bi_len * GFS2_NBBY)) {
+ blk = gfs2_bitfit((const unsigned char *)rgd->bh[idx]->b_data + bi->bi_offset,
+ bi->bi_len, blk, state);
+ if (blk == BFITNOENT)
+ break;
+ buf[n++] = blk + (bi->bi_start * GFS2_NBBY) + rgd->ri.ri_data0;
+ blk++;
+ }
+
+ return n;
+}
+
/**
* gfs2_next_rg_meta
* @rgd:
@@ -545,11 +563,6 @@ int gfs2_next_rg_meta(struct rgrp_tree *rgd, uint64_t *block, int first)
return __gfs2_next_rg_meta(rgd, block, first, GFS2_BLKST_DINODE);
}
-int gfs2_next_rg_freemeta(struct rgrp_tree *rgd, uint64_t *block, int first)
-{
- return __gfs2_next_rg_meta(rgd, block, first, GFS2_BLKST_UNLINKED);
-}
-
/**
* next_rg_metatype
* @rgd:
11 years, 2 months
cluster: RHEL59 - rgmanager: Update status after resource recovery
by Ryan McCabe
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=a1e906313b8...
Commit: a1e906313b85a6d0451feda7a6222cfd4386caf5
Parent: b0c42d287f7f749794a61796f016c2e56148d64b
Author: Ryan McCabe <rmccabe(a)redhat.com>
AuthorDate: Fri Nov 30 11:28:57 2012 -0500
Committer: Ryan McCabe <rmccabe(a)redhat.com>
CommitterDate: Tue Feb 19 11:37:59 2013 -0500
rgmanager: Update status after resource recovery
>From John Ruemker <jrummy(a)redhat.com>:
"When a service is configured with a recoverable resource, such as
nfsclient, a failure of that client correctly triggers the recover
function. However, even if recover is successful, rgmanager still stops
and recovers the service."
Resolves: rhbz#912625
Acked-by: Lon Hohberger <lhh(a)redhat.com>
Signed-off-by: Ryan McCabe <rmccabe(a)redhat.com>
---
rgmanager/src/daemons/restree.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/rgmanager/src/daemons/restree.c b/rgmanager/src/daemons/restree.c
index 367fbb3..ba80247 100644
--- a/rgmanager/src/daemons/restree.c
+++ b/rgmanager/src/daemons/restree.c
@@ -1353,8 +1353,10 @@ do_status(resource_node_t *node)
return x;
/* Strange/failed status. Try to recover inline. */
- if ((x = res_exec(node, RS_RECOVER, NULL, 0)) == 0)
+ if ((x = res_exec(node, RS_RECOVER, NULL, 0)) == 0) {
+ node->rn_last_status = x;
return 0;
+ }
return x;
}
11 years, 2 months
cluster: STABLE32 - fenced: Fix path to "two_node" in ccs
by Christine Caulfield
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=0cce9f812d2...
Commit: 0cce9f812d2238777797491104d520fdd825c3fa
Parent: 9c9a1d36ed64d269b98124bfff9f79f58994397c
Author: Christine Caulfield <ccaulfie(a)redhat.com>
AuthorDate: Tue Feb 19 15:19:59 2013 +0000
Committer: Christine Caulfield <ccaulfie(a)redhat.com>
CommitterDate: Tue Feb 19 15:19:59 2013 +0000
fenced: Fix path to "two_node" in ccs
The path in the previous two_node patch was incorrect, it should have been:
Thanks to John Ruemker for spotting this
Signed-off-by: Christine Caulfield <ccaulfie(a)redhat.com>
---
fence/fenced/config.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/fence/fenced/config.c b/fence/fenced/config.c
index 651ea8b..1b9a3e0 100644
--- a/fence/fenced/config.c
+++ b/fence/fenced/config.c
@@ -95,7 +95,7 @@ void read_ccs_int(const char *path, int *config_val)
#define OVERRIDE_PATH_PATH "/cluster/fence_daemon/@override_path"
#define OVERRIDE_TIME_PATH "/cluster/fence_daemon/@override_time"
#define METHOD_NAME_PATH "/cluster/clusternodes/clusternode[@name=\"%s\"]/fence/method[%d]/@name"
-#define TWO_NODE_PATH "/cluster/cman/two_node"
+#define TWO_NODE_PATH "/cluster/cman/@two_node"
static int count_methods(char *victim)
{
11 years, 2 months
cluster: RHEL510 - rgmanager: Update status after resource recovery
by Ryan McCabe
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=a2f0c013886...
Commit: a2f0c0138865d6df3741feb3d753969aa3495c77
Parent: e6c64dc7a0a6432151fc88c22796d76deed180b7
Author: Ryan McCabe <rmccabe(a)redhat.com>
AuthorDate: Fri Nov 30 11:28:57 2012 -0500
Committer: Ryan McCabe <rmccabe(a)redhat.com>
CommitterDate: Mon Feb 18 13:38:26 2013 -0500
rgmanager: Update status after resource recovery
>From John Ruemker <jrummy(a)redhat.com>:
"When a service is configured with a recoverable resource, such as
nfsclient, a failure of that client correctly triggers the recover
function. However, even if recover is successful, rgmanager still stops
and recovers the service."
Resolves: rhbz#879029
Acked-by: Lon Hohberger <lhh(a)redhat.com>
Signed-off-by: Ryan McCabe <rmccabe(a)redhat.com>
---
rgmanager/src/daemons/restree.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/rgmanager/src/daemons/restree.c b/rgmanager/src/daemons/restree.c
index 367fbb3..ba80247 100644
--- a/rgmanager/src/daemons/restree.c
+++ b/rgmanager/src/daemons/restree.c
@@ -1353,8 +1353,10 @@ do_status(resource_node_t *node)
return x;
/* Strange/failed status. Try to recover inline. */
- if ((x = res_exec(node, RS_RECOVER, NULL, 0)) == 0)
+ if ((x = res_exec(node, RS_RECOVER, NULL, 0)) == 0) {
+ node->rn_last_status = x;
return 0;
+ }
return x;
}
11 years, 2 months
cluster: RHEL510 - rgmanager: Fix dependent service handling during recovery
by Ryan McCabe
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=e6c64dc7a0a...
Commit: e6c64dc7a0a6432151fc88c22796d76deed180b7
Parent: 75c20f80a14595f912814bb78e66fc5702c82296
Author: Ryan McCabe <rmccabe(a)redhat.com>
AuthorDate: Fri May 4 15:59:15 2012 -0400
Committer: Ryan McCabe <rmccabe(a)redhat.com>
CommitterDate: Mon Feb 18 13:29:37 2013 -0500
rgmanager: Fix dependent service handling during recovery
Resolves: rhbz#909459
Signed-off-by: Ryan McCabe <rmccabe(a)redhat.com>
Acked-by: Lon Hohberger <lhh(a)redhat.com>
---
rgmanager/src/resources/default_event_script.sl | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/rgmanager/src/resources/default_event_script.sl b/rgmanager/src/resources/default_event_script.sl
index 62de2d2..d337f76 100644
--- a/rgmanager/src/resources/default_event_script.sl
+++ b/rgmanager/src/resources/default_event_script.sl
@@ -480,8 +480,6 @@ define default_service_event_handler()
}
()=move_or_start(service_name, nodes);
-
- return;
}
%
@@ -536,6 +534,10 @@ define default_service_event_handler()
}
}
+ if (service_state == "recovering") {
+ return;
+ }
+
%
% Try to restart exclusive service which might have been recently
% stopped in order to make room for other exclusive services.
11 years, 2 months
gfs2-utils: master - fsck: Speed up reading of dir leaf blocks
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=a4aceade...
Commit: a4aceaded44d1f00597ad3b2d6a86f8e7adde2a2
Parent: 361ba0c65f68fbd63d8f7cc6d97b68532e3cc8fd
Author: Steven Whitehouse <swhiteho(a)redhat.com>
AuthorDate: Mon Feb 18 17:06:58 2013 +0000
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Mon Feb 18 17:39:36 2013 +0000
fsck: Speed up reading of dir leaf blocks
This patch adds readahead for directory leaf blocks. It gives me a speed
up of only around one second on my test filesystem, however that only
has one directory with a reasonable number of files in it. So that is
actually pretty good going for that small a filesystem.
Due to the reading of the dir hash table in a single sweep, this reduces
the number of calls to read dir hash table blocks considerably.
The patch takes all the valid leaf block pointers, sorts them into disk
block order and then issues readahead requests for the blocks in order
that they are read in, in good time before they are needed.
Signed-off-by: Steven Whitehouse <swhiteho(a)redhat.com>
---
gfs2/fsck/metawalk.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 80 insertions(+), 6 deletions(-)
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index f19c0f7..d8193c5 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -9,6 +9,7 @@
#include <unistd.h>
#include <libintl.h>
#include <ctype.h>
+#include <fcntl.h>
#define _(String) gettext(String)
#include "libgfs2.h"
@@ -638,24 +639,87 @@ out_copy_old_leaf:
return 1;
}
+static uint64_t *get_dir_hash(struct gfs2_inode *ip)
+{
+ unsigned hsize = (1 << ip->i_di.di_depth) * sizeof(uint64_t);
+ int ret;
+ uint64_t *tbl = malloc(hsize);
+
+ if (tbl == NULL)
+ return NULL;
+
+ ret = gfs2_readi(ip, tbl, 0, hsize);
+ if (ret != hsize) {
+ free(tbl);
+ return NULL;
+ }
+
+ return tbl;
+}
+
+static int u64cmp(const void *p1, const void *p2)
+{
+ uint64_t a = *(uint64_t *)p1;
+ uint64_t b = *(uint64_t *)p2;
+
+ if (a > b)
+ return 1;
+ if (b < b)
+ return -1;
+
+ return 0;
+}
+
+static void dir_leaf_reada(struct gfs2_inode *ip, uint64_t *tbl, unsigned hsize)
+{
+ uint64_t *t = alloca(hsize * sizeof(uint64_t));
+ uint64_t leaf_no;
+ struct gfs2_sbd *sdp = ip->i_sbd;
+ unsigned n = 0;
+ unsigned i;
+
+ for (i = 0; i < hsize; i++) {
+ leaf_no = be64_to_cpu(tbl[i]);
+ if (valid_block(ip->i_sbd, leaf_no))
+ t[n++] = leaf_no * sdp->bsize;
+ }
+ qsort(t, n, sizeof(uint64_t), u64cmp);
+ for (i = 0; i < n; i++)
+ posix_fadvise(sdp->device_fd, t[i], sdp->bsize, POSIX_FADV_WILLNEED);
+}
+
/* Checks exhash directory entries */
static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
{
int error;
struct gfs2_leaf leaf, oldleaf;
+ unsigned hsize = (1 << ip->i_di.di_depth);
uint64_t leaf_no, old_leaf, bad_leaf = -1;
uint64_t first_ok_leaf;
struct gfs2_buffer_head *lbh;
int lindex;
struct gfs2_sbd *sdp = ip->i_sbd;
int ref_count = 0, old_was_dup;
+ uint64_t *tbl;
+
+ tbl = get_dir_hash(ip);
+ if (tbl == NULL) {
+ perror("get_dir_hash");
+ return -1;
+ }
+
+ /* Turn off system readahead */
+ posix_fadvise(sdp->device_fd, 0, 0, POSIX_FADV_RANDOM);
+
+ /* Readahead */
+ dir_leaf_reada(ip, tbl, hsize);
/* Find the first valid leaf pointer in range and use it as our "old"
leaf. That way, bad blocks at the beginning will be overwritten
with the first valid leaf. */
first_ok_leaf = leaf_no = -1;
- for (lindex = 0; lindex < (1 << ip->i_di.di_depth); lindex++) {
- gfs2_get_leaf_nr(ip, lindex, &leaf_no);
+ for (lindex = 0; lindex < hsize; lindex++) {
+ leaf_no = be64_to_cpu(tbl[lindex]);
if (valid_block(ip->i_sbd, leaf_no)) {
lbh = bread(sdp, leaf_no);
/* Make sure it's really a valid leaf block. */
@@ -672,19 +736,22 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
"blocks\n"),
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr);
+ free(tbl);
+ posix_fadvise(sdp->device_fd, 0, 0, POSIX_FADV_NORMAL);
return 1;
}
old_leaf = -1;
memset(&oldleaf, 0, sizeof(oldleaf));
old_was_dup = 0;
- for (lindex = 0; lindex < (1 << ip->i_di.di_depth); lindex++) {
+ for (lindex = 0; lindex < hsize; lindex++) {
if (fsck_abort)
break;
- gfs2_get_leaf_nr(ip, lindex, &leaf_no);
+ leaf_no = be64_to_cpu(tbl[lindex]);
/* GFS has multiple indirect pointers to the same leaf
* until those extra pointers are needed, so skip the dups */
if (leaf_no == bad_leaf) {
+ tbl[lindex] = cpu_to_be64(old_leaf);
gfs2_put_leaf_nr(ip, lindex, old_leaf);
ref_count++;
continue;
@@ -694,8 +761,11 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
}
do {
- if (fsck_abort)
+ if (fsck_abort) {
+ free(tbl);
+ posix_fadvise(sdp->device_fd, 0, 0, POSIX_FADV_NORMAL);
return 0;
+ }
/* If the old leaf was a duplicate referenced by a
previous dinode, we can't check the number of
pointers because the number of pointers may be for
@@ -706,8 +776,10 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
&ref_count,
&lindex,
&oldleaf);
- if (error)
+ if (error) {
+ free(tbl);
return error;
+ }
}
error = check_leaf(ip, lindex, pass, &ref_count,
&leaf_no, old_leaf, &bad_leaf,
@@ -722,6 +794,8 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
(unsigned long long)leaf_no);
} while (1); /* while we have chained leaf blocks */
} /* for every leaf block */
+ free(tbl);
+ posix_fadvise(sdp->device_fd, 0, 0, POSIX_FADV_NORMAL);
return 0;
}
11 years, 2 months
gfs2-utils: master - libgfs2: Add readahead for rgrp headers
by Andrew Price
Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=361ba0c6...
Commit: 361ba0c65f68fbd63d8f7cc6d97b68532e3cc8fd
Parent: e6100419b58041b85463a76283451ebce6041707
Author: Steven Whitehouse <swhiteho(a)redhat.com>
AuthorDate: Mon Feb 18 10:27:00 2013 +0000
Committer: Andrew Price <anprice(a)redhat.com>
CommitterDate: Mon Feb 18 12:13:39 2013 +0000
libgfs2: Add readahead for rgrp headers
This adds readahead to rgrp headers, greatly improving the speed with
which they can be read in during fsck. Also, the multiple reads which
were used before are replaced with a single read per resource group.
This is an example of the kinds of speed up which may well be possible
elsewhere in the code. I started with this example simply because it was
the easiest one to do.
An alternative implementation might O_DIRECT and aio, but I'm not sure
that there would be much benefit compared with this method. A further
thought would be to use drop behind in places where we know that we will
not be looking at the data again.
Taking timings for just the rgrp reading section of fsck, I see almost a
10x speed up for that section of code using this patch on a 500G
filesystem.
Signed-off-by: Steven Whitehouse <swhiteho(a)redhat.com>
---
gfs2/libgfs2/buf.c | 60 ++++++++++++++++++++++++++++++-----------------
gfs2/libgfs2/libgfs2.h | 2 +
gfs2/libgfs2/rgrp.c | 6 ++--
gfs2/libgfs2/super.c | 35 ++++++++++++++++++++++++++++
4 files changed, 78 insertions(+), 25 deletions(-)
diff --git a/gfs2/libgfs2/buf.c b/gfs2/libgfs2/buf.c
index 5bc1a4e..68f0731 100644
--- a/gfs2/libgfs2/buf.c
+++ b/gfs2/libgfs2/buf.c
@@ -7,6 +7,7 @@
#include <inttypes.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/time.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
@@ -30,39 +31,54 @@ struct gfs2_buffer_head *bget(struct gfs2_sbd *sdp, uint64_t num)
return bh;
}
-struct gfs2_buffer_head *__bread(struct gfs2_sbd *sdp, uint64_t num, int line,
- const char *caller)
+int __breadm(struct gfs2_sbd *sdp, struct gfs2_buffer_head **bhs, size_t n,
+ uint64_t block, int line, const char *caller)
{
- struct gfs2_buffer_head *bh = bget(sdp, num);
- if (bh == NULL)
- return bh;
- if (lseek(sdp->device_fd, num * sdp->bsize, SEEK_SET) !=
- num * sdp->bsize) {
- fprintf(stderr, "bad seek: %s from %s:%d: block "
- "%llu (0x%llx)\n", strerror(errno),
- caller, line, (unsigned long long)num,
- (unsigned long long)num);
- exit(-1);
+ struct iovec *iov = alloca(n * 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;
}
- if (readv(sdp->device_fd, &bh->iov, 1) < 0) {
+
+ 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)num,
- (unsigned long long)num);
+ "%llu (0x%llx)\n", strerror(errno),
+ caller, line, (unsigned long long)block,
+ (unsigned long long)block);
exit(-1);
}
- return bh;
+
+ return 0;
+}
+
+struct gfs2_buffer_head *__bread(struct gfs2_sbd *sdp, uint64_t num, int line,
+ const char *caller)
+{
+ struct gfs2_buffer_head *bh;
+ int ret;
+
+ ret = __breadm(sdp, &bh, 1, num, line, caller);
+ if (ret >= 0)
+ return bh;
+ return NULL;
}
int bwrite(struct gfs2_buffer_head *bh)
{
struct gfs2_sbd *sdp = bh->sdp;
- if (lseek(sdp->device_fd, bh->b_blocknr * sdp->bsize, SEEK_SET) !=
- bh->b_blocknr * sdp->bsize) {
- return -1;
- }
- if (writev(sdp->device_fd, &bh->iov, 1) != bh->iov.iov_len)
+ if (pwritev(sdp->device_fd, &bh->iov, 1, bh->b_blocknr * sdp->bsize) != bh->iov.iov_len)
return -1;
sdp->writes++;
bh->b_modified = 0;
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 2b109fb..46d4d67 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -382,6 +382,7 @@ extern void gfs2_special_clear(struct special_blocks *blocklist,
extern struct gfs2_buffer_head *bget(struct gfs2_sbd *sdp, uint64_t num);
extern struct gfs2_buffer_head *__bread(struct gfs2_sbd *sdp, uint64_t num,
int line, const char *caller);
+extern int __breadm(struct gfs2_sbd *sdp, struct gfs2_buffer_head **bhs, size_t n, uint64_t block, int line, const char *caller);
extern int bwrite(struct gfs2_buffer_head *bh);
extern int brelse(struct gfs2_buffer_head *bh);
extern uint32_t lgfs2_get_block_type(const struct gfs2_buffer_head *lbh);
@@ -389,6 +390,7 @@ extern uint32_t lgfs2_get_block_type(const struct gfs2_buffer_head *lbh);
#define bmodified(bh) do { bh->b_modified = 1; } while(0)
#define bread(bl, num) __bread(bl, num, __LINE__, __FUNCTION__)
+#define breadm(bl, bhs, n, block) __breadm(bl, bhs, n, block, __LINE__, __FUNCTION__)
/* device_geometry.c */
extern int lgfs2_get_dev_info(int fd, struct lgfs2_dev_info *i);
diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c
index cbab2a3..f7dc01e 100644
--- a/gfs2/libgfs2/rgrp.c
+++ b/gfs2/libgfs2/rgrp.c
@@ -127,10 +127,10 @@ uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_tree *rgd)
return -1;
if (gfs2_check_range(sdp, rgd->ri.ri_addr))
return -1;
+ if (breadm(sdp, rgd->bh, length, rgd->ri.ri_addr))
+ return -1;
for (x = 0; x < length; x++){
- rgd->bh[x] = bread(sdp, rgd->ri.ri_addr + x);
- if(gfs2_check_meta(rgd->bh[x],
- (x) ? GFS2_METATYPE_RB : GFS2_METATYPE_RG))
+ if(gfs2_check_meta(rgd->bh[x], (x) ? GFS2_METATYPE_RB : GFS2_METATYPE_RG))
{
uint64_t error;
diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c
index 8317862..21c9f7b 100644
--- a/gfs2/libgfs2/super.c
+++ b/gfs2/libgfs2/super.c
@@ -7,6 +7,7 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
+#include <fcntl.h>
#include "libgfs2.h"
#include "osi_list.h"
@@ -198,6 +199,29 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *sane)
return 0;
}
+#define RA_WINDOW 32
+
+static unsigned gfs2_rgrp_reada(struct gfs2_sbd *sdp, unsigned cur_window,
+ struct osi_node *n)
+{
+ struct rgrp_tree *rgd;
+ unsigned i;
+ off_t start, len;
+
+ for (i = 0; i < RA_WINDOW; i++, n = osi_next(n)) {
+ if (n == NULL)
+ return i;
+ if (i < cur_window)
+ continue;
+ rgd = (struct rgrp_tree *)n;
+ start = rgd->ri.ri_addr * sdp->bsize;
+ len = rgd->ri.ri_length * sdp->bsize;
+ posix_fadvise(sdp->device_fd, start, len, POSIX_FADV_WILLNEED);
+ }
+
+ return i;
+}
+
/**
* ri_update - attach rgrps to the super block
* @sdp: incore superblock data
@@ -218,15 +242,24 @@ static int __ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int *sane,
uint64_t errblock = 0;
uint64_t rmax = 0;
struct osi_node *n, *next = NULL;
+ unsigned ra_window = 0;
+
+ /* Turn off generic readhead */
+ posix_fadvise(sdp->device_fd, 0, 0, POSIX_FADV_RANDOM);
if (rindex_read(sdp, fd, &count1, sane))
goto fail;
for (n = osi_first(&sdp->rgtree); n; n = next) {
next = osi_next(n);
rgd = (struct rgrp_tree *)n;
+ /* Readahead resource group headers */
+ if (ra_window < RA_WINDOW/2)
+ ra_window = gfs2_rgrp_reada(sdp, ra_window, n);
+ /* Read resource group header */
errblock = gfs2_rgrp_read(sdp, rgd);
if (errblock)
return errblock;
+ ra_window--;
count2++;
if (!quiet && count2 % 100 == 0) {
printf(".");
@@ -242,9 +275,11 @@ static int __ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int *sane,
if (count1 != count2)
goto fail;
+ posix_fadvise(sdp->device_fd, 0, 0, POSIX_FADV_NORMAL);
return 0;
fail:
+ posix_fadvise(sdp->device_fd, 0, 0, POSIX_FADV_NORMAL);
gfs2_rgrp_free(&sdp->rgtree);
return -1;
}
11 years, 2 months
fence-agents: master - fencing: All command prompt defaults should be list
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=e9e83a...
Commit: e9e83a7f037709e598b0660ff74e3d096882a5b9
Parent: 8ebd978406b6a9adec0904d2a7d7b56c63da628f
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: Mon Feb 18 12:33:55 2013 +0100
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Mon Feb 18 12:33:55 2013 +0100
fencing: All command prompt defaults should be list
options["cmd_prompt"]["default"] have to be list, so we can use this option consistently in fencing library
---
fence/agents/bladecenter/fence_bladecenter.py | 2 +-
fence/agents/drac/fence_drac.py | 4 ++--
fence/agents/hds_cb/fence_hds_cb.py | 2 +-
fence/agents/hpblade/fence_hpblade.py | 2 +-
fence/agents/rsb/fence_rsb.py | 2 +-
5 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/fence/agents/bladecenter/fence_bladecenter.py b/fence/agents/bladecenter/fence_bladecenter.py
index ffd3f35..43c5076 100644
--- a/fence/agents/bladecenter/fence_bladecenter.py
+++ b/fence/agents/bladecenter/fence_bladecenter.py
@@ -84,7 +84,7 @@ def main():
atexit.register(atexit_handler)
all_opt["power_wait"]["default"] = "10"
- all_opt["cmd_prompt"]["default"] = "system>"
+ all_opt["cmd_prompt"]["default"] = [ "system>" ]
options = check_input(device_opt, process_input(device_opt))
diff --git a/fence/agents/drac/fence_drac.py b/fence/agents/drac/fence_drac.py
index e081001..c690b21 100644
--- a/fence/agents/drac/fence_drac.py
+++ b/fence/agents/drac/fence_drac.py
@@ -32,9 +32,9 @@ def main():
opt = process_input(device_opt)
if "--username" in opt:
- all_opt["cmd_prompt"]["default"] = "\\[" + opt["--username"] + "\\]# "
+ all_opt["cmd_prompt"]["default"] = [ "\\[" + opt["--username"] + "\\]# " ]
else:
- all_opt["cmd_prompt"]["default"] = "\\[" "username" + "\\]# "
+ all_opt["cmd_prompt"]["default"] = [ "\\[" "username" + "\\]# " ]
options = check_input(device_opt, opt)
diff --git a/fence/agents/hds_cb/fence_hds_cb.py b/fence/agents/hds_cb/fence_hds_cb.py
index ed7d678..0e15af3 100755
--- a/fence/agents/hds_cb/fence_hds_cb.py
+++ b/fence/agents/hds_cb/fence_hds_cb.py
@@ -113,7 +113,7 @@ def main():
atexit.register(atexit_handler)
all_opt["power_wait"]["default"] = "5"
- all_opt["cmd_prompt"]["default"] = "\) :"
+ all_opt["cmd_prompt"]["default"] = [ "\) :" ]
options = check_input(device_opt, process_input(device_opt))
diff --git a/fence/agents/hpblade/fence_hpblade.py b/fence/agents/hpblade/fence_hpblade.py
index 7d08e6a..42f5309 100644
--- a/fence/agents/hpblade/fence_hpblade.py
+++ b/fence/agents/hpblade/fence_hpblade.py
@@ -61,7 +61,7 @@ def main():
atexit.register(atexit_handler)
- all_opt["cmd_prompt"]["default"] = "c7000oa>"
+ all_opt["cmd_prompt"]["default"] = [ "c7000oa>" ]
options = check_input(device_opt, process_input(device_opt))
diff --git a/fence/agents/rsb/fence_rsb.py b/fence/agents/rsb/fence_rsb.py
index 5ce3087..1da186f 100755
--- a/fence/agents/rsb/fence_rsb.py
+++ b/fence/agents/rsb/fence_rsb.py
@@ -41,7 +41,7 @@ def main():
atexit.register(atexit_handler)
- all_opt["cmd_prompt"]["default"] = "to quit:"
+ all_opt["cmd_prompt"]["default"] = [ "to quit:" ]
opt = process_input(device_opt)
11 years, 2 months
fence-agents: master - fencing: Fix indentation in --help message
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=8ebd97...
Commit: 8ebd978406b6a9adec0904d2a7d7b56c63da628f
Parent: 0d4892a43337bacc8edb9276600464bd42b5bb18
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: Mon Feb 18 11:08:02 2013 +0100
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Mon Feb 18 11:08:02 2013 +0100
fencing: Fix indentation in --help message
---
fence/agents/lib/fencing.py.py | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py
index 35f5764..cb8af45 100644
--- a/fence/agents/lib/fencing.py.py
+++ b/fence/agents/lib/fencing.py.py
@@ -165,7 +165,7 @@ all_opt = {
"ssh_options" : {
"getopt" : "X:",
"longopt" : "ssh-options",
- "help" : "--ssh-options=[options] SSH options to use",
+ "help" : "--ssh-options=[options] SSH options to use",
"shortdesc" : "SSH options to use",
"required" : "0",
"order" : 1 },
11 years, 2 months
fence-agents: master - fencing: present default values for --ipport in --help
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=0d4892...
Commit: 0d4892a43337bacc8edb9276600464bd42b5bb18
Parent: d2b7fb001fc50a8e14da8f2b6b974a5b5ade50fc
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: Mon Feb 18 11:06:08 2013 +0100
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Mon Feb 18 11:06:08 2013 +0100
fencing: present default values for --ipport in --help
Resolves: rhbz#895717
---
fence/agents/lib/fencing.py.py | 35 +++++++++++++++++++++---
fence/agents/vmware_soap/fence_vmware_soap.py | 2 +-
2 files changed, 31 insertions(+), 6 deletions(-)
diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py
index 907d654..35f5764 100644
--- a/fence/agents/lib/fencing.py.py
+++ b/fence/agents/lib/fencing.py.py
@@ -601,11 +601,6 @@ def check_input(device_opt, opt):
else:
all_opt["login"]["required"] = "0"
- ## In special cases (show help, metadata or version) we don't need to check anything
- #####
- if options.has_key("--help") or options.has_key("--version") or (options.has_key("--action") and options["--action"].lower() == "metadata"):
- return options
-
## Set default values
#####
for opt in device_opt:
@@ -614,6 +609,36 @@ def check_input(device_opt, opt):
if 0 == options.has_key(getopt_long):
options[getopt_long] = all_opt[opt]["default"]
+ if device_opt.count("ipport"):
+ if options.has_key("--ipport"):
+ all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use (default "+ options["--ipport"] +")"
+ elif options.has_key("--ssh"):
+ all_opt["ipport"]["default"] = 22
+ all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use (default 22)"
+ elif options.has_key("--ssl"):
+ all_opt["ipport"]["default"] = 443
+ all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use (default 443)"
+ elif device_opt.count("web"):
+ all_opt["ipport"]["default"] = 80
+ if device_opt.count("ssl") == 0:
+ all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use (default 80)"
+ else:
+ all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use\n\
+ (default 80, 443 if --ssl option is used)"
+ else:
+ all_opt["ipport"]["default"] = 23
+ if device_opt.count("secure") == 0:
+ all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use (default 23)"
+ else:
+ all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use\n\
+ (default 23, 22 if --ssh option is used)"
+
+
+ ## In special cases (show help, metadata or version) we don't need to check anything
+ #####
+ if options.has_key("--help") or options.has_key("--version") or (options.has_key("--action") and options["--action"].lower() == "metadata"):
+ return options
+
options["--action"] = options["--action"].lower()
if options.has_key("--verbose"):
diff --git a/fence/agents/vmware_soap/fence_vmware_soap.py b/fence/agents/vmware_soap/fence_vmware_soap.py
index aeafa26..365f8cc 100644
--- a/fence/agents/vmware_soap/fence_vmware_soap.py
+++ b/fence/agents/vmware_soap/fence_vmware_soap.py
@@ -156,7 +156,7 @@ def set_power_status(conn, options):
conn.service.PowerOffVM_Task(mo_machine)
def main():
- device_opt = [ "ipaddr", "login", "passwd", "ssl", "port" ]
+ device_opt = [ "ipaddr", "login", "passwd", "web", "ssl", "port" ]
atexit.register(atexit_handler)
11 years, 2 months