aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJoel Becker <joel.becker@oracle.com>2008-10-09 20:20:29 -0400
committerMark Fasheh <mfasheh@suse.com>2008-10-14 14:29:10 -0400
commitda1e90985a0e767e44397c9db0937e236033fa58 (patch)
tree88d16dd378bf1b180d345a87de95316546af348a /fs
parent936b8834366ec05f2a6993f73afd8348cac9718e (diff)
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: Joel Becker <joel.becker@oracle.com> Signed-off-by: Mark Fasheh <mfasheh@suse.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/ocfs2/buffer_head_io.c84
-rw-r--r--fs/ocfs2/buffer_head_io.h2
-rw-r--r--fs/ocfs2/inode.c7
-rw-r--r--fs/ocfs2/journal.c5
-rw-r--r--fs/ocfs2/resize.c8
5 files changed, 96 insertions, 10 deletions
diff --git a/fs/ocfs2/buffer_head_io.c b/fs/ocfs2/buffer_head_io.c
index f136639f5b41..ca4ab7ce85bf 100644
--- a/fs/ocfs2/buffer_head_io.c
+++ b/fs/ocfs2/buffer_head_io.c
@@ -66,7 +66,7 @@ int ocfs2_write_block(struct ocfs2_super *osb, struct buffer_head *bh,
66 /* remove from dirty list before I/O. */ 66 /* remove from dirty list before I/O. */
67 clear_buffer_dirty(bh); 67 clear_buffer_dirty(bh);
68 68
69 get_bh(bh); /* for end_buffer_write_sync() */ 69 get_bh(bh); /* for end_buffer_write_sync() */
70 bh->b_end_io = end_buffer_write_sync; 70 bh->b_end_io = end_buffer_write_sync;
71 submit_bh(WRITE, bh); 71 submit_bh(WRITE, bh);
72 72
@@ -88,6 +88,88 @@ out:
88 return ret; 88 return ret;
89} 89}
90 90
91int ocfs2_read_blocks_sync(struct ocfs2_super *osb, u64 block,
92 unsigned int nr, struct buffer_head *bhs[])
93{
94 int status = 0;
95 unsigned int i;
96 struct buffer_head *bh;
97
98 if (!nr) {
99 mlog(ML_BH_IO, "No buffers will be read!\n");
100 goto bail;
101 }
102
103 for (i = 0 ; i < nr ; i++) {
104 if (bhs[i] == NULL) {
105 bhs[i] = sb_getblk(osb->sb, block++);
106 if (bhs[i] == NULL) {
107 status = -EIO;
108 mlog_errno(status);
109 goto bail;
110 }
111 }
112 bh = bhs[i];
113
114 if (buffer_jbd(bh)) {
115 mlog(ML_ERROR,
116 "trying to sync read a jbd "
117 "managed bh (blocknr = %llu), skipping\n",
118 (unsigned long long)bh->b_blocknr);
119 continue;
120 }
121
122 if (buffer_dirty(bh)) {
123 /* This should probably be a BUG, or
124 * at least return an error. */
125 mlog(ML_ERROR,
126 "trying to sync read a dirty "
127 "buffer! (blocknr = %llu), skipping\n",
128 (unsigned long long)bh->b_blocknr);
129 continue;
130 }
131
132 lock_buffer(bh);
133 if (buffer_jbd(bh)) {
134 mlog(ML_ERROR,
135 "block %llu had the JBD bit set "
136 "while I was in lock_buffer!",
137 (unsigned long long)bh->b_blocknr);
138 BUG();
139 }
140
141 clear_buffer_uptodate(bh);
142 get_bh(bh); /* for end_buffer_read_sync() */
143 bh->b_end_io = end_buffer_read_sync;
144 submit_bh(READ, bh);
145 }
146
147 for (i = nr; i > 0; i--) {
148 bh = bhs[i - 1];
149
150 if (buffer_jbd(bh)) {
151 mlog(ML_ERROR,
152 "the journal got the buffer while it was "
153 "locked for io! (blocknr = %llu)\n",
154 (unsigned long long)bh->b_blocknr);
155 BUG();
156 }
157
158 wait_on_buffer(bh);
159 if (!buffer_uptodate(bh)) {
160 /* Status won't be cleared from here on out,
161 * so we can safely record this and loop back
162 * to cleanup the other buffers. */
163 status = -EIO;
164 put_bh(bh);
165 bhs[i - 1] = NULL;
166 }
167 }
168
169bail:
170 return status;
171}
172
91int ocfs2_read_blocks(struct ocfs2_super *osb, u64 block, int nr, 173int ocfs2_read_blocks(struct ocfs2_super *osb, u64 block, int nr,
92 struct buffer_head *bhs[], int flags, 174 struct buffer_head *bhs[], int flags,
93 struct inode *inode) 175 struct inode *inode)
diff --git a/fs/ocfs2/buffer_head_io.h b/fs/ocfs2/buffer_head_io.h
index c2e78614c3e5..71646b470ac8 100644
--- a/fs/ocfs2/buffer_head_io.h
+++ b/fs/ocfs2/buffer_head_io.h
@@ -46,6 +46,8 @@ int ocfs2_read_blocks(struct ocfs2_super *osb,
46 struct buffer_head *bhs[], 46 struct buffer_head *bhs[],
47 int flags, 47 int flags,
48 struct inode *inode); 48 struct inode *inode);
49int ocfs2_read_blocks_sync(struct ocfs2_super *osb, u64 block,
50 unsigned int nr, struct buffer_head *bhs[]);
49 51
50int ocfs2_write_super_or_backup(struct ocfs2_super *osb, 52int ocfs2_write_super_or_backup(struct ocfs2_super *osb,
51 struct buffer_head *bh); 53 struct buffer_head *bh);
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c
index 05ad1186a167..522297033945 100644
--- a/fs/ocfs2/inode.c
+++ b/fs/ocfs2/inode.c
@@ -460,8 +460,11 @@ static int ocfs2_read_locked_inode(struct inode *inode,
460 } 460 }
461 } 461 }
462 462
463 status = ocfs2_read_block(osb, args->fi_blkno, &bh, 0, 463 if (can_lock)
464 can_lock ? inode : NULL); 464 status = ocfs2_read_block(osb, args->fi_blkno, &bh, 0,
465 inode);
466 else
467 status = ocfs2_read_blocks_sync(osb, args->fi_blkno, 1, &bh);
465 if (status < 0) { 468 if (status < 0) {
466 mlog_errno(status); 469 mlog_errno(status);
467 goto bail; 470 goto bail;
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c
index 562ba652593e..10c51b562be8 100644
--- a/fs/ocfs2/journal.c
+++ b/fs/ocfs2/journal.c
@@ -850,9 +850,8 @@ static int ocfs2_force_read_journal(struct inode *inode)
850 850
851 /* We are reading journal data which should not 851 /* We are reading journal data which should not
852 * be put in the uptodate cache */ 852 * be put in the uptodate cache */
853 status = ocfs2_read_blocks(OCFS2_SB(inode->i_sb), 853 status = ocfs2_read_blocks_sync(OCFS2_SB(inode->i_sb),
854 p_blkno, p_blocks, bhs, 0, 854 p_blkno, p_blocks, bhs);
855 NULL);
856 if (status < 0) { 855 if (status < 0) {
857 mlog_errno(status); 856 mlog_errno(status);
858 goto bail; 857 goto bail;
diff --git a/fs/ocfs2/resize.c b/fs/ocfs2/resize.c
index 8166968e9015..472d854796c2 100644
--- a/fs/ocfs2/resize.c
+++ b/fs/ocfs2/resize.c
@@ -200,7 +200,7 @@ static int update_backups(struct inode * inode, u32 clusters, char *data)
200 if (cluster > clusters) 200 if (cluster > clusters)
201 break; 201 break;
202 202
203 ret = ocfs2_read_block(osb, blkno, &backup, 0, NULL); 203 ret = ocfs2_read_blocks_sync(osb, blkno, 1, &backup);
204 if (ret < 0) { 204 if (ret < 0) {
205 mlog_errno(ret); 205 mlog_errno(ret);
206 break; 206 break;
@@ -236,8 +236,8 @@ static void ocfs2_update_super_and_backups(struct inode *inode,
236 * update the superblock last. 236 * update the superblock last.
237 * It doesn't matter if the write failed. 237 * It doesn't matter if the write failed.
238 */ 238 */
239 ret = ocfs2_read_block(osb, OCFS2_SUPER_BLOCK_BLKNO, 239 ret = ocfs2_read_blocks_sync(osb, OCFS2_SUPER_BLOCK_BLKNO, 1,
240 &super_bh, 0, NULL); 240 &super_bh);
241 if (ret < 0) { 241 if (ret < 0) {
242 mlog_errno(ret); 242 mlog_errno(ret);
243 goto out; 243 goto out;
@@ -540,7 +540,7 @@ int ocfs2_group_add(struct inode *inode, struct ocfs2_new_group_input *input)
540 goto out_unlock; 540 goto out_unlock;
541 } 541 }
542 542
543 ret = ocfs2_read_block(osb, input->group, &group_bh, 0, NULL); 543 ret = ocfs2_read_blocks_sync(osb, input->group, 1, &group_bh);
544 if (ret < 0) { 544 if (ret < 0) {
545 mlog(ML_ERROR, "Can't read the group descriptor # %llu " 545 mlog(ML_ERROR, "Can't read the group descriptor # %llu "
546 "from the device.", (unsigned long long)input->group); 546 "from the device.", (unsigned long long)input->group);