From 3c72afb2b3afdd38ec486dc6e2b72095e38ebec5 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 15 Jan 2009 14:44:25 +0100 Subject: [PATCH] aio: first support for buffered async writes Signed-off-by: Jens Axboe --- fs/buffer.c | 5 +---- fs/ext3/inode.c | 2 ++ include/linux/pagemap.h | 2 ++ mm/filemap.c | 44 ++++++++++++++++++++++++++++------------- mm/page-writeback.c | 4 +++- 5 files changed, 38 insertions(+), 19 deletions(-) diff --git a/fs/buffer.c b/fs/buffer.c index 9bbae13011ce..25b307128b2e 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -3369,10 +3369,7 @@ int bh_submit_read(struct buffer_head *bh) get_bh(bh); bh->b_end_io = end_buffer_read_sync; submit_bh(READ, bh); - if (wait_on_buffer_async(bh, current->io_wait)) { - WARN(1, "%s: err\n", __FUNCTION__); - return -EIOCBRETRY; - } + wait_on_buffer(bh); if (buffer_uptodate(bh)) return 0; return -EIO; diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index acf1b1423327..d59b237f349c 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c @@ -1171,6 +1171,8 @@ retry: page = grab_cache_page_write_begin(mapping, index, flags); if (!page) return -ENOMEM; + else if (IS_ERR(page)) + return PTR_ERR(page); *pagep = page; handle = ext3_journal_start(inode, needed_blocks); diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 3c80f3a45688..0d154a789441 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -224,6 +224,8 @@ extern struct page * find_get_page(struct address_space *mapping, pgoff_t index); extern struct page * find_lock_page(struct address_space *mapping, pgoff_t index); +extern struct page *find_lock_page_async(struct address_space *mapping, + pgoff_t index, struct wait_bit_queue *wait); extern struct page * find_or_create_page(struct address_space *mapping, pgoff_t index, gfp_t gfp_mask); unsigned find_get_pages(struct address_space *mapping, pgoff_t start, diff --git a/mm/filemap.c b/mm/filemap.c index 4fffb32ba3a7..26348d3bdcb4 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -693,24 +693,22 @@ repeat: } EXPORT_SYMBOL(find_get_page); -/** - * find_lock_page - locate, pin and lock a pagecache page - * @mapping: the address_space to search - * @offset: the page index - * - * Locates the desired pagecache page, locks it, increments its reference - * count and returns its address. - * - * Returns zero if the page was not present. find_lock_page() may sleep. - */ -struct page *find_lock_page(struct address_space *mapping, pgoff_t offset) +struct page *find_lock_page_async(struct address_space *mapping, pgoff_t offset, + struct wait_bit_queue *wait) { struct page *page; repeat: page = find_get_page(mapping, offset); if (page) { - lock_page(page); + int ret; + + ret = lock_page_async(page, wait); + if (ret) { + page_cache_release(page); + page = ERR_PTR(ret); + goto out; + } /* Has the page been truncated? */ if (unlikely(page->mapping != mapping)) { unlock_page(page); @@ -719,8 +717,26 @@ repeat: } VM_BUG_ON(page->index != offset); } +out: return page; } +EXPORT_SYMBOL(find_lock_page_async); + +/** + * find_lock_page - locate, pin and lock a pagecache page + * @mapping: the address_space to search + * @offset: the page index + * + * Locates the desired pagecache page, locks it, increments its reference + * count and returns its address. + * + * Returns zero if the page was not present. find_lock_page() may sleep. + */ +struct page *find_lock_page(struct address_space *mapping, pgoff_t offset) +{ + + return find_lock_page_async(mapping, offset, NULL); +} EXPORT_SYMBOL(find_lock_page); /** @@ -2183,8 +2199,8 @@ struct page *grab_cache_page_write_begin(struct address_space *mapping, if (flags & AOP_FLAG_NOFS) gfp_notmask = __GFP_FS; repeat: - page = find_lock_page(mapping, index); - if (likely(page)) + page = find_lock_page_async(mapping, index, current->io_wait); + if (page || IS_ERR(page)) return page; page = __page_cache_alloc(mapping_gfp_mask(mapping) & ~gfp_notmask); diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 69b5fbabc8bd..4be7cc5243d4 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c @@ -886,7 +886,9 @@ retry: done_index = page->index + 1; - lock_page(page); + ret = lock_page_async(page, current->io_wait); + if (ret) + break; /* * Page truncated or invalidated. We can freely skip it -- 2.25.1