aboutsummaryrefslogtreecommitdiffstats
path: root/fs/buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/buffer.c')
-rw-r--r--fs/buffer.c67
1 files changed, 65 insertions, 2 deletions
diff --git a/fs/buffer.c b/fs/buffer.c
index 3dc712f29d2d..a9b399402007 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,68 @@ 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 int rc;
3064
3065 if (!mapping)
3066 return -EAGAIN;
3067
3068 if (!page_has_buffers(page))
3069 return migrate_page(newpage, page);
3070
3071 head = page_buffers(page);
3072
3073 rc = migrate_page_remove_references(newpage, page, 3);
3074 if (rc)
3075 return rc;
3076
3077 bh = head;
3078 do {
3079 get_bh(bh);
3080 lock_buffer(bh);
3081 bh = bh->b_this_page;
3082
3083 } while (bh != head);
3084
3085 ClearPagePrivate(page);
3086 set_page_private(newpage, page_private(page));
3087 set_page_private(page, 0);
3088 put_page(page);
3089 get_page(newpage);
3090
3091 bh = head;
3092 do {
3093 set_bh_page(bh, newpage, bh_offset(bh));
3094 bh = bh->b_this_page;
3095
3096 } while (bh != head);
3097
3098 SetPagePrivate(newpage);
3099
3100 migrate_page_copy(newpage, page);
3101
3102 bh = head;
3103 do {
3104 unlock_buffer(bh);
3105 put_bh(bh);
3106 bh = bh->b_this_page;
3107
3108 } while (bh != head);
3109
3110 return 0;
3111}
3112EXPORT_SYMBOL(buffer_migrate_page);
3113#endif
3114
3115/*
3053 * Buffer-head allocation 3116 * Buffer-head allocation
3054 */ 3117 */
3055static kmem_cache_t *bh_cachep; 3118static kmem_cache_t *bh_cachep;