diff options
| author | Dave Kleikamp <shaggy@austin.ibm.com> | 2006-03-14 18:05:45 -0500 |
|---|---|---|
| committer | Dave Kleikamp <shaggy@austin.ibm.com> | 2006-03-14 18:05:45 -0500 |
| commit | c5111f504d2a9b0d258d7c4752b4093523315989 (patch) | |
| tree | 6a52864aff79691689aea21cb0cb928327d5de5b /fs/buffer.c | |
| parent | 69eb66d7da7dba2696281981347698e1693c2340 (diff) | |
| parent | a488edc914aa1d766a4e2c982b5ae03d5657ec1b (diff) | |
Merge with /home/shaggy/git/linus-clean/
Diffstat (limited to 'fs/buffer.c')
| -rw-r--r-- | fs/buffer.c | 65 |
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 | ||
| 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; |
