aboutsummaryrefslogtreecommitdiffstats
path: root/mm/migrate.c
diff options
context:
space:
mode:
authorChristoph Lameter <clameter@sgi.com>2006-06-23 05:03:33 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-23 10:42:50 -0400
commit8351a6e4785218a2b03c142be92926baff95ba5c (patch)
tree479fe6bcecb38ddc2c34ec812d82e432a79d0dfa /mm/migrate.c
parent2d1db3b1170db4e8bf0531dd636742269c2cf579 (diff)
[PATCH] page migration cleanup: move fallback handling into special function
Move the fallback code into a new fallback function and make the function behave like any other migration function. This requires retaking the lock if pageout() drops it. Signed-off-by: Christoph Lameter <clameter@sgi.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'mm/migrate.c')
-rw-r--r--mm/migrate.c90
1 files changed, 39 insertions, 51 deletions
diff --git a/mm/migrate.c b/mm/migrate.c
index f65e69d94527..5a340f4ca212 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -349,6 +349,42 @@ int buffer_migrate_page(struct address_space *mapping,
349} 349}
350EXPORT_SYMBOL(buffer_migrate_page); 350EXPORT_SYMBOL(buffer_migrate_page);
351 351
352static int fallback_migrate_page(struct address_space *mapping,
353 struct page *newpage, struct page *page)
354{
355 /*
356 * Default handling if a filesystem does not provide
357 * a migration function. We can only migrate clean
358 * pages so try to write out any dirty pages first.
359 */
360 if (PageDirty(page)) {
361 switch (pageout(page, mapping)) {
362 case PAGE_KEEP:
363 case PAGE_ACTIVATE:
364 return -EAGAIN;
365
366 case PAGE_SUCCESS:
367 /* Relock since we lost the lock */
368 lock_page(page);
369 /* Must retry since page state may have changed */
370 return -EAGAIN;
371
372 case PAGE_CLEAN:
373 ; /* try to migrate the page below */
374 }
375 }
376
377 /*
378 * Buffers may be managed in a filesystem specific way.
379 * We must have no buffers or drop them.
380 */
381 if (page_has_buffers(page) &&
382 !try_to_release_page(page, GFP_KERNEL))
383 return -EAGAIN;
384
385 return migrate_page(mapping, newpage, page);
386}
387
352/* 388/*
353 * migrate_pages 389 * migrate_pages
354 * 390 *
@@ -478,7 +514,7 @@ redo:
478 if (!mapping) 514 if (!mapping)
479 goto unlock_both; 515 goto unlock_both;
480 516
481 if (mapping->a_ops->migratepage) { 517 if (mapping->a_ops->migratepage)
482 /* 518 /*
483 * Most pages have a mapping and most filesystems 519 * Most pages have a mapping and most filesystems
484 * should provide a migration function. Anonymous 520 * should provide a migration function. Anonymous
@@ -488,56 +524,8 @@ redo:
488 */ 524 */
489 rc = mapping->a_ops->migratepage(mapping, 525 rc = mapping->a_ops->migratepage(mapping,
490 newpage, page); 526 newpage, page);
491 goto unlock_both; 527 else
492 } 528 rc = fallback_migrate_page(mapping, newpage, page);
493
494 /*
495 * Default handling if a filesystem does not provide
496 * a migration function. We can only migrate clean
497 * pages so try to write out any dirty pages first.
498 */
499 if (PageDirty(page)) {
500 switch (pageout(page, mapping)) {
501 case PAGE_KEEP:
502 case PAGE_ACTIVATE:
503 goto unlock_both;
504
505 case PAGE_SUCCESS:
506 unlock_page(newpage);
507 goto next;
508
509 case PAGE_CLEAN:
510 ; /* try to migrate the page below */
511 }
512 }
513
514 /*
515 * Buffers are managed in a filesystem specific way.
516 * We must have no buffers or drop them.
517 */
518 if (!page_has_buffers(page) ||
519 try_to_release_page(page, GFP_KERNEL)) {
520 rc = migrate_page(mapping, newpage, page);
521 goto unlock_both;
522 }
523
524 /*
525 * On early passes with mapped pages simply
526 * retry. There may be a lock held for some
527 * buffers that may go away. Later
528 * swap them out.
529 */
530 if (pass > 4) {
531 /*
532 * Persistently unable to drop buffers..... As a
533 * measure of last resort we fall back to
534 * swap_page().
535 */
536 unlock_page(newpage);
537 newpage = NULL;
538 rc = swap_page(page);
539 goto next;
540 }
541 529
542unlock_both: 530unlock_both:
543 unlock_page(newpage); 531 unlock_page(newpage);