version 1.2.42.1, 2014/05/22 11:37:28 |
version 1.3, 2013/10/26 20:31:23 |
Line 141 map_add(off_t start, off_t size, int typ |
|
Line 141 map_add(off_t start, off_t size, int typ |
|
} |
} |
|
|
map_t * |
map_t * |
map_alloc(off_t start, off_t size, off_t alignment) |
map_alloc(off_t start, off_t size) |
{ |
{ |
off_t delta; |
off_t delta; |
map_t *m; |
map_t *m; |
|
|
if (alignment > 0) { |
|
if ((start % alignment) != 0) |
|
start = (start + alignment) / alignment * alignment; |
|
if ((size % alignment) != 0) |
|
size = (size + alignment) / alignment * alignment; |
|
} |
|
|
|
for (m = mediamap; m != NULL; m = m->map_next) { |
for (m = mediamap; m != NULL; m = m->map_next) { |
if (m->map_type != MAP_TYPE_UNUSED || m->map_start < 2) |
if (m->map_type != MAP_TYPE_UNUSED || m->map_start < 2) |
continue; |
continue; |
if (start != 0 && m->map_start > start) |
if (start != 0 && m->map_start > start) |
return (NULL); |
return (NULL); |
|
delta = (start != 0) ? start - m->map_start : 0; |
if (start != 0) |
if (size == 0 || m->map_size - delta >= size) { |
delta = start - m->map_start; |
if (m->map_size - delta <= 0) |
else if (alignment > 0 && m->map_start % alignment != 0) |
|
delta = (m->map_start + alignment) / |
|
alignment * alignment - m->map_start; |
|
else |
|
delta = 0; |
|
|
|
if (size == 0 || m->map_size - delta >= size) { |
|
if (m->map_size - delta < alignment) |
|
continue; |
continue; |
if (size == 0) { |
if (size == 0) |
if (alignment > 0 && |
size = m->map_size - delta; |
(m->map_size - delta) % alignment != 0) |
return (map_add(m->map_start + delta, size, |
size = (m->map_size - delta) / |
MAP_TYPE_GPT_PART, NULL)); |
alignment * alignment; |
|
else |
|
size = m->map_size - delta; |
|
} |
|
return map_add(m->map_start + delta, size, |
|
MAP_TYPE_GPT_PART, NULL); |
|
} |
} |
} |
} |
|
|
return NULL; |
return (NULL); |
} |
|
|
|
off_t |
|
map_resize(map_t *m, off_t size, off_t alignment) |
|
{ |
|
map_t *n, *o; |
|
off_t alignsize, prevsize; |
|
|
|
n = m->map_next; |
|
|
|
if (size < 0 || alignment < 0) { |
|
warnx("negative size or alignment"); |
|
return 0; |
|
} |
|
if (size == 0 && alignment == 0) { |
|
if (n == NULL || n->map_type != MAP_TYPE_UNUSED) |
|
return 0; |
|
else { |
|
size = m->map_size + n->map_size; |
|
m->map_size = size; |
|
m->map_next = n->map_next; |
|
if (n->map_next != NULL) |
|
n->map_next->map_prev = m; |
|
if (n->map_data != NULL) |
|
free(n->map_data); |
|
free(n); |
|
return size; |
|
} |
|
} |
|
|
|
if (size == 0 && alignment > 0) { |
|
if (n == NULL || n->map_type != MAP_TYPE_UNUSED) |
|
return 0; |
|
else { |
|
prevsize = m->map_size; |
|
size = (m->map_size + n->map_size) / |
|
alignment * alignment; |
|
if (size <= prevsize) |
|
return 0; |
|
m->map_size = size; |
|
n->map_start += size - prevsize; |
|
n->map_size -= size - prevsize; |
|
if (n->map_size == 0) { |
|
m->map_next = n->map_next; |
|
if (n->map_next != NULL) |
|
n->map_next->map_prev = m; |
|
if (n->map_data != NULL) |
|
free(n->map_data); |
|
free(n); |
|
} |
|
return size; |
|
} |
|
} |
|
|
|
alignsize = size; |
|
if (alignment % size != 0) |
|
alignsize = (size + alignment) / alignment * alignment; |
|
|
|
if (alignsize < m->map_size) { /* shrinking */ |
|
prevsize = m->map_size; |
|
m->map_size = alignsize; |
|
if (n == NULL || n->map_type != MAP_TYPE_UNUSED) { |
|
o = mkmap(m->map_start + alignsize, |
|
prevsize - alignsize, MAP_TYPE_UNUSED); |
|
m->map_next = o; |
|
o->map_prev = m; |
|
o->map_next = n; |
|
if (n != NULL) |
|
n->map_prev = o; |
|
return alignsize; |
|
} else { |
|
n->map_start -= alignsize; |
|
n->map_size += alignsize; |
|
return alignsize; |
|
} |
|
} else if (alignsize > m->map_size) { /* expanding */ |
|
if (n == NULL || n->map_type != MAP_TYPE_UNUSED || |
|
n->map_size < alignsize - m->map_size) { |
|
return 0; |
|
} |
|
n->map_size -= alignsize - m->map_size; |
|
n->map_start += alignsize - m->map_size; |
|
if (n->map_size == 0) { |
|
m->map_next = n->map_next; |
|
if (n->map_next != NULL) |
|
n->map_next->map_prev = m; |
|
if (n->map_data != NULL) |
|
free(n->map_data); |
|
free(n); |
|
} |
|
m->map_size = alignsize; |
|
return alignsize; |
|
} else /* correct size */ |
|
return alignsize; |
|
} |
} |
|
|
map_t * |
map_t * |