diff options
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r-- | fs/btrfs/extent-tree.c | 339 |
1 files changed, 290 insertions, 49 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 7527523c2d2d..9abf81f71c46 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -60,6 +60,10 @@ static int update_block_group(struct btrfs_trans_handle *trans, | |||
60 | u64 bytenr, u64 num_bytes, int alloc, | 60 | u64 bytenr, u64 num_bytes, int alloc, |
61 | int mark_free); | 61 | int mark_free); |
62 | 62 | ||
63 | static int do_chunk_alloc(struct btrfs_trans_handle *trans, | ||
64 | struct btrfs_root *extent_root, u64 alloc_bytes, | ||
65 | u64 flags, int force); | ||
66 | |||
63 | static int block_group_bits(struct btrfs_block_group_cache *cache, u64 bits) | 67 | static int block_group_bits(struct btrfs_block_group_cache *cache, u64 bits) |
64 | { | 68 | { |
65 | return (cache->flags & bits) == bits; | 69 | return (cache->flags & bits) == bits; |
@@ -1323,8 +1327,25 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | |||
1323 | int btrfs_extent_post_op(struct btrfs_trans_handle *trans, | 1327 | int btrfs_extent_post_op(struct btrfs_trans_handle *trans, |
1324 | struct btrfs_root *root) | 1328 | struct btrfs_root *root) |
1325 | { | 1329 | { |
1326 | finish_current_insert(trans, root->fs_info->extent_root, 1); | 1330 | u64 start; |
1327 | del_pending_extents(trans, root->fs_info->extent_root, 1); | 1331 | u64 end; |
1332 | int ret; | ||
1333 | |||
1334 | while(1) { | ||
1335 | finish_current_insert(trans, root->fs_info->extent_root, 1); | ||
1336 | del_pending_extents(trans, root->fs_info->extent_root, 1); | ||
1337 | |||
1338 | /* is there more work to do? */ | ||
1339 | ret = find_first_extent_bit(&root->fs_info->pending_del, | ||
1340 | 0, &start, &end, EXTENT_WRITEBACK); | ||
1341 | if (!ret) | ||
1342 | continue; | ||
1343 | ret = find_first_extent_bit(&root->fs_info->extent_ins, | ||
1344 | 0, &start, &end, EXTENT_WRITEBACK); | ||
1345 | if (!ret) | ||
1346 | continue; | ||
1347 | break; | ||
1348 | } | ||
1328 | return 0; | 1349 | return 0; |
1329 | } | 1350 | } |
1330 | 1351 | ||
@@ -1892,6 +1913,7 @@ static int update_space_info(struct btrfs_fs_info *info, u64 flags, | |||
1892 | found->bytes_pinned = 0; | 1913 | found->bytes_pinned = 0; |
1893 | found->bytes_reserved = 0; | 1914 | found->bytes_reserved = 0; |
1894 | found->bytes_readonly = 0; | 1915 | found->bytes_readonly = 0; |
1916 | found->bytes_delalloc = 0; | ||
1895 | found->full = 0; | 1917 | found->full = 0; |
1896 | found->force_alloc = 0; | 1918 | found->force_alloc = 0; |
1897 | *space_info = found; | 1919 | *space_info = found; |
@@ -1955,6 +1977,233 @@ u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags) | |||
1955 | return flags; | 1977 | return flags; |
1956 | } | 1978 | } |
1957 | 1979 | ||
1980 | static u64 btrfs_get_alloc_profile(struct btrfs_root *root, u64 data) | ||
1981 | { | ||
1982 | struct btrfs_fs_info *info = root->fs_info; | ||
1983 | u64 alloc_profile; | ||
1984 | |||
1985 | if (data) { | ||
1986 | alloc_profile = info->avail_data_alloc_bits & | ||
1987 | info->data_alloc_profile; | ||
1988 | data = BTRFS_BLOCK_GROUP_DATA | alloc_profile; | ||
1989 | } else if (root == root->fs_info->chunk_root) { | ||
1990 | alloc_profile = info->avail_system_alloc_bits & | ||
1991 | info->system_alloc_profile; | ||
1992 | data = BTRFS_BLOCK_GROUP_SYSTEM | alloc_profile; | ||
1993 | } else { | ||
1994 | alloc_profile = info->avail_metadata_alloc_bits & | ||
1995 | info->metadata_alloc_profile; | ||
1996 | data = BTRFS_BLOCK_GROUP_METADATA | alloc_profile; | ||
1997 | } | ||
1998 | |||
1999 | return btrfs_reduce_alloc_profile(root, data); | ||
2000 | } | ||
2001 | |||
2002 | void btrfs_set_inode_space_info(struct btrfs_root *root, struct inode *inode) | ||
2003 | { | ||
2004 | u64 alloc_target; | ||
2005 | |||
2006 | alloc_target = btrfs_get_alloc_profile(root, 1); | ||
2007 | BTRFS_I(inode)->space_info = __find_space_info(root->fs_info, | ||
2008 | alloc_target); | ||
2009 | } | ||
2010 | |||
2011 | /* | ||
2012 | * for now this just makes sure we have at least 5% of our metadata space free | ||
2013 | * for use. | ||
2014 | */ | ||
2015 | int btrfs_check_metadata_free_space(struct btrfs_root *root) | ||
2016 | { | ||
2017 | struct btrfs_fs_info *info = root->fs_info; | ||
2018 | struct btrfs_space_info *meta_sinfo; | ||
2019 | u64 alloc_target, thresh; | ||
2020 | int committed = 0, ret; | ||
2021 | |||
2022 | /* get the space info for where the metadata will live */ | ||
2023 | alloc_target = btrfs_get_alloc_profile(root, 0); | ||
2024 | meta_sinfo = __find_space_info(info, alloc_target); | ||
2025 | |||
2026 | again: | ||
2027 | spin_lock(&meta_sinfo->lock); | ||
2028 | if (!meta_sinfo->full) | ||
2029 | thresh = meta_sinfo->total_bytes * 80; | ||
2030 | else | ||
2031 | thresh = meta_sinfo->total_bytes * 95; | ||
2032 | |||
2033 | do_div(thresh, 100); | ||
2034 | |||
2035 | if (meta_sinfo->bytes_used + meta_sinfo->bytes_reserved + | ||
2036 | meta_sinfo->bytes_pinned + meta_sinfo->bytes_readonly > thresh) { | ||
2037 | struct btrfs_trans_handle *trans; | ||
2038 | if (!meta_sinfo->full) { | ||
2039 | meta_sinfo->force_alloc = 1; | ||
2040 | spin_unlock(&meta_sinfo->lock); | ||
2041 | |||
2042 | trans = btrfs_start_transaction(root, 1); | ||
2043 | if (!trans) | ||
2044 | return -ENOMEM; | ||
2045 | |||
2046 | ret = do_chunk_alloc(trans, root->fs_info->extent_root, | ||
2047 | 2 * 1024 * 1024, alloc_target, 0); | ||
2048 | btrfs_end_transaction(trans, root); | ||
2049 | goto again; | ||
2050 | } | ||
2051 | spin_unlock(&meta_sinfo->lock); | ||
2052 | |||
2053 | if (!committed) { | ||
2054 | committed = 1; | ||
2055 | trans = btrfs_join_transaction(root, 1); | ||
2056 | if (!trans) | ||
2057 | return -ENOMEM; | ||
2058 | ret = btrfs_commit_transaction(trans, root); | ||
2059 | if (ret) | ||
2060 | return ret; | ||
2061 | goto again; | ||
2062 | } | ||
2063 | return -ENOSPC; | ||
2064 | } | ||
2065 | spin_unlock(&meta_sinfo->lock); | ||
2066 | |||
2067 | return 0; | ||
2068 | } | ||
2069 | |||
2070 | /* | ||
2071 | * This will check the space that the inode allocates from to make sure we have | ||
2072 | * enough space for bytes. | ||
2073 | */ | ||
2074 | int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode, | ||
2075 | u64 bytes) | ||
2076 | { | ||
2077 | struct btrfs_space_info *data_sinfo; | ||
2078 | int ret = 0, committed = 0; | ||
2079 | |||
2080 | /* make sure bytes are sectorsize aligned */ | ||
2081 | bytes = (bytes + root->sectorsize - 1) & ~((u64)root->sectorsize - 1); | ||
2082 | |||
2083 | data_sinfo = BTRFS_I(inode)->space_info; | ||
2084 | again: | ||
2085 | /* make sure we have enough space to handle the data first */ | ||
2086 | spin_lock(&data_sinfo->lock); | ||
2087 | if (data_sinfo->total_bytes - data_sinfo->bytes_used - | ||
2088 | data_sinfo->bytes_delalloc - data_sinfo->bytes_reserved - | ||
2089 | data_sinfo->bytes_pinned - data_sinfo->bytes_readonly - | ||
2090 | data_sinfo->bytes_may_use < bytes) { | ||
2091 | struct btrfs_trans_handle *trans; | ||
2092 | |||
2093 | /* | ||
2094 | * if we don't have enough free bytes in this space then we need | ||
2095 | * to alloc a new chunk. | ||
2096 | */ | ||
2097 | if (!data_sinfo->full) { | ||
2098 | u64 alloc_target; | ||
2099 | |||
2100 | data_sinfo->force_alloc = 1; | ||
2101 | spin_unlock(&data_sinfo->lock); | ||
2102 | |||
2103 | alloc_target = btrfs_get_alloc_profile(root, 1); | ||
2104 | trans = btrfs_start_transaction(root, 1); | ||
2105 | if (!trans) | ||
2106 | return -ENOMEM; | ||
2107 | |||
2108 | ret = do_chunk_alloc(trans, root->fs_info->extent_root, | ||
2109 | bytes + 2 * 1024 * 1024, | ||
2110 | alloc_target, 0); | ||
2111 | btrfs_end_transaction(trans, root); | ||
2112 | if (ret) | ||
2113 | return ret; | ||
2114 | goto again; | ||
2115 | } | ||
2116 | spin_unlock(&data_sinfo->lock); | ||
2117 | |||
2118 | /* commit the current transaction and try again */ | ||
2119 | if (!committed) { | ||
2120 | committed = 1; | ||
2121 | trans = btrfs_join_transaction(root, 1); | ||
2122 | if (!trans) | ||
2123 | return -ENOMEM; | ||
2124 | ret = btrfs_commit_transaction(trans, root); | ||
2125 | if (ret) | ||
2126 | return ret; | ||
2127 | goto again; | ||
2128 | } | ||
2129 | |||
2130 | printk(KERN_ERR "no space left, need %llu, %llu delalloc bytes" | ||
2131 | ", %llu bytes_used, %llu bytes_reserved, " | ||
2132 | "%llu bytes_pinned, %llu bytes_readonly, %llu may use" | ||
2133 | "%llu total\n", bytes, data_sinfo->bytes_delalloc, | ||
2134 | data_sinfo->bytes_used, data_sinfo->bytes_reserved, | ||
2135 | data_sinfo->bytes_pinned, data_sinfo->bytes_readonly, | ||
2136 | data_sinfo->bytes_may_use, data_sinfo->total_bytes); | ||
2137 | return -ENOSPC; | ||
2138 | } | ||
2139 | data_sinfo->bytes_may_use += bytes; | ||
2140 | BTRFS_I(inode)->reserved_bytes += bytes; | ||
2141 | spin_unlock(&data_sinfo->lock); | ||
2142 | |||
2143 | return btrfs_check_metadata_free_space(root); | ||
2144 | } | ||
2145 | |||
2146 | /* | ||
2147 | * if there was an error for whatever reason after calling | ||
2148 | * btrfs_check_data_free_space, call this so we can cleanup the counters. | ||
2149 | */ | ||
2150 | void btrfs_free_reserved_data_space(struct btrfs_root *root, | ||
2151 | struct inode *inode, u64 bytes) | ||
2152 | { | ||
2153 | struct btrfs_space_info *data_sinfo; | ||
2154 | |||
2155 | /* make sure bytes are sectorsize aligned */ | ||
2156 | bytes = (bytes + root->sectorsize - 1) & ~((u64)root->sectorsize - 1); | ||
2157 | |||
2158 | data_sinfo = BTRFS_I(inode)->space_info; | ||
2159 | spin_lock(&data_sinfo->lock); | ||
2160 | data_sinfo->bytes_may_use -= bytes; | ||
2161 | BTRFS_I(inode)->reserved_bytes -= bytes; | ||
2162 | spin_unlock(&data_sinfo->lock); | ||
2163 | } | ||
2164 | |||
2165 | /* called when we are adding a delalloc extent to the inode's io_tree */ | ||
2166 | void btrfs_delalloc_reserve_space(struct btrfs_root *root, struct inode *inode, | ||
2167 | u64 bytes) | ||
2168 | { | ||
2169 | struct btrfs_space_info *data_sinfo; | ||
2170 | |||
2171 | /* get the space info for where this inode will be storing its data */ | ||
2172 | data_sinfo = BTRFS_I(inode)->space_info; | ||
2173 | |||
2174 | /* make sure we have enough space to handle the data first */ | ||
2175 | spin_lock(&data_sinfo->lock); | ||
2176 | data_sinfo->bytes_delalloc += bytes; | ||
2177 | |||
2178 | /* | ||
2179 | * we are adding a delalloc extent without calling | ||
2180 | * btrfs_check_data_free_space first. This happens on a weird | ||
2181 | * writepage condition, but shouldn't hurt our accounting | ||
2182 | */ | ||
2183 | if (unlikely(bytes > BTRFS_I(inode)->reserved_bytes)) { | ||
2184 | data_sinfo->bytes_may_use -= BTRFS_I(inode)->reserved_bytes; | ||
2185 | BTRFS_I(inode)->reserved_bytes = 0; | ||
2186 | } else { | ||
2187 | data_sinfo->bytes_may_use -= bytes; | ||
2188 | BTRFS_I(inode)->reserved_bytes -= bytes; | ||
2189 | } | ||
2190 | |||
2191 | spin_unlock(&data_sinfo->lock); | ||
2192 | } | ||
2193 | |||
2194 | /* called when we are clearing an delalloc extent from the inode's io_tree */ | ||
2195 | void btrfs_delalloc_free_space(struct btrfs_root *root, struct inode *inode, | ||
2196 | u64 bytes) | ||
2197 | { | ||
2198 | struct btrfs_space_info *info; | ||
2199 | |||
2200 | info = BTRFS_I(inode)->space_info; | ||
2201 | |||
2202 | spin_lock(&info->lock); | ||
2203 | info->bytes_delalloc -= bytes; | ||
2204 | spin_unlock(&info->lock); | ||
2205 | } | ||
2206 | |||
1958 | static int do_chunk_alloc(struct btrfs_trans_handle *trans, | 2207 | static int do_chunk_alloc(struct btrfs_trans_handle *trans, |
1959 | struct btrfs_root *extent_root, u64 alloc_bytes, | 2208 | struct btrfs_root *extent_root, u64 alloc_bytes, |
1960 | u64 flags, int force) | 2209 | u64 flags, int force) |
@@ -2211,13 +2460,12 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, | |||
2211 | u64 end; | 2460 | u64 end; |
2212 | u64 priv; | 2461 | u64 priv; |
2213 | u64 search = 0; | 2462 | u64 search = 0; |
2214 | u64 skipped = 0; | ||
2215 | struct btrfs_fs_info *info = extent_root->fs_info; | 2463 | struct btrfs_fs_info *info = extent_root->fs_info; |
2216 | struct btrfs_path *path; | 2464 | struct btrfs_path *path; |
2217 | struct pending_extent_op *extent_op, *tmp; | 2465 | struct pending_extent_op *extent_op, *tmp; |
2218 | struct list_head insert_list, update_list; | 2466 | struct list_head insert_list, update_list; |
2219 | int ret; | 2467 | int ret; |
2220 | int num_inserts = 0, max_inserts; | 2468 | int num_inserts = 0, max_inserts, restart = 0; |
2221 | 2469 | ||
2222 | path = btrfs_alloc_path(); | 2470 | path = btrfs_alloc_path(); |
2223 | INIT_LIST_HEAD(&insert_list); | 2471 | INIT_LIST_HEAD(&insert_list); |
@@ -2233,19 +2481,19 @@ again: | |||
2233 | ret = find_first_extent_bit(&info->extent_ins, search, &start, | 2481 | ret = find_first_extent_bit(&info->extent_ins, search, &start, |
2234 | &end, EXTENT_WRITEBACK); | 2482 | &end, EXTENT_WRITEBACK); |
2235 | if (ret) { | 2483 | if (ret) { |
2236 | if (skipped && all && !num_inserts && | 2484 | if (restart && !num_inserts && |
2237 | list_empty(&update_list)) { | 2485 | list_empty(&update_list)) { |
2238 | skipped = 0; | 2486 | restart = 0; |
2239 | search = 0; | 2487 | search = 0; |
2240 | continue; | 2488 | continue; |
2241 | } | 2489 | } |
2242 | mutex_unlock(&info->extent_ins_mutex); | ||
2243 | break; | 2490 | break; |
2244 | } | 2491 | } |
2245 | 2492 | ||
2246 | ret = try_lock_extent(&info->extent_ins, start, end, GFP_NOFS); | 2493 | ret = try_lock_extent(&info->extent_ins, start, end, GFP_NOFS); |
2247 | if (!ret) { | 2494 | if (!ret) { |
2248 | skipped = 1; | 2495 | if (all) |
2496 | restart = 1; | ||
2249 | search = end + 1; | 2497 | search = end + 1; |
2250 | if (need_resched()) { | 2498 | if (need_resched()) { |
2251 | mutex_unlock(&info->extent_ins_mutex); | 2499 | mutex_unlock(&info->extent_ins_mutex); |
@@ -2264,7 +2512,7 @@ again: | |||
2264 | list_add_tail(&extent_op->list, &insert_list); | 2512 | list_add_tail(&extent_op->list, &insert_list); |
2265 | search = end + 1; | 2513 | search = end + 1; |
2266 | if (num_inserts == max_inserts) { | 2514 | if (num_inserts == max_inserts) { |
2267 | mutex_unlock(&info->extent_ins_mutex); | 2515 | restart = 1; |
2268 | break; | 2516 | break; |
2269 | } | 2517 | } |
2270 | } else if (extent_op->type == PENDING_BACKREF_UPDATE) { | 2518 | } else if (extent_op->type == PENDING_BACKREF_UPDATE) { |
@@ -2280,7 +2528,6 @@ again: | |||
2280 | * somebody marked this thing for deletion then just unlock it and be | 2528 | * somebody marked this thing for deletion then just unlock it and be |
2281 | * done, the free_extents will handle it | 2529 | * done, the free_extents will handle it |
2282 | */ | 2530 | */ |
2283 | mutex_lock(&info->extent_ins_mutex); | ||
2284 | list_for_each_entry_safe(extent_op, tmp, &update_list, list) { | 2531 | list_for_each_entry_safe(extent_op, tmp, &update_list, list) { |
2285 | clear_extent_bits(&info->extent_ins, extent_op->bytenr, | 2532 | clear_extent_bits(&info->extent_ins, extent_op->bytenr, |
2286 | extent_op->bytenr + extent_op->num_bytes - 1, | 2533 | extent_op->bytenr + extent_op->num_bytes - 1, |
@@ -2302,6 +2549,10 @@ again: | |||
2302 | if (!list_empty(&update_list)) { | 2549 | if (!list_empty(&update_list)) { |
2303 | ret = update_backrefs(trans, extent_root, path, &update_list); | 2550 | ret = update_backrefs(trans, extent_root, path, &update_list); |
2304 | BUG_ON(ret); | 2551 | BUG_ON(ret); |
2552 | |||
2553 | /* we may have COW'ed new blocks, so lets start over */ | ||
2554 | if (all) | ||
2555 | restart = 1; | ||
2305 | } | 2556 | } |
2306 | 2557 | ||
2307 | /* | 2558 | /* |
@@ -2309,9 +2560,9 @@ again: | |||
2309 | * need to make sure everything is cleaned then reset everything and | 2560 | * need to make sure everything is cleaned then reset everything and |
2310 | * go back to the beginning | 2561 | * go back to the beginning |
2311 | */ | 2562 | */ |
2312 | if (!num_inserts && all && skipped) { | 2563 | if (!num_inserts && restart) { |
2313 | search = 0; | 2564 | search = 0; |
2314 | skipped = 0; | 2565 | restart = 0; |
2315 | INIT_LIST_HEAD(&update_list); | 2566 | INIT_LIST_HEAD(&update_list); |
2316 | INIT_LIST_HEAD(&insert_list); | 2567 | INIT_LIST_HEAD(&insert_list); |
2317 | goto again; | 2568 | goto again; |
@@ -2368,27 +2619,19 @@ again: | |||
2368 | BUG_ON(ret); | 2619 | BUG_ON(ret); |
2369 | 2620 | ||
2370 | /* | 2621 | /* |
2371 | * if we broke out of the loop in order to insert stuff because we hit | 2622 | * if restart is set for whatever reason we need to go back and start |
2372 | * the maximum number of inserts at a time we can handle, then loop | 2623 | * searching through the pending list again. |
2373 | * back and pick up where we left off | 2624 | * |
2625 | * We just inserted some extents, which could have resulted in new | ||
2626 | * blocks being allocated, which would result in new blocks needing | ||
2627 | * updates, so if all is set we _must_ restart to get the updated | ||
2628 | * blocks. | ||
2374 | */ | 2629 | */ |
2375 | if (num_inserts == max_inserts) { | 2630 | if (restart || all) { |
2376 | INIT_LIST_HEAD(&insert_list); | ||
2377 | INIT_LIST_HEAD(&update_list); | ||
2378 | num_inserts = 0; | ||
2379 | goto again; | ||
2380 | } | ||
2381 | |||
2382 | /* | ||
2383 | * again, if we need to make absolutely sure there are no more pending | ||
2384 | * extent operations left and we know that we skipped some, go back to | ||
2385 | * the beginning and do it all again | ||
2386 | */ | ||
2387 | if (all && skipped) { | ||
2388 | INIT_LIST_HEAD(&insert_list); | 2631 | INIT_LIST_HEAD(&insert_list); |
2389 | INIT_LIST_HEAD(&update_list); | 2632 | INIT_LIST_HEAD(&update_list); |
2390 | search = 0; | 2633 | search = 0; |
2391 | skipped = 0; | 2634 | restart = 0; |
2392 | num_inserts = 0; | 2635 | num_inserts = 0; |
2393 | goto again; | 2636 | goto again; |
2394 | } | 2637 | } |
@@ -2709,6 +2952,8 @@ again: | |||
2709 | goto again; | 2952 | goto again; |
2710 | } | 2953 | } |
2711 | 2954 | ||
2955 | if (!err) | ||
2956 | finish_current_insert(trans, extent_root, 0); | ||
2712 | return err; | 2957 | return err; |
2713 | } | 2958 | } |
2714 | 2959 | ||
@@ -2859,7 +3104,8 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, | |||
2859 | 3104 | ||
2860 | if (data & BTRFS_BLOCK_GROUP_METADATA) { | 3105 | if (data & BTRFS_BLOCK_GROUP_METADATA) { |
2861 | last_ptr = &root->fs_info->last_alloc; | 3106 | last_ptr = &root->fs_info->last_alloc; |
2862 | empty_cluster = 64 * 1024; | 3107 | if (!btrfs_test_opt(root, SSD)) |
3108 | empty_cluster = 64 * 1024; | ||
2863 | } | 3109 | } |
2864 | 3110 | ||
2865 | if ((data & BTRFS_BLOCK_GROUP_DATA) && btrfs_test_opt(root, SSD)) | 3111 | if ((data & BTRFS_BLOCK_GROUP_DATA) && btrfs_test_opt(root, SSD)) |
@@ -3091,6 +3337,10 @@ static void dump_space_info(struct btrfs_space_info *info, u64 bytes) | |||
3091 | (unsigned long long)(info->total_bytes - info->bytes_used - | 3337 | (unsigned long long)(info->total_bytes - info->bytes_used - |
3092 | info->bytes_pinned - info->bytes_reserved), | 3338 | info->bytes_pinned - info->bytes_reserved), |
3093 | (info->full) ? "" : "not "); | 3339 | (info->full) ? "" : "not "); |
3340 | printk(KERN_INFO "space_info total=%llu, pinned=%llu, delalloc=%llu," | ||
3341 | " may_use=%llu, used=%llu\n", info->total_bytes, | ||
3342 | info->bytes_pinned, info->bytes_delalloc, info->bytes_may_use, | ||
3343 | info->bytes_used); | ||
3094 | 3344 | ||
3095 | down_read(&info->groups_sem); | 3345 | down_read(&info->groups_sem); |
3096 | list_for_each_entry(cache, &info->block_groups, list) { | 3346 | list_for_each_entry(cache, &info->block_groups, list) { |
@@ -3117,24 +3367,10 @@ static int __btrfs_reserve_extent(struct btrfs_trans_handle *trans, | |||
3117 | { | 3367 | { |
3118 | int ret; | 3368 | int ret; |
3119 | u64 search_start = 0; | 3369 | u64 search_start = 0; |
3120 | u64 alloc_profile; | ||
3121 | struct btrfs_fs_info *info = root->fs_info; | 3370 | struct btrfs_fs_info *info = root->fs_info; |
3122 | 3371 | ||
3123 | if (data) { | 3372 | data = btrfs_get_alloc_profile(root, data); |
3124 | alloc_profile = info->avail_data_alloc_bits & | ||
3125 | info->data_alloc_profile; | ||
3126 | data = BTRFS_BLOCK_GROUP_DATA | alloc_profile; | ||
3127 | } else if (root == root->fs_info->chunk_root) { | ||
3128 | alloc_profile = info->avail_system_alloc_bits & | ||
3129 | info->system_alloc_profile; | ||
3130 | data = BTRFS_BLOCK_GROUP_SYSTEM | alloc_profile; | ||
3131 | } else { | ||
3132 | alloc_profile = info->avail_metadata_alloc_bits & | ||
3133 | info->metadata_alloc_profile; | ||
3134 | data = BTRFS_BLOCK_GROUP_METADATA | alloc_profile; | ||
3135 | } | ||
3136 | again: | 3373 | again: |
3137 | data = btrfs_reduce_alloc_profile(root, data); | ||
3138 | /* | 3374 | /* |
3139 | * the only place that sets empty_size is btrfs_realloc_node, which | 3375 | * the only place that sets empty_size is btrfs_realloc_node, which |
3140 | * is not called recursively on allocations | 3376 | * is not called recursively on allocations |
@@ -3402,7 +3638,8 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans, | |||
3402 | 3638 | ||
3403 | struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, | 3639 | struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, |
3404 | struct btrfs_root *root, | 3640 | struct btrfs_root *root, |
3405 | u64 bytenr, u32 blocksize) | 3641 | u64 bytenr, u32 blocksize, |
3642 | int level) | ||
3406 | { | 3643 | { |
3407 | struct extent_buffer *buf; | 3644 | struct extent_buffer *buf; |
3408 | 3645 | ||
@@ -3410,6 +3647,7 @@ struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, | |||
3410 | if (!buf) | 3647 | if (!buf) |
3411 | return ERR_PTR(-ENOMEM); | 3648 | return ERR_PTR(-ENOMEM); |
3412 | btrfs_set_header_generation(buf, trans->transid); | 3649 | btrfs_set_header_generation(buf, trans->transid); |
3650 | btrfs_set_buffer_lockdep_class(buf, level); | ||
3413 | btrfs_tree_lock(buf); | 3651 | btrfs_tree_lock(buf); |
3414 | clean_tree_block(trans, root, buf); | 3652 | clean_tree_block(trans, root, buf); |
3415 | 3653 | ||
@@ -3453,7 +3691,8 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | |||
3453 | return ERR_PTR(ret); | 3691 | return ERR_PTR(ret); |
3454 | } | 3692 | } |
3455 | 3693 | ||
3456 | buf = btrfs_init_new_buffer(trans, root, ins.objectid, blocksize); | 3694 | buf = btrfs_init_new_buffer(trans, root, ins.objectid, |
3695 | blocksize, level); | ||
3457 | return buf; | 3696 | return buf; |
3458 | } | 3697 | } |
3459 | 3698 | ||
@@ -4179,13 +4418,13 @@ int btrfs_drop_subtree(struct btrfs_trans_handle *trans, | |||
4179 | path = btrfs_alloc_path(); | 4418 | path = btrfs_alloc_path(); |
4180 | BUG_ON(!path); | 4419 | BUG_ON(!path); |
4181 | 4420 | ||
4182 | BUG_ON(!btrfs_tree_locked(parent)); | 4421 | btrfs_assert_tree_locked(parent); |
4183 | parent_level = btrfs_header_level(parent); | 4422 | parent_level = btrfs_header_level(parent); |
4184 | extent_buffer_get(parent); | 4423 | extent_buffer_get(parent); |
4185 | path->nodes[parent_level] = parent; | 4424 | path->nodes[parent_level] = parent; |
4186 | path->slots[parent_level] = btrfs_header_nritems(parent); | 4425 | path->slots[parent_level] = btrfs_header_nritems(parent); |
4187 | 4426 | ||
4188 | BUG_ON(!btrfs_tree_locked(node)); | 4427 | btrfs_assert_tree_locked(node); |
4189 | level = btrfs_header_level(node); | 4428 | level = btrfs_header_level(node); |
4190 | extent_buffer_get(node); | 4429 | extent_buffer_get(node); |
4191 | path->nodes[level] = node; | 4430 | path->nodes[level] = node; |
@@ -5641,7 +5880,9 @@ static noinline int relocate_one_extent(struct btrfs_root *extent_root, | |||
5641 | prev_block = block_start; | 5880 | prev_block = block_start; |
5642 | } | 5881 | } |
5643 | 5882 | ||
5883 | mutex_lock(&extent_root->fs_info->trans_mutex); | ||
5644 | btrfs_record_root_in_trans(found_root); | 5884 | btrfs_record_root_in_trans(found_root); |
5885 | mutex_unlock(&extent_root->fs_info->trans_mutex); | ||
5645 | if (ref_path->owner_objectid >= BTRFS_FIRST_FREE_OBJECTID) { | 5886 | if (ref_path->owner_objectid >= BTRFS_FIRST_FREE_OBJECTID) { |
5646 | /* | 5887 | /* |
5647 | * try to update data extent references while | 5888 | * try to update data extent references while |