Back out r233646. Although it fixed most libgeom consumers under 32-bit

compatibility, it broke programs using devstat, under 32-bit compatibility and
not.

It's very difficult to fix the identifiers used by devstat, so this change is
simply being backed out.  Since changes to 3rd-party code seem likely, and may be
necessary to properly fix 32-bit binaries on 64-bit kernel, it would seem better
to make more invasive changes to fix GEOM's problems with 32-bit compatibility in
general.

The right thing to do is to replace all of the use of pointers as opaque
identifiers with a fixed-size (64-bit or even 32-bit should be enough for tracking
unique GEOM elments) field.  That probably maintains source compatibility with
most GEOM consumers, and allows xml2tree to make better assumptions about how to
decode the identifiers.

Submitted by:	Anton Yuzhaninov
This commit is contained in:
Juli Mallett 2012-04-10 17:37:24 +00:00
parent cb77f0da67
commit 019100de26
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=234107
2 changed files with 29 additions and 82 deletions

View File

@ -55,56 +55,9 @@ struct mystate {
int level;
struct sbuf *sbuf[20];
struct gconf *config;
unsigned nident;
int nident;
};
static void *
internalize_ident(struct mystate *mt, const char *element, const char *str)
{
struct gident *gip;
unsigned i;
if (mt->nident != 0 && mt->mesh->lg_ident == NULL) {
warn("Cannot continue due to previous memory exhaustion.");
return (NULL);
}
for (i = 0; i < mt->nident; i++) {
if (strcmp(mt->mesh->lg_ident[i].lg_id, str) != 0)
continue;
return ((void *)(uintptr_t)(i + 1));
}
i = mt->nident;
mt->nident++;
mt->mesh->lg_ident = reallocf(mt->mesh->lg_ident, (mt->nident + 1) * sizeof mt->mesh->lg_ident[0]);
if (mt->mesh->lg_ident == NULL) {
warn("Cannot allocate memory during processing of '%s' "
"element for identifier '%s'", element, str);
return (NULL);
}
gip = &mt->mesh->lg_ident[i];
gip->lg_id = strdup(str);
if (gip->lg_id == NULL) {
free(mt->mesh->lg_ident);
mt->mesh->lg_ident = NULL;
warn("Cannot allocate memory during processing of '%s' "
"element for identifier '%s'", element, str);
return (NULL);
}
gip->lg_ptr = NULL;
gip->lg_what = ISUNRESOLVED;
/* Terminator entry. */
gip = &mt->mesh->lg_ident[i + 1];
gip->lg_id = NULL;
gip->lg_ptr = NULL;
gip->lg_what = ISUNRESOLVED;
return ((void *)(uintptr_t)(i + 1));
}
static void
StartElement(void *userData, const char *name, const char **attr)
{
@ -120,9 +73,10 @@ StartElement(void *userData, const char *name, const char **attr)
ref = NULL;
for (i = 0; attr[i] != NULL; i += 2) {
if (!strcmp(attr[i], "id")) {
id = internalize_ident(mt, name, attr[i + 1]);
id = (void *)strtoul(attr[i + 1], NULL, 0);
mt->nident++;
} else if (!strcmp(attr[i], "ref")) {
ref = internalize_ident(mt, name, attr[i + 1]);
ref = (void *)strtoul(attr[i + 1], NULL, 0);
} else
printf("%*.*s[%s = %s]\n",
mt->level + 1, mt->level + 1, "",
@ -363,16 +317,11 @@ CharData(void *userData , const XML_Char *s , int len)
struct gident *
geom_lookupid(struct gmesh *gmp, const void *id)
{
unsigned i;
struct gident *gip;
if (gmp->lg_ident == NULL)
return (NULL);
for (i = 0; gmp->lg_ident[i].lg_id != NULL; i++) {
if (i + 1 != (unsigned)(uintptr_t)id)
continue;
return (&gmp->lg_ident[i]);
}
for (gip = gmp->lg_ident; gip->lg_id != NULL; gip++)
if (gip->lg_id == id)
return (gip);
return (NULL);
}
@ -385,7 +334,6 @@ geom_xml2tree(struct gmesh *gmp, char *p)
struct ggeom *ge;
struct gprovider *pr;
struct gconsumer *co;
struct gident *gip;
int i;
memset(gmp, 0, sizeof *gmp);
@ -408,30 +356,33 @@ geom_xml2tree(struct gmesh *gmp, char *p)
free(mt);
return (-1);
}
if (gmp->lg_ident == NULL && mt->nident != 0) {
free(mt);
return (ENOMEM);
}
gmp->lg_ident = calloc(sizeof *gmp->lg_ident, mt->nident + 1);
free(mt);
if (gmp->lg_ident == NULL)
return (ENOMEM);
i = 0;
/* Collect all identifiers */
LIST_FOREACH(cl, &gmp->lg_class, lg_class) {
gip = geom_lookupid(gmp, cl->lg_id);
gip->lg_ptr = cl;
gip->lg_what = ISCLASS;
gmp->lg_ident[i].lg_id = cl->lg_id;
gmp->lg_ident[i].lg_ptr = cl;
gmp->lg_ident[i].lg_what = ISCLASS;
i++;
LIST_FOREACH(ge, &cl->lg_geom, lg_geom) {
gip = geom_lookupid(gmp, ge->lg_id);
gip->lg_ptr = ge;
gip->lg_what = ISGEOM;
gmp->lg_ident[i].lg_id = ge->lg_id;
gmp->lg_ident[i].lg_ptr = ge;
gmp->lg_ident[i].lg_what = ISGEOM;
i++;
LIST_FOREACH(pr, &ge->lg_provider, lg_provider) {
gip = geom_lookupid(gmp, pr->lg_id);
gip->lg_ptr = pr;
gip->lg_what = ISPROVIDER;
gmp->lg_ident[i].lg_id = pr->lg_id;
gmp->lg_ident[i].lg_ptr = pr;
gmp->lg_ident[i].lg_what = ISPROVIDER;
i++;
}
LIST_FOREACH(co, &ge->lg_consumer, lg_consumer) {
gip = geom_lookupid(gmp, co->lg_id);
gip->lg_ptr = co;
gip->lg_what = ISCONSUMER;
gmp->lg_ident[i].lg_id = co->lg_id;
gmp->lg_ident[i].lg_ptr = co;
gmp->lg_ident[i].lg_what = ISCONSUMER;
i++;
}
}
}
@ -498,10 +449,7 @@ geom_deletetree(struct gmesh *gmp)
struct ggeom *ge;
struct gprovider *pr;
struct gconsumer *co;
unsigned i;
for (i = 0; gmp->lg_ident[i].lg_id != NULL; i++)
free(gmp->lg_ident[i].lg_id);
free(gmp->lg_ident);
gmp->lg_ident = NULL;
for (;;) {

View File

@ -71,8 +71,7 @@ struct gident {
enum { ISCLASS,
ISGEOM,
ISPROVIDER,
ISCONSUMER,
ISUNRESOLVED } lg_what;
ISCONSUMER } lg_what;
};
struct gmesh {