Commit 5aaef24b authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents 78a089d0 76a66ba1
Loading
Loading
Loading
Loading
+4 −6
Original line number Diff line number Diff line
@@ -166,11 +166,9 @@ static bool btrfs_supported_super_csum(u16 csum_type)
 * Return 0 if the superblock checksum type matches the checksum value of that
 * algorithm. Pass the raw disk superblock data.
 */
static int btrfs_check_super_csum(struct btrfs_fs_info *fs_info,
				  char *raw_disk_sb)
int btrfs_check_super_csum(struct btrfs_fs_info *fs_info,
			   const struct btrfs_super_block *disk_sb)
{
	struct btrfs_super_block *disk_sb =
		(struct btrfs_super_block *)raw_disk_sb;
	char result[BTRFS_CSUM_SIZE];
	SHASH_DESC_ON_STACK(shash, fs_info->csum_shash);

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

	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
	 * We want to check superblock checksum, the type is stored inside.
	 * Pass the whole disk block of size BTRFS_SUPER_INFO_SIZE (4k).
	 */
	if (btrfs_check_super_csum(fs_info, (u8 *)disk_super)) {
	if (btrfs_check_super_csum(fs_info, disk_super)) {
		btrfs_err(fs_info, "superblock checksum mismatch");
		err = -EINVAL;
		btrfs_release_disk_super(disk_super);
+2 −0
Original line number Diff line number Diff line
@@ -42,6 +42,8 @@ struct extent_buffer *btrfs_find_create_tree_block(
void btrfs_clean_tree_block(struct extent_buffer *buf);
void btrfs_clear_oneshot_options(struct btrfs_fs_info *fs_info);
int btrfs_start_pre_rw_mount(struct btrfs_fs_info *fs_info);
int btrfs_check_super_csum(struct btrfs_fs_info *fs_info,
			   const struct btrfs_super_block *disk_sb);
int __cold open_ctree(struct super_block *sb,
	       struct btrfs_fs_devices *fs_devices,
	       char *options);
+1 −1
Original line number Diff line number Diff line
@@ -58,7 +58,7 @@ static int btrfs_encode_fh(struct inode *inode, u32 *fh, int *max_len,
}

struct dentry *btrfs_get_dentry(struct super_block *sb, u64 objectid,
				u64 root_objectid, u32 generation,
				u64 root_objectid, u64 generation,
				int check_generation)
{
	struct btrfs_fs_info *fs_info = btrfs_sb(sb);
+1 −1
Original line number Diff line number Diff line
@@ -19,7 +19,7 @@ struct btrfs_fid {
} __attribute__ ((packed));

struct dentry *btrfs_get_dentry(struct super_block *sb, u64 objectid,
				u64 root_objectid, u32 generation,
				u64 root_objectid, u64 generation,
				int check_generation);
struct dentry *btrfs_get_parent(struct dentry *child);

+13 −12
Original line number Diff line number Diff line
@@ -3295,21 +3295,22 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
		}

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

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