libfdisk: cleanup parttype API
* add reference counting * add functions to set allocated types Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
parent
0123bd1a87
commit
dfc6db2a35
|
@ -725,7 +725,7 @@ static int command_parttype(struct sfdisk *sf, int argc, char **argv)
|
|||
else if (fdisk_set_partition_type(sf->cxt, partno - 1, type) != 0)
|
||||
errx(EXIT_FAILURE, _("%s: partition %zu: failed to set partition type"),
|
||||
devname, partno);
|
||||
fdisk_free_parttype(type);
|
||||
fdisk_unref_parttype(type);
|
||||
return write_changes(sf);
|
||||
}
|
||||
|
||||
|
|
|
@ -1165,7 +1165,7 @@ static int add_partition(struct fdisk_context *cxt, size_t n,
|
|||
struct fdisk_parttype *t =
|
||||
fdisk_label_get_parttype_from_code(cxt->label, sys);
|
||||
fdisk_info_new_partition(cxt, n + 1, start, stop, t);
|
||||
fdisk_free_parttype(t);
|
||||
fdisk_unref_parttype(t);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -96,10 +96,11 @@ struct fdisk_iter {
|
|||
*/
|
||||
struct fdisk_parttype {
|
||||
unsigned int code; /* type as number or zero */
|
||||
const char *name; /* description */
|
||||
char *name; /* description */
|
||||
char *typestr; /* type as string or NULL */
|
||||
|
||||
unsigned int flags; /* FDISK_PARTTYPE_* flags */
|
||||
int refcount; /* reference counter for allocated types */
|
||||
};
|
||||
|
||||
enum {
|
||||
|
|
|
@ -2093,7 +2093,7 @@ static int gpt_add_partition(
|
|||
|
||||
t = gpt_partition_parttype(cxt, &ents[partnum]);
|
||||
fdisk_info_new_partition(cxt, partnum + 1, user_f, user_l, t);
|
||||
fdisk_free_parttype(t);
|
||||
fdisk_unref_parttype(t);
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
|
|
|
@ -137,26 +137,27 @@ sector_t fdisk_get_geom_cylinders(struct fdisk_context *cxt);
|
|||
|
||||
|
||||
/* parttype.c */
|
||||
const struct fdisk_parttype *fdisk_label_get_parttype(const struct fdisk_label *lb, size_t n);
|
||||
struct fdisk_parttype *fdisk_new_parttype(void);
|
||||
void fdisk_ref_parttype(struct fdisk_parttype *t);
|
||||
void fdisk_unref_parttype(struct fdisk_parttype *t);
|
||||
int fdisk_parttype_set_name(struct fdisk_parttype *t, const char *str);
|
||||
int fdisk_parttype_set_typestr(struct fdisk_parttype *t, const char *str);
|
||||
int fdisk_parttype_set_code(struct fdisk_parttype *t, int code);
|
||||
size_t fdisk_label_get_nparttypes(const struct fdisk_label *lb);
|
||||
|
||||
struct fdisk_parttype *fdisk_label_get_parttype(const struct fdisk_label *lb, size_t n);
|
||||
int fdisk_label_has_code_parttypes(const struct fdisk_label *lb);
|
||||
struct fdisk_parttype *fdisk_label_get_parttype_from_code(
|
||||
const struct fdisk_label *lb,
|
||||
unsigned int code);
|
||||
|
||||
struct fdisk_parttype *fdisk_label_get_parttype_from_string(
|
||||
const struct fdisk_label *lb,
|
||||
const char *str);
|
||||
struct fdisk_parttype *fdisk_new_unknown_parttype(unsigned int code,
|
||||
const char *typestr);
|
||||
struct fdisk_parttype *fdisk_copy_parttype(const struct fdisk_parttype *type);
|
||||
struct fdisk_parttype *fdisk_label_parse_parttype(
|
||||
const struct fdisk_label *lb,
|
||||
const char *str);
|
||||
|
||||
struct fdisk_parttype *fdisk_copy_parttype(const struct fdisk_parttype *type);
|
||||
void fdisk_free_parttype(struct fdisk_parttype *t); /* TODO: use refcount */
|
||||
|
||||
const char *fdisk_parttype_get_string(const struct fdisk_parttype *t);
|
||||
unsigned int fdisk_parttype_get_code(const struct fdisk_parttype *t);
|
||||
const char *fdisk_parttype_get_name(const struct fdisk_parttype *t);
|
||||
|
@ -271,8 +272,8 @@ int fdisk_partition_cmp_partno(struct fdisk_partition *a,
|
|||
int fdisk_partition_partno_follow_default(struct fdisk_partition *pa, int enable);
|
||||
|
||||
|
||||
extern int fdisk_partition_set_type(struct fdisk_partition *pa, const struct fdisk_parttype *type);
|
||||
extern const struct fdisk_parttype *fdisk_partition_get_type(struct fdisk_partition *pa);
|
||||
extern int fdisk_partition_set_type(struct fdisk_partition *pa, struct fdisk_parttype *type);
|
||||
extern struct fdisk_parttype *fdisk_partition_get_type(struct fdisk_partition *pa);
|
||||
extern int fdisk_partition_set_name(struct fdisk_partition *pa, const char *name);
|
||||
extern const char *fdisk_partition_get_name(struct fdisk_partition *pa);
|
||||
extern int fdisk_partition_set_uuid(struct fdisk_partition *pa, const char *uuid);
|
||||
|
|
|
@ -48,7 +48,7 @@ void fdisk_reset_partition(struct fdisk_partition *pa)
|
|||
DBG(PART, ul_debugobj(pa, "reset"));
|
||||
ref = pa->refcount;
|
||||
|
||||
fdisk_free_parttype(pa->type);
|
||||
fdisk_unref_parttype(pa->type);
|
||||
free(pa->name);
|
||||
free(pa->uuid);
|
||||
free(pa->attrs);
|
||||
|
@ -383,17 +383,35 @@ int fdisk_partition_partno_follow_default(struct fdisk_partition *pa, int enable
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* fdisk_partition_set_type:
|
||||
* @pa: partition
|
||||
* @type: partition type
|
||||
*
|
||||
* Sets parition type.
|
||||
*
|
||||
* Returns: 0 on success, <0 on error.
|
||||
*/
|
||||
int fdisk_partition_set_type(struct fdisk_partition *pa,
|
||||
const struct fdisk_parttype *type)
|
||||
struct fdisk_parttype *type)
|
||||
{
|
||||
if (!pa)
|
||||
return -EINVAL;
|
||||
fdisk_free_parttype(pa->type);
|
||||
pa->type = fdisk_copy_parttype(type);
|
||||
|
||||
fdisk_ref_parttype(type);
|
||||
fdisk_unref_parttype(pa->type);
|
||||
pa->type = type;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct fdisk_parttype *fdisk_partition_get_type(struct fdisk_partition *pa)
|
||||
/**
|
||||
* fdisk_partition_get_type:
|
||||
* @pa: partition
|
||||
*
|
||||
* Returns: pointer to partition type.
|
||||
*/
|
||||
struct fdisk_parttype *fdisk_partition_get_type(struct fdisk_partition *pa)
|
||||
{
|
||||
return pa ? pa->type : NULL;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,131 @@
|
|||
#include "fdiskP.h"
|
||||
|
||||
|
||||
/**
|
||||
* fdisk_new_parttype:
|
||||
*
|
||||
* It's recommended to use fdisk_label_get_parttype_from_code() or
|
||||
* fdisk_label_get_parttype_from_string() for well known types rather
|
||||
* than allocate a new instance.
|
||||
*
|
||||
* Returns: new instance.
|
||||
*/
|
||||
struct fdisk_parttype *fdisk_new_parttype(void)
|
||||
{
|
||||
struct fdisk_parttype *t = calloc(1, sizeof(*t));
|
||||
|
||||
t->refcount = 1;
|
||||
t->flags = FDISK_PARTTYPE_ALLOCATED;
|
||||
DBG(PARTTYPE, ul_debugobj(t, "alloc"));
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* fdisk_ref_parttype:
|
||||
* @t: partition type
|
||||
*
|
||||
* Incremparts reference counter for allocated types
|
||||
*/
|
||||
void fdisk_ref_parttype(struct fdisk_parttype *t)
|
||||
{
|
||||
if (fdisk_parttype_is_allocated(t))
|
||||
t->refcount++;
|
||||
}
|
||||
|
||||
/**
|
||||
* fdisk_unref_parttype
|
||||
* @t: partition pointer
|
||||
*
|
||||
* De-incremparts reference counter, on zero the @t is automatically
|
||||
* deallocated.
|
||||
*/
|
||||
void fdisk_unref_parttype(struct fdisk_parttype *t)
|
||||
{
|
||||
if (!fdisk_parttype_is_allocated(t))
|
||||
return;
|
||||
|
||||
t->refcount--;
|
||||
if (t->refcount <= 0) {
|
||||
DBG(PARTTYPE, ul_debugobj(t, "free"));
|
||||
free(t->typestr);
|
||||
free(t->name);
|
||||
free(t);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* fdisk_parttype_set_name:
|
||||
* @t: partition type
|
||||
* @str: type name
|
||||
*
|
||||
* Sets type name to allocated partition type, for static types
|
||||
* it returns -EINVAL.
|
||||
*
|
||||
* Return: 0 on success, <0 on error
|
||||
*/
|
||||
int fdisk_parttype_set_name(struct fdisk_parttype *t, const char *str)
|
||||
{
|
||||
char *p = NULL;
|
||||
|
||||
if (!t || !fdisk_parttype_is_allocated(t))
|
||||
return -EINVAL;
|
||||
if (str) {
|
||||
p = strdup(str);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
free(t->name);
|
||||
t->name = p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* fdisk_parttype_set_typestr:
|
||||
* @t: partition type
|
||||
* @str: type identificator (e.g. GUID for GPT)
|
||||
*
|
||||
* Sets type string to allocated partition type, for static types
|
||||
* it returns -EINVAL. Don't use this function for MBR, see
|
||||
* fdisk_parttype_set_code().
|
||||
*
|
||||
* Return: 0 on success, <0 on error
|
||||
*/
|
||||
int fdisk_parttype_set_typestr(struct fdisk_parttype *t, const char *str)
|
||||
{
|
||||
char *p = NULL;
|
||||
|
||||
if (!t || !fdisk_parttype_is_allocated(t))
|
||||
return -EINVAL;
|
||||
if (str) {
|
||||
p = strdup(str);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
free(t->typestr);
|
||||
t->typestr = p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* fdisk_parttype_set_code:
|
||||
* @t: partition type
|
||||
* @int: type identificator (e.g. MBR type codes)
|
||||
*
|
||||
* Sets type code to allocated partition type, for static types it returns
|
||||
* -EINVAL. Don't use this function for GPT, see fdisk_parttype_set_typestr().
|
||||
*
|
||||
* Return: 0 on success, <0 on error
|
||||
*/
|
||||
int fdisk_parttype_set_code(struct fdisk_parttype *t, int code)
|
||||
{
|
||||
if (!t || !fdisk_parttype_is_allocated(t))
|
||||
return -EINVAL;
|
||||
t->code = code;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* fdisk_label_get_nparttypes:
|
||||
* @lb: label
|
||||
|
@ -26,7 +151,7 @@ size_t fdisk_label_get_nparttypes(const struct fdisk_label *lb)
|
|||
*
|
||||
* Returns: return parttype
|
||||
*/
|
||||
const struct fdisk_parttype *fdisk_label_get_parttype(const struct fdisk_label *lb, size_t n)
|
||||
struct fdisk_parttype *fdisk_label_get_parttype(const struct fdisk_label *lb, size_t n)
|
||||
{
|
||||
if (!lb || n >= lb->nparttypes)
|
||||
return NULL;
|
||||
|
@ -55,7 +180,8 @@ int fdisk_label_has_code_parttypes(const struct fdisk_label *lb)
|
|||
* @lb: label
|
||||
* @code: code to search for
|
||||
*
|
||||
* Search in lable-specific table of supported partition types by code.
|
||||
* Search for partition type in label-specific table. The result
|
||||
* is pointer to static array of label types.
|
||||
*
|
||||
* Returns: partition type or NULL upon failure or invalid @code.
|
||||
*/
|
||||
|
@ -73,7 +199,6 @@ struct fdisk_parttype *fdisk_label_get_parttype_from_code(
|
|||
for (i = 0; i < lb->nparttypes; i++)
|
||||
if (lb->parttypes[i].code == code)
|
||||
return &lb->parttypes[i];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -82,7 +207,8 @@ struct fdisk_parttype *fdisk_label_get_parttype_from_code(
|
|||
* @lb: label
|
||||
* @str: string to search for
|
||||
*
|
||||
* Search in lable-specific table of supported partition types by typestr.
|
||||
* Search for partition type in label-specific table. The result
|
||||
* is pointer to static array of label types.
|
||||
*
|
||||
* Returns: partition type or NULL upon failure or invalid @str.
|
||||
*/
|
||||
|
@ -105,35 +231,12 @@ struct fdisk_parttype *fdisk_label_get_parttype_from_string(
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static struct fdisk_parttype *new_parttype(unsigned int code,
|
||||
const char *typestr,
|
||||
const char *name)
|
||||
{
|
||||
struct fdisk_parttype *t= calloc(1, sizeof(*t));
|
||||
|
||||
if (!t)
|
||||
return NULL;
|
||||
if (typestr) {
|
||||
t->typestr = strdup(typestr);
|
||||
if (!t->typestr) {
|
||||
free(t);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
t->name = name;
|
||||
t->code = code;
|
||||
t->flags |= FDISK_PARTTYPE_ALLOCATED;
|
||||
|
||||
DBG(PARTTYPE, ul_debugobj(t, "allocated new %s type", name));
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* fdisk_new_unknown_parttype:
|
||||
* @code: type as number
|
||||
* @typestr: type as string
|
||||
|
||||
* Allocates new 'unknown' partition type. Use fdisk_free_parttype() to
|
||||
* Allocates new 'unknown' partition type. Use fdisk_unref_parttype() to
|
||||
* deallocate.
|
||||
*
|
||||
* Returns: newly allocated partition type, or NULL upon failure.
|
||||
|
@ -141,11 +244,16 @@ static struct fdisk_parttype *new_parttype(unsigned int code,
|
|||
struct fdisk_parttype *fdisk_new_unknown_parttype(unsigned int code,
|
||||
const char *typestr)
|
||||
{
|
||||
struct fdisk_parttype *t = new_parttype(code, typestr, _("unknown"));
|
||||
struct fdisk_parttype *t = fdisk_new_parttype();
|
||||
|
||||
if (!t)
|
||||
return NULL;
|
||||
|
||||
fdisk_parttype_set_name(t, _("unknown"));
|
||||
fdisk_parttype_set_code(t, code);
|
||||
fdisk_parttype_set_typestr(t, typestr);
|
||||
t->flags |= FDISK_PARTTYPE_UNKNOWN;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
|
@ -153,13 +261,22 @@ struct fdisk_parttype *fdisk_new_unknown_parttype(unsigned int code,
|
|||
* fdisk_copy_parttype:
|
||||
* @type: type to copy
|
||||
*
|
||||
* Use fdisk_free_parttype() to deallocate.
|
||||
* Use fdisk_unref_parttype() to deallocate.
|
||||
*
|
||||
* Returns: newly allocated partition type, or NULL upon failure.
|
||||
*/
|
||||
struct fdisk_parttype *fdisk_copy_parttype(const struct fdisk_parttype *type)
|
||||
{
|
||||
return new_parttype(type->code, type->typestr, type->name);
|
||||
struct fdisk_parttype *t = fdisk_new_parttype();
|
||||
|
||||
if (!t)
|
||||
return NULL;
|
||||
|
||||
fdisk_parttype_set_name(t, type->name);
|
||||
fdisk_parttype_set_code(t, type->code);
|
||||
fdisk_parttype_set_typestr(t, type->typestr);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -167,9 +284,12 @@ struct fdisk_parttype *fdisk_copy_parttype(const struct fdisk_parttype *type)
|
|||
* @lb: label
|
||||
* @str: string to parse from
|
||||
*
|
||||
* Returns: pointer to static table of the partition types, or newly allocated
|
||||
* partition type for unknown types. It's safe to call fdisk_free_parttype()
|
||||
* for all results.
|
||||
* Parses partition type from @str according to the label. Thefunction returns
|
||||
* a pointer to static table of the partition types, or newly allocated
|
||||
* partition type for unknown types (see fdisk_parttype_is_unknown(). It's
|
||||
* safe to call fdisk_unref_parttype() for all results.
|
||||
*
|
||||
* Returns: pointer to type or NULL on error.
|
||||
*/
|
||||
struct fdisk_parttype *fdisk_label_parse_parttype(
|
||||
const struct fdisk_label *lb,
|
||||
|
@ -186,7 +306,6 @@ struct fdisk_parttype *fdisk_label_parse_parttype(
|
|||
|
||||
DBG(LABEL, ul_debugobj((void *) lb, "parsing '%s' (%s) partition type",
|
||||
str, lb->name));
|
||||
|
||||
types = lb->parttypes;
|
||||
|
||||
if (types[0].typestr == NULL && isxdigit(*str)) {
|
||||
|
@ -226,32 +345,35 @@ done:
|
|||
}
|
||||
|
||||
/**
|
||||
* fdisk_free_parttype:
|
||||
* @t: new type
|
||||
* fdisk_parttype_get_string:
|
||||
* @t: type
|
||||
*
|
||||
* Free the @type.
|
||||
* Returns: partition type string (e.g. GUID for GPT)
|
||||
*/
|
||||
void fdisk_free_parttype(struct fdisk_parttype *t)
|
||||
{
|
||||
if (t && (t->flags & FDISK_PARTTYPE_ALLOCATED)) {
|
||||
DBG(PARTTYPE, ul_debugobj(t, "free"));
|
||||
free(t->typestr);
|
||||
free(t);
|
||||
}
|
||||
}
|
||||
|
||||
const char *fdisk_parttype_get_string(const struct fdisk_parttype *t)
|
||||
{
|
||||
assert(t);
|
||||
return t->typestr && *t->typestr ? t->typestr : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* fdisk_parttype_get_code:
|
||||
* @t: type
|
||||
*
|
||||
* Returns: partition type code (e.g. for MBR)
|
||||
*/
|
||||
unsigned int fdisk_parttype_get_code(const struct fdisk_parttype *t)
|
||||
{
|
||||
assert(t);
|
||||
return t->code;
|
||||
}
|
||||
|
||||
/**
|
||||
* fdisk_parttype_get_name:
|
||||
* @t: type
|
||||
*
|
||||
* Returns: partition type human readable name
|
||||
*/
|
||||
const char *fdisk_parttype_get_name(const struct fdisk_parttype *t)
|
||||
{
|
||||
assert(t);
|
||||
|
|
|
@ -668,7 +668,7 @@ static int parse_script_line(struct fdisk_script *dp, char *s)
|
|||
|
||||
if (!pa->type || fdisk_parttype_is_unknown(pa->type)) {
|
||||
rc = -EINVAL;
|
||||
fdisk_free_parttype(pa->type);
|
||||
fdisk_unref_parttype(pa->type);
|
||||
pa->type = NULL;
|
||||
break;
|
||||
}
|
||||
|
@ -810,7 +810,7 @@ static int parse_commas_line(struct fdisk_script *dp, char *s)
|
|||
|
||||
if (!pa->type || fdisk_parttype_is_unknown(pa->type)) {
|
||||
rc = -EINVAL;
|
||||
fdisk_free_parttype(pa->type);
|
||||
fdisk_unref_parttype(pa->type);
|
||||
pa->type = NULL;
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue