summaryrefslogtreecommitdiffstats
path: root/lib/libdisk/chunk.c
diff options
context:
space:
mode:
authornwhitehorn <nwhitehorn@FreeBSD.org>2012-12-30 16:28:06 +0000
committernwhitehorn <nwhitehorn@FreeBSD.org>2012-12-30 16:28:06 +0000
commit1e6b48e616e0254370d121cb6a306ec4ceaa9c96 (patch)
tree4e9bfc72c8e0bee428f0ece9ac3d080dcccd4b74 /lib/libdisk/chunk.c
parent7bc5e60204e1ef48719ba2e75231b6c7c314f228 (diff)
downloadFreeBSD-src-1e6b48e616e0254370d121cb6a306ec4ceaa9c96.zip
FreeBSD-src-1e6b48e616e0254370d121cb6a306ec4ceaa9c96.tar.gz
With the old sade removed, libdisk is no longer used by anything in HEAD
and uses a number of problematic pre-gpart interfaces. Since it has been entirely obsoleted by interfaces in geom, remove it.
Diffstat (limited to 'lib/libdisk/chunk.c')
-rw-r--r--lib/libdisk/chunk.c595
1 files changed, 0 insertions, 595 deletions
diff --git a/lib/libdisk/chunk.c b/lib/libdisk/chunk.c
deleted file mode 100644
index fb43ef5..0000000
--- a/lib/libdisk/chunk.c
+++ /dev/null
@@ -1,595 +0,0 @@
-/*
- * ----------------------------------------------------------------------------
- * "THE BEER-WARE LICENSE" (Revision 42):
- * <phk@FreeBSD.org> wrote this file. As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
- * ----------------------------------------------------------------------------
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/types.h>
-#include <sys/stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <err.h>
-#include "libdisk.h"
-
-struct chunk *
-New_Chunk(void)
-{
- struct chunk *c;
-
- c = malloc(sizeof *c);
- if (c != NULL)
- memset(c, 0, sizeof *c);
- return (c);
-}
-
-/* Is c2 completely inside c1 ? */
-
-static int
-Chunk_Inside(const struct chunk *c1, const struct chunk *c2)
-{
- /* if c1 ends before c2 do */
- if (c1->end < c2->end)
- return 0;
- /* if c1 starts after c2 do */
- if (c1->offset > c2->offset)
- return 0;
- return 1;
-}
-
-static struct chunk *
-Find_Mother_Chunk(struct chunk *chunks, daddr_t offset, daddr_t end,
- chunk_e type)
-{
- struct chunk *c1, *c2, ct;
-
- ct.offset = offset;
- ct.end = end;
- switch (type) {
- case whole:
- if (Chunk_Inside(chunks, &ct))
- return chunks;
- case extended:
- for (c1 = chunks->part; c1; c1 = c1->next) {
- if (c1->type != type)
- continue;
- if (Chunk_Inside(c1, &ct))
- return c1;
- }
- return 0;
- case freebsd:
- for (c1 = chunks->part; c1; c1 = c1->next) {
- if (c1->type == type)
- if (Chunk_Inside(c1, &ct))
- return c1;
- if (c1->type != extended)
- continue;
- for (c2 = c1->part; c2; c2 = c2->next)
- if (c2->type == type && Chunk_Inside(c2, &ct))
- return c2;
- }
- return 0;
-#ifdef __powerpc__
- case apple:
- for (c1 = chunks->part; c1; c1 = c1->next) {
- if (c1->type == type)
- if (Chunk_Inside(c1, &ct))
- return c1;
- }
- return 0;
-#endif
- default:
- warn("Unsupported mother type in Find_Mother_Chunk");
- return 0;
- }
-}
-
-void
-Free_Chunk(struct chunk *c1)
-{
- if(c1 == NULL)
- return;
- if(c1->private_data && c1->private_free)
- (*c1->private_free)(c1->private_data);
- if(c1->part != NULL)
- Free_Chunk(c1->part);
- if(c1->next != NULL)
- Free_Chunk(c1->next);
- if (c1->name != NULL)
- free(c1->name);
- if (c1->sname != NULL)
- free(c1->sname);
- free(c1);
-}
-
-struct chunk *
-Clone_Chunk(const struct chunk *c1)
-{
- struct chunk *c2;
-
- if(!c1)
- return NULL;
- c2 = New_Chunk();
- if (c2 == NULL)
- return NULL;
- *c2 = *c1;
- if (c1->private_data && c1->private_clone)
- c2->private_data = c2->private_clone(c2->private_data);
- c2->name = strdup(c2->name);
- if (c2->sname != NULL)
- c2->sname = strdup(c2->sname);
- c2->next = Clone_Chunk(c2->next);
- c2->part = Clone_Chunk(c2->part);
- return c2;
-}
-
-int
-Insert_Chunk(struct chunk *c2, daddr_t offset, daddr_t size, const char *name,
- chunk_e type, int subtype, u_long flags, const char *sname)
-{
- struct chunk *ct,*cs;
-
- /* We will only insert into empty spaces */
- if (c2->type != unused)
- return __LINE__;
-
- ct = New_Chunk();
- if (ct == NULL)
- return __LINE__;
- ct->disk = c2->disk;
- ct->offset = offset;
- ct->size = size;
- ct->end = offset + size - 1;
- ct->type = type;
- if (sname != NULL)
- ct->sname = strdup(sname);
- ct->name = strdup(name);
- ct->subtype = subtype;
- ct->flags = flags;
-
- if (!Chunk_Inside(c2, ct)) {
- Free_Chunk(ct);
- return __LINE__;
- }
-
- if ((type == freebsd || type == extended || type == apple)) {
- cs = New_Chunk();
- if (cs == NULL)
- return __LINE__;
- cs->disk = c2->disk;
- cs->offset = offset;
- cs->size = size;
- cs->end = offset + size - 1;
- cs->type = unused;
- if (sname != NULL)
- cs->sname = strdup(sname);
- cs->name = strdup("-");
- ct->part = cs;
- }
-
- /* Make a new chunk for any trailing unused space */
- if (c2->end > ct->end) {
- cs = New_Chunk();
- if (cs == NULL)
- return __LINE__;
- *cs = *c2;
- cs->disk = c2->disk;
- cs->offset = ct->end + 1;
- cs->size = c2->end - ct->end;
- if (c2->sname != NULL)
- cs->sname = strdup(c2->sname);
- if (c2->name)
- cs->name = strdup(c2->name);
- c2->next = cs;
- c2->size -= c2->end - ct->end;
- c2->end = ct->end;
- }
- /* If no leading unused space just occupy the old chunk */
- if (c2->offset == ct->offset) {
- c2->sname = ct->sname;
- c2->name = ct->name;
- c2->type = ct->type;
- c2->part = ct->part;
- c2->subtype = ct->subtype;
- c2->flags = ct->flags;
- ct->sname = NULL;
- ct->name = NULL;
- ct->part = 0;
- Free_Chunk(ct);
- return 0;
- }
- /* else insert new chunk and adjust old one */
- c2->end = ct->offset - 1;
- c2->size -= ct->size;
- ct->next = c2->next;
- c2->next = ct;
- return 0;
-}
-
-int
-Add_Chunk(struct disk *d, daddr_t offset, daddr_t size, const char *name,
- chunk_e type, int subtype, u_long flags, const char *sname)
-{
- struct chunk *c1, *c2, ct;
- daddr_t end = offset + size - 1;
- ct.offset = offset;
- ct.end = end;
- ct.size = size;
-
- if (type == whole) {
- d->chunks = c1 = New_Chunk();
- if (c1 == NULL)
- return __LINE__;
- c2 = c1->part = New_Chunk();
- if (c2 == NULL)
- return __LINE__;
- c2->disk = c1->disk = d;
- c2->offset = c1->offset = offset;
- c2->size = c1->size = size;
- c2->end = c1->end = end;
- c1->sname = strdup(sname);
- c2->sname = strdup("-");
- c1->name = strdup(name);
- c2->name = strdup("-");
- c1->type = type;
- c2->type = unused;
- c1->flags = flags;
- c1->subtype = subtype;
- return 0;
- }
-
- c1 = 0;
- /* PLATFORM POLICY BEGIN ------------------------------------- */
- switch(platform) {
- case p_i386:
- case p_amd64:
- switch (type) {
- case fat:
- case gpt:
- case mbr:
- case extended:
- case freebsd:
- c1 = Find_Mother_Chunk(d->chunks, offset, end, whole);
- break;
- case part:
- c1 = Find_Mother_Chunk(d->chunks, offset, end, freebsd);
- break;
- default:
- return(-1);
- }
- break;
- case p_ia64:
- switch (type) {
- case freebsd:
- subtype = 0xa5;
- /* FALL THROUGH */
- case fat:
- case efi:
- case mbr:
- c1 = Find_Mother_Chunk(d->chunks, offset, end, whole);
- break;
- case part:
- c1 = Find_Mother_Chunk(d->chunks, offset, end,
- freebsd);
- if (!c1)
- c1 = Find_Mother_Chunk(d->chunks, offset, end,
- whole);
- break;
- default:
- return (-1);
- }
- break;
- case p_pc98:
- switch (type) {
- case fat:
- case pc98:
- case freebsd:
- c1 = Find_Mother_Chunk(d->chunks, offset, end, whole);
- break;
- case part:
- c1 = Find_Mother_Chunk(d->chunks, offset, end, freebsd);
- break;
- default:
- return(-1);
- }
- break;
- case p_sparc64:
- case p_alpha:
- switch (type) {
- case freebsd:
- c1 = Find_Mother_Chunk(d->chunks, offset, end, whole);
- break;
- case part:
- c1 = Find_Mother_Chunk(d->chunks, offset, end, freebsd);
- break;
- default:
- return(-1);
- }
- break;
- case p_ppc:
- switch (type) {
- case apple:
- c1 = Find_Mother_Chunk(d->chunks, offset, end, whole);
- break;
- case part:
- c1 = Find_Mother_Chunk(d->chunks, offset, end, apple);
- break;
- default:
- return (-1);
- }
- break;
- default:
- return (-1);
- }
- /* PLATFORM POLICY END ---------------------------------------- */
-
- if(!c1)
- return __LINE__;
- for(c2 = c1->part; c2; c2 = c2->next) {
- if (c2->type != unused)
- continue;
- if(!Chunk_Inside(c2, &ct))
- continue;
-/* PLATFORM POLICY BEGIN ------------------------------------- */
- if (platform == p_sparc64) {
- offset = Prev_Cyl_Aligned(d, offset);
- size = Next_Cyl_Aligned(d, size);
- } else if (platform == p_i386 || platform == p_pc98 ||
- platform == p_amd64) {
- if (type != freebsd)
- break;
- if (!(flags & CHUNK_ALIGN))
- break;
- if (offset == d->chunks->offset &&
- end == d->chunks->end)
- break;
-
- /* Round down to prev cylinder */
- offset = Prev_Cyl_Aligned(d,offset);
- /* Stay inside the parent */
- if (offset < c2->offset)
- offset = c2->offset;
- /* Round up to next cylinder */
- offset = Next_Cyl_Aligned(d, offset);
- /* Keep one track clear in front of parent */
- if (offset == c1->offset)
- offset = Next_Track_Aligned(d, offset + 1);
- /* Work on the (end+1) */
- size += offset;
- /* Round up to cylinder */
- size = Next_Cyl_Aligned(d, size);
- /* Stay inside parent */
- if ((size-1) > c2->end)
- size = c2->end + 1;
- /* Round down to cylinder */
- size = Prev_Cyl_Aligned(d, size);
-
- /* Convert back to size */
- size -= offset;
- }
- break;
-
-/* PLATFORM POLICY END ------------------------------------- */
- }
- if (c2 == NULL)
- return (__LINE__);
- return Insert_Chunk(c2, offset, size, name, type, subtype, flags,
- sname);
-}
-
-char *
-ShowChunkFlags(struct chunk *c)
-{
- static char ret[10];
- int i = 0;
-
- if (c->flags & CHUNK_ACTIVE)
- ret[i++] = 'A';
- if (c->flags & CHUNK_ALIGN)
- ret[i++] = '=';
- if (c->flags & CHUNK_IS_ROOT)
- ret[i++] = 'R';
- ret[i++] = '\0';
-
- return ret;
-}
-
-static void
-Print_Chunk(struct chunk *c1, int offset)
-{
- int i;
-
- if (!c1)
- return;
- for (i = 0; i < offset - 2; i++)
- putchar(' ');
- for (; i < offset; i++)
- putchar('-');
- putchar('>');
- for (; i < 10; i++)
- putchar(' ');
-#ifndef __ia64__
- printf("%p ", c1);
-#endif
- printf("%8jd %8jd %8jd %-8s %-16s %-8s 0x%02x %s",
- (intmax_t)c1->offset, (intmax_t)c1->size, (intmax_t)c1->end,
- c1->name, c1->sname, chunk_name(c1->type), c1->subtype,
- ShowChunkFlags(c1));
- putchar('\n');
- Print_Chunk(c1->part, offset + 2);
- Print_Chunk(c1->next, offset);
-}
-
-void
-Debug_Chunk(struct chunk *c1)
-{
-
- Print_Chunk(c1, 2);
-}
-
-int
-Delete_Chunk(struct disk *d, struct chunk *c)
-{
-
- return (Delete_Chunk2(d, c, 0));
-}
-
-int
-Delete_Chunk2(struct disk *d, struct chunk *c, int rflags)
-{
- struct chunk *c1, *c2, *c3;
- daddr_t offset = c->offset;
-
- switch (c->type) {
- case whole:
- case unused:
- return 1;
- case extended:
- c1 = Find_Mother_Chunk(d->chunks, c->offset, c->end, whole);
- break;
- case part:
- c1 = Find_Mother_Chunk(d->chunks, c->offset, c->end, freebsd);
-#ifdef __ia64__
- if (c1 == NULL)
- c1 = Find_Mother_Chunk(d->chunks, c->offset, c->end,
- whole);
-#endif
-#ifdef __powerpc__
- if (c1 == NULL)
- c1 = Find_Mother_Chunk(d->chunks, c->offset, c->end,
- apple);
-#endif
- break;
- default:
- c1 = Find_Mother_Chunk(d->chunks, c->offset, c->end, extended);
- if (c1 == NULL)
- c1 = Find_Mother_Chunk(d->chunks, c->offset, c->end,
- whole);
- break;
- }
- if (c1 == NULL)
- return 1;
- for (c2 = c1->part; c2; c2 = c2->next) {
- if (c2 == c) {
- c2->type = unused;
- c2->subtype = 0;
- c2->flags = 0;
- if (c2->sname != NULL)
- free(c2->sname);
- c2->sname = strdup("-");
- free(c2->name);
- c2->name = strdup("-");
- Free_Chunk(c2->part);
- c2->part =0;
- goto scan;
- }
- }
- return 1;
-scan:
- /*
- * Collapse multiple unused elements together, and attempt
- * to extend the previous chunk into the freed chunk.
- *
- * We only extend non-unused elements which are marked
- * for newfs (we can't extend working filesystems), and
- * only if we are called with DELCHUNK_RECOVER.
- */
- for (c2 = c1->part; c2; c2 = c2->next) {
- if (c2->type != unused) {
- if (c2->offset + c2->size != offset ||
- (rflags & DELCHUNK_RECOVER) == 0 ||
- (c2->flags & CHUNK_NEWFS) == 0) {
- continue;
- }
- /* else extend into free area */
- }
- if (!c2->next)
- continue;
- if (c2->next->type != unused)
- continue;
- c3 = c2->next;
- c2->size += c3->size;
- c2->end = c3->end;
- c2->next = c3->next;
- c3->next = 0;
- Free_Chunk(c3);
- goto scan;
- }
- Fixup_Names(d);
- return 0;
-}
-
-#if 0
-int
-Collapse_Chunk(struct disk *d, struct chunk *c1)
-{
- struct chunk *c2, *c3;
-
- if (c1->next && Collapse_Chunk(d, c1->next))
- return 1;
-
- if (c1->type == unused && c1->next && c1->next->type == unused) {
- c3 = c1->next;
- c1->size += c3->size;
- c1->end = c3->end;
- c1->next = c3->next;
- c3->next = 0;
- Free_Chunk(c3);
- return 1;
- }
- c3 = c1->part;
- if (!c3)
- return 0;
- if (Collapse_Chunk(d, c1->part))
- return 1;
-
- if (c1->type == whole)
- return 0;
-
- if (c3->type == unused && c3->size == c1->size) {
- Delete_Chunk(d, c1);
- return 1;
- }
- if (c3->type == unused) {
- c2 = New_Chunk();
- if (c2 == NULL)
- barfout(1, "malloc failed");
- *c2 = *c1;
- c1->next = c2;
- c1->disk = d;
- c1->sname = strdup("-");
- c1->name = strdup("-");
- c1->part = 0;
- c1->type = unused;
- c1->flags = 0;
- c1->subtype = 0;
- c1->size = c3->size;
- c1->end = c3->end;
- c2->offset += c1->size;
- c2->size -= c1->size;
- c2->part = c3->next;
- c3->next = 0;
- Free_Chunk(c3);
- return 1;
- }
- for (c2 = c3; c2->next; c2 = c2->next)
- c3 = c2;
- if (c2 && c2->type == unused) {
- c3->next = 0;
- c2->next = c1->next;
- c1->next = c2;
- c1->size -= c2->size;
- c1->end -= c2->size;
- return 1;
- }
-
- return 0;
-}
-#endif
OpenPOWER on IntegriCloud