1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#include <linux/fs.h>
27#include <linux/types.h>
28#include <linux/slab.h>
29#include <linux/highmem.h>
30
31#include <cluster/masklog.h>
32
33#include "ocfs2.h"
34
35#include "alloc.h"
36#include "inode.h"
37#include "journal.h"
38#include "uptodate.h"
39
40#include "buffer_head_io.h"
41
42int ocfs2_write_block(struct ocfs2_super *osb, struct buffer_head *bh,
43 struct inode *inode)
44{
45 int ret = 0;
46
47 mlog_entry("(bh->b_blocknr = %llu, inode=%p)\n",
48 (unsigned long long)bh->b_blocknr, inode);
49
50 BUG_ON(bh->b_blocknr < OCFS2_SUPER_BLOCK_BLKNO);
51 BUG_ON(buffer_jbd(bh));
52
53
54
55
56 if (ocfs2_is_hard_readonly(osb)) {
57 ret = -EROFS;
58 goto out;
59 }
60
61 mutex_lock(&OCFS2_I(inode)->ip_io_mutex);
62
63 lock_buffer(bh);
64 set_buffer_uptodate(bh);
65
66
67 clear_buffer_dirty(bh);
68
69 get_bh(bh);
70 bh->b_end_io = end_buffer_write_sync;
71 submit_bh(WRITE, bh);
72
73 wait_on_buffer(bh);
74
75 if (buffer_uptodate(bh)) {
76 ocfs2_set_buffer_uptodate(inode, bh);
77 } else {
78
79
80
81 ret = -EIO;
82 put_bh(bh);
83 }
84
85 mutex_unlock(&OCFS2_I(inode)->ip_io_mutex);
86out:
87 mlog_exit(ret);
88 return ret;
89}
90
91int ocfs2_read_blocks(struct ocfs2_super *osb, u64 block, int nr,
92 struct buffer_head *bhs[], int flags,
93 struct inode *inode)
94{
95 int status = 0;
96 struct super_block *sb;
97 int i, ignore_cache = 0;
98 struct buffer_head *bh;
99
100 mlog_entry("(block=(%llu), nr=(%d), flags=%d, inode=%p)\n",
101 (unsigned long long)block, nr, flags, inode);
102
103 BUG_ON((flags & OCFS2_BH_READAHEAD) &&
104 (!inode || !(flags & OCFS2_BH_CACHED)));
105
106 if (osb == NULL || osb->sb == NULL || bhs == NULL) {
107 status = -EINVAL;
108 mlog_errno(status);
109 goto bail;
110 }
111
112 if (nr < 0) {
113 mlog(ML_ERROR, "asked to read %d blocks!\n", nr);
114 status = -EINVAL;
115 mlog_errno(status);
116 goto bail;
117 }
118
119 if (nr == 0) {
120 mlog(ML_BH_IO, "No buffers will be read!\n");
121 status = 0;
122 goto bail;
123 }
124
125 sb = osb->sb;
126
127 if (flags & OCFS2_BH_CACHED && !inode)
128 flags &= ~OCFS2_BH_CACHED;
129
130 if (inode)
131 mutex_lock(&OCFS2_I(inode)->ip_io_mutex);
132 for (i = 0 ; i < nr ; i++) {
133 if (bhs[i] == NULL) {
134 bhs[i] = sb_getblk(sb, block++);
135 if (bhs[i] == NULL) {
136 if (inode)
137 mutex_unlock(&OCFS2_I(inode)->ip_io_mutex);
138 status = -EIO;
139 mlog_errno(status);
140 goto bail;
141 }
142 }
143 bh = bhs[i];
144 ignore_cache = 0;
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170 if (flags & OCFS2_BH_CACHED &&
171 !ocfs2_buffer_uptodate(inode, bh)) {
172 mlog(ML_UPTODATE,
173 "bh (%llu), inode %llu not uptodate\n",
174 (unsigned long long)bh->b_blocknr,
175 (unsigned long long)OCFS2_I(inode)->ip_blkno);
176 ignore_cache = 1;
177 }
178
179
180
181 if (buffer_jbd(bh)) {
182 if (!(flags & OCFS2_BH_CACHED) || ignore_cache)
183 mlog(ML_BH_IO, "trying to sync read a jbd "
184 "managed bh (blocknr = %llu)\n",
185 (unsigned long long)bh->b_blocknr);
186 continue;
187 }
188
189 if (!(flags & OCFS2_BH_CACHED) || ignore_cache) {
190 if (buffer_dirty(bh)) {
191
192
193 mlog(ML_BH_IO, "asking me to sync read a dirty "
194 "buffer! (blocknr = %llu)\n",
195 (unsigned long long)bh->b_blocknr);
196 continue;
197 }
198
199
200
201
202
203 if ((flags & OCFS2_BH_READAHEAD)
204 && ocfs2_buffer_read_ahead(inode, bh))
205 continue;
206
207 lock_buffer(bh);
208 if (buffer_jbd(bh)) {
209#ifdef CATCH_BH_JBD_RACES
210 mlog(ML_ERROR, "block %llu had the JBD bit set "
211 "while I was in lock_buffer!",
212 (unsigned long long)bh->b_blocknr);
213 BUG();
214#else
215 unlock_buffer(bh);
216 continue;
217#endif
218 }
219
220
221
222
223
224 if ((flags & OCFS2_BH_CACHED)
225 && !(flags & OCFS2_BH_READAHEAD)
226 && ocfs2_buffer_uptodate(inode, bh)) {
227 unlock_buffer(bh);
228 continue;
229 }
230
231 clear_buffer_uptodate(bh);
232 get_bh(bh);
233 bh->b_end_io = end_buffer_read_sync;
234 submit_bh(READ, bh);
235 continue;
236 }
237 }
238
239 status = 0;
240
241 for (i = (nr - 1); i >= 0; i--) {
242 bh = bhs[i];
243
244 if (!(flags & OCFS2_BH_READAHEAD)) {
245
246
247
248 if (!buffer_jbd(bh))
249 wait_on_buffer(bh);
250
251 if (!buffer_uptodate(bh)) {
252
253
254
255
256
257
258 status = -EIO;
259 put_bh(bh);
260 bhs[i] = NULL;
261 continue;
262 }
263 }
264
265
266
267
268 if (inode)
269 ocfs2_set_buffer_uptodate(inode, bh);
270 }
271 if (inode)
272 mutex_unlock(&OCFS2_I(inode)->ip_io_mutex);
273
274 mlog(ML_BH_IO, "block=(%llu), nr=(%d), cached=%s, flags=0x%x\n",
275 (unsigned long long)block, nr,
276 (!(flags & OCFS2_BH_CACHED) || ignore_cache) ? "no" : "yes", flags);
277
278bail:
279
280 mlog_exit(status);
281 return status;
282}
283
284
285static void ocfs2_check_super_or_backup(struct super_block *sb,
286 sector_t blkno)
287{
288 int i;
289 u64 backup_blkno;
290
291 if (blkno == OCFS2_SUPER_BLOCK_BLKNO)
292 return;
293
294 for (i = 0; i < OCFS2_MAX_BACKUP_SUPERBLOCKS; i++) {
295 backup_blkno = ocfs2_backup_super_blkno(sb, i);
296 if (backup_blkno == blkno)
297 return;
298 }
299
300 BUG();
301}
302
303
304
305
306
307
308int ocfs2_write_super_or_backup(struct ocfs2_super *osb,
309 struct buffer_head *bh)
310{
311 int ret = 0;
312
313 mlog_entry_void();
314
315 BUG_ON(buffer_jbd(bh));
316 ocfs2_check_super_or_backup(osb->sb, bh->b_blocknr);
317
318 if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb)) {
319 ret = -EROFS;
320 goto out;
321 }
322
323 lock_buffer(bh);
324 set_buffer_uptodate(bh);
325
326
327 clear_buffer_dirty(bh);
328
329 get_bh(bh);
330 bh->b_end_io = end_buffer_write_sync;
331 submit_bh(WRITE, bh);
332
333 wait_on_buffer(bh);
334
335 if (!buffer_uptodate(bh)) {
336 ret = -EIO;
337 put_bh(bh);
338 }
339
340out:
341 mlog_exit(ret);
342 return ret;
343}
344