diff options
-rw-r--r-- | fs/ocfs2/buffer_head_io.c | 84 | ||||
-rw-r--r-- | fs/ocfs2/buffer_head_io.h | 2 | ||||
-rw-r--r-- | fs/ocfs2/inode.c | 7 | ||||
-rw-r--r-- | fs/ocfs2/journal.c | 5 | ||||
-rw-r--r-- | fs/ocfs2/resize.c | 8 |
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 | ||
91 | int 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 | |||
169 | bail: | ||
170 | return status; | ||
171 | } | ||
172 | |||
91 | int ocfs2_read_blocks(struct ocfs2_super *osb, u64 block, int nr, | 173 | int 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); |
49 | int ocfs2_read_blocks_sync(struct ocfs2_super *osb, u64 block, | ||
50 | unsigned int nr, struct buffer_head *bhs[]); | ||
49 | 51 | ||
50 | int ocfs2_write_super_or_backup(struct ocfs2_super *osb, | 52 | int 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); |