aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/ctree.c3
-rw-r--r--fs/btrfs/ctree.h5
-rw-r--r--fs/btrfs/file.c13
-rw-r--r--fs/btrfs/inode.c78
-rw-r--r--fs/btrfs/send.c158
-rw-r--r--fs/btrfs/tree-log.c172
6 files changed, 373 insertions, 56 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 316136bd6dd7..bcd0bd85e3ed 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -41,7 +41,6 @@ static void del_ptr(struct btrfs_root *root, struct btrfs_path *path,
41 int level, int slot); 41 int level, int slot);
42static void tree_mod_log_free_eb(struct btrfs_fs_info *fs_info, 42static void tree_mod_log_free_eb(struct btrfs_fs_info *fs_info,
43 struct extent_buffer *eb); 43 struct extent_buffer *eb);
44static int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path);
45 44
46struct btrfs_path *btrfs_alloc_path(void) 45struct btrfs_path *btrfs_alloc_path(void)
47{ 46{
@@ -4817,7 +4816,7 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root,
4817 * This may release the path, and so you may lose any locks held at the 4816 * This may release the path, and so you may lose any locks held at the
4818 * time you call it. 4817 * time you call it.
4819 */ 4818 */
4820static int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path) 4819int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path)
4821{ 4820{
4822 struct btrfs_key key; 4821 struct btrfs_key key;
4823 struct btrfs_disk_key found_key; 4822 struct btrfs_disk_key found_key;
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 54ab86127f7a..8be78f7d57e1 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -521,6 +521,7 @@ struct btrfs_super_block {
521#define BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF (1ULL << 6) 521#define BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF (1ULL << 6)
522#define BTRFS_FEATURE_INCOMPAT_RAID56 (1ULL << 7) 522#define BTRFS_FEATURE_INCOMPAT_RAID56 (1ULL << 7)
523#define BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA (1ULL << 8) 523#define BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA (1ULL << 8)
524#define BTRFS_FEATURE_INCOMPAT_NO_HOLES (1ULL << 9)
524 525
525#define BTRFS_FEATURE_COMPAT_SUPP 0ULL 526#define BTRFS_FEATURE_COMPAT_SUPP 0ULL
526#define BTRFS_FEATURE_COMPAT_RO_SUPP 0ULL 527#define BTRFS_FEATURE_COMPAT_RO_SUPP 0ULL
@@ -532,7 +533,8 @@ struct btrfs_super_block {
532 BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO | \ 533 BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO | \
533 BTRFS_FEATURE_INCOMPAT_RAID56 | \ 534 BTRFS_FEATURE_INCOMPAT_RAID56 | \
534 BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF | \ 535 BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF | \
535 BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA) 536 BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA | \
537 BTRFS_FEATURE_INCOMPAT_NO_HOLES)
536 538
537/* 539/*
538 * A leaf is full of items. offset and size tell us where to find 540 * A leaf is full of items. offset and size tell us where to find
@@ -3399,6 +3401,7 @@ static inline int btrfs_insert_empty_item(struct btrfs_trans_handle *trans,
3399} 3401}
3400 3402
3401int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path); 3403int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path);
3404int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path);
3402int btrfs_next_old_leaf(struct btrfs_root *root, struct btrfs_path *path, 3405int btrfs_next_old_leaf(struct btrfs_root *root, struct btrfs_path *path,
3403 u64 time_seq); 3406 u64 time_seq);
3404static inline int btrfs_next_old_item(struct btrfs_root *root, 3407static inline int btrfs_next_old_item(struct btrfs_root *root,
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 82d0342763c5..c77da440146a 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1963,11 +1963,13 @@ static int fill_holes(struct btrfs_trans_handle *trans, struct inode *inode,
1963 struct btrfs_key key; 1963 struct btrfs_key key;
1964 int ret; 1964 int ret;
1965 1965
1966 if (btrfs_fs_incompat(root->fs_info, NO_HOLES))
1967 goto out;
1968
1966 key.objectid = btrfs_ino(inode); 1969 key.objectid = btrfs_ino(inode);
1967 key.type = BTRFS_EXTENT_DATA_KEY; 1970 key.type = BTRFS_EXTENT_DATA_KEY;
1968 key.offset = offset; 1971 key.offset = offset;
1969 1972
1970
1971 ret = btrfs_search_slot(trans, root, &key, path, 0, 1); 1973 ret = btrfs_search_slot(trans, root, &key, path, 0, 1);
1972 if (ret < 0) 1974 if (ret < 0)
1973 return ret; 1975 return ret;
@@ -2064,8 +2066,10 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len)
2064 u64 drop_end; 2066 u64 drop_end;
2065 int ret = 0; 2067 int ret = 0;
2066 int err = 0; 2068 int err = 0;
2069 int rsv_count;
2067 bool same_page = ((offset >> PAGE_CACHE_SHIFT) == 2070 bool same_page = ((offset >> PAGE_CACHE_SHIFT) ==
2068 ((offset + len - 1) >> PAGE_CACHE_SHIFT)); 2071 ((offset + len - 1) >> PAGE_CACHE_SHIFT));
2072 bool no_holes = btrfs_fs_incompat(root->fs_info, NO_HOLES);
2069 2073
2070 ret = btrfs_wait_ordered_range(inode, offset, len); 2074 ret = btrfs_wait_ordered_range(inode, offset, len);
2071 if (ret) 2075 if (ret)
@@ -2163,9 +2167,10 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len)
2163 /* 2167 /*
2164 * 1 - update the inode 2168 * 1 - update the inode
2165 * 1 - removing the extents in the range 2169 * 1 - removing the extents in the range
2166 * 1 - adding the hole extent 2170 * 1 - adding the hole extent if no_holes isn't set
2167 */ 2171 */
2168 trans = btrfs_start_transaction(root, 3); 2172 rsv_count = no_holes ? 2 : 3;
2173 trans = btrfs_start_transaction(root, rsv_count);
2169 if (IS_ERR(trans)) { 2174 if (IS_ERR(trans)) {
2170 err = PTR_ERR(trans); 2175 err = PTR_ERR(trans);
2171 goto out_free; 2176 goto out_free;
@@ -2202,7 +2207,7 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len)
2202 btrfs_end_transaction(trans, root); 2207 btrfs_end_transaction(trans, root);
2203 btrfs_btree_balance_dirty(root); 2208 btrfs_btree_balance_dirty(root);
2204 2209
2205 trans = btrfs_start_transaction(root, 3); 2210 trans = btrfs_start_transaction(root, rsv_count);
2206 if (IS_ERR(trans)) { 2211 if (IS_ERR(trans)) {
2207 ret = PTR_ERR(trans); 2212 ret = PTR_ERR(trans);
2208 trans = NULL; 2213 trans = NULL;
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index f1a77449d032..c0c0dc8f07fa 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -4203,6 +4203,49 @@ out:
4203 return ret; 4203 return ret;
4204} 4204}
4205 4205
4206static int maybe_insert_hole(struct btrfs_root *root, struct inode *inode,
4207 u64 offset, u64 len)
4208{
4209 struct btrfs_trans_handle *trans;
4210 int ret;
4211
4212 /*
4213 * Still need to make sure the inode looks like it's been updated so
4214 * that any holes get logged if we fsync.
4215 */
4216 if (btrfs_fs_incompat(root->fs_info, NO_HOLES)) {
4217 BTRFS_I(inode)->last_trans = root->fs_info->generation;
4218 BTRFS_I(inode)->last_sub_trans = root->log_transid;
4219 BTRFS_I(inode)->last_log_commit = root->last_log_commit;
4220 return 0;
4221 }
4222
4223 /*
4224 * 1 - for the one we're dropping
4225 * 1 - for the one we're adding
4226 * 1 - for updating the inode.
4227 */
4228 trans = btrfs_start_transaction(root, 3);
4229 if (IS_ERR(trans))
4230 return PTR_ERR(trans);
4231
4232 ret = btrfs_drop_extents(trans, root, inode, offset, offset + len, 1);
4233 if (ret) {
4234 btrfs_abort_transaction(trans, root, ret);
4235 btrfs_end_transaction(trans, root);
4236 return ret;
4237 }
4238
4239 ret = btrfs_insert_file_extent(trans, root, btrfs_ino(inode), offset,
4240 0, 0, len, 0, len, 0, 0, 0);
4241 if (ret)
4242 btrfs_abort_transaction(trans, root, ret);
4243 else
4244 btrfs_update_inode(trans, root, inode);
4245 btrfs_end_transaction(trans, root);
4246 return ret;
4247}
4248
4206/* 4249/*
4207 * This function puts in dummy file extents for the area we're creating a hole 4250 * This function puts in dummy file extents for the area we're creating a hole
4208 * for. So if we are truncating this file to a larger size we need to insert 4251 * for. So if we are truncating this file to a larger size we need to insert
@@ -4211,7 +4254,6 @@ out:
4211 */ 4254 */
4212int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size) 4255int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size)
4213{ 4256{
4214 struct btrfs_trans_handle *trans;
4215 struct btrfs_root *root = BTRFS_I(inode)->root; 4257 struct btrfs_root *root = BTRFS_I(inode)->root;
4216 struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; 4258 struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
4217 struct extent_map *em = NULL; 4259 struct extent_map *em = NULL;
@@ -4266,31 +4308,10 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size)
4266 struct extent_map *hole_em; 4308 struct extent_map *hole_em;
4267 hole_size = last_byte - cur_offset; 4309 hole_size = last_byte - cur_offset;
4268 4310
4269 trans = btrfs_start_transaction(root, 3); 4311 err = maybe_insert_hole(root, inode, cur_offset,
4270 if (IS_ERR(trans)) { 4312 hole_size);
4271 err = PTR_ERR(trans); 4313 if (err)
4272 break;
4273 }
4274
4275 err = btrfs_drop_extents(trans, root, inode,
4276 cur_offset,
4277 cur_offset + hole_size, 1);
4278 if (err) {
4279 btrfs_abort_transaction(trans, root, err);
4280 btrfs_end_transaction(trans, root);
4281 break;
4282 }
4283
4284 err = btrfs_insert_file_extent(trans, root,
4285 btrfs_ino(inode), cur_offset, 0,
4286 0, hole_size, 0, hole_size,
4287 0, 0, 0);
4288 if (err) {
4289 btrfs_abort_transaction(trans, root, err);
4290 btrfs_end_transaction(trans, root);
4291 break; 4314 break;
4292 }
4293
4294 btrfs_drop_extent_cache(inode, cur_offset, 4315 btrfs_drop_extent_cache(inode, cur_offset,
4295 cur_offset + hole_size - 1, 0); 4316 cur_offset + hole_size - 1, 0);
4296 hole_em = alloc_extent_map(); 4317 hole_em = alloc_extent_map();
@@ -4309,7 +4330,7 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size)
4309 hole_em->ram_bytes = hole_size; 4330 hole_em->ram_bytes = hole_size;
4310 hole_em->bdev = root->fs_info->fs_devices->latest_bdev; 4331 hole_em->bdev = root->fs_info->fs_devices->latest_bdev;
4311 hole_em->compress_type = BTRFS_COMPRESS_NONE; 4332 hole_em->compress_type = BTRFS_COMPRESS_NONE;
4312 hole_em->generation = trans->transid; 4333 hole_em->generation = root->fs_info->generation;
4313 4334
4314 while (1) { 4335 while (1) {
4315 write_lock(&em_tree->lock); 4336 write_lock(&em_tree->lock);
@@ -4322,17 +4343,14 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size)
4322 hole_size - 1, 0); 4343 hole_size - 1, 0);
4323 } 4344 }
4324 free_extent_map(hole_em); 4345 free_extent_map(hole_em);
4325next:
4326 btrfs_update_inode(trans, root, inode);
4327 btrfs_end_transaction(trans, root);
4328 } 4346 }
4347next:
4329 free_extent_map(em); 4348 free_extent_map(em);
4330 em = NULL; 4349 em = NULL;
4331 cur_offset = last_byte; 4350 cur_offset = last_byte;
4332 if (cur_offset >= block_end) 4351 if (cur_offset >= block_end)
4333 break; 4352 break;
4334 } 4353 }
4335
4336 free_extent_map(em); 4354 free_extent_map(em);
4337 unlock_extent_cached(io_tree, hole_start, block_end - 1, &cached_state, 4355 unlock_extent_cached(io_tree, hole_start, block_end - 1, &cached_state,
4338 GFP_NOFS); 4356 GFP_NOFS);
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 945d1db98f26..29803b4129fc 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -111,6 +111,7 @@ struct send_ctx {
111 int cur_inode_deleted; 111 int cur_inode_deleted;
112 u64 cur_inode_size; 112 u64 cur_inode_size;
113 u64 cur_inode_mode; 113 u64 cur_inode_mode;
114 u64 cur_inode_last_extent;
114 115
115 u64 send_progress; 116 u64 send_progress;
116 117
@@ -145,6 +146,13 @@ struct name_cache_entry {
145 char name[]; 146 char name[];
146}; 147};
147 148
149static int need_send_hole(struct send_ctx *sctx)
150{
151 return (sctx->parent_root && !sctx->cur_inode_new &&
152 !sctx->cur_inode_new_gen && !sctx->cur_inode_deleted &&
153 S_ISREG(sctx->cur_inode_mode));
154}
155
148static void fs_path_reset(struct fs_path *p) 156static void fs_path_reset(struct fs_path *p)
149{ 157{
150 if (p->reversed) { 158 if (p->reversed) {
@@ -3752,6 +3760,39 @@ out:
3752 return ret; 3760 return ret;
3753} 3761}
3754 3762
3763static int send_hole(struct send_ctx *sctx, u64 end)
3764{
3765 struct fs_path *p = NULL;
3766 u64 offset = sctx->cur_inode_last_extent;
3767 u64 len;
3768 int ret = 0;
3769
3770 p = fs_path_alloc();
3771 if (!p)
3772 return -ENOMEM;
3773 memset(sctx->read_buf, 0, BTRFS_SEND_READ_SIZE);
3774 while (offset < end) {
3775 len = min_t(u64, end - offset, BTRFS_SEND_READ_SIZE);
3776
3777 ret = begin_cmd(sctx, BTRFS_SEND_C_WRITE);
3778 if (ret < 0)
3779 break;
3780 ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p);
3781 if (ret < 0)
3782 break;
3783 TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
3784 TLV_PUT_U64(sctx, BTRFS_SEND_A_FILE_OFFSET, offset);
3785 TLV_PUT(sctx, BTRFS_SEND_A_DATA, sctx->read_buf, len);
3786 ret = send_cmd(sctx);
3787 if (ret < 0)
3788 break;
3789 offset += len;
3790 }
3791tlv_put_failure:
3792 fs_path_free(p);
3793 return ret;
3794}
3795
3755static int send_write_or_clone(struct send_ctx *sctx, 3796static int send_write_or_clone(struct send_ctx *sctx,
3756 struct btrfs_path *path, 3797 struct btrfs_path *path,
3757 struct btrfs_key *key, 3798 struct btrfs_key *key,
@@ -3979,6 +4020,84 @@ out:
3979 return ret; 4020 return ret;
3980} 4021}
3981 4022
4023static int get_last_extent(struct send_ctx *sctx, u64 offset)
4024{
4025 struct btrfs_path *path;
4026 struct btrfs_root *root = sctx->send_root;
4027 struct btrfs_file_extent_item *fi;
4028 struct btrfs_key key;
4029 u64 extent_end;
4030 u8 type;
4031 int ret;
4032
4033 path = alloc_path_for_send();
4034 if (!path)
4035 return -ENOMEM;
4036
4037 sctx->cur_inode_last_extent = 0;
4038
4039 key.objectid = sctx->cur_ino;
4040 key.type = BTRFS_EXTENT_DATA_KEY;
4041 key.offset = offset;
4042 ret = btrfs_search_slot_for_read(root, &key, path, 0, 1);
4043 if (ret < 0)
4044 goto out;
4045 ret = 0;
4046 btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
4047 if (key.objectid != sctx->cur_ino || key.type != BTRFS_EXTENT_DATA_KEY)
4048 goto out;
4049
4050 fi = btrfs_item_ptr(path->nodes[0], path->slots[0],
4051 struct btrfs_file_extent_item);
4052 type = btrfs_file_extent_type(path->nodes[0], fi);
4053 if (type == BTRFS_FILE_EXTENT_INLINE) {
4054 u64 size = btrfs_file_extent_inline_len(path->nodes[0], fi);
4055 extent_end = ALIGN(key.offset + size,
4056 sctx->send_root->sectorsize);
4057 } else {
4058 extent_end = key.offset +
4059 btrfs_file_extent_num_bytes(path->nodes[0], fi);
4060 }
4061 sctx->cur_inode_last_extent = extent_end;
4062out:
4063 btrfs_free_path(path);
4064 return ret;
4065}
4066
4067static int maybe_send_hole(struct send_ctx *sctx, struct btrfs_path *path,
4068 struct btrfs_key *key)
4069{
4070 struct btrfs_file_extent_item *fi;
4071 u64 extent_end;
4072 u8 type;
4073 int ret = 0;
4074
4075 if (sctx->cur_ino != key->objectid || !need_send_hole(sctx))
4076 return 0;
4077
4078 if (sctx->cur_inode_last_extent == (u64)-1) {
4079 ret = get_last_extent(sctx, key->offset - 1);
4080 if (ret)
4081 return ret;
4082 }
4083
4084 fi = btrfs_item_ptr(path->nodes[0], path->slots[0],
4085 struct btrfs_file_extent_item);
4086 type = btrfs_file_extent_type(path->nodes[0], fi);
4087 if (type == BTRFS_FILE_EXTENT_INLINE) {
4088 u64 size = btrfs_file_extent_inline_len(path->nodes[0], fi);
4089 extent_end = ALIGN(key->offset + size,
4090 sctx->send_root->sectorsize);
4091 } else {
4092 extent_end = key->offset +
4093 btrfs_file_extent_num_bytes(path->nodes[0], fi);
4094 }
4095 if (sctx->cur_inode_last_extent < key->offset)
4096 ret = send_hole(sctx, key->offset);
4097 sctx->cur_inode_last_extent = extent_end;
4098 return ret;
4099}
4100
3982static int process_extent(struct send_ctx *sctx, 4101static int process_extent(struct send_ctx *sctx,
3983 struct btrfs_path *path, 4102 struct btrfs_path *path,
3984 struct btrfs_key *key) 4103 struct btrfs_key *key)
@@ -3995,7 +4114,7 @@ static int process_extent(struct send_ctx *sctx,
3995 goto out; 4114 goto out;
3996 if (ret) { 4115 if (ret) {
3997 ret = 0; 4116 ret = 0;
3998 goto out; 4117 goto out_hole;
3999 } 4118 }
4000 } else { 4119 } else {
4001 struct btrfs_file_extent_item *ei; 4120 struct btrfs_file_extent_item *ei;
@@ -4031,7 +4150,10 @@ static int process_extent(struct send_ctx *sctx,
4031 goto out; 4150 goto out;
4032 4151
4033 ret = send_write_or_clone(sctx, path, key, found_clone); 4152 ret = send_write_or_clone(sctx, path, key, found_clone);
4034 4153 if (ret)
4154 goto out;
4155out_hole:
4156 ret = maybe_send_hole(sctx, path, key);
4035out: 4157out:
4036 return ret; 4158 return ret;
4037} 4159}
@@ -4157,6 +4279,19 @@ static int finish_inode_if_needed(struct send_ctx *sctx, int at_end)
4157 } 4279 }
4158 4280
4159 if (S_ISREG(sctx->cur_inode_mode)) { 4281 if (S_ISREG(sctx->cur_inode_mode)) {
4282 if (need_send_hole(sctx)) {
4283 if (sctx->cur_inode_last_extent == (u64)-1) {
4284 ret = get_last_extent(sctx, (u64)-1);
4285 if (ret)
4286 goto out;
4287 }
4288 if (sctx->cur_inode_last_extent <
4289 sctx->cur_inode_size) {
4290 ret = send_hole(sctx, sctx->cur_inode_size);
4291 if (ret)
4292 goto out;
4293 }
4294 }
4160 ret = send_truncate(sctx, sctx->cur_ino, sctx->cur_inode_gen, 4295 ret = send_truncate(sctx, sctx->cur_ino, sctx->cur_inode_gen,
4161 sctx->cur_inode_size); 4296 sctx->cur_inode_size);
4162 if (ret < 0) 4297 if (ret < 0)
@@ -4200,6 +4335,7 @@ static int changed_inode(struct send_ctx *sctx,
4200 4335
4201 sctx->cur_ino = key->objectid; 4336 sctx->cur_ino = key->objectid;
4202 sctx->cur_inode_new_gen = 0; 4337 sctx->cur_inode_new_gen = 0;
4338 sctx->cur_inode_last_extent = (u64)-1;
4203 4339
4204 /* 4340 /*
4205 * Set send_progress to current inode. This will tell all get_cur_xxx 4341 * Set send_progress to current inode. This will tell all get_cur_xxx
@@ -4480,14 +4616,18 @@ static int changed_cb(struct btrfs_root *left_root,
4480 struct send_ctx *sctx = ctx; 4616 struct send_ctx *sctx = ctx;
4481 4617
4482 if (result == BTRFS_COMPARE_TREE_SAME) { 4618 if (result == BTRFS_COMPARE_TREE_SAME) {
4483 if (key->type != BTRFS_INODE_REF_KEY && 4619 if (key->type == BTRFS_INODE_REF_KEY ||
4484 key->type != BTRFS_INODE_EXTREF_KEY) 4620 key->type == BTRFS_INODE_EXTREF_KEY) {
4485 return 0; 4621 ret = compare_refs(sctx, left_path, key);
4486 ret = compare_refs(sctx, left_path, key); 4622 if (!ret)
4487 if (!ret) 4623 return 0;
4624 if (ret < 0)
4625 return ret;
4626 } else if (key->type == BTRFS_EXTENT_DATA_KEY) {
4627 return maybe_send_hole(sctx, left_path, key);
4628 } else {
4488 return 0; 4629 return 0;
4489 if (ret < 0) 4630 }
4490 return ret;
4491 result = BTRFS_COMPARE_TREE_CHANGED; 4631 result = BTRFS_COMPARE_TREE_CHANGED;
4492 ret = 0; 4632 ret = 0;
4493 } 4633 }
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 9f7fc51ca334..e7d7a837512a 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -3194,7 +3194,7 @@ static int log_inode_item(struct btrfs_trans_handle *trans,
3194static noinline int copy_items(struct btrfs_trans_handle *trans, 3194static noinline int copy_items(struct btrfs_trans_handle *trans,
3195 struct inode *inode, 3195 struct inode *inode,
3196 struct btrfs_path *dst_path, 3196 struct btrfs_path *dst_path,
3197 struct extent_buffer *src, 3197 struct btrfs_path *src_path, u64 *last_extent,
3198 int start_slot, int nr, int inode_only) 3198 int start_slot, int nr, int inode_only)
3199{ 3199{
3200 unsigned long src_offset; 3200 unsigned long src_offset;
@@ -3202,6 +3202,8 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
3202 struct btrfs_root *log = BTRFS_I(inode)->root->log_root; 3202 struct btrfs_root *log = BTRFS_I(inode)->root->log_root;
3203 struct btrfs_file_extent_item *extent; 3203 struct btrfs_file_extent_item *extent;
3204 struct btrfs_inode_item *inode_item; 3204 struct btrfs_inode_item *inode_item;
3205 struct extent_buffer *src = src_path->nodes[0];
3206 struct btrfs_key first_key, last_key, key;
3205 int ret; 3207 int ret;
3206 struct btrfs_key *ins_keys; 3208 struct btrfs_key *ins_keys;
3207 u32 *ins_sizes; 3209 u32 *ins_sizes;
@@ -3209,6 +3211,9 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
3209 int i; 3211 int i;
3210 struct list_head ordered_sums; 3212 struct list_head ordered_sums;
3211 int skip_csum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM; 3213 int skip_csum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM;
3214 bool has_extents = false;
3215 bool need_find_last_extent = (*last_extent == 0);
3216 bool done = false;
3212 3217
3213 INIT_LIST_HEAD(&ordered_sums); 3218 INIT_LIST_HEAD(&ordered_sums);
3214 3219
@@ -3217,6 +3222,8 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
3217 if (!ins_data) 3222 if (!ins_data)
3218 return -ENOMEM; 3223 return -ENOMEM;
3219 3224
3225 first_key.objectid = (u64)-1;
3226
3220 ins_sizes = (u32 *)ins_data; 3227 ins_sizes = (u32 *)ins_data;
3221 ins_keys = (struct btrfs_key *)(ins_data + nr * sizeof(u32)); 3228 ins_keys = (struct btrfs_key *)(ins_data + nr * sizeof(u32));
3222 3229
@@ -3237,6 +3244,9 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
3237 3244
3238 src_offset = btrfs_item_ptr_offset(src, start_slot + i); 3245 src_offset = btrfs_item_ptr_offset(src, start_slot + i);
3239 3246
3247 if ((i == (nr - 1)))
3248 last_key = ins_keys[i];
3249
3240 if (ins_keys[i].type == BTRFS_INODE_ITEM_KEY) { 3250 if (ins_keys[i].type == BTRFS_INODE_ITEM_KEY) {
3241 inode_item = btrfs_item_ptr(dst_path->nodes[0], 3251 inode_item = btrfs_item_ptr(dst_path->nodes[0],
3242 dst_path->slots[0], 3252 dst_path->slots[0],
@@ -3248,6 +3258,21 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
3248 src_offset, ins_sizes[i]); 3258 src_offset, ins_sizes[i]);
3249 } 3259 }
3250 3260
3261 /*
3262 * We set need_find_last_extent here in case we know we were
3263 * processing other items and then walk into the first extent in
3264 * the inode. If we don't hit an extent then nothing changes,
3265 * we'll do the last search the next time around.
3266 */
3267 if (ins_keys[i].type == BTRFS_EXTENT_DATA_KEY) {
3268 has_extents = true;
3269 if (need_find_last_extent &&
3270 first_key.objectid == (u64)-1)
3271 first_key = ins_keys[i];
3272 } else {
3273 need_find_last_extent = false;
3274 }
3275
3251 /* take a reference on file data extents so that truncates 3276 /* take a reference on file data extents so that truncates
3252 * or deletes of this inode don't have to relog the inode 3277 * or deletes of this inode don't have to relog the inode
3253 * again 3278 * again
@@ -3312,6 +3337,126 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
3312 list_del(&sums->list); 3337 list_del(&sums->list);
3313 kfree(sums); 3338 kfree(sums);
3314 } 3339 }
3340
3341 if (!has_extents)
3342 return ret;
3343
3344 /*
3345 * Because we use btrfs_search_forward we could skip leaves that were
3346 * not modified and then assume *last_extent is valid when it really
3347 * isn't. So back up to the previous leaf and read the end of the last
3348 * extent before we go and fill in holes.
3349 */
3350 if (need_find_last_extent) {
3351 u64 len;
3352
3353 ret = btrfs_prev_leaf(BTRFS_I(inode)->root, src_path);
3354 if (ret < 0)
3355 return ret;
3356 if (ret)
3357 goto fill_holes;
3358 if (src_path->slots[0])
3359 src_path->slots[0]--;
3360 src = src_path->nodes[0];
3361 btrfs_item_key_to_cpu(src, &key, src_path->slots[0]);
3362 if (key.objectid != btrfs_ino(inode) ||
3363 key.type != BTRFS_EXTENT_DATA_KEY)
3364 goto fill_holes;
3365 extent = btrfs_item_ptr(src, src_path->slots[0],
3366 struct btrfs_file_extent_item);
3367 if (btrfs_file_extent_type(src, extent) ==
3368 BTRFS_FILE_EXTENT_INLINE) {
3369 len = btrfs_file_extent_inline_len(src, extent);
3370 *last_extent = ALIGN(key.offset + len,
3371 log->sectorsize);
3372 } else {
3373 len = btrfs_file_extent_num_bytes(src, extent);
3374 *last_extent = key.offset + len;
3375 }
3376 }
3377fill_holes:
3378 /* So we did prev_leaf, now we need to move to the next leaf, but a few
3379 * things could have happened
3380 *
3381 * 1) A merge could have happened, so we could currently be on a leaf
3382 * that holds what we were copying in the first place.
3383 * 2) A split could have happened, and now not all of the items we want
3384 * are on the same leaf.
3385 *
3386 * So we need to adjust how we search for holes, we need to drop the
3387 * path and re-search for the first extent key we found, and then walk
3388 * forward until we hit the last one we copied.
3389 */
3390 if (need_find_last_extent) {
3391 /* btrfs_prev_leaf could return 1 without releasing the path */
3392 btrfs_release_path(src_path);
3393 ret = btrfs_search_slot(NULL, BTRFS_I(inode)->root, &first_key,
3394 src_path, 0, 0);
3395 if (ret < 0)
3396 return ret;
3397 ASSERT(ret == 0);
3398 src = src_path->nodes[0];
3399 i = src_path->slots[0];
3400 } else {
3401 i = start_slot;
3402 }
3403
3404 /*
3405 * Ok so here we need to go through and fill in any holes we may have
3406 * to make sure that holes are punched for those areas in case they had
3407 * extents previously.
3408 */
3409 while (!done) {
3410 u64 offset, len;
3411 u64 extent_end;
3412
3413 if (i >= btrfs_header_nritems(src_path->nodes[0])) {
3414 ret = btrfs_next_leaf(BTRFS_I(inode)->root, src_path);
3415 if (ret < 0)
3416 return ret;
3417 ASSERT(ret == 0);
3418 src = src_path->nodes[0];
3419 i = 0;
3420 }
3421
3422 btrfs_item_key_to_cpu(src, &key, i);
3423 if (!btrfs_comp_cpu_keys(&key, &last_key))
3424 done = true;
3425 if (key.objectid != btrfs_ino(inode) ||
3426 key.type != BTRFS_EXTENT_DATA_KEY) {
3427 i++;
3428 continue;
3429 }
3430 extent = btrfs_item_ptr(src, i, struct btrfs_file_extent_item);
3431 if (btrfs_file_extent_type(src, extent) ==
3432 BTRFS_FILE_EXTENT_INLINE) {
3433 len = btrfs_file_extent_inline_len(src, extent);
3434 extent_end = ALIGN(key.offset + len, log->sectorsize);
3435 } else {
3436 len = btrfs_file_extent_num_bytes(src, extent);
3437 extent_end = key.offset + len;
3438 }
3439 i++;
3440
3441 if (*last_extent == key.offset) {
3442 *last_extent = extent_end;
3443 continue;
3444 }
3445 offset = *last_extent;
3446 len = key.offset - *last_extent;
3447 ret = btrfs_insert_file_extent(trans, log, btrfs_ino(inode),
3448 offset, 0, 0, len, 0, len, 0,
3449 0, 0);
3450 if (ret)
3451 break;
3452 *last_extent = offset + len;
3453 }
3454 /*
3455 * Need to let the callers know we dropped the path so they should
3456 * re-search.
3457 */
3458 if (!ret && need_find_last_extent)
3459 ret = 1;
3315 return ret; 3460 return ret;
3316} 3461}
3317 3462
@@ -3630,6 +3775,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
3630 struct btrfs_key max_key; 3775 struct btrfs_key max_key;
3631 struct btrfs_root *log = root->log_root; 3776 struct btrfs_root *log = root->log_root;
3632 struct extent_buffer *src = NULL; 3777 struct extent_buffer *src = NULL;
3778 u64 last_extent = 0;
3633 int err = 0; 3779 int err = 0;
3634 int ret; 3780 int ret;
3635 int nritems; 3781 int nritems;
@@ -3745,11 +3891,15 @@ again:
3745 goto next_slot; 3891 goto next_slot;
3746 } 3892 }
3747 3893
3748 ret = copy_items(trans, inode, dst_path, src, ins_start_slot, 3894 ret = copy_items(trans, inode, dst_path, path, &last_extent,
3749 ins_nr, inode_only); 3895 ins_start_slot, ins_nr, inode_only);
3750 if (ret) { 3896 if (ret < 0) {
3751 err = ret; 3897 err = ret;
3752 goto out_unlock; 3898 goto out_unlock;
3899 } if (ret) {
3900 ins_nr = 0;
3901 btrfs_release_path(path);
3902 continue;
3753 } 3903 }
3754 ins_nr = 1; 3904 ins_nr = 1;
3755 ins_start_slot = path->slots[0]; 3905 ins_start_slot = path->slots[0];
@@ -3763,13 +3913,14 @@ next_slot:
3763 goto again; 3913 goto again;
3764 } 3914 }
3765 if (ins_nr) { 3915 if (ins_nr) {
3766 ret = copy_items(trans, inode, dst_path, src, 3916 ret = copy_items(trans, inode, dst_path, path,
3767 ins_start_slot, 3917 &last_extent, ins_start_slot,
3768 ins_nr, inode_only); 3918 ins_nr, inode_only);
3769 if (ret) { 3919 if (ret < 0) {
3770 err = ret; 3920 err = ret;
3771 goto out_unlock; 3921 goto out_unlock;
3772 } 3922 }
3923 ret = 0;
3773 ins_nr = 0; 3924 ins_nr = 0;
3774 } 3925 }
3775 btrfs_release_path(path); 3926 btrfs_release_path(path);
@@ -3784,12 +3935,13 @@ next_slot:
3784 } 3935 }
3785 } 3936 }
3786 if (ins_nr) { 3937 if (ins_nr) {
3787 ret = copy_items(trans, inode, dst_path, src, ins_start_slot, 3938 ret = copy_items(trans, inode, dst_path, path, &last_extent,
3788 ins_nr, inode_only); 3939 ins_start_slot, ins_nr, inode_only);
3789 if (ret) { 3940 if (ret < 0) {
3790 err = ret; 3941 err = ret;
3791 goto out_unlock; 3942 goto out_unlock;
3792 } 3943 }
3944 ret = 0;
3793 ins_nr = 0; 3945 ins_nr = 0;
3794 } 3946 }
3795 3947