aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mm/migrate.c142
1 files changed, 72 insertions, 70 deletions
diff --git a/mm/migrate.c b/mm/migrate.c
index 1c25040693d2..49e71ddb6792 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -120,15 +120,6 @@ int putback_lru_pages(struct list_head *l)
120} 120}
121 121
122/* 122/*
123 * Non migratable page
124 */
125int fail_migrate_page(struct page *newpage, struct page *page)
126{
127 return -EIO;
128}
129EXPORT_SYMBOL(fail_migrate_page);
130
131/*
132 * swapout a single page 123 * swapout a single page
133 * page is locked upon entry, unlocked on exit 124 * page is locked upon entry, unlocked on exit
134 */ 125 */
@@ -297,6 +288,17 @@ void migrate_page_copy(struct page *newpage, struct page *page)
297} 288}
298EXPORT_SYMBOL(migrate_page_copy); 289EXPORT_SYMBOL(migrate_page_copy);
299 290
291/************************************************************
292 * Migration functions
293 ***********************************************************/
294
295/* Always fail migration. Used for mappings that are not movable */
296int fail_migrate_page(struct page *newpage, struct page *page)
297{
298 return -EIO;
299}
300EXPORT_SYMBOL(fail_migrate_page);
301
300/* 302/*
301 * Common logic to directly migrate a single page suitable for 303 * Common logic to directly migrate a single page suitable for
302 * pages that do not use PagePrivate. 304 * pages that do not use PagePrivate.
@@ -330,6 +332,67 @@ int migrate_page(struct page *newpage, struct page *page)
330EXPORT_SYMBOL(migrate_page); 332EXPORT_SYMBOL(migrate_page);
331 333
332/* 334/*
335 * Migration function for pages with buffers. This function can only be used
336 * if the underlying filesystem guarantees that no other references to "page"
337 * exist.
338 */
339int buffer_migrate_page(struct page *newpage, struct page *page)
340{
341 struct address_space *mapping = page->mapping;
342 struct buffer_head *bh, *head;
343 int rc;
344
345 if (!mapping)
346 return -EAGAIN;
347
348 if (!page_has_buffers(page))
349 return migrate_page(newpage, page);
350
351 head = page_buffers(page);
352
353 rc = migrate_page_remove_references(newpage, page, 3);
354
355 if (rc)
356 return rc;
357
358 bh = head;
359 do {
360 get_bh(bh);
361 lock_buffer(bh);
362 bh = bh->b_this_page;
363
364 } while (bh != head);
365
366 ClearPagePrivate(page);
367 set_page_private(newpage, page_private(page));
368 set_page_private(page, 0);
369 put_page(page);
370 get_page(newpage);
371
372 bh = head;
373 do {
374 set_bh_page(bh, newpage, bh_offset(bh));
375 bh = bh->b_this_page;
376
377 } while (bh != head);
378
379 SetPagePrivate(newpage);
380
381 migrate_page_copy(newpage, page);
382
383 bh = head;
384 do {
385 unlock_buffer(bh);
386 put_bh(bh);
387 bh = bh->b_this_page;
388
389 } while (bh != head);
390
391 return 0;
392}
393EXPORT_SYMBOL(buffer_migrate_page);
394
395/*
333 * migrate_pages 396 * migrate_pages
334 * 397 *
335 * Two lists are passed to this function. The first list 398 * Two lists are passed to this function. The first list
@@ -529,67 +592,6 @@ next:
529} 592}
530 593
531/* 594/*
532 * Migration function for pages with buffers. This function can only be used
533 * if the underlying filesystem guarantees that no other references to "page"
534 * exist.
535 */
536int buffer_migrate_page(struct page *newpage, struct page *page)
537{
538 struct address_space *mapping = page->mapping;
539 struct buffer_head *bh, *head;
540 int rc;
541
542 if (!mapping)
543 return -EAGAIN;
544
545 if (!page_has_buffers(page))
546 return migrate_page(newpage, page);
547
548 head = page_buffers(page);
549
550 rc = migrate_page_remove_references(newpage, page, 3);
551
552 if (rc)
553 return rc;
554
555 bh = head;
556 do {
557 get_bh(bh);
558 lock_buffer(bh);
559 bh = bh->b_this_page;
560
561 } while (bh != head);
562
563 ClearPagePrivate(page);
564 set_page_private(newpage, page_private(page));
565 set_page_private(page, 0);
566 put_page(page);
567 get_page(newpage);
568
569 bh = head;
570 do {
571 set_bh_page(bh, newpage, bh_offset(bh));
572 bh = bh->b_this_page;
573
574 } while (bh != head);
575
576 SetPagePrivate(newpage);
577
578 migrate_page_copy(newpage, page);
579
580 bh = head;
581 do {
582 unlock_buffer(bh);
583 put_bh(bh);
584 bh = bh->b_this_page;
585
586 } while (bh != head);
587
588 return 0;
589}
590EXPORT_SYMBOL(buffer_migrate_page);
591
592/*
593 * Migrate the list 'pagelist' of pages to a certain destination. 595 * Migrate the list 'pagelist' of pages to a certain destination.
594 * 596 *
595 * Specify destination with either non-NULL vma or dest_node >= 0 597 * Specify destination with either non-NULL vma or dest_node >= 0