aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-11-06 15:09:29 -0500
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:03:57 -0400
commite644d021e328d3902559e5db687383f2da85993c (patch)
tree12fa85275a3333c709ddc03c2f4fd426b97a9dcf
parentf84a8b362d9785ca1fa0598d8a90f35184bd8750 (diff)
downloadkernel_samsung_smdk4412-e644d021e328d3902559e5db687383f2da85993c.zip
kernel_samsung_smdk4412-e644d021e328d3902559e5db687383f2da85993c.tar.gz
kernel_samsung_smdk4412-e644d021e328d3902559e5db687383f2da85993c.tar.bz2
Fix recursive KM_USER1 usage in btrfs_realloc_node
Signed-off-by: Chris Mason <chris.mason@oracle.com>
-rw-r--r--fs/btrfs/ctree.h11
-rw-r--r--fs/btrfs/struct-funcs.c16
2 files changed, 19 insertions, 8 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index f7907b0..030d21d 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -557,14 +557,9 @@ static inline unsigned long btrfs_node_key_ptr_offset(int nr)
sizeof(struct btrfs_key_ptr) * nr;
}
-static inline void btrfs_node_key(struct extent_buffer *eb,
- struct btrfs_disk_key *disk_key, int nr)
-{
- unsigned long ptr;
- ptr = btrfs_node_key_ptr_offset(nr);
- read_eb_member(eb, (struct btrfs_key_ptr *)ptr,
- struct btrfs_key_ptr, key, disk_key);
-}
+void btrfs_node_key(struct extent_buffer *eb,
+ struct btrfs_disk_key *disk_key, int nr);
+
static inline void btrfs_set_node_key(struct extent_buffer *eb,
struct btrfs_disk_key *disk_key, int nr)
{
diff --git a/fs/btrfs/struct-funcs.c b/fs/btrfs/struct-funcs.c
index cf68fcf..c5715a6 100644
--- a/fs/btrfs/struct-funcs.c
+++ b/fs/btrfs/struct-funcs.c
@@ -95,3 +95,19 @@ void btrfs_set_##name(struct extent_buffer *eb, \
#include "ctree.h"
+void btrfs_node_key(struct extent_buffer *eb,
+ struct btrfs_disk_key *disk_key, int nr)
+{
+ unsigned long ptr = btrfs_node_key_ptr_offset(nr);
+ if (eb->map_token && ptr >= eb->map_start &&
+ ptr + sizeof(*disk_key) <= eb->map_start + eb->map_len) {
+ memcpy(disk_key, eb->kaddr + ptr - eb->map_start,
+ sizeof(*disk_key));
+ return;
+ } else if (eb->map_token) {
+ unmap_extent_buffer(eb, eb->map_token, KM_USER1);
+ eb->map_token = NULL;
+ }
+ read_eb_member(eb, (struct btrfs_key_ptr *)ptr,
+ struct btrfs_key_ptr, key, disk_key);
+}