diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-03-26 10:45:22 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-03-26 10:45:22 -0400 |
commit | a5ebc0b1a7843508b375f7ab8a36a628e5c9f372 (patch) | |
tree | 04d3ab410e08b4d9174c663dd6bf95611dd16d0a /fs/btrfs/extent-tree.c | |
parent | 5ba1ae92b6796b3367152ccd9baa022dde7eed4c (diff) | |
parent | 8e0ee43bc2c3e19db56a4adaa9a9b04ce885cd84 (diff) |
Merge commit 'v2.6.29' into timers/core
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r-- | fs/btrfs/extent-tree.c | 384 |
1 files changed, 332 insertions, 52 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 7527523c2d2d..fefe83ad2059 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/writeback.h> | 20 | #include <linux/writeback.h> |
21 | #include <linux/blkdev.h> | 21 | #include <linux/blkdev.h> |
22 | #include <linux/sort.h> | 22 | #include <linux/sort.h> |
23 | #include <linux/rcupdate.h> | ||
23 | #include "compat.h" | 24 | #include "compat.h" |
24 | #include "hash.h" | 25 | #include "hash.h" |
25 | #include "crc32c.h" | 26 | #include "crc32c.h" |
@@ -60,6 +61,10 @@ static int update_block_group(struct btrfs_trans_handle *trans, | |||
60 | u64 bytenr, u64 num_bytes, int alloc, | 61 | u64 bytenr, u64 num_bytes, int alloc, |
61 | int mark_free); | 62 | int mark_free); |
62 | 63 | ||
64 | static int do_chunk_alloc(struct btrfs_trans_handle *trans, | ||
65 | struct btrfs_root *extent_root, u64 alloc_bytes, | ||
66 | u64 flags, int force); | ||
67 | |||
63 | static int block_group_bits(struct btrfs_block_group_cache *cache, u64 bits) | 68 | static int block_group_bits(struct btrfs_block_group_cache *cache, u64 bits) |
64 | { | 69 | { |
65 | return (cache->flags & bits) == bits; | 70 | return (cache->flags & bits) == bits; |
@@ -326,13 +331,33 @@ static struct btrfs_space_info *__find_space_info(struct btrfs_fs_info *info, | |||
326 | { | 331 | { |
327 | struct list_head *head = &info->space_info; | 332 | struct list_head *head = &info->space_info; |
328 | struct btrfs_space_info *found; | 333 | struct btrfs_space_info *found; |
329 | list_for_each_entry(found, head, list) { | 334 | |
330 | if (found->flags == flags) | 335 | rcu_read_lock(); |
336 | list_for_each_entry_rcu(found, head, list) { | ||
337 | if (found->flags == flags) { | ||
338 | rcu_read_unlock(); | ||
331 | return found; | 339 | return found; |
340 | } | ||
332 | } | 341 | } |
342 | rcu_read_unlock(); | ||
333 | return NULL; | 343 | return NULL; |
334 | } | 344 | } |
335 | 345 | ||
346 | /* | ||
347 | * after adding space to the filesystem, we need to clear the full flags | ||
348 | * on all the space infos. | ||
349 | */ | ||
350 | void btrfs_clear_space_info_full(struct btrfs_fs_info *info) | ||
351 | { | ||
352 | struct list_head *head = &info->space_info; | ||
353 | struct btrfs_space_info *found; | ||
354 | |||
355 | rcu_read_lock(); | ||
356 | list_for_each_entry_rcu(found, head, list) | ||
357 | found->full = 0; | ||
358 | rcu_read_unlock(); | ||
359 | } | ||
360 | |||
336 | static u64 div_factor(u64 num, int factor) | 361 | static u64 div_factor(u64 num, int factor) |
337 | { | 362 | { |
338 | if (factor == 10) | 363 | if (factor == 10) |
@@ -1323,8 +1348,25 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | |||
1323 | int btrfs_extent_post_op(struct btrfs_trans_handle *trans, | 1348 | int btrfs_extent_post_op(struct btrfs_trans_handle *trans, |
1324 | struct btrfs_root *root) | 1349 | struct btrfs_root *root) |
1325 | { | 1350 | { |
1326 | finish_current_insert(trans, root->fs_info->extent_root, 1); | 1351 | u64 start; |
1327 | del_pending_extents(trans, root->fs_info->extent_root, 1); | 1352 | u64 end; |
1353 | int ret; | ||
1354 | |||
1355 | while(1) { | ||
1356 | finish_current_insert(trans, root->fs_info->extent_root, 1); | ||
1357 | del_pending_extents(trans, root->fs_info->extent_root, 1); | ||
1358 | |||
1359 | /* is there more work to do? */ | ||
1360 | ret = find_first_extent_bit(&root->fs_info->pending_del, | ||
1361 | 0, &start, &end, EXTENT_WRITEBACK); | ||
1362 | if (!ret) | ||
1363 | continue; | ||
1364 | ret = find_first_extent_bit(&root->fs_info->extent_ins, | ||
1365 | 0, &start, &end, EXTENT_WRITEBACK); | ||
1366 | if (!ret) | ||
1367 | continue; | ||
1368 | break; | ||
1369 | } | ||
1328 | return 0; | 1370 | return 0; |
1329 | } | 1371 | } |
1330 | 1372 | ||
@@ -1882,7 +1924,6 @@ static int update_space_info(struct btrfs_fs_info *info, u64 flags, | |||
1882 | if (!found) | 1924 | if (!found) |
1883 | return -ENOMEM; | 1925 | return -ENOMEM; |
1884 | 1926 | ||
1885 | list_add(&found->list, &info->space_info); | ||
1886 | INIT_LIST_HEAD(&found->block_groups); | 1927 | INIT_LIST_HEAD(&found->block_groups); |
1887 | init_rwsem(&found->groups_sem); | 1928 | init_rwsem(&found->groups_sem); |
1888 | spin_lock_init(&found->lock); | 1929 | spin_lock_init(&found->lock); |
@@ -1892,9 +1933,11 @@ static int update_space_info(struct btrfs_fs_info *info, u64 flags, | |||
1892 | found->bytes_pinned = 0; | 1933 | found->bytes_pinned = 0; |
1893 | found->bytes_reserved = 0; | 1934 | found->bytes_reserved = 0; |
1894 | found->bytes_readonly = 0; | 1935 | found->bytes_readonly = 0; |
1936 | found->bytes_delalloc = 0; | ||
1895 | found->full = 0; | 1937 | found->full = 0; |
1896 | found->force_alloc = 0; | 1938 | found->force_alloc = 0; |
1897 | *space_info = found; | 1939 | *space_info = found; |
1940 | list_add_rcu(&found->list, &info->space_info); | ||
1898 | return 0; | 1941 | return 0; |
1899 | } | 1942 | } |
1900 | 1943 | ||
@@ -1955,6 +1998,233 @@ u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags) | |||
1955 | return flags; | 1998 | return flags; |
1956 | } | 1999 | } |
1957 | 2000 | ||
2001 | static u64 btrfs_get_alloc_profile(struct btrfs_root *root, u64 data) | ||
2002 | { | ||
2003 | struct btrfs_fs_info *info = root->fs_info; | ||
2004 | u64 alloc_profile; | ||
2005 | |||
2006 | if (data) { | ||
2007 | alloc_profile = info->avail_data_alloc_bits & | ||
2008 | info->data_alloc_profile; | ||
2009 | data = BTRFS_BLOCK_GROUP_DATA | alloc_profile; | ||
2010 | } else if (root == root->fs_info->chunk_root) { | ||
2011 | alloc_profile = info->avail_system_alloc_bits & | ||
2012 | info->system_alloc_profile; | ||
2013 | data = BTRFS_BLOCK_GROUP_SYSTEM | alloc_profile; | ||
2014 | } else { | ||
2015 | alloc_profile = info->avail_metadata_alloc_bits & | ||
2016 | info->metadata_alloc_profile; | ||
2017 | data = BTRFS_BLOCK_GROUP_METADATA | alloc_profile; | ||
2018 | } | ||
2019 | |||
2020 | return btrfs_reduce_alloc_profile(root, data); | ||
2021 | } | ||
2022 | |||
2023 | void btrfs_set_inode_space_info(struct btrfs_root *root, struct inode *inode) | ||
2024 | { | ||
2025 | u64 alloc_target; | ||
2026 | |||
2027 | alloc_target = btrfs_get_alloc_profile(root, 1); | ||
2028 | BTRFS_I(inode)->space_info = __find_space_info(root->fs_info, | ||
2029 | alloc_target); | ||
2030 | } | ||
2031 | |||
2032 | /* | ||
2033 | * for now this just makes sure we have at least 5% of our metadata space free | ||
2034 | * for use. | ||
2035 | */ | ||
2036 | int btrfs_check_metadata_free_space(struct btrfs_root *root) | ||
2037 | { | ||
2038 | struct btrfs_fs_info *info = root->fs_info; | ||
2039 | struct btrfs_space_info *meta_sinfo; | ||
2040 | u64 alloc_target, thresh; | ||
2041 | int committed = 0, ret; | ||
2042 | |||
2043 | /* get the space info for where the metadata will live */ | ||
2044 | alloc_target = btrfs_get_alloc_profile(root, 0); | ||
2045 | meta_sinfo = __find_space_info(info, alloc_target); | ||
2046 | |||
2047 | again: | ||
2048 | spin_lock(&meta_sinfo->lock); | ||
2049 | if (!meta_sinfo->full) | ||
2050 | thresh = meta_sinfo->total_bytes * 80; | ||
2051 | else | ||
2052 | thresh = meta_sinfo->total_bytes * 95; | ||
2053 | |||
2054 | do_div(thresh, 100); | ||
2055 | |||
2056 | if (meta_sinfo->bytes_used + meta_sinfo->bytes_reserved + | ||
2057 | meta_sinfo->bytes_pinned + meta_sinfo->bytes_readonly > thresh) { | ||
2058 | struct btrfs_trans_handle *trans; | ||
2059 | if (!meta_sinfo->full) { | ||
2060 | meta_sinfo->force_alloc = 1; | ||
2061 | spin_unlock(&meta_sinfo->lock); | ||
2062 | |||
2063 | trans = btrfs_start_transaction(root, 1); | ||
2064 | if (!trans) | ||
2065 | return -ENOMEM; | ||
2066 | |||
2067 | ret = do_chunk_alloc(trans, root->fs_info->extent_root, | ||
2068 | 2 * 1024 * 1024, alloc_target, 0); | ||
2069 | btrfs_end_transaction(trans, root); | ||
2070 | goto again; | ||
2071 | } | ||
2072 | spin_unlock(&meta_sinfo->lock); | ||
2073 | |||
2074 | if (!committed) { | ||
2075 | committed = 1; | ||
2076 | trans = btrfs_join_transaction(root, 1); | ||
2077 | if (!trans) | ||
2078 | return -ENOMEM; | ||
2079 | ret = btrfs_commit_transaction(trans, root); | ||
2080 | if (ret) | ||
2081 | return ret; | ||
2082 | goto again; | ||
2083 | } | ||
2084 | return -ENOSPC; | ||
2085 | } | ||
2086 | spin_unlock(&meta_sinfo->lock); | ||
2087 | |||
2088 | return 0; | ||
2089 | } | ||
2090 | |||
2091 | /* | ||
2092 | * This will check the space that the inode allocates from to make sure we have | ||
2093 | * enough space for bytes. | ||
2094 | */ | ||
2095 | int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode, | ||
2096 | u64 bytes) | ||
2097 | { | ||
2098 | struct btrfs_space_info *data_sinfo; | ||
2099 | int ret = 0, committed = 0; | ||
2100 | |||
2101 | /* make sure bytes are sectorsize aligned */ | ||
2102 | bytes = (bytes + root->sectorsize - 1) & ~((u64)root->sectorsize - 1); | ||
2103 | |||
2104 | data_sinfo = BTRFS_I(inode)->space_info; | ||
2105 | again: | ||
2106 | /* make sure we have enough space to handle the data first */ | ||
2107 | spin_lock(&data_sinfo->lock); | ||
2108 | if (data_sinfo->total_bytes - data_sinfo->bytes_used - | ||
2109 | data_sinfo->bytes_delalloc - data_sinfo->bytes_reserved - | ||
2110 | data_sinfo->bytes_pinned - data_sinfo->bytes_readonly - | ||
2111 | data_sinfo->bytes_may_use < bytes) { | ||
2112 | struct btrfs_trans_handle *trans; | ||
2113 | |||
2114 | /* | ||
2115 | * if we don't have enough free bytes in this space then we need | ||
2116 | * to alloc a new chunk. | ||
2117 | */ | ||
2118 | if (!data_sinfo->full) { | ||
2119 | u64 alloc_target; | ||
2120 | |||
2121 | data_sinfo->force_alloc = 1; | ||
2122 | spin_unlock(&data_sinfo->lock); | ||
2123 | |||
2124 | alloc_target = btrfs_get_alloc_profile(root, 1); | ||
2125 | trans = btrfs_start_transaction(root, 1); | ||
2126 | if (!trans) | ||
2127 | return -ENOMEM; | ||
2128 | |||
2129 | ret = do_chunk_alloc(trans, root->fs_info->extent_root, | ||
2130 | bytes + 2 * 1024 * 1024, | ||
2131 | alloc_target, 0); | ||
2132 | btrfs_end_transaction(trans, root); | ||
2133 | if (ret) | ||
2134 | return ret; | ||
2135 | goto again; | ||
2136 | } | ||
2137 | spin_unlock(&data_sinfo->lock); | ||
2138 | |||
2139 | /* commit the current transaction and try again */ | ||
2140 | if (!committed) { | ||
2141 | committed = 1; | ||
2142 | trans = btrfs_join_transaction(root, 1); | ||
2143 | if (!trans) | ||
2144 | return -ENOMEM; | ||
2145 | ret = btrfs_commit_transaction(trans, root); | ||
2146 | if (ret) | ||
2147 | return ret; | ||
2148 | goto again; | ||
2149 | } | ||
2150 | |||
2151 | printk(KERN_ERR "no space left, need %llu, %llu delalloc bytes" | ||
2152 | ", %llu bytes_used, %llu bytes_reserved, " | ||
2153 | "%llu bytes_pinned, %llu bytes_readonly, %llu may use" | ||
2154 | "%llu total\n", bytes, data_sinfo->bytes_delalloc, | ||
2155 | data_sinfo->bytes_used, data_sinfo->bytes_reserved, | ||
2156 | data_sinfo->bytes_pinned, data_sinfo->bytes_readonly, | ||
2157 | data_sinfo->bytes_may_use, data_sinfo->total_bytes); | ||
2158 | return -ENOSPC; | ||
2159 | } | ||
2160 | data_sinfo->bytes_may_use += bytes; | ||
2161 | BTRFS_I(inode)->reserved_bytes += bytes; | ||
2162 | spin_unlock(&data_sinfo->lock); | ||
2163 | |||
2164 | return btrfs_check_metadata_free_space(root); | ||
2165 | } | ||
2166 | |||
2167 | /* | ||
2168 | * if there was an error for whatever reason after calling | ||
2169 | * btrfs_check_data_free_space, call this so we can cleanup the counters. | ||
2170 | */ | ||
2171 | void btrfs_free_reserved_data_space(struct btrfs_root *root, | ||
2172 | struct inode *inode, u64 bytes) | ||
2173 | { | ||
2174 | struct btrfs_space_info *data_sinfo; | ||
2175 | |||
2176 | /* make sure bytes are sectorsize aligned */ | ||
2177 | bytes = (bytes + root->sectorsize - 1) & ~((u64)root->sectorsize - 1); | ||
2178 | |||
2179 | data_sinfo = BTRFS_I(inode)->space_info; | ||
2180 | spin_lock(&data_sinfo->lock); | ||
2181 | data_sinfo->bytes_may_use -= bytes; | ||
2182 | BTRFS_I(inode)->reserved_bytes -= bytes; | ||
2183 | spin_unlock(&data_sinfo->lock); | ||
2184 | } | ||
2185 | |||
2186 | /* called when we are adding a delalloc extent to the inode's io_tree */ | ||
2187 | void btrfs_delalloc_reserve_space(struct btrfs_root *root, struct inode *inode, | ||
2188 | u64 bytes) | ||
2189 | { | ||
2190 | struct btrfs_space_info *data_sinfo; | ||
2191 | |||
2192 | /* get the space info for where this inode will be storing its data */ | ||
2193 | data_sinfo = BTRFS_I(inode)->space_info; | ||
2194 | |||
2195 | /* make sure we have enough space to handle the data first */ | ||
2196 | spin_lock(&data_sinfo->lock); | ||
2197 | data_sinfo->bytes_delalloc += bytes; | ||
2198 | |||
2199 | /* | ||
2200 | * we are adding a delalloc extent without calling | ||
2201 | * btrfs_check_data_free_space first. This happens on a weird | ||
2202 | * writepage condition, but shouldn't hurt our accounting | ||
2203 | */ | ||
2204 | if (unlikely(bytes > BTRFS_I(inode)->reserved_bytes)) { | ||
2205 | data_sinfo->bytes_may_use -= BTRFS_I(inode)->reserved_bytes; | ||
2206 | BTRFS_I(inode)->reserved_bytes = 0; | ||
2207 | } else { | ||
2208 | data_sinfo->bytes_may_use -= bytes; | ||
2209 | BTRFS_I(inode)->reserved_bytes -= bytes; | ||
2210 | } | ||
2211 | |||
2212 | spin_unlock(&data_sinfo->lock); | ||
2213 | } | ||
2214 | |||
2215 | /* called when we are clearing an delalloc extent from the inode's io_tree */ | ||
2216 | void btrfs_delalloc_free_space(struct btrfs_root *root, struct inode *inode, | ||
2217 | u64 bytes) | ||
2218 | { | ||
2219 | struct btrfs_space_info *info; | ||
2220 | |||
2221 | info = BTRFS_I(inode)->space_info; | ||
2222 | |||
2223 | spin_lock(&info->lock); | ||
2224 | info->bytes_delalloc -= bytes; | ||
2225 | spin_unlock(&info->lock); | ||
2226 | } | ||
2227 | |||
1958 | static int do_chunk_alloc(struct btrfs_trans_handle *trans, | 2228 | static int do_chunk_alloc(struct btrfs_trans_handle *trans, |
1959 | struct btrfs_root *extent_root, u64 alloc_bytes, | 2229 | struct btrfs_root *extent_root, u64 alloc_bytes, |
1960 | u64 flags, int force) | 2230 | u64 flags, int force) |
@@ -2211,13 +2481,12 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, | |||
2211 | u64 end; | 2481 | u64 end; |
2212 | u64 priv; | 2482 | u64 priv; |
2213 | u64 search = 0; | 2483 | u64 search = 0; |
2214 | u64 skipped = 0; | ||
2215 | struct btrfs_fs_info *info = extent_root->fs_info; | 2484 | struct btrfs_fs_info *info = extent_root->fs_info; |
2216 | struct btrfs_path *path; | 2485 | struct btrfs_path *path; |
2217 | struct pending_extent_op *extent_op, *tmp; | 2486 | struct pending_extent_op *extent_op, *tmp; |
2218 | struct list_head insert_list, update_list; | 2487 | struct list_head insert_list, update_list; |
2219 | int ret; | 2488 | int ret; |
2220 | int num_inserts = 0, max_inserts; | 2489 | int num_inserts = 0, max_inserts, restart = 0; |
2221 | 2490 | ||
2222 | path = btrfs_alloc_path(); | 2491 | path = btrfs_alloc_path(); |
2223 | INIT_LIST_HEAD(&insert_list); | 2492 | INIT_LIST_HEAD(&insert_list); |
@@ -2233,19 +2502,19 @@ again: | |||
2233 | ret = find_first_extent_bit(&info->extent_ins, search, &start, | 2502 | ret = find_first_extent_bit(&info->extent_ins, search, &start, |
2234 | &end, EXTENT_WRITEBACK); | 2503 | &end, EXTENT_WRITEBACK); |
2235 | if (ret) { | 2504 | if (ret) { |
2236 | if (skipped && all && !num_inserts && | 2505 | if (restart && !num_inserts && |
2237 | list_empty(&update_list)) { | 2506 | list_empty(&update_list)) { |
2238 | skipped = 0; | 2507 | restart = 0; |
2239 | search = 0; | 2508 | search = 0; |
2240 | continue; | 2509 | continue; |
2241 | } | 2510 | } |
2242 | mutex_unlock(&info->extent_ins_mutex); | ||
2243 | break; | 2511 | break; |
2244 | } | 2512 | } |
2245 | 2513 | ||
2246 | ret = try_lock_extent(&info->extent_ins, start, end, GFP_NOFS); | 2514 | ret = try_lock_extent(&info->extent_ins, start, end, GFP_NOFS); |
2247 | if (!ret) { | 2515 | if (!ret) { |
2248 | skipped = 1; | 2516 | if (all) |
2517 | restart = 1; | ||
2249 | search = end + 1; | 2518 | search = end + 1; |
2250 | if (need_resched()) { | 2519 | if (need_resched()) { |
2251 | mutex_unlock(&info->extent_ins_mutex); | 2520 | mutex_unlock(&info->extent_ins_mutex); |
@@ -2264,7 +2533,7 @@ again: | |||
2264 | list_add_tail(&extent_op->list, &insert_list); | 2533 | list_add_tail(&extent_op->list, &insert_list); |
2265 | search = end + 1; | 2534 | search = end + 1; |
2266 | if (num_inserts == max_inserts) { | 2535 | if (num_inserts == max_inserts) { |
2267 | mutex_unlock(&info->extent_ins_mutex); | 2536 | restart = 1; |
2268 | break; | 2537 | break; |
2269 | } | 2538 | } |
2270 | } else if (extent_op->type == PENDING_BACKREF_UPDATE) { | 2539 | } else if (extent_op->type == PENDING_BACKREF_UPDATE) { |
@@ -2280,7 +2549,6 @@ again: | |||
2280 | * somebody marked this thing for deletion then just unlock it and be | 2549 | * somebody marked this thing for deletion then just unlock it and be |
2281 | * done, the free_extents will handle it | 2550 | * done, the free_extents will handle it |
2282 | */ | 2551 | */ |
2283 | mutex_lock(&info->extent_ins_mutex); | ||
2284 | list_for_each_entry_safe(extent_op, tmp, &update_list, list) { | 2552 | list_for_each_entry_safe(extent_op, tmp, &update_list, list) { |
2285 | clear_extent_bits(&info->extent_ins, extent_op->bytenr, | 2553 | clear_extent_bits(&info->extent_ins, extent_op->bytenr, |
2286 | extent_op->bytenr + extent_op->num_bytes - 1, | 2554 | extent_op->bytenr + extent_op->num_bytes - 1, |
@@ -2302,6 +2570,10 @@ again: | |||
2302 | if (!list_empty(&update_list)) { | 2570 | if (!list_empty(&update_list)) { |
2303 | ret = update_backrefs(trans, extent_root, path, &update_list); | 2571 | ret = update_backrefs(trans, extent_root, path, &update_list); |
2304 | BUG_ON(ret); | 2572 | BUG_ON(ret); |
2573 | |||
2574 | /* we may have COW'ed new blocks, so lets start over */ | ||
2575 | if (all) | ||
2576 | restart = 1; | ||
2305 | } | 2577 | } |
2306 | 2578 | ||
2307 | /* | 2579 | /* |
@@ -2309,9 +2581,9 @@ again: | |||
2309 | * need to make sure everything is cleaned then reset everything and | 2581 | * need to make sure everything is cleaned then reset everything and |
2310 | * go back to the beginning | 2582 | * go back to the beginning |
2311 | */ | 2583 | */ |
2312 | if (!num_inserts && all && skipped) { | 2584 | if (!num_inserts && restart) { |
2313 | search = 0; | 2585 | search = 0; |
2314 | skipped = 0; | 2586 | restart = 0; |
2315 | INIT_LIST_HEAD(&update_list); | 2587 | INIT_LIST_HEAD(&update_list); |
2316 | INIT_LIST_HEAD(&insert_list); | 2588 | INIT_LIST_HEAD(&insert_list); |
2317 | goto again; | 2589 | goto again; |
@@ -2368,27 +2640,19 @@ again: | |||
2368 | BUG_ON(ret); | 2640 | BUG_ON(ret); |
2369 | 2641 | ||
2370 | /* | 2642 | /* |
2371 | * if we broke out of the loop in order to insert stuff because we hit | 2643 | * 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 | 2644 | * searching through the pending list again. |
2373 | * back and pick up where we left off | 2645 | * |
2646 | * We just inserted some extents, which could have resulted in new | ||
2647 | * blocks being allocated, which would result in new blocks needing | ||
2648 | * updates, so if all is set we _must_ restart to get the updated | ||
2649 | * blocks. | ||
2374 | */ | 2650 | */ |
2375 | if (num_inserts == max_inserts) { | 2651 | 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); | 2652 | INIT_LIST_HEAD(&insert_list); |
2389 | INIT_LIST_HEAD(&update_list); | 2653 | INIT_LIST_HEAD(&update_list); |
2390 | search = 0; | 2654 | search = 0; |
2391 | skipped = 0; | 2655 | restart = 0; |
2392 | num_inserts = 0; | 2656 | num_inserts = 0; |
2393 | goto again; | 2657 | goto again; |
2394 | } | 2658 | } |
@@ -2709,6 +2973,8 @@ again: | |||
2709 | goto again; | 2973 | goto again; |
2710 | } | 2974 | } |
2711 | 2975 | ||
2976 | if (!err) | ||
2977 | finish_current_insert(trans, extent_root, 0); | ||
2712 | return err; | 2978 | return err; |
2713 | } | 2979 | } |
2714 | 2980 | ||
@@ -2859,7 +3125,8 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, | |||
2859 | 3125 | ||
2860 | if (data & BTRFS_BLOCK_GROUP_METADATA) { | 3126 | if (data & BTRFS_BLOCK_GROUP_METADATA) { |
2861 | last_ptr = &root->fs_info->last_alloc; | 3127 | last_ptr = &root->fs_info->last_alloc; |
2862 | empty_cluster = 64 * 1024; | 3128 | if (!btrfs_test_opt(root, SSD)) |
3129 | empty_cluster = 64 * 1024; | ||
2863 | } | 3130 | } |
2864 | 3131 | ||
2865 | if ((data & BTRFS_BLOCK_GROUP_DATA) && btrfs_test_opt(root, SSD)) | 3132 | if ((data & BTRFS_BLOCK_GROUP_DATA) && btrfs_test_opt(root, SSD)) |
@@ -3091,6 +3358,10 @@ static void dump_space_info(struct btrfs_space_info *info, u64 bytes) | |||
3091 | (unsigned long long)(info->total_bytes - info->bytes_used - | 3358 | (unsigned long long)(info->total_bytes - info->bytes_used - |
3092 | info->bytes_pinned - info->bytes_reserved), | 3359 | info->bytes_pinned - info->bytes_reserved), |
3093 | (info->full) ? "" : "not "); | 3360 | (info->full) ? "" : "not "); |
3361 | printk(KERN_INFO "space_info total=%llu, pinned=%llu, delalloc=%llu," | ||
3362 | " may_use=%llu, used=%llu\n", info->total_bytes, | ||
3363 | info->bytes_pinned, info->bytes_delalloc, info->bytes_may_use, | ||
3364 | info->bytes_used); | ||
3094 | 3365 | ||
3095 | down_read(&info->groups_sem); | 3366 | down_read(&info->groups_sem); |
3096 | list_for_each_entry(cache, &info->block_groups, list) { | 3367 | list_for_each_entry(cache, &info->block_groups, list) { |
@@ -3117,24 +3388,10 @@ static int __btrfs_reserve_extent(struct btrfs_trans_handle *trans, | |||
3117 | { | 3388 | { |
3118 | int ret; | 3389 | int ret; |
3119 | u64 search_start = 0; | 3390 | u64 search_start = 0; |
3120 | u64 alloc_profile; | ||
3121 | struct btrfs_fs_info *info = root->fs_info; | 3391 | struct btrfs_fs_info *info = root->fs_info; |
3122 | 3392 | ||
3123 | if (data) { | 3393 | 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: | 3394 | again: |
3137 | data = btrfs_reduce_alloc_profile(root, data); | ||
3138 | /* | 3395 | /* |
3139 | * the only place that sets empty_size is btrfs_realloc_node, which | 3396 | * the only place that sets empty_size is btrfs_realloc_node, which |
3140 | * is not called recursively on allocations | 3397 | * is not called recursively on allocations |
@@ -3402,7 +3659,8 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans, | |||
3402 | 3659 | ||
3403 | struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, | 3660 | struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, |
3404 | struct btrfs_root *root, | 3661 | struct btrfs_root *root, |
3405 | u64 bytenr, u32 blocksize) | 3662 | u64 bytenr, u32 blocksize, |
3663 | int level) | ||
3406 | { | 3664 | { |
3407 | struct extent_buffer *buf; | 3665 | struct extent_buffer *buf; |
3408 | 3666 | ||
@@ -3410,6 +3668,7 @@ struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, | |||
3410 | if (!buf) | 3668 | if (!buf) |
3411 | return ERR_PTR(-ENOMEM); | 3669 | return ERR_PTR(-ENOMEM); |
3412 | btrfs_set_header_generation(buf, trans->transid); | 3670 | btrfs_set_header_generation(buf, trans->transid); |
3671 | btrfs_set_buffer_lockdep_class(buf, level); | ||
3413 | btrfs_tree_lock(buf); | 3672 | btrfs_tree_lock(buf); |
3414 | clean_tree_block(trans, root, buf); | 3673 | clean_tree_block(trans, root, buf); |
3415 | 3674 | ||
@@ -3453,7 +3712,8 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | |||
3453 | return ERR_PTR(ret); | 3712 | return ERR_PTR(ret); |
3454 | } | 3713 | } |
3455 | 3714 | ||
3456 | buf = btrfs_init_new_buffer(trans, root, ins.objectid, blocksize); | 3715 | buf = btrfs_init_new_buffer(trans, root, ins.objectid, |
3716 | blocksize, level); | ||
3457 | return buf; | 3717 | return buf; |
3458 | } | 3718 | } |
3459 | 3719 | ||
@@ -4179,13 +4439,13 @@ int btrfs_drop_subtree(struct btrfs_trans_handle *trans, | |||
4179 | path = btrfs_alloc_path(); | 4439 | path = btrfs_alloc_path(); |
4180 | BUG_ON(!path); | 4440 | BUG_ON(!path); |
4181 | 4441 | ||
4182 | BUG_ON(!btrfs_tree_locked(parent)); | 4442 | btrfs_assert_tree_locked(parent); |
4183 | parent_level = btrfs_header_level(parent); | 4443 | parent_level = btrfs_header_level(parent); |
4184 | extent_buffer_get(parent); | 4444 | extent_buffer_get(parent); |
4185 | path->nodes[parent_level] = parent; | 4445 | path->nodes[parent_level] = parent; |
4186 | path->slots[parent_level] = btrfs_header_nritems(parent); | 4446 | path->slots[parent_level] = btrfs_header_nritems(parent); |
4187 | 4447 | ||
4188 | BUG_ON(!btrfs_tree_locked(node)); | 4448 | btrfs_assert_tree_locked(node); |
4189 | level = btrfs_header_level(node); | 4449 | level = btrfs_header_level(node); |
4190 | extent_buffer_get(node); | 4450 | extent_buffer_get(node); |
4191 | path->nodes[level] = node; | 4451 | path->nodes[level] = node; |
@@ -5641,7 +5901,9 @@ static noinline int relocate_one_extent(struct btrfs_root *extent_root, | |||
5641 | prev_block = block_start; | 5901 | prev_block = block_start; |
5642 | } | 5902 | } |
5643 | 5903 | ||
5904 | mutex_lock(&extent_root->fs_info->trans_mutex); | ||
5644 | btrfs_record_root_in_trans(found_root); | 5905 | btrfs_record_root_in_trans(found_root); |
5906 | mutex_unlock(&extent_root->fs_info->trans_mutex); | ||
5645 | if (ref_path->owner_objectid >= BTRFS_FIRST_FREE_OBJECTID) { | 5907 | if (ref_path->owner_objectid >= BTRFS_FIRST_FREE_OBJECTID) { |
5646 | /* | 5908 | /* |
5647 | * try to update data extent references while | 5909 | * try to update data extent references while |
@@ -6079,6 +6341,7 @@ out: | |||
6079 | int btrfs_free_block_groups(struct btrfs_fs_info *info) | 6341 | int btrfs_free_block_groups(struct btrfs_fs_info *info) |
6080 | { | 6342 | { |
6081 | struct btrfs_block_group_cache *block_group; | 6343 | struct btrfs_block_group_cache *block_group; |
6344 | struct btrfs_space_info *space_info; | ||
6082 | struct rb_node *n; | 6345 | struct rb_node *n; |
6083 | 6346 | ||
6084 | spin_lock(&info->block_group_cache_lock); | 6347 | spin_lock(&info->block_group_cache_lock); |
@@ -6100,6 +6363,23 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info) | |||
6100 | spin_lock(&info->block_group_cache_lock); | 6363 | spin_lock(&info->block_group_cache_lock); |
6101 | } | 6364 | } |
6102 | spin_unlock(&info->block_group_cache_lock); | 6365 | spin_unlock(&info->block_group_cache_lock); |
6366 | |||
6367 | /* now that all the block groups are freed, go through and | ||
6368 | * free all the space_info structs. This is only called during | ||
6369 | * the final stages of unmount, and so we know nobody is | ||
6370 | * using them. We call synchronize_rcu() once before we start, | ||
6371 | * just to be on the safe side. | ||
6372 | */ | ||
6373 | synchronize_rcu(); | ||
6374 | |||
6375 | while(!list_empty(&info->space_info)) { | ||
6376 | space_info = list_entry(info->space_info.next, | ||
6377 | struct btrfs_space_info, | ||
6378 | list); | ||
6379 | |||
6380 | list_del(&space_info->list); | ||
6381 | kfree(space_info); | ||
6382 | } | ||
6103 | return 0; | 6383 | return 0; |
6104 | } | 6384 | } |
6105 | 6385 | ||