Skip to content

Commit

Permalink
Merge tag 'for-5.9-rc4-tag' of git:https://git.kernel.org/pub/scm/linux/ker…
Browse files Browse the repository at this point in the history
…nel/git/kdave/linux

Pull btrfs fixes from David Sterba:
 "A few more fixes:

   - regression fix for a crash after failed snapshot creation

   - one more lockep fix: use nofs allocation when allocating missing
     device

   - fix reloc tree leak on degraded mount

   - make some extent buffer alignment checks less strict to mount
     filesystems created by btrfs-convert"

* tag 'for-5.9-rc4-tag' of git:https://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
  btrfs: fix NULL pointer dereference after failure to create snapshot
  btrfs: free data reloc tree on failed mount
  btrfs: require only sector size alignment for parent eb bytenr
  btrfs: fix lockdep splat in add_missing_dev
  • Loading branch information
torvalds committed Sep 12, 2020
2 parents 5a3c558 + 2d892cc commit edf6b0e
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 15 deletions.
2 changes: 2 additions & 0 deletions fs/btrfs/disk-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -3418,6 +3418,8 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
btrfs_put_block_group_cache(fs_info);

fail_tree_roots:
if (fs_info->data_reloc_root)
btrfs_drop_and_free_fs_root(fs_info, fs_info->data_reloc_root);
free_root_pointers(fs_info, true);
invalidate_inode_pages2(fs_info->btree_inode->i_mapping);

Expand Down
19 changes: 9 additions & 10 deletions fs/btrfs/extent-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -400,12 +400,11 @@ int btrfs_get_extent_inline_ref_type(const struct extent_buffer *eb,
if (type == BTRFS_SHARED_BLOCK_REF_KEY) {
ASSERT(eb->fs_info);
/*
* Every shared one has parent tree
* block, which must be aligned to
* nodesize.
* Every shared one has parent tree block,
* which must be aligned to sector size.
*/
if (offset &&
IS_ALIGNED(offset, eb->fs_info->nodesize))
IS_ALIGNED(offset, eb->fs_info->sectorsize))
return type;
}
} else if (is_data == BTRFS_REF_TYPE_DATA) {
Expand All @@ -414,12 +413,11 @@ int btrfs_get_extent_inline_ref_type(const struct extent_buffer *eb,
if (type == BTRFS_SHARED_DATA_REF_KEY) {
ASSERT(eb->fs_info);
/*
* Every shared one has parent tree
* block, which must be aligned to
* nodesize.
* Every shared one has parent tree block,
* which must be aligned to sector size.
*/
if (offset &&
IS_ALIGNED(offset, eb->fs_info->nodesize))
IS_ALIGNED(offset, eb->fs_info->sectorsize))
return type;
}
} else {
Expand All @@ -429,8 +427,9 @@ int btrfs_get_extent_inline_ref_type(const struct extent_buffer *eb,
}

btrfs_print_leaf((struct extent_buffer *)eb);
btrfs_err(eb->fs_info, "eb %llu invalid extent inline ref type %d",
eb->start, type);
btrfs_err(eb->fs_info,
"eb %llu iref 0x%lx invalid extent inline ref type %d",
eb->start, (unsigned long)iref, type);
WARN_ON(1);

return BTRFS_REF_TYPE_INVALID;
Expand Down
12 changes: 7 additions & 5 deletions fs/btrfs/print-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,10 @@ static void print_extent_item(struct extent_buffer *eb, int slot, int type)
* offset is supposed to be a tree block which
* must be aligned to nodesize.
*/
if (!IS_ALIGNED(offset, eb->fs_info->nodesize))
pr_info("\t\t\t(parent %llu is NOT ALIGNED to nodesize %llu)\n",
offset, (unsigned long long)eb->fs_info->nodesize);
if (!IS_ALIGNED(offset, eb->fs_info->sectorsize))
pr_info(
"\t\t\t(parent %llu not aligned to sectorsize %u)\n",
offset, eb->fs_info->sectorsize);
break;
case BTRFS_EXTENT_DATA_REF_KEY:
dref = (struct btrfs_extent_data_ref *)(&iref->offset);
Expand All @@ -112,8 +113,9 @@ static void print_extent_item(struct extent_buffer *eb, int slot, int type)
* must be aligned to nodesize.
*/
if (!IS_ALIGNED(offset, eb->fs_info->nodesize))
pr_info("\t\t\t(parent %llu is NOT ALIGNED to nodesize %llu)\n",
offset, (unsigned long long)eb->fs_info->nodesize);
pr_info(
"\t\t\t(parent %llu not aligned to sectorsize %u)\n",
offset, eb->fs_info->sectorsize);
break;
default:
pr_cont("(extent %llu has INVALID ref type %d)\n",
Expand Down
1 change: 1 addition & 0 deletions fs/btrfs/transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -1636,6 +1636,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
pending->snap = btrfs_get_new_fs_root(fs_info, objectid, pending->anon_dev);
if (IS_ERR(pending->snap)) {
ret = PTR_ERR(pending->snap);
pending->snap = NULL;
btrfs_abort_transaction(trans, ret);
goto fail;
}
Expand Down
10 changes: 10 additions & 0 deletions fs/btrfs/volumes.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/

#include <linux/sched.h>
#include <linux/sched/mm.h>
#include <linux/bio.h>
#include <linux/slab.h>
#include <linux/blkdev.h>
Expand Down Expand Up @@ -6484,8 +6485,17 @@ static struct btrfs_device *add_missing_dev(struct btrfs_fs_devices *fs_devices,
u64 devid, u8 *dev_uuid)
{
struct btrfs_device *device;
unsigned int nofs_flag;

/*
* We call this under the chunk_mutex, so we want to use NOFS for this
* allocation, however we don't want to change btrfs_alloc_device() to
* always do NOFS because we use it in a lot of other GFP_KERNEL safe
* places.
*/
nofs_flag = memalloc_nofs_save();
device = btrfs_alloc_device(NULL, &devid, dev_uuid);
memalloc_nofs_restore(nofs_flag);
if (IS_ERR(device))
return device;

Expand Down

0 comments on commit edf6b0e

Please sign in to comment.