}
 
 /* Needs to either be called under a log transaction or the log_mutex */
-void btrfs_get_logged_extents(struct btrfs_root *log, struct inode *inode)
+void btrfs_get_logged_extents(struct inode *inode,
+                             struct list_head *logged_list)
 {
        struct btrfs_ordered_inode_tree *tree;
        struct btrfs_ordered_extent *ordered;
        struct rb_node *n;
-       int index = log->log_transid % 2;
 
        tree = &BTRFS_I(inode)->ordered_tree;
        spin_lock_irq(&tree->lock);
        for (n = rb_first(&tree->tree); n; n = rb_next(n)) {
                ordered = rb_entry(n, struct btrfs_ordered_extent, rb_node);
-               spin_lock(&log->log_extents_lock[index]);
-               if (list_empty(&ordered->log_list)) {
-                       list_add_tail(&ordered->log_list, &log->logged_list[index]);
-                       atomic_inc(&ordered->refs);
-               }
-               spin_unlock(&log->log_extents_lock[index]);
+               if (!list_empty(&ordered->log_list))
+                       continue;
+               list_add_tail(&ordered->log_list, logged_list);
+               atomic_inc(&ordered->refs);
        }
        spin_unlock_irq(&tree->lock);
 }
 
+void btrfs_put_logged_extents(struct list_head *logged_list)
+{
+       struct btrfs_ordered_extent *ordered;
+
+       while (!list_empty(logged_list)) {
+               ordered = list_first_entry(logged_list,
+                                          struct btrfs_ordered_extent,
+                                          log_list);
+               list_del_init(&ordered->log_list);
+               btrfs_put_ordered_extent(ordered);
+       }
+}
+
+void btrfs_submit_logged_extents(struct list_head *logged_list,
+                                struct btrfs_root *log)
+{
+       int index = log->log_transid % 2;
+
+       spin_lock_irq(&log->log_extents_lock[index]);
+       list_splice_tail(logged_list, &log->logged_list[index]);
+       spin_unlock_irq(&log->log_extents_lock[index]);
+}
+
 void btrfs_wait_logged_extents(struct btrfs_root *log, u64 transid)
 {
        struct btrfs_ordered_extent *ordered;
 
                                 struct inode *inode);
 int btrfs_wait_ordered_extents(struct btrfs_root *root, int nr);
 void btrfs_wait_ordered_roots(struct btrfs_fs_info *fs_info, int nr);
-void btrfs_get_logged_extents(struct btrfs_root *log, struct inode *inode);
+void btrfs_get_logged_extents(struct inode *inode,
+                             struct list_head *logged_list);
+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_free_logged_extents(struct btrfs_root *log, u64 transid);
 int __init ordered_data_init(void);
 
 
 static int log_one_extent(struct btrfs_trans_handle *trans,
                          struct inode *inode, struct btrfs_root *root,
-                         struct extent_map *em, struct btrfs_path *path)
+                         struct extent_map *em, struct btrfs_path *path,
+                         struct list_head *logged_list)
 {
        struct btrfs_root *log = root->log_root;
        struct btrfs_file_extent_item *fi;
        u64 extent_offset = em->start - em->orig_start;
        u64 block_len;
        int ret;
-       int index = log->log_transid % 2;
        bool skip_csum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM;
        int extent_inserted = 0;
 
         * First check and see if our csums are on our outstanding ordered
         * extents.
         */
-again:
-       spin_lock_irq(&log->log_extents_lock[index]);
-       list_for_each_entry(ordered, &log->logged_list[index], log_list) {
+       list_for_each_entry(ordered, logged_list, log_list) {
                struct btrfs_ordered_sum *sum;
 
                if (!mod_len)
                        break;
 
-               if (ordered->inode != inode)
-                       continue;
-
                if (ordered->file_offset + ordered->len <= mod_start ||
                    mod_start + mod_len <= ordered->file_offset)
                        continue;
                if (test_and_set_bit(BTRFS_ORDERED_LOGGED_CSUM,
                                     &ordered->flags))
                        continue;
-               atomic_inc(&ordered->refs);
-               spin_unlock_irq(&log->log_extents_lock[index]);
-               /*
-                * we've dropped the lock, we must either break or
-                * start over after this.
-                */
 
                if (ordered->csum_bytes_left) {
                        btrfs_start_ordered_extent(inode, ordered, 0);
 
                list_for_each_entry(sum, &ordered->list, list) {
                        ret = btrfs_csum_file_blocks(trans, log, sum);
-                       if (ret) {
-                               btrfs_put_ordered_extent(ordered);
+                       if (ret)
                                goto unlocked;
-                       }
                }
-               btrfs_put_ordered_extent(ordered);
-               goto again;
 
        }
-       spin_unlock_irq(&log->log_extents_lock[index]);
 unlocked:
 
        if (!mod_len || ret)
 static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans,
                                     struct btrfs_root *root,
                                     struct inode *inode,
-                                    struct btrfs_path *path)
+                                    struct btrfs_path *path,
+                                    struct list_head *logged_list)
 {
        struct extent_map *em, *n;
        struct list_head extents;
 
                write_unlock(&tree->lock);
 
-               ret = log_one_extent(trans, inode, root, em, path);
+               ret = log_one_extent(trans, inode, root, em, path, logged_list);
                write_lock(&tree->lock);
                clear_em_logging(tree, em);
                free_extent_map(em);
        struct btrfs_key max_key;
        struct btrfs_root *log = root->log_root;
        struct extent_buffer *src = NULL;
+       LIST_HEAD(logged_list);
        u64 last_extent = 0;
        int err = 0;
        int ret;
 
        mutex_lock(&BTRFS_I(inode)->log_mutex);
 
-       btrfs_get_logged_extents(log, inode);
+       btrfs_get_logged_extents(inode, &logged_list);
 
        /*
         * a brute force approach to making sure we get the most uptodate
        btrfs_release_path(path);
        btrfs_release_path(dst_path);
        if (fast_search) {
-               ret = btrfs_log_changed_extents(trans, root, inode, dst_path);
+               ret = btrfs_log_changed_extents(trans, root, inode, dst_path,
+                                               &logged_list);
                if (ret) {
                        err = ret;
                        goto out_unlock;
        BTRFS_I(inode)->logged_trans = trans->transid;
        BTRFS_I(inode)->last_log_commit = BTRFS_I(inode)->last_sub_trans;
 out_unlock:
-       if (err)
-               btrfs_free_logged_extents(log, log->log_transid);
+       if (unlikely(err))
+               btrfs_put_logged_extents(&logged_list);
+       else
+               btrfs_submit_logged_extents(&logged_list, log);
        mutex_unlock(&BTRFS_I(inode)->log_mutex);
 
        btrfs_free_path(path);