Blame view

fs/mpage.c 20.3 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
  /*
   * fs/mpage.c
   *
   * Copyright (C) 2002, Linus Torvalds.
   *
   * Contains functions related to preparing and submitting BIOs which contain
   * multiple pagecache pages.
   *
   * 15May2002	akpm@zip.com.au
   *		Initial version
   * 27Jun2002	axboe@suse.de
   *		use bio_add_page() to build bio's just the right size
   */
  
  #include <linux/kernel.h>
  #include <linux/module.h>
  #include <linux/mm.h>
  #include <linux/kdev_t.h>
  #include <linux/bio.h>
  #include <linux/fs.h>
  #include <linux/buffer_head.h>
  #include <linux/blkdev.h>
  #include <linux/highmem.h>
  #include <linux/prefetch.h>
  #include <linux/mpage.h>
  #include <linux/writeback.h>
  #include <linux/backing-dev.h>
  #include <linux/pagevec.h>
  
  /*
   * I/O completion handler for multipage BIOs.
   *
   * The mpage code never puts partial pages into a BIO (except for end-of-file).
   * If a page does not map to a contiguous run of blocks then it simply falls
   * back to block_read_full_page().
   *
   * Why is this?  If a page's completion depends on a number of different BIOs
   * which can complete in any order (or at the same time) then determining the
   * status of that page is hard.  See end_buffer_async_read() for the details.
   * There is no point in duplicating all that complexity.
   */
  static int mpage_end_io_read(struct bio *bio, unsigned int bytes_done, int err)
  {
  	const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
  	struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;
  
  	if (bio->bi_size)
  		return 1;
  
  	do {
  		struct page *page = bvec->bv_page;
  
  		if (--bvec >= bio->bi_io_vec)
  			prefetchw(&bvec->bv_page->flags);
  
  		if (uptodate) {
  			SetPageUptodate(page);
  		} else {
  			ClearPageUptodate(page);
  			SetPageError(page);
  		}
  		unlock_page(page);
  	} while (bvec >= bio->bi_io_vec);
  	bio_put(bio);
  	return 0;
  }
  
  static int mpage_end_io_write(struct bio *bio, unsigned int bytes_done, int err)
  {
  	const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
  	struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;
  
  	if (bio->bi_size)
  		return 1;
  
  	do {
  		struct page *page = bvec->bv_page;
  
  		if (--bvec >= bio->bi_io_vec)
  			prefetchw(&bvec->bv_page->flags);
854715be7   Qu Fuping   [PATCH] mpage_end...
81
  		if (!uptodate){
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
82
  			SetPageError(page);
854715be7   Qu Fuping   [PATCH] mpage_end...
83
84
85
  			if (page->mapping)
  				set_bit(AS_EIO, &page->mapping->flags);
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
86
87
88
89
90
  		end_page_writeback(page);
  	} while (bvec >= bio->bi_io_vec);
  	bio_put(bio);
  	return 0;
  }
75c96f858   Adrian Bunk   [PATCH] make some...
91
  static struct bio *mpage_bio_submit(int rw, struct bio *bio)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
92
93
94
95
96
97
98
99
100
101
102
  {
  	bio->bi_end_io = mpage_end_io_read;
  	if (rw == WRITE)
  		bio->bi_end_io = mpage_end_io_write;
  	submit_bio(rw, bio);
  	return NULL;
  }
  
  static struct bio *
  mpage_alloc(struct block_device *bdev,
  		sector_t first_sector, int nr_vecs,
dd0fc66fb   Al Viro   [PATCH] gfp flags...
103
  		gfp_t gfp_flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
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
152
153
154
155
156
157
158
159
160
161
162
  {
  	struct bio *bio;
  
  	bio = bio_alloc(gfp_flags, nr_vecs);
  
  	if (bio == NULL && (current->flags & PF_MEMALLOC)) {
  		while (!bio && (nr_vecs /= 2))
  			bio = bio_alloc(gfp_flags, nr_vecs);
  	}
  
  	if (bio) {
  		bio->bi_bdev = bdev;
  		bio->bi_sector = first_sector;
  	}
  	return bio;
  }
  
  /*
   * support function for mpage_readpages.  The fs supplied get_block might
   * return an up to date buffer.  This is used to map that buffer into
   * the page, which allows readpage to avoid triggering a duplicate call
   * to get_block.
   *
   * The idea is to avoid adding buffers to pages that don't already have
   * them.  So when the buffer is up to date and the page size == block size,
   * this marks the page up to date instead of adding new buffers.
   */
  static void 
  map_buffer_to_page(struct page *page, struct buffer_head *bh, int page_block) 
  {
  	struct inode *inode = page->mapping->host;
  	struct buffer_head *page_bh, *head;
  	int block = 0;
  
  	if (!page_has_buffers(page)) {
  		/*
  		 * don't make any buffers if there is only one buffer on
  		 * the page and the page just needs to be set up to date
  		 */
  		if (inode->i_blkbits == PAGE_CACHE_SHIFT && 
  		    buffer_uptodate(bh)) {
  			SetPageUptodate(page);    
  			return;
  		}
  		create_empty_buffers(page, 1 << inode->i_blkbits, 0);
  	}
  	head = page_buffers(page);
  	page_bh = head;
  	do {
  		if (block == page_block) {
  			page_bh->b_state = bh->b_state;
  			page_bh->b_bdev = bh->b_bdev;
  			page_bh->b_blocknr = bh->b_blocknr;
  			break;
  		}
  		page_bh = page_bh->b_this_page;
  		block++;
  	} while (page_bh != head);
  }
fa30bd058   Badari Pulavarty   [PATCH] map multi...
163
164
165
166
167
168
169
170
171
  /*
   * This is the worker routine which does all the work of mapping the disk
   * blocks and constructs largest possible bios, submits them for IO if the
   * blocks are not contiguous on the disk.
   *
   * We pass a buffer_head back and forth and use its buffer_mapped() flag to
   * represent the validity of its disk mapping and to decide when to do the next
   * get_block() call.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
172
173
  static struct bio *
  do_mpage_readpage(struct bio *bio, struct page *page, unsigned nr_pages,
fa30bd058   Badari Pulavarty   [PATCH] map multi...
174
175
  		sector_t *last_block_in_bio, struct buffer_head *map_bh,
  		unsigned long *first_logical_block, get_block_t get_block)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
176
177
178
179
180
181
182
  {
  	struct inode *inode = page->mapping->host;
  	const unsigned blkbits = inode->i_blkbits;
  	const unsigned blocks_per_page = PAGE_CACHE_SIZE >> blkbits;
  	const unsigned blocksize = 1 << blkbits;
  	sector_t block_in_file;
  	sector_t last_block;
fa30bd058   Badari Pulavarty   [PATCH] map multi...
183
  	sector_t last_block_in_file;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
184
185
186
187
  	sector_t blocks[MAX_BUF_PER_PAGE];
  	unsigned page_block;
  	unsigned first_hole = blocks_per_page;
  	struct block_device *bdev = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
188
189
  	int length;
  	int fully_mapped = 1;
fa30bd058   Badari Pulavarty   [PATCH] map multi...
190
191
  	unsigned nblocks;
  	unsigned relative_block;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
192
193
194
  
  	if (page_has_buffers(page))
  		goto confused;
54b21a799   Andrew Morton   [PATCH] fix possi...
195
  	block_in_file = (sector_t)page->index << (PAGE_CACHE_SHIFT - blkbits);
fa30bd058   Badari Pulavarty   [PATCH] map multi...
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
  	last_block = block_in_file + nr_pages * blocks_per_page;
  	last_block_in_file = (i_size_read(inode) + blocksize - 1) >> blkbits;
  	if (last_block > last_block_in_file)
  		last_block = last_block_in_file;
  	page_block = 0;
  
  	/*
  	 * Map blocks using the result from the previous get_blocks call first.
  	 */
  	nblocks = map_bh->b_size >> blkbits;
  	if (buffer_mapped(map_bh) && block_in_file > *first_logical_block &&
  			block_in_file < (*first_logical_block + nblocks)) {
  		unsigned map_offset = block_in_file - *first_logical_block;
  		unsigned last = nblocks - map_offset;
  
  		for (relative_block = 0; ; relative_block++) {
  			if (relative_block == last) {
  				clear_buffer_mapped(map_bh);
  				break;
  			}
  			if (page_block == blocks_per_page)
  				break;
  			blocks[page_block] = map_bh->b_blocknr + map_offset +
  						relative_block;
  			page_block++;
  			block_in_file++;
  		}
  		bdev = map_bh->b_bdev;
  	}
  
  	/*
  	 * Then do more get_blocks calls until we are done with this page.
  	 */
  	map_bh->b_page = page;
  	while (page_block < blocks_per_page) {
  		map_bh->b_state = 0;
  		map_bh->b_size = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
233

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
234
  		if (block_in_file < last_block) {
fa30bd058   Badari Pulavarty   [PATCH] map multi...
235
236
  			map_bh->b_size = (last_block-block_in_file) << blkbits;
  			if (get_block(inode, block_in_file, map_bh, 0))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
237
  				goto confused;
fa30bd058   Badari Pulavarty   [PATCH] map multi...
238
  			*first_logical_block = block_in_file;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
239
  		}
fa30bd058   Badari Pulavarty   [PATCH] map multi...
240
  		if (!buffer_mapped(map_bh)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
241
242
243
  			fully_mapped = 0;
  			if (first_hole == blocks_per_page)
  				first_hole = page_block;
fa30bd058   Badari Pulavarty   [PATCH] map multi...
244
245
246
  			page_block++;
  			block_in_file++;
  			clear_buffer_mapped(map_bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
247
248
249
250
251
252
253
254
255
  			continue;
  		}
  
  		/* some filesystems will copy data into the page during
  		 * the get_block call, in which case we don't want to
  		 * read it again.  map_buffer_to_page copies the data
  		 * we just collected from get_block into the page's buffers
  		 * so readpage doesn't have to repeat the get_block call
  		 */
fa30bd058   Badari Pulavarty   [PATCH] map multi...
256
257
  		if (buffer_uptodate(map_bh)) {
  			map_buffer_to_page(page, map_bh, page_block);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
258
259
260
261
262
263
264
  			goto confused;
  		}
  	
  		if (first_hole != blocks_per_page)
  			goto confused;		/* hole -> non-hole */
  
  		/* Contiguous blocks? */
fa30bd058   Badari Pulavarty   [PATCH] map multi...
265
  		if (page_block && blocks[page_block-1] != map_bh->b_blocknr-1)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
266
  			goto confused;
fa30bd058   Badari Pulavarty   [PATCH] map multi...
267
268
269
270
271
272
273
274
275
276
277
278
  		nblocks = map_bh->b_size >> blkbits;
  		for (relative_block = 0; ; relative_block++) {
  			if (relative_block == nblocks) {
  				clear_buffer_mapped(map_bh);
  				break;
  			} else if (page_block == blocks_per_page)
  				break;
  			blocks[page_block] = map_bh->b_blocknr+relative_block;
  			page_block++;
  			block_in_file++;
  		}
  		bdev = map_bh->b_bdev;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
279
280
281
  	}
  
  	if (first_hole != blocks_per_page) {
01f2705da   Nate Diller   fs: convert core ...
282
283
284
  		zero_user_page(page, first_hole << blkbits,
  				PAGE_CACHE_SIZE - (first_hole << blkbits),
  				KM_USER0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
  		if (first_hole == 0) {
  			SetPageUptodate(page);
  			unlock_page(page);
  			goto out;
  		}
  	} else if (fully_mapped) {
  		SetPageMappedToDisk(page);
  	}
  
  	/*
  	 * This page will go to BIO.  Do we need to send this BIO off first?
  	 */
  	if (bio && (*last_block_in_bio != blocks[0] - 1))
  		bio = mpage_bio_submit(READ, bio);
  
  alloc_new:
  	if (bio == NULL) {
  		bio = mpage_alloc(bdev, blocks[0] << (blkbits - 9),
  			  	min_t(int, nr_pages, bio_get_nr_vecs(bdev)),
  				GFP_KERNEL);
  		if (bio == NULL)
  			goto confused;
  	}
  
  	length = first_hole << blkbits;
  	if (bio_add_page(bio, page, length, 0) < length) {
  		bio = mpage_bio_submit(READ, bio);
  		goto alloc_new;
  	}
fa30bd058   Badari Pulavarty   [PATCH] map multi...
314
  	if (buffer_boundary(map_bh) || (first_hole != blocks_per_page))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
  		bio = mpage_bio_submit(READ, bio);
  	else
  		*last_block_in_bio = blocks[blocks_per_page - 1];
  out:
  	return bio;
  
  confused:
  	if (bio)
  		bio = mpage_bio_submit(READ, bio);
  	if (!PageUptodate(page))
  	        block_read_full_page(page, get_block);
  	else
  		unlock_page(page);
  	goto out;
  }
67be2dd1b   Martin Waitz   [PATCH] DocBook: ...
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
  /**
   * mpage_readpages - populate an address space with some pages, and
   *                       start reads against them.
   *
   * @mapping: the address_space
   * @pages: The address of a list_head which contains the target pages.  These
   *   pages have their ->index populated and are otherwise uninitialised.
   *
   *   The page at @pages->prev has the lowest file offset, and reads should be
   *   issued in @pages->prev to @pages->next order.
   *
   * @nr_pages: The number of pages at *@pages
   * @get_block: The filesystem's block mapper function.
   *
   * This function walks the pages and the blocks within each page, building and
   * emitting large BIOs.
   *
   * If anything unusual happens, such as:
   *
   * - encountering a page which has buffers
   * - encountering a page which has a non-hole after a hole
   * - encountering a page with non-contiguous blocks
   *
   * then this code just gives up and calls the buffer_head-based read function.
   * It does handle a page which has holes at the end - that is a common case:
   * the end-of-file on blocksize < PAGE_CACHE_SIZE setups.
   *
   * BH_Boundary explanation:
   *
   * There is a problem.  The mpage read code assembles several pages, gets all
   * their disk mappings, and then submits them all.  That's fine, but obtaining
   * the disk mappings may require I/O.  Reads of indirect blocks, for example.
   *
   * So an mpage read of the first 16 blocks of an ext2 file will cause I/O to be
   * submitted in the following order:
   * 	12 0 1 2 3 4 5 6 7 8 9 10 11 13 14 15 16
   * because the indirect block has to be read to get the mappings of blocks
   * 13,14,15,16.  Obviously, this impacts performance.
   *
   * So what we do it to allow the filesystem's get_block() function to set
   * BH_Boundary when it maps block 11.  BH_Boundary says: mapping of the block
   * after this one will require I/O against a block which is probably close to
   * this one.  So you should push what I/O you have currently accumulated.
   *
   * This all causes the disk requests to be issued in the correct order.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
376
377
378
379
380
381
382
383
  int
  mpage_readpages(struct address_space *mapping, struct list_head *pages,
  				unsigned nr_pages, get_block_t get_block)
  {
  	struct bio *bio = NULL;
  	unsigned page_idx;
  	sector_t last_block_in_bio = 0;
  	struct pagevec lru_pvec;
fa30bd058   Badari Pulavarty   [PATCH] map multi...
384
385
  	struct buffer_head map_bh;
  	unsigned long first_logical_block = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
386

fa30bd058   Badari Pulavarty   [PATCH] map multi...
387
  	clear_buffer_mapped(&map_bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
388
389
390
391
392
393
394
395
396
397
  	pagevec_init(&lru_pvec, 0);
  	for (page_idx = 0; page_idx < nr_pages; page_idx++) {
  		struct page *page = list_entry(pages->prev, struct page, lru);
  
  		prefetchw(&page->flags);
  		list_del(&page->lru);
  		if (!add_to_page_cache(page, mapping,
  					page->index, GFP_KERNEL)) {
  			bio = do_mpage_readpage(bio, page,
  					nr_pages - page_idx,
fa30bd058   Badari Pulavarty   [PATCH] map multi...
398
399
400
  					&last_block_in_bio, &map_bh,
  					&first_logical_block,
  					get_block);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
  			if (!pagevec_add(&lru_pvec, page))
  				__pagevec_lru_add(&lru_pvec);
  		} else {
  			page_cache_release(page);
  		}
  	}
  	pagevec_lru_add(&lru_pvec);
  	BUG_ON(!list_empty(pages));
  	if (bio)
  		mpage_bio_submit(READ, bio);
  	return 0;
  }
  EXPORT_SYMBOL(mpage_readpages);
  
  /*
   * This isn't called much at all
   */
  int mpage_readpage(struct page *page, get_block_t get_block)
  {
  	struct bio *bio = NULL;
  	sector_t last_block_in_bio = 0;
fa30bd058   Badari Pulavarty   [PATCH] map multi...
422
423
  	struct buffer_head map_bh;
  	unsigned long first_logical_block = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
424

fa30bd058   Badari Pulavarty   [PATCH] map multi...
425
426
427
  	clear_buffer_mapped(&map_bh);
  	bio = do_mpage_readpage(bio, page, 1, &last_block_in_bio,
  			&map_bh, &first_logical_block, get_block);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
  	if (bio)
  		mpage_bio_submit(READ, bio);
  	return 0;
  }
  EXPORT_SYMBOL(mpage_readpage);
  
  /*
   * Writing is not so simple.
   *
   * If the page has buffers then they will be used for obtaining the disk
   * mapping.  We only support pages which are fully mapped-and-dirty, with a
   * special case for pages which are unmapped at the end: end-of-file.
   *
   * If the page has no buffers (preferred) then the page is mapped here.
   *
   * If all blocks are found to be contiguous then the page can go into the
   * BIO.  Otherwise fall back to the mapping's writepage().
   * 
   * FIXME: This code wants an estimate of how many pages are still to be
   * written, so it can intelligently allocate a suitably-sized BIO.  For now,
   * just allocate full-size (16-page) BIOs.
   */
0ea971801   Miklos Szeredi   consolidate gener...
450
451
452
453
454
455
456
457
458
  struct mpage_data {
  	struct bio *bio;
  	sector_t last_block_in_bio;
  	get_block_t *get_block;
  	unsigned use_writepage;
  };
  
  static int __mpage_writepage(struct page *page, struct writeback_control *wbc,
  			     void *data)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
459
  {
0ea971801   Miklos Szeredi   consolidate gener...
460
461
  	struct mpage_data *mpd = data;
  	struct bio *bio = mpd->bio;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
  	struct address_space *mapping = page->mapping;
  	struct inode *inode = page->mapping->host;
  	const unsigned blkbits = inode->i_blkbits;
  	unsigned long end_index;
  	const unsigned blocks_per_page = PAGE_CACHE_SIZE >> blkbits;
  	sector_t last_block;
  	sector_t block_in_file;
  	sector_t blocks[MAX_BUF_PER_PAGE];
  	unsigned page_block;
  	unsigned first_unmapped = blocks_per_page;
  	struct block_device *bdev = NULL;
  	int boundary = 0;
  	sector_t boundary_block = 0;
  	struct block_device *boundary_bdev = NULL;
  	int length;
  	struct buffer_head map_bh;
  	loff_t i_size = i_size_read(inode);
0ea971801   Miklos Szeredi   consolidate gener...
479
  	int ret = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
  
  	if (page_has_buffers(page)) {
  		struct buffer_head *head = page_buffers(page);
  		struct buffer_head *bh = head;
  
  		/* If they're all mapped and dirty, do it */
  		page_block = 0;
  		do {
  			BUG_ON(buffer_locked(bh));
  			if (!buffer_mapped(bh)) {
  				/*
  				 * unmapped dirty buffers are created by
  				 * __set_page_dirty_buffers -> mmapped data
  				 */
  				if (buffer_dirty(bh))
  					goto confused;
  				if (first_unmapped == blocks_per_page)
  					first_unmapped = page_block;
  				continue;
  			}
  
  			if (first_unmapped != blocks_per_page)
  				goto confused;	/* hole -> non-hole */
  
  			if (!buffer_dirty(bh) || !buffer_uptodate(bh))
  				goto confused;
  			if (page_block) {
  				if (bh->b_blocknr != blocks[page_block-1] + 1)
  					goto confused;
  			}
  			blocks[page_block++] = bh->b_blocknr;
  			boundary = buffer_boundary(bh);
  			if (boundary) {
  				boundary_block = bh->b_blocknr;
  				boundary_bdev = bh->b_bdev;
  			}
  			bdev = bh->b_bdev;
  		} while ((bh = bh->b_this_page) != head);
  
  		if (first_unmapped)
  			goto page_is_mapped;
  
  		/*
  		 * Page has buffers, but they are all unmapped. The page was
  		 * created by pagein or read over a hole which was handled by
  		 * block_read_full_page().  If this address_space is also
  		 * using mpage_readpages then this can rarely happen.
  		 */
  		goto confused;
  	}
  
  	/*
  	 * The page has no buffers: map it to disk
  	 */
  	BUG_ON(!PageUptodate(page));
54b21a799   Andrew Morton   [PATCH] fix possi...
535
  	block_in_file = (sector_t)page->index << (PAGE_CACHE_SHIFT - blkbits);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
536
537
538
539
540
  	last_block = (i_size - 1) >> blkbits;
  	map_bh.b_page = page;
  	for (page_block = 0; page_block < blocks_per_page; ) {
  
  		map_bh.b_state = 0;
b0cf2321c   Badari Pulavarty   [PATCH] pass b_si...
541
  		map_bh.b_size = 1 << blkbits;
0ea971801   Miklos Szeredi   consolidate gener...
542
  		if (mpd->get_block(inode, block_in_file, &map_bh, 1))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
  			goto confused;
  		if (buffer_new(&map_bh))
  			unmap_underlying_metadata(map_bh.b_bdev,
  						map_bh.b_blocknr);
  		if (buffer_boundary(&map_bh)) {
  			boundary_block = map_bh.b_blocknr;
  			boundary_bdev = map_bh.b_bdev;
  		}
  		if (page_block) {
  			if (map_bh.b_blocknr != blocks[page_block-1] + 1)
  				goto confused;
  		}
  		blocks[page_block++] = map_bh.b_blocknr;
  		boundary = buffer_boundary(&map_bh);
  		bdev = map_bh.b_bdev;
  		if (block_in_file == last_block)
  			break;
  		block_in_file++;
  	}
  	BUG_ON(page_block == 0);
  
  	first_unmapped = page_block;
  
  page_is_mapped:
  	end_index = i_size >> PAGE_CACHE_SHIFT;
  	if (page->index >= end_index) {
  		/*
  		 * The page straddles i_size.  It must be zeroed out on each
  		 * and every writepage invokation because it may be mmapped.
  		 * "A file is mapped in multiples of the page size.  For a file
  		 * that is not a multiple of the page size, the remaining memory
  		 * is zeroed when mapped, and writes to that region are not
  		 * written out to the file."
  		 */
  		unsigned offset = i_size & (PAGE_CACHE_SIZE - 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
578
579
580
  
  		if (page->index > end_index || !offset)
  			goto confused;
01f2705da   Nate Diller   fs: convert core ...
581
582
  		zero_user_page(page, offset, PAGE_CACHE_SIZE - offset,
  				KM_USER0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
583
584
585
586
587
  	}
  
  	/*
  	 * This page will go to BIO.  Do we need to send this BIO off first?
  	 */
0ea971801   Miklos Szeredi   consolidate gener...
588
  	if (bio && mpd->last_block_in_bio != blocks[0] - 1)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
  		bio = mpage_bio_submit(WRITE, bio);
  
  alloc_new:
  	if (bio == NULL) {
  		bio = mpage_alloc(bdev, blocks[0] << (blkbits - 9),
  				bio_get_nr_vecs(bdev), GFP_NOFS|__GFP_HIGH);
  		if (bio == NULL)
  			goto confused;
  	}
  
  	/*
  	 * Must try to add the page before marking the buffer clean or
  	 * the confused fail path above (OOM) will be very confused when
  	 * it finds all bh marked clean (i.e. it will not write anything)
  	 */
  	length = first_unmapped << blkbits;
  	if (bio_add_page(bio, page, length, 0) < length) {
  		bio = mpage_bio_submit(WRITE, bio);
  		goto alloc_new;
  	}
  
  	/*
  	 * OK, we have our BIO, so we can now mark the buffers clean.  Make
  	 * sure to only clean buffers which we know we'll be writing.
  	 */
  	if (page_has_buffers(page)) {
  		struct buffer_head *head = page_buffers(page);
  		struct buffer_head *bh = head;
  		unsigned buffer_counter = 0;
  
  		do {
  			if (buffer_counter++ == first_unmapped)
  				break;
  			clear_buffer_dirty(bh);
  			bh = bh->b_this_page;
  		} while (bh != head);
  
  		/*
  		 * we cannot drop the bh if the page is not uptodate
  		 * or a concurrent readpage would fail to serialize with the bh
  		 * and it would read from disk before we reach the platter.
  		 */
  		if (buffer_heads_over_limit && PageUptodate(page))
  			try_to_free_buffers(page);
  	}
  
  	BUG_ON(PageWriteback(page));
  	set_page_writeback(page);
  	unlock_page(page);
  	if (boundary || (first_unmapped != blocks_per_page)) {
  		bio = mpage_bio_submit(WRITE, bio);
  		if (boundary_block) {
  			write_boundary_block(boundary_bdev,
  					boundary_block, 1 << blkbits);
  		}
  	} else {
0ea971801   Miklos Szeredi   consolidate gener...
645
  		mpd->last_block_in_bio = blocks[blocks_per_page - 1];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
646
647
648
649
650
651
  	}
  	goto out;
  
  confused:
  	if (bio)
  		bio = mpage_bio_submit(WRITE, bio);
0ea971801   Miklos Szeredi   consolidate gener...
652
653
  	if (mpd->use_writepage) {
  		ret = mapping->a_ops->writepage(page, wbc);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
654
  	} else {
0ea971801   Miklos Szeredi   consolidate gener...
655
  		ret = -EAGAIN;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
656
657
658
659
660
  		goto out;
  	}
  	/*
  	 * The caller has a ref on the inode, so *mapping is stable
  	 */
0ea971801   Miklos Szeredi   consolidate gener...
661
  	mapping_set_error(mapping, ret);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
662
  out:
0ea971801   Miklos Szeredi   consolidate gener...
663
664
  	mpd->bio = bio;
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
  }
  
  /**
   * mpage_writepages - walk the list of dirty pages of the given
   * address space and writepage() all of them.
   * 
   * @mapping: address space structure to write
   * @wbc: subtract the number of written pages from *@wbc->nr_to_write
   * @get_block: the filesystem's block mapper function.
   *             If this is NULL then use a_ops->writepage.  Otherwise, go
   *             direct-to-BIO.
   *
   * This is a library function, which implements the writepages()
   * address_space_operation.
   *
   * If a page is already under I/O, generic_writepages() skips it, even
   * if it's dirty.  This is desirable behaviour for memory-cleaning writeback,
   * but it is INCORRECT for data-integrity system calls such as fsync().  fsync()
   * and msync() need to guarantee that all the data which was dirty at the time
   * the call was made get new I/O started against them.  If wbc->sync_mode is
   * WB_SYNC_ALL then we were called for data integrity and we must wait for
   * existing IO to complete.
   */
  int
  mpage_writepages(struct address_space *mapping,
  		struct writeback_control *wbc, get_block_t get_block)
  {
0ea971801   Miklos Szeredi   consolidate gener...
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
  	int ret;
  
  	if (!get_block)
  		ret = generic_writepages(mapping, wbc);
  	else {
  		struct mpage_data mpd = {
  			.bio = NULL,
  			.last_block_in_bio = 0,
  			.get_block = get_block,
  			.use_writepage = 1,
  		};
  
  		ret = write_cache_pages(mapping, wbc, __mpage_writepage, &mpd);
  		if (mpd.bio)
  			mpage_bio_submit(WRITE, mpd.bio);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
707
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
708
709
710
  	return ret;
  }
  EXPORT_SYMBOL(mpage_writepages);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
711
712
713
714
  
  int mpage_writepage(struct page *page, get_block_t get_block,
  	struct writeback_control *wbc)
  {
0ea971801   Miklos Szeredi   consolidate gener...
715
716
717
718
719
720
721
722
723
  	struct mpage_data mpd = {
  		.bio = NULL,
  		.last_block_in_bio = 0,
  		.get_block = get_block,
  		.use_writepage = 0,
  	};
  	int ret = __mpage_writepage(page, wbc, &mpd);
  	if (mpd.bio)
  		mpage_bio_submit(WRITE, mpd.bio);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
724
725
726
  	return ret;
  }
  EXPORT_SYMBOL(mpage_writepage);