aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/tree-log.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/tree-log.c')
-rw-r--r--fs/btrfs/tree-log.c181
1 files changed, 166 insertions, 15 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 83186c7e45d4..451fad96ecd1 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -278,8 +278,7 @@ static int process_one_buffer(struct btrfs_root *log,
278 struct walk_control *wc, u64 gen) 278 struct walk_control *wc, u64 gen)
279{ 279{
280 if (wc->pin) 280 if (wc->pin)
281 btrfs_pin_extent_for_log_replay(wc->trans, 281 btrfs_pin_extent_for_log_replay(log->fs_info->extent_root,
282 log->fs_info->extent_root,
283 eb->start, eb->len); 282 eb->start, eb->len);
284 283
285 if (btrfs_buffer_uptodate(eb, gen, 0)) { 284 if (btrfs_buffer_uptodate(eb, gen, 0)) {
@@ -485,7 +484,6 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
485 struct btrfs_key *key) 484 struct btrfs_key *key)
486{ 485{
487 int found_type; 486 int found_type;
488 u64 mask = root->sectorsize - 1;
489 u64 extent_end; 487 u64 extent_end;
490 u64 start = key->offset; 488 u64 start = key->offset;
491 u64 saved_nbytes; 489 u64 saved_nbytes;
@@ -502,7 +500,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
502 extent_end = start + btrfs_file_extent_num_bytes(eb, item); 500 extent_end = start + btrfs_file_extent_num_bytes(eb, item);
503 else if (found_type == BTRFS_FILE_EXTENT_INLINE) { 501 else if (found_type == BTRFS_FILE_EXTENT_INLINE) {
504 size = btrfs_file_extent_inline_len(eb, item); 502 size = btrfs_file_extent_inline_len(eb, item);
505 extent_end = (start + size + mask) & ~mask; 503 extent_end = ALIGN(start + size, root->sectorsize);
506 } else { 504 } else {
507 ret = 0; 505 ret = 0;
508 goto out; 506 goto out;
@@ -1384,7 +1382,10 @@ static noinline int link_to_fixup_dir(struct btrfs_trans_handle *trans,
1384 1382
1385 btrfs_release_path(path); 1383 btrfs_release_path(path);
1386 if (ret == 0) { 1384 if (ret == 0) {
1387 btrfs_inc_nlink(inode); 1385 if (!inode->i_nlink)
1386 set_nlink(inode, 1);
1387 else
1388 btrfs_inc_nlink(inode);
1388 ret = btrfs_update_inode(trans, root, inode); 1389 ret = btrfs_update_inode(trans, root, inode);
1389 } else if (ret == -EEXIST) { 1390 } else if (ret == -EEXIST) {
1390 ret = 0; 1391 ret = 0;
@@ -2281,6 +2282,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
2281 unsigned long log_transid = 0; 2282 unsigned long log_transid = 0;
2282 2283
2283 mutex_lock(&root->log_mutex); 2284 mutex_lock(&root->log_mutex);
2285 log_transid = root->log_transid;
2284 index1 = root->log_transid % 2; 2286 index1 = root->log_transid % 2;
2285 if (atomic_read(&root->log_commit[index1])) { 2287 if (atomic_read(&root->log_commit[index1])) {
2286 wait_log_commit(trans, root, root->log_transid); 2288 wait_log_commit(trans, root, root->log_transid);
@@ -2308,11 +2310,11 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
2308 /* bail out if we need to do a full commit */ 2310 /* bail out if we need to do a full commit */
2309 if (root->fs_info->last_trans_log_full_commit == trans->transid) { 2311 if (root->fs_info->last_trans_log_full_commit == trans->transid) {
2310 ret = -EAGAIN; 2312 ret = -EAGAIN;
2313 btrfs_free_logged_extents(log, log_transid);
2311 mutex_unlock(&root->log_mutex); 2314 mutex_unlock(&root->log_mutex);
2312 goto out; 2315 goto out;
2313 } 2316 }
2314 2317
2315 log_transid = root->log_transid;
2316 if (log_transid % 2 == 0) 2318 if (log_transid % 2 == 0)
2317 mark = EXTENT_DIRTY; 2319 mark = EXTENT_DIRTY;
2318 else 2320 else
@@ -2324,6 +2326,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
2324 ret = btrfs_write_marked_extents(log, &log->dirty_log_pages, mark); 2326 ret = btrfs_write_marked_extents(log, &log->dirty_log_pages, mark);
2325 if (ret) { 2327 if (ret) {
2326 btrfs_abort_transaction(trans, root, ret); 2328 btrfs_abort_transaction(trans, root, ret);
2329 btrfs_free_logged_extents(log, log_transid);
2327 mutex_unlock(&root->log_mutex); 2330 mutex_unlock(&root->log_mutex);
2328 goto out; 2331 goto out;
2329 } 2332 }
@@ -2363,6 +2366,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
2363 } 2366 }
2364 root->fs_info->last_trans_log_full_commit = trans->transid; 2367 root->fs_info->last_trans_log_full_commit = trans->transid;
2365 btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark); 2368 btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark);
2369 btrfs_free_logged_extents(log, log_transid);
2366 mutex_unlock(&log_root_tree->log_mutex); 2370 mutex_unlock(&log_root_tree->log_mutex);
2367 ret = -EAGAIN; 2371 ret = -EAGAIN;
2368 goto out; 2372 goto out;
@@ -2373,6 +2377,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
2373 btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark); 2377 btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark);
2374 wait_log_commit(trans, log_root_tree, 2378 wait_log_commit(trans, log_root_tree,
2375 log_root_tree->log_transid); 2379 log_root_tree->log_transid);
2380 btrfs_free_logged_extents(log, log_transid);
2376 mutex_unlock(&log_root_tree->log_mutex); 2381 mutex_unlock(&log_root_tree->log_mutex);
2377 ret = 0; 2382 ret = 0;
2378 goto out; 2383 goto out;
@@ -2392,6 +2397,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
2392 */ 2397 */
2393 if (root->fs_info->last_trans_log_full_commit == trans->transid) { 2398 if (root->fs_info->last_trans_log_full_commit == trans->transid) {
2394 btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark); 2399 btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark);
2400 btrfs_free_logged_extents(log, log_transid);
2395 mutex_unlock(&log_root_tree->log_mutex); 2401 mutex_unlock(&log_root_tree->log_mutex);
2396 ret = -EAGAIN; 2402 ret = -EAGAIN;
2397 goto out_wake_log_root; 2403 goto out_wake_log_root;
@@ -2402,10 +2408,12 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
2402 EXTENT_DIRTY | EXTENT_NEW); 2408 EXTENT_DIRTY | EXTENT_NEW);
2403 if (ret) { 2409 if (ret) {
2404 btrfs_abort_transaction(trans, root, ret); 2410 btrfs_abort_transaction(trans, root, ret);
2411 btrfs_free_logged_extents(log, log_transid);
2405 mutex_unlock(&log_root_tree->log_mutex); 2412 mutex_unlock(&log_root_tree->log_mutex);
2406 goto out_wake_log_root; 2413 goto out_wake_log_root;
2407 } 2414 }
2408 btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark); 2415 btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark);
2416 btrfs_wait_logged_extents(log, log_transid);
2409 2417
2410 btrfs_set_super_log_root(root->fs_info->super_for_commit, 2418 btrfs_set_super_log_root(root->fs_info->super_for_commit,
2411 log_root_tree->node->start); 2419 log_root_tree->node->start);
@@ -2461,8 +2469,10 @@ static void free_log_tree(struct btrfs_trans_handle *trans,
2461 .process_func = process_one_buffer 2469 .process_func = process_one_buffer
2462 }; 2470 };
2463 2471
2464 ret = walk_log_tree(trans, log, &wc); 2472 if (trans) {
2465 BUG_ON(ret); 2473 ret = walk_log_tree(trans, log, &wc);
2474 BUG_ON(ret);
2475 }
2466 2476
2467 while (1) { 2477 while (1) {
2468 ret = find_first_extent_bit(&log->dirty_log_pages, 2478 ret = find_first_extent_bit(&log->dirty_log_pages,
@@ -2475,6 +2485,14 @@ static void free_log_tree(struct btrfs_trans_handle *trans,
2475 EXTENT_DIRTY | EXTENT_NEW, GFP_NOFS); 2485 EXTENT_DIRTY | EXTENT_NEW, GFP_NOFS);
2476 } 2486 }
2477 2487
2488 /*
2489 * We may have short-circuited the log tree with the full commit logic
2490 * and left ordered extents on our list, so clear these out to keep us
2491 * from leaking inodes and memory.
2492 */
2493 btrfs_free_logged_extents(log, 0);
2494 btrfs_free_logged_extents(log, 1);
2495
2478 free_extent_buffer(log->node); 2496 free_extent_buffer(log->node);
2479 kfree(log); 2497 kfree(log);
2480} 2498}
@@ -2724,7 +2742,7 @@ static noinline int log_dir_items(struct btrfs_trans_handle *trans,
2724 path->keep_locks = 1; 2742 path->keep_locks = 1;
2725 2743
2726 ret = btrfs_search_forward(root, &min_key, &max_key, 2744 ret = btrfs_search_forward(root, &min_key, &max_key,
2727 path, 0, trans->transid); 2745 path, trans->transid);
2728 2746
2729 /* 2747 /*
2730 * we didn't find anything from this transaction, see if there 2748 * we didn't find anything from this transaction, see if there
@@ -3271,16 +3289,21 @@ static int log_one_extent(struct btrfs_trans_handle *trans,
3271 struct btrfs_root *log = root->log_root; 3289 struct btrfs_root *log = root->log_root;
3272 struct btrfs_file_extent_item *fi; 3290 struct btrfs_file_extent_item *fi;
3273 struct extent_buffer *leaf; 3291 struct extent_buffer *leaf;
3292 struct btrfs_ordered_extent *ordered;
3274 struct list_head ordered_sums; 3293 struct list_head ordered_sums;
3275 struct btrfs_map_token token; 3294 struct btrfs_map_token token;
3276 struct btrfs_key key; 3295 struct btrfs_key key;
3277 u64 csum_offset = em->mod_start - em->start; 3296 u64 mod_start = em->mod_start;
3278 u64 csum_len = em->mod_len; 3297 u64 mod_len = em->mod_len;
3298 u64 csum_offset;
3299 u64 csum_len;
3279 u64 extent_offset = em->start - em->orig_start; 3300 u64 extent_offset = em->start - em->orig_start;
3280 u64 block_len; 3301 u64 block_len;
3281 int ret; 3302 int ret;
3303 int index = log->log_transid % 2;
3282 bool skip_csum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM; 3304 bool skip_csum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM;
3283 3305
3306insert:
3284 INIT_LIST_HEAD(&ordered_sums); 3307 INIT_LIST_HEAD(&ordered_sums);
3285 btrfs_init_map_token(&token); 3308 btrfs_init_map_token(&token);
3286 key.objectid = btrfs_ino(inode); 3309 key.objectid = btrfs_ino(inode);
@@ -3296,6 +3319,23 @@ static int log_one_extent(struct btrfs_trans_handle *trans,
3296 leaf = path->nodes[0]; 3319 leaf = path->nodes[0];
3297 fi = btrfs_item_ptr(leaf, path->slots[0], 3320 fi = btrfs_item_ptr(leaf, path->slots[0],
3298 struct btrfs_file_extent_item); 3321 struct btrfs_file_extent_item);
3322
3323 /*
3324 * If we are overwriting an inline extent with a real one then we need
3325 * to just delete the inline extent as it may not be large enough to
3326 * have the entire file_extent_item.
3327 */
3328 if (ret && btrfs_token_file_extent_type(leaf, fi, &token) ==
3329 BTRFS_FILE_EXTENT_INLINE) {
3330 ret = btrfs_del_item(trans, log, path);
3331 btrfs_release_path(path);
3332 if (ret) {
3333 path->really_keep_locks = 0;
3334 return ret;
3335 }
3336 goto insert;
3337 }
3338
3299 btrfs_set_token_file_extent_generation(leaf, fi, em->generation, 3339 btrfs_set_token_file_extent_generation(leaf, fi, em->generation,
3300 &token); 3340 &token);
3301 if (test_bit(EXTENT_FLAG_PREALLOC, &em->flags)) { 3341 if (test_bit(EXTENT_FLAG_PREALLOC, &em->flags)) {
@@ -3357,6 +3397,97 @@ static int log_one_extent(struct btrfs_trans_handle *trans,
3357 if (skip_csum) 3397 if (skip_csum)
3358 return 0; 3398 return 0;
3359 3399
3400 if (em->compress_type) {
3401 csum_offset = 0;
3402 csum_len = block_len;
3403 }
3404
3405 /*
3406 * First check and see if our csums are on our outstanding ordered
3407 * extents.
3408 */
3409again:
3410 spin_lock_irq(&log->log_extents_lock[index]);
3411 list_for_each_entry(ordered, &log->logged_list[index], log_list) {
3412 struct btrfs_ordered_sum *sum;
3413
3414 if (!mod_len)
3415 break;
3416
3417 if (ordered->inode != inode)
3418 continue;
3419
3420 if (ordered->file_offset + ordered->len <= mod_start ||
3421 mod_start + mod_len <= ordered->file_offset)
3422 continue;
3423
3424 /*
3425 * We are going to copy all the csums on this ordered extent, so
3426 * go ahead and adjust mod_start and mod_len in case this
3427 * ordered extent has already been logged.
3428 */
3429 if (ordered->file_offset > mod_start) {
3430 if (ordered->file_offset + ordered->len >=
3431 mod_start + mod_len)
3432 mod_len = ordered->file_offset - mod_start;
3433 /*
3434 * If we have this case
3435 *
3436 * |--------- logged extent ---------|
3437 * |----- ordered extent ----|
3438 *
3439 * Just don't mess with mod_start and mod_len, we'll
3440 * just end up logging more csums than we need and it
3441 * will be ok.
3442 */
3443 } else {
3444 if (ordered->file_offset + ordered->len <
3445 mod_start + mod_len) {
3446 mod_len = (mod_start + mod_len) -
3447 (ordered->file_offset + ordered->len);
3448 mod_start = ordered->file_offset +
3449 ordered->len;
3450 } else {
3451 mod_len = 0;
3452 }
3453 }
3454
3455 /*
3456 * To keep us from looping for the above case of an ordered
3457 * extent that falls inside of the logged extent.
3458 */
3459 if (test_and_set_bit(BTRFS_ORDERED_LOGGED_CSUM,
3460 &ordered->flags))
3461 continue;
3462 atomic_inc(&ordered->refs);
3463 spin_unlock_irq(&log->log_extents_lock[index]);
3464 /*
3465 * we've dropped the lock, we must either break or
3466 * start over after this.
3467 */
3468
3469 wait_event(ordered->wait, ordered->csum_bytes_left == 0);
3470
3471 list_for_each_entry(sum, &ordered->list, list) {
3472 ret = btrfs_csum_file_blocks(trans, log, sum);
3473 if (ret) {
3474 btrfs_put_ordered_extent(ordered);
3475 goto unlocked;
3476 }
3477 }
3478 btrfs_put_ordered_extent(ordered);
3479 goto again;
3480
3481 }
3482 spin_unlock_irq(&log->log_extents_lock[index]);
3483unlocked:
3484
3485 if (!mod_len || ret)
3486 return ret;
3487
3488 csum_offset = mod_start - em->start;
3489 csum_len = mod_len;
3490
3360 /* block start is already adjusted for the file extent offset. */ 3491 /* block start is already adjusted for the file extent offset. */
3361 ret = btrfs_lookup_csums_range(log->fs_info->csum_root, 3492 ret = btrfs_lookup_csums_range(log->fs_info->csum_root,
3362 em->block_start + csum_offset, 3493 em->block_start + csum_offset,
@@ -3388,6 +3519,7 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans,
3388 struct extent_map_tree *tree = &BTRFS_I(inode)->extent_tree; 3519 struct extent_map_tree *tree = &BTRFS_I(inode)->extent_tree;
3389 u64 test_gen; 3520 u64 test_gen;
3390 int ret = 0; 3521 int ret = 0;
3522 int num = 0;
3391 3523
3392 INIT_LIST_HEAD(&extents); 3524 INIT_LIST_HEAD(&extents);
3393 3525
@@ -3396,27 +3528,42 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans,
3396 3528
3397 list_for_each_entry_safe(em, n, &tree->modified_extents, list) { 3529 list_for_each_entry_safe(em, n, &tree->modified_extents, list) {
3398 list_del_init(&em->list); 3530 list_del_init(&em->list);
3531
3532 /*
3533 * Just an arbitrary number, this can be really CPU intensive
3534 * once we start getting a lot of extents, and really once we
3535 * have a bunch of extents we just want to commit since it will
3536 * be faster.
3537 */
3538 if (++num > 32768) {
3539 list_del_init(&tree->modified_extents);
3540 ret = -EFBIG;
3541 goto process;
3542 }
3543
3399 if (em->generation <= test_gen) 3544 if (em->generation <= test_gen)
3400 continue; 3545 continue;
3401 /* Need a ref to keep it from getting evicted from cache */ 3546 /* Need a ref to keep it from getting evicted from cache */
3402 atomic_inc(&em->refs); 3547 atomic_inc(&em->refs);
3403 set_bit(EXTENT_FLAG_LOGGING, &em->flags); 3548 set_bit(EXTENT_FLAG_LOGGING, &em->flags);
3404 list_add_tail(&em->list, &extents); 3549 list_add_tail(&em->list, &extents);
3550 num++;
3405 } 3551 }
3406 3552
3407 list_sort(NULL, &extents, extent_cmp); 3553 list_sort(NULL, &extents, extent_cmp);
3408 3554
3555process:
3409 while (!list_empty(&extents)) { 3556 while (!list_empty(&extents)) {
3410 em = list_entry(extents.next, struct extent_map, list); 3557 em = list_entry(extents.next, struct extent_map, list);
3411 3558
3412 list_del_init(&em->list); 3559 list_del_init(&em->list);
3413 clear_bit(EXTENT_FLAG_LOGGING, &em->flags);
3414 3560
3415 /* 3561 /*
3416 * If we had an error we just need to delete everybody from our 3562 * If we had an error we just need to delete everybody from our
3417 * private list. 3563 * private list.
3418 */ 3564 */
3419 if (ret) { 3565 if (ret) {
3566 clear_em_logging(tree, em);
3420 free_extent_map(em); 3567 free_extent_map(em);
3421 continue; 3568 continue;
3422 } 3569 }
@@ -3424,8 +3571,9 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans,
3424 write_unlock(&tree->lock); 3571 write_unlock(&tree->lock);
3425 3572
3426 ret = log_one_extent(trans, inode, root, em, path); 3573 ret = log_one_extent(trans, inode, root, em, path);
3427 free_extent_map(em);
3428 write_lock(&tree->lock); 3574 write_lock(&tree->lock);
3575 clear_em_logging(tree, em);
3576 free_extent_map(em);
3429 } 3577 }
3430 WARN_ON(!list_empty(&extents)); 3578 WARN_ON(!list_empty(&extents));
3431 write_unlock(&tree->lock); 3579 write_unlock(&tree->lock);
@@ -3507,6 +3655,8 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
3507 3655
3508 mutex_lock(&BTRFS_I(inode)->log_mutex); 3656 mutex_lock(&BTRFS_I(inode)->log_mutex);
3509 3657
3658 btrfs_get_logged_extents(log, inode);
3659
3510 /* 3660 /*
3511 * a brute force approach to making sure we get the most uptodate 3661 * a brute force approach to making sure we get the most uptodate
3512 * copies of everything. 3662 * copies of everything.
@@ -3552,7 +3702,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
3552 while (1) { 3702 while (1) {
3553 ins_nr = 0; 3703 ins_nr = 0;
3554 ret = btrfs_search_forward(root, &min_key, &max_key, 3704 ret = btrfs_search_forward(root, &min_key, &max_key,
3555 path, 0, trans->transid); 3705 path, trans->transid);
3556 if (ret != 0) 3706 if (ret != 0)
3557 break; 3707 break;
3558again: 3708again:
@@ -3650,6 +3800,8 @@ log_extents:
3650 BTRFS_I(inode)->logged_trans = trans->transid; 3800 BTRFS_I(inode)->logged_trans = trans->transid;
3651 BTRFS_I(inode)->last_log_commit = BTRFS_I(inode)->last_sub_trans; 3801 BTRFS_I(inode)->last_log_commit = BTRFS_I(inode)->last_sub_trans;
3652out_unlock: 3802out_unlock:
3803 if (err)
3804 btrfs_free_logged_extents(log, log->log_transid);
3653 mutex_unlock(&BTRFS_I(inode)->log_mutex); 3805 mutex_unlock(&BTRFS_I(inode)->log_mutex);
3654 3806
3655 btrfs_free_path(path); 3807 btrfs_free_path(path);
@@ -3816,7 +3968,6 @@ int btrfs_log_inode_parent(struct btrfs_trans_handle *trans,
3816end_trans: 3968end_trans:
3817 dput(old_parent); 3969 dput(old_parent);
3818 if (ret < 0) { 3970 if (ret < 0) {
3819 WARN_ON(ret != -ENOSPC);
3820 root->fs_info->last_trans_log_full_commit = trans->transid; 3971 root->fs_info->last_trans_log_full_commit = trans->transid;
3821 ret = 1; 3972 ret = 1;
3822 } 3973 }