]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libfdisk: cleanup parttype API
authorKarel Zak <kzak@redhat.com>
Wed, 15 Oct 2014 12:10:25 +0000 (14:10 +0200)
committerKarel Zak <kzak@redhat.com>
Wed, 15 Oct 2014 12:10:25 +0000 (14:10 +0200)
 * add reference counting
 * add functions to set allocated types

Signed-off-by: Karel Zak <kzak@redhat.com>
disk-utils/sfdisk.c
libfdisk/src/dos.c
libfdisk/src/fdiskP.h
libfdisk/src/gpt.c
libfdisk/src/libfdisk.h
libfdisk/src/partition.c
libfdisk/src/parttype.c
libfdisk/src/script.c

index 821b5ed15d863c91d25543b7e95520e134c5b4b6..ad0e17e2126501b43fe2dbf1e1ce81f5c5d13373 100644 (file)
@@ -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);
 }
 
index bcfacfc7d48d08b5e97e707ce36852ecacd3d355..5f928a7adb8c46b929a867815da4b87c1bc4bb16 100644 (file)
@@ -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);
        }
 
 
index 7915e5cf02ce7fd5c8d422d473701530ae3b912d..b9955fafb1ce7216ffb6098aacaa898c9f25d286 100644 (file)
@@ -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 {
index ec6dbd6644099a6a7898a0a24f7b22a4ea40cb80..422c461a3cff089f122ecab611d367ff8bd7c86d 100644 (file)
@@ -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;
index 92f641678502c533fc576e983f3d66af41f5e569..cb40ecf01e5746afaf11ada75dfc03fcd5ec41b5 100644 (file)
@@ -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);
index d63dae03e630d3276d66dbddfe0962356480020e..ee33d7bdf1c3e4be7ec964760f76785774197c36 100644 (file)
@@ -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;
 }
index 8c4ac61ef1b2afabf2ef15d7ed8bdc533c7b5db1..2bcf69d6f565e29705835b0ea0acd24f4422e99c 100644 (file)
@@ -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);
index 97b5e4d26adf343530ca97724eeef68dce0c15dd..144f421382a25e8cb4e315a2e4c05fe43dad6192 100644 (file)
@@ -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;
                        }