aio: first support for buffered async writes
authorJens Axboe <jens.axboe@oracle.com>
Thu, 15 Jan 2009 13:44:25 +0000 (14:44 +0100)
committerJens Axboe <jens.axboe@oracle.com>
Sat, 26 Sep 2009 15:36:25 +0000 (17:36 +0200)
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
fs/buffer.c
fs/ext3/inode.c
include/linux/pagemap.h
mm/filemap.c
mm/page-writeback.c

index 9bbae13011cef9069fb33ae4c41f603a9e76de84..25b307128b2ec5244242397158ad1dc8cd03d5b4 100644 (file)
@@ -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;
index acf1b14233275e891fd5e1d55560fed331add18c..d59b237f349c4bcf4b066818922d32bc65bbb8d0 100644 (file)
@@ -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);
index 3c80f3a45688e2a3dce6e03d8accf80aeef6dd69..0d154a78944125d7ca1388ba76cac99e1daf7f03 100644 (file)
@@ -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,
index 4fffb32ba3a71e1e587bc2be0b888bd29a04921a..26348d3bdcb4b3721df66c3c38d6e057655ccaf4 100644 (file)
@@ -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);
index 69b5fbabc8bd4e9248f54f460d0f01b4e75f8e86..4be7cc5243d4b9c1ed87592d4be8b13f00710826 100644 (file)
@@ -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