1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-22 17:35:59 +03:00
lvm2/lib/label/label.c

155 lines
2.5 KiB
C
Raw Normal View History

/*
2002-01-10 21:12:26 +03:00
* Copyright (C) 2002 Sistina Software
*
* This file is released under the LGPL.
*/
#include "label.h"
#include "list.h"
#include "dbg_malloc.h"
#include "log.h"
/*
* Internal labeller struct.
*/
struct labeller_i {
struct list list;
struct labeller *l;
char name[0];
};
static struct list _labellers;
static struct labeller_i *_alloc_li(const char *name, struct labeller *l)
{
struct labeller_i *li;
size_t len;
len = sizeof(*li) + strlen(name) + 1;
if (!(li = dbg_malloc(len))) {
log_error("Couldn't allocate memory for labeller list object.");
return NULL;
}
li->l = l;
strcpy(li->name, name);
return li;
2001-12-12 12:05:44 +03:00
}
2002-01-11 13:43:32 +03:00
static void _free_li(struct labeller_i *li)
2001-12-12 12:05:44 +03:00
{
dbg_free(li);
}
int label_init(void)
{
list_init(&_labellers);
return 1;
}
void label_exit(void)
{
struct list *c, *n;
2002-01-11 13:43:32 +03:00
struct labeller_i *li;
for (c = _labellers.n; c != &_labellers; c = n) {
n = c->n;
2002-01-11 13:43:32 +03:00
li = list_item(c, struct labeller_i);
_free_li(li);
}
}
int label_register_handler(const char *name, struct labeller *handler)
{
struct labeller_i *li;
if (!(li = _alloc_li(name, handler))) {
stack;
return 0;
}
list_add(&_labellers, &li->list);
return 1;
}
struct labeller *label_get_handler(const char *name)
{
struct list *lih;
struct labeller_i *li;
list_iterate (lih, &_labellers) {
li = list_item(lih, struct labeller_i);
if (!strcmp(li->name, name))
return li->l;
}
return NULL;
}
2002-01-11 13:43:32 +03:00
static struct labeller *_find_labeller(struct device *dev)
{
struct list *lih;
struct labeller_i *li;
list_iterate (lih, &_labellers) {
li = list_item(lih, struct labeller_i);
2002-01-11 13:43:32 +03:00
if (li->l->ops->can_handle(li->l, dev))
return li->l;
}
log_debug("No label on device '%s'.", dev_name(dev));
return NULL;
}
2002-01-11 13:43:32 +03:00
int label_remove(struct device *dev)
{
struct labeller *l;
2002-01-11 13:43:32 +03:00
if (!(l = _find_labeller(dev))) {
stack;
return 0;
}
2002-01-11 13:43:32 +03:00
return l->ops->remove(l, dev);
}
2002-01-11 13:43:32 +03:00
int label_read(struct device *dev, struct label **result)
{
int r;
struct list *lih;
struct labeller_i *li;
list_iterate (lih, &_labellers) {
li = list_item(lih, struct labeller_i);
if ((r = li->l->ops->read(li->l, dev, result))) {
(*result)->labeller = li->l;
return r;
}
}
log_debug("No label on device '%s'.", dev_name(dev));
return 0;
}
2002-01-11 13:43:32 +03:00
int label_verify(struct device *dev)
{
struct labeller *l;
2002-01-11 13:43:32 +03:00
if (!(l = _find_labeller(dev))) {
stack;
return 0;
}
2002-01-11 13:43:32 +03:00
return l->ops->verify(l, dev);
}
void label_destroy(struct label *lab)
{
lab->labeller->ops->destroy_label(lab->labeller, lab);
}