Skip to content

Commit

Permalink
[PATCH] page migration cleanup: move fallback handling into special f…
Browse files Browse the repository at this point in the history
…unction

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>
  • Loading branch information
Christoph Lameter authored and Linus Torvalds committed Jun 23, 2006
1 parent 2d1db3b commit 8351a6e
Showing 1 changed file with 39 additions and 51 deletions.
90 changes: 39 additions & 51 deletions mm/migrate.c
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,42 @@ int buffer_migrate_page(struct address_space *mapping,
}
EXPORT_SYMBOL(buffer_migrate_page);

static int fallback_migrate_page(struct address_space *mapping,
struct page *newpage, struct page *page)
{
/*
* Default handling if a filesystem does not provide
* a migration function. We can only migrate clean
* pages so try to write out any dirty pages first.
*/
if (PageDirty(page)) {
switch (pageout(page, mapping)) {
case PAGE_KEEP:
case PAGE_ACTIVATE:
return -EAGAIN;

case PAGE_SUCCESS:
/* Relock since we lost the lock */
lock_page(page);
/* Must retry since page state may have changed */
return -EAGAIN;

case PAGE_CLEAN:
; /* try to migrate the page below */
}
}

/*
* Buffers may be managed in a filesystem specific way.
* We must have no buffers or drop them.
*/
if (page_has_buffers(page) &&
!try_to_release_page(page, GFP_KERNEL))
return -EAGAIN;

return migrate_page(mapping, newpage, page);
}

/*
* migrate_pages
*
Expand Down Expand Up @@ -478,7 +514,7 @@ int migrate_pages(struct list_head *from, struct list_head *to,
if (!mapping)
goto unlock_both;

if (mapping->a_ops->migratepage) {
if (mapping->a_ops->migratepage)
/*
* Most pages have a mapping and most filesystems
* should provide a migration function. Anonymous
Expand All @@ -488,56 +524,8 @@ int migrate_pages(struct list_head *from, struct list_head *to,
*/
rc = mapping->a_ops->migratepage(mapping,
newpage, page);
goto unlock_both;
}

/*
* Default handling if a filesystem does not provide
* a migration function. We can only migrate clean
* pages so try to write out any dirty pages first.
*/
if (PageDirty(page)) {
switch (pageout(page, mapping)) {
case PAGE_KEEP:
case PAGE_ACTIVATE:
goto unlock_both;

case PAGE_SUCCESS:
unlock_page(newpage);
goto next;

case PAGE_CLEAN:
; /* try to migrate the page below */
}
}

/*
* Buffers are managed in a filesystem specific way.
* We must have no buffers or drop them.
*/
if (!page_has_buffers(page) ||
try_to_release_page(page, GFP_KERNEL)) {
rc = migrate_page(mapping, newpage, page);
goto unlock_both;
}

/*
* On early passes with mapped pages simply
* retry. There may be a lock held for some
* buffers that may go away. Later
* swap them out.
*/
if (pass > 4) {
/*
* Persistently unable to drop buffers..... As a
* measure of last resort we fall back to
* swap_page().
*/
unlock_page(newpage);
newpage = NULL;
rc = swap_page(page);
goto next;
}
else
rc = fallback_migrate_page(mapping, newpage, page);

unlock_both:
unlock_page(newpage);
Expand Down

0 comments on commit 8351a6e

Please sign in to comment.