cluster: RHEL6 - fsck.gfs2: shorten some debug messages in lost+found
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=89e2e4a2f24...
Commit: 89e2e4a2f24f54c14cf7b241daea375324a0a5eb
Parent: 872b99e0a2569404c49f4483260b5a1b8023d372
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Wed Mar 6 10:29:38 2013 -0700
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri May 17 14:56:50 2013 -0500
fsck.gfs2: shorten some debug messages in lost+found
This patch changes the debug output of lost+found such that it
only prints the block number in hexadecimal. This shortens the output
and makes debug output easier to read.
rhbz#902920
---
gfs2/fsck/lost_n_found.c | 12 ++++--------
1 files changed, 4 insertions(+), 8 deletions(-)
diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c
index 42d97ee..388787d 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -32,11 +32,9 @@ static void add_dotdot(struct gfs2_inode *ip)
if (di && valid_block(sdp, di->dotdot_parent.no_addr)) {
struct gfs2_inode *dip;
- log_debug(_("Directory %lld (0x%llx) already had a "
- "\"..\" link to %lld (0x%llx).\n"),
+ log_debug(_("Directory (0x%llx) already had a "
+ "\"..\" link to (0x%llx).\n"),
(unsigned long long)ip->i_di.di_num.no_addr,
- (unsigned long long)ip->i_di.di_num.no_addr,
- (unsigned long long)di->dotdot_parent.no_addr,
(unsigned long long)di->dotdot_parent.no_addr);
dip = fsck_load_inode(sdp, di->dotdot_parent.no_addr);
if (dip->i_di.di_num.no_formal_ino ==
@@ -74,15 +72,13 @@ static void add_dotdot(struct gfs2_inode *ip)
} else {
if (di)
log_debug(_("Couldn't find a valid \"..\" entry "
- "for orphan directory %lld (0x%llx): "
+ "for orphan directory (0x%llx): "
"'..' = 0x%llx\n"),
(unsigned long long)ip->i_di.di_num.no_addr,
- (unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)di->dotdot_parent.no_addr);
else
- log_debug(_("Couldn't find directory %lld (0x%llx) "
+ log_debug(_("Couldn't find directory (0x%llx) "
"in directory tree.\n"),
- (unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)ip->i_di.di_num.no_addr);
}
if (gfs2_dirent_del(ip, "..", 2))
11 years
cluster: RHEL6 - fsck.gfs2: Check for formal inode mismatch when adding to lost+found
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=872b99e0a25...
Commit: 872b99e0a2569404c49f4483260b5a1b8023d372
Parent: 1325bb4d27bffbcaa5c2170bb1300d8e2c3a9807
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Wed Mar 6 10:28:20 2013 -0700
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri May 17 14:56:44 2013 -0500
fsck.gfs2: Check for formal inode mismatch when adding to lost+found
This patch adds a check to the code that adds inodes to lost+found
so that dinodes with formal inode mismatches are logged, but not added.
rhbz#902920
---
gfs2/fsck/lost_n_found.c | 44 ++++++++++++++++++++++++++++----------------
1 files changed, 28 insertions(+), 16 deletions(-)
diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c
index 751cbd8..42d97ee 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -38,24 +38,36 @@ static void add_dotdot(struct gfs2_inode *ip)
(unsigned long long)ip->i_di.di_num.no_addr,
(unsigned long long)di->dotdot_parent.no_addr,
(unsigned long long)di->dotdot_parent.no_addr);
- decr_link_count(di->dotdot_parent.no_addr,
- ip->i_di.di_num.no_addr,
- _(".. unlinked, moving to lost+found"));
dip = fsck_load_inode(sdp, di->dotdot_parent.no_addr);
- if (dip->i_di.di_nlink > 0) {
- dip->i_di.di_nlink--;
- set_di_nlink(dip); /* keep inode tree in sync */
- log_debug(_("Decrementing its links to %d\n"),
- dip->i_di.di_nlink);
- bmodified(dip->i_bh);
- } else if (!dip->i_di.di_nlink) {
- log_debug(_("Its link count is zero.\n"));
+ if (dip->i_di.di_num.no_formal_ino ==
+ di->dotdot_parent.no_formal_ino) {
+ decr_link_count(di->dotdot_parent.no_addr,
+ ip->i_di.di_num.no_addr,
+ _(".. unlinked, moving to lost+found"));
+ if (dip->i_di.di_nlink > 0) {
+ dip->i_di.di_nlink--;
+ set_di_nlink(dip); /* keep inode tree in sync */
+ log_debug(_("Decrementing its links to %d\n"),
+ dip->i_di.di_nlink);
+ bmodified(dip->i_bh);
+ } else if (!dip->i_di.di_nlink) {
+ log_debug(_("Its link count is zero.\n"));
+ } else {
+ log_debug(_("Its link count is %d! Changing "
+ "it to 0.\n"), dip->i_di.di_nlink);
+ dip->i_di.di_nlink = 0;
+ set_di_nlink(dip); /* keep inode tree in sync */
+ bmodified(dip->i_bh);
+ }
} else {
- log_debug(_("Its link count is %d! Changing "
- "it to 0.\n"), dip->i_di.di_nlink);
- dip->i_di.di_nlink = 0;
- set_di_nlink(dip); /* keep inode tree in sync */
- bmodified(dip->i_bh);
+ log_debug(_("Directory (0x%llx)'s link to parent "
+ "(0x%llx) had a formal inode discrepancy: "
+ "was 0x%llx, expected 0x%llx\n"),
+ (unsigned long long)ip->i_di.di_num.no_addr,
+ (unsigned long long)di->dotdot_parent.no_addr,
+ di->dotdot_parent.no_formal_ino,
+ dip->i_di.di_num.no_formal_ino);
+ log_debug(_("The parent directory was not changed.\n"));
}
fsck_inode_put(&dip);
di = NULL;
11 years
cluster: RHEL6 - fsck.gfs2: Split out function to make sure lost+found exists
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=1325bb4d27b...
Commit: 1325bb4d27bffbcaa5c2170bb1300d8e2c3a9807
Parent: 82558210e8ef16821170bb9787c0b46a1abf9bfd
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Mon Feb 25 10:18:55 2013 -0700
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri May 17 14:56:33 2013 -0500
fsck.gfs2: Split out function to make sure lost+found exists
This patch extracts a section of code from the lost+found functions
and makes a new make_sure_lf_exists function that can be called
from more places.
rhbz#902920
---
gfs2/fsck/lost_n_found.c | 129 +++++++++++++++++++++++-----------------------
gfs2/fsck/lost_n_found.h | 1 +
2 files changed, 66 insertions(+), 64 deletions(-)
diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c
index 282d673..751cbd8 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -86,6 +86,70 @@ static void add_dotdot(struct gfs2_inode *ip)
}
}
+void make_sure_lf_exists(struct gfs2_inode *ip)
+{
+ uint8_t q;
+ struct dir_info *di;
+ struct gfs2_sbd *sdp = ip->i_sbd;
+ uint32_t mode;
+
+ if (lf_dip)
+ return;
+
+ log_info( _("Locating/Creating lost+found directory\n"));
+
+ /* if this is gfs1, we have to trick createi into using
+ no_formal_ino = no_addr, so we set next_inum to the
+ free block we're about to allocate. */
+ if (sdp->gfs1)
+ sdp->md.next_inum = find_free_blk(sdp);
+ mode = (sdp->gfs1 ? DT2IF(GFS_FILE_DIR) : S_IFDIR) | 0700;
+ if (sdp->gfs1)
+ lf_dip = gfs_createi(sdp->md.rooti, "lost+found", mode, 0);
+ else
+ lf_dip = createi(sdp->md.rooti, "lost+found",
+ S_IFDIR | 0700, 0);
+ if (lf_dip == NULL) {
+ log_crit(_("Error creating lost+found: %s\n"),
+ strerror(errno));
+ exit(FSCK_ERROR);
+ }
+
+ /* createi will have incremented the di_nlink link count for the root
+ directory. We must set the nlink value in the hash table to keep
+ them in sync so that pass4 can detect and fix any descrepancies. */
+ set_di_nlink(sdp->md.rooti);
+
+ q = block_type(lf_dip->i_di.di_num.no_addr);
+ if (q != gfs2_inode_dir) {
+ /* This is a new lost+found directory, so set its block type
+ and increment link counts for the directories */
+ /* FIXME: i'd feel better about this if fs_mkdir returned
+ whether it created a new directory or just found an old one,
+ and we used that instead of the block_type to run this */
+ fsck_blockmap_set(ip, lf_dip->i_di.di_num.no_addr,
+ _("lost+found dinode"), gfs2_inode_dir);
+ dirtree_insert(lf_dip->i_di.di_num);
+ /* root inode links to lost+found */
+ incr_link_count(sdp->md.rooti->i_di.di_num, lf_dip, _("root"));
+ /* lost+found link for '.' from itself */
+ incr_link_count(lf_dip->i_di.di_num, lf_dip, "\".\"");
+ /* lost+found link for '..' back to root */
+ incr_link_count(lf_dip->i_di.di_num, sdp->md.rooti, "\"..\"");
+ if (sdp->gfs1)
+ lf_dip->i_di.__pad1 = GFS_FILE_DIR;
+ }
+ log_info( _("lost+found directory is dinode %lld (0x%llx)\n"),
+ (unsigned long long)lf_dip->i_di.di_num.no_addr,
+ (unsigned long long)lf_dip->i_di.di_num.no_addr);
+ di = dirtree_find(lf_dip->i_di.di_num.no_addr);
+ if (di) {
+ log_info( _("Marking lost+found inode connected\n"));
+ di->checked = 1;
+ di = NULL;
+ }
+}
+
/* add_inode_to_lf - Add dir entry to lost+found for the inode
* @ip: inode to add to lost + found
*
@@ -100,73 +164,10 @@ int add_inode_to_lf(struct gfs2_inode *ip){
__be32 inode_type;
uint64_t lf_blocks;
struct gfs2_sbd *sdp = ip->i_sbd;
- struct dir_info *di;
int err = 0;
uint32_t mode;
- if (!lf_dip) {
- uint8_t q;
-
- log_info( _("Locating/Creating lost+found directory\n"));
-
- /* if this is gfs1, we have to trick createi into using
- no_formal_ino = no_addr, so we set next_inum to the
- free block we're about to allocate. */
- if (sdp->gfs1)
- sdp->md.next_inum = find_free_blk(sdp);
- mode = (sdp->gfs1 ? DT2IF(GFS_FILE_DIR) : S_IFDIR) | 0700;
- if (sdp->gfs1)
- lf_dip = gfs_createi(sdp->md.rooti, "lost+found",
- mode, 0);
- else
- lf_dip = createi(sdp->md.rooti, "lost+found",
- S_IFDIR | 0700, 0);
- if (lf_dip == NULL) {
- log_crit(_("Error %d creating lost+found\n"), errno);
- exit(FSCK_ERROR);
- }
-
- /* createi will have incremented the di_nlink link count for
- the root directory. We must set the nlink value
- in the hash table to keep them in sync so that pass4 can
- detect and fix any descrepancies. */
- set_di_nlink(sdp->md.rooti);
-
- q = block_type(lf_dip->i_di.di_num.no_addr);
- if (q != gfs2_inode_dir) {
- /* This is a new lost+found directory, so set its
- * block type and increment link counts for
- * the directories */
- /* FIXME: i'd feel better about this if
- * fs_mkdir returned whether it created a new
- * directory or just found an old one, and we
- * used that instead of the block_type to run
- * this */
- fsck_blockmap_set(ip, lf_dip->i_di.di_num.no_addr,
- _("lost+found dinode"),
- gfs2_inode_dir);
- /* root inode links to lost+found */
- incr_link_count(sdp->md.rooti->i_di.di_num,
- lf_dip, _("root"));
- /* lost+found link for '.' from itself */
- incr_link_count(lf_dip->i_di.di_num,
- lf_dip, "\".\"");
- /* lost+found link for '..' back to root */
- incr_link_count(lf_dip->i_di.di_num, sdp->md.rooti,
- "\"..\"");
- if (sdp->gfs1)
- lf_dip->i_di.__pad1 = GFS_FILE_DIR;
- }
- log_info( _("lost+found directory is dinode %lld (0x%llx)\n"),
- (unsigned long long)lf_dip->i_di.di_num.no_addr,
- (unsigned long long)lf_dip->i_di.di_num.no_addr);
- di = dirtree_find(lf_dip->i_di.di_num.no_addr);
- if (di) {
- log_info( _("Marking lost+found inode connected\n"));
- di->checked = 1;
- di = NULL;
- }
- }
+ make_sure_lf_exists(ip);
if (ip->i_di.di_num.no_addr == lf_dip->i_di.di_num.no_addr) {
log_err( _("Trying to add lost+found to itself...skipping"));
return 0;
diff --git a/gfs2/fsck/lost_n_found.h b/gfs2/fsck/lost_n_found.h
index f28a1d9..2b76cc2 100644
--- a/gfs2/fsck/lost_n_found.h
+++ b/gfs2/fsck/lost_n_found.h
@@ -4,5 +4,6 @@
#include "libgfs2.h"
int add_inode_to_lf(struct gfs2_inode *ip);
+void make_sure_lf_exists(struct gfs2_inode *ip);
#endif /* __LOST_N_FOUND_H__ */
11 years
cluster: RHEL6 - fsck.gfs2: Move function find_free_blk to util.c
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=82558210e8e...
Commit: 82558210e8ef16821170bb9787c0b46a1abf9bfd
Parent: 43729045dbdf085af140885b6af582851bf521f1
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Thu Feb 21 09:43:22 2013 -0700
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri May 17 14:55:59 2013 -0500
fsck.gfs2: Move function find_free_blk to util.c
In a future patch to fsck, function find_free_blk will be called in
order to correctly report blocks that will need to be allocated for
things such as leaf splits. This patch moves function find_free_blk
to a more centralized place, util.c, to that end.
rhbz#902920
---
gfs2/fsck/lost_n_found.c | 39 ---------------------------------------
gfs2/fsck/util.c | 39 +++++++++++++++++++++++++++++++++++++++
gfs2/fsck/util.h | 1 +
3 files changed, 40 insertions(+), 39 deletions(-)
diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c
index 06ee485..282d673 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -86,45 +86,6 @@ static void add_dotdot(struct gfs2_inode *ip)
}
}
-static uint64_t find_free_blk(struct gfs2_sbd *sdp)
-{
- struct osi_node *n, *next = NULL;
- struct rgrp_tree *rl = NULL;
- struct gfs2_rindex *ri;
- struct gfs2_rgrp *rg;
- unsigned int block, bn = 0, x = 0, y = 0;
- unsigned int state;
- struct gfs2_buffer_head *bh;
-
- memset(&rg, 0, sizeof(rg));
- for (n = osi_first(&sdp->rgtree); n; n = next) {
- next = osi_next(n);
- rl = (struct rgrp_tree *)n;
- if (rl->rg.rg_free)
- break;
- }
-
- if (n == NULL)
- return 0;
-
- ri = &rl->ri;
- rg = &rl->rg;
-
- for (block = 0; block < ri->ri_length; block++) {
- bh = rl->bh[block];
- x = (block) ? sizeof(struct gfs2_meta_header) : sizeof(struct gfs2_rgrp);
-
- for (; x < sdp->bsize; x++)
- for (y = 0; y < GFS2_NBBY; y++) {
- state = (bh->b_data[x] >> (GFS2_BIT_SIZE * y)) & 0x03;
- if (state == GFS2_BLKST_FREE)
- return ri->ri_data0 + bn;
- bn++;
- }
- }
- return 0;
-}
-
/* add_inode_to_lf - Add dir entry to lost+found for the inode
* @ip: inode to add to lost + found
*
diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
index 24bae6f..5e14dd4 100644
--- a/gfs2/fsck/util.c
+++ b/gfs2/fsck/util.c
@@ -532,3 +532,42 @@ bad_dinode:
stack;
return -EPERM;
}
+
+uint64_t find_free_blk(struct gfs2_sbd *sdp)
+{
+ struct osi_node *n, *next = NULL;
+ struct rgrp_tree *rl = NULL;
+ struct gfs2_rindex *ri;
+ struct gfs2_rgrp *rg;
+ unsigned int block, bn = 0, x = 0, y = 0;
+ unsigned int state;
+ struct gfs2_buffer_head *bh;
+
+ memset(&rg, 0, sizeof(rg));
+ for (n = osi_first(&sdp->rgtree); n; n = next) {
+ next = osi_next(n);
+ rl = (struct rgrp_tree *)n;
+ if (rl->rg.rg_free)
+ break;
+ }
+
+ if (n == NULL)
+ return 0;
+
+ ri = &rl->ri;
+ rg = &rl->rg;
+
+ for (block = 0; block < ri->ri_length; block++) {
+ bh = rl->bh[block];
+ x = (block) ? sizeof(struct gfs2_meta_header) : sizeof(struct gfs2_rgrp);
+
+ for (; x < sdp->bsize; x++)
+ for (y = 0; y < GFS2_NBBY; y++) {
+ state = (bh->b_data[x] >> (GFS2_BIT_SIZE * y)) & 0x03;
+ if (state == GFS2_BLKST_FREE)
+ return ri->ri_data0 + bn;
+ bn++;
+ }
+ }
+ return 0;
+}
diff --git a/gfs2/fsck/util.h b/gfs2/fsck/util.h
index b56fe69..5ee38ad 100644
--- a/gfs2/fsck/util.h
+++ b/gfs2/fsck/util.h
@@ -180,4 +180,5 @@ extern void *gfs2_bmap_destroy(struct gfs2_sbd *sdp, struct gfs2_bmap *il);
extern int gfs2_blockmap_set(struct gfs2_bmap *il, uint64_t block,
enum gfs2_mark_block mark);
extern int set_ip_blockmap(struct gfs2_inode *ip, int instree);
+extern uint64_t find_free_blk(struct gfs2_sbd *sdp);
#endif /* __UTIL_H__ */
11 years
cluster: RHEL6 - libgfs2: let dir_split_leaf receive a "broken" lindex
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=43729045dbd...
Commit: 43729045dbdf085af140885b6af582851bf521f1
Parent: 3cb07500ec76da42ff56fbbb01eca50e5358c10e
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Thu Feb 21 09:36:01 2013 -0700
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri May 17 14:42:48 2013 -0500
libgfs2: let dir_split_leaf receive a "broken" lindex
For ordinary leaf blocks, the hash table must follow the rules,
which means it needs to follow a power-of-two boundary. In other
words, it needs to enforce that: start = (lindex & ~(len - 1));
But when doing repairs, fsck will need to detect when hash tables
violate this rule and fix it. In that case, it may need to pass
in an invalid starting offset for a leaf to split. This patch
moves the responsibility for checking the starting block to the
calling function.
rhbz#902920
---
gfs2/libgfs2/fs_ops.c | 13 +++++++------
gfs2/libgfs2/libgfs2.h | 2 +-
2 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index f88c48f..690d8dd 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -865,13 +865,13 @@ void gfs2_put_leaf_nr(struct gfs2_inode *dip, uint32_t inx, uint64_t leaf_out)
die("gfs2_put_leaf_nr: Bad internal write.\n");
}
-void dir_split_leaf(struct gfs2_inode *dip, uint32_t lindex, uint64_t leaf_no,
+void dir_split_leaf(struct gfs2_inode *dip, uint32_t start, uint64_t leaf_no,
struct gfs2_buffer_head *obh)
{
struct gfs2_buffer_head *nbh;
struct gfs2_leaf *nleaf, *oleaf;
struct gfs2_dirent *dent, *prev = NULL, *next = NULL, *new;
- uint32_t start, len, half_len, divider;
+ uint32_t len, half_len, divider;
uint64_t bn, *lp;
uint32_t name_len;
int x, moved = FALSE;
@@ -897,8 +897,6 @@ void dir_split_leaf(struct gfs2_inode *dip, uint32_t lindex, uint64_t leaf_no,
len = 1 << (dip->i_di.di_depth - be16_to_cpu(oleaf->lf_depth));
half_len = len >> 1;
- start = (lindex & ~(len - 1));
-
lp = calloc(1, half_len * sizeof(uint64_t));
if (lp == NULL) {
fprintf(stderr, "Out of memory in %s\n", __FUNCTION__);
@@ -1091,7 +1089,7 @@ static int dir_e_add(struct gfs2_inode *dip, const char *filename, int len,
struct gfs2_buffer_head *bh, *nbh;
struct gfs2_leaf *leaf, *nleaf;
struct gfs2_dirent *dent;
- uint32_t lindex;
+ uint32_t lindex, llen;
uint32_t hash;
uint64_t leaf_no, bn;
int err = 0;
@@ -1113,7 +1111,10 @@ restart:
if (dirent_alloc(dip, bh, len, &dent)) {
if (be16_to_cpu(leaf->lf_depth) < dip->i_di.di_depth) {
- dir_split_leaf(dip, lindex, leaf_no, bh);
+ llen = 1 << (dip->i_di.di_depth -
+ be16_to_cpu(leaf->lf_depth));
+ dir_split_leaf(dip, lindex & ~(llen - 1),
+ leaf_no, bh);
brelse(bh);
goto restart;
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 8354a14..d5de337 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -400,7 +400,7 @@ extern void block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
extern void gfs2_get_leaf_nr(struct gfs2_inode *dip, uint32_t index,
uint64_t *leaf_out);
extern void gfs2_put_leaf_nr(struct gfs2_inode *dip, uint32_t inx, uint64_t leaf_out);
-extern void dir_split_leaf(struct gfs2_inode *dip, uint32_t lindex,
+extern void dir_split_leaf(struct gfs2_inode *dip, uint32_t start,
uint64_t leaf_no, struct gfs2_buffer_head *obh);
extern void gfs2_free_block(struct gfs2_sbd *sdp, uint64_t block);
extern int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t block);
11 years
cluster: RHEL6 - libgfs2: allow dir_split_leaf to receive a leaf buffer
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=3cb07500ec7...
Commit: 3cb07500ec76da42ff56fbbb01eca50e5358c10e
Parent: 6f85923316e5b1504a231cd7c8bde5bb6a059506
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Thu Feb 21 09:33:24 2013 -0700
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri May 17 14:30:57 2013 -0500
libgfs2: allow dir_split_leaf to receive a leaf buffer
This is a small performance improvement. Rather than having function
dir_split_leaf read in the leaf to be split, this patch lets the
buffer_head to be passed in from the calling function, which has it
read in anyway.
rhbz#902920
---
gfs2/libgfs2/fs_ops.c | 9 ++++-----
gfs2/libgfs2/libgfs2.h | 2 +-
2 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index 5417efb..f88c48f 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -865,9 +865,10 @@ void gfs2_put_leaf_nr(struct gfs2_inode *dip, uint32_t inx, uint64_t leaf_out)
die("gfs2_put_leaf_nr: Bad internal write.\n");
}
-void dir_split_leaf(struct gfs2_inode *dip, uint32_t lindex, uint64_t leaf_no)
+void dir_split_leaf(struct gfs2_inode *dip, uint32_t lindex, uint64_t leaf_no,
+ struct gfs2_buffer_head *obh)
{
- struct gfs2_buffer_head *nbh, *obh;
+ struct gfs2_buffer_head *nbh;
struct gfs2_leaf *nleaf, *oleaf;
struct gfs2_dirent *dent, *prev = NULL, *next = NULL, *new;
uint32_t start, len, half_len, divider;
@@ -891,7 +892,6 @@ void dir_split_leaf(struct gfs2_inode *dip, uint32_t lindex, uint64_t leaf_no)
nleaf = (struct gfs2_leaf *)nbh->b_data;
nleaf->lf_dirent_format = cpu_to_be32(GFS2_FORMAT_DE);
- obh = bread(dip->i_sbd, leaf_no);
oleaf = (struct gfs2_leaf *)obh->b_data;
len = 1 << (dip->i_di.di_depth - be16_to_cpu(oleaf->lf_depth));
@@ -970,7 +970,6 @@ void dir_split_leaf(struct gfs2_inode *dip, uint32_t lindex, uint64_t leaf_no)
bmodified(dip->i_bh);
bmodified(obh); /* Need to do this in case nothing was moved */
- brelse(obh);
bmodified(nbh);
brelse(nbh);
}
@@ -1114,8 +1113,8 @@ restart:
if (dirent_alloc(dip, bh, len, &dent)) {
if (be16_to_cpu(leaf->lf_depth) < dip->i_di.di_depth) {
+ dir_split_leaf(dip, lindex, leaf_no, bh);
brelse(bh);
- dir_split_leaf(dip, lindex, leaf_no);
goto restart;
} else if (dip->i_di.di_depth < GFS2_DIR_MAX_DEPTH) {
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 9e3de8a..8354a14 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -401,7 +401,7 @@ extern void gfs2_get_leaf_nr(struct gfs2_inode *dip, uint32_t index,
uint64_t *leaf_out);
extern void gfs2_put_leaf_nr(struct gfs2_inode *dip, uint32_t inx, uint64_t leaf_out);
extern void dir_split_leaf(struct gfs2_inode *dip, uint32_t lindex,
- uint64_t leaf_no);
+ uint64_t leaf_no, struct gfs2_buffer_head *obh);
extern void gfs2_free_block(struct gfs2_sbd *sdp, uint64_t block);
extern int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t block);
extern int gfs2_get_leaf(struct gfs2_inode *dip, uint64_t leaf_no,
11 years
cluster: RHEL6 - libgfs2: externalize dir_split_leaf
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=6f85923316e...
Commit: 6f85923316e5b1504a231cd7c8bde5bb6a059506
Parent: c361fd8d3d7b1074107f0800fdae79820574b81d
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Thu Feb 21 09:29:24 2013 -0700
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri May 17 14:30:22 2013 -0500
libgfs2: externalize dir_split_leaf
This patch makes libgfs2 externalize function dir_split_leaf so that
fsck.gfs2 can split leafs in a future patch.
rhbz#902920
---
gfs2/libgfs2/fs_ops.c | 3 +--
gfs2/libgfs2/libgfs2.h | 2 ++
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index 1164a8c..5417efb 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -865,8 +865,7 @@ void gfs2_put_leaf_nr(struct gfs2_inode *dip, uint32_t inx, uint64_t leaf_out)
die("gfs2_put_leaf_nr: Bad internal write.\n");
}
-static void dir_split_leaf(struct gfs2_inode *dip, uint32_t lindex,
- uint64_t leaf_no)
+void dir_split_leaf(struct gfs2_inode *dip, uint32_t lindex, uint64_t leaf_no)
{
struct gfs2_buffer_head *nbh, *obh;
struct gfs2_leaf *nleaf, *oleaf;
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index bf834a5..9e3de8a 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -400,6 +400,8 @@ extern void block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
extern void gfs2_get_leaf_nr(struct gfs2_inode *dip, uint32_t index,
uint64_t *leaf_out);
extern void gfs2_put_leaf_nr(struct gfs2_inode *dip, uint32_t inx, uint64_t leaf_out);
+extern void dir_split_leaf(struct gfs2_inode *dip, uint32_t lindex,
+ uint64_t leaf_no);
extern void gfs2_free_block(struct gfs2_sbd *sdp, uint64_t block);
extern int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t block);
extern int gfs2_get_leaf(struct gfs2_inode *dip, uint64_t leaf_no,
11 years
cluster: RHEL6 - fsck: Speed up reading of dir leaf blocks
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=c361fd8d3d7...
Commit: c361fd8d3d7b1074107f0800fdae79820574b81d
Parent: 0cf2544edfa377c47b0e904ecdce00194590593e
Author: Steven Whitehouse <swhiteho(a)redhat.com>
AuthorDate: Mon Feb 18 17:06:58 2013 +0000
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri May 17 14:29:20 2013 -0500
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.
rhbz#902920
---
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 fb461ae..ce80738 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -7,6 +7,7 @@
#include <unistd.h>
#include <libintl.h>
#include <ctype.h>
+#include <fcntl.h>
#define _(String) gettext(String)
#include "libgfs2.h"
@@ -640,24 +641,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. */
@@ -674,19 +738,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;
@@ -696,8 +763,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
@@ -708,8 +778,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,
@@ -724,6 +796,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
cluster: RHEL6 - libgfs2: Add readahead for rgrp headers
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=0cf2544edfa...
Commit: 0cf2544edfa377c47b0e904ecdce00194590593e
Parent: 62a5ab048683b4ce77f0eeaba81d3330da574d41
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Sun Feb 17 13:08:04 2013 -0700
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Fri May 17 14:26:27 2013 -0500
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.
rhbz#902920
---
gfs2/fsck/main.c | 4 ++
gfs2/libgfs2/buf.c | 83 ++++++++++++++++++++++++++++++++++++++++-------
gfs2/libgfs2/libgfs2.h | 10 +++++-
gfs2/libgfs2/rgrp.c | 6 ++--
gfs2/libgfs2/super.c | 35 ++++++++++++++++++++
5 files changed, 120 insertions(+), 18 deletions(-)
diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c
index 676b676..ec44c83 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -35,6 +35,8 @@ struct osi_root inodetree = (struct osi_root) { NULL, };
int dups_found = 0, dups_found_first = 0;
struct gfs_sb *sbd1 = NULL;
+extern FILE *brdfp;
+
/* This function is for libgfs2's sake. */
void print_it(const char *label, const char *fmt, const char *fmt2, ...)
{
@@ -232,6 +234,8 @@ int main(int argc, char **argv)
memset(sdp, 0, sizeof(*sdp));
+/* brdfp = fopen("brd-log.txt", "w"); */
+
if ((error = read_cmdline(argc, argv, &opts)))
exit(error);
setbuf(stdout, NULL);
diff --git a/gfs2/libgfs2/buf.c b/gfs2/libgfs2/buf.c
index 5a0f718..fdd6e3d 100644
--- a/gfs2/libgfs2/buf.c
+++ b/gfs2/libgfs2/buf.c
@@ -5,6 +5,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>
@@ -12,6 +13,61 @@
#include "libgfs2.h"
+FILE *brdfp = NULL;
+
+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));
+ struct iovec *iovbase = iov;
+ struct timeval st, et, tt;
+ 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;
+ }
+
+ gettimeofday(&st, NULL);
+ ret = preadv(sdp->device_fd, iovbase, n, block * sdp->bsize);
+ gettimeofday(&et, NULL);
+
+ 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);
+ }
+
+ if (brdfp) {
+ unsigned long usecs;
+ timersub(&et, &st, &tt);
+ usecs = tt.tv_usec + 1000000*tt.tv_sec;
+ fprintf(brdfp, "%lu\t%d\t%s\n", usecs, line, caller);
+ }
+
+ 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;
+}
+
struct gfs2_buffer_head *__bget_generic(struct gfs2_sbd *sdp, uint64_t num,
int read_disk,
int line, const char *caller)
@@ -46,27 +102,28 @@ struct gfs2_buffer_head *__bget_generic(struct gfs2_sbd *sdp, uint64_t num,
return bh;
}
-struct gfs2_buffer_head *__bget(struct gfs2_sbd *sdp, uint64_t num, int line,
- const char *caller)
+struct gfs2_buffer_head *bget(struct gfs2_sbd *sdp, uint64_t num)
{
- return __bget_generic(sdp, num, FALSE, line, caller);
-}
+ struct gfs2_buffer_head *bh;
-struct gfs2_buffer_head *__bread(struct gfs2_sbd *sdp, uint64_t num, int line,
- const char *caller)
-{
- return __bget_generic(sdp, num, TRUE, line, caller);
+ bh = calloc(1, sizeof(struct gfs2_buffer_head) + sdp->bsize);
+ if (bh == NULL)
+ return NULL;
+
+ bh->b_blocknr = num;
+ bh->sdp = sdp;
+ bh->iov.iov_base = (char *)bh + sizeof(struct gfs2_buffer_head);
+ bh->iov.iov_len = sdp->bsize;
+
+ return bh;
}
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 (write(sdp->device_fd, bh->b_data, sdp->bsize) != sdp->bsize)
+ 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 1b0b98d..bf834a5 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -10,6 +10,7 @@
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
+#include <sys/uio.h>
#include <linux/types.h>
#include <linux/limits.h>
#include <endian.h>
@@ -112,7 +113,10 @@ struct gfs2_buffer_head {
osi_list_t b_altlist; /* alternate list */
uint64_t b_blocknr;
int b_modified;
- char *b_data;
+ union {
+ struct iovec iov;
+ char *b_data;
+ };
struct gfs2_sbd *sdp;
};
@@ -291,6 +295,8 @@ extern struct gfs2_buffer_head *__bget(struct gfs2_sbd *sdp, uint64_t num,
int line, const char *caller);
extern struct gfs2_buffer_head *__bread(struct gfs2_sbd *sdp, uint64_t num,
int line, const char *caller);
+extern struct gfs2_buffer_head *bget(struct gfs2_sbd *sdp, uint64_t num);
+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);
@@ -299,8 +305,8 @@ extern int brelse(struct gfs2_buffer_head *bh);
#define bget_generic(bl, num, find, read) __bget_generic(bl, num, find, read, \
__LINE__, \
__FUNCTION__)
-#define bget(bl, num) __bget(bl, num, __LINE__, __FUNCTION__)
#define bread(bl, num) __bread(bl, num, __LINE__, __FUNCTION__)
+#define breadm(bl, bhs, n, block) __breadm(bl, bhs, n, block, __LINE__, __FUNCTION__)
#define bsync(bl) do { __bsync(bl, __LINE__, __FUNCTION__); } while(0)
#define bcommit(bl) do { __bcommit(bl, __LINE__, __FUNCTION__); } while(0)
diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c
index 0fcea3c..64703e0 100644
--- a/gfs2/libgfs2/rgrp.c
+++ b/gfs2/libgfs2/rgrp.c
@@ -129,10 +129,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 f8de2e6..8f49dff 100644
--- a/gfs2/libgfs2/super.c
+++ b/gfs2/libgfs2/super.c
@@ -5,6 +5,7 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
+#include <fcntl.h>
#include "libgfs2.h"
#include "osi_list.h"
@@ -206,6 +207,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
@@ -226,15 +250,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(".");
@@ -250,9 +283,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
cluster: RHEL510 - Med: Don't preserve SELinux context when copying files to /var/lib/nfs/sm
by Ryan McCabe
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=0c3782fd3fa...
Commit: 0c3782fd3fa61e9ceea938cc4f61e8572c6916c8
Parent: d45a4fe2fa265a19a4130161caa4ce92367f9072
Author: Ryan McCabe <rmccabe(a)redhat.com>
AuthorDate: Mon May 20 15:16:02 2013 -0400
Committer: Ryan McCabe <rmccabe(a)redhat.com>
CommitterDate: Mon May 20 23:46:49 2013 -0400
Med: Don't preserve SELinux context when copying files to /var/lib/nfs/sm
Pass the flags -Rdpf instead of -af to cp when copying files to
/var/lib/nfs/sm so that the SELinux context is inherited from the
target directory and not preserved from the files being copied.
Resolves: rhbz#907898
Signed-off-by: Ryan McCabe <rmccabe(a)redhat.com>
---
rgmanager/src/resources/svclib_nfslock | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/rgmanager/src/resources/svclib_nfslock b/rgmanager/src/resources/svclib_nfslock
index 2ec7bdd..fbfa94e 100644
--- a/rgmanager/src/resources/svclib_nfslock
+++ b/rgmanager/src/resources/svclib_nfslock
@@ -228,7 +228,7 @@ notify_list_store()
fi
owner=$(ls -dl /var/lib/nfs/statd/sm | awk '{print $3"."$4}')
- cp -af /var/lib/nfs/statd/sm/* $nl_dir/sm
+ cp -Rdpf /var/lib/nfs/statd/sm/* $nl_dir/sm
chown -R $owner $nl_dir
return 0
elif [ -d "/var/lib/nfs/sm" ]; then
@@ -238,7 +238,7 @@ notify_list_store()
fi
owner=$(ls -dl /var/lib/nfs/sm | awk '{print $3"."$4}')
- cp -af /var/lib/nfs/sm/* $nl_dir/sm
+ cp -Rdpf /var/lib/nfs/sm/* $nl_dir/sm
chown -R $owner $nl_dir
return 0
fi
@@ -265,12 +265,12 @@ notify_list_merge()
if [ -d "/var/lib/nfs/statd/sm" ]; then
owner=$(ls -dl /var/lib/nfs/statd/sm | awk '{print $3"."$4}')
- cp -af $nl_dir/sm/* /var/lib/nfs/statd/sm
+ cp -Rdpf $nl_dir/sm/* /var/lib/nfs/statd/sm
chown -R $owner $nl_dir
return 0
elif [ -d "/var/lib/nfs/sm" ]; then
owner=$(ls -dl /var/lib/nfs/sm | awk '{print $3"."$4}')
- cp -af $nl_dir/sm/* /var/lib/nfs/sm
+ cp -Rdpf $nl_dir/sm/* /var/lib/nfs/sm
chown -R $owner $nl_dir
return 0
fi
11 years