Skip to content

Commit 5aaef24

Browse files
committed
Merge tag 'for-6.1-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs fixes from David Sterba: "A few more fixes and regression fixes: - fix a corner case when handling tree-mod-log chagnes in reallocated notes - fix crash on raid0 filesystems created with <5.4 mkfs.btrfs that could lead to division by zero - add missing super block checksum verification after thawing filesystem - handle one more case in send when dealing with orphan files - fix parameter type mismatch for generation when reading dentry - improved error handling in raid56 code - better struct bio packing after recent cleanups" * tag 'for-6.1-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: don't use btrfs_chunk::sub_stripes from disk btrfs: fix type of parameter generation in btrfs_get_dentry btrfs: send: fix send failure of a subcase of orphan inodes btrfs: make thaw time super block check to also verify checksum btrfs: fix tree mod log mishandling of reallocated nodes btrfs: reorder btrfs_bio for better packing btrfs: raid56: avoid double freeing for rbio if full_stripe_write() failed btrfs: raid56: properly handle the error when unable to find the missing stripe
2 parents 78a089d + 76a66ba commit 5aaef24

File tree

10 files changed

+73
-40
lines changed

10 files changed

+73
-40
lines changed

fs/btrfs/disk-io.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -166,11 +166,9 @@ static bool btrfs_supported_super_csum(u16 csum_type)
166166
* Return 0 if the superblock checksum type matches the checksum value of that
167167
* algorithm. Pass the raw disk superblock data.
168168
*/
169-
static int btrfs_check_super_csum(struct btrfs_fs_info *fs_info,
170-
char *raw_disk_sb)
169+
int btrfs_check_super_csum(struct btrfs_fs_info *fs_info,
170+
const struct btrfs_super_block *disk_sb)
171171
{
172-
struct btrfs_super_block *disk_sb =
173-
(struct btrfs_super_block *)raw_disk_sb;
174172
char result[BTRFS_CSUM_SIZE];
175173
SHASH_DESC_ON_STACK(shash, fs_info->csum_shash);
176174

@@ -181,7 +179,7 @@ static int btrfs_check_super_csum(struct btrfs_fs_info *fs_info,
181179
* BTRFS_SUPER_INFO_SIZE range, we expect that the unused space is
182180
* filled with zeros and is included in the checksum.
183181
*/
184-
crypto_shash_digest(shash, raw_disk_sb + BTRFS_CSUM_SIZE,
182+
crypto_shash_digest(shash, (const u8 *)disk_sb + BTRFS_CSUM_SIZE,
185183
BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE, result);
186184

187185
if (memcmp(disk_sb->csum, result, fs_info->csum_size))
@@ -3479,7 +3477,7 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
34793477
* We want to check superblock checksum, the type is stored inside.
34803478
* Pass the whole disk block of size BTRFS_SUPER_INFO_SIZE (4k).
34813479
*/
3482-
if (btrfs_check_super_csum(fs_info, (u8 *)disk_super)) {
3480+
if (btrfs_check_super_csum(fs_info, disk_super)) {
34833481
btrfs_err(fs_info, "superblock checksum mismatch");
34843482
err = -EINVAL;
34853483
btrfs_release_disk_super(disk_super);

fs/btrfs/disk-io.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ struct extent_buffer *btrfs_find_create_tree_block(
4242
void btrfs_clean_tree_block(struct extent_buffer *buf);
4343
void btrfs_clear_oneshot_options(struct btrfs_fs_info *fs_info);
4444
int btrfs_start_pre_rw_mount(struct btrfs_fs_info *fs_info);
45+
int btrfs_check_super_csum(struct btrfs_fs_info *fs_info,
46+
const struct btrfs_super_block *disk_sb);
4547
int __cold open_ctree(struct super_block *sb,
4648
struct btrfs_fs_devices *fs_devices,
4749
char *options);

fs/btrfs/export.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ static int btrfs_encode_fh(struct inode *inode, u32 *fh, int *max_len,
5858
}
5959

6060
struct dentry *btrfs_get_dentry(struct super_block *sb, u64 objectid,
61-
u64 root_objectid, u32 generation,
61+
u64 root_objectid, u64 generation,
6262
int check_generation)
6363
{
6464
struct btrfs_fs_info *fs_info = btrfs_sb(sb);

fs/btrfs/export.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ struct btrfs_fid {
1919
} __attribute__ ((packed));
2020

2121
struct dentry *btrfs_get_dentry(struct super_block *sb, u64 objectid,
22-
u64 root_objectid, u32 generation,
22+
u64 root_objectid, u64 generation,
2323
int check_generation);
2424
struct dentry *btrfs_get_parent(struct dentry *child);
2525

fs/btrfs/extent-tree.c

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3295,21 +3295,22 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
32953295
}
32963296

32973297
/*
3298-
* If this is a leaf and there are tree mod log users, we may
3299-
* have recorded mod log operations that point to this leaf.
3300-
* So we must make sure no one reuses this leaf's extent before
3301-
* mod log operations are applied to a node, otherwise after
3302-
* rewinding a node using the mod log operations we get an
3303-
* inconsistent btree, as the leaf's extent may now be used as
3304-
* a node or leaf for another different btree.
3298+
* If there are tree mod log users we may have recorded mod log
3299+
* operations for this node. If we re-allocate this node we
3300+
* could replay operations on this node that happened when it
3301+
* existed in a completely different root. For example if it
3302+
* was part of root A, then was reallocated to root B, and we
3303+
* are doing a btrfs_old_search_slot(root b), we could replay
3304+
* operations that happened when the block was part of root A,
3305+
* giving us an inconsistent view of the btree.
3306+
*
33053307
* We are safe from races here because at this point no other
33063308
* node or root points to this extent buffer, so if after this
3307-
* check a new tree mod log user joins, it will not be able to
3308-
* find a node pointing to this leaf and record operations that
3309-
* point to this leaf.
3309+
* check a new tree mod log user joins we will not have an
3310+
* existing log of operations on this node that we have to
3311+
* contend with.
33103312
*/
3311-
if (btrfs_header_level(buf) == 0 &&
3312-
test_bit(BTRFS_FS_TREE_MOD_LOG_USERS, &fs_info->flags))
3313+
if (test_bit(BTRFS_FS_TREE_MOD_LOG_USERS, &fs_info->flags))
33133314
must_pin = true;
33143315

33153316
if (must_pin || btrfs_is_zoned(fs_info)) {

fs/btrfs/raid56.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1632,10 +1632,8 @@ static int full_stripe_write(struct btrfs_raid_bio *rbio)
16321632
int ret;
16331633

16341634
ret = alloc_rbio_parity_pages(rbio);
1635-
if (ret) {
1636-
__free_raid_bio(rbio);
1635+
if (ret)
16371636
return ret;
1638-
}
16391637

16401638
ret = lock_stripe_add(rbio);
16411639
if (ret == 0)
@@ -1823,8 +1821,10 @@ void raid56_parity_write(struct bio *bio, struct btrfs_io_context *bioc)
18231821
*/
18241822
if (rbio_is_full(rbio)) {
18251823
ret = full_stripe_write(rbio);
1826-
if (ret)
1824+
if (ret) {
1825+
__free_raid_bio(rbio);
18271826
goto fail;
1827+
}
18281828
return;
18291829
}
18301830

@@ -1838,8 +1838,10 @@ void raid56_parity_write(struct bio *bio, struct btrfs_io_context *bioc)
18381838
list_add_tail(&rbio->plug_list, &plug->rbio_list);
18391839
} else {
18401840
ret = __raid56_parity_write(rbio);
1841-
if (ret)
1841+
if (ret) {
1842+
__free_raid_bio(rbio);
18421843
goto fail;
1844+
}
18431845
}
18441846

18451847
return;
@@ -2742,8 +2744,10 @@ raid56_alloc_missing_rbio(struct bio *bio, struct btrfs_io_context *bioc)
27422744

27432745
rbio->faila = find_logical_bio_stripe(rbio, bio);
27442746
if (rbio->faila == -1) {
2745-
BUG();
2746-
kfree(rbio);
2747+
btrfs_warn_rl(fs_info,
2748+
"can not determine the failed stripe number for full stripe %llu",
2749+
bioc->raid_map[0]);
2750+
__free_raid_bio(rbio);
27472751
return NULL;
27482752
}
27492753

fs/btrfs/send.c

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6668,17 +6668,19 @@ static int changed_inode(struct send_ctx *sctx,
66686668
/*
66696669
* First, process the inode as if it was deleted.
66706670
*/
6671-
sctx->cur_inode_gen = right_gen;
6672-
sctx->cur_inode_new = false;
6673-
sctx->cur_inode_deleted = true;
6674-
sctx->cur_inode_size = btrfs_inode_size(
6675-
sctx->right_path->nodes[0], right_ii);
6676-
sctx->cur_inode_mode = btrfs_inode_mode(
6677-
sctx->right_path->nodes[0], right_ii);
6678-
ret = process_all_refs(sctx,
6679-
BTRFS_COMPARE_TREE_DELETED);
6680-
if (ret < 0)
6681-
goto out;
6671+
if (old_nlinks > 0) {
6672+
sctx->cur_inode_gen = right_gen;
6673+
sctx->cur_inode_new = false;
6674+
sctx->cur_inode_deleted = true;
6675+
sctx->cur_inode_size = btrfs_inode_size(
6676+
sctx->right_path->nodes[0], right_ii);
6677+
sctx->cur_inode_mode = btrfs_inode_mode(
6678+
sctx->right_path->nodes[0], right_ii);
6679+
ret = process_all_refs(sctx,
6680+
BTRFS_COMPARE_TREE_DELETED);
6681+
if (ret < 0)
6682+
goto out;
6683+
}
66826684

66836685
/*
66846686
* Now process the inode as if it was new.

fs/btrfs/super.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2555,6 +2555,7 @@ static int check_dev_super(struct btrfs_device *dev)
25552555
{
25562556
struct btrfs_fs_info *fs_info = dev->fs_info;
25572557
struct btrfs_super_block *sb;
2558+
u16 csum_type;
25582559
int ret = 0;
25592560

25602561
/* This should be called with fs still frozen. */
@@ -2569,6 +2570,21 @@ static int check_dev_super(struct btrfs_device *dev)
25692570
if (IS_ERR(sb))
25702571
return PTR_ERR(sb);
25712572

2573+
/* Verify the checksum. */
2574+
csum_type = btrfs_super_csum_type(sb);
2575+
if (csum_type != btrfs_super_csum_type(fs_info->super_copy)) {
2576+
btrfs_err(fs_info, "csum type changed, has %u expect %u",
2577+
csum_type, btrfs_super_csum_type(fs_info->super_copy));
2578+
ret = -EUCLEAN;
2579+
goto out;
2580+
}
2581+
2582+
if (btrfs_check_super_csum(fs_info, sb)) {
2583+
btrfs_err(fs_info, "csum for on-disk super block no longer matches");
2584+
ret = -EUCLEAN;
2585+
goto out;
2586+
}
2587+
25722588
/* Btrfs_validate_super() includes fsid check against super->fsid. */
25732589
ret = btrfs_validate_super(fs_info, sb, 0);
25742590
if (ret < 0)

fs/btrfs/volumes.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7142,13 +7142,15 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
71427142
u64 devid;
71437143
u64 type;
71447144
u8 uuid[BTRFS_UUID_SIZE];
7145+
int index;
71457146
int num_stripes;
71467147
int ret;
71477148
int i;
71487149

71497150
logical = key->offset;
71507151
length = btrfs_chunk_length(leaf, chunk);
71517152
type = btrfs_chunk_type(leaf, chunk);
7153+
index = btrfs_bg_flags_to_raid_index(type);
71527154
num_stripes = btrfs_chunk_num_stripes(leaf, chunk);
71537155

71547156
#if BITS_PER_LONG == 32
@@ -7202,7 +7204,15 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
72027204
map->io_align = btrfs_chunk_io_align(leaf, chunk);
72037205
map->stripe_len = btrfs_chunk_stripe_len(leaf, chunk);
72047206
map->type = type;
7205-
map->sub_stripes = btrfs_chunk_sub_stripes(leaf, chunk);
7207+
/*
7208+
* We can't use the sub_stripes value, as for profiles other than
7209+
* RAID10, they may have 0 as sub_stripes for filesystems created by
7210+
* older mkfs (<v5.4).
7211+
* In that case, it can cause divide-by-zero errors later.
7212+
* Since currently sub_stripes is fixed for each profile, let's
7213+
* use the trusted value instead.
7214+
*/
7215+
map->sub_stripes = btrfs_raid_array[index].sub_stripes;
72067216
map->verified_stripes = 0;
72077217
em->orig_block_len = btrfs_calc_stripe_length(em);
72087218
for (i = 0; i < num_stripes; i++) {

fs/btrfs/volumes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@ typedef void (*btrfs_bio_end_io_t)(struct btrfs_bio *bbio);
395395
*/
396396
struct btrfs_bio {
397397
unsigned int mirror_num;
398+
struct bvec_iter iter;
398399

399400
/* for direct I/O */
400401
u64 file_offset;
@@ -403,7 +404,6 @@ struct btrfs_bio {
403404
struct btrfs_device *device;
404405
u8 *csum;
405406
u8 csum_inline[BTRFS_BIO_INLINE_CSUM_SIZE];
406-
struct bvec_iter iter;
407407

408408
/* End I/O information supplied to btrfs_bio_alloc */
409409
btrfs_bio_end_io_t end_io;

0 commit comments

Comments
 (0)