summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/ctree.h7
-rw-r--r--fs/btrfs/inode-item.c44
-rw-r--r--fs/btrfs/inode.c11
-rw-r--r--fs/btrfs/relocation.c18
-rw-r--r--fs/btrfs/send.c3
-rw-r--r--fs/btrfs/super.c2
-rw-r--r--fs/btrfs/sysfs.c8
-rw-r--r--fs/btrfs/transaction.c20
-rw-r--r--fs/btrfs/tree-log.c114
-rw-r--r--fs/btrfs/volumes.c11
10 files changed, 191 insertions, 47 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 1a462ab85c49..da308774b8a4 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -2974,7 +2974,7 @@ static inline void free_fs_info(struct btrfs_fs_info *fs_info)
2974 kfree(fs_info->super_copy); 2974 kfree(fs_info->super_copy);
2975 kfree(fs_info->super_for_commit); 2975 kfree(fs_info->super_for_commit);
2976 security_free_mnt_opts(&fs_info->security_opts); 2976 security_free_mnt_opts(&fs_info->security_opts);
2977 kfree(fs_info); 2977 kvfree(fs_info);
2978} 2978}
2979 2979
2980/* tree mod log functions from ctree.c */ 2980/* tree mod log functions from ctree.c */
@@ -3095,7 +3095,10 @@ btrfs_lookup_inode_extref(struct btrfs_trans_handle *trans,
3095 u64 inode_objectid, u64 ref_objectid, int ins_len, 3095 u64 inode_objectid, u64 ref_objectid, int ins_len,
3096 int cow); 3096 int cow);
3097 3097
3098int btrfs_find_name_in_ext_backref(struct btrfs_path *path, 3098int btrfs_find_name_in_backref(struct extent_buffer *leaf, int slot,
3099 const char *name,
3100 int name_len, struct btrfs_inode_ref **ref_ret);
3101int btrfs_find_name_in_ext_backref(struct extent_buffer *leaf, int slot,
3099 u64 ref_objectid, const char *name, 3102 u64 ref_objectid, const char *name,
3100 int name_len, 3103 int name_len,
3101 struct btrfs_inode_extref **extref_ret); 3104 struct btrfs_inode_extref **extref_ret);
diff --git a/fs/btrfs/inode-item.c b/fs/btrfs/inode-item.c
index 39c968f80157..65e1a76bf755 100644
--- a/fs/btrfs/inode-item.c
+++ b/fs/btrfs/inode-item.c
@@ -22,10 +22,10 @@
22#include "transaction.h" 22#include "transaction.h"
23#include "print-tree.h" 23#include "print-tree.h"
24 24
25static int find_name_in_backref(struct btrfs_path *path, const char *name, 25int btrfs_find_name_in_backref(struct extent_buffer *leaf, int slot,
26 int name_len, struct btrfs_inode_ref **ref_ret) 26 const char *name,
27 int name_len, struct btrfs_inode_ref **ref_ret)
27{ 28{
28 struct extent_buffer *leaf;
29 struct btrfs_inode_ref *ref; 29 struct btrfs_inode_ref *ref;
30 unsigned long ptr; 30 unsigned long ptr;
31 unsigned long name_ptr; 31 unsigned long name_ptr;
@@ -33,9 +33,8 @@ static int find_name_in_backref(struct btrfs_path *path, const char *name,
33 u32 cur_offset = 0; 33 u32 cur_offset = 0;
34 int len; 34 int len;
35 35
36 leaf = path->nodes[0]; 36 item_size = btrfs_item_size_nr(leaf, slot);
37 item_size = btrfs_item_size_nr(leaf, path->slots[0]); 37 ptr = btrfs_item_ptr_offset(leaf, slot);
38 ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);
39 while (cur_offset < item_size) { 38 while (cur_offset < item_size) {
40 ref = (struct btrfs_inode_ref *)(ptr + cur_offset); 39 ref = (struct btrfs_inode_ref *)(ptr + cur_offset);
41 len = btrfs_inode_ref_name_len(leaf, ref); 40 len = btrfs_inode_ref_name_len(leaf, ref);
@@ -44,18 +43,19 @@ static int find_name_in_backref(struct btrfs_path *path, const char *name,
44 if (len != name_len) 43 if (len != name_len)
45 continue; 44 continue;
46 if (memcmp_extent_buffer(leaf, name, name_ptr, name_len) == 0) { 45 if (memcmp_extent_buffer(leaf, name, name_ptr, name_len) == 0) {
47 *ref_ret = ref; 46 if (ref_ret)
47 *ref_ret = ref;
48 return 1; 48 return 1;
49 } 49 }
50 } 50 }
51 return 0; 51 return 0;
52} 52}
53 53
54int btrfs_find_name_in_ext_backref(struct btrfs_path *path, u64 ref_objectid, 54int btrfs_find_name_in_ext_backref(struct extent_buffer *leaf, int slot,
55 u64 ref_objectid,
55 const char *name, int name_len, 56 const char *name, int name_len,
56 struct btrfs_inode_extref **extref_ret) 57 struct btrfs_inode_extref **extref_ret)
57{ 58{
58 struct extent_buffer *leaf;
59 struct btrfs_inode_extref *extref; 59 struct btrfs_inode_extref *extref;
60 unsigned long ptr; 60 unsigned long ptr;
61 unsigned long name_ptr; 61 unsigned long name_ptr;
@@ -63,9 +63,8 @@ int btrfs_find_name_in_ext_backref(struct btrfs_path *path, u64 ref_objectid,
63 u32 cur_offset = 0; 63 u32 cur_offset = 0;
64 int ref_name_len; 64 int ref_name_len;
65 65
66 leaf = path->nodes[0]; 66 item_size = btrfs_item_size_nr(leaf, slot);
67 item_size = btrfs_item_size_nr(leaf, path->slots[0]); 67 ptr = btrfs_item_ptr_offset(leaf, slot);
68 ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);
69 68
70 /* 69 /*
71 * Search all extended backrefs in this item. We're only 70 * Search all extended backrefs in this item. We're only
@@ -113,7 +112,9 @@ btrfs_lookup_inode_extref(struct btrfs_trans_handle *trans,
113 return ERR_PTR(ret); 112 return ERR_PTR(ret);
114 if (ret > 0) 113 if (ret > 0)
115 return NULL; 114 return NULL;
116 if (!btrfs_find_name_in_ext_backref(path, ref_objectid, name, name_len, &extref)) 115 if (!btrfs_find_name_in_ext_backref(path->nodes[0], path->slots[0],
116 ref_objectid, name, name_len,
117 &extref))
117 return NULL; 118 return NULL;
118 return extref; 119 return extref;
119} 120}
@@ -155,7 +156,8 @@ static int btrfs_del_inode_extref(struct btrfs_trans_handle *trans,
155 * This should always succeed so error here will make the FS 156 * This should always succeed so error here will make the FS
156 * readonly. 157 * readonly.
157 */ 158 */
158 if (!btrfs_find_name_in_ext_backref(path, ref_objectid, 159 if (!btrfs_find_name_in_ext_backref(path->nodes[0], path->slots[0],
160 ref_objectid,
159 name, name_len, &extref)) { 161 name, name_len, &extref)) {
160 btrfs_handle_fs_error(root->fs_info, -ENOENT, NULL); 162 btrfs_handle_fs_error(root->fs_info, -ENOENT, NULL);
161 ret = -EROFS; 163 ret = -EROFS;
@@ -225,7 +227,8 @@ int btrfs_del_inode_ref(struct btrfs_trans_handle *trans,
225 } else if (ret < 0) { 227 } else if (ret < 0) {
226 goto out; 228 goto out;
227 } 229 }
228 if (!find_name_in_backref(path, name, name_len, &ref)) { 230 if (!btrfs_find_name_in_backref(path->nodes[0], path->slots[0],
231 name, name_len, &ref)) {
229 ret = -ENOENT; 232 ret = -ENOENT;
230 search_ext_refs = 1; 233 search_ext_refs = 1;
231 goto out; 234 goto out;
@@ -293,7 +296,9 @@ static int btrfs_insert_inode_extref(struct btrfs_trans_handle *trans,
293 ret = btrfs_insert_empty_item(trans, root, path, &key, 296 ret = btrfs_insert_empty_item(trans, root, path, &key,
294 ins_len); 297 ins_len);
295 if (ret == -EEXIST) { 298 if (ret == -EEXIST) {
296 if (btrfs_find_name_in_ext_backref(path, ref_objectid, 299 if (btrfs_find_name_in_ext_backref(path->nodes[0],
300 path->slots[0],
301 ref_objectid,
297 name, name_len, NULL)) 302 name, name_len, NULL))
298 goto out; 303 goto out;
299 304
@@ -351,7 +356,8 @@ int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans,
351 if (ret == -EEXIST) { 356 if (ret == -EEXIST) {
352 u32 old_size; 357 u32 old_size;
353 358
354 if (find_name_in_backref(path, name, name_len, &ref)) 359 if (btrfs_find_name_in_backref(path->nodes[0], path->slots[0],
360 name, name_len, &ref))
355 goto out; 361 goto out;
356 362
357 old_size = btrfs_item_size_nr(path->nodes[0], path->slots[0]); 363 old_size = btrfs_item_size_nr(path->nodes[0], path->slots[0]);
@@ -365,7 +371,9 @@ int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans,
365 ret = 0; 371 ret = 0;
366 } else if (ret < 0) { 372 } else if (ret < 0) {
367 if (ret == -EOVERFLOW) { 373 if (ret == -EOVERFLOW) {
368 if (find_name_in_backref(path, name, name_len, &ref)) 374 if (btrfs_find_name_in_backref(path->nodes[0],
375 path->slots[0],
376 name, name_len, &ref))
369 ret = -EEXIST; 377 ret = -EEXIST;
370 else 378 else
371 ret = -EMLINK; 379 ret = -EMLINK;
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index a79299a89b7d..f53470112670 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -2043,12 +2043,15 @@ static noinline int add_pending_csums(struct btrfs_trans_handle *trans,
2043 struct inode *inode, struct list_head *list) 2043 struct inode *inode, struct list_head *list)
2044{ 2044{
2045 struct btrfs_ordered_sum *sum; 2045 struct btrfs_ordered_sum *sum;
2046 int ret;
2046 2047
2047 list_for_each_entry(sum, list, list) { 2048 list_for_each_entry(sum, list, list) {
2048 trans->adding_csums = true; 2049 trans->adding_csums = true;
2049 btrfs_csum_file_blocks(trans, 2050 ret = btrfs_csum_file_blocks(trans,
2050 BTRFS_I(inode)->root->fs_info->csum_root, sum); 2051 BTRFS_I(inode)->root->fs_info->csum_root, sum);
2051 trans->adding_csums = false; 2052 trans->adding_csums = false;
2053 if (ret)
2054 return ret;
2052 } 2055 }
2053 return 0; 2056 return 0;
2054} 2057}
@@ -3062,7 +3065,11 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent)
3062 goto out; 3065 goto out;
3063 } 3066 }
3064 3067
3065 add_pending_csums(trans, inode, &ordered_extent->list); 3068 ret = add_pending_csums(trans, inode, &ordered_extent->list);
3069 if (ret) {
3070 btrfs_abort_transaction(trans, ret);
3071 goto out;
3072 }
3066 3073
3067 btrfs_ordered_update_i_size(inode, 0, ordered_extent); 3074 btrfs_ordered_update_i_size(inode, 0, ordered_extent);
3068 ret = btrfs_update_inode_fallback(trans, root, inode); 3075 ret = btrfs_update_inode_fallback(trans, root, inode);
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index f0c3f00e97cb..cd2298d185dd 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -3268,8 +3268,22 @@ static int relocate_file_extent_cluster(struct inode *inode,
3268 nr++; 3268 nr++;
3269 } 3269 }
3270 3270
3271 btrfs_set_extent_delalloc(inode, page_start, page_end, 0, NULL, 3271 ret = btrfs_set_extent_delalloc(inode, page_start, page_end, 0,
3272 0); 3272 NULL, 0);
3273 if (ret) {
3274 unlock_page(page);
3275 put_page(page);
3276 btrfs_delalloc_release_metadata(BTRFS_I(inode),
3277 PAGE_SIZE);
3278 btrfs_delalloc_release_extents(BTRFS_I(inode),
3279 PAGE_SIZE);
3280
3281 clear_extent_bits(&BTRFS_I(inode)->io_tree,
3282 page_start, page_end,
3283 EXTENT_LOCKED | EXTENT_BOUNDARY);
3284 goto out;
3285
3286 }
3273 set_page_dirty(page); 3287 set_page_dirty(page);
3274 3288
3275 unlock_extent(&BTRFS_I(inode)->io_tree, 3289 unlock_extent(&BTRFS_I(inode)->io_tree,
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index f306c608dc28..484e2af793de 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -5005,6 +5005,9 @@ static int send_hole(struct send_ctx *sctx, u64 end)
5005 u64 len; 5005 u64 len;
5006 int ret = 0; 5006 int ret = 0;
5007 5007
5008 if (sctx->flags & BTRFS_SEND_FLAG_NO_FILE_DATA)
5009 return send_update_extent(sctx, offset, end - offset);
5010
5008 p = fs_path_alloc(); 5011 p = fs_path_alloc();
5009 if (!p) 5012 if (!p)
5010 return -ENOMEM; 5013 return -ENOMEM;
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 6e71a2a78363..4b817947e00f 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -1545,7 +1545,7 @@ static struct dentry *btrfs_mount_root(struct file_system_type *fs_type,
1545 * it for searching for existing supers, so this lets us do that and 1545 * it for searching for existing supers, so this lets us do that and
1546 * then open_ctree will properly initialize everything later. 1546 * then open_ctree will properly initialize everything later.
1547 */ 1547 */
1548 fs_info = kzalloc(sizeof(struct btrfs_fs_info), GFP_KERNEL); 1548 fs_info = kvzalloc(sizeof(struct btrfs_fs_info), GFP_KERNEL);
1549 if (!fs_info) { 1549 if (!fs_info) {
1550 error = -ENOMEM; 1550 error = -ENOMEM;
1551 goto error_sec_opts; 1551 goto error_sec_opts;
diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c
index a8bafed931f4..d11c70bff5a9 100644
--- a/fs/btrfs/sysfs.c
+++ b/fs/btrfs/sysfs.c
@@ -423,7 +423,7 @@ static ssize_t btrfs_nodesize_show(struct kobject *kobj,
423{ 423{
424 struct btrfs_fs_info *fs_info = to_fs_info(kobj); 424 struct btrfs_fs_info *fs_info = to_fs_info(kobj);
425 425
426 return snprintf(buf, PAGE_SIZE, "%u\n", fs_info->super_copy->nodesize); 426 return snprintf(buf, PAGE_SIZE, "%u\n", fs_info->nodesize);
427} 427}
428 428
429BTRFS_ATTR(, nodesize, btrfs_nodesize_show); 429BTRFS_ATTR(, nodesize, btrfs_nodesize_show);
@@ -433,8 +433,7 @@ static ssize_t btrfs_sectorsize_show(struct kobject *kobj,
433{ 433{
434 struct btrfs_fs_info *fs_info = to_fs_info(kobj); 434 struct btrfs_fs_info *fs_info = to_fs_info(kobj);
435 435
436 return snprintf(buf, PAGE_SIZE, "%u\n", 436 return snprintf(buf, PAGE_SIZE, "%u\n", fs_info->sectorsize);
437 fs_info->super_copy->sectorsize);
438} 437}
439 438
440BTRFS_ATTR(, sectorsize, btrfs_sectorsize_show); 439BTRFS_ATTR(, sectorsize, btrfs_sectorsize_show);
@@ -444,8 +443,7 @@ static ssize_t btrfs_clone_alignment_show(struct kobject *kobj,
444{ 443{
445 struct btrfs_fs_info *fs_info = to_fs_info(kobj); 444 struct btrfs_fs_info *fs_info = to_fs_info(kobj);
446 445
447 return snprintf(buf, PAGE_SIZE, "%u\n", 446 return snprintf(buf, PAGE_SIZE, "%u\n", fs_info->sectorsize);
448 fs_info->super_copy->sectorsize);
449} 447}
450 448
451BTRFS_ATTR(, clone_alignment, btrfs_clone_alignment_show); 449BTRFS_ATTR(, clone_alignment, btrfs_clone_alignment_show);
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 04f07144b45c..9220f004001c 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -1722,19 +1722,23 @@ static void update_super_roots(struct btrfs_fs_info *fs_info)
1722 1722
1723 super = fs_info->super_copy; 1723 super = fs_info->super_copy;
1724 1724
1725 /* update latest btrfs_super_block::chunk_root refs */
1725 root_item = &fs_info->chunk_root->root_item; 1726 root_item = &fs_info->chunk_root->root_item;
1726 super->chunk_root = root_item->bytenr; 1727 btrfs_set_super_chunk_root(super, root_item->bytenr);
1727 super->chunk_root_generation = root_item->generation; 1728 btrfs_set_super_chunk_root_generation(super, root_item->generation);
1728 super->chunk_root_level = root_item->level; 1729 btrfs_set_super_chunk_root_level(super, root_item->level);
1729 1730
1731 /* update latest btrfs_super_block::root refs */
1730 root_item = &fs_info->tree_root->root_item; 1732 root_item = &fs_info->tree_root->root_item;
1731 super->root = root_item->bytenr; 1733 btrfs_set_super_root(super, root_item->bytenr);
1732 super->generation = root_item->generation; 1734 btrfs_set_super_generation(super, root_item->generation);
1733 super->root_level = root_item->level; 1735 btrfs_set_super_root_level(super, root_item->level);
1736
1734 if (btrfs_test_opt(fs_info, SPACE_CACHE)) 1737 if (btrfs_test_opt(fs_info, SPACE_CACHE))
1735 super->cache_generation = root_item->generation; 1738 btrfs_set_super_cache_generation(super, root_item->generation);
1736 if (test_bit(BTRFS_FS_UPDATE_UUID_TREE_GEN, &fs_info->flags)) 1739 if (test_bit(BTRFS_FS_UPDATE_UUID_TREE_GEN, &fs_info->flags))
1737 super->uuid_tree_generation = root_item->generation; 1740 btrfs_set_super_uuid_tree_generation(super,
1741 root_item->generation);
1738} 1742}
1739 1743
1740int btrfs_transaction_in_commit(struct btrfs_fs_info *info) 1744int btrfs_transaction_in_commit(struct btrfs_fs_info *info)
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 4fd19b4d6675..434457794c27 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -967,7 +967,9 @@ static noinline int backref_in_log(struct btrfs_root *log,
967 ptr = btrfs_item_ptr_offset(path->nodes[0], path->slots[0]); 967 ptr = btrfs_item_ptr_offset(path->nodes[0], path->slots[0]);
968 968
969 if (key->type == BTRFS_INODE_EXTREF_KEY) { 969 if (key->type == BTRFS_INODE_EXTREF_KEY) {
970 if (btrfs_find_name_in_ext_backref(path, ref_objectid, 970 if (btrfs_find_name_in_ext_backref(path->nodes[0],
971 path->slots[0],
972 ref_objectid,
971 name, namelen, NULL)) 973 name, namelen, NULL))
972 match = 1; 974 match = 1;
973 975
@@ -1191,7 +1193,8 @@ static int extref_get_fields(struct extent_buffer *eb, unsigned long ref_ptr,
1191 read_extent_buffer(eb, *name, (unsigned long)&extref->name, 1193 read_extent_buffer(eb, *name, (unsigned long)&extref->name,
1192 *namelen); 1194 *namelen);
1193 1195
1194 *index = btrfs_inode_extref_index(eb, extref); 1196 if (index)
1197 *index = btrfs_inode_extref_index(eb, extref);
1195 if (parent_objectid) 1198 if (parent_objectid)
1196 *parent_objectid = btrfs_inode_extref_parent(eb, extref); 1199 *parent_objectid = btrfs_inode_extref_parent(eb, extref);
1197 1200
@@ -1212,12 +1215,102 @@ static int ref_get_fields(struct extent_buffer *eb, unsigned long ref_ptr,
1212 1215
1213 read_extent_buffer(eb, *name, (unsigned long)(ref + 1), *namelen); 1216 read_extent_buffer(eb, *name, (unsigned long)(ref + 1), *namelen);
1214 1217
1215 *index = btrfs_inode_ref_index(eb, ref); 1218 if (index)
1219 *index = btrfs_inode_ref_index(eb, ref);
1216 1220
1217 return 0; 1221 return 0;
1218} 1222}
1219 1223
1220/* 1224/*
1225 * Take an inode reference item from the log tree and iterate all names from the
1226 * inode reference item in the subvolume tree with the same key (if it exists).
1227 * For any name that is not in the inode reference item from the log tree, do a
1228 * proper unlink of that name (that is, remove its entry from the inode
1229 * reference item and both dir index keys).
1230 */
1231static int unlink_old_inode_refs(struct btrfs_trans_handle *trans,
1232 struct btrfs_root *root,
1233 struct btrfs_path *path,
1234 struct btrfs_inode *inode,
1235 struct extent_buffer *log_eb,
1236 int log_slot,
1237 struct btrfs_key *key)
1238{
1239 int ret;
1240 unsigned long ref_ptr;
1241 unsigned long ref_end;
1242 struct extent_buffer *eb;
1243
1244again:
1245 btrfs_release_path(path);
1246 ret = btrfs_search_slot(NULL, root, key, path, 0, 0);
1247 if (ret > 0) {
1248 ret = 0;
1249 goto out;
1250 }
1251 if (ret < 0)
1252 goto out;
1253
1254 eb = path->nodes[0];
1255 ref_ptr = btrfs_item_ptr_offset(eb, path->slots[0]);
1256 ref_end = ref_ptr + btrfs_item_size_nr(eb, path->slots[0]);
1257 while (ref_ptr < ref_end) {
1258 char *name = NULL;
1259 int namelen;
1260 u64 parent_id;
1261
1262 if (key->type == BTRFS_INODE_EXTREF_KEY) {
1263 ret = extref_get_fields(eb, ref_ptr, &namelen, &name,
1264 NULL, &parent_id);
1265 } else {
1266 parent_id = key->offset;
1267 ret = ref_get_fields(eb, ref_ptr, &namelen, &name,
1268 NULL);
1269 }
1270 if (ret)
1271 goto out;
1272
1273 if (key->type == BTRFS_INODE_EXTREF_KEY)
1274 ret = btrfs_find_name_in_ext_backref(log_eb, log_slot,
1275 parent_id, name,
1276 namelen, NULL);
1277 else
1278 ret = btrfs_find_name_in_backref(log_eb, log_slot, name,
1279 namelen, NULL);
1280
1281 if (!ret) {
1282 struct inode *dir;
1283
1284 btrfs_release_path(path);
1285 dir = read_one_inode(root, parent_id);
1286 if (!dir) {
1287 ret = -ENOENT;
1288 kfree(name);
1289 goto out;
1290 }
1291 ret = btrfs_unlink_inode(trans, root, BTRFS_I(dir),
1292 inode, name, namelen);
1293 kfree(name);
1294 iput(dir);
1295 if (ret)
1296 goto out;
1297 goto again;
1298 }
1299
1300 kfree(name);
1301 ref_ptr += namelen;
1302 if (key->type == BTRFS_INODE_EXTREF_KEY)
1303 ref_ptr += sizeof(struct btrfs_inode_extref);
1304 else
1305 ref_ptr += sizeof(struct btrfs_inode_ref);
1306 }
1307 ret = 0;
1308 out:
1309 btrfs_release_path(path);
1310 return ret;
1311}
1312
1313/*
1221 * replay one inode back reference item found in the log tree. 1314 * replay one inode back reference item found in the log tree.
1222 * eb, slot and key refer to the buffer and key found in the log tree. 1315 * eb, slot and key refer to the buffer and key found in the log tree.
1223 * root is the destination we are replaying into, and path is for temp 1316 * root is the destination we are replaying into, and path is for temp
@@ -1345,6 +1438,19 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
1345 } 1438 }
1346 } 1439 }
1347 1440
1441 /*
1442 * Before we overwrite the inode reference item in the subvolume tree
1443 * with the item from the log tree, we must unlink all names from the
1444 * parent directory that are in the subvolume's tree inode reference
1445 * item, otherwise we end up with an inconsistent subvolume tree where
1446 * dir index entries exist for a name but there is no inode reference
1447 * item with the same name.
1448 */
1449 ret = unlink_old_inode_refs(trans, root, path, BTRFS_I(inode), eb, slot,
1450 key);
1451 if (ret)
1452 goto out;
1453
1348 /* finally write the back reference in the inode */ 1454 /* finally write the back reference in the inode */
1349 ret = overwrite_item(trans, root, path, eb, slot, key); 1455 ret = overwrite_item(trans, root, path, eb, slot, key);
1350out: 1456out:
@@ -5853,7 +5959,7 @@ int btrfs_log_new_name(struct btrfs_trans_handle *trans,
5853 * this will force the logging code to walk the dentry chain 5959 * this will force the logging code to walk the dentry chain
5854 * up for the file 5960 * up for the file
5855 */ 5961 */
5856 if (S_ISREG(inode->vfs_inode.i_mode)) 5962 if (!S_ISDIR(inode->vfs_inode.i_mode))
5857 inode->last_unlink_trans = trans->transid; 5963 inode->last_unlink_trans = trans->transid;
5858 5964
5859 /* 5965 /*
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 2ceb924ca0d6..b2d05c6b1c56 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -4829,10 +4829,13 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
4829 ndevs = min(ndevs, devs_max); 4829 ndevs = min(ndevs, devs_max);
4830 4830
4831 /* 4831 /*
4832 * the primary goal is to maximize the number of stripes, so use as many 4832 * The primary goal is to maximize the number of stripes, so use as
4833 * devices as possible, even if the stripes are not maximum sized. 4833 * many devices as possible, even if the stripes are not maximum sized.
4834 *
4835 * The DUP profile stores more than one stripe per device, the
4836 * max_avail is the total size so we have to adjust.
4834 */ 4837 */
4835 stripe_size = devices_info[ndevs-1].max_avail; 4838 stripe_size = div_u64(devices_info[ndevs - 1].max_avail, dev_stripes);
4836 num_stripes = ndevs * dev_stripes; 4839 num_stripes = ndevs * dev_stripes;
4837 4840
4838 /* 4841 /*
@@ -4867,8 +4870,6 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
4867 stripe_size = devices_info[ndevs-1].max_avail; 4870 stripe_size = devices_info[ndevs-1].max_avail;
4868 } 4871 }
4869 4872
4870 stripe_size = div_u64(stripe_size, dev_stripes);
4871
4872 /* align to BTRFS_STRIPE_LEN */ 4873 /* align to BTRFS_STRIPE_LEN */
4873 stripe_size = round_down(stripe_size, BTRFS_STRIPE_LEN); 4874 stripe_size = round_down(stripe_size, BTRFS_STRIPE_LEN);
4874 4875