aboutsummaryrefslogtreecommitdiffstats
path: root/fs
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
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')
-rw-r--r--fs/buffer.c60
-rw-r--r--fs/ext2/inode.c2
-rw-r--r--fs/ext3/inode.c2
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c1
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.c1
5 files changed, 66 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;
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index e7d3f0522d01..a717837f272e 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -706,6 +706,7 @@ struct address_space_operations ext2_aops = {
706 .bmap = ext2_bmap, 706 .bmap = ext2_bmap,
707 .direct_IO = ext2_direct_IO, 707 .direct_IO = ext2_direct_IO,
708 .writepages = ext2_writepages, 708 .writepages = ext2_writepages,
709 .migratepage = buffer_migrate_page,
709}; 710};
710 711
711struct address_space_operations ext2_aops_xip = { 712struct address_space_operations ext2_aops_xip = {
@@ -723,6 +724,7 @@ struct address_space_operations ext2_nobh_aops = {
723 .bmap = ext2_bmap, 724 .bmap = ext2_bmap,
724 .direct_IO = ext2_direct_IO, 725 .direct_IO = ext2_direct_IO,
725 .writepages = ext2_writepages, 726 .writepages = ext2_writepages,
727 .migratepage = buffer_migrate_page,
726}; 728};
727 729
728/* 730/*
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index 8824e84f8a56..3fc4238e9703 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -1559,6 +1559,7 @@ static struct address_space_operations ext3_ordered_aops = {
1559 .invalidatepage = ext3_invalidatepage, 1559 .invalidatepage = ext3_invalidatepage,
1560 .releasepage = ext3_releasepage, 1560 .releasepage = ext3_releasepage,
1561 .direct_IO = ext3_direct_IO, 1561 .direct_IO = ext3_direct_IO,
1562 .migratepage = buffer_migrate_page,
1562}; 1563};
1563 1564
1564static struct address_space_operations ext3_writeback_aops = { 1565static struct address_space_operations ext3_writeback_aops = {
@@ -1572,6 +1573,7 @@ static struct address_space_operations ext3_writeback_aops = {
1572 .invalidatepage = ext3_invalidatepage, 1573 .invalidatepage = ext3_invalidatepage,
1573 .releasepage = ext3_releasepage, 1574 .releasepage = ext3_releasepage,
1574 .direct_IO = ext3_direct_IO, 1575 .direct_IO = ext3_direct_IO,
1576 .migratepage = buffer_migrate_page,
1575}; 1577};
1576 1578
1577static struct address_space_operations ext3_journalled_aops = { 1579static struct address_space_operations ext3_journalled_aops = {
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 120626789406..9892268e3005 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -1462,4 +1462,5 @@ struct address_space_operations linvfs_aops = {
1462 .commit_write = generic_commit_write, 1462 .commit_write = generic_commit_write,
1463 .bmap = linvfs_bmap, 1463 .bmap = linvfs_bmap,
1464 .direct_IO = linvfs_direct_IO, 1464 .direct_IO = linvfs_direct_IO,
1465 .migratepage = buffer_migrate_page,
1465}; 1466};
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c
index a36a8e3b703f..bfb4f2917bb6 100644
--- a/fs/xfs/linux-2.6/xfs_buf.c
+++ b/fs/xfs/linux-2.6/xfs_buf.c
@@ -1521,6 +1521,7 @@ xfs_mapping_buftarg(
1521 struct address_space *mapping; 1521 struct address_space *mapping;
1522 static struct address_space_operations mapping_aops = { 1522 static struct address_space_operations mapping_aops = {
1523 .sync_page = block_sync_page, 1523 .sync_page = block_sync_page,
1524 .migratepage = fail_migrate_page,
1524 }; 1525 };
1525 1526
1526 inode = new_inode(bdev->bd_inode->i_sb); 1527 inode = new_inode(bdev->bd_inode->i_sb);