diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-08-10 18:21:47 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-08-10 18:21:47 -0400 |
commit | d92581fcad188d38a5c82c01ace43623bcafea48 (patch) | |
tree | 792b2e31170b32a41f4f19cea7a2be5efc5eb251 /fs | |
parent | b8ea0d06ff00906f6ff133851496b48439d5b04f (diff) | |
parent | db62efbbf883c099d44b0fafe18f8ad8f0396892 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs
Pull btrfs fixes from Chris Mason:
"These are assorted fixes, mostly from Josef nailing down xfstests
runs. Zach also has a long standing fix for problems with readdir
wrapping f_pos (or ctx->pos)
These patches were spread out over different bases, so I rebased
things on top of rc4 and retested overnight"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs:
btrfs: don't loop on large offsets in readdir
Btrfs: check to see if root_list is empty before adding it to dead roots
Btrfs: release both paths before logging dir/changed extents
Btrfs: allow splitting of hole em's when dropping extent cache
Btrfs: make sure the backref walker catches all refs to our extent
Btrfs: fix backref walking when we hit a compressed extent
Btrfs: do not offset physical if we're compressed
Btrfs: fix extent buffer leak after backref walking
Btrfs: fix a bug of snapshot-aware defrag to make it work on partial extents
btrfs: fix file truncation if FALLOC_FL_KEEP_SIZE is specified
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/backref.c | 48 | ||||
-rw-r--r-- | fs/btrfs/ctree.c | 1 | ||||
-rw-r--r-- | fs/btrfs/extent_io.c | 9 | ||||
-rw-r--r-- | fs/btrfs/file.c | 62 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 52 | ||||
-rw-r--r-- | fs/btrfs/transaction.c | 8 | ||||
-rw-r--r-- | fs/btrfs/transaction.h | 2 | ||||
-rw-r--r-- | fs/btrfs/tree-log.c | 5 |
8 files changed, 119 insertions, 68 deletions
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index eaf133384a8f..8bc5e8ccb091 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c | |||
@@ -36,16 +36,23 @@ static int check_extent_in_eb(struct btrfs_key *key, struct extent_buffer *eb, | |||
36 | u64 extent_item_pos, | 36 | u64 extent_item_pos, |
37 | struct extent_inode_elem **eie) | 37 | struct extent_inode_elem **eie) |
38 | { | 38 | { |
39 | u64 data_offset; | 39 | u64 offset = 0; |
40 | u64 data_len; | ||
41 | struct extent_inode_elem *e; | 40 | struct extent_inode_elem *e; |
42 | 41 | ||
43 | data_offset = btrfs_file_extent_offset(eb, fi); | 42 | if (!btrfs_file_extent_compression(eb, fi) && |
44 | data_len = btrfs_file_extent_num_bytes(eb, fi); | 43 | !btrfs_file_extent_encryption(eb, fi) && |
44 | !btrfs_file_extent_other_encoding(eb, fi)) { | ||
45 | u64 data_offset; | ||
46 | u64 data_len; | ||
45 | 47 | ||
46 | if (extent_item_pos < data_offset || | 48 | data_offset = btrfs_file_extent_offset(eb, fi); |
47 | extent_item_pos >= data_offset + data_len) | 49 | data_len = btrfs_file_extent_num_bytes(eb, fi); |
48 | return 1; | 50 | |
51 | if (extent_item_pos < data_offset || | ||
52 | extent_item_pos >= data_offset + data_len) | ||
53 | return 1; | ||
54 | offset = extent_item_pos - data_offset; | ||
55 | } | ||
49 | 56 | ||
50 | e = kmalloc(sizeof(*e), GFP_NOFS); | 57 | e = kmalloc(sizeof(*e), GFP_NOFS); |
51 | if (!e) | 58 | if (!e) |
@@ -53,7 +60,7 @@ static int check_extent_in_eb(struct btrfs_key *key, struct extent_buffer *eb, | |||
53 | 60 | ||
54 | e->next = *eie; | 61 | e->next = *eie; |
55 | e->inum = key->objectid; | 62 | e->inum = key->objectid; |
56 | e->offset = key->offset + (extent_item_pos - data_offset); | 63 | e->offset = key->offset + offset; |
57 | *eie = e; | 64 | *eie = e; |
58 | 65 | ||
59 | return 0; | 66 | return 0; |
@@ -189,7 +196,7 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path, | |||
189 | struct extent_buffer *eb; | 196 | struct extent_buffer *eb; |
190 | struct btrfs_key key; | 197 | struct btrfs_key key; |
191 | struct btrfs_file_extent_item *fi; | 198 | struct btrfs_file_extent_item *fi; |
192 | struct extent_inode_elem *eie = NULL; | 199 | struct extent_inode_elem *eie = NULL, *old = NULL; |
193 | u64 disk_byte; | 200 | u64 disk_byte; |
194 | 201 | ||
195 | if (level != 0) { | 202 | if (level != 0) { |
@@ -223,6 +230,7 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path, | |||
223 | 230 | ||
224 | if (disk_byte == wanted_disk_byte) { | 231 | if (disk_byte == wanted_disk_byte) { |
225 | eie = NULL; | 232 | eie = NULL; |
233 | old = NULL; | ||
226 | if (extent_item_pos) { | 234 | if (extent_item_pos) { |
227 | ret = check_extent_in_eb(&key, eb, fi, | 235 | ret = check_extent_in_eb(&key, eb, fi, |
228 | *extent_item_pos, | 236 | *extent_item_pos, |
@@ -230,18 +238,20 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path, | |||
230 | if (ret < 0) | 238 | if (ret < 0) |
231 | break; | 239 | break; |
232 | } | 240 | } |
233 | if (!ret) { | 241 | if (ret > 0) |
234 | ret = ulist_add(parents, eb->start, | 242 | goto next; |
235 | (uintptr_t)eie, GFP_NOFS); | 243 | ret = ulist_add_merge(parents, eb->start, |
236 | if (ret < 0) | 244 | (uintptr_t)eie, |
237 | break; | 245 | (u64 *)&old, GFP_NOFS); |
238 | if (!extent_item_pos) { | 246 | if (ret < 0) |
239 | ret = btrfs_next_old_leaf(root, path, | 247 | break; |
240 | time_seq); | 248 | if (!ret && extent_item_pos) { |
241 | continue; | 249 | while (old->next) |
242 | } | 250 | old = old->next; |
251 | old->next = eie; | ||
243 | } | 252 | } |
244 | } | 253 | } |
254 | next: | ||
245 | ret = btrfs_next_old_item(root, path, time_seq); | 255 | ret = btrfs_next_old_item(root, path, time_seq); |
246 | } | 256 | } |
247 | 257 | ||
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 5bf4c39e2ad6..ed504607d8ec 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -1271,7 +1271,6 @@ tree_mod_log_rewind(struct btrfs_fs_info *fs_info, struct extent_buffer *eb, | |||
1271 | BUG_ON(!eb_rewin); | 1271 | BUG_ON(!eb_rewin); |
1272 | } | 1272 | } |
1273 | 1273 | ||
1274 | extent_buffer_get(eb_rewin); | ||
1275 | btrfs_tree_read_unlock(eb); | 1274 | btrfs_tree_read_unlock(eb); |
1276 | free_extent_buffer(eb); | 1275 | free_extent_buffer(eb); |
1277 | 1276 | ||
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 583d98bd065e..fe443fece851 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -4048,7 +4048,7 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
4048 | } | 4048 | } |
4049 | 4049 | ||
4050 | while (!end) { | 4050 | while (!end) { |
4051 | u64 offset_in_extent; | 4051 | u64 offset_in_extent = 0; |
4052 | 4052 | ||
4053 | /* break if the extent we found is outside the range */ | 4053 | /* break if the extent we found is outside the range */ |
4054 | if (em->start >= max || extent_map_end(em) < off) | 4054 | if (em->start >= max || extent_map_end(em) < off) |
@@ -4064,9 +4064,12 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
4064 | 4064 | ||
4065 | /* | 4065 | /* |
4066 | * record the offset from the start of the extent | 4066 | * record the offset from the start of the extent |
4067 | * for adjusting the disk offset below | 4067 | * for adjusting the disk offset below. Only do this if the |
4068 | * extent isn't compressed since our in ram offset may be past | ||
4069 | * what we have actually allocated on disk. | ||
4068 | */ | 4070 | */ |
4069 | offset_in_extent = em_start - em->start; | 4071 | if (!test_bit(EXTENT_FLAG_COMPRESSED, &em->flags)) |
4072 | offset_in_extent = em_start - em->start; | ||
4070 | em_end = extent_map_end(em); | 4073 | em_end = extent_map_end(em); |
4071 | em_len = em_end - em_start; | 4074 | em_len = em_end - em_start; |
4072 | emflags = em->flags; | 4075 | emflags = em->flags; |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index a005fe2c072a..8e686a427ce2 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -596,20 +596,29 @@ void btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, | |||
596 | if (no_splits) | 596 | if (no_splits) |
597 | goto next; | 597 | goto next; |
598 | 598 | ||
599 | if (em->block_start < EXTENT_MAP_LAST_BYTE && | 599 | if (em->start < start) { |
600 | em->start < start) { | ||
601 | split->start = em->start; | 600 | split->start = em->start; |
602 | split->len = start - em->start; | 601 | split->len = start - em->start; |
603 | split->orig_start = em->orig_start; | ||
604 | split->block_start = em->block_start; | ||
605 | 602 | ||
606 | if (compressed) | 603 | if (em->block_start < EXTENT_MAP_LAST_BYTE) { |
607 | split->block_len = em->block_len; | 604 | split->orig_start = em->orig_start; |
608 | else | 605 | split->block_start = em->block_start; |
609 | split->block_len = split->len; | 606 | |
610 | split->ram_bytes = em->ram_bytes; | 607 | if (compressed) |
611 | split->orig_block_len = max(split->block_len, | 608 | split->block_len = em->block_len; |
612 | em->orig_block_len); | 609 | else |
610 | split->block_len = split->len; | ||
611 | split->orig_block_len = max(split->block_len, | ||
612 | em->orig_block_len); | ||
613 | split->ram_bytes = em->ram_bytes; | ||
614 | } else { | ||
615 | split->orig_start = split->start; | ||
616 | split->block_len = 0; | ||
617 | split->block_start = em->block_start; | ||
618 | split->orig_block_len = 0; | ||
619 | split->ram_bytes = split->len; | ||
620 | } | ||
621 | |||
613 | split->generation = gen; | 622 | split->generation = gen; |
614 | split->bdev = em->bdev; | 623 | split->bdev = em->bdev; |
615 | split->flags = flags; | 624 | split->flags = flags; |
@@ -620,8 +629,7 @@ void btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, | |||
620 | split = split2; | 629 | split = split2; |
621 | split2 = NULL; | 630 | split2 = NULL; |
622 | } | 631 | } |
623 | if (em->block_start < EXTENT_MAP_LAST_BYTE && | 632 | if (testend && em->start + em->len > start + len) { |
624 | testend && em->start + em->len > start + len) { | ||
625 | u64 diff = start + len - em->start; | 633 | u64 diff = start + len - em->start; |
626 | 634 | ||
627 | split->start = start + len; | 635 | split->start = start + len; |
@@ -630,18 +638,28 @@ void btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, | |||
630 | split->flags = flags; | 638 | split->flags = flags; |
631 | split->compress_type = em->compress_type; | 639 | split->compress_type = em->compress_type; |
632 | split->generation = gen; | 640 | split->generation = gen; |
633 | split->orig_block_len = max(em->block_len, | 641 | |
642 | if (em->block_start < EXTENT_MAP_LAST_BYTE) { | ||
643 | split->orig_block_len = max(em->block_len, | ||
634 | em->orig_block_len); | 644 | em->orig_block_len); |
635 | split->ram_bytes = em->ram_bytes; | ||
636 | 645 | ||
637 | if (compressed) { | 646 | split->ram_bytes = em->ram_bytes; |
638 | split->block_len = em->block_len; | 647 | if (compressed) { |
639 | split->block_start = em->block_start; | 648 | split->block_len = em->block_len; |
640 | split->orig_start = em->orig_start; | 649 | split->block_start = em->block_start; |
650 | split->orig_start = em->orig_start; | ||
651 | } else { | ||
652 | split->block_len = split->len; | ||
653 | split->block_start = em->block_start | ||
654 | + diff; | ||
655 | split->orig_start = em->orig_start; | ||
656 | } | ||
641 | } else { | 657 | } else { |
642 | split->block_len = split->len; | 658 | split->ram_bytes = split->len; |
643 | split->block_start = em->block_start + diff; | 659 | split->orig_start = split->start; |
644 | split->orig_start = em->orig_start; | 660 | split->block_len = 0; |
661 | split->block_start = em->block_start; | ||
662 | split->orig_block_len = 0; | ||
645 | } | 663 | } |
646 | 664 | ||
647 | ret = add_extent_mapping(em_tree, split, modified); | 665 | ret = add_extent_mapping(em_tree, split, modified); |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 6d1b93c8aafb..021694c08181 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -2166,16 +2166,23 @@ static noinline int record_one_backref(u64 inum, u64 offset, u64 root_id, | |||
2166 | if (btrfs_file_extent_disk_bytenr(leaf, extent) != old->bytenr) | 2166 | if (btrfs_file_extent_disk_bytenr(leaf, extent) != old->bytenr) |
2167 | continue; | 2167 | continue; |
2168 | 2168 | ||
2169 | extent_offset = btrfs_file_extent_offset(leaf, extent); | 2169 | /* |
2170 | if (key.offset - extent_offset != offset) | 2170 | * 'offset' refers to the exact key.offset, |
2171 | * NOT the 'offset' field in btrfs_extent_data_ref, ie. | ||
2172 | * (key.offset - extent_offset). | ||
2173 | */ | ||
2174 | if (key.offset != offset) | ||
2171 | continue; | 2175 | continue; |
2172 | 2176 | ||
2177 | extent_offset = btrfs_file_extent_offset(leaf, extent); | ||
2173 | num_bytes = btrfs_file_extent_num_bytes(leaf, extent); | 2178 | num_bytes = btrfs_file_extent_num_bytes(leaf, extent); |
2179 | |||
2174 | if (extent_offset >= old->extent_offset + old->offset + | 2180 | if (extent_offset >= old->extent_offset + old->offset + |
2175 | old->len || extent_offset + num_bytes <= | 2181 | old->len || extent_offset + num_bytes <= |
2176 | old->extent_offset + old->offset) | 2182 | old->extent_offset + old->offset) |
2177 | continue; | 2183 | continue; |
2178 | 2184 | ||
2185 | ret = 0; | ||
2179 | break; | 2186 | break; |
2180 | } | 2187 | } |
2181 | 2188 | ||
@@ -2187,7 +2194,7 @@ static noinline int record_one_backref(u64 inum, u64 offset, u64 root_id, | |||
2187 | 2194 | ||
2188 | backref->root_id = root_id; | 2195 | backref->root_id = root_id; |
2189 | backref->inum = inum; | 2196 | backref->inum = inum; |
2190 | backref->file_pos = offset + extent_offset; | 2197 | backref->file_pos = offset; |
2191 | backref->num_bytes = num_bytes; | 2198 | backref->num_bytes = num_bytes; |
2192 | backref->extent_offset = extent_offset; | 2199 | backref->extent_offset = extent_offset; |
2193 | backref->generation = btrfs_file_extent_generation(leaf, extent); | 2200 | backref->generation = btrfs_file_extent_generation(leaf, extent); |
@@ -2210,7 +2217,8 @@ static noinline bool record_extent_backrefs(struct btrfs_path *path, | |||
2210 | new->path = path; | 2217 | new->path = path; |
2211 | 2218 | ||
2212 | list_for_each_entry_safe(old, tmp, &new->head, list) { | 2219 | list_for_each_entry_safe(old, tmp, &new->head, list) { |
2213 | ret = iterate_inodes_from_logical(old->bytenr, fs_info, | 2220 | ret = iterate_inodes_from_logical(old->bytenr + |
2221 | old->extent_offset, fs_info, | ||
2214 | path, record_one_backref, | 2222 | path, record_one_backref, |
2215 | old); | 2223 | old); |
2216 | BUG_ON(ret < 0 && ret != -ENOENT); | 2224 | BUG_ON(ret < 0 && ret != -ENOENT); |
@@ -4391,9 +4399,6 @@ static int btrfs_setsize(struct inode *inode, struct iattr *attr) | |||
4391 | int mask = attr->ia_valid; | 4399 | int mask = attr->ia_valid; |
4392 | int ret; | 4400 | int ret; |
4393 | 4401 | ||
4394 | if (newsize == oldsize) | ||
4395 | return 0; | ||
4396 | |||
4397 | /* | 4402 | /* |
4398 | * The regular truncate() case without ATTR_CTIME and ATTR_MTIME is a | 4403 | * The regular truncate() case without ATTR_CTIME and ATTR_MTIME is a |
4399 | * special case where we need to update the times despite not having | 4404 | * special case where we need to update the times despite not having |
@@ -5165,14 +5170,31 @@ next: | |||
5165 | } | 5170 | } |
5166 | 5171 | ||
5167 | /* Reached end of directory/root. Bump pos past the last item. */ | 5172 | /* Reached end of directory/root. Bump pos past the last item. */ |
5168 | if (key_type == BTRFS_DIR_INDEX_KEY) | 5173 | ctx->pos++; |
5169 | /* | 5174 | |
5170 | * 32-bit glibc will use getdents64, but then strtol - | 5175 | /* |
5171 | * so the last number we can serve is this. | 5176 | * Stop new entries from being returned after we return the last |
5172 | */ | 5177 | * entry. |
5173 | ctx->pos = 0x7fffffff; | 5178 | * |
5174 | else | 5179 | * New directory entries are assigned a strictly increasing |
5175 | ctx->pos++; | 5180 | * offset. This means that new entries created during readdir |
5181 | * are *guaranteed* to be seen in the future by that readdir. | ||
5182 | * This has broken buggy programs which operate on names as | ||
5183 | * they're returned by readdir. Until we re-use freed offsets | ||
5184 | * we have this hack to stop new entries from being returned | ||
5185 | * under the assumption that they'll never reach this huge | ||
5186 | * offset. | ||
5187 | * | ||
5188 | * This is being careful not to overflow 32bit loff_t unless the | ||
5189 | * last entry requires it because doing so has broken 32bit apps | ||
5190 | * in the past. | ||
5191 | */ | ||
5192 | if (key_type == BTRFS_DIR_INDEX_KEY) { | ||
5193 | if (ctx->pos >= INT_MAX) | ||
5194 | ctx->pos = LLONG_MAX; | ||
5195 | else | ||
5196 | ctx->pos = INT_MAX; | ||
5197 | } | ||
5176 | nopos: | 5198 | nopos: |
5177 | ret = 0; | 5199 | ret = 0; |
5178 | err: | 5200 | err: |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index d58cce77fc6c..af1931a5960d 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -983,12 +983,12 @@ static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans, | |||
983 | * a dirty root struct and adds it into the list of dead roots that need to | 983 | * a dirty root struct and adds it into the list of dead roots that need to |
984 | * be deleted | 984 | * be deleted |
985 | */ | 985 | */ |
986 | int btrfs_add_dead_root(struct btrfs_root *root) | 986 | void btrfs_add_dead_root(struct btrfs_root *root) |
987 | { | 987 | { |
988 | spin_lock(&root->fs_info->trans_lock); | 988 | spin_lock(&root->fs_info->trans_lock); |
989 | list_add_tail(&root->root_list, &root->fs_info->dead_roots); | 989 | if (list_empty(&root->root_list)) |
990 | list_add_tail(&root->root_list, &root->fs_info->dead_roots); | ||
990 | spin_unlock(&root->fs_info->trans_lock); | 991 | spin_unlock(&root->fs_info->trans_lock); |
991 | return 0; | ||
992 | } | 992 | } |
993 | 993 | ||
994 | /* | 994 | /* |
@@ -1925,7 +1925,7 @@ int btrfs_clean_one_deleted_snapshot(struct btrfs_root *root) | |||
1925 | } | 1925 | } |
1926 | root = list_first_entry(&fs_info->dead_roots, | 1926 | root = list_first_entry(&fs_info->dead_roots, |
1927 | struct btrfs_root, root_list); | 1927 | struct btrfs_root, root_list); |
1928 | list_del(&root->root_list); | 1928 | list_del_init(&root->root_list); |
1929 | spin_unlock(&fs_info->trans_lock); | 1929 | spin_unlock(&fs_info->trans_lock); |
1930 | 1930 | ||
1931 | pr_debug("btrfs: cleaner removing %llu\n", | 1931 | pr_debug("btrfs: cleaner removing %llu\n", |
diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h index 005b0375d18c..defbc4269897 100644 --- a/fs/btrfs/transaction.h +++ b/fs/btrfs/transaction.h | |||
@@ -143,7 +143,7 @@ int btrfs_wait_for_commit(struct btrfs_root *root, u64 transid); | |||
143 | int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, | 143 | int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, |
144 | struct btrfs_root *root); | 144 | struct btrfs_root *root); |
145 | 145 | ||
146 | int btrfs_add_dead_root(struct btrfs_root *root); | 146 | void btrfs_add_dead_root(struct btrfs_root *root); |
147 | int btrfs_defrag_root(struct btrfs_root *root); | 147 | int btrfs_defrag_root(struct btrfs_root *root); |
148 | int btrfs_clean_one_deleted_snapshot(struct btrfs_root *root); | 148 | int btrfs_clean_one_deleted_snapshot(struct btrfs_root *root); |
149 | int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | 149 | int btrfs_commit_transaction(struct btrfs_trans_handle *trans, |
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 2c6791493637..ff60d8978ae2 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
@@ -3746,8 +3746,9 @@ next_slot: | |||
3746 | } | 3746 | } |
3747 | 3747 | ||
3748 | log_extents: | 3748 | log_extents: |
3749 | btrfs_release_path(path); | ||
3750 | btrfs_release_path(dst_path); | ||
3749 | if (fast_search) { | 3751 | if (fast_search) { |
3750 | btrfs_release_path(dst_path); | ||
3751 | ret = btrfs_log_changed_extents(trans, root, inode, dst_path); | 3752 | ret = btrfs_log_changed_extents(trans, root, inode, dst_path); |
3752 | if (ret) { | 3753 | if (ret) { |
3753 | err = ret; | 3754 | err = ret; |
@@ -3764,8 +3765,6 @@ log_extents: | |||
3764 | } | 3765 | } |
3765 | 3766 | ||
3766 | if (inode_only == LOG_INODE_ALL && S_ISDIR(inode->i_mode)) { | 3767 | if (inode_only == LOG_INODE_ALL && S_ISDIR(inode->i_mode)) { |
3767 | btrfs_release_path(path); | ||
3768 | btrfs_release_path(dst_path); | ||
3769 | ret = log_directory_changes(trans, root, inode, path, dst_path); | 3768 | ret = log_directory_changes(trans, root, inode, path, dst_path); |
3770 | if (ret) { | 3769 | if (ret) { |
3771 | err = ret; | 3770 | err = ret; |