Commit fb90f8c2 authored by Hans Reiser's avatar Hans Reiser Committed by Linus Torvalds

[PATCH] 07-reiserfs-bitmap-journal-read-ahead.diff

   Speed up reading of journal bitmaps. RAID users should notice significant
   speedup when mounting reiserfs over self-rebuilding RAID arays.
parent 55702c2a
...@@ -71,7 +71,9 @@ DECLARE_WAIT_QUEUE_HEAD(reiserfs_commit_thread_wait) ; ...@@ -71,7 +71,9 @@ DECLARE_WAIT_QUEUE_HEAD(reiserfs_commit_thread_wait) ;
static DECLARE_WAIT_QUEUE_HEAD(reiserfs_commit_thread_done) ; static DECLARE_WAIT_QUEUE_HEAD(reiserfs_commit_thread_done) ;
DECLARE_TASK_QUEUE(reiserfs_commit_thread_tq) ; DECLARE_TASK_QUEUE(reiserfs_commit_thread_tq) ;
#define JOURNAL_TRANS_HALF 1018 /* must be correct to keep the desc and commit structs at 4k */ #define JOURNAL_TRANS_HALF 1018 /* must be correct to keep the desc and commit
structs at 4k */
#define BUFNR 64 /*read ahead */
/* cnode stat bits. Move these into reiserfs_fs.h */ /* cnode stat bits. Move these into reiserfs_fs.h */
...@@ -1598,6 +1600,41 @@ static int journal_read_transaction(struct super_block *p_s_sb, unsigned long cu ...@@ -1598,6 +1600,41 @@ static int journal_read_transaction(struct super_block *p_s_sb, unsigned long cu
** **
** On exit, it sets things up so the first transaction will work correctly. ** On exit, it sets things up so the first transaction will work correctly.
*/ */
struct buffer_head * reiserfs_breada (kdev_t dev, int block, int bufsize,
unsigned int max_block)
{
struct buffer_head * bhlist[BUFNR];
unsigned int blocks = BUFNR;
struct buffer_head * bh;
int i, j;
bh = getblk (dev, block, bufsize);
if (buffer_uptodate (bh))
return (bh);
if (block + BUFNR > max_block) {
blocks = max_block - block;
}
bhlist[0] = bh;
j = 1;
for (i = 1; i < blocks; i++) {
bh = getblk (dev, block + i, bufsize);
if (buffer_uptodate (bh)) {
brelse (bh);
break;
}
else bhlist[j++] = bh;
}
ll_rw_block (READ, j, bhlist);
for(i = 1; i < j; i++)
brelse (bhlist[i]);
bh = bhlist[0];
wait_on_buffer (bh);
if (buffer_uptodate (bh))
return bh;
brelse (bh);
return NULL;
}
static int journal_read(struct super_block *p_s_sb) { static int journal_read(struct super_block *p_s_sb) {
struct reiserfs_journal_desc *desc ; struct reiserfs_journal_desc *desc ;
unsigned long last_flush_trans_id = 0 ; unsigned long last_flush_trans_id = 0 ;
...@@ -1668,7 +1705,8 @@ static int journal_read(struct super_block *p_s_sb) { ...@@ -1668,7 +1705,8 @@ static int journal_read(struct super_block *p_s_sb) {
** all the valid transactions, and pick out the oldest. ** all the valid transactions, and pick out the oldest.
*/ */
while(continue_replay && cur_dblock < (SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + SB_ONDISK_JOURNAL_SIZE(p_s_sb))) { while(continue_replay && cur_dblock < (SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + SB_ONDISK_JOURNAL_SIZE(p_s_sb))) {
d_bh = bread(SB_JOURNAL_DEV(p_s_sb), cur_dblock, p_s_sb->s_blocksize) ; d_bh = reiserfs_breada(p_s_sb->s_dev, cur_dblock, p_s_sb->s_blocksize,
SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + SB_ONDISK_JOURNAL_SIZE(p_s_sb)) ;
ret = journal_transaction_is_valid(p_s_sb, d_bh, &oldest_invalid_trans_id, &newest_mount_id) ; ret = journal_transaction_is_valid(p_s_sb, d_bh, &oldest_invalid_trans_id, &newest_mount_id) ;
if (ret == 1) { if (ret == 1) {
desc = (struct reiserfs_journal_desc *)d_bh->b_data ; desc = (struct reiserfs_journal_desc *)d_bh->b_data ;
......
...@@ -655,28 +655,30 @@ static int reiserfs_remount (struct super_block * s, int * flags, char * data) ...@@ -655,28 +655,30 @@ static int reiserfs_remount (struct super_block * s, int * flags, char * data)
static int read_bitmaps (struct super_block * s) static int read_bitmaps (struct super_block * s)
{ {
int i, bmp, dl ; int i, bmp;
struct reiserfs_super_block * rs = SB_DISK_SUPER_BLOCK(s);
SB_AP_BITMAP (s) = reiserfs_kmalloc (sizeof (struct buffer_head *) * sb_bmap_nr(rs), GFP_NOFS, s); SB_AP_BITMAP (s) = reiserfs_kmalloc (sizeof (struct buffer_head *) * SB_BMAP_NR(s), GFP_NOFS, s);
if (SB_AP_BITMAP (s) == 0) if (SB_AP_BITMAP (s) == 0)
return 1; return 1;
memset (SB_AP_BITMAP (s), 0, sizeof (struct buffer_head *) * sb_bmap_nr(rs)); for (i = 0, bmp = REISERFS_DISK_OFFSET_IN_BYTES / s->s_blocksize + 1;
i < SB_BMAP_NR(s); i++, bmp = s->s_blocksize * 8 * i) {
/* reiserfs leaves the first 64k unused so that any partition SB_AP_BITMAP (s)[i] = getblk (s->s_dev, bmp, s->s_blocksize);
labeling scheme currently used will have enough space. Then we if (!buffer_uptodate(SB_AP_BITMAP(s)[i]))
need one block for the super. -Hans */ ll_rw_block(READ, 1, SB_AP_BITMAP(s) + i);
bmp = (REISERFS_DISK_OFFSET_IN_BYTES / s->s_blocksize) + 1; /* first of bitmap blocks */ }
SB_AP_BITMAP (s)[0] = reiserfs_bread (s, bmp); for (i = 0; i < SB_BMAP_NR(s); i++) {
if(!SB_AP_BITMAP(s)[0]) wait_on_buffer(SB_AP_BITMAP (s)[i]);
return 1; if (!buffer_uptodate(SB_AP_BITMAP(s)[i])) {
for (i = 1, bmp = dl = s->s_blocksize * 8; i < sb_bmap_nr(rs); i ++) { reiserfs_warning("sh-2029: reiserfs read_bitmaps: "
SB_AP_BITMAP (s)[i] = reiserfs_bread (s, bmp); "bitmap block (#%lu) reading failed\n",
if (!SB_AP_BITMAP (s)[i]) SB_AP_BITMAP(s)[i]->b_blocknr);
for (i = 0; i < SB_BMAP_NR(s); i++)
brelse(SB_AP_BITMAP(s)[i]);
reiserfs_kfree(SB_AP_BITMAP(s), sizeof(struct buffer_head *) * SB_BMAP_NR(s), s);
SB_AP_BITMAP(s) = NULL;
return 1; return 1;
bmp += dl; }
} }
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment