Home Home > GIT Browse > SLE12-SP5-AZURE
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Thumshirn <jthumshirn@suse.de>2019-09-04 14:12:31 +0200
committerJohannes Thumshirn <jthumshirn@suse.de>2019-09-05 11:55:39 +0200
commitcfb980a9aec86717124f68da199cfc994a228f55 (patch)
tree6f35120af0d94d58121ae6324a35324dc642fe33
parent093d4d4130fa5bc51252b710677618b38e986d1b (diff)
Btrfs: add one more sanity check for shared ref type
(bsc#1149325).
-rw-r--r--patches.suse/btrfs-add-one-more-sanity-check-for-shared-ref-type.patch141
-rw-r--r--series.conf1
2 files changed, 142 insertions, 0 deletions
diff --git a/patches.suse/btrfs-add-one-more-sanity-check-for-shared-ref-type.patch b/patches.suse/btrfs-add-one-more-sanity-check-for-shared-ref-type.patch
new file mode 100644
index 0000000000..d9970fdd51
--- /dev/null
+++ b/patches.suse/btrfs-add-one-more-sanity-check-for-shared-ref-type.patch
@@ -0,0 +1,141 @@
+From: Liu Bo <bo.li.liu@oracle.com>
+Date: Fri, 18 Aug 2017 15:15:24 -0600
+Subject: Btrfs: add one more sanity check for shared ref type
+Git-commit: 64ecdb647ddb83dcff9c8e2a5c40119f171ea004
+Patch-mainline: v4.14-rc1
+References: bsc#1149325
+
+Every shared ref has a parent tree block, which can be get from
+btrfs_extent_inline_ref_offset(). And the tree block must be aligned
+to the nodesize, so we'd know this inline ref is not valid if this
+block's bytenr is not aligned to the nodesize, in which case, most
+likely the ref type has been misused.
+
+This adds the above mentioned check and also updates
+print_extent_item() called by btrfs_print_leaf() to point out the
+invalid ref while printing the tree structure.
+
+Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ fs/btrfs/extent-tree.c | 29 +++++++++++++++++++++++++----
+ fs/btrfs/print-tree.c | 27 +++++++++++++++++++++------
+ 2 files changed, 46 insertions(+), 10 deletions(-)
+
+diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
+index 51a691532fd8..96e49fd5b888 100644
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -1158,19 +1158,40 @@ int btrfs_get_extent_inline_ref_type(const struct extent_buffer *eb,
+ enum btrfs_inline_ref_type is_data)
+ {
+ int type = btrfs_extent_inline_ref_type(eb, iref);
++ u64 offset = btrfs_extent_inline_ref_offset(eb, iref);
+
+ if (type == BTRFS_TREE_BLOCK_REF_KEY ||
+ type == BTRFS_SHARED_BLOCK_REF_KEY ||
+ type == BTRFS_SHARED_DATA_REF_KEY ||
+ type == BTRFS_EXTENT_DATA_REF_KEY) {
+ if (is_data == BTRFS_REF_TYPE_BLOCK) {
+- if (type == BTRFS_TREE_BLOCK_REF_KEY ||
+- type == BTRFS_SHARED_BLOCK_REF_KEY)
++ if (type == BTRFS_TREE_BLOCK_REF_KEY)
+ return type;
++ if (type == BTRFS_SHARED_BLOCK_REF_KEY) {
++ ASSERT(eb->fs_info);
++ /*
++ * Every shared one has parent tree
++ * block, which must be aligned to
++ * nodesize.
++ */
++ if (offset &&
++ IS_ALIGNED(offset, eb->fs_info->nodesize))
++ return type;
++ }
+ } else if (is_data == BTRFS_REF_TYPE_DATA) {
+- if (type == BTRFS_EXTENT_DATA_REF_KEY ||
+- type == BTRFS_SHARED_DATA_REF_KEY)
++ if (type == BTRFS_EXTENT_DATA_REF_KEY)
+ return type;
++ if (type == BTRFS_SHARED_DATA_REF_KEY) {
++ ASSERT(eb->fs_info);
++ /*
++ * Every shared one has parent tree
++ * block, which must be aligned to
++ * nodesize.
++ */
++ if (offset &&
++ IS_ALIGNED(offset, eb->fs_info->nodesize))
++ return type;
++ }
+ } else {
+ ASSERT(is_data == BTRFS_REF_TYPE_ANY);
+ return type;
+diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c
+index c1acbdcb476c..569205e651c7 100644
+--- a/fs/btrfs/print-tree.c
++++ b/fs/btrfs/print-tree.c
+@@ -44,7 +44,7 @@ static void print_dev_item(struct extent_buffer *eb,
+ static void print_extent_data_ref(struct extent_buffer *eb,
+ struct btrfs_extent_data_ref *ref)
+ {
+- pr_info("\t\textent data backref root %llu objectid %llu offset %llu count %u\n",
++ pr_cont("extent data backref root %llu objectid %llu offset %llu count %u\n",
+ btrfs_extent_data_ref_root(eb, ref),
+ btrfs_extent_data_ref_objectid(eb, ref),
+ btrfs_extent_data_ref_offset(eb, ref),
+@@ -63,6 +63,7 @@ static void print_extent_item(struct extent_buffer *eb, int slot, int type)
+ u32 item_size = btrfs_item_size_nr(eb, slot);
+ u64 flags;
+ u64 offset;
++ int ref_index = 0;
+
+ if (item_size < sizeof(*ei)) {
+ #ifdef BTRFS_COMPAT_EXTENT_TREE_V0
+@@ -104,12 +105,20 @@ static void print_extent_item(struct extent_buffer *eb, int slot, int type)
+ iref = (struct btrfs_extent_inline_ref *)ptr;
+ type = btrfs_extent_inline_ref_type(eb, iref);
+ offset = btrfs_extent_inline_ref_offset(eb, iref);
++ pr_info("\t\tref#%d: ", ref_index++);
+ switch (type) {
+ case BTRFS_TREE_BLOCK_REF_KEY:
+- pr_info("\t\ttree block backref root %llu\n", offset);
++ pr_cont("tree block backref root %llu\n", offset);
+ break;
+ case BTRFS_SHARED_BLOCK_REF_KEY:
+- pr_info("\t\tshared block backref parent %llu\n", offset);
++ pr_cont("shared block backref parent %llu\n", offset);
++ /*
++ * 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);
+ break;
+ case BTRFS_EXTENT_DATA_REF_KEY:
+ dref = (struct btrfs_extent_data_ref *)(&iref->offset);
+@@ -117,12 +126,18 @@ static void print_extent_item(struct extent_buffer *eb, int slot, int type)
+ break;
+ case BTRFS_SHARED_DATA_REF_KEY:
+ sref = (struct btrfs_shared_data_ref *)(iref + 1);
+- pr_info("\t\tshared data backref parent %llu count %u\n",
++ pr_cont("shared data backref parent %llu count %u\n",
+ offset, btrfs_shared_data_ref_count(eb, sref));
++ /*
++ * 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);
+ break;
+ default:
+- btrfs_err(eb->fs_info,
+- "extent %llu has invalid ref type %d",
++ pr_cont("(extent %llu has INVALID ref type %d)\n",
+ eb->start, type);
+ return;
+ }
+
diff --git a/series.conf b/series.conf
index 7596039a98..f015e258e9 100644
--- a/series.conf
+++ b/series.conf
@@ -6816,6 +6816,7 @@
patches.suse/btrfs-remove-bug-in-print_extent_item.patch
patches.suse/btrfs-remove-bug-in-add_data_reference.patch
patches.suse/btrfs-remove-bug_on-in-_add_tree_block.patch
+ patches.suse/btrfs-add-one-more-sanity-check-for-shared-ref-type.patch
patches.suse/svcrdma-Limit-RQ-depth.patch
patches.suse/rdma-core-Add-rdma_rw_mr_payload.patch
patches.suse/svcrdma-Estimate-Send-Queue-depth-properly.patch