aboutsummaryrefslogtreecommitdiffstats
path: root/fs/buffer.c
diff options
context:
space:
mode:
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;