10 * Returns: new instance.
12 struct fdisk_partition
*fdisk_new_partition(void)
14 struct fdisk_partition
*pa
= calloc(1, sizeof(*pa
));
17 INIT_LIST_HEAD(&pa
->parts
);
18 pa
->partno
= FDISK_EMPTY_PARTNO
;
19 pa
->parent_partno
= FDISK_EMPTY_PARTNO
;
20 DBG(PART
, ul_debugobj(pa
, "alloc"));
25 * fdisk_reset_partition:
28 * Resets partition content.
30 void fdisk_reset_partition(struct fdisk_partition
*pa
)
37 DBG(PART
, ul_debugobj(pa
, "reset"));
39 fdisk_free_parttype(pa
->type
);
43 memset(pa
, 0, sizeof(*pa
));
44 pa
->partno
= FDISK_EMPTY_PARTNO
;
45 pa
->parent_partno
= FDISK_EMPTY_PARTNO
;
47 INIT_LIST_HEAD(&pa
->parts
);
51 * fdisk_ref_partition:
52 * @tb: partition pointer
54 * Incremparts reference counter.
56 void fdisk_ref_partition(struct fdisk_partition
*pa
)
63 * fdisk_unref_partition:
64 * @tb: partition pointer
66 * De-incremparts reference counter, on zero the @tb is automatically
69 void fdisk_unref_partition(struct fdisk_partition
*pa
)
75 if (pa
->refcount
<= 0) {
76 DBG(PART
, ul_debugobj(pa
, "free"));
77 fdisk_reset_partition(pa
);
84 * fdisk_partition_set_start:
86 * @off: offset in sectors
88 * Returns: 0 on success, <0 on error.
90 int fdisk_partition_set_start(struct fdisk_partition
*pa
, uint64_t off
)
99 * fdisk_partition_get_start:
102 * Returns: start offset in sectors
104 uint64_t fdisk_partition_get_start(struct fdisk_partition
*pa
)
106 return pa
? pa
->start
: 0;
110 * fdisk_partition_cmp_start:
113 * See fdisk_sort_table().
115 int fdisk_partition_cmp_start(struct fdisk_partition
*a
,
116 struct fdisk_partition
*b
)
118 return a
->start
- b
->start
;
122 * fdisk_partition_set_end:
124 * @off: offset in sectors
126 * Sets end offset, and zeroize size.
128 * The usual way is to address end of the partition by fdisk_partition_set_size().
130 * Returns: 0 on success, <0 on error.
132 int fdisk_partition_set_end(struct fdisk_partition
*pa
, uint64_t off
)
142 * fdisk_partition_get_start:
145 * Returns: start offset in sectors
147 uint64_t fdisk_partition_get_end(struct fdisk_partition
*pa
)
149 return pa
? pa
->end
: 0;
153 * fdisk_partition_set_size
157 * Sets size, zeroize end offset. See also fdisk_partition_set_end().
159 * Returns: 0 on success, <0 on error.
161 int fdisk_partition_set_size(struct fdisk_partition
*pa
, uint64_t size
)
171 * fdisk_partition_get_start:
174 * Returns: size in sectors
176 uint64_t fdisk_partition_get_size(struct fdisk_partition
*pa
)
178 return pa
? pa
->size
: 0;
182 * fdisk_partition_set_partno
184 * @n: partitiion number
186 * When @pa used as a tempalate for fdisk_add_partition() when infor label driver
187 * about wanted partition position.
189 * Returns: 0 on success, <0 on error.
191 int fdisk_partition_set_partno(struct fdisk_partition
*pa
, size_t n
)
199 size_t fdisk_partition_get_partno(struct fdisk_partition
*pa
)
201 return pa
? pa
->partno
: (size_t) -1;
204 int fdisk_partition_cmp_partno(struct fdisk_partition
*a
,
205 struct fdisk_partition
*b
)
207 return a
->partno
- b
->partno
;
210 int fdisk_partition_set_type(struct fdisk_partition
*pa
, struct fdisk_parttype
*type
)
214 fdisk_free_parttype(pa
->type
);
219 const struct fdisk_parttype
*fdisk_partition_get_type(struct fdisk_partition
*pa
)
221 return pa
? pa
->type
: NULL
;
224 int fdisk_partition_set_name(struct fdisk_partition
*pa
, const char *name
)
240 const char *fdisk_partition_get_name(struct fdisk_partition
*pa
)
242 return pa
? pa
->name
: NULL
;
245 int fdisk_partition_set_uuid(struct fdisk_partition
*pa
, const char *uuid
)
262 * fdisk_partition_partno_follow_default
266 * When @pa used as a tempalate for fdisk_add_partition() when force label driver
267 * to add a new partition to the default (next) position.
269 * Returns: 0 on success, <0 on error.
271 int fdisk_partition_partno_follow_default(struct fdisk_partition
*pa
, int enable
)
275 pa
->partno_follow_default
= enable
? 1 : 0;
280 * fdisk_partition_start_follow_default
284 * When @pa used as a tempalate for fdisk_add_partition() when force label driver
285 * to use the first possible space for the new partition.
287 * Returns: 0 on success, <0 on error.
289 int fdisk_partition_start_follow_default(struct fdisk_partition
*pa
, int enable
)
293 pa
->start_follow_default
= enable
? 1 : 0;
298 * fdisk_partition_start_follow_default
302 * When @pa used as a tempalate for fdisk_add_partition() when force label driver
303 * to use all the possible space for the new partition.
305 * Returns: 0 on success, <0 on error.
307 int fdisk_partition_end_follow_default(struct fdisk_partition
*pa
, int enable
)
311 pa
->end_follow_default
= enable
? 1 : 0;
315 const char *fdisk_partition_get_uuid(struct fdisk_partition
*pa
)
317 return pa
? pa
->uuid
: NULL
;
320 const char *fdisk_partition_get_attrs(struct fdisk_partition
*pa
)
322 return pa
? pa
->attrs
: NULL
;
325 int fdisk_partition_is_nested(struct fdisk_partition
*pa
)
327 return pa
&& pa
->parent_partno
!= FDISK_EMPTY_PARTNO
;
330 int fdisk_partition_is_container(struct fdisk_partition
*pa
)
332 return pa
&& pa
->container
;
335 int fdisk_partition_get_parent(struct fdisk_partition
*pa
, size_t *parent
)
338 *parent
= pa
->parent_partno
;
344 int fdisk_partition_is_used(struct fdisk_partition
*pa
)
346 return pa
&& pa
->used
;
349 int fdisk_partition_is_bootable(struct fdisk_partition
*pa
)
351 return pa
&& pa
->boot
;
354 int fdisk_partition_is_freespace(struct fdisk_partition
*pa
)
356 return pa
&& pa
->freespace
;
359 int fdisk_partition_next_partno(
360 struct fdisk_partition
*pa
,
361 struct fdisk_context
*cxt
,
367 if (pa
&& pa
->partno_follow_default
) {
370 DBG(PART
, ul_debugobj(pa
, "next partno (follow default)"));
372 for (i
= 0; i
< cxt
->label
->nparts_max
; i
++) {
373 if (!fdisk_is_partition_used(cxt
, i
)) {
380 } else if (pa
&& pa
->partno
!= FDISK_EMPTY_PARTNO
) {
382 DBG(PART
, ul_debugobj(pa
, "next partno (specified=%zu)", pa
->partno
));
384 if (pa
->partno
>= cxt
->label
->nparts_max
)
388 return fdisk_ask_partnum(cxt
, n
, 1);
394 * fdisk_partition_to_string:
396 * @id: field (FDISK_FIELD_*)
397 * @data: returns string with allocated data
399 * Returns info about partition converted to printable string.
403 * struct fdisk_parition *pa;
405 * fdisk_get_partition(cxt, 0, &pa);
406 * fdisk_partition_to_string(pa, FDISK_FIELD_UUID, &data);
407 * printf("first partition uuid: %s\n", data);
409 * fdisk_unref_partition(pa);
411 * returns UUID for the first partition.
413 * Returns 0 on success, otherwise, a corresponding error.
416 int fdisk_partition_to_string(struct fdisk_partition
*pa
,
417 struct fdisk_context
*cxt
,
429 case FDISK_FIELD_DEVICE
:
431 p
= strdup(_("Free space"));
432 else if (cxt
->label
->flags
& FDISK_LABEL_FL_INCHARS_PARTNO
)
433 rc
= asprintf(&p
, "%c", (int) pa
->partno
+ 'a');
435 p
= fdisk_partname(cxt
->dev_path
, pa
->partno
+ 1);
437 case FDISK_FIELD_BOOT
:
438 rc
= asprintf(&p
, "%c", pa
->boot
? '*' : ' ');
440 case FDISK_FIELD_START
:
441 x
= fdisk_cround(cxt
, pa
->start
);
442 rc
= pa
->start_post
?
443 asprintf(&p
, "%ju%c", x
, pa
->start_post
) :
444 asprintf(&p
, "%ju", x
);
446 case FDISK_FIELD_END
:
447 x
= fdisk_cround(cxt
, pa
->end
);
449 asprintf(&p
, "%ju%c", x
, pa
->end_post
) :
450 asprintf(&p
, "%ju", x
);
452 case FDISK_FIELD_SIZE
:
454 uint64_t sz
= pa
->size
* cxt
->sector_size
;
456 if (fdisk_is_details(cxt
)) {
458 asprintf(&p
, "%ju%c", sz
, pa
->size_post
) :
459 asprintf(&p
, "%ju", sz
);
461 p
= size_to_human_string(SIZE_SUFFIX_1LETTER
, sz
);
467 case FDISK_FIELD_CYLINDERS
:
468 rc
= asprintf(&p
, "%ju", (uintmax_t)
469 fdisk_cround(cxt
, pa
->size
));
471 case FDISK_FIELD_SECTORS
:
472 rc
= asprintf(&p
, "%ju", pa
->size
);
474 case FDISK_FIELD_BSIZE
:
475 rc
= asprintf(&p
, "%ju", pa
->bsize
);
477 case FDISK_FIELD_FSIZE
:
478 rc
= asprintf(&p
, "%ju", pa
->fsize
);
480 case FDISK_FIELD_CPG
:
481 rc
= asprintf(&p
, "%ju", pa
->cpg
);
483 case FDISK_FIELD_TYPE
:
484 p
= pa
->type
&& pa
->type
->name
? strdup(pa
->type
->name
) : NULL
;
486 case FDISK_FIELD_TYPEID
:
487 if (pa
->type
&& fdisk_parttype_get_string(pa
->type
))
488 rc
= asprintf(&p
, "%s", fdisk_parttype_get_string(pa
->type
));
490 rc
= asprintf(&p
, "%x", fdisk_parttype_get_code(pa
->type
));
492 case FDISK_FIELD_UUID
:
493 p
= pa
->uuid
? strdup(pa
->uuid
) : NULL
;
495 case FDISK_FIELD_NAME
:
496 p
= pa
->name
? strdup(pa
->name
) : NULL
;
498 case FDISK_FIELD_ATTR
:
499 p
= pa
->attrs
? strdup(pa
->attrs
) : NULL
;
501 case FDISK_FIELD_SADDR
:
502 p
= pa
->start_addr
? strdup(pa
->start_addr
) : NULL
;
504 case FDISK_FIELD_EADDR
:
505 p
= pa
->end_addr
? strdup(pa
->end_addr
) : NULL
;
522 * fdisk_get_partition:
525 * @pa: pointer to partition struct
527 * Fills in @pa with data about partition @n.
529 * Returns: 0 on success, otherwise, a corresponding error.
531 int fdisk_get_partition(struct fdisk_context
*cxt
, size_t partno
,
532 struct fdisk_partition
**pa
)
535 struct fdisk_partition
*np
= NULL
;
537 if (!cxt
|| !cxt
->label
|| !pa
)
539 if (!cxt
->label
->op
->get_part
)
541 if (!fdisk_is_partition_used(cxt
, partno
))
545 np
= *pa
= fdisk_new_partition();
549 fdisk_reset_partition(*pa
);
551 (*pa
)->partno
= partno
;
552 rc
= cxt
->label
->op
->get_part(cxt
, partno
, *pa
);
556 fdisk_unref_partition(np
);
559 fdisk_reset_partition(*pa
);
565 * This is faster than fdisk_get_partition() + fdisk_partition_is_used()
567 int fdisk_is_partition_used(struct fdisk_context
*cxt
, size_t n
)
569 if (!cxt
|| !cxt
->label
)
571 if (!cxt
->label
->op
->part_is_used
)
574 return cxt
->label
->op
->part_is_used(cxt
, n
);
578 * fdisk_add_partition:
579 * @cxt: fdisk context
580 * @pa: template for the partition
582 * If @pa is not specified or any @pa item is missiong the libfdisk will ask by
585 * Creates a new partition.
589 int fdisk_add_partition(struct fdisk_context
*cxt
,
590 struct fdisk_partition
*pa
)
597 if (!cxt
|| !cxt
->label
)
599 if (!cxt
->label
->op
->add_part
)
601 if (fdisk_missing_geometry(cxt
))
604 DBG(CXT
, ul_debugobj(cxt
, "adding new partition (start=%ju, end=%ju, size=%ju, "
605 "defaults(start=%s, end=%s, partno=%s)",
609 pa
&& pa
->start_follow_default
? "yes" : "no",
610 pa
&& pa
->end_follow_default
? "yes" : "no",
611 pa
&& pa
->partno_follow_default
? "yes" : "no"));
613 rc
= cxt
->label
->op
->add_part(cxt
, pa
);
615 DBG(CXT
, ul_debugobj(cxt
, "add partition done (rc=%d)", rc
));
620 * fdisk_delete_partition:
621 * @cxt: fdisk context
622 * @partnum: partition number to delete
624 * Deletes a @partnum partition.
626 * Returns 0 on success, otherwise, a corresponding error.
628 int fdisk_delete_partition(struct fdisk_context
*cxt
, size_t partnum
)
630 if (!cxt
|| !cxt
->label
)
632 if (!cxt
->label
->op
->part_delete
)
635 DBG(CXT
, ul_debugobj(cxt
, "deleting %s partition number %zd",
636 cxt
->label
->name
, partnum
));
637 return cxt
->label
->op
->part_delete(cxt
, partnum
);
641 * fdisk_delete_all_partitions:
642 * @cxt: fdisk context
644 * Delete all used partitions.
646 * Returns: 0 on success, otherwise, a corresponding error.
648 int fdisk_delete_all_partitions(struct fdisk_context
*cxt
)
653 if (!cxt
|| !cxt
->label
)
656 for (i
= 0; i
< cxt
->label
->nparts_max
; i
++) {
658 if (!fdisk_is_partition_used(cxt
, i
))
660 rc
= fdisk_delete_partition(cxt
, i
);