aboutsummaryrefslogtreecommitdiffstats
path: root/fs/buffer.c
diff options
context:
space:
mode:
authorChristoph Lameter <clameter@sgi.com>2006-02-01 06:05:41 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-02-01 11:53:17 -0500
commite965f9630c651fa4249039fd4b80c9392d07a856 (patch)
tree1353dd536d0ee549c30e462086624c21788ee9d2 /fs/buffer.c
parent7e2ab150d1b3b286a4c864c60a549b2601777b63 (diff)
[PATCH] Direct Migration V9: Avoid writeback / page_migrate() method
Migrate a page with buffers without requiring writeback This introduces a new address space operation migratepage() that may be used by a filesystem to implement its own version of page migration. A version is provided that migrates buffers attached to pages. Some filesystems (ext2, ext3, xfs) are modified to utilize this feature. The swapper address space operation are modified so that a regular migrate_page() will occur for anonymous pages without writeback (migrate_pages forces every anonymous page to have a swap entry). Signed-off-by: Mike Kravetz <kravetz@us.ibm.com> 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 'fs/buffer.c')
-rw-r--r--fs/buffer.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/fs/buffer.c b/fs/buffer.c
index 3dc712f29d2d..8bcbac87a28c 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -3050,6 +3050,66 @@ asmlinkage long sys_bdflush(int func, long data)
3050} 3050}
3051 3051
3052/* 3052/*
3053 * Migration function for pages with buffers. This function can only be used
3054 * if the underlying filesystem guarantees that no other references to "page"
3055 * exist.
3056 */
3057#ifdef CONFIG_MIGRATION
3058int buffer_migrate_page(struct page *newpage, struct page *page)
3059{
3060 struct address_space *mapping = page->mapping;
3061 struct buffer_head *bh, *head;
3062
3063 if (!mapping)
3064 return -EAGAIN;
3065
3066 if (!page_has_buffers(page))
3067 return migrate_page(newpage, page);
3068
3069 head = page_buffers(page);
3070
3071 if (migrate_page_remove_references(newpage, page, 3))
3072 return -EAGAIN;
3073
3074 bh = head;
3075 do {
3076 get_bh(bh);
3077 lock_buffer(bh);
3078 bh = bh->b_this_page;
3079
3080 } while (bh != head);
3081
3082 ClearPagePrivate(page);
3083 set_page_private(newpage, page_private(page));
3084 set_page_private(page, 0);
3085 put_page(page);
3086 get_page(newpage);
3087
3088 bh = head;
3089 do {
3090 set_bh_page(bh, newpage, bh_offset(bh));
3091 bh = bh->b_this_page;
3092
3093 } while (bh != head);
3094
3095 SetPagePrivate(newpage);
3096
3097 migrate_page_copy(newpage, page);
3098
3099 bh = head;
3100 do {
3101 unlock_buffer(bh);
3102 put_bh(bh);
3103 bh = bh->b_this_page;
3104
3105 } while (bh != head);
3106
3107 return 0;
3108}
3109EXPORT_SYMBOL(buffer_migrate_page);
3110#endif
3111
3112/*
3053 * Buffer-head allocation 3113 * Buffer-head allocation
3054 */ 3114 */
3055static kmem_cache_t *bh_cachep; 3115static kmem_cache_t *bh_cachep;