Skip to contentSkip to conversation

ocfs2: improve recovery performance

PATCH Applied Junxiao Bi 5 participants 9 messages Jun 17, 2016 – Jul 7, 2016 OCFS2

lore
Share & tools
lore

Junxiao Bi

author
#0 lore raw

PATCH v2 1/1 ocfs2: improve recovery performance

Journal replay will be run when do recovery for a dead node, to avoid the stale cache impact, all blocks of dead node's journal inode were reload from disk. This hurts the performance, check whether one block is cached before reload it can improve a lot performance. In my test env, the time doing recovery was improved from 120s to 1s.

---
 fs/ocfs2/journal.c |   41 ++++++++++++++++++++++-------------------
 1 file changed, 22 insertions(+), 19 deletions(-)
fs/ocfs2/journal.c +22 -19
index e607419cdfa4..bc0e21e8a674 100644
@@ -1159,10 +1159,8 @@ static int ocfs2_force_read_journal(struct inode *inode)
 	int status = 0;
 	int i;
 	u64 v_blkno, p_blkno, p_blocks, num_blocks;
-#define CONCURRENT_JOURNAL_FILL 32ULL
-	struct buffer_head *bhs[CONCURRENT_JOURNAL_FILL];
-
-	memset(bhs, 0, sizeof(struct buffer_head *) * CONCURRENT_JOURNAL_FILL);
+	struct buffer_head *bh = NULL;
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
 
 	num_blocks = ocfs2_blocks_for_bytes(inode->i_sb, i_size_read(inode));
 	v_blkno = 0;
@@ -1174,29 +1172,34 @@ static int ocfs2_force_read_journal(struct inode *inode)
 			goto bail;
 		}
 
-		if (p_blocks > CONCURRENT_JOURNAL_FILL)
-			p_blocks = CONCURRENT_JOURNAL_FILL;
+		for (i = 0; i < p_blocks; i++) {
+			bh = __find_get_block(osb->sb->s_bdev, p_blkno,
+					osb->sb->s_blocksize);
+			/* block not cached. */
+			if (!bh) {
+				p_blkno++;
+				continue;
+			}
 
-		/* We are reading journal data which should not
-		 * be put in the uptodate cache */
-		status = ocfs2_read_blocks_sync(OCFS2_SB(inode->i_sb),
-						p_blkno, p_blocks, bhs);
-		if (status < 0) {
-			mlog_errno(status);
-			goto bail;
-		}
+			brelse(bh);
+			bh = NULL;
+			/* We are reading journal data which should not
+			 * be put in the uptodate cache.
+			 */
+			status = ocfs2_read_blocks_sync(osb, p_blkno, 1, &bh);
+			if (status < 0) {
+				mlog_errno(status);
+				goto bail;
+			}
 
-		for(i = 0; i < p_blocks; i++) {
-			brelse(bhs[i]);
-			bhs[i] = NULL;
+			brelse(bh);
+			bh = NULL;
 		}
 
 		v_blkno += p_blocks;
 	}
 
 bail:
-	for(i = 0; i < CONCURRENT_JOURNAL_FILL; i++)
-		brelse(bhs[i]);
 	return status;
 }
 
Signature · 1 line
1.7.9.5
#1 lore raw

PATCH v2 1/1 ocfs2: improve recovery performance

Quoted 8 lines · Junxiao Bi

Journal replay will be run when do recovery for a dead node, to avoid the stale cache impact, all blocks of dead node's journal inode were reload from disk. This hurts the performance, check whether one block is cached before reload it can improve a lot performance. In my test env, the time doing recovery was improved from 120s to 1s.

Looks good to me. And it indeed has performance improvement from my test.

Quoted 72 lines
---
 fs/ocfs2/journal.c |   41 ++++++++++++++++++++++-------------------
 1 file changed, 22 insertions(+), 19 deletions(-)
fs/ocfs2/journal.c +22 -19
index e607419cdfa4..bc0e21e8a674 100644
@@ -1159,10 +1159,8 @@ static int ocfs2_force_read_journal(struct inode *inode)
 	int status = 0;
 	int i;
 	u64 v_blkno, p_blkno, p_blocks, num_blocks;
-#define CONCURRENT_JOURNAL_FILL 32ULL
-	struct buffer_head *bhs[CONCURRENT_JOURNAL_FILL];
-
-	memset(bhs, 0, sizeof(struct buffer_head *) * CONCURRENT_JOURNAL_FILL);
+	struct buffer_head *bh = NULL;
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
 
 	num_blocks = ocfs2_blocks_for_bytes(inode->i_sb, i_size_read(inode));
 	v_blkno = 0;
@@ -1174,29 +1172,34 @@ static int ocfs2_force_read_journal(struct inode *inode)
 			goto bail;
 		}
 
-		if (p_blocks > CONCURRENT_JOURNAL_FILL)
-			p_blocks = CONCURRENT_JOURNAL_FILL;
+		for (i = 0; i < p_blocks; i++) {
+			bh = __find_get_block(osb->sb->s_bdev, p_blkno,
+					osb->sb->s_blocksize);
+			/* block not cached. */
+			if (!bh) {
+				p_blkno++;
+				continue;
+			}
 
-		/* We are reading journal data which should not
-		 * be put in the uptodate cache */
-		status = ocfs2_read_blocks_sync(OCFS2_SB(inode->i_sb),
-						p_blkno, p_blocks, bhs);
-		if (status < 0) {
-			mlog_errno(status);
-			goto bail;
-		}
+			brelse(bh);
+			bh = NULL;
+			/* We are reading journal data which should not
+			 * be put in the uptodate cache.
+			 */
+			status = ocfs2_read_blocks_sync(osb, p_blkno, 1, &bh);
+			if (status < 0) {
+				mlog_errno(status);
+				goto bail;
+			}
 
-		for(i = 0; i < p_blocks; i++) {
-			brelse(bhs[i]);
-			bhs[i] = NULL;
+			brelse(bh);
+			bh = NULL;
 		}
 
 		v_blkno += p_blocks;
 	}
 
 bail:
-	for(i = 0; i < CONCURRENT_JOURNAL_FILL; i++)
-		brelse(bhs[i]);
 	return status;
 }
 
#2 lore raw

PATCH v2 1/1 ocfs2: improve recovery performance

Hello Junxiao,

I think this change will bring a performance improvement, but from the function comments /*
* JBD Might read a cached version of another nodes journal file. We
* don't want this as this file changes often and we get no
* notification on those changes. The only way to be sure that we've
* got the most up to date version of those blocks then is to force
* read them off disk. Just searching through the buffer cache won't
* work as there may be pages backing this file which are still marked
* up to date. We know things can't change on this file underneath us
* as we have the lock by now :)
*/
static int ocfs2_force_read_journal(struct inode *inode)

Did we consider this potential risk behind this patch? I am not familiar with this part code,
I want to know if there is any sync mechanism to make sure the block cache for another node journal file is really the latest data?

Thanks
Gang

Quoted 95 lines
Quoted 1 line
Quoted 1 line
Quoted 8 lines · Junxiao Bi

Journal replay will be run when do recovery for a dead node, to avoid the stale cache impact, all blocks of dead node's journal inode were reload from disk. This hurts the performance, check whether one block is cached before reload it can improve a lot performance. In my test env, the time doing recovery was improved from 120s to 1s.

Looks good to me. And it indeed has performance improvement from my test.

fs/ocfs2/journal.c static int ocfs2_force_read_journal(struct inode

Quoted 9 lines
---
 fs/ocfs2/journal.c |   41 ++++++++++++++++++++++-------------------
 1 file changed, 22 insertions(+), 19 deletions(-)
fs/ocfs2/journal.c +0 -0
index e607419cdfa4..bc0e21e8a674 100644
@@ -1159,10 +1159,8 @@ static int ocfs2_force_read_journal(struct inode 

*inode)

fs/ocfs2/journal.c static int ocfs2_force_read_journal(struct inode

Quoted 13 lines
fs/ocfs2/journal.c +2 -4
 	int status = 0;
 	int i;
 	u64 v_blkno, p_blkno, p_blocks, num_blocks;
-#define CONCURRENT_JOURNAL_FILL 32ULL
-	struct buffer_head *bhs[CONCURRENT_JOURNAL_FILL];
-
-	memset(bhs, 0, sizeof(struct buffer_head *) * CONCURRENT_JOURNAL_FILL);
+	struct buffer_head *bh = NULL;
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
 
 	num_blocks = ocfs2_blocks_for_bytes(inode->i_sb, i_size_read(inode));
 	v_blkno = 0;
@@ -1174,29 +1172,34 @@ static int ocfs2_force_read_journal(struct inode 

*inode)

Quoted 40 lines
fs/ocfs2/journal.c +20 -13
 			goto bail;
 		}
 
-		if (p_blocks > CONCURRENT_JOURNAL_FILL)
-			p_blocks = CONCURRENT_JOURNAL_FILL;
+		for (i = 0; i < p_blocks; i++) {
+			bh = __find_get_block(osb->sb->s_bdev, p_blkno,
+					osb->sb->s_blocksize);
+			/* block not cached. */
+			if (!bh) {
+				p_blkno++;
+				continue;
+			}
 
-		/* We are reading journal data which should not
-		 * be put in the uptodate cache */
-		status = ocfs2_read_blocks_sync(OCFS2_SB(inode->i_sb),
-						p_blkno, p_blocks, bhs);
-		if (status < 0) {
-			mlog_errno(status);
-			goto bail;
-		}
+			brelse(bh);
+			bh = NULL;
+			/* We are reading journal data which should not
+			 * be put in the uptodate cache.
+			 */
+			status = ocfs2_read_blocks_sync(osb, p_blkno, 1, &bh);
+			if (status < 0) {
+				mlog_errno(status);
+				goto bail;
+			}
 
-		for(i = 0; i < p_blocks; i++) {
-			brelse(bhs[i]);
-			bhs[i] = NULL;
+			brelse(bh);
+			bh = NULL;
 		}

fs/ocfs2/journal.c static int ocfs2_force_read_journal(struct inode *inode) · line 1205

Quoted 10 lines
fs/ocfs2/journal.c +0 -2
 
 		v_blkno += p_blocks;
 	}
 
 bail:
-	for(i = 0; i < CONCURRENT_JOURNAL_FILL; i++)
-		brelse(bhs[i]);
 	return status;
 }
 

_______________________________________________
Ocfs2-devel mailing list
Ocfs2-devel at oss.oracle.com
https://oss.oracle.com/mailman/listinfo/ocfs2-devel

author
#3 lore raw

PATCH v2 1/1 ocfs2: improve recovery performance

Hi Gang,

Quoted 15 lines · Gang He

Hello Junxiao,

I think this change will bring a performance improvement, but from the function comments /*
* JBD Might read a cached version of another nodes journal file. We
* don't want this as this file changes often and we get no
* notification on those changes. The only way to be sure that we've
* got the most up to date version of those blocks then is to force
* read them off disk. Just searching through the buffer cache won't
* work as there may be pages backing this file which are still marked
* up to date. We know things can't change on this file underneath us
* as we have the lock by now :)
*/
static int ocfs2_force_read_journal(struct inode *inode)

Quoted 2 lines

Did we consider this potential risk behind this patch? I am not familiar with this part code,
I want to know if there is any sync mechanism to make sure the block cache for another node journal file is really the latest data?

I don't see that is needed, because those stale info will not be used except journal replay.

Thanks,
Junxiao.

Quoted 103 lines

Thanks
Gang

Quoted 95 lines
Quoted 1 line
Quoted 1 line
Quoted 8 lines · Junxiao Bi

Journal replay will be run when do recovery for a dead node, to avoid the stale cache impact, all blocks of dead node's journal inode were reload from disk. This hurts the performance, check whether one block is cached before reload it can improve a lot performance. In my test env, the time doing recovery was improved from 120s to 1s.

Looks good to me. And it indeed has performance improvement from my test.

fs/ocfs2/journal.c static int ocfs2_force_read_journal(struct inode

Quoted 9 lines
---
 fs/ocfs2/journal.c |   41 ++++++++++++++++++++++-------------------
 1 file changed, 22 insertions(+), 19 deletions(-)
fs/ocfs2/journal.c +0 -0
index e607419cdfa4..bc0e21e8a674 100644
@@ -1159,10 +1159,8 @@ static int ocfs2_force_read_journal(struct inode 

*inode)

fs/ocfs2/journal.c static int ocfs2_force_read_journal(struct inode

Quoted 13 lines
fs/ocfs2/journal.c +2 -4
 	int status = 0;
 	int i;
 	u64 v_blkno, p_blkno, p_blocks, num_blocks;
-#define CONCURRENT_JOURNAL_FILL 32ULL
-	struct buffer_head *bhs[CONCURRENT_JOURNAL_FILL];
-
-	memset(bhs, 0, sizeof(struct buffer_head *) * CONCURRENT_JOURNAL_FILL);
+	struct buffer_head *bh = NULL;
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
 
 	num_blocks = ocfs2_blocks_for_bytes(inode->i_sb, i_size_read(inode));
 	v_blkno = 0;
@@ -1174,29 +1172,34 @@ static int ocfs2_force_read_journal(struct inode 

*inode)

Quoted 40 lines
fs/ocfs2/journal.c +20 -13
 			goto bail;
 		}
 
-		if (p_blocks > CONCURRENT_JOURNAL_FILL)
-			p_blocks = CONCURRENT_JOURNAL_FILL;
+		for (i = 0; i < p_blocks; i++) {
+			bh = __find_get_block(osb->sb->s_bdev, p_blkno,
+					osb->sb->s_blocksize);
+			/* block not cached. */
+			if (!bh) {
+				p_blkno++;
+				continue;
+			}
 
-		/* We are reading journal data which should not
-		 * be put in the uptodate cache */
-		status = ocfs2_read_blocks_sync(OCFS2_SB(inode->i_sb),
-						p_blkno, p_blocks, bhs);
-		if (status < 0) {
-			mlog_errno(status);
-			goto bail;
-		}
+			brelse(bh);
+			bh = NULL;
+			/* We are reading journal data which should not
+			 * be put in the uptodate cache.
+			 */
+			status = ocfs2_read_blocks_sync(osb, p_blkno, 1, &bh);
+			if (status < 0) {
+				mlog_errno(status);
+				goto bail;
+			}
 
-		for(i = 0; i < p_blocks; i++) {
-			brelse(bhs[i]);
-			bhs[i] = NULL;
+			brelse(bh);
+			bh = NULL;
 		}

fs/ocfs2/journal.c static int ocfs2_force_read_journal(struct inode *inode) · line 1205

Quoted 10 lines
fs/ocfs2/journal.c +0 -2
 
 		v_blkno += p_blocks;
 	}
 
 bail:
-	for(i = 0; i < CONCURRENT_JOURNAL_FILL; i++)
-		brelse(bhs[i]);
 	return status;
 }
 

_______________________________________________
Ocfs2-devel mailing list
Ocfs2-devel at oss.oracle.com
https://oss.oracle.com/mailman/listinfo/ocfs2-devel

author
#4 lore raw

PATCH v2 1/1 ocfs2: improve recovery performance

In reply to Joseph Qi

Hi Andrew,

Did you miss this patch to your tree?

Thanks,
Junxiao.

Quoted 87 lines · Joseph Qi
Quoted 8 lines · Junxiao Bi

Journal replay will be run when do recovery for a dead node, to avoid the stale cache impact, all blocks of dead node's journal inode were reload from disk. This hurts the performance, check whether one block is cached before reload it can improve a lot performance. In my test env, the time doing recovery was improved from 120s to 1s.

Looks good to me. And it indeed has performance improvement from my test.

Quoted 72 lines
---
 fs/ocfs2/journal.c |   41 ++++++++++++++++++++++-------------------
 1 file changed, 22 insertions(+), 19 deletions(-)
fs/ocfs2/journal.c +22 -19
index e607419cdfa4..bc0e21e8a674 100644
@@ -1159,10 +1159,8 @@ static int ocfs2_force_read_journal(struct inode *inode)
 	int status = 0;
 	int i;
 	u64 v_blkno, p_blkno, p_blocks, num_blocks;
-#define CONCURRENT_JOURNAL_FILL 32ULL
-	struct buffer_head *bhs[CONCURRENT_JOURNAL_FILL];
-
-	memset(bhs, 0, sizeof(struct buffer_head *) * CONCURRENT_JOURNAL_FILL);
+	struct buffer_head *bh = NULL;
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
 
 	num_blocks = ocfs2_blocks_for_bytes(inode->i_sb, i_size_read(inode));
 	v_blkno = 0;
@@ -1174,29 +1172,34 @@ static int ocfs2_force_read_journal(struct inode *inode)
 			goto bail;
 		}
 
-		if (p_blocks > CONCURRENT_JOURNAL_FILL)
-			p_blocks = CONCURRENT_JOURNAL_FILL;
+		for (i = 0; i < p_blocks; i++) {
+			bh = __find_get_block(osb->sb->s_bdev, p_blkno,
+					osb->sb->s_blocksize);
+			/* block not cached. */
+			if (!bh) {
+				p_blkno++;
+				continue;
+			}
 
-		/* We are reading journal data which should not
-		 * be put in the uptodate cache */
-		status = ocfs2_read_blocks_sync(OCFS2_SB(inode->i_sb),
-						p_blkno, p_blocks, bhs);
-		if (status < 0) {
-			mlog_errno(status);
-			goto bail;
-		}
+			brelse(bh);
+			bh = NULL;
+			/* We are reading journal data which should not
+			 * be put in the uptodate cache.
+			 */
+			status = ocfs2_read_blocks_sync(osb, p_blkno, 1, &bh);
+			if (status < 0) {
+				mlog_errno(status);
+				goto bail;
+			}
 
-		for(i = 0; i < p_blocks; i++) {
-			brelse(bhs[i]);
-			bhs[i] = NULL;
+			brelse(bh);
+			bh = NULL;
 		}
 
 		v_blkno += p_blocks;
 	}
 
 bail:
-	for(i = 0; i < CONCURRENT_JOURNAL_FILL; i++)
-		brelse(bhs[i]);
 	return status;
 }
 
#5 lore raw

PATCH v2 1/1 ocfs2: improve recovery performance

Quoted 3 lines · On Thu, 23 Jun 2016 09:17:53 +0800 Junxiao Bi <[email protected]> wrote:

Hi Andrew,

Did you miss this patch to your tree?

I would have seen it eventually. Explicitly cc'ing me on patches helps, please.

author
#6 lore raw

PATCH v2 1/1 ocfs2: improve recovery performance

Quoted 8 lines · Andrew Morton
Quoted 3 lines · On Thu, 23 Jun 2016 09:17:53 +0800 Junxiao Bi <[email protected]> wrote:

Hi Andrew,

Did you miss this patch to your tree?

I would have seen it eventually. Explicitly cc'ing me on patches helps, please.

I see, will cc you next time.

Thanks,
Junxiao.

Quoted 1 line
#7 lore raw

PATCH v2 1/1 ocfs2: improve recovery performance

In reply to Junxiao Bi

Hi Junxiao,
p_blkno is not increased after force reading from disk, so this block is read many times from disk while other blocks remain in cached are not reloaded.

Thanks,
Jiufei

Quoted 80 lines · Junxiao Bi

Journal replay will be run when do recovery for a dead node, to avoid the stale cache impact, all blocks of dead node's journal inode were reload from disk. This hurts the performance, check whether one block is cached before reload it can improve a lot performance. In my test env, the time doing recovery was improved from 120s to 1s.

---
 fs/ocfs2/journal.c |   41 ++++++++++++++++++++++-------------------
 1 file changed, 22 insertions(+), 19 deletions(-)
fs/ocfs2/journal.c +22 -19
index e607419cdfa4..bc0e21e8a674 100644
@@ -1159,10 +1159,8 @@ static int ocfs2_force_read_journal(struct inode *inode)
 	int status = 0;
 	int i;
 	u64 v_blkno, p_blkno, p_blocks, num_blocks;
-#define CONCURRENT_JOURNAL_FILL 32ULL
-	struct buffer_head *bhs[CONCURRENT_JOURNAL_FILL];
-
-	memset(bhs, 0, sizeof(struct buffer_head *) * CONCURRENT_JOURNAL_FILL);
+	struct buffer_head *bh = NULL;
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
 
 	num_blocks = ocfs2_blocks_for_bytes(inode->i_sb, i_size_read(inode));
 	v_blkno = 0;
@@ -1174,29 +1172,34 @@ static int ocfs2_force_read_journal(struct inode *inode)
 			goto bail;
 		}
 
-		if (p_blocks > CONCURRENT_JOURNAL_FILL)
-			p_blocks = CONCURRENT_JOURNAL_FILL;
+		for (i = 0; i < p_blocks; i++) {
+			bh = __find_get_block(osb->sb->s_bdev, p_blkno,
+					osb->sb->s_blocksize);
+			/* block not cached. */
+			if (!bh) {
+				p_blkno++;
+				continue;
+			}
 
-		/* We are reading journal data which should not
-		 * be put in the uptodate cache */
-		status = ocfs2_read_blocks_sync(OCFS2_SB(inode->i_sb),
-						p_blkno, p_blocks, bhs);
-		if (status < 0) {
-			mlog_errno(status);
-			goto bail;
-		}
+			brelse(bh);
+			bh = NULL;
+			/* We are reading journal data which should not
+			 * be put in the uptodate cache.
+			 */
+			status = ocfs2_read_blocks_sync(osb, p_blkno, 1, &bh);
+			if (status < 0) {
+				mlog_errno(status);
+				goto bail;
+			}
 
-		for(i = 0; i < p_blocks; i++) {
-			brelse(bhs[i]);
-			bhs[i] = NULL;
+			brelse(bh);
+			bh = NULL;
 		}
 
 		v_blkno += p_blocks;
 	}
 
 bail:
-	for(i = 0; i < CONCURRENT_JOURNAL_FILL; i++)
-		brelse(bhs[i]);
 	return status;
 }
 
author
#8 lore raw

PATCH v2 1/1 ocfs2: improve recovery performance

Quoted 4 lines · xuejiufei

Hi Junxiao,
p_blkno is not increased after force reading from disk, so this block is read many times from disk while other blocks remain in cached are not reloaded.

Good catch. Will send a v2 version.

Thanks,
Junxiao.

Quoted 86 lines

Thanks,
Jiufei

Quoted 80 lines · Junxiao Bi

Journal replay will be run when do recovery for a dead node, to avoid the stale cache impact, all blocks of dead node's journal inode were reload from disk. This hurts the performance, check whether one block is cached before reload it can improve a lot performance. In my test env, the time doing recovery was improved from 120s to 1s.

---
 fs/ocfs2/journal.c |   41 ++++++++++++++++++++++-------------------
 1 file changed, 22 insertions(+), 19 deletions(-)
fs/ocfs2/journal.c +22 -19
index e607419cdfa4..bc0e21e8a674 100644
@@ -1159,10 +1159,8 @@ static int ocfs2_force_read_journal(struct inode *inode)
 	int status = 0;
 	int i;
 	u64 v_blkno, p_blkno, p_blocks, num_blocks;
-#define CONCURRENT_JOURNAL_FILL 32ULL
-	struct buffer_head *bhs[CONCURRENT_JOURNAL_FILL];
-
-	memset(bhs, 0, sizeof(struct buffer_head *) * CONCURRENT_JOURNAL_FILL);
+	struct buffer_head *bh = NULL;
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
 
 	num_blocks = ocfs2_blocks_for_bytes(inode->i_sb, i_size_read(inode));
 	v_blkno = 0;
@@ -1174,29 +1172,34 @@ static int ocfs2_force_read_journal(struct inode *inode)
 			goto bail;
 		}
 
-		if (p_blocks > CONCURRENT_JOURNAL_FILL)
-			p_blocks = CONCURRENT_JOURNAL_FILL;
+		for (i = 0; i < p_blocks; i++) {
+			bh = __find_get_block(osb->sb->s_bdev, p_blkno,
+					osb->sb->s_blocksize);
+			/* block not cached. */
+			if (!bh) {
+				p_blkno++;
+				continue;
+			}
 
-		/* We are reading journal data which should not
-		 * be put in the uptodate cache */
-		status = ocfs2_read_blocks_sync(OCFS2_SB(inode->i_sb),
-						p_blkno, p_blocks, bhs);
-		if (status < 0) {
-			mlog_errno(status);
-			goto bail;
-		}
+			brelse(bh);
+			bh = NULL;
+			/* We are reading journal data which should not
+			 * be put in the uptodate cache.
+			 */
+			status = ocfs2_read_blocks_sync(osb, p_blkno, 1, &bh);
+			if (status < 0) {
+				mlog_errno(status);
+				goto bail;
+			}
 
-		for(i = 0; i < p_blocks; i++) {
-			brelse(bhs[i]);
-			bhs[i] = NULL;
+			brelse(bh);
+			bh = NULL;
 		}
 
 		v_blkno += p_blocks;
 	}
 
 bail:
-	for(i = 0; i < CONCURRENT_JOURNAL_FILL; i++)
-		brelse(bhs[i]);
 	return status;
 }