2 * Copyright (c) 2002 Marcel Moolenaar
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 * $FreeBSD: src/sbin/gpt/map.c,v 1.6 2005/08/31 01:47:19 marcel Exp $
27 * $DragonFly: src/sbin/gpt/map.c,v 1.2 2007/06/17 08:34:59 dillon Exp $
30 #include <sys/types.h>
39 static map_t
*mediamap
;
42 mkmap(off_t start
, off_t size
, int type
)
46 m
= malloc(sizeof(*m
));
51 m
->map_next
= m
->map_prev
= NULL
;
53 m
->map_index
= NOENTRY
;
59 map_add(off_t start
, off_t size
, int type
, void *data
)
64 while (n
!= NULL
&& n
->map_start
+ n
->map_size
<= start
)
69 if (n
->map_start
+ n
->map_size
< start
+ size
) {
70 warnx("error: bogus map");
74 if (n
->map_start
== start
&& n
->map_size
== size
) {
75 if (n
->map_type
!= MAP_TYPE_UNUSED
) {
76 if (n
->map_type
!= MAP_TYPE_MBR_PART
||
77 type
!= MAP_TYPE_GPT_PART
) {
78 warnx("warning: partition(%llu,%llu) mirrored",
79 (long long)start
, (long long)size
);
87 if (n
->map_type
!= MAP_TYPE_UNUSED
) {
88 if (n
->map_type
!= MAP_TYPE_MBR_PART
||
89 type
!= MAP_TYPE_GPT_PART
) {
90 warnx("error: bogus map");
93 n
->map_type
= MAP_TYPE_UNUSED
;
96 m
= mkmap(start
, size
, type
);
102 if (start
== n
->map_start
) {
103 m
->map_prev
= n
->map_prev
;
105 if (m
->map_prev
!= NULL
)
106 m
->map_prev
->map_next
= m
;
110 n
->map_start
+= size
;
112 } else if (start
+ size
== n
->map_start
+ n
->map_size
) {
114 m
->map_next
= p
->map_next
;
116 if (m
->map_next
!= NULL
)
117 m
->map_next
->map_prev
= m
;
121 p
= mkmap(n
->map_start
, start
- n
->map_start
, n
->map_type
);
122 n
->map_start
+= p
->map_size
+ m
->map_size
;
123 n
->map_size
-= (p
->map_size
+ m
->map_size
);
124 p
->map_prev
= n
->map_prev
;
129 if (p
->map_prev
!= NULL
)
130 p
->map_prev
->map_next
= p
;
139 map_alloc(off_t start
, off_t size
)
144 for (m
= mediamap
; m
!= NULL
; m
= m
->map_next
) {
145 if (m
->map_type
!= MAP_TYPE_UNUSED
|| m
->map_start
< 2)
147 if (start
!= 0 && m
->map_start
> start
)
149 delta
= (start
!= 0) ? start
- m
->map_start
: 0;
150 if (size
== 0 || m
->map_size
- delta
>= size
) {
151 if (m
->map_size
- delta
<= 0)
154 size
= m
->map_size
- delta
;
155 return (map_add(m
->map_start
+ delta
, size
,
156 MAP_TYPE_GPT_PART
, NULL
));
169 while (m
!= NULL
&& m
->map_type
!= type
)
186 while (m
!= NULL
&& m
->map_next
!= NULL
)
192 map_free(off_t start
, off_t size
)
198 while (m
!= NULL
&& m
->map_start
+ m
->map_size
<= start
)
200 if (m
== NULL
|| m
->map_type
!= MAP_TYPE_UNUSED
)
203 return ((m
->map_start
+ m
->map_size
>= start
+ size
) ? 1 : 0);
204 return (m
->map_size
- (start
- m
->map_start
));
212 mediamap
= mkmap(0LL, size
, MAP_TYPE_UNUSED
);
213 lbawidth
= sprintf(buf
, "%llu", (long long)size
);