diff options
Diffstat (limited to 'fs/btrfs/send.c')
-rw-r--r-- | fs/btrfs/send.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index ff40f1c00ce3..ba9690b9ae24 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c | |||
@@ -4579,6 +4579,41 @@ long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_) | |||
4579 | send_root = BTRFS_I(file_inode(mnt_file))->root; | 4579 | send_root = BTRFS_I(file_inode(mnt_file))->root; |
4580 | fs_info = send_root->fs_info; | 4580 | fs_info = send_root->fs_info; |
4581 | 4581 | ||
4582 | /* | ||
4583 | * This is done when we lookup the root, it should already be complete | ||
4584 | * by the time we get here. | ||
4585 | */ | ||
4586 | WARN_ON(send_root->orphan_cleanup_state != ORPHAN_CLEANUP_DONE); | ||
4587 | |||
4588 | /* | ||
4589 | * If we just created this root we need to make sure that the orphan | ||
4590 | * cleanup has been done and committed since we search the commit root, | ||
4591 | * so check its commit root transid with our otransid and if they match | ||
4592 | * commit the transaction to make sure everything is updated. | ||
4593 | */ | ||
4594 | down_read(&send_root->fs_info->extent_commit_sem); | ||
4595 | if (btrfs_header_generation(send_root->commit_root) == | ||
4596 | btrfs_root_otransid(&send_root->root_item)) { | ||
4597 | struct btrfs_trans_handle *trans; | ||
4598 | |||
4599 | up_read(&send_root->fs_info->extent_commit_sem); | ||
4600 | |||
4601 | trans = btrfs_attach_transaction_barrier(send_root); | ||
4602 | if (IS_ERR(trans)) { | ||
4603 | if (PTR_ERR(trans) != -ENOENT) { | ||
4604 | ret = PTR_ERR(trans); | ||
4605 | goto out; | ||
4606 | } | ||
4607 | /* ENOENT means theres no transaction */ | ||
4608 | } else { | ||
4609 | ret = btrfs_commit_transaction(trans, send_root); | ||
4610 | if (ret) | ||
4611 | goto out; | ||
4612 | } | ||
4613 | } else { | ||
4614 | up_read(&send_root->fs_info->extent_commit_sem); | ||
4615 | } | ||
4616 | |||
4582 | arg = memdup_user(arg_, sizeof(*arg)); | 4617 | arg = memdup_user(arg_, sizeof(*arg)); |
4583 | if (IS_ERR(arg)) { | 4618 | if (IS_ERR(arg)) { |
4584 | ret = PTR_ERR(arg); | 4619 | ret = PTR_ERR(arg); |