aboutsummaryrefslogtreecommitdiffstats
path: root/fs/buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/buffer.c')
-rw-r--r--fs/buffer.c45
1 files changed, 34 insertions, 11 deletions
diff --git a/fs/buffer.c b/fs/buffer.c
index ff8bb1f2333a..b3e5be7514f5 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -360,7 +360,7 @@ still_busy:
360 * Completion handler for block_write_full_page() - pages which are unlocked 360 * Completion handler for block_write_full_page() - pages which are unlocked
361 * during I/O, and which have PageWriteback cleared upon I/O completion. 361 * during I/O, and which have PageWriteback cleared upon I/O completion.
362 */ 362 */
363static void end_buffer_async_write(struct buffer_head *bh, int uptodate) 363void end_buffer_async_write(struct buffer_head *bh, int uptodate)
364{ 364{
365 char b[BDEVNAME_SIZE]; 365 char b[BDEVNAME_SIZE];
366 unsigned long flags; 366 unsigned long flags;
@@ -438,11 +438,17 @@ static void mark_buffer_async_read(struct buffer_head *bh)
438 set_buffer_async_read(bh); 438 set_buffer_async_read(bh);
439} 439}
440 440
441void mark_buffer_async_write(struct buffer_head *bh) 441void mark_buffer_async_write_endio(struct buffer_head *bh,
442 bh_end_io_t *handler)
442{ 443{
443 bh->b_end_io = end_buffer_async_write; 444 bh->b_end_io = handler;
444 set_buffer_async_write(bh); 445 set_buffer_async_write(bh);
445} 446}
447
448void mark_buffer_async_write(struct buffer_head *bh)
449{
450 mark_buffer_async_write_endio(bh, end_buffer_async_write);
451}
446EXPORT_SYMBOL(mark_buffer_async_write); 452EXPORT_SYMBOL(mark_buffer_async_write);
447 453
448 454
@@ -1615,7 +1621,8 @@ EXPORT_SYMBOL(unmap_underlying_metadata);
1615 * unplugging the device queue. 1621 * unplugging the device queue.
1616 */ 1622 */
1617static int __block_write_full_page(struct inode *inode, struct page *page, 1623static int __block_write_full_page(struct inode *inode, struct page *page,
1618 get_block_t *get_block, struct writeback_control *wbc) 1624 get_block_t *get_block, struct writeback_control *wbc,
1625 bh_end_io_t *handler)
1619{ 1626{
1620 int err; 1627 int err;
1621 sector_t block; 1628 sector_t block;
@@ -1700,7 +1707,7 @@ static int __block_write_full_page(struct inode *inode, struct page *page,
1700 continue; 1707 continue;
1701 } 1708 }
1702 if (test_clear_buffer_dirty(bh)) { 1709 if (test_clear_buffer_dirty(bh)) {
1703 mark_buffer_async_write(bh); 1710 mark_buffer_async_write_endio(bh, handler);
1704 } else { 1711 } else {
1705 unlock_buffer(bh); 1712 unlock_buffer(bh);
1706 } 1713 }
@@ -1753,7 +1760,7 @@ recover:
1753 if (buffer_mapped(bh) && buffer_dirty(bh) && 1760 if (buffer_mapped(bh) && buffer_dirty(bh) &&
1754 !buffer_delay(bh)) { 1761 !buffer_delay(bh)) {
1755 lock_buffer(bh); 1762 lock_buffer(bh);
1756 mark_buffer_async_write(bh); 1763 mark_buffer_async_write_endio(bh, handler);
1757 } else { 1764 } else {
1758 /* 1765 /*
1759 * The buffer may have been set dirty during 1766 * The buffer may have been set dirty during
@@ -2679,7 +2686,8 @@ int nobh_writepage(struct page *page, get_block_t *get_block,
2679out: 2686out:
2680 ret = mpage_writepage(page, get_block, wbc); 2687 ret = mpage_writepage(page, get_block, wbc);
2681 if (ret == -EAGAIN) 2688 if (ret == -EAGAIN)
2682 ret = __block_write_full_page(inode, page, get_block, wbc); 2689 ret = __block_write_full_page(inode, page, get_block, wbc,
2690 end_buffer_async_write);
2683 return ret; 2691 return ret;
2684} 2692}
2685EXPORT_SYMBOL(nobh_writepage); 2693EXPORT_SYMBOL(nobh_writepage);
@@ -2837,9 +2845,10 @@ out:
2837 2845
2838/* 2846/*
2839 * The generic ->writepage function for buffer-backed address_spaces 2847 * The generic ->writepage function for buffer-backed address_spaces
2848 * this form passes in the end_io handler used to finish the IO.
2840 */ 2849 */
2841int block_write_full_page(struct page *page, get_block_t *get_block, 2850int block_write_full_page_endio(struct page *page, get_block_t *get_block,
2842 struct writeback_control *wbc) 2851 struct writeback_control *wbc, bh_end_io_t *handler)
2843{ 2852{
2844 struct inode * const inode = page->mapping->host; 2853 struct inode * const inode = page->mapping->host;
2845 loff_t i_size = i_size_read(inode); 2854 loff_t i_size = i_size_read(inode);
@@ -2848,7 +2857,8 @@ int block_write_full_page(struct page *page, get_block_t *get_block,
2848 2857
2849 /* Is the page fully inside i_size? */ 2858 /* Is the page fully inside i_size? */
2850 if (page->index < end_index) 2859 if (page->index < end_index)
2851 return __block_write_full_page(inode, page, get_block, wbc); 2860 return __block_write_full_page(inode, page, get_block, wbc,
2861 handler);
2852 2862
2853 /* Is the page fully outside i_size? (truncate in progress) */ 2863 /* Is the page fully outside i_size? (truncate in progress) */
2854 offset = i_size & (PAGE_CACHE_SIZE-1); 2864 offset = i_size & (PAGE_CACHE_SIZE-1);
@@ -2871,9 +2881,20 @@ int block_write_full_page(struct page *page, get_block_t *get_block,
2871 * writes to that region are not written out to the file." 2881 * writes to that region are not written out to the file."
2872 */ 2882 */
2873 zero_user_segment(page, offset, PAGE_CACHE_SIZE); 2883 zero_user_segment(page, offset, PAGE_CACHE_SIZE);
2874 return __block_write_full_page(inode, page, get_block, wbc); 2884 return __block_write_full_page(inode, page, get_block, wbc, handler);
2875} 2885}
2876 2886
2887/*
2888 * The generic ->writepage function for buffer-backed address_spaces
2889 */
2890int block_write_full_page(struct page *page, get_block_t *get_block,
2891 struct writeback_control *wbc)
2892{
2893 return block_write_full_page_endio(page, get_block, wbc,
2894 end_buffer_async_write);
2895}
2896
2897
2877sector_t generic_block_bmap(struct address_space *mapping, sector_t block, 2898sector_t generic_block_bmap(struct address_space *mapping, sector_t block,
2878 get_block_t *get_block) 2899 get_block_t *get_block)
2879{ 2900{
@@ -3342,9 +3363,11 @@ EXPORT_SYMBOL(block_read_full_page);
3342EXPORT_SYMBOL(block_sync_page); 3363EXPORT_SYMBOL(block_sync_page);
3343EXPORT_SYMBOL(block_truncate_page); 3364EXPORT_SYMBOL(block_truncate_page);
3344EXPORT_SYMBOL(block_write_full_page); 3365EXPORT_SYMBOL(block_write_full_page);
3366EXPORT_SYMBOL(block_write_full_page_endio);
3345EXPORT_SYMBOL(cont_write_begin); 3367EXPORT_SYMBOL(cont_write_begin);
3346EXPORT_SYMBOL(end_buffer_read_sync); 3368EXPORT_SYMBOL(end_buffer_read_sync);
3347EXPORT_SYMBOL(end_buffer_write_sync); 3369EXPORT_SYMBOL(end_buffer_write_sync);
3370EXPORT_SYMBOL(end_buffer_async_write);
3348EXPORT_SYMBOL(file_fsync); 3371EXPORT_SYMBOL(file_fsync);
3349EXPORT_SYMBOL(generic_block_bmap); 3372EXPORT_SYMBOL(generic_block_bmap);
3350EXPORT_SYMBOL(generic_cont_expand_simple); 3373EXPORT_SYMBOL(generic_cont_expand_simple);