Skip to content

Commit af8c081

Browse files
committed
Merge tag 'for-4.16-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs fixes from David Sterba: - when NR_CPUS is large, a SRCU structure can significantly inflate size of the main filesystem structure that would not be possible to allocate by kmalloc, so the kvalloc fallback is used - improved error handling - fix endiannes when printing some filesystem attributes via sysfs, this is could happen when a filesystem is moved between different endianity hosts - send fixes: the NO_HOLE mode should not send a write operation for a file hole - fix log replay for for special files followed by file hardlinks - fix log replay failure after unlink and link combination - fix max chunk size calculation for DUP allocation * tag 'for-4.16-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: Btrfs: fix log replay failure after unlink and link combination Btrfs: fix log replay failure after linking special file and fsync Btrfs: send, fix issuing write op when processing hole in no data mode btrfs: use proper endianness accessors for super_copy btrfs: alloc_chunk: fix DUP stripe size handling btrfs: Handle btrfs_set_extent_delalloc failure in relocate_file_extent_cluster btrfs: handle failure of add_pending_csums btrfs: use kvzalloc to allocate btrfs_fs_info
2 parents 58bdf60 + 1f250e9 commit af8c081

File tree

10 files changed

+191
-47
lines changed

10 files changed

+191
-47
lines changed

fs/btrfs/ctree.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2974,7 +2974,7 @@ static inline void free_fs_info(struct btrfs_fs_info *fs_info)
29742974
kfree(fs_info->super_copy);
29752975
kfree(fs_info->super_for_commit);
29762976
security_free_mnt_opts(&fs_info->security_opts);
2977-
kfree(fs_info);
2977+
kvfree(fs_info);
29782978
}
29792979

29802980
/* tree mod log functions from ctree.c */
@@ -3095,7 +3095,10 @@ btrfs_lookup_inode_extref(struct btrfs_trans_handle *trans,
30953095
u64 inode_objectid, u64 ref_objectid, int ins_len,
30963096
int cow);
30973097

3098-
int btrfs_find_name_in_ext_backref(struct btrfs_path *path,
3098+
int 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);
3101+
int btrfs_find_name_in_ext_backref(struct extent_buffer *leaf, int slot,
30993102
u64 ref_objectid, const char *name,
31003103
int name_len,
31013104
struct btrfs_inode_extref **extref_ret);

fs/btrfs/inode-item.c

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,19 @@
2222
#include "transaction.h"
2323
#include "print-tree.h"
2424

25-
static int find_name_in_backref(struct btrfs_path *path, const char *name,
26-
int name_len, struct btrfs_inode_ref **ref_ret)
25+
int btrfs_find_name_in_backref(struct extent_buffer *leaf, int slot,
26+
const char *name,
27+
int name_len, struct btrfs_inode_ref **ref_ret)
2728
{
28-
struct extent_buffer *leaf;
2929
struct btrfs_inode_ref *ref;
3030
unsigned long ptr;
3131
unsigned long name_ptr;
3232
u32 item_size;
3333
u32 cur_offset = 0;
3434
int len;
3535

36-
leaf = path->nodes[0];
37-
item_size = btrfs_item_size_nr(leaf, path->slots[0]);
38-
ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);
36+
item_size = btrfs_item_size_nr(leaf, slot);
37+
ptr = btrfs_item_ptr_offset(leaf, slot);
3938
while (cur_offset < item_size) {
4039
ref = (struct btrfs_inode_ref *)(ptr + cur_offset);
4140
len = btrfs_inode_ref_name_len(leaf, ref);
@@ -44,28 +43,28 @@ static int find_name_in_backref(struct btrfs_path *path, const char *name,
4443
if (len != name_len)
4544
continue;
4645
if (memcmp_extent_buffer(leaf, name, name_ptr, name_len) == 0) {
47-
*ref_ret = ref;
46+
if (ref_ret)
47+
*ref_ret = ref;
4848
return 1;
4949
}
5050
}
5151
return 0;
5252
}
5353

54-
int btrfs_find_name_in_ext_backref(struct btrfs_path *path, u64 ref_objectid,
54+
int btrfs_find_name_in_ext_backref(struct extent_buffer *leaf, int slot,
55+
u64 ref_objectid,
5556
const char *name, int name_len,
5657
struct btrfs_inode_extref **extref_ret)
5758
{
58-
struct extent_buffer *leaf;
5959
struct btrfs_inode_extref *extref;
6060
unsigned long ptr;
6161
unsigned long name_ptr;
6262
u32 item_size;
6363
u32 cur_offset = 0;
6464
int ref_name_len;
6565

66-
leaf = path->nodes[0];
67-
item_size = btrfs_item_size_nr(leaf, path->slots[0]);
68-
ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);
66+
item_size = btrfs_item_size_nr(leaf, slot);
67+
ptr = btrfs_item_ptr_offset(leaf, slot);
6968

7069
/*
7170
* Search all extended backrefs in this item. We're only
@@ -113,7 +112,9 @@ btrfs_lookup_inode_extref(struct btrfs_trans_handle *trans,
113112
return ERR_PTR(ret);
114113
if (ret > 0)
115114
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))
117118
return NULL;
118119
return extref;
119120
}
@@ -155,7 +156,8 @@ static int btrfs_del_inode_extref(struct btrfs_trans_handle *trans,
155156
* This should always succeed so error here will make the FS
156157
* readonly.
157158
*/
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,
159161
name, name_len, &extref)) {
160162
btrfs_handle_fs_error(root->fs_info, -ENOENT, NULL);
161163
ret = -EROFS;
@@ -225,7 +227,8 @@ int btrfs_del_inode_ref(struct btrfs_trans_handle *trans,
225227
} else if (ret < 0) {
226228
goto out;
227229
}
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)) {
229232
ret = -ENOENT;
230233
search_ext_refs = 1;
231234
goto out;
@@ -293,7 +296,9 @@ static int btrfs_insert_inode_extref(struct btrfs_trans_handle *trans,
293296
ret = btrfs_insert_empty_item(trans, root, path, &key,
294297
ins_len);
295298
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,
297302
name, name_len, NULL))
298303
goto out;
299304

@@ -351,7 +356,8 @@ int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans,
351356
if (ret == -EEXIST) {
352357
u32 old_size;
353358

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))
355361
goto out;
356362

357363
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,
365371
ret = 0;
366372
} else if (ret < 0) {
367373
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))
369377
ret = -EEXIST;
370378
else
371379
ret = -EMLINK;

fs/btrfs/inode.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2043,12 +2043,15 @@ static noinline int add_pending_csums(struct btrfs_trans_handle *trans,
20432043
struct inode *inode, struct list_head *list)
20442044
{
20452045
struct btrfs_ordered_sum *sum;
2046+
int ret;
20462047

20472048
list_for_each_entry(sum, list, list) {
20482049
trans->adding_csums = true;
2049-
btrfs_csum_file_blocks(trans,
2050+
ret = btrfs_csum_file_blocks(trans,
20502051
BTRFS_I(inode)->root->fs_info->csum_root, sum);
20512052
trans->adding_csums = false;
2053+
if (ret)
2054+
return ret;
20522055
}
20532056
return 0;
20542057
}
@@ -3062,7 +3065,11 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent)
30623065
goto out;
30633066
}
30643067

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+
}
30663073

30673074
btrfs_ordered_update_i_size(inode, 0, ordered_extent);
30683075
ret = btrfs_update_inode_fallback(trans, root, inode);

fs/btrfs/relocation.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3268,8 +3268,22 @@ static int relocate_file_extent_cluster(struct inode *inode,
32683268
nr++;
32693269
}
32703270

3271-
btrfs_set_extent_delalloc(inode, page_start, page_end, 0, NULL,
3272-
0);
3271+
ret = btrfs_set_extent_delalloc(inode, page_start, page_end, 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+
}
32733287
set_page_dirty(page);
32743288

32753289
unlock_extent(&BTRFS_I(inode)->io_tree,

fs/btrfs/send.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5005,6 +5005,9 @@ static int send_hole(struct send_ctx *sctx, u64 end)
50055005
u64 len;
50065006
int ret = 0;
50075007

5008+
if (sctx->flags & BTRFS_SEND_FLAG_NO_FILE_DATA)
5009+
return send_update_extent(sctx, offset, end - offset);
5010+
50085011
p = fs_path_alloc();
50095012
if (!p)
50105013
return -ENOMEM;

fs/btrfs/super.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1545,7 +1545,7 @@ static struct dentry *btrfs_mount_root(struct file_system_type *fs_type,
15451545
* it for searching for existing supers, so this lets us do that and
15461546
* then open_ctree will properly initialize everything later.
15471547
*/
1548-
fs_info = kzalloc(sizeof(struct btrfs_fs_info), GFP_KERNEL);
1548+
fs_info = kvzalloc(sizeof(struct btrfs_fs_info), GFP_KERNEL);
15491549
if (!fs_info) {
15501550
error = -ENOMEM;
15511551
goto error_sec_opts;

fs/btrfs/sysfs.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ static ssize_t btrfs_nodesize_show(struct kobject *kobj,
423423
{
424424
struct btrfs_fs_info *fs_info = to_fs_info(kobj);
425425

426-
return snprintf(buf, PAGE_SIZE, "%u\n", fs_info->super_copy->nodesize);
426+
return snprintf(buf, PAGE_SIZE, "%u\n", fs_info->nodesize);
427427
}
428428

429429
BTRFS_ATTR(, nodesize, btrfs_nodesize_show);
@@ -433,8 +433,7 @@ static ssize_t btrfs_sectorsize_show(struct kobject *kobj,
433433
{
434434
struct btrfs_fs_info *fs_info = to_fs_info(kobj);
435435

436-
return snprintf(buf, PAGE_SIZE, "%u\n",
437-
fs_info->super_copy->sectorsize);
436+
return snprintf(buf, PAGE_SIZE, "%u\n", fs_info->sectorsize);
438437
}
439438

440439
BTRFS_ATTR(, sectorsize, btrfs_sectorsize_show);
@@ -444,8 +443,7 @@ static ssize_t btrfs_clone_alignment_show(struct kobject *kobj,
444443
{
445444
struct btrfs_fs_info *fs_info = to_fs_info(kobj);
446445

447-
return snprintf(buf, PAGE_SIZE, "%u\n",
448-
fs_info->super_copy->sectorsize);
446+
return snprintf(buf, PAGE_SIZE, "%u\n", fs_info->sectorsize);
449447
}
450448

451449
BTRFS_ATTR(, clone_alignment, btrfs_clone_alignment_show);

fs/btrfs/transaction.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1722,19 +1722,23 @@ static void update_super_roots(struct btrfs_fs_info *fs_info)
17221722

17231723
super = fs_info->super_copy;
17241724

1725+
/* update latest btrfs_super_block::chunk_root refs */
17251726
root_item = &fs_info->chunk_root->root_item;
1726-
super->chunk_root = root_item->bytenr;
1727-
super->chunk_root_generation = root_item->generation;
1728-
super->chunk_root_level = root_item->level;
1727+
btrfs_set_super_chunk_root(super, root_item->bytenr);
1728+
btrfs_set_super_chunk_root_generation(super, root_item->generation);
1729+
btrfs_set_super_chunk_root_level(super, root_item->level);
17291730

1731+
/* update latest btrfs_super_block::root refs */
17301732
root_item = &fs_info->tree_root->root_item;
1731-
super->root = root_item->bytenr;
1732-
super->generation = root_item->generation;
1733-
super->root_level = root_item->level;
1733+
btrfs_set_super_root(super, root_item->bytenr);
1734+
btrfs_set_super_generation(super, root_item->generation);
1735+
btrfs_set_super_root_level(super, root_item->level);
1736+
17341737
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);
17361739
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);
17381742
}
17391743

17401744
int btrfs_transaction_in_commit(struct btrfs_fs_info *info)

0 commit comments

Comments
 (0)