Blame view

fs/ocfs2/buffer_head_io.c 10.4 KB
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
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
27
  /* -*- mode: c; c-basic-offset: 8; -*-
   * vim: noexpandtab sw=8 ts=8 sts=0:
   *
   * io.c
   *
   * Buffer cache handling
   *
   * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public
   * License as published by the Free Software Foundation; either
   * version 2 of the License, or (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * General Public License for more details.
   *
   * You should have received a copy of the GNU General Public
   * License along with this program; if not, write to the
   * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   * Boston, MA 021110-1307, USA.
   */
  
  #include <linux/fs.h>
  #include <linux/types.h>
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
28
29
30
31
32
33
34
35
36
37
  #include <linux/highmem.h>
  
  #include <cluster/masklog.h>
  
  #include "ocfs2.h"
  
  #include "alloc.h"
  #include "inode.h"
  #include "journal.h"
  #include "uptodate.h"
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
38
  #include "buffer_head_io.h"
15057e981   Tao Ma   ocfs2: Remove mas...
39
  #include "ocfs2_trace.h"
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
40

970e4936d   Joel Becker   ocfs2: Validate m...
41
42
43
  /*
   * Bits on bh->b_state used by ocfs2.
   *
b86c86fa1   Mark Fasheh   ocfs2: Use BH_JBD...
44
   * These MUST be after the JBD2 bits.  Hence, we use BH_JBDPrivateStart.
970e4936d   Joel Becker   ocfs2: Validate m...
45
46
   */
  enum ocfs2_state_bits {
b86c86fa1   Mark Fasheh   ocfs2: Use BH_JBD...
47
  	BH_NeedsValidate = BH_JBDPrivateStart,
970e4936d   Joel Becker   ocfs2: Validate m...
48
49
50
51
  };
  
  /* Expand the magic b_state functions */
  BUFFER_FNS(NeedsValidate, needs_validate);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
52
  int ocfs2_write_block(struct ocfs2_super *osb, struct buffer_head *bh,
8cb471e8f   Joel Becker   ocfs2: Take the i...
53
  		      struct ocfs2_caching_info *ci)
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
54
55
  {
  	int ret = 0;
15057e981   Tao Ma   ocfs2: Remove mas...
56
  	trace_ocfs2_write_block((unsigned long long)bh->b_blocknr, ci);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
57
58
59
60
61
62
63
64
65
  
  	BUG_ON(bh->b_blocknr < OCFS2_SUPER_BLOCK_BLKNO);
  	BUG_ON(buffer_jbd(bh));
  
  	/* No need to check for a soft readonly file system here. non
  	 * journalled writes are only ever done on system files which
  	 * can get modified during recovery even if read-only. */
  	if (ocfs2_is_hard_readonly(osb)) {
  		ret = -EROFS;
c1e8d35ef   Tao Ma   ocfs2: Remove EXI...
66
  		mlog_errno(ret);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
67
68
  		goto out;
  	}
8cb471e8f   Joel Becker   ocfs2: Take the i...
69
  	ocfs2_metadata_cache_io_lock(ci);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
70
71
72
73
74
75
  
  	lock_buffer(bh);
  	set_buffer_uptodate(bh);
  
  	/* remove from dirty list before I/O. */
  	clear_buffer_dirty(bh);
da1e90985   Joel Becker   ocfs2: Separate o...
76
  	get_bh(bh); /* for end_buffer_write_sync() */
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
77
78
79
80
81
82
  	bh->b_end_io = end_buffer_write_sync;
  	submit_bh(WRITE, bh);
  
  	wait_on_buffer(bh);
  
  	if (buffer_uptodate(bh)) {
8cb471e8f   Joel Becker   ocfs2: Take the i...
83
  		ocfs2_set_buffer_uptodate(ci, bh);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
84
85
86
87
88
  	} else {
  		/* We don't need to remove the clustered uptodate
  		 * information for this bh as it's not marked locally
  		 * uptodate. */
  		ret = -EIO;
2fe5c1d7e   Mark Fasheh   ocfs2: clean up b...
89
  		put_bh(bh);
c1e8d35ef   Tao Ma   ocfs2: Remove EXI...
90
  		mlog_errno(ret);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
91
  	}
8cb471e8f   Joel Becker   ocfs2: Take the i...
92
  	ocfs2_metadata_cache_io_unlock(ci);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
93
  out:
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
94
95
  	return ret;
  }
da1e90985   Joel Becker   ocfs2: Separate o...
96
97
98
99
100
101
  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;
15057e981   Tao Ma   ocfs2: Remove mas...
102
103
104
  	trace_ocfs2_read_blocks_sync((unsigned long long)block, nr);
  
  	if (!nr)
da1e90985   Joel Becker   ocfs2: Separate o...
105
  		goto bail;
da1e90985   Joel Becker   ocfs2: Separate o...
106
107
108
109
110
111
112
113
114
115
116
117
118
  
  	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)) {
15057e981   Tao Ma   ocfs2: Remove mas...
119
120
  			trace_ocfs2_read_blocks_sync_jbd(
  					(unsigned long long)bh->b_blocknr);
da1e90985   Joel Becker   ocfs2: Separate o...
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
  			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
  ",
  			     (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];
d6b58f89f   Mark Fasheh   ocfs2: fix regres...
152
153
154
  		/* No need to wait on the buffer if it's managed by JBD. */
  		if (!buffer_jbd(bh))
  			wait_on_buffer(bh);
da1e90985   Joel Becker   ocfs2: Separate o...
155

da1e90985   Joel Becker   ocfs2: Separate o...
156
157
158
159
160
161
162
163
164
165
166
167
168
  		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;
  }
8cb471e8f   Joel Becker   ocfs2: Take the i...
169
  int ocfs2_read_blocks(struct ocfs2_caching_info *ci, u64 block, int nr,
970e4936d   Joel Becker   ocfs2: Validate m...
170
171
172
  		      struct buffer_head *bhs[], int flags,
  		      int (*validate)(struct super_block *sb,
  				      struct buffer_head *bh))
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
173
174
  {
  	int status = 0;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
175
176
  	int i, ignore_cache = 0;
  	struct buffer_head *bh;
8cb471e8f   Joel Becker   ocfs2: Take the i...
177
  	struct super_block *sb = ocfs2_metadata_cache_get_super(ci);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
178

15057e981   Tao Ma   ocfs2: Remove mas...
179
  	trace_ocfs2_read_blocks_begin(ci, (unsigned long long)block, nr, flags);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
180

8cb471e8f   Joel Becker   ocfs2: Take the i...
181
  	BUG_ON(!ci);
d4a8c93c8   Joel Becker   ocfs2: Make cache...
182
183
  	BUG_ON((flags & OCFS2_BH_READAHEAD) &&
  	       (flags & OCFS2_BH_IGNORE_CACHE));
aa9588741   Mark Fasheh   ocfs2: implement ...
184

31d33073c   Joel Becker   ocfs2: Require an...
185
  	if (bhs == NULL) {
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
186
187
188
189
190
191
192
193
194
195
196
197
198
199
  		status = -EINVAL;
  		mlog_errno(status);
  		goto bail;
  	}
  
  	if (nr < 0) {
  		mlog(ML_ERROR, "asked to read %d blocks!
  ", nr);
  		status = -EINVAL;
  		mlog_errno(status);
  		goto bail;
  	}
  
  	if (nr == 0) {
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
200
201
202
  		status = 0;
  		goto bail;
  	}
8cb471e8f   Joel Becker   ocfs2: Take the i...
203
  	ocfs2_metadata_cache_io_lock(ci);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
204
205
  	for (i = 0 ; i < nr ; i++) {
  		if (bhs[i] == NULL) {
8cb471e8f   Joel Becker   ocfs2: Take the i...
206
  			bhs[i] = sb_getblk(sb, block++);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
207
  			if (bhs[i] == NULL) {
8cb471e8f   Joel Becker   ocfs2: Take the i...
208
  				ocfs2_metadata_cache_io_unlock(ci);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
209
210
211
212
213
214
  				status = -EIO;
  				mlog_errno(status);
  				goto bail;
  			}
  		}
  		bh = bhs[i];
d4a8c93c8   Joel Becker   ocfs2: Make cache...
215
  		ignore_cache = (flags & OCFS2_BH_IGNORE_CACHE);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
216

aa9588741   Mark Fasheh   ocfs2: implement ...
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
  		/* There are three read-ahead cases here which we need to
  		 * be concerned with. All three assume a buffer has
  		 * previously been submitted with OCFS2_BH_READAHEAD
  		 * and it hasn't yet completed I/O.
  		 *
  		 * 1) The current request is sync to disk. This rarely
  		 *    happens these days, and never when performance
  		 *    matters - the code can just wait on the buffer
  		 *    lock and re-submit.
  		 *
  		 * 2) The current request is cached, but not
  		 *    readahead. ocfs2_buffer_uptodate() will return
  		 *    false anyway, so we'll wind up waiting on the
  		 *    buffer lock to do I/O. We re-check the request
  		 *    with after getting the lock to avoid a re-submit.
  		 *
  		 * 3) The current request is readahead (and so must
  		 *    also be a caching one). We short circuit if the
  		 *    buffer is locked (under I/O) and if it's in the
  		 *    uptodate cache. The re-check from #2 catches the
  		 *    case that the previous read-ahead completes just
  		 *    before our is-it-in-flight check.
  		 */
8cb471e8f   Joel Becker   ocfs2: Take the i...
240
  		if (!ignore_cache && !ocfs2_buffer_uptodate(ci, bh)) {
d701485a6   Tao Ma   ocfs2: Remove mas...
241
  			trace_ocfs2_read_blocks_from_disk(
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
242
  			     (unsigned long long)bh->b_blocknr,
8cb471e8f   Joel Becker   ocfs2: Take the i...
243
  			     (unsigned long long)ocfs2_metadata_cache_owner(ci));
d4a8c93c8   Joel Becker   ocfs2: Make cache...
244
245
  			/* We're using ignore_cache here to say
  			 * "go to disk" */
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
246
247
  			ignore_cache = 1;
  		}
15057e981   Tao Ma   ocfs2: Remove mas...
248
249
  		trace_ocfs2_read_blocks_bh((unsigned long long)bh->b_blocknr,
  			ignore_cache, buffer_jbd(bh), buffer_dirty(bh));
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
250
  		if (buffer_jbd(bh)) {
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
251
252
  			continue;
  		}
d4a8c93c8   Joel Becker   ocfs2: Make cache...
253
  		if (ignore_cache) {
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
254
255
256
  			if (buffer_dirty(bh)) {
  				/* This should probably be a BUG, or
  				 * at least return an error. */
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
257
258
  				continue;
  			}
aa9588741   Mark Fasheh   ocfs2: implement ...
259
260
261
262
263
  			/* A read-ahead request was made - if the
  			 * buffer is already under read-ahead from a
  			 * previously submitted request than we are
  			 * done here. */
  			if ((flags & OCFS2_BH_READAHEAD)
8cb471e8f   Joel Becker   ocfs2: Take the i...
264
  			    && ocfs2_buffer_read_ahead(ci, bh))
aa9588741   Mark Fasheh   ocfs2: implement ...
265
  				continue;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
266
267
268
269
270
271
272
273
274
275
276
277
  			lock_buffer(bh);
  			if (buffer_jbd(bh)) {
  #ifdef CATCH_BH_JBD_RACES
  				mlog(ML_ERROR, "block %llu had the JBD bit set "
  					       "while I was in lock_buffer!",
  				     (unsigned long long)bh->b_blocknr);
  				BUG();
  #else
  				unlock_buffer(bh);
  				continue;
  #endif
  			}
aa9588741   Mark Fasheh   ocfs2: implement ...
278
279
280
281
282
  
  			/* Re-check ocfs2_buffer_uptodate() as a
  			 * previously read-ahead buffer may have
  			 * completed I/O while we were waiting for the
  			 * buffer lock. */
d4a8c93c8   Joel Becker   ocfs2: Make cache...
283
  			if (!(flags & OCFS2_BH_IGNORE_CACHE)
aa9588741   Mark Fasheh   ocfs2: implement ...
284
  			    && !(flags & OCFS2_BH_READAHEAD)
8cb471e8f   Joel Becker   ocfs2: Take the i...
285
  			    && ocfs2_buffer_uptodate(ci, bh)) {
aa9588741   Mark Fasheh   ocfs2: implement ...
286
287
288
  				unlock_buffer(bh);
  				continue;
  			}
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
289
290
  			clear_buffer_uptodate(bh);
  			get_bh(bh); /* for end_buffer_read_sync() */
970e4936d   Joel Becker   ocfs2: Validate m...
291
292
  			if (validate)
  				set_buffer_needs_validate(bh);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
293
  			bh->b_end_io = end_buffer_read_sync;
aa9588741   Mark Fasheh   ocfs2: implement ...
294
  			submit_bh(READ, bh);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
295
296
297
298
299
300
301
302
  			continue;
  		}
  	}
  
  	status = 0;
  
  	for (i = (nr - 1); i >= 0; i--) {
  		bh = bhs[i];
aa9588741   Mark Fasheh   ocfs2: implement ...
303
304
  		if (!(flags & OCFS2_BH_READAHEAD)) {
  			/* We know this can't have changed as we hold the
8cb471e8f   Joel Becker   ocfs2: Take the i...
305
  			 * owner sem. Avoid doing any work on the bh if the
aa9588741   Mark Fasheh   ocfs2: implement ...
306
307
308
309
310
311
312
313
314
315
316
317
  			 * journal has it. */
  			if (!buffer_jbd(bh))
  				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. Don't need to
  				 * remove the clustered uptodate information
  				 * for this bh as it's not marked locally
  				 * uptodate. */
  				status = -EIO;
2fe5c1d7e   Mark Fasheh   ocfs2: clean up b...
318
  				put_bh(bh);
aa9588741   Mark Fasheh   ocfs2: implement ...
319
320
321
  				bhs[i] = NULL;
  				continue;
  			}
970e4936d   Joel Becker   ocfs2: Validate m...
322
323
324
325
326
327
328
  
  			if (buffer_needs_validate(bh)) {
  				/* We never set NeedsValidate if the
  				 * buffer was held by the journal, so
  				 * that better not have changed */
  				BUG_ON(buffer_jbd(bh));
  				clear_buffer_needs_validate(bh);
8cb471e8f   Joel Becker   ocfs2: Take the i...
329
  				status = validate(sb, bh);
970e4936d   Joel Becker   ocfs2: Validate m...
330
331
332
333
334
335
  				if (status) {
  					put_bh(bh);
  					bhs[i] = NULL;
  					continue;
  				}
  			}
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
336
  		}
aa9588741   Mark Fasheh   ocfs2: implement ...
337
338
339
  		/* Always set the buffer in the cache, even if it was
  		 * a forced read, or read-ahead which hasn't yet
  		 * completed. */
8cb471e8f   Joel Becker   ocfs2: Take the i...
340
  		ocfs2_set_buffer_uptodate(ci, bh);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
341
  	}
8cb471e8f   Joel Becker   ocfs2: Take the i...
342
  	ocfs2_metadata_cache_io_unlock(ci);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
343

15057e981   Tao Ma   ocfs2: Remove mas...
344
345
  	trace_ocfs2_read_blocks_end((unsigned long long)block, nr,
  				    flags, ignore_cache);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
346
347
  
  bail:
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
348
349
  	return status;
  }
d659072f7   Tao Ma   [PATCH 1/2] ocfs2...
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
  
  /* Check whether the blkno is the super block or one of the backups. */
  static void ocfs2_check_super_or_backup(struct super_block *sb,
  					sector_t blkno)
  {
  	int i;
  	u64 backup_blkno;
  
  	if (blkno == OCFS2_SUPER_BLOCK_BLKNO)
  		return;
  
  	for (i = 0; i < OCFS2_MAX_BACKUP_SUPERBLOCKS; i++) {
  		backup_blkno = ocfs2_backup_super_blkno(sb, i);
  		if (backup_blkno == blkno)
  			return;
  	}
  
  	BUG();
  }
  
  /*
   * Write super block and backups doesn't need to collaborate with journal,
8cb471e8f   Joel Becker   ocfs2: Take the i...
372
   * so we don't need to lock ip_io_mutex and ci doesn't need to bea passed
d659072f7   Tao Ma   [PATCH 1/2] ocfs2...
373
374
375
376
377
378
   * into this function.
   */
  int ocfs2_write_super_or_backup(struct ocfs2_super *osb,
  				struct buffer_head *bh)
  {
  	int ret = 0;
a42ab8e1a   Joel Becker   ocfs2: Compute me...
379
  	struct ocfs2_dinode *di = (struct ocfs2_dinode *)bh->b_data;
d659072f7   Tao Ma   [PATCH 1/2] ocfs2...
380

d659072f7   Tao Ma   [PATCH 1/2] ocfs2...
381
382
383
384
385
  	BUG_ON(buffer_jbd(bh));
  	ocfs2_check_super_or_backup(osb->sb, bh->b_blocknr);
  
  	if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb)) {
  		ret = -EROFS;
c1e8d35ef   Tao Ma   ocfs2: Remove EXI...
386
  		mlog_errno(ret);
d659072f7   Tao Ma   [PATCH 1/2] ocfs2...
387
388
389
390
391
392
393
394
395
396
397
  		goto out;
  	}
  
  	lock_buffer(bh);
  	set_buffer_uptodate(bh);
  
  	/* remove from dirty list before I/O. */
  	clear_buffer_dirty(bh);
  
  	get_bh(bh); /* for end_buffer_write_sync() */
  	bh->b_end_io = end_buffer_write_sync;
a42ab8e1a   Joel Becker   ocfs2: Compute me...
398
  	ocfs2_compute_meta_ecc(osb->sb, bh->b_data, &di->i_check);
d659072f7   Tao Ma   [PATCH 1/2] ocfs2...
399
400
401
402
403
404
  	submit_bh(WRITE, bh);
  
  	wait_on_buffer(bh);
  
  	if (!buffer_uptodate(bh)) {
  		ret = -EIO;
2fe5c1d7e   Mark Fasheh   ocfs2: clean up b...
405
  		put_bh(bh);
c1e8d35ef   Tao Ma   ocfs2: Remove EXI...
406
  		mlog_errno(ret);
d659072f7   Tao Ma   [PATCH 1/2] ocfs2...
407
408
409
  	}
  
  out:
d659072f7   Tao Ma   [PATCH 1/2] ocfs2...
410
411
  	return ret;
  }