aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@fusionio.com>2013-10-25 11:36:01 -0400
committerChris Mason <chris.mason@fusionio.com>2013-11-11 22:07:11 -0500
commited2590953bd06b892f0411fc94e19175d32f197a (patch)
tree8569c16f58a2780b5780bf1e50a788d29625670b /fs
parent301993a4a13b34c13f7f2a7ed3429d231a6d6166 (diff)
Btrfs: stop using vfs_read in send
Apparently we don't actually close the files until we return to userspace, so stop using vfs_read in send. This is actually better for us since we can avoid all the extra logic of holding the file we're sending open and making sure to clean it up. This will fix people who have been hitting too many files open errors when trying to send. Thanks, Signed-off-by: Josef Bacik <jbacik@fusionio.com> Signed-off-by: Chris Mason <chris.mason@fusionio.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/send.c175
1 files changed, 72 insertions, 103 deletions
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 0a894399be16..e26a3a62fd3f 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
@@ -2120,77 +2119,6 @@ out:
2120} 2119}
2121 2120
2122/* 2121/*
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 2122 * Sends a BTRFS_SEND_C_SUBVOL command/item to userspace
2195 */ 2123 */
2196static int send_subvol_begin(struct send_ctx *sctx) 2124static int send_subvol_begin(struct send_ctx *sctx)
@@ -3622,6 +3550,72 @@ out:
3622 return ret; 3550 return ret;
3623} 3551}
3624 3552
3553static ssize_t fill_read_buf(struct send_ctx *sctx, u64 offset, u32 len)
3554{
3555 struct btrfs_root *root = sctx->send_root;
3556 struct btrfs_fs_info *fs_info = root->fs_info;
3557 struct inode *inode;
3558 struct page *page;
3559 char *addr;
3560 struct btrfs_key key;
3561 pgoff_t index = offset >> PAGE_CACHE_SHIFT;
3562 pgoff_t last_index;
3563 unsigned pg_offset = offset & ~PAGE_CACHE_MASK;
3564 ssize_t ret = 0;
3565
3566 key.objectid = sctx->cur_ino;
3567 key.type = BTRFS_INODE_ITEM_KEY;
3568 key.offset = 0;
3569
3570 inode = btrfs_iget(fs_info->sb, &key, root, NULL);
3571 if (IS_ERR(inode))
3572 return PTR_ERR(inode);
3573
3574 if (offset + len > i_size_read(inode)) {
3575 if (offset > i_size_read(inode))
3576 len = 0;
3577 else
3578 len = offset - i_size_read(inode);
3579 }
3580 if (len == 0)
3581 goto out;
3582
3583 last_index = (offset + len - 1) >> PAGE_CACHE_SHIFT;
3584 while (index <= last_index) {
3585 unsigned cur_len = min_t(unsigned, len,
3586 PAGE_CACHE_SIZE - pg_offset);
3587 page = find_or_create_page(inode->i_mapping, index, GFP_NOFS);
3588 if (!page) {
3589 ret = -ENOMEM;
3590 break;
3591 }
3592
3593 if (!PageUptodate(page)) {
3594 btrfs_readpage(NULL, page);
3595 lock_page(page);
3596 if (!PageUptodate(page)) {
3597 unlock_page(page);
3598 page_cache_release(page);
3599 ret = -EIO;
3600 break;
3601 }
3602 }
3603
3604 addr = kmap(page);
3605 memcpy(sctx->read_buf + ret, addr + pg_offset, cur_len);
3606 kunmap(page);
3607 unlock_page(page);
3608 page_cache_release(page);
3609 index++;
3610 pg_offset = 0;
3611 len -= cur_len;
3612 ret += cur_len;
3613 }
3614out:
3615 iput(inode);
3616 return ret;
3617}
3618
3625/* 3619/*
3626 * Read some bytes from the current inode/file and send a write command to 3620 * Read some bytes from the current inode/file and send a write command to
3627 * user space. 3621 * user space.
@@ -3630,35 +3624,20 @@ static int send_write(struct send_ctx *sctx, u64 offset, u32 len)
3630{ 3624{
3631 int ret = 0; 3625 int ret = 0;
3632 struct fs_path *p; 3626 struct fs_path *p;
3633 loff_t pos = offset; 3627 ssize_t num_read = 0;
3634 int num_read = 0;
3635 mm_segment_t old_fs;
3636 3628
3637 p = fs_path_alloc(); 3629 p = fs_path_alloc();
3638 if (!p) 3630 if (!p)
3639 return -ENOMEM; 3631 return -ENOMEM;
3640 3632
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); 3633verbose_printk("btrfs: send_write offset=%llu, len=%d\n", offset, len);
3651 3634
3652 ret = open_cur_inode_file(sctx); 3635 num_read = fill_read_buf(sctx, offset, len);
3653 if (ret < 0) 3636 if (num_read <= 0) {
3654 goto out; 3637 if (num_read < 0)
3655 3638 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; 3639 goto out;
3640 }
3662 3641
3663 ret = begin_cmd(sctx, BTRFS_SEND_C_WRITE); 3642 ret = begin_cmd(sctx, BTRFS_SEND_C_WRITE);
3664 if (ret < 0) 3643 if (ret < 0)
@@ -3677,7 +3656,6 @@ verbose_printk("btrfs: send_write offset=%llu, len=%d\n", offset, len);
3677tlv_put_failure: 3656tlv_put_failure:
3678out: 3657out:
3679 fs_path_free(p); 3658 fs_path_free(p);
3680 set_fs(old_fs);
3681 if (ret < 0) 3659 if (ret < 0)
3682 return ret; 3660 return ret;
3683 return num_read; 3661 return num_read;
@@ -4222,10 +4200,6 @@ static int changed_inode(struct send_ctx *sctx,
4222 u64 left_gen = 0; 4200 u64 left_gen = 0;
4223 u64 right_gen = 0; 4201 u64 right_gen = 0;
4224 4202
4225 ret = close_cur_inode_file(sctx);
4226 if (ret < 0)
4227 goto out;
4228
4229 sctx->cur_ino = key->objectid; 4203 sctx->cur_ino = key->objectid;
4230 sctx->cur_inode_new_gen = 0; 4204 sctx->cur_inode_new_gen = 0;
4231 4205
@@ -4686,11 +4660,6 @@ static int send_subvol(struct send_ctx *sctx)
4686 } 4660 }
4687 4661
4688out: 4662out:
4689 if (!ret)
4690 ret = close_cur_inode_file(sctx);
4691 else
4692 close_cur_inode_file(sctx);
4693
4694 free_recorded_refs(sctx); 4663 free_recorded_refs(sctx);
4695 return ret; 4664 return ret;
4696} 4665}