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
xfs
xfs_ialloc_btree.c
Go to the documentation of this file.
1
/*
2
* Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
3
* All Rights Reserved.
4
*
5
* This program is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU General Public License as
7
* published by the Free Software Foundation.
8
*
9
* This program is distributed in the hope that it would be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
13
*
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write the Free Software Foundation,
16
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
*/
18
#include "
xfs.h
"
19
#include "
xfs_fs.h
"
20
#include "
xfs_types.h
"
21
#include "
xfs_bit.h
"
22
#include "
xfs_log.h
"
23
#include "
xfs_trans.h
"
24
#include "
xfs_sb.h
"
25
#include "
xfs_ag.h
"
26
#include "
xfs_mount.h
"
27
#include "
xfs_bmap_btree.h
"
28
#include "
xfs_alloc_btree.h
"
29
#include "
xfs_ialloc_btree.h
"
30
#include "
xfs_dinode.h
"
31
#include "
xfs_inode.h
"
32
#include "
xfs_btree.h
"
33
#include "
xfs_ialloc.h
"
34
#include "
xfs_alloc.h
"
35
#include "
xfs_error.h
"
36
37
38
STATIC
int
39
xfs_inobt_get_minrecs
(
40
struct
xfs_btree_cur
*
cur
,
41
int
level
)
42
{
43
return
cur->
bc_mp
->m_inobt_mnr[level != 0];
44
}
45
46
STATIC
struct
xfs_btree_cur
*
47
xfs_inobt_dup_cursor
(
48
struct
xfs_btree_cur
*
cur
)
49
{
50
return
xfs_inobt_init_cursor
(cur->
bc_mp
, cur->
bc_tp
,
51
cur->
bc_private
.
a
.agbp, cur->
bc_private
.
a
.agno);
52
}
53
54
STATIC
void
55
xfs_inobt_set_root
(
56
struct
xfs_btree_cur
*
cur
,
57
union
xfs_btree_ptr
*nptr,
58
int
inc
)
/* level change */
59
{
60
struct
xfs_buf
*agbp = cur->
bc_private
.
a
.agbp;
61
struct
xfs_agi
*agi =
XFS_BUF_TO_AGI
(agbp);
62
63
agi->
agi_root
= nptr->
s
;
64
be32_add_cpu(&agi->
agi_level
, inc);
65
xfs_ialloc_log_agi
(cur->
bc_tp
, agbp,
XFS_AGI_ROOT
|
XFS_AGI_LEVEL
);
66
}
67
68
STATIC
int
69
xfs_inobt_alloc_block
(
70
struct
xfs_btree_cur
*
cur
,
71
union
xfs_btree_ptr
*
start
,
72
union
xfs_btree_ptr
*
new
,
73
int
length
,
74
int
*
stat
)
75
{
76
xfs_alloc_arg_t
args
;
/* block allocation args */
77
int
error
;
/* error return value */
78
xfs_agblock_t
sbno =
be32_to_cpu
(start->
s
);
79
80
XFS_BTREE_TRACE_CURSOR
(cur, XBT_ENTRY);
81
82
memset
(&args, 0,
sizeof
(args));
83
args.
tp
= cur->
bc_tp
;
84
args.
mp
= cur->
bc_mp
;
85
args.
fsbno
=
XFS_AGB_TO_FSB
(args.
mp
, cur->
bc_private
.
a
.agno, sbno);
86
args.
minlen
= 1;
87
args.
maxlen
= 1;
88
args.
prod
= 1;
89
args.
type
=
XFS_ALLOCTYPE_NEAR_BNO
;
90
91
error =
xfs_alloc_vextent
(&args);
92
if
(error) {
93
XFS_BTREE_TRACE_CURSOR
(cur, XBT_ERROR);
94
return
error
;
95
}
96
if
(args.
fsbno
==
NULLFSBLOCK
) {
97
XFS_BTREE_TRACE_CURSOR
(cur, XBT_EXIT);
98
*stat = 0;
99
return
0;
100
}
101
ASSERT
(args.
len
== 1);
102
XFS_BTREE_TRACE_CURSOR
(cur, XBT_EXIT);
103
104
new
->s =
cpu_to_be32
(
XFS_FSB_TO_AGBNO
(args.
mp
, args.
fsbno
));
105
*stat = 1;
106
return
0;
107
}
108
109
STATIC
int
110
xfs_inobt_free_block
(
111
struct
xfs_btree_cur
*
cur
,
112
struct
xfs_buf
*bp)
113
{
114
xfs_fsblock_t
fsbno;
115
int
error
;
116
117
fsbno =
XFS_DADDR_TO_FSB
(cur->
bc_mp
,
XFS_BUF_ADDR
(bp));
118
error =
xfs_free_extent
(cur->
bc_tp
, fsbno, 1);
119
if
(error)
120
return
error
;
121
122
xfs_trans_binval
(cur->
bc_tp
, bp);
123
return
error
;
124
}
125
126
STATIC
int
127
xfs_inobt_get_maxrecs
(
128
struct
xfs_btree_cur
*
cur
,
129
int
level
)
130
{
131
return
cur->
bc_mp
->m_inobt_mxr[level != 0];
132
}
133
134
STATIC
void
135
xfs_inobt_init_key_from_rec
(
136
union
xfs_btree_key
*
key
,
137
union
xfs_btree_rec
*rec)
138
{
139
key->
inobt
.
ir_startino
= rec->
inobt
.
ir_startino
;
140
}
141
142
STATIC
void
143
xfs_inobt_init_rec_from_key
(
144
union
xfs_btree_key
*
key
,
145
union
xfs_btree_rec
*rec)
146
{
147
rec->
inobt
.
ir_startino
= key->
inobt
.
ir_startino
;
148
}
149
150
STATIC
void
151
xfs_inobt_init_rec_from_cur
(
152
struct
xfs_btree_cur
*
cur
,
153
union
xfs_btree_rec
*rec)
154
{
155
rec->
inobt
.
ir_startino
=
cpu_to_be32
(cur->
bc_rec
.
i
.
ir_startino
);
156
rec->
inobt
.
ir_freecount
=
cpu_to_be32
(cur->
bc_rec
.
i
.
ir_freecount
);
157
rec->
inobt
.
ir_free
=
cpu_to_be64
(cur->
bc_rec
.
i
.
ir_free
);
158
}
159
160
/*
161
* initial value of ptr for lookup
162
*/
163
STATIC
void
164
xfs_inobt_init_ptr_from_cur
(
165
struct
xfs_btree_cur
*
cur
,
166
union
xfs_btree_ptr
*
ptr
)
167
{
168
struct
xfs_agi
*agi =
XFS_BUF_TO_AGI
(cur->
bc_private
.
a
.agbp);
169
170
ASSERT
(cur->
bc_private
.
a
.agno ==
be32_to_cpu
(agi->
agi_seqno
));
171
172
ptr->
s
= agi->
agi_root
;
173
}
174
175
STATIC
__int64_t
176
xfs_inobt_key_diff
(
177
struct
xfs_btree_cur
*
cur
,
178
union
xfs_btree_key
*
key
)
179
{
180
return
(__int64_t)
be32_to_cpu
(key->
inobt
.
ir_startino
) -
181
cur->
bc_rec
.
i
.
ir_startino
;
182
}
183
184
#ifdef DEBUG
185
STATIC
int
186
xfs_inobt_keys_inorder(
187
struct
xfs_btree_cur
*
cur
,
188
union
xfs_btree_key
*
k1
,
189
union
xfs_btree_key
*k2)
190
{
191
return
be32_to_cpu
(k1->
inobt
.
ir_startino
) <
192
be32_to_cpu
(k2->
inobt
.
ir_startino
);
193
}
194
195
STATIC
int
196
xfs_inobt_recs_inorder(
197
struct
xfs_btree_cur
*
cur
,
198
union
xfs_btree_rec
*
r1
,
199
union
xfs_btree_rec
*
r2
)
200
{
201
return
be32_to_cpu
(r1->
inobt
.
ir_startino
) +
XFS_INODES_PER_CHUNK
<=
202
be32_to_cpu
(r2->
inobt
.
ir_startino
);
203
}
204
#endif
/* DEBUG */
205
206
static
const
struct
xfs_btree_ops
xfs_inobt_ops = {
207
.rec_len =
sizeof
(
xfs_inobt_rec_t
),
208
.
key_len
=
sizeof
(
xfs_inobt_key_t
),
209
210
.dup_cursor =
xfs_inobt_dup_cursor
,
211
.set_root =
xfs_inobt_set_root
,
212
.alloc_block =
xfs_inobt_alloc_block
,
213
.free_block =
xfs_inobt_free_block
,
214
.get_minrecs =
xfs_inobt_get_minrecs
,
215
.get_maxrecs =
xfs_inobt_get_maxrecs
,
216
.init_key_from_rec =
xfs_inobt_init_key_from_rec
,
217
.init_rec_from_key =
xfs_inobt_init_rec_from_key
,
218
.init_rec_from_cur =
xfs_inobt_init_rec_from_cur
,
219
.init_ptr_from_cur =
xfs_inobt_init_ptr_from_cur
,
220
.key_diff =
xfs_inobt_key_diff
,
221
#ifdef DEBUG
222
.keys_inorder = xfs_inobt_keys_inorder,
223
.recs_inorder = xfs_inobt_recs_inorder,
224
#endif
225
};
226
227
/*
228
* Allocate a new inode btree cursor.
229
*/
230
struct
xfs_btree_cur
*
/* new inode btree cursor */
231
xfs_inobt_init_cursor
(
232
struct
xfs_mount *
mp
,
/* file system mount point */
233
struct
xfs_trans *tp,
/* transaction pointer */
234
struct
xfs_buf
*
agbp
,
/* buffer for agi structure */
235
xfs_agnumber_t
agno
)
/* allocation group number */
236
{
237
struct
xfs_agi
*agi =
XFS_BUF_TO_AGI
(agbp);
238
struct
xfs_btree_cur
*
cur
;
239
240
cur =
kmem_zone_zalloc
(
xfs_btree_cur_zone
,
KM_SLEEP
);
241
242
cur->
bc_tp
= tp;
243
cur->
bc_mp
=
mp
;
244
cur->
bc_nlevels
=
be32_to_cpu
(agi->
agi_level
);
245
cur->
bc_btnum
=
XFS_BTNUM_INO
;
246
cur->
bc_blocklog
= mp->m_sb.sb_blocklog;
247
248
cur->
bc_ops
= &xfs_inobt_ops;
249
250
cur->
bc_private
.
a
.agbp =
agbp
;
251
cur->
bc_private
.
a
.agno =
agno
;
252
253
return
cur
;
254
}
255
256
/*
257
* Calculate number of records in an inobt btree block.
258
*/
259
int
260
xfs_inobt_maxrecs
(
261
struct
xfs_mount *
mp
,
262
int
blocklen,
263
int
leaf
)
264
{
265
blocklen -=
XFS_INOBT_BLOCK_LEN
(mp);
266
267
if
(leaf)
268
return
blocklen /
sizeof
(
xfs_inobt_rec_t
);
269
return
blocklen / (
sizeof
(
xfs_inobt_key_t
) +
sizeof
(
xfs_inobt_ptr_t
));
270
}
Generated on Thu Jan 10 2013 14:50:27 for Linux Kernel by
1.8.2