Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 581231 Details for
Bug 761107
fsck.gfs2: Add readahead of directory leaf blocks
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
Patch to avoid rereading directory blocks in check_leaf_blks
0001-fsck.gfs2-Avoid-rereading-the-hashtable-in-check_lea.patch (text/plain), 5.13 KB, created by
Andrew Price
on 2012-04-30 17:25:43 UTC
(
hide
)
Description:
Patch to avoid rereading directory blocks in check_leaf_blks
Filename:
MIME Type:
Creator:
Andrew Price
Created:
2012-04-30 17:25:43 UTC
Size:
5.13 KB
patch
obsolete
>From e13d0790df9341279bc808cc8294ec99e73014bb Mon Sep 17 00:00:00 2001 >From: Andrew Price <anprice@redhat.com> >Date: Fri, 27 Apr 2012 09:24:18 +0100 >Subject: [PATCH] fsck.gfs2: Avoid rereading the hashtable in check_leaf_blks > >Every time check_leaf_blks requires the next leaf it rereads the >hashtable block. This can lead to a large number of read requests being >emitted for large directories. This patch reads the entire hashtable >once, using a new lgfs2_read_hashtable function in libgfs2, in order to >avoid the overhead of the duplicate read requests. > >Signed-off-by: Andrew Price <anprice@redhat.com> >--- > gfs2/fsck/metawalk.c | 21 +++++++++++++++++---- > gfs2/libgfs2/fs_ops.c | 26 ++++++++++++++++++++++++++ > gfs2/libgfs2/libgfs2.h | 1 + > 3 files changed, 44 insertions(+), 4 deletions(-) > >diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c >index acdd10f..8d1af67 100644 >--- a/gfs2/fsck/metawalk.c >+++ b/gfs2/fsck/metawalk.c >@@ -649,13 +649,19 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass) > int lindex; > struct gfs2_sbd *sdp = ip->i_sbd; > int ref_count = 0, old_was_dup; >+ uint64_t *pointers; > >+ error = lgfs2_read_hashtable(ip, &pointers); >+ if (error) { >+ log_err("Error reading hashtable: %s\n", strerror(errno)); >+ return -errno; >+ } > /* 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); >+ leaf_no = pointers[lindex]; > if (valid_block(ip->i_sbd, leaf_no)) { > lbh = bread(sdp, leaf_no); > /* Make sure it's really a valid leaf block. */ >@@ -672,6 +678,7 @@ 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(pointers); > return 1; > } > old_leaf = -1; >@@ -680,7 +687,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass) > for (lindex = 0; lindex < (1 << ip->i_di.di_depth); lindex++) { > if (fsck_abort) > break; >- gfs2_get_leaf_nr(ip, lindex, &leaf_no); >+ leaf_no = pointers[lindex]; > > /* GFS has multiple indirect pointers to the same leaf > * until those extra pointers are needed, so skip the dups */ >@@ -694,8 +701,10 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass) > } > > do { >- if (fsck_abort) >+ if (fsck_abort) { >+ free(pointers); > 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 +715,10 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass) > &ref_count, > &lindex, > &oldleaf); >- if (error) >+ if (error) { >+ free(pointers); > return error; >+ } > } > error = check_leaf(ip, lindex, pass, &ref_count, > &leaf_no, old_leaf, &bad_leaf, >@@ -722,6 +733,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(pointers); > return 0; > } > >diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c >index a72394f..f47c56c 100644 >--- a/gfs2/libgfs2/fs_ops.c >+++ b/gfs2/libgfs2/fs_ops.c >@@ -845,6 +845,32 @@ void dirent2_del(struct gfs2_inode *dip, struct gfs2_buffer_head *bh, > prev->de_rec_len = cpu_to_be16(prev_rec_len); > } > >+/** >+ * Allocate an array of leaf block pointers and read the hashtable data from >+ * unstuffed directory inode *ip into it. The caller should free the memory >+ * pointed to by *pointers. >+ * Returns 0 if successful, -1 with errno set otherwise >+ */ >+int lgfs2_read_hashtable(struct gfs2_inode *ip, uint64_t **pointers) >+{ >+ int i; >+ size_t size; >+ >+ *pointers = (uint64_t *)calloc(1 << ip->i_di.di_depth, sizeof(uint64_t)); >+ if (*pointers == NULL) { >+ return -1; >+ } >+ size = gfs2_readi(ip, *pointers, 0, (1 << ip->i_di.di_depth) * sizeof(uint64_t)); >+ if (size != (1 << ip->i_di.di_depth) * sizeof(uint64_t)) { >+ free(*pointers); >+ return -1; >+ } >+ for (i = 0; i < (1 << ip->i_di.di_depth); i++) { >+ (*pointers)[i] = be64_to_cpu((*pointers)[i]); >+ } >+ return 0; >+} >+ > void gfs2_get_leaf_nr(struct gfs2_inode *dip, uint32_t lindex, > uint64_t *leaf_out) > { >diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h >index 4bd01a8..ceade5f 100644 >--- a/gfs2/libgfs2/libgfs2.h >+++ b/gfs2/libgfs2/libgfs2.h >@@ -470,6 +470,7 @@ extern int gfs2_dirent_del(struct gfs2_inode *dip, const char *filename, > int filename_len); > extern void block_map(struct gfs2_inode *ip, uint64_t lblock, int *new, > uint64_t *dblock, uint32_t *extlen, int prealloc); >+extern int lgfs2_read_hashtable(struct gfs2_inode *ip, uint64_t **pointers); > 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); >-- >1.7.7.6 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 761107
: 581231