diff options
author | Steve French <sfrench@us.ibm.com> | 2006-02-01 15:16:53 -0500 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2006-02-01 15:16:53 -0500 |
commit | e6da74e1f20ea7822e52a9e4fbd3d25bd907e471 (patch) | |
tree | d9b3bc7e654fb788d1cf3a1759b1b3c74cc56a04 /fs/buffer.c | |
parent | 1877c9ea66a29563987f22d0a86c66f438a87ce2 (diff) | |
parent | 3c3b809e256c417847f1a96b2f9d9f66c7fcb02c (diff) |
Merge with /pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/buffer.c')
-rw-r--r-- | fs/buffer.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/fs/buffer.c b/fs/buffer.c index 3dc712f29d2d..5e4a90ee103f 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 */ |
@@ -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 | ||
3059 | int 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 | } | ||
3110 | EXPORT_SYMBOL(buffer_migrate_page); | ||
3111 | #endif | ||
3112 | |||
3113 | /* | ||
3053 | * Buffer-head allocation | 3114 | * Buffer-head allocation |
3054 | */ | 3115 | */ |
3055 | static kmem_cache_t *bh_cachep; | 3116 | static kmem_cache_t *bh_cachep; |