return 0;
 }
 
+static void btrfs_free_pending_ordered(struct btrfs_transaction *cur_trans,
+                                      struct btrfs_fs_info *fs_info)
+{
+       struct btrfs_ordered_extent *ordered;
+
+       spin_lock(&fs_info->trans_lock);
+       while (!list_empty(&cur_trans->pending_ordered)) {
+               ordered = list_first_entry(&cur_trans->pending_ordered,
+                                          struct btrfs_ordered_extent,
+                                          trans_list);
+               list_del_init(&ordered->trans_list);
+               spin_unlock(&fs_info->trans_lock);
+
+               btrfs_put_ordered_extent(ordered);
+               spin_lock(&fs_info->trans_lock);
+       }
+       spin_unlock(&fs_info->trans_lock);
+}
+
 void btrfs_cleanup_one_transaction(struct btrfs_transaction *cur_trans,
                                   struct btrfs_root *root)
 {
        cur_trans->state = TRANS_STATE_UNBLOCKED;
        wake_up(&root->fs_info->transaction_wait);
 
+       btrfs_free_pending_ordered(cur_trans, root->fs_info);
        btrfs_destroy_delayed_inodes(root);
        btrfs_assert_delayed_root_empty(root);
 
 
        INIT_LIST_HEAD(&entry->work_list);
        init_completion(&entry->completion);
        INIT_LIST_HEAD(&entry->log_list);
+       INIT_LIST_HEAD(&entry->trans_list);
 
        trace_btrfs_ordered_extent_add(inode, entry);
 
                ordered = rb_entry(n, struct btrfs_ordered_extent, rb_node);
                if (!list_empty(&ordered->log_list))
                        continue;
+               if (test_bit(BTRFS_ORDERED_LOGGED, &ordered->flags))
+                       continue;
                list_add_tail(&ordered->log_list, logged_list);
                atomic_inc(&ordered->refs);
        }
        spin_unlock_irq(&log->log_extents_lock[index]);
 }
 
-void btrfs_wait_logged_extents(struct btrfs_root *log, u64 transid)
+void btrfs_wait_logged_extents(struct btrfs_trans_handle *trans,
+                              struct btrfs_root *log, u64 transid)
 {
        struct btrfs_ordered_extent *ordered;
        int index = transid % 2;
                wait_event(ordered->wait, test_bit(BTRFS_ORDERED_IO_DONE,
                                                   &ordered->flags));
 
-               btrfs_put_ordered_extent(ordered);
+               if (!test_and_set_bit(BTRFS_ORDERED_LOGGED, &ordered->flags))
+                       list_add_tail(&ordered->trans_list, &trans->ordered);
                spin_lock_irq(&log->log_extents_lock[index]);
        }
        spin_unlock_irq(&log->log_extents_lock[index]);
 
                                       ordered extent */
 #define BTRFS_ORDERED_TRUNCATED 9 /* Set when we have to truncate an extent */
 
+#define BTRFS_ORDERED_LOGGED 10 /* Set when we've waited on this ordered extent
+                                * in the logging code. */
 struct btrfs_ordered_extent {
        /* logical offset in the file */
        u64 file_offset;
        /* If we need to wait on this to be done */
        struct list_head log_list;
 
+       /* If the transaction needs to wait on this ordered extent */
+       struct list_head trans_list;
+
        /* used to wait for the BTRFS_ORDERED_COMPLETE bit */
        wait_queue_head_t wait;
 
 void btrfs_put_logged_extents(struct list_head *logged_list);
 void btrfs_submit_logged_extents(struct list_head *logged_list,
                                 struct btrfs_root *log);
-void btrfs_wait_logged_extents(struct btrfs_root *log, u64 transid);
+void btrfs_wait_logged_extents(struct btrfs_trans_handle *trans,
+                              struct btrfs_root *log, u64 transid);
 void btrfs_free_logged_extents(struct btrfs_root *log, u64 transid);
 int __init ordered_data_init(void);
 void ordered_data_exit(void);
 
        INIT_LIST_HEAD(&cur_trans->pending_snapshots);
        INIT_LIST_HEAD(&cur_trans->pending_chunks);
        INIT_LIST_HEAD(&cur_trans->switch_commits);
+       INIT_LIST_HEAD(&cur_trans->pending_ordered);
        list_add_tail(&cur_trans->list, &fs_info->trans_list);
        extent_io_tree_init(&cur_trans->dirty_pages,
                             fs_info->btree_inode->i_mapping);
        h->sync = false;
        INIT_LIST_HEAD(&h->qgroup_ref_list);
        INIT_LIST_HEAD(&h->new_bgs);
+       INIT_LIST_HEAD(&h->ordered);
 
        smp_mb();
        if (cur_trans->state >= TRANS_STATE_BLOCKED &&
        if (!list_empty(&trans->new_bgs))
                btrfs_create_pending_block_groups(trans, root);
 
+       if (!list_empty(&trans->ordered)) {
+               spin_lock(&info->trans_lock);
+               list_splice(&trans->ordered, &cur_trans->pending_ordered);
+               spin_unlock(&info->trans_lock);
+       }
+
        trans->delayed_ref_updates = 0;
        if (!trans->sync) {
                must_run_delayed_refs =
                btrfs_wait_ordered_roots(fs_info, -1);
 }
 
+static inline void
+btrfs_wait_pending_ordered(struct btrfs_transaction *cur_trans,
+                          struct btrfs_fs_info *fs_info)
+{
+       struct btrfs_ordered_extent *ordered;
+
+       spin_lock(&fs_info->trans_lock);
+       while (!list_empty(&cur_trans->pending_ordered)) {
+               ordered = list_first_entry(&cur_trans->pending_ordered,
+                                          struct btrfs_ordered_extent,
+                                          trans_list);
+               list_del_init(&ordered->trans_list);
+               spin_unlock(&fs_info->trans_lock);
+
+               wait_event(ordered->wait, test_bit(BTRFS_ORDERED_COMPLETE,
+                                                  &ordered->flags));
+               btrfs_put_ordered_extent(ordered);
+               spin_lock(&fs_info->trans_lock);
+       }
+       spin_unlock(&fs_info->trans_lock);
+}
+
 int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
                             struct btrfs_root *root)
 {
        }
 
        spin_lock(&root->fs_info->trans_lock);
+       list_splice(&trans->ordered, &cur_trans->pending_ordered);
        if (cur_trans->state >= TRANS_STATE_COMMIT_START) {
                spin_unlock(&root->fs_info->trans_lock);
                atomic_inc(&cur_trans->use_count);
 
        btrfs_wait_delalloc_flush(root->fs_info);
 
+       btrfs_wait_pending_ordered(cur_trans, root->fs_info);
+
        btrfs_scrub_pause(root);
        /*
         * Ok now we need to make sure to block out any other joins while we
 
        wait_queue_head_t commit_wait;
        struct list_head pending_snapshots;
        struct list_head pending_chunks;
+       struct list_head pending_ordered;
        struct list_head switch_commits;
        struct btrfs_delayed_ref_root delayed_refs;
        int aborted;
         */
        struct btrfs_root *root;
        struct seq_list delayed_ref_elem;
+       struct list_head ordered;
        struct list_head qgroup_ref_list;
        struct list_head new_bgs;
 };
 
        if (atomic_read(&log_root_tree->log_commit[index2])) {
                blk_finish_plug(&plug);
                btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark);
-               btrfs_wait_logged_extents(log, log_transid);
+               btrfs_wait_logged_extents(trans, log, log_transid);
                wait_log_commit(trans, log_root_tree,
                                root_log_ctx.log_transid);
                mutex_unlock(&log_root_tree->log_mutex);
        btrfs_wait_marked_extents(log_root_tree,
                                  &log_root_tree->dirty_log_pages,
                                  EXTENT_NEW | EXTENT_DIRTY);
-       btrfs_wait_logged_extents(log, log_transid);
+       btrfs_wait_logged_extents(trans, log, log_transid);
 
        btrfs_set_super_log_root(root->fs_info->super_for_commit,
                                log_root_tree->node->start);
        fi = btrfs_item_ptr(leaf, path->slots[0],
                            struct btrfs_file_extent_item);
 
-       btrfs_set_token_file_extent_generation(leaf, fi, em->generation,
+       btrfs_set_token_file_extent_generation(leaf, fi, trans->transid,
                                               &token);
        if (test_bit(EXTENT_FLAG_PREALLOC, &em->flags))
                btrfs_set_token_file_extent_type(leaf, fi,