aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/send.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/send.c')
-rw-r--r--fs/btrfs/send.c197
1 files changed, 82 insertions, 115 deletions
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index e46e0ed74925..945d1db98f26 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -121,7 +121,6 @@ struct send_ctx {
121 struct list_head name_cache_list; 121 struct list_head name_cache_list;
122 int name_cache_size; 122 int name_cache_size;
123 123
124 struct file *cur_inode_filp;
125 char *read_buf; 124 char *read_buf;
126}; 125};
127 126
@@ -565,10 +564,8 @@ static int begin_cmd(struct send_ctx *sctx, int cmd)
565{ 564{
566 struct btrfs_cmd_header *hdr; 565 struct btrfs_cmd_header *hdr;
567 566
568 if (!sctx->send_buf) { 567 if (WARN_ON(!sctx->send_buf))
569 WARN_ON(1);
570 return -EINVAL; 568 return -EINVAL;
571 }
572 569
573 BUG_ON(sctx->send_size); 570 BUG_ON(sctx->send_size);
574 571
@@ -791,7 +788,7 @@ static int iterate_inode_ref(struct btrfs_root *root, struct btrfs_path *path,
791 if (found_key->type == BTRFS_INODE_REF_KEY) { 788 if (found_key->type == BTRFS_INODE_REF_KEY) {
792 ptr = (unsigned long)btrfs_item_ptr(eb, slot, 789 ptr = (unsigned long)btrfs_item_ptr(eb, slot,
793 struct btrfs_inode_ref); 790 struct btrfs_inode_ref);
794 item = btrfs_item_nr(eb, slot); 791 item = btrfs_item_nr(slot);
795 total = btrfs_item_size(eb, item); 792 total = btrfs_item_size(eb, item);
796 elem_size = sizeof(*iref); 793 elem_size = sizeof(*iref);
797 } else { 794 } else {
@@ -905,7 +902,7 @@ static int iterate_dir_item(struct btrfs_root *root, struct btrfs_path *path,
905 902
906 eb = path->nodes[0]; 903 eb = path->nodes[0];
907 slot = path->slots[0]; 904 slot = path->slots[0];
908 item = btrfs_item_nr(eb, slot); 905 item = btrfs_item_nr(slot);
909 di = btrfs_item_ptr(eb, slot, struct btrfs_dir_item); 906 di = btrfs_item_ptr(eb, slot, struct btrfs_dir_item);
910 cur = 0; 907 cur = 0;
911 len = 0; 908 len = 0;
@@ -2120,77 +2117,6 @@ out:
2120} 2117}
2121 2118
2122/* 2119/*
2123 * Called for regular files when sending extents data. Opens a struct file
2124 * to read from the file.
2125 */
2126static int open_cur_inode_file(struct send_ctx *sctx)
2127{
2128 int ret = 0;
2129 struct btrfs_key key;
2130 struct path path;
2131 struct inode *inode;
2132 struct dentry *dentry;
2133 struct file *filp;
2134 int new = 0;
2135
2136 if (sctx->cur_inode_filp)
2137 goto out;
2138
2139 key.objectid = sctx->cur_ino;
2140 key.type = BTRFS_INODE_ITEM_KEY;
2141 key.offset = 0;
2142
2143 inode = btrfs_iget(sctx->send_root->fs_info->sb, &key, sctx->send_root,
2144 &new);
2145 if (IS_ERR(inode)) {
2146 ret = PTR_ERR(inode);
2147 goto out;
2148 }
2149
2150 dentry = d_obtain_alias(inode);
2151 inode = NULL;
2152 if (IS_ERR(dentry)) {
2153 ret = PTR_ERR(dentry);
2154 goto out;
2155 }
2156
2157 path.mnt = sctx->mnt;
2158 path.dentry = dentry;
2159 filp = dentry_open(&path, O_RDONLY | O_LARGEFILE, current_cred());
2160 dput(dentry);
2161 dentry = NULL;
2162 if (IS_ERR(filp)) {
2163 ret = PTR_ERR(filp);
2164 goto out;
2165 }
2166 sctx->cur_inode_filp = filp;
2167
2168out:
2169 /*
2170 * no xxxput required here as every vfs op
2171 * does it by itself on failure
2172 */
2173 return ret;
2174}
2175
2176/*
2177 * Closes the struct file that was created in open_cur_inode_file
2178 */
2179static int close_cur_inode_file(struct send_ctx *sctx)
2180{
2181 int ret = 0;
2182
2183 if (!sctx->cur_inode_filp)
2184 goto out;
2185
2186 ret = filp_close(sctx->cur_inode_filp, NULL);
2187 sctx->cur_inode_filp = NULL;
2188
2189out:
2190 return ret;
2191}
2192
2193/*
2194 * Sends a BTRFS_SEND_C_SUBVOL command/item to userspace 2120 * Sends a BTRFS_SEND_C_SUBVOL command/item to userspace
2195 */ 2121 */
2196static int send_subvol_begin(struct send_ctx *sctx) 2122static int send_subvol_begin(struct send_ctx *sctx)
@@ -3622,6 +3548,72 @@ out:
3622 return ret; 3548 return ret;
3623} 3549}
3624 3550
3551static ssize_t fill_read_buf(struct send_ctx *sctx, u64 offset, u32 len)
3552{
3553 struct btrfs_root *root = sctx->send_root;
3554 struct btrfs_fs_info *fs_info = root->fs_info;
3555 struct inode *inode;
3556 struct page *page;
3557 char *addr;
3558 struct btrfs_key key;
3559 pgoff_t index = offset >> PAGE_CACHE_SHIFT;
3560 pgoff_t last_index;
3561 unsigned pg_offset = offset & ~PAGE_CACHE_MASK;
3562 ssize_t ret = 0;
3563
3564 key.objectid = sctx->cur_ino;
3565 key.type = BTRFS_INODE_ITEM_KEY;
3566 key.offset = 0;
3567
3568 inode = btrfs_iget(fs_info->sb, &key, root, NULL);
3569 if (IS_ERR(inode))
3570 return PTR_ERR(inode);
3571
3572 if (offset + len > i_size_read(inode)) {
3573 if (offset > i_size_read(inode))
3574 len = 0;
3575 else
3576 len = offset - i_size_read(inode);
3577 }
3578 if (len == 0)
3579 goto out;
3580
3581 last_index = (offset + len - 1) >> PAGE_CACHE_SHIFT;
3582 while (index <= last_index) {
3583 unsigned cur_len = min_t(unsigned, len,
3584 PAGE_CACHE_SIZE - pg_offset);
3585 page = find_or_create_page(inode->i_mapping, index, GFP_NOFS);
3586 if (!page) {
3587 ret = -ENOMEM;
3588 break;
3589 }
3590
3591 if (!PageUptodate(page)) {
3592 btrfs_readpage(NULL, page);
3593 lock_page(page);
3594 if (!PageUptodate(page)) {
3595 unlock_page(page);
3596 page_cache_release(page);
3597 ret = -EIO;
3598 break;
3599 }
3600 }
3601
3602 addr = kmap(page);
3603 memcpy(sctx->read_buf + ret, addr + pg_offset, cur_len);
3604 kunmap(page);
3605 unlock_page(page);
3606 page_cache_release(page);
3607 index++;
3608 pg_offset = 0;
3609 len -= cur_len;
3610 ret += cur_len;
3611 }
3612out:
3613 iput(inode);
3614 return ret;
3615}
3616
3625/* 3617/*
3626 * Read some bytes from the current inode/file and send a write command to 3618 * Read some bytes from the current inode/file and send a write command to
3627 * user space. 3619 * user space.
@@ -3630,35 +3622,20 @@ static int send_write(struct send_ctx *sctx, u64 offset, u32 len)
3630{ 3622{
3631 int ret = 0; 3623 int ret = 0;
3632 struct fs_path *p; 3624 struct fs_path *p;
3633 loff_t pos = offset; 3625 ssize_t num_read = 0;
3634 int num_read = 0;
3635 mm_segment_t old_fs;
3636 3626
3637 p = fs_path_alloc(); 3627 p = fs_path_alloc();
3638 if (!p) 3628 if (!p)
3639 return -ENOMEM; 3629 return -ENOMEM;
3640 3630
3641 /*
3642 * vfs normally only accepts user space buffers for security reasons.
3643 * we only read from the file and also only provide the read_buf buffer
3644 * to vfs. As this buffer does not come from a user space call, it's
3645 * ok to temporary allow kernel space buffers.
3646 */
3647 old_fs = get_fs();
3648 set_fs(KERNEL_DS);
3649
3650verbose_printk("btrfs: send_write offset=%llu, len=%d\n", offset, len); 3631verbose_printk("btrfs: send_write offset=%llu, len=%d\n", offset, len);
3651 3632
3652 ret = open_cur_inode_file(sctx); 3633 num_read = fill_read_buf(sctx, offset, len);
3653 if (ret < 0) 3634 if (num_read <= 0) {
3654 goto out; 3635 if (num_read < 0)
3655 3636 ret = num_read;
3656 ret = vfs_read(sctx->cur_inode_filp, sctx->read_buf, len, &pos);
3657 if (ret < 0)
3658 goto out;
3659 num_read = ret;
3660 if (!num_read)
3661 goto out; 3637 goto out;
3638 }
3662 3639
3663 ret = begin_cmd(sctx, BTRFS_SEND_C_WRITE); 3640 ret = begin_cmd(sctx, BTRFS_SEND_C_WRITE);
3664 if (ret < 0) 3641 if (ret < 0)
@@ -3677,7 +3654,6 @@ verbose_printk("btrfs: send_write offset=%llu, len=%d\n", offset, len);
3677tlv_put_failure: 3654tlv_put_failure:
3678out: 3655out:
3679 fs_path_free(p); 3656 fs_path_free(p);
3680 set_fs(old_fs);
3681 if (ret < 0) 3657 if (ret < 0)
3682 return ret; 3658 return ret;
3683 return num_read; 3659 return num_read;
@@ -3926,16 +3902,16 @@ static int is_extent_unchanged(struct send_ctx *sctx,
3926 while (key.offset < ekey->offset + left_len) { 3902 while (key.offset < ekey->offset + left_len) {
3927 ei = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item); 3903 ei = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item);
3928 right_type = btrfs_file_extent_type(eb, ei); 3904 right_type = btrfs_file_extent_type(eb, ei);
3929 right_disknr = btrfs_file_extent_disk_bytenr(eb, ei);
3930 right_len = btrfs_file_extent_num_bytes(eb, ei);
3931 right_offset = btrfs_file_extent_offset(eb, ei);
3932 right_gen = btrfs_file_extent_generation(eb, ei);
3933
3934 if (right_type != BTRFS_FILE_EXTENT_REG) { 3905 if (right_type != BTRFS_FILE_EXTENT_REG) {
3935 ret = 0; 3906 ret = 0;
3936 goto out; 3907 goto out;
3937 } 3908 }
3938 3909
3910 right_disknr = btrfs_file_extent_disk_bytenr(eb, ei);
3911 right_len = btrfs_file_extent_num_bytes(eb, ei);
3912 right_offset = btrfs_file_extent_offset(eb, ei);
3913 right_gen = btrfs_file_extent_generation(eb, ei);
3914
3939 /* 3915 /*
3940 * Are we at extent 8? If yes, we know the extent is changed. 3916 * Are we at extent 8? If yes, we know the extent is changed.
3941 * This may only happen on the first iteration. 3917 * This may only happen on the first iteration.
@@ -4222,10 +4198,6 @@ static int changed_inode(struct send_ctx *sctx,
4222 u64 left_gen = 0; 4198 u64 left_gen = 0;
4223 u64 right_gen = 0; 4199 u64 right_gen = 0;
4224 4200
4225 ret = close_cur_inode_file(sctx);
4226 if (ret < 0)
4227 goto out;
4228
4229 sctx->cur_ino = key->objectid; 4201 sctx->cur_ino = key->objectid;
4230 sctx->cur_inode_new_gen = 0; 4202 sctx->cur_inode_new_gen = 0;
4231 4203
@@ -4686,11 +4658,6 @@ static int send_subvol(struct send_ctx *sctx)
4686 } 4658 }
4687 4659
4688out: 4660out:
4689 if (!ret)
4690 ret = close_cur_inode_file(sctx);
4691 else
4692 close_cur_inode_file(sctx);
4693
4694 free_recorded_refs(sctx); 4661 free_recorded_refs(sctx);
4695 return ret; 4662 return ret;
4696} 4663}
@@ -4756,8 +4723,8 @@ long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_)
4756 } 4723 }
4757 4724
4758 if (!access_ok(VERIFY_READ, arg->clone_sources, 4725 if (!access_ok(VERIFY_READ, arg->clone_sources,
4759 sizeof(*arg->clone_sources * 4726 sizeof(*arg->clone_sources) *
4760 arg->clone_sources_count))) { 4727 arg->clone_sources_count)) {
4761 ret = -EFAULT; 4728 ret = -EFAULT;
4762 goto out; 4729 goto out;
4763 } 4730 }