}
 #endif
 
+static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr,
+                               u64 num_bytes)
+{
+#ifdef BIO_RW_DISCARD
+       int ret;
+       u64 map_length = num_bytes;
+       struct btrfs_multi_bio *multi = NULL;
+
+       /* Tell the block device(s) that the sectors can be discarded */
+       ret = btrfs_map_block(&root->fs_info->mapping_tree, READ,
+                             bytenr, &map_length, &multi, 0);
+       if (!ret) {
+               struct btrfs_bio_stripe *stripe = multi->stripes;
+               int i;
+
+               if (map_length > num_bytes)
+                       map_length = num_bytes;
+
+               for (i = 0; i < multi->num_stripes; i++, stripe++) {
+                       btrfs_issue_discard(stripe->dev->bdev,
+                                           stripe->physical,
+                                           map_length);
+               }
+               kfree(multi);
+       }
+
+       return ret;
+#else
+       return 0;
+#endif
+}
+
 static int noinline free_extents(struct btrfs_trans_handle *trans,
                                 struct btrfs_root *extent_root,
                                 struct list_head *del_list)
                for (pos = cur, n = pos->next; pos != end;
                     pos = n, n = pos->next) {
                        struct pending_extent_op *tmp;
-#ifdef BIO_RW_DISCARD
-                       u64 map_length;
-                       struct btrfs_multi_bio *multi = NULL;
-#endif
                        tmp = list_entry(pos, struct pending_extent_op, list);
 
                        /*
                                                 tmp->del);
                        BUG_ON(ret);
 
-#ifdef BIO_RW_DISCARD
-                       map_length = tmp->num_bytes;
-                       ret = btrfs_map_block(&info->mapping_tree, READ,
-                                             tmp->bytenr, &map_length, &multi,
-                                             0);
-                       if (!ret) {
-                               struct btrfs_bio_stripe *stripe;
-                               int i;
-
-                               stripe = multi->stripes;
-
-                               if (map_length > tmp->num_bytes)
-                                       map_length = tmp->num_bytes;
-
-                               for (i = 0; i < multi->num_stripes;
-                                    i++, stripe++)
-                                       btrfs_issue_discard(stripe->dev->bdev,
-                                                           stripe->physical,
-                                                           map_length);
-                               kfree(multi);
-                       }
-#endif
                        list_del_init(&tmp->list);
                        unlock_extent(&info->extent_ins, tmp->bytenr,
                                      tmp->bytenr + tmp->num_bytes - 1,
                        spin_unlock(&cache->space_info->lock);
                        if (mark_free) {
                                int ret;
+
+                               ret = btrfs_discard_extent(root, bytenr,
+                                                          num_bytes);
+                               WARN_ON(ret);
+
                                ret = btrfs_add_free_space(cache, bytenr,
                                                           num_bytes);
                                WARN_ON(ret);
                                            EXTENT_DIRTY);
                if (ret)
                        break;
+
+               ret = btrfs_discard_extent(root, start, end + 1 - start);
+
                btrfs_update_pinned_extents(root, start, end + 1 - start, 0);
                clear_extent_dirty(unpin, start, end, GFP_NOFS);
+
                if (need_resched()) {
                        mutex_unlock(&root->fs_info->pinned_mutex);
                        cond_resched();
                }
        }
        mutex_unlock(&root->fs_info->pinned_mutex);
-       return 0;
+       return ret;
 }
 
 static int finish_current_insert(struct btrfs_trans_handle *trans,
        if (refs == 0) {
                u64 super_used;
                u64 root_used;
-#ifdef BIO_RW_DISCARD
-               u64 map_length = num_bytes;
-               struct btrfs_multi_bio *multi = NULL;
-#endif
 
                if (pin) {
                        mutex_lock(&root->fs_info->pinned_mutex);
                ret = update_block_group(trans, root, bytenr, num_bytes, 0,
                                         mark_free);
                BUG_ON(ret);
-#ifdef BIO_RW_DISCARD
-               /* Tell the block device(s) that the sectors can be discarded */
-               ret = btrfs_map_block(&root->fs_info->mapping_tree, READ,
-                                     bytenr, &map_length, &multi, 0);
-               if (!ret) {
-                       struct btrfs_bio_stripe *stripe = multi->stripes;
-                       int i;
-
-                       if (map_length > num_bytes)
-                               map_length = num_bytes;
-
-                       for (i = 0; i < multi->num_stripes; i++, stripe++) {
-                               btrfs_issue_discard(stripe->dev->bdev,
-                                                   stripe->physical,
-                                                    map_length);
-                       }
-                       kfree(multi);
-               }
-#endif
        }
        btrfs_free_path(path);
        finish_current_insert(trans, extent_root, 0);
 int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len)
 {
        struct btrfs_block_group_cache *cache;
+       int ret = 0;
 
        cache = btrfs_lookup_block_group(root->fs_info, start);
        if (!cache) {
                printk(KERN_ERR "Unable to find block group for %Lu\n", start);
                return -ENOSPC;
        }
+
+       ret = btrfs_discard_extent(root, start, len);
+
        btrfs_add_free_space(cache, start, len);
        put_block_group(cache);
        update_reserved_extents(root, start, len, 0);
-       return 0;
+
+       return ret;
 }
 
 int btrfs_reserve_extent(struct btrfs_trans_handle *trans,