Commit da1e9098 authored by Joel Becker's avatar Joel Becker Committed by Mark Fasheh

ocfs2: Separate out sync reads from ocfs2_read_blocks()

The ocfs2_read_blocks() function currently handles sync reads, cached,
reads, and sometimes cached reads.  We're going to add some
functionality to it, so first we should simplify it.  The uncached,
synchronous reads are much easer to handle as a separate function, so we
instroduce ocfs2_read_blocks_sync().
Signed-off-by: default avatarJoel Becker <joel.becker@oracle.com>
Signed-off-by: default avatarMark Fasheh <mfasheh@suse.com>
parent 936b8834
...@@ -88,6 +88,88 @@ int ocfs2_write_block(struct ocfs2_super *osb, struct buffer_head *bh, ...@@ -88,6 +88,88 @@ int ocfs2_write_block(struct ocfs2_super *osb, struct buffer_head *bh,
return ret; return ret;
} }
int ocfs2_read_blocks_sync(struct ocfs2_super *osb, u64 block,
unsigned int nr, struct buffer_head *bhs[])
{
int status = 0;
unsigned int i;
struct buffer_head *bh;
if (!nr) {
mlog(ML_BH_IO, "No buffers will be read!\n");
goto bail;
}
for (i = 0 ; i < nr ; i++) {
if (bhs[i] == NULL) {
bhs[i] = sb_getblk(osb->sb, block++);
if (bhs[i] == NULL) {
status = -EIO;
mlog_errno(status);
goto bail;
}
}
bh = bhs[i];
if (buffer_jbd(bh)) {
mlog(ML_ERROR,
"trying to sync read a jbd "
"managed bh (blocknr = %llu), skipping\n",
(unsigned long long)bh->b_blocknr);
continue;
}
if (buffer_dirty(bh)) {
/* This should probably be a BUG, or
* at least return an error. */
mlog(ML_ERROR,
"trying to sync read a dirty "
"buffer! (blocknr = %llu), skipping\n",
(unsigned long long)bh->b_blocknr);
continue;
}
lock_buffer(bh);
if (buffer_jbd(bh)) {
mlog(ML_ERROR,
"block %llu had the JBD bit set "
"while I was in lock_buffer!",
(unsigned long long)bh->b_blocknr);
BUG();
}
clear_buffer_uptodate(bh);
get_bh(bh); /* for end_buffer_read_sync() */
bh->b_end_io = end_buffer_read_sync;
submit_bh(READ, bh);
}
for (i = nr; i > 0; i--) {
bh = bhs[i - 1];
if (buffer_jbd(bh)) {
mlog(ML_ERROR,
"the journal got the buffer while it was "
"locked for io! (blocknr = %llu)\n",
(unsigned long long)bh->b_blocknr);
BUG();
}
wait_on_buffer(bh);
if (!buffer_uptodate(bh)) {
/* Status won't be cleared from here on out,
* so we can safely record this and loop back
* to cleanup the other buffers. */
status = -EIO;
put_bh(bh);
bhs[i - 1] = NULL;
}
}
bail:
return status;
}
int ocfs2_read_blocks(struct ocfs2_super *osb, u64 block, int nr, int ocfs2_read_blocks(struct ocfs2_super *osb, u64 block, int nr,
struct buffer_head *bhs[], int flags, struct buffer_head *bhs[], int flags,
struct inode *inode) struct inode *inode)
......
...@@ -46,6 +46,8 @@ int ocfs2_read_blocks(struct ocfs2_super *osb, ...@@ -46,6 +46,8 @@ int ocfs2_read_blocks(struct ocfs2_super *osb,
struct buffer_head *bhs[], struct buffer_head *bhs[],
int flags, int flags,
struct inode *inode); struct inode *inode);
int ocfs2_read_blocks_sync(struct ocfs2_super *osb, u64 block,
unsigned int nr, struct buffer_head *bhs[]);
int ocfs2_write_super_or_backup(struct ocfs2_super *osb, int ocfs2_write_super_or_backup(struct ocfs2_super *osb,
struct buffer_head *bh); struct buffer_head *bh);
......
...@@ -460,8 +460,11 @@ static int ocfs2_read_locked_inode(struct inode *inode, ...@@ -460,8 +460,11 @@ static int ocfs2_read_locked_inode(struct inode *inode,
} }
} }
if (can_lock)
status = ocfs2_read_block(osb, args->fi_blkno, &bh, 0, status = ocfs2_read_block(osb, args->fi_blkno, &bh, 0,
can_lock ? inode : NULL); inode);
else
status = ocfs2_read_blocks_sync(osb, args->fi_blkno, 1, &bh);
if (status < 0) { if (status < 0) {
mlog_errno(status); mlog_errno(status);
goto bail; goto bail;
......
...@@ -850,9 +850,8 @@ static int ocfs2_force_read_journal(struct inode *inode) ...@@ -850,9 +850,8 @@ static int ocfs2_force_read_journal(struct inode *inode)
/* We are reading journal data which should not /* We are reading journal data which should not
* be put in the uptodate cache */ * be put in the uptodate cache */
status = ocfs2_read_blocks(OCFS2_SB(inode->i_sb), status = ocfs2_read_blocks_sync(OCFS2_SB(inode->i_sb),
p_blkno, p_blocks, bhs, 0, p_blkno, p_blocks, bhs);
NULL);
if (status < 0) { if (status < 0) {
mlog_errno(status); mlog_errno(status);
goto bail; goto bail;
......
...@@ -200,7 +200,7 @@ static int update_backups(struct inode * inode, u32 clusters, char *data) ...@@ -200,7 +200,7 @@ static int update_backups(struct inode * inode, u32 clusters, char *data)
if (cluster > clusters) if (cluster > clusters)
break; break;
ret = ocfs2_read_block(osb, blkno, &backup, 0, NULL); ret = ocfs2_read_blocks_sync(osb, blkno, 1, &backup);
if (ret < 0) { if (ret < 0) {
mlog_errno(ret); mlog_errno(ret);
break; break;
...@@ -236,8 +236,8 @@ static void ocfs2_update_super_and_backups(struct inode *inode, ...@@ -236,8 +236,8 @@ static void ocfs2_update_super_and_backups(struct inode *inode,
* update the superblock last. * update the superblock last.
* It doesn't matter if the write failed. * It doesn't matter if the write failed.
*/ */
ret = ocfs2_read_block(osb, OCFS2_SUPER_BLOCK_BLKNO, ret = ocfs2_read_blocks_sync(osb, OCFS2_SUPER_BLOCK_BLKNO, 1,
&super_bh, 0, NULL); &super_bh);
if (ret < 0) { if (ret < 0) {
mlog_errno(ret); mlog_errno(ret);
goto out; goto out;
...@@ -540,7 +540,7 @@ int ocfs2_group_add(struct inode *inode, struct ocfs2_new_group_input *input) ...@@ -540,7 +540,7 @@ int ocfs2_group_add(struct inode *inode, struct ocfs2_new_group_input *input)
goto out_unlock; goto out_unlock;
} }
ret = ocfs2_read_block(osb, input->group, &group_bh, 0, NULL); ret = ocfs2_read_blocks_sync(osb, input->group, 1, &group_bh);
if (ret < 0) { if (ret < 0) {
mlog(ML_ERROR, "Can't read the group descriptor # %llu " mlog(ML_ERROR, "Can't read the group descriptor # %llu "
"from the device.", (unsigned long long)input->group); "from the device.", (unsigned long long)input->group);
......
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