Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
fs
btrfs
struct-funcs.c
Go to the documentation of this file.
1
/*
2
* Copyright (C) 2007 Oracle. All rights reserved.
3
*
4
* This program is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU General Public
6
* License v2 as published by the Free Software Foundation.
7
*
8
* This program is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
* General Public License for more details.
12
*
13
* You should have received a copy of the GNU General Public
14
* License along with this program; if not, write to the
15
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16
* Boston, MA 021110-1307, USA.
17
*/
18
19
#include <
linux/highmem.h
>
20
#include <asm/unaligned.h>
21
22
#include "
ctree.h
"
23
24
static
inline
u8
get_unaligned_le8(
const
void
*
p
)
25
{
26
return
*(
u8
*)p;
27
}
28
29
static
inline
void
put_unaligned_le8(
u8
val
,
void
*
p
)
30
{
31
*(
u8
*)p = val;
32
}
33
34
/*
35
* this is some deeply nasty code.
36
*
37
* The end result is that anyone who #includes ctree.h gets a
38
* declaration for the btrfs_set_foo functions and btrfs_foo functions,
39
* which are wappers of btrfs_set_token_#bits functions and
40
* btrfs_get_token_#bits functions, which are defined in this file.
41
*
42
* These setget functions do all the extent_buffer related mapping
43
* required to efficiently read and write specific fields in the extent
44
* buffers. Every pointer to metadata items in btrfs is really just
45
* an unsigned long offset into the extent buffer which has been
46
* cast to a specific type. This gives us all the gcc type checking.
47
*
48
* The extent buffer api is used to do the page spanning work required to
49
* have a metadata blocksize different from the page size.
50
*/
51
52
#define DEFINE_BTRFS_SETGET_BITS(bits) \
53
u##bits btrfs_get_token_##bits(struct extent_buffer *eb, void *ptr, \
54
unsigned long off, \
55
struct btrfs_map_token *token) \
56
{ \
57
unsigned long part_offset = (unsigned long)ptr; \
58
unsigned long offset = part_offset + off; \
59
void *p; \
60
int err; \
61
char *kaddr; \
62
unsigned long map_start; \
63
unsigned long map_len; \
64
int size = sizeof(u##bits); \
65
u##bits res; \
66
\
67
if (token && token->kaddr && token->offset <= offset && \
68
token->eb == eb && \
69
(token->offset + PAGE_CACHE_SIZE >= offset + size)) { \
70
kaddr = token->kaddr; \
71
p = kaddr + part_offset - token->offset; \
72
res = get_unaligned_le##bits(p + off); \
73
return res; \
74
} \
75
err = map_private_extent_buffer(eb, offset, size, \
76
&kaddr, &map_start, &map_len); \
77
if (err) { \
78
__le##bits leres; \
79
\
80
read_extent_buffer(eb, &leres, offset, size); \
81
return le##bits##_to_cpu(leres); \
82
} \
83
p = kaddr + part_offset - map_start; \
84
res = get_unaligned_le##bits(p + off); \
85
if (token) { \
86
token->kaddr = kaddr; \
87
token->offset = map_start; \
88
token->eb = eb; \
89
} \
90
return res; \
91
} \
92
void btrfs_set_token_##bits(struct extent_buffer *eb, \
93
void *ptr, unsigned long off, u##bits val, \
94
struct btrfs_map_token *token) \
95
{ \
96
unsigned long part_offset = (unsigned long)ptr; \
97
unsigned long offset = part_offset + off; \
98
void *p; \
99
int err; \
100
char *kaddr; \
101
unsigned long map_start; \
102
unsigned long map_len; \
103
int size = sizeof(u##bits); \
104
\
105
if (token && token->kaddr && token->offset <= offset && \
106
token->eb == eb && \
107
(token->offset + PAGE_CACHE_SIZE >= offset + size)) { \
108
kaddr = token->kaddr; \
109
p = kaddr + part_offset - token->offset; \
110
put_unaligned_le##bits(val, p + off); \
111
return; \
112
} \
113
err = map_private_extent_buffer(eb, offset, size, \
114
&kaddr, &map_start, &map_len); \
115
if (err) { \
116
__le##bits val2; \
117
\
118
val2 = cpu_to_le##bits(val); \
119
write_extent_buffer(eb, &val2, offset, size); \
120
return; \
121
} \
122
p = kaddr + part_offset - map_start; \
123
put_unaligned_le##bits(val, p + off); \
124
if (token) { \
125
token->kaddr = kaddr; \
126
token->offset = map_start; \
127
token->eb = eb; \
128
} \
129
}
130
131
DEFINE_BTRFS_SETGET_BITS
(8)
132
DEFINE_BTRFS_SETGET_BITS
(16)
133
DEFINE_BTRFS_SETGET_BITS
(32)
134
DEFINE_BTRFS_SETGET_BITS
(64)
135
136
void
btrfs_node_key
(
struct
extent_buffer
*
eb
,
137
struct
btrfs_disk_key
*disk_key,
int
nr
)
138
{
139
unsigned
long
ptr
= btrfs_node_key_ptr_offset(nr);
140
read_eb_member
(eb, (
struct
btrfs_key_ptr
*)ptr,
141
struct
btrfs_key_ptr
,
key
, disk_key);
142
}
Generated on Thu Jan 10 2013 14:45:44 for Linux Kernel by
1.8.2