diff options
| -rw-r--r-- | fs/btrfs/disk-io.c | 13 | ||||
| -rw-r--r-- | fs/btrfs/extent-tree.c | 59 | ||||
| -rw-r--r-- | fs/btrfs/transaction.c | 15 |
3 files changed, 29 insertions, 58 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index d2d1cc87e8a..da9dda4338a 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
| @@ -188,13 +188,6 @@ static int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf, | |||
| 188 | btrfs_csum_final(crc, result); | 188 | btrfs_csum_final(crc, result); |
| 189 | 189 | ||
| 190 | if (verify) { | 190 | if (verify) { |
| 191 | int from_this_trans = 0; | ||
| 192 | |||
| 193 | if (root->fs_info->running_transaction && | ||
| 194 | btrfs_header_generation(buf) == | ||
| 195 | root->fs_info->running_transaction->transid) | ||
| 196 | from_this_trans = 1; | ||
| 197 | |||
| 198 | /* FIXME, this is not good */ | 191 | /* FIXME, this is not good */ |
| 199 | if (memcmp_extent_buffer(buf, result, 0, BTRFS_CRC32_SIZE)) { | 192 | if (memcmp_extent_buffer(buf, result, 0, BTRFS_CRC32_SIZE)) { |
| 200 | u32 val; | 193 | u32 val; |
| @@ -203,11 +196,9 @@ static int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf, | |||
| 203 | 196 | ||
| 204 | read_extent_buffer(buf, &val, 0, BTRFS_CRC32_SIZE); | 197 | read_extent_buffer(buf, &val, 0, BTRFS_CRC32_SIZE); |
| 205 | printk("btrfs: %s checksum verify failed on %llu " | 198 | printk("btrfs: %s checksum verify failed on %llu " |
| 206 | "wanted %X found %X from_this_trans %d " | 199 | "wanted %X found %X level %d\n", |
| 207 | "level %d\n", | ||
| 208 | root->fs_info->sb->s_id, | 200 | root->fs_info->sb->s_id, |
| 209 | buf->start, val, found, from_this_trans, | 201 | buf->start, val, found, btrfs_header_level(buf)); |
| 210 | btrfs_header_level(buf)); | ||
| 211 | return 1; | 202 | return 1; |
| 212 | } | 203 | } |
| 213 | } else { | 204 | } else { |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 98a1c0faeda..1aeb695078b 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
| @@ -2369,6 +2369,11 @@ static int noinline drop_leaf_ref_no_cache(struct btrfs_trans_handle *trans, | |||
| 2369 | leaf_owner, leaf_generation, | 2369 | leaf_owner, leaf_generation, |
| 2370 | key.objectid, key.offset, 0); | 2370 | key.objectid, key.offset, 0); |
| 2371 | mutex_unlock(&root->fs_info->alloc_mutex); | 2371 | mutex_unlock(&root->fs_info->alloc_mutex); |
| 2372 | |||
| 2373 | atomic_inc(&root->fs_info->throttle_gen); | ||
| 2374 | wake_up(&root->fs_info->transaction_throttle); | ||
| 2375 | cond_resched(); | ||
| 2376 | |||
| 2372 | BUG_ON(ret); | 2377 | BUG_ON(ret); |
| 2373 | } | 2378 | } |
| 2374 | return 0; | 2379 | return 0; |
| @@ -2389,6 +2394,11 @@ static int noinline drop_leaf_ref(struct btrfs_trans_handle *trans, | |||
| 2389 | ref->owner, ref->generation, | 2394 | ref->owner, ref->generation, |
| 2390 | info->objectid, info->offset, 0); | 2395 | info->objectid, info->offset, 0); |
| 2391 | mutex_unlock(&root->fs_info->alloc_mutex); | 2396 | mutex_unlock(&root->fs_info->alloc_mutex); |
| 2397 | |||
| 2398 | atomic_inc(&root->fs_info->throttle_gen); | ||
| 2399 | wake_up(&root->fs_info->transaction_throttle); | ||
| 2400 | cond_resched(); | ||
| 2401 | |||
| 2392 | BUG_ON(ret); | 2402 | BUG_ON(ret); |
| 2393 | info++; | 2403 | info++; |
| 2394 | } | 2404 | } |
| @@ -2396,51 +2406,6 @@ static int noinline drop_leaf_ref(struct btrfs_trans_handle *trans, | |||
| 2396 | return 0; | 2406 | return 0; |
| 2397 | } | 2407 | } |
| 2398 | 2408 | ||
| 2399 | static void noinline reada_walk_down(struct btrfs_root *root, | ||
| 2400 | struct extent_buffer *node, | ||
| 2401 | int slot) | ||
| 2402 | { | ||
| 2403 | u64 bytenr; | ||
| 2404 | u64 last = 0; | ||
| 2405 | u32 nritems; | ||
| 2406 | u32 refs; | ||
| 2407 | u32 blocksize; | ||
| 2408 | int ret; | ||
| 2409 | int i; | ||
| 2410 | int level; | ||
| 2411 | int skipped = 0; | ||
| 2412 | |||
| 2413 | nritems = btrfs_header_nritems(node); | ||
| 2414 | level = btrfs_header_level(node); | ||
| 2415 | if (level) | ||
| 2416 | return; | ||
| 2417 | |||
| 2418 | for (i = slot; i < nritems && skipped < 32; i++) { | ||
| 2419 | bytenr = btrfs_node_blockptr(node, i); | ||
| 2420 | if (last && ((bytenr > last && bytenr - last > 32 * 1024) || | ||
| 2421 | (last > bytenr && last - bytenr > 32 * 1024))) { | ||
| 2422 | skipped++; | ||
| 2423 | continue; | ||
| 2424 | } | ||
| 2425 | blocksize = btrfs_level_size(root, level - 1); | ||
| 2426 | if (i != slot) { | ||
| 2427 | ret = lookup_extent_ref(NULL, root, bytenr, | ||
| 2428 | blocksize, &refs); | ||
| 2429 | BUG_ON(ret); | ||
| 2430 | if (refs != 1) { | ||
| 2431 | skipped++; | ||
| 2432 | continue; | ||
| 2433 | } | ||
| 2434 | } | ||
| 2435 | ret = readahead_tree_block(root, bytenr, blocksize, | ||
| 2436 | btrfs_node_ptr_generation(node, i)); | ||
| 2437 | last = bytenr + blocksize; | ||
| 2438 | cond_resched(); | ||
| 2439 | if (ret) | ||
| 2440 | break; | ||
| 2441 | } | ||
| 2442 | } | ||
| 2443 | |||
| 2444 | int drop_snap_lookup_refcount(struct btrfs_root *root, u64 start, u64 len, | 2409 | int drop_snap_lookup_refcount(struct btrfs_root *root, u64 start, u64 len, |
| 2445 | u32 *refs) | 2410 | u32 *refs) |
| 2446 | { | 2411 | { |
| @@ -2549,6 +2514,7 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans, | |||
| 2549 | 2514 | ||
| 2550 | atomic_inc(&root->fs_info->throttle_gen); | 2515 | atomic_inc(&root->fs_info->throttle_gen); |
| 2551 | wake_up(&root->fs_info->transaction_throttle); | 2516 | wake_up(&root->fs_info->transaction_throttle); |
| 2517 | cond_resched(); | ||
| 2552 | 2518 | ||
| 2553 | continue; | 2519 | continue; |
| 2554 | } | 2520 | } |
| @@ -2578,8 +2544,6 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans, | |||
| 2578 | if (!next || !btrfs_buffer_uptodate(next, ptr_gen)) { | 2544 | if (!next || !btrfs_buffer_uptodate(next, ptr_gen)) { |
| 2579 | free_extent_buffer(next); | 2545 | free_extent_buffer(next); |
| 2580 | 2546 | ||
| 2581 | if (path->slots[*level] == 0) | ||
| 2582 | reada_walk_down(root, cur, path->slots[*level]); | ||
| 2583 | next = read_tree_block(root, bytenr, blocksize, | 2547 | next = read_tree_block(root, bytenr, blocksize, |
| 2584 | ptr_gen); | 2548 | ptr_gen); |
| 2585 | cond_resched(); | 2549 | cond_resched(); |
| @@ -2601,6 +2565,7 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans, | |||
| 2601 | path->nodes[*level-1] = next; | 2565 | path->nodes[*level-1] = next; |
| 2602 | *level = btrfs_header_level(next); | 2566 | *level = btrfs_header_level(next); |
| 2603 | path->slots[*level] = 0; | 2567 | path->slots[*level] = 0; |
| 2568 | cond_resched(); | ||
| 2604 | } | 2569 | } |
| 2605 | out: | 2570 | out: |
| 2606 | WARN_ON(*level < 0); | 2571 | WARN_ON(*level < 0); |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 9d84daf1000..cf73342e821 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
| @@ -210,7 +210,9 @@ static noinline int wait_for_commit(struct btrfs_root *root, | |||
| 210 | static void throttle_on_drops(struct btrfs_root *root) | 210 | static void throttle_on_drops(struct btrfs_root *root) |
| 211 | { | 211 | { |
| 212 | struct btrfs_fs_info *info = root->fs_info; | 212 | struct btrfs_fs_info *info = root->fs_info; |
| 213 | int harder_count = 0; | ||
| 213 | 214 | ||
| 215 | harder: | ||
| 214 | if (atomic_read(&info->throttles)) { | 216 | if (atomic_read(&info->throttles)) { |
| 215 | DEFINE_WAIT(wait); | 217 | DEFINE_WAIT(wait); |
| 216 | int thr; | 218 | int thr; |
| @@ -226,6 +228,19 @@ static void throttle_on_drops(struct btrfs_root *root) | |||
| 226 | schedule(); | 228 | schedule(); |
| 227 | finish_wait(&info->transaction_throttle, &wait); | 229 | finish_wait(&info->transaction_throttle, &wait); |
| 228 | } while (thr == atomic_read(&info->throttle_gen)); | 230 | } while (thr == atomic_read(&info->throttle_gen)); |
| 231 | harder_count++; | ||
| 232 | |||
| 233 | if (root->fs_info->total_ref_cache_size > 1 * 1024 * 1024 && | ||
| 234 | harder_count < 2) | ||
| 235 | goto harder; | ||
| 236 | |||
| 237 | if (root->fs_info->total_ref_cache_size > 5 * 1024 * 1024 && | ||
| 238 | harder_count < 10) | ||
| 239 | goto harder; | ||
| 240 | |||
| 241 | if (root->fs_info->total_ref_cache_size > 10 * 1024 * 1024 && | ||
| 242 | harder_count < 20) | ||
| 243 | goto harder; | ||
| 229 | } | 244 | } |
| 230 | } | 245 | } |
| 231 | 246 | ||
