aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ocfs2')
-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);