Commit 8f282f71 authored by David Sterba's avatar David Sterba

btrfs: fallback to vmalloc in btrfs_compare_tree

The allocation of node could fail if the memory is too fragmented for a
given node size, practically observed with 64k.

http://article.gmane.org/gmane.comp.file-systems.btrfs/54689Reported-and-tested-by: default avatarJean-Denis Girard <jd.girard@sysnux.pf>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 918c2ee1
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/rbtree.h> #include <linux/rbtree.h>
#include <linux/vmalloc.h>
#include "ctree.h" #include "ctree.h"
#include "disk-io.h" #include "disk-io.h"
#include "transaction.h" #include "transaction.h"
...@@ -5361,11 +5362,14 @@ int btrfs_compare_trees(struct btrfs_root *left_root, ...@@ -5361,11 +5362,14 @@ int btrfs_compare_trees(struct btrfs_root *left_root,
goto out; goto out;
} }
tmp_buf = kmalloc(left_root->nodesize, GFP_KERNEL); tmp_buf = kmalloc(left_root->nodesize, GFP_KERNEL | __GFP_NOWARN);
if (!tmp_buf) {
tmp_buf = vmalloc(left_root->nodesize);
if (!tmp_buf) { if (!tmp_buf) {
ret = -ENOMEM; ret = -ENOMEM;
goto out; goto out;
} }
}
left_path->search_commit_root = 1; left_path->search_commit_root = 1;
left_path->skip_locking = 1; left_path->skip_locking = 1;
...@@ -5565,7 +5569,7 @@ int btrfs_compare_trees(struct btrfs_root *left_root, ...@@ -5565,7 +5569,7 @@ int btrfs_compare_trees(struct btrfs_root *left_root,
out: out:
btrfs_free_path(left_path); btrfs_free_path(left_path);
btrfs_free_path(right_path); btrfs_free_path(right_path);
kfree(tmp_buf); kvfree(tmp_buf);
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment