filemap_flush(root->fs_info->btree_inode->i_mapping);
                return 0;
        }
-       filemap_write_and_wait(root->fs_info->btree_inode->i_mapping);
        mutex_lock(&root->fs_info->fs_mutex);
        trans = btrfs_start_transaction(root, 1);
        ret = btrfs_commit_transaction(trans, root);
 
                cur_trans->use_count = 1;
                cur_trans->commit_done = 0;
                list_add_tail(&cur_trans->list, &root->fs_info->trans_list);
+               init_bit_radix(&cur_trans->dirty_pages);
        }
        cur_trans->num_writers++;
        return 0;
 int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
                                     struct btrfs_root *root)
 {
-       filemap_write_and_wait(root->fs_info->btree_inode->i_mapping);
-       return 0;
+       unsigned long gang[16];
+       int ret;
+       int i;
+       int err;
+       int werr = 0;
+       struct page *page;
+       struct radix_tree_root *dirty_pages;
+       struct inode *btree_inode = root->fs_info->btree_inode;
+
+       if (!trans || !trans->transaction) {
+               return filemap_write_and_wait(btree_inode->i_mapping);
+       }
+       dirty_pages = &trans->transaction->dirty_pages;
+       while(1) {
+               ret = find_first_radix_bit(dirty_pages, gang, ARRAY_SIZE(gang));
+               if (!ret)
+                       break;
+               for (i = 0; i < ret; i++) {
+                       /* FIXME EIO */
+                       clear_radix_bit(dirty_pages, gang[i]);
+                       page = find_lock_page(btree_inode->i_mapping,
+                                             gang[i]);
+                       if (!page)
+                               continue;
+                       err = write_one_page(page, 0);
+                       if (err)
+                               werr = err;
+                       page_cache_release(page);
+               }
+       }
+       err = filemap_fdatawait(btree_inode->i_mapping);
+       if (err)
+               werr = err;
+       return werr;
 }
 
 int btrfs_commit_tree_roots(struct btrfs_trans_handle *trans,