7 struct fdisk_partition
*fdisk_new_partition(void)
9 struct fdisk_partition
*pa
= calloc(1, sizeof(*pa
));
12 INIT_LIST_HEAD(&pa
->parts
);
13 pa
->partno
= FDISK_EMPTY_PARTNO
;
14 pa
->parent_partno
= FDISK_EMPTY_PARTNO
;
15 DBG(PART
, ul_debugobj(pa
, "alloc"));
19 void fdisk_reset_partition(struct fdisk_partition
*pa
)
26 DBG(PART
, ul_debugobj(pa
, "reset"));
28 fdisk_free_parttype(pa
->type
);
32 memset(pa
, 0, sizeof(*pa
));
33 pa
->partno
= FDISK_EMPTY_PARTNO
;
34 pa
->parent_partno
= FDISK_EMPTY_PARTNO
;
36 INIT_LIST_HEAD(&pa
->parts
);
39 void fdisk_ref_partition(struct fdisk_partition
*pa
)
45 void fdisk_unref_partition(struct fdisk_partition
*pa
)
51 if (pa
->refcount
<= 0) {
52 DBG(PART
, ul_debugobj(pa
, "free"));
53 fdisk_reset_partition(pa
);
59 int fdisk_dump_partition(struct fdisk_partition
*pa
, FILE *f
)
64 if (pa
->partno
== FDISK_EMPTY_PARTNO
)
67 fprintf(f
, "#%zu ", pa
->partno
);
69 fprintf(f
, "[%p] start=%ju, end=%ju, size=%ju",
70 pa
, pa
->start
, pa
->end
, pa
->size
);
71 if (pa
->parent_partno
!= FDISK_EMPTY_PARTNO
)
72 fprintf(f
, ", parent=%zu", pa
->parent_partno
);
73 if (fdisk_partition_is_freespace(pa
))
74 fputs(" freespace", f
);
75 if (fdisk_partition_is_container(pa
))
76 fputs(" container", f
);
77 if (fdisk_partition_is_nested(pa
))
83 int fdisk_partition_set_start(struct fdisk_partition
*pa
, uint64_t off
)
91 uint64_t fdisk_partition_get_start(struct fdisk_partition
*pa
)
93 return pa
? pa
->start
: 0;
96 int fdisk_partition_cmp_start(struct fdisk_partition
*a
,
97 struct fdisk_partition
*b
)
99 return a
->start
- b
->start
;
102 int fdisk_partition_set_end(struct fdisk_partition
*pa
, uint64_t off
)
111 uint64_t fdisk_partition_get_end(struct fdisk_partition
*pa
)
113 return pa
? pa
->end
: 0;
117 int fdisk_partition_set_size(struct fdisk_partition
*pa
, uint64_t size
)
126 uint64_t fdisk_partition_get_size(struct fdisk_partition
*pa
)
128 return pa
? pa
->size
: 0;
131 int fdisk_partition_set_partno(struct fdisk_partition
*pa
, size_t n
)
139 size_t fdisk_partition_get_partno(struct fdisk_partition
*pa
)
141 return pa
? pa
->partno
: (size_t) -1;
144 int fdisk_partition_cmp_partno(struct fdisk_partition
*a
,
145 struct fdisk_partition
*b
)
147 return a
->partno
- b
->partno
;
150 int fdisk_partition_set_type(struct fdisk_partition
*pa
, struct fdisk_parttype
*type
)
154 fdisk_free_parttype(pa
->type
);
159 const struct fdisk_parttype
*fdisk_partition_get_type(struct fdisk_partition
*pa
)
161 return pa
? pa
->type
: NULL
;
164 int fdisk_partition_set_name(struct fdisk_partition
*pa
, const char *name
)
180 const char *fdisk_partition_get_name(struct fdisk_partition
*pa
)
182 return pa
? pa
->name
: NULL
;
185 int fdisk_partition_set_uuid(struct fdisk_partition
*pa
, const char *uuid
)
201 int fdisk_partition_partno_follow_default(struct fdisk_partition
*pa
, int enable
)
205 pa
->partno_follow_default
= enable
? 1 : 0;
209 int fdisk_partition_start_follow_default(struct fdisk_partition
*pa
, int enable
)
213 pa
->start_follow_default
= enable
? 1 : 0;
217 int fdisk_partition_end_follow_default(struct fdisk_partition
*pa
, int enable
)
221 pa
->end_follow_default
= enable
? 1 : 0;
225 const char *fdisk_partition_get_uuid(struct fdisk_partition
*pa
)
227 return pa
? pa
->uuid
: NULL
;
230 const char *fdisk_partition_get_attrs(struct fdisk_partition
*pa
)
232 return pa
? pa
->attrs
: NULL
;
235 int fdisk_partition_is_nested(struct fdisk_partition
*pa
)
237 return pa
&& pa
->parent_partno
!= FDISK_EMPTY_PARTNO
;
240 int fdisk_partition_is_container(struct fdisk_partition
*pa
)
242 return pa
&& pa
->container
;
245 int fdisk_partition_get_parent(struct fdisk_partition
*pa
, size_t *parent
)
248 *parent
= pa
->parent_partno
;
254 int fdisk_partition_is_used(struct fdisk_partition
*pa
)
256 return pa
&& pa
->used
;
259 int fdisk_partition_is_freespace(struct fdisk_partition
*pa
)
261 return pa
&& pa
->freespace
;
264 int fdisk_partition_next_partno(
265 struct fdisk_partition
*pa
,
266 struct fdisk_context
*cxt
,
272 if (pa
&& pa
->partno_follow_default
) {
275 DBG(PART
, ul_debugobj(pa
, "next partno (follow default)"));
277 for (i
= 0; i
< cxt
->label
->nparts_max
; i
++) {
278 if (!fdisk_is_partition_used(cxt
, i
)) {
285 } else if (pa
&& pa
->partno
!= FDISK_EMPTY_PARTNO
) {
287 DBG(PART
, ul_debugobj(pa
, "next partno (specified=%zu)", pa
->partno
));
289 if (pa
->partno
>= cxt
->label
->nparts_max
)
293 return fdisk_ask_partnum(cxt
, n
, 1);
299 * fdisk_partition_to_string:
301 * @id: column (FDISK_COL_*)
302 * @data: returns string with allocated data
304 * Returns info about partition converted to printable string.
308 * struct fdisk_parition *pa;
310 * fdisk_get_partition(cxt, 0, &pa);
311 * fdisk_partition_to_string(pa, FDISK_COL_UUID, &data);
312 * printf("first partition uuid: %s\n", data);
314 * fdisk_unref_partition(pa);
316 * returns UUID for the first partition.
318 * Returns 0 on success, otherwise, a corresponding error.
321 int fdisk_partition_to_string(struct fdisk_partition
*pa
,
322 struct fdisk_context
*cxt
,
334 case FDISK_COL_DEVICE
:
336 p
= strdup(_("Free space"));
337 else if (cxt
->label
->flags
& FDISK_LABEL_FL_INCHARS_PARTNO
)
338 rc
= asprintf(&p
, "%c", (int) pa
->partno
+ 'a');
340 p
= fdisk_partname(cxt
->dev_path
, pa
->partno
+ 1);
343 rc
= asprintf(&p
, "%c", pa
->boot
);
345 case FDISK_COL_START
:
346 x
= fdisk_cround(cxt
, pa
->start
);
347 rc
= pa
->start_post
?
348 asprintf(&p
, "%ju%c", x
, pa
->start_post
) :
349 asprintf(&p
, "%ju", x
);
352 x
= fdisk_cround(cxt
, pa
->end
);
354 asprintf(&p
, "%ju%c", x
, pa
->end_post
) :
355 asprintf(&p
, "%ju", x
);
359 uint64_t sz
= pa
->size
* cxt
->sector_size
;
361 if (fdisk_context_display_details(cxt
)) {
363 asprintf(&p
, "%ju%c", sz
, pa
->size_post
) :
364 asprintf(&p
, "%ju", sz
);
366 p
= size_to_human_string(SIZE_SUFFIX_1LETTER
, sz
);
372 case FDISK_COL_CYLINDERS
:
373 rc
= asprintf(&p
, "%ju", (uintmax_t)
374 fdisk_cround(cxt
, pa
->size
));
376 case FDISK_COL_SECTORS
:
377 rc
= asprintf(&p
, "%ju", pa
->size
);
379 case FDISK_COL_BSIZE
:
380 rc
= asprintf(&p
, "%ju", pa
->bsize
);
382 case FDISK_COL_FSIZE
:
383 rc
= asprintf(&p
, "%ju", pa
->fsize
);
386 rc
= asprintf(&p
, "%ju", pa
->cpg
);
389 p
= pa
->type
&& pa
->type
->name
? strdup(pa
->type
->name
) : NULL
;
391 case FDISK_COL_TYPEID
:
392 if (pa
->type
&& pa
->type
->typestr
)
393 rc
= asprintf(&p
, "%s", pa
->type
->typestr
);
395 rc
= asprintf(&p
, "%x", pa
->type
->type
);
398 p
= pa
->uuid
? strdup(pa
->uuid
) : NULL
;
401 p
= pa
->name
? strdup(pa
->name
) : NULL
;
404 p
= pa
->attrs
? strdup(pa
->attrs
) : NULL
;
406 case FDISK_COL_SADDR
:
407 p
= pa
->start_addr
? strdup(pa
->start_addr
) : NULL
;
409 case FDISK_COL_EADDR
:
410 p
= pa
->end_addr
? strdup(pa
->end_addr
) : NULL
;
427 * fdisk_get_partition:
430 * @pa: pointer to partition struct
432 * Fills in @pa with data about partition @n.
434 * Returns: 0 on success, otherwise, a corresponding error.
436 int fdisk_get_partition(struct fdisk_context
*cxt
, size_t partno
,
437 struct fdisk_partition
**pa
)
440 struct fdisk_partition
*np
= NULL
;
442 if (!cxt
|| !cxt
->label
|| !pa
)
444 if (!cxt
->label
->op
->get_part
)
446 if (!fdisk_is_partition_used(cxt
, partno
))
450 np
= *pa
= fdisk_new_partition();
454 fdisk_reset_partition(*pa
);
456 (*pa
)->partno
= partno
;
457 rc
= cxt
->label
->op
->get_part(cxt
, partno
, *pa
);
461 fdisk_unref_partition(np
);
464 fdisk_reset_partition(*pa
);
470 * This is faster than fdisk_get_partition() + fdisk_partition_is_used()
472 int fdisk_is_partition_used(struct fdisk_context
*cxt
, size_t n
)
474 if (!cxt
|| !cxt
->label
)
476 if (!cxt
->label
->op
->part_is_used
)
479 return cxt
->label
->op
->part_is_used(cxt
, n
);
483 * fdisk_add_partition:
484 * @cxt: fdisk context
485 * @pa: template for the partition
487 * If @pa is not specified or any @pa item is missiong the libfdisk will ask by
490 * Creates a new partition.
494 int fdisk_add_partition(struct fdisk_context
*cxt
,
495 struct fdisk_partition
*pa
)
502 if (!cxt
|| !cxt
->label
)
504 if (!cxt
->label
->op
->add_part
)
506 if (fdisk_missing_geometry(cxt
))
509 DBG(CXT
, ul_debugobj(cxt
, "adding new partition (start=%ju, end=%ju, size=%ju, "
510 "defaults(start=%s, end=%s, partno=%s)",
514 pa
&& pa
->start_follow_default
? "yes" : "no",
515 pa
&& pa
->end_follow_default
? "yes" : "no",
516 pa
&& pa
->partno_follow_default
? "yes" : "no"));
518 rc
= cxt
->label
->op
->add_part(cxt
, pa
);
520 DBG(CXT
, ul_debugobj(cxt
, "add partition done (rc=%d)", rc
));
525 * fdisk_delete_partition:
526 * @cxt: fdisk context
527 * @partnum: partition number to delete
529 * Deletes a @partnum partition.
531 * Returns 0 on success, otherwise, a corresponding error.
533 int fdisk_delete_partition(struct fdisk_context
*cxt
, size_t partnum
)
535 if (!cxt
|| !cxt
->label
)
537 if (!cxt
->label
->op
->part_delete
)
540 DBG(CXT
, ul_debugobj(cxt
, "deleting %s partition number %zd",
541 cxt
->label
->name
, partnum
));
542 return cxt
->label
->op
->part_delete(cxt
, partnum
);