Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=89e2e4a2f24f5…
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))
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=1325bb4d27bff…
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__ */
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=c361fd8d3d7b1…
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;
}