aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/extent-tree.c99
1 files changed, 48 insertions, 51 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index fe0e59ab33cc..780c1eeb8299 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -876,6 +876,38 @@ static void btrfs_issue_discard(struct block_device *bdev,
876} 876}
877#endif 877#endif
878 878
879static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr,
880 u64 num_bytes)
881{
882#ifdef BIO_RW_DISCARD
883 int ret;
884 u64 map_length = num_bytes;
885 struct btrfs_multi_bio *multi = NULL;
886
887 /* Tell the block device(s) that the sectors can be discarded */
888 ret = btrfs_map_block(&root->fs_info->mapping_tree, READ,
889 bytenr, &map_length, &multi, 0);
890 if (!ret) {
891 struct btrfs_bio_stripe *stripe = multi->stripes;
892 int i;
893
894 if (map_length > num_bytes)
895 map_length = num_bytes;
896
897 for (i = 0; i < multi->num_stripes; i++, stripe++) {
898 btrfs_issue_discard(stripe->dev->bdev,
899 stripe->physical,
900 map_length);
901 }
902 kfree(multi);
903 }
904
905 return ret;
906#else
907 return 0;
908#endif
909}
910
879static int noinline free_extents(struct btrfs_trans_handle *trans, 911static int noinline free_extents(struct btrfs_trans_handle *trans,
880 struct btrfs_root *extent_root, 912 struct btrfs_root *extent_root,
881 struct list_head *del_list) 913 struct list_head *del_list)
@@ -1069,10 +1101,6 @@ search:
1069 for (pos = cur, n = pos->next; pos != end; 1101 for (pos = cur, n = pos->next; pos != end;
1070 pos = n, n = pos->next) { 1102 pos = n, n = pos->next) {
1071 struct pending_extent_op *tmp; 1103 struct pending_extent_op *tmp;
1072#ifdef BIO_RW_DISCARD
1073 u64 map_length;
1074 struct btrfs_multi_bio *multi = NULL;
1075#endif
1076 tmp = list_entry(pos, struct pending_extent_op, list); 1104 tmp = list_entry(pos, struct pending_extent_op, list);
1077 1105
1078 /* 1106 /*
@@ -1084,28 +1112,6 @@ search:
1084 tmp->del); 1112 tmp->del);
1085 BUG_ON(ret); 1113 BUG_ON(ret);
1086 1114
1087#ifdef BIO_RW_DISCARD
1088 map_length = tmp->num_bytes;
1089 ret = btrfs_map_block(&info->mapping_tree, READ,
1090 tmp->bytenr, &map_length, &multi,
1091 0);
1092 if (!ret) {
1093 struct btrfs_bio_stripe *stripe;
1094 int i;
1095
1096 stripe = multi->stripes;
1097
1098 if (map_length > tmp->num_bytes)
1099 map_length = tmp->num_bytes;
1100
1101 for (i = 0; i < multi->num_stripes;
1102 i++, stripe++)
1103 btrfs_issue_discard(stripe->dev->bdev,
1104 stripe->physical,
1105 map_length);
1106 kfree(multi);
1107 }
1108#endif
1109 list_del_init(&tmp->list); 1115 list_del_init(&tmp->list);
1110 unlock_extent(&info->extent_ins, tmp->bytenr, 1116 unlock_extent(&info->extent_ins, tmp->bytenr,
1111 tmp->bytenr + tmp->num_bytes - 1, 1117 tmp->bytenr + tmp->num_bytes - 1,
@@ -1965,6 +1971,11 @@ static int update_block_group(struct btrfs_trans_handle *trans,
1965 spin_unlock(&cache->space_info->lock); 1971 spin_unlock(&cache->space_info->lock);
1966 if (mark_free) { 1972 if (mark_free) {
1967 int ret; 1973 int ret;
1974
1975 ret = btrfs_discard_extent(root, bytenr,
1976 num_bytes);
1977 WARN_ON(ret);
1978
1968 ret = btrfs_add_free_space(cache, bytenr, 1979 ret = btrfs_add_free_space(cache, bytenr,
1969 num_bytes); 1980 num_bytes);
1970 WARN_ON(ret); 1981 WARN_ON(ret);
@@ -2104,8 +2115,12 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans,
2104 EXTENT_DIRTY); 2115 EXTENT_DIRTY);
2105 if (ret) 2116 if (ret)
2106 break; 2117 break;
2118
2119 ret = btrfs_discard_extent(root, start, end + 1 - start);
2120
2107 btrfs_update_pinned_extents(root, start, end + 1 - start, 0); 2121 btrfs_update_pinned_extents(root, start, end + 1 - start, 0);
2108 clear_extent_dirty(unpin, start, end, GFP_NOFS); 2122 clear_extent_dirty(unpin, start, end, GFP_NOFS);
2123
2109 if (need_resched()) { 2124 if (need_resched()) {
2110 mutex_unlock(&root->fs_info->pinned_mutex); 2125 mutex_unlock(&root->fs_info->pinned_mutex);
2111 cond_resched(); 2126 cond_resched();
@@ -2113,7 +2128,7 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans,
2113 } 2128 }
2114 } 2129 }
2115 mutex_unlock(&root->fs_info->pinned_mutex); 2130 mutex_unlock(&root->fs_info->pinned_mutex);
2116 return 0; 2131 return ret;
2117} 2132}
2118 2133
2119static int finish_current_insert(struct btrfs_trans_handle *trans, 2134static int finish_current_insert(struct btrfs_trans_handle *trans,
@@ -2458,10 +2473,6 @@ static int __free_extent(struct btrfs_trans_handle *trans,
2458 if (refs == 0) { 2473 if (refs == 0) {
2459 u64 super_used; 2474 u64 super_used;
2460 u64 root_used; 2475 u64 root_used;
2461#ifdef BIO_RW_DISCARD
2462 u64 map_length = num_bytes;
2463 struct btrfs_multi_bio *multi = NULL;
2464#endif
2465 2476
2466 if (pin) { 2477 if (pin) {
2467 mutex_lock(&root->fs_info->pinned_mutex); 2478 mutex_lock(&root->fs_info->pinned_mutex);
@@ -2496,25 +2507,6 @@ static int __free_extent(struct btrfs_trans_handle *trans,
2496 ret = update_block_group(trans, root, bytenr, num_bytes, 0, 2507 ret = update_block_group(trans, root, bytenr, num_bytes, 0,
2497 mark_free); 2508 mark_free);
2498 BUG_ON(ret); 2509 BUG_ON(ret);
2499#ifdef BIO_RW_DISCARD
2500 /* Tell the block device(s) that the sectors can be discarded */
2501 ret = btrfs_map_block(&root->fs_info->mapping_tree, READ,
2502 bytenr, &map_length, &multi, 0);
2503 if (!ret) {
2504 struct btrfs_bio_stripe *stripe = multi->stripes;
2505 int i;
2506
2507 if (map_length > num_bytes)
2508 map_length = num_bytes;
2509
2510 for (i = 0; i < multi->num_stripes; i++, stripe++) {
2511 btrfs_issue_discard(stripe->dev->bdev,
2512 stripe->physical,
2513 map_length);
2514 }
2515 kfree(multi);
2516 }
2517#endif
2518 } 2510 }
2519 btrfs_free_path(path); 2511 btrfs_free_path(path);
2520 finish_current_insert(trans, extent_root, 0); 2512 finish_current_insert(trans, extent_root, 0);
@@ -3112,16 +3104,21 @@ again:
3112int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len) 3104int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len)
3113{ 3105{
3114 struct btrfs_block_group_cache *cache; 3106 struct btrfs_block_group_cache *cache;
3107 int ret = 0;
3115 3108
3116 cache = btrfs_lookup_block_group(root->fs_info, start); 3109 cache = btrfs_lookup_block_group(root->fs_info, start);
3117 if (!cache) { 3110 if (!cache) {
3118 printk(KERN_ERR "Unable to find block group for %Lu\n", start); 3111 printk(KERN_ERR "Unable to find block group for %Lu\n", start);
3119 return -ENOSPC; 3112 return -ENOSPC;
3120 } 3113 }
3114
3115 ret = btrfs_discard_extent(root, start, len);
3116
3121 btrfs_add_free_space(cache, start, len); 3117 btrfs_add_free_space(cache, start, len);
3122 put_block_group(cache); 3118 put_block_group(cache);
3123 update_reserved_extents(root, start, len, 0); 3119 update_reserved_extents(root, start, len, 0);
3124 return 0; 3120
3121 return ret;
3125} 3122}
3126 3123
3127int btrfs_reserve_extent(struct btrfs_trans_handle *trans, 3124int btrfs_reserve_extent(struct btrfs_trans_handle *trans,