#include <linux/sched.h>
 #include <linux/writeback.h>
 #include <linux/pagemap.h>
+#include <linux/blkdev.h>
 #include "ctree.h"
 #include "disk-io.h"
 #include "transaction.h"
        int werr = 0;
        struct page *page;
        struct inode *btree_inode = root->fs_info->btree_inode;
+       struct extent_io_tree *io_tree = &BTRFS_I(btree_inode)->io_tree;
        u64 start = 0;
        u64 end;
        unsigned long index;
                        page_cache_release(page);
                }
        }
+       /*
+        * we unplug once and then use the wait_on_extent_bit for
+        * everything else
+        */
+       blk_run_address_space(btree_inode->i_mapping);
        while(1) {
                ret = find_first_extent_bit(dirty_pages, 0, &start, &end,
                                            EXTENT_DIRTY);
                                if (err)
                                        werr = err;
                        }
-                       wait_on_page_writeback(page);
+                       if (PageWriteback(page)) {
+                               /*
+                                * we don't wait on the page writeback bit
+                                * because that triggers a lot of unplugs.
+                                * The extent bits are much nicer to
+                                * the disks, but come with a slightly
+                                * higher latency because we aren't forcing
+                                * unplugs.
+                                */
+                               wait_on_extent_writeback(io_tree,
+                                        page_offset(page),
+                                        page_offset(page) +
+                                        PAGE_CACHE_SIZE - 1);
+                       }
+                       if (PageWriteback(page)) {
+                               /*
+                                * the state bits get cleared before the
+                                * page bits, lets add some extra
+                                * paranoia here
+                                */
+                               wait_on_page_writeback(page);
+                       }
                        page_cache_release(page);
                        cond_resched();
                }
 
                 * is now congested.  Back off and let other work structs
                 * run instead
                 */
-               if (pending && bdi_write_congested(bdi)) {
+               if (pending && bdi_write_congested(bdi) &&
+                   fs_info->fs_devices->open_devices > 1) {
                        struct bio *old_head;
 
                        spin_lock(&device->io_lock);