diff options
Diffstat (limited to 'fs/btrfs/struct-funcs.c')
-rw-r--r-- | fs/btrfs/struct-funcs.c | 100 |
1 files changed, 31 insertions, 69 deletions
diff --git a/fs/btrfs/struct-funcs.c b/fs/btrfs/struct-funcs.c index c0f7ecaf1e79..bc1f6ad18442 100644 --- a/fs/btrfs/struct-funcs.c +++ b/fs/btrfs/struct-funcs.c | |||
@@ -50,36 +50,22 @@ u##bits btrfs_##name(struct extent_buffer *eb, \ | |||
50 | unsigned long part_offset = (unsigned long)s; \ | 50 | unsigned long part_offset = (unsigned long)s; \ |
51 | unsigned long offset = part_offset + offsetof(type, member); \ | 51 | unsigned long offset = part_offset + offsetof(type, member); \ |
52 | type *p; \ | 52 | type *p; \ |
53 | /* ugly, but we want the fast path here */ \ | 53 | int err; \ |
54 | if (eb->map_token && offset >= eb->map_start && \ | 54 | char *kaddr; \ |
55 | offset + sizeof(((type *)0)->member) <= eb->map_start + \ | 55 | unsigned long map_start; \ |
56 | eb->map_len) { \ | 56 | unsigned long map_len; \ |
57 | p = (type *)(eb->kaddr + part_offset - eb->map_start); \ | 57 | u##bits res; \ |
58 | return le##bits##_to_cpu(p->member); \ | 58 | err = map_private_extent_buffer(eb, offset, \ |
59 | } \ | 59 | sizeof(((type *)0)->member), \ |
60 | { \ | 60 | &kaddr, &map_start, &map_len); \ |
61 | int err; \ | 61 | if (err) { \ |
62 | char *map_token; \ | 62 | __le##bits leres; \ |
63 | char *kaddr; \ | 63 | read_eb_member(eb, s, type, member, &leres); \ |
64 | int unmap_on_exit = (eb->map_token == NULL); \ | 64 | return le##bits##_to_cpu(leres); \ |
65 | unsigned long map_start; \ | 65 | } \ |
66 | unsigned long map_len; \ | 66 | p = (type *)(kaddr + part_offset - map_start); \ |
67 | u##bits res; \ | 67 | res = le##bits##_to_cpu(p->member); \ |
68 | err = map_extent_buffer(eb, offset, \ | 68 | return res; \ |
69 | sizeof(((type *)0)->member), \ | ||
70 | &map_token, &kaddr, \ | ||
71 | &map_start, &map_len, KM_USER1); \ | ||
72 | if (err) { \ | ||
73 | __le##bits leres; \ | ||
74 | read_eb_member(eb, s, type, member, &leres); \ | ||
75 | return le##bits##_to_cpu(leres); \ | ||
76 | } \ | ||
77 | p = (type *)(kaddr + part_offset - map_start); \ | ||
78 | res = le##bits##_to_cpu(p->member); \ | ||
79 | if (unmap_on_exit) \ | ||
80 | unmap_extent_buffer(eb, map_token, KM_USER1); \ | ||
81 | return res; \ | ||
82 | } \ | ||
83 | } \ | 69 | } \ |
84 | void btrfs_set_##name(struct extent_buffer *eb, \ | 70 | void btrfs_set_##name(struct extent_buffer *eb, \ |
85 | type *s, u##bits val) \ | 71 | type *s, u##bits val) \ |
@@ -87,36 +73,21 @@ void btrfs_set_##name(struct extent_buffer *eb, \ | |||
87 | unsigned long part_offset = (unsigned long)s; \ | 73 | unsigned long part_offset = (unsigned long)s; \ |
88 | unsigned long offset = part_offset + offsetof(type, member); \ | 74 | unsigned long offset = part_offset + offsetof(type, member); \ |
89 | type *p; \ | 75 | type *p; \ |
90 | /* ugly, but we want the fast path here */ \ | 76 | int err; \ |
91 | if (eb->map_token && offset >= eb->map_start && \ | 77 | char *kaddr; \ |
92 | offset + sizeof(((type *)0)->member) <= eb->map_start + \ | 78 | unsigned long map_start; \ |
93 | eb->map_len) { \ | 79 | unsigned long map_len; \ |
94 | p = (type *)(eb->kaddr + part_offset - eb->map_start); \ | 80 | err = map_private_extent_buffer(eb, offset, \ |
95 | p->member = cpu_to_le##bits(val); \ | 81 | sizeof(((type *)0)->member), \ |
96 | return; \ | 82 | &kaddr, &map_start, &map_len); \ |
97 | } \ | 83 | if (err) { \ |
98 | { \ | 84 | __le##bits val2; \ |
99 | int err; \ | 85 | val2 = cpu_to_le##bits(val); \ |
100 | char *map_token; \ | 86 | write_eb_member(eb, s, type, member, &val2); \ |
101 | char *kaddr; \ | 87 | return; \ |
102 | int unmap_on_exit = (eb->map_token == NULL); \ | 88 | } \ |
103 | unsigned long map_start; \ | 89 | p = (type *)(kaddr + part_offset - map_start); \ |
104 | unsigned long map_len; \ | 90 | p->member = cpu_to_le##bits(val); \ |
105 | err = map_extent_buffer(eb, offset, \ | ||
106 | sizeof(((type *)0)->member), \ | ||
107 | &map_token, &kaddr, \ | ||
108 | &map_start, &map_len, KM_USER1); \ | ||
109 | if (err) { \ | ||
110 | __le##bits val2; \ | ||
111 | val2 = cpu_to_le##bits(val); \ | ||
112 | write_eb_member(eb, s, type, member, &val2); \ | ||
113 | return; \ | ||
114 | } \ | ||
115 | p = (type *)(kaddr + part_offset - map_start); \ | ||
116 | p->member = cpu_to_le##bits(val); \ | ||
117 | if (unmap_on_exit) \ | ||
118 | unmap_extent_buffer(eb, map_token, KM_USER1); \ | ||
119 | } \ | ||
120 | } | 91 | } |
121 | 92 | ||
122 | #include "ctree.h" | 93 | #include "ctree.h" |
@@ -125,15 +96,6 @@ void btrfs_node_key(struct extent_buffer *eb, | |||
125 | struct btrfs_disk_key *disk_key, int nr) | 96 | struct btrfs_disk_key *disk_key, int nr) |
126 | { | 97 | { |
127 | unsigned long ptr = btrfs_node_key_ptr_offset(nr); | 98 | unsigned long ptr = btrfs_node_key_ptr_offset(nr); |
128 | if (eb->map_token && ptr >= eb->map_start && | ||
129 | ptr + sizeof(*disk_key) <= eb->map_start + eb->map_len) { | ||
130 | memcpy(disk_key, eb->kaddr + ptr - eb->map_start, | ||
131 | sizeof(*disk_key)); | ||
132 | return; | ||
133 | } else if (eb->map_token) { | ||
134 | unmap_extent_buffer(eb, eb->map_token, KM_USER1); | ||
135 | eb->map_token = NULL; | ||
136 | } | ||
137 | read_eb_member(eb, (struct btrfs_key_ptr *)ptr, | 99 | read_eb_member(eb, (struct btrfs_key_ptr *)ptr, |
138 | struct btrfs_key_ptr, key, disk_key); | 100 | struct btrfs_key_ptr, key, disk_key); |
139 | } | 101 | } |