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.
27 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD: src/sbin/gpt/map.c,v 1.6 2005/08/31 01:47:19 marcel Exp $");
35 #include <sys/types.h>
44 static map_t
*mediamap
;
47 mkmap(off_t start
, off_t size
, int type
)
51 m
= malloc(sizeof(*m
));
56 m
->map_next
= m
->map_prev
= NULL
;
64 map_add(off_t start
, off_t size
, int type
, void *data
)
69 while (n
!= NULL
&& n
->map_start
+ n
->map_size
<= start
)
74 if (n
->map_start
+ n
->map_size
< start
+ size
) {
75 warnx("error: bogus map");
79 if (n
->map_start
== start
&& n
->map_size
== size
) {
80 if (n
->map_type
!= MAP_TYPE_UNUSED
) {
81 if (n
->map_type
!= MAP_TYPE_MBR_PART
||
82 type
!= MAP_TYPE_GPT_PART
) {
83 warnx("warning: partition(%llu,%llu) mirrored",
84 (long long)start
, (long long)size
);
92 if (n
->map_type
!= MAP_TYPE_UNUSED
) {
93 if (n
->map_type
!= MAP_TYPE_MBR_PART
||
94 type
!= MAP_TYPE_GPT_PART
) {
95 warnx("error: bogus map");
98 n
->map_type
= MAP_TYPE_UNUSED
;
101 m
= mkmap(start
, size
, type
);
107 if (start
== n
->map_start
) {
108 m
->map_prev
= n
->map_prev
;
110 if (m
->map_prev
!= NULL
)
111 m
->map_prev
->map_next
= m
;
115 n
->map_start
+= size
;
117 } else if (start
+ size
== n
->map_start
+ n
->map_size
) {
119 m
->map_next
= p
->map_next
;
121 if (m
->map_next
!= NULL
)
122 m
->map_next
->map_prev
= m
;
126 p
= mkmap(n
->map_start
, start
- n
->map_start
, n
->map_type
);
127 n
->map_start
+= p
->map_size
+ m
->map_size
;
128 n
->map_size
-= (p
->map_size
+ m
->map_size
);
129 p
->map_prev
= n
->map_prev
;
134 if (p
->map_prev
!= NULL
)
135 p
->map_prev
->map_next
= p
;
144 map_alloc(off_t start
, off_t size
)
149 for (m
= mediamap
; m
!= NULL
; m
= m
->map_next
) {
150 if (m
->map_type
!= MAP_TYPE_UNUSED
|| m
->map_start
< 2)
152 if (start
!= 0 && m
->map_start
> start
)
154 delta
= (start
!= 0) ? start
- m
->map_start
: 0;
155 if (size
== 0 || m
->map_size
- delta
>= size
) {
156 if (m
->map_size
- delta
<= 0)
159 size
= m
->map_size
- delta
;
160 return (map_add(m
->map_start
+ delta
, size
,
161 MAP_TYPE_GPT_PART
, NULL
));
174 while (m
!= NULL
&& m
->map_type
!= type
)
191 while (m
!= NULL
&& m
->map_next
!= NULL
)
197 map_free(off_t start
, off_t size
)
203 while (m
!= NULL
&& m
->map_start
+ m
->map_size
<= start
)
205 if (m
== NULL
|| m
->map_type
!= MAP_TYPE_UNUSED
)
208 return ((m
->map_start
+ m
->map_size
>= start
+ size
) ? 1 : 0);
209 return (m
->map_size
- (start
- m
->map_start
));
217 mediamap
= mkmap(0LL, size
, MAP_TYPE_UNUSED
);
218 lbawidth
= sprintf(buf
, "%llu", (long long)size
);