diff options
Diffstat (limited to 'fs/btrfs/inode-map.c')
-rw-r--r-- | fs/btrfs/inode-map.c | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/fs/btrfs/inode-map.c b/fs/btrfs/inode-map.c index 53dcbdf446cd..f8962a957d65 100644 --- a/fs/btrfs/inode-map.c +++ b/fs/btrfs/inode-map.c | |||
@@ -398,6 +398,8 @@ int btrfs_save_ino_cache(struct btrfs_root *root, | |||
398 | struct btrfs_free_space_ctl *ctl = root->free_ino_ctl; | 398 | struct btrfs_free_space_ctl *ctl = root->free_ino_ctl; |
399 | struct btrfs_path *path; | 399 | struct btrfs_path *path; |
400 | struct inode *inode; | 400 | struct inode *inode; |
401 | struct btrfs_block_rsv *rsv; | ||
402 | u64 num_bytes; | ||
401 | u64 alloc_hint = 0; | 403 | u64 alloc_hint = 0; |
402 | int ret; | 404 | int ret; |
403 | int prealloc; | 405 | int prealloc; |
@@ -421,11 +423,26 @@ int btrfs_save_ino_cache(struct btrfs_root *root, | |||
421 | if (!path) | 423 | if (!path) |
422 | return -ENOMEM; | 424 | return -ENOMEM; |
423 | 425 | ||
426 | rsv = trans->block_rsv; | ||
427 | trans->block_rsv = &root->fs_info->trans_block_rsv; | ||
428 | |||
429 | num_bytes = trans->bytes_reserved; | ||
430 | /* | ||
431 | * 1 item for inode item insertion if need | ||
432 | * 3 items for inode item update (in the worst case) | ||
433 | * 1 item for free space object | ||
434 | * 3 items for pre-allocation | ||
435 | */ | ||
436 | trans->bytes_reserved = btrfs_calc_trans_metadata_size(root, 8); | ||
437 | ret = btrfs_block_rsv_add_noflush(root, trans->block_rsv, | ||
438 | trans->bytes_reserved); | ||
439 | if (ret) | ||
440 | goto out; | ||
424 | again: | 441 | again: |
425 | inode = lookup_free_ino_inode(root, path); | 442 | inode = lookup_free_ino_inode(root, path); |
426 | if (IS_ERR(inode) && PTR_ERR(inode) != -ENOENT) { | 443 | if (IS_ERR(inode) && PTR_ERR(inode) != -ENOENT) { |
427 | ret = PTR_ERR(inode); | 444 | ret = PTR_ERR(inode); |
428 | goto out; | 445 | goto out_release; |
429 | } | 446 | } |
430 | 447 | ||
431 | if (IS_ERR(inode)) { | 448 | if (IS_ERR(inode)) { |
@@ -434,7 +451,7 @@ again: | |||
434 | 451 | ||
435 | ret = create_free_ino_inode(root, trans, path); | 452 | ret = create_free_ino_inode(root, trans, path); |
436 | if (ret) | 453 | if (ret) |
437 | goto out; | 454 | goto out_release; |
438 | goto again; | 455 | goto again; |
439 | } | 456 | } |
440 | 457 | ||
@@ -477,11 +494,14 @@ again: | |||
477 | } | 494 | } |
478 | btrfs_free_reserved_data_space(inode, prealloc); | 495 | btrfs_free_reserved_data_space(inode, prealloc); |
479 | 496 | ||
497 | ret = btrfs_write_out_ino_cache(root, trans, path); | ||
480 | out_put: | 498 | out_put: |
481 | iput(inode); | 499 | iput(inode); |
500 | out_release: | ||
501 | btrfs_block_rsv_release(root, trans->block_rsv, trans->bytes_reserved); | ||
482 | out: | 502 | out: |
483 | if (ret == 0) | 503 | trans->block_rsv = rsv; |
484 | ret = btrfs_write_out_ino_cache(root, trans, path); | 504 | trans->bytes_reserved = num_bytes; |
485 | 505 | ||
486 | btrfs_free_path(path); | 506 | btrfs_free_path(path); |
487 | return ret; | 507 | return ret; |