aboutsummaryrefslogtreecommitdiffstats
path: root/fs/buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/buffer.c')
-rw-r--r--fs/buffer.c65
1 files changed, 63 insertions, 2 deletions
diff --git a/fs/buffer.c b/fs/buffer.c
index 3dc712f29d2d..62cfd17dc5fe 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -1022,6 +1022,7 @@ try_again:
1022 1022
1023 bh->b_state = 0; 1023 bh->b_state = 0;
1024 atomic_set(&bh->b_count, 0); 1024 atomic_set(&bh->b_count, 0);
1025 bh->b_private = NULL;
1025 bh->b_size = size; 1026 bh->b_size = size;
1026 1027
1027 /* Link the buffer to its page */ 1028 /* Link the buffer to its page */
@@ -2866,22 +2867,22 @@ void ll_rw_block(int rw, int nr, struct buffer_head *bhs[])
2866 else if (test_set_buffer_locked(bh)) 2867 else if (test_set_buffer_locked(bh))
2867 continue; 2868 continue;
2868 2869
2869 get_bh(bh);
2870 if (rw == WRITE || rw == SWRITE) { 2870 if (rw == WRITE || rw == SWRITE) {
2871 if (test_clear_buffer_dirty(bh)) { 2871 if (test_clear_buffer_dirty(bh)) {
2872 bh->b_end_io = end_buffer_write_sync; 2872 bh->b_end_io = end_buffer_write_sync;
2873 get_bh(bh);
2873 submit_bh(WRITE, bh); 2874 submit_bh(WRITE, bh);
2874 continue; 2875 continue;
2875 } 2876 }
2876 } else { 2877 } else {
2877 if (!buffer_uptodate(bh)) { 2878 if (!buffer_uptodate(bh)) {
2878 bh->b_end_io = end_buffer_read_sync; 2879 bh->b_end_io = end_buffer_read_sync;
2880 get_bh(bh);
2879 submit_bh(rw, bh); 2881 submit_bh(rw, bh);
2880 continue; 2882 continue;
2881 } 2883 }
2882 } 2884 }
2883 unlock_buffer(bh); 2885 unlock_buffer(bh);
2884 put_bh(bh);
2885 } 2886 }
2886} 2887}
2887 2888
@@ -3050,6 +3051,66 @@ asmlinkage long sys_bdflush(int func, long data)
3050} 3051}
3051 3052
3052/* 3053/*
3054 * Migration function for pages with buffers. This function can only be used
3055 * if the underlying filesystem guarantees that no other references to "page"
3056 * exist.
3057 */
3058#ifdef CONFIG_MIGRATION
3059int buffer_migrate_page(struct page *newpage, struct page *page)
3060{
3061 struct address_space *mapping = page->mapping;
3062 struct buffer_head *bh, *head;
3063
3064 if (!mapping)
3065 return -EAGAIN;
3066
3067 if (!page_has_buffers(page))
3068 return migrate_page(newpage, page);
3069
3070 head = page_buffers(page);
3071
3072 if (migrate_page_remove_references(newpage, page, 3))
3073 return -EAGAIN;
3074
3075 bh = head;
3076 do {
3077 get_bh(bh);
3078 lock_buffer(bh);
3079 bh = bh->b_this_page;
3080
3081 } while (bh != head);
3082
3083 ClearPagePrivate(page);
3084 set_page_private(newpage, page_private(page));
3085 set_page_private(page, 0);
3086 put_page(page);
3087 get_page(newpage);
3088
3089 bh = head;
3090 do {
3091 set_bh_page(bh, newpage, bh_offset(bh));
3092 bh = bh->b_this_page;
3093
3094 } while (bh != head);
3095
3096 SetPagePrivate(newpage);
3097
3098 migrate_page_copy(newpage, page);
3099
3100 bh = head;
3101 do {
3102 unlock_buffer(bh);
3103 put_bh(bh);
3104 bh = bh->b_this_page;
3105
3106 } while (bh != head);
3107
3108 return 0;
3109}
3110EXPORT_SYMBOL(buffer_migrate_page);
3111#endif
3112
3113/*
3053 * Buffer-head allocation 3114 * Buffer-head allocation
3054 */ 3115 */
3055static kmem_cache_t *bh_cachep; 3116static kmem_cache_t *bh_cachep;