Changeset 6453e306 in mainline


Ignore:
Timestamp:
2013-12-25T16:09:43Z (10 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
ac36aed
Parents:
d51beba3
Message:

basic code review and coding style cleanup

Location:
uspace
Files:
19 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/hdisk/common.h

    rd51beba3 r6453e306  
    11/*
    2  * Copyright (c) 2012, 2013 Dominik Taborsky
     2 * Copyright (c) 2012-2013 Dominik Taborsky
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29  /** @addtogroup hdisk
     29/** @addtogroup hdisk
    3030 * @{
    3131 */
     
    4545} layouts_t;
    4646
    47 union label_data {
    48         mbr_label_t     *mbr;
    49         gpt_label_t     *gpt;
    50 };
     47typedef union {
     48        mbr_label_t *mbr;
     49        gpt_label_t *gpt;
     50} label_data_t;
    5151
    52 typedef struct label label_t;
    53 
    54 struct label {
     52typedef struct label {
    5553        layouts_t layout;
    56         aoff64_t nblocks;
     54        aoff64_t blocks;
    5755        service_id_t device;
    58         union label_data data;
     56        label_data_t data;
    5957        unsigned int alignment;
    60         int (* destroy_label)(label_t *);
    61         int (* add_part)     (label_t *, tinput_t *);
    62         int (* delete_part)  (label_t *, tinput_t *);
    63         int (* new_label)    (label_t *);
    64         int (* print_parts)  (label_t *);
    65         int (* read_parts)   (label_t *);
    66         int (* write_parts)  (label_t *);
    67         int (* extra_funcs)  (label_t *, tinput_t *);
    68 };
     58        int (* destroy_label)(struct label *);
     59        int (* add_part)(struct label *, tinput_t *);
     60        int (* delete_part)(struct label *, tinput_t *);
     61        int (* new_label)(struct label *);
     62        int (* print_parts)(struct label *);
     63        int (* read_parts)(struct label *);
     64        int (* write_parts)(struct label *);
     65        int (* extra_funcs)(struct label *, tinput_t *);
     66} label_t;
    6967
    7068#endif
    71 
  • uspace/app/hdisk/func_gpt.c

    rd51beba3 r6453e306  
    11/*
    2  * Copyright (c) 2012, 2013 Dominik Taborsky
     2 * Copyright (c) 2012-2013 Dominik Taborsky
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29  /** @addtogroup hdisk
     29/** @addtogroup hdisk
    3030 * @{
    3131 */
     
    3939#include <sys/types.h>
    4040#include <sys/typefmt.h>
    41 
    4241#include "func_gpt.h"
    4342#include "input.h"
     
    5150        this->alignment = 1;
    5251       
    53         this->add_part      = add_gpt_part;
    54         this->delete_part   = delete_gpt_part;
     52        this->add_part = add_gpt_part;
     53        this->delete_part = delete_gpt_part;
    5554        this->destroy_label = destroy_gpt_label;
    56         this->new_label     = new_gpt_label;
    57         this->print_parts   = print_gpt_parts;
    58         this->read_parts    = read_gpt_parts;
    59         this->write_parts   = write_gpt_parts;
    60         this->extra_funcs   = extra_gpt_funcs;
     55        this->new_label = new_gpt_label;
     56        this->print_parts = print_gpt_parts;
     57        this->read_parts = read_gpt_parts;
     58        this->write_parts = write_gpt_parts;
     59        this->extra_funcs = extra_gpt_funcs;
    6160       
    6261        return this->new_label(this);
     
    6564int add_gpt_part(label_t *this, tinput_t *in)
    6665{
    67         gpt_part_t * p = gpt_get_partition(this->data.gpt);
    68         if (p == NULL) {
     66        gpt_part_t *partition = gpt_get_partition(this->data.gpt);
     67        if (partition == NULL)
    6968                return ENOMEM;
    70         }
    71        
    72         return set_gpt_partition(in, p, this);
     69       
     70        return set_gpt_partition(in, partition, this);
    7371}
    7472
    7573int delete_gpt_part(label_t *this, tinput_t *in)
    7674{
    77         int rc;
    78         size_t idx;
    79        
    80         printf("Number of the partition to delete (counted from 0): ");
    81         idx = get_input_size_t(in);
    82        
    83         rc = gpt_remove_partition(this->data.gpt, idx);
     75        printf("Index of the partition to delete (counted from 0): ");
     76        size_t idx = get_input_size_t(in);
     77       
     78        int rc = gpt_remove_partition(this->data.gpt, idx);
    8479        if (rc == ENOMEM) {
    85                 printf("Warning: running low on memory, not resizing...\n");
     80                printf("Warning: Running out on memory, not resizing.\n");
    8681                return rc;
    8782        } else if (rc == EINVAL) {
     
    107102int print_gpt_parts(label_t *this)
    108103{
    109         printf("Current partition scheme (GPT)(number of blocks: %" PRIu64 "):\n", this->nblocks);
    110         printf("%15s %10s %10s Type: Name:\n", "Start:", "End:", "Length:");
     104        printf("Current partition scheme: GPT\n");
     105        printf("Number of blocks: %" PRIu64 "\n", this->blocks);
    111106       
    112107        size_t i = 0;
    113        
    114108        gpt_part_foreach (this->data.gpt, iter) {
    115                 i++;
    116                
    117109                if (gpt_get_part_type(iter) == GPT_PTE_UNUSED)
    118110                        continue;
    119111               
    120112                if (i % 20 == 0)
    121                         printf("%15s %10s %10s Type: Name:\n", "Start:", "End:", "Length:");
    122                
     113                        printf("%15s %10s %10s Type: Name:\n",
     114                            "Start:", "End:", "Length:");
    123115               
    124116                printf("%3zu  %10" PRIu64 " %10" PRIu64 " %10" PRIu64 "    %3zu %s\n",
    125                    i-1, gpt_get_start_lba(iter), gpt_get_end_lba(iter),
    126                         gpt_get_end_lba(iter) - gpt_get_start_lba(iter),
    127                         gpt_get_part_type(iter), gpt_get_part_name(iter));
    128                
     117                   i, gpt_get_start_lba(iter), gpt_get_end_lba(iter),
     118                   gpt_get_end_lba(iter) - gpt_get_start_lba(iter),
     119                   gpt_get_part_type(iter), gpt_get_part_name(iter));
     120               
     121                i++;
    129122        }
    130123       
     
    134127int read_gpt_parts(label_t *this)
    135128{
    136         int rc;
    137        
    138         rc = gpt_read_header(this->data.gpt, this->device);
    139         if (rc != EOK) {
    140                 printf("Error: Reading header failed: %d (%s)\n", rc, str_error(rc));
     129        int rc = gpt_read_header(this->data.gpt, this->device);
     130        if (rc != EOK) {
     131                printf("Error: Reading header failed: %d (%s)\n", rc,
     132                    str_error(rc));
    141133                return rc;
    142134        }
     
    144136        rc = gpt_read_partitions(this->data.gpt);
    145137        if (rc != EOK) {
    146                 printf("Error: Reading partitions failed: %d (%s)\n", rc, str_error(rc));
     138                printf("Error: Reading partitions failed: %d (%s)\n", rc,
     139                    str_error(rc));
    147140                return rc;
    148141        }
     
    153146int write_gpt_parts(label_t *this)
    154147{
    155         int rc;
    156         printf("test1\n");
    157         rc = gpt_write_partitions(this->data.gpt, this->device);
    158         if (rc != EOK) {
    159                 printf("Error: Writing partitions failed: %d (%s)\n", rc, str_error(rc));
    160                 return rc;
    161         }
    162         printf("test2\n");
     148        int rc = gpt_write_partitions(this->data.gpt, this->device);
     149        if (rc != EOK) {
     150                printf("Error: Writing partitions failed: %d (%s)\n", rc,
     151                    str_error(rc));
     152                return rc;
     153        }
     154       
    163155        return EOK;
    164156}
     
    170162}
    171163
    172 static int set_gpt_partition(tinput_t *in, gpt_part_t *p, label_t * this)
    173 {
    174         int rc;
    175        
    176         uint64_t sa, ea;
    177        
     164static int set_gpt_partition(tinput_t *in, gpt_part_t *partition, label_t *this)
     165{
    178166        printf("Set starting address: ");
    179         sa = get_input_uint64(in);
    180         if (this->alignment != 0 && this->alignment != 1 && sa % this->alignment != 0)
     167        uint64_t sa = get_input_uint64(in);
     168        if ((this->alignment != 0) && (this->alignment != 1) &&
     169            (sa % this->alignment != 0))
    181170                sa = gpt_get_next_aligned(sa, this->alignment);
    182171       
    183         printf("Set end address (max: %" PRIu64 "): ", this->nblocks);
    184         ea = get_input_uint64(in);
     172        printf("Set end address (max: %" PRIu64 "): ", this->blocks);
     173        uint64_t ea = get_input_uint64(in);
    185174       
    186175        if (ea <= sa) {
     
    189178        }
    190179       
    191         gpt_set_start_lba(p, sa);
    192         gpt_set_end_lba(p, ea);
    193        
    194         /* See global.c from libgpt for all partition types. */
     180        gpt_set_start_lba(partition, sa);
     181        gpt_set_end_lba(partition, ea);
     182       
    195183        printf("Choose type: ");
    196184        print_part_types();
    197185        printf("Set type (1 for HelenOS System): ");
    198186        size_t idx = get_input_size_t(in);
    199         gpt_set_part_type(p, idx);
    200        
    201         gpt_set_random_uuid(p->part_id);
    202        
     187        gpt_set_part_type(partition, idx);
     188       
     189        gpt_set_random_uuid(partition->part_id);
     190       
     191        printf("Name the partition: ");
    203192        char *name;
    204         printf("Name the partition: ");
    205         rc = get_input_line(in, &name);
     193        int rc = get_input_line(in, &name);
    206194        if (rc != EOK) {
    207195                printf("Error reading name: %d (%s)\n", rc, str_error(rc));
     
    209197        }
    210198       
    211         gpt_set_part_name(p, name, str_size(name));
     199        gpt_set_part_name(partition, name, str_size(name));
    212200       
    213201        return EOK;
     
    216204static void print_part_types(void)
    217205{
    218         int c;
    219         int count = 0;
    220         const struct partition_type * ptype = gpt_ptypes;
     206        unsigned int count = 0;
     207        const partition_type_t *ptype = gpt_ptypes;
    221208       
    222209        do {
     210                printf("%u: %s\n", count, ptype->desc);
     211                count++;
     212                ptype++;
     213               
    223214                if (count % 10 == 0) {
    224215                        printf("Print (more) partition types? (y/n)\n");
    225                         c = getchar();
     216                        int c = getchar();
    226217                        if (c == 'n')
    227218                                return;
    228219                }
    229                
    230                 printf("%d: %s\n", count, ptype->desc);
    231                 ++count;
    232                 ++ptype;
    233220        } while (ptype->guid != NULL);
    234221}
    235 
  • uspace/app/hdisk/func_gpt.h

    rd51beba3 r6453e306  
    11/*
    2  * Copyright (c) 2012, 2013 Dominik Taborsky
     2 * Copyright (c) 2012-2013 Dominik Taborsky
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29  /** @addtogroup hdisk
     29/** @addtogroup hdisk
    3030 * @{
    3131 */
     
    3434
    3535#ifndef __FUNC_GPT_H__
    36 #define __FUNC_GPT_H__
     36#define __FUNC_GPT_H__
    3737
    3838#include <loc.h>
    3939#include <tinput.h>
    4040#include <libgpt.h>
    41 
    4241#include "common.h"
    4342
    4443extern int construct_gpt_label(label_t *);
    45 extern int add_gpt_part     (label_t *, tinput_t *);
    46 extern int delete_gpt_part  (label_t *, tinput_t *);
     44extern int add_gpt_part(label_t *, tinput_t *);
     45extern int delete_gpt_part(label_t *, tinput_t *);
    4746extern int destroy_gpt_label(label_t *);
    48 extern int new_gpt_label    (label_t *);
    49 extern int print_gpt_parts  (label_t *);
    50 extern int read_gpt_parts   (label_t *);
    51 extern int write_gpt_parts  (label_t *);
    52 extern int extra_gpt_funcs  (label_t *, tinput_t *);
     47extern int new_gpt_label(label_t *);
     48extern int print_gpt_parts(label_t *);
     49extern int read_gpt_parts(label_t *);
     50extern int write_gpt_parts(label_t *);
     51extern int extra_gpt_funcs(label_t *, tinput_t *);
    5352
    5453#endif
  • uspace/app/hdisk/func_mbr.c

    rd51beba3 r6453e306  
    11/*
    2  * Copyright (c) 2012, 2013 Dominik Taborsky
     2 * Copyright (c) 2012-2013 Dominik Taborsky
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29  /** @addtogroup hdisk
     29/** @addtogroup hdisk
    3030 * @{
    3131 */
     
    3737#include <str_error.h>
    3838#include <sys/types.h>
    39 
    4039#include "func_mbr.h"
    4140#include "input.h"
     
    6261int add_mbr_part(label_t *this, tinput_t *in)
    6362{
    64         int rc;
    65        
    66         mbr_part_t *part = mbr_alloc_partition();
    67        
    68         rc = set_mbr_partition(in, part, this);
     63        mbr_part_t *partition = mbr_alloc_partition();
     64        if (partition == NULL)
     65                return ENOMEM;
     66       
     67        int rc = set_mbr_partition(in, partition, this);
    6968        if (rc != EOK)
    7069                return rc;
    7170       
    72         rc = mbr_add_partition(this->data.mbr, part);
    73         if (rc != ERR_OK) {
     71        rc = mbr_add_partition(this->data.mbr, partition);
     72        if (rc != ERR_OK)
    7473                printf("Error adding partition: %d\n", rc);
    75         }
    7674       
    7775        return EOK;
     
    8078int delete_mbr_part(label_t *this, tinput_t *in)
    8179{
    82         int rc;
    83         size_t idx;
    84        
    85         printf("Number of the partition to delete (counted from 0): ");
    86         idx = get_input_size_t(in);
    87        
    88         if (idx == 0 && errno != EOK)
    89                 return errno;
    90        
    91         rc = mbr_remove_partition(this->data.mbr, idx);
    92         if (rc != EOK) {
     80        printf("Index of the partition to delete (counted from 0): ");
     81        size_t idx = get_input_size_t(in);
     82       
     83        if ((idx == 0) && (errno != EOK))
     84                return errno;
     85       
     86        int rc = mbr_remove_partition(this->data.mbr, idx);
     87        if (rc != EOK)
    9388                printf("Error: partition does not exist?\n");
    94         }
    9589       
    9690        return EOK;
     
    113107}
    114108
    115 /** Print current partition scheme */
    116109int print_mbr_parts(label_t *this)
    117110{
    118         int num = 0;
    119        
    120         printf("Current partition scheme (MBR)(number of blocks: %" PRIu64 "):\n", this->nblocks);
    121         printf("\t\t%10s  %10s %10s %10s %7s\n", "Bootable:", "Start:", "End:", "Length:", "Type:");
    122        
     111        printf("Current partition scheme: MBR\n");
     112        printf("Number of blocks: %" PRIu64 "\n", this->blocks);
     113        printf("\t\t%10s  %10s %10s %10s %7s\n",
     114            "Bootable:", "Start:", "End:", "Length:", "Type:");
     115       
     116        unsigned int num = 0;
    123117        mbr_part_t *it;
    124        
    125118        for (it = mbr_get_first_partition(this->data.mbr); it != NULL;
    126119             it = mbr_get_next_partition(this->data.mbr, it)) {
     
    128121                        continue;
    129122               
    130                 printf("\tP%d:\t", num);
     123                printf("\tP%u:\t", num);
    131124                if (mbr_get_flag(it, ST_BOOT))
    132125                        printf("*");
     
    134127                        printf(" ");
    135128               
    136                 printf("\t%10u %10u %10u %7u\n", it->start_addr, it->start_addr + it->length, it->length, it->type);
     129                printf("\t%10u %10u %10u %7u\n", it->start_addr,
     130                    it->start_addr + it->length, it->length, it->type);
    137131               
    138132                num++;
    139133        }
    140134       
    141         printf("%d partitions found.\n", num);
     135        printf("%u partitions found.\n", num);
    142136       
    143137        return EOK;
     
    146140int read_mbr_parts(label_t *this)
    147141{
    148         int rc;
    149         rc = mbr_read_mbr(this->data.mbr, this->device);
     142        int rc = mbr_read_mbr(this->data.mbr, this->device);
    150143        if (rc != EOK)
    151144                return rc;
     
    164157{
    165158        int rc = mbr_write_partitions(this->data.mbr, this->device);
    166         if (rc != EOK) {
    167                 printf("Error occured during writing: ERR: %d: %s\n", rc, str_error(rc));
    168         }
     159        if (rc != EOK)
     160                printf("Error occured during writing: ERR: %d: %s\n", rc,
     161                    str_error(rc));
    169162       
    170163        return rc;
     
    177170}
    178171
    179 static int set_mbr_partition(tinput_t *in, mbr_part_t *p, label_t * this)
    180 {
    181         int c;
    182         uint8_t type;
    183        
     172static int set_mbr_partition(tinput_t *in, mbr_part_t *partition, label_t *this)
     173{
    184174        printf("Primary (p) or logical (l): ");
    185         c = getchar();
     175        int c = getchar();
    186176        printf("%c\n", c);
    187177
    188178        switch (c) {
    189179        case 'p':
    190                 mbr_set_flag(p, ST_LOGIC, false);
     180                mbr_set_flag(partition, ST_LOGIC, false);
    191181                break;
    192182        case 'l':
    193                 mbr_set_flag(p, ST_LOGIC, true);
     183                mbr_set_flag(partition, ST_LOGIC, true);
    194184                break;
    195185        default:
     
    198188        }
    199189       
    200         printf("Set type (0-255): ");
    201         type = get_input_uint8(in);
    202         if (type == 0 && errno != EOK)
    203                 return errno;
    204 
    205         ///TODO: there can only be one boolabel partition; let's do it just like fdisk
     190        printf("Set type (0 - 255): ");
     191        uint8_t type = get_input_uint8(in);
     192        if ((type == 0) && (errno != EOK))
     193                return errno;
     194       
     195        // FIXME: Make sure there is at most one bootable partition
    206196        printf("Bootable? (y/n): ");
    207197        c = getchar();
    208         if (c != 'y' && c != 'Y' && c != 'n' && c != 'N') {
     198        if ((c != 'y') && (c != 'Y') && (c != 'n') && (c != 'N')) {
    209199                printf("Invalid value. Cancelled.");
    210200                return EINVAL;
    211201        }
     202       
    212203        printf("%c\n", c);
    213         mbr_set_flag(p, ST_BOOT, (c == 'y' || c == 'Y') ? true : false);
    214 
    215 
    216         uint32_t sa, ea;
    217 
     204        mbr_set_flag(partition, ST_BOOT, (c == 'y' || c == 'Y') ? true : false);
     205       
    218206        printf("Set starting address: ");
    219         sa = get_input_uint32(in);
    220         if (sa == 0 && errno != EOK)
    221                 return errno;
    222        
    223         if (this->alignment != 0 && this->alignment != 1 && sa % this->alignment != 0) {
     207        uint32_t sa = get_input_uint32(in);
     208        if ((sa == 0) && (errno != EOK))
     209                return errno;
     210       
     211        if ((this->alignment != 0) && (this->alignment != 1) &&
     212            (sa % this->alignment != 0)) {
    224213                sa = mbr_get_next_aligned(sa, this->alignment);
    225                 printf("Starting address was aligned to %u.\n", sa);
    226         }
    227        
    228         printf("Set end addres (max: %" PRIu64 "): ", this->nblocks);
    229         ea = get_input_uint32(in);
    230         if (ea == 0 && errno != EOK)
     214                printf("Starting address was aligned to %" PRIu32 ".\n", sa);
     215        }
     216       
     217        printf("Set end addres (max: %" PRIu64 "): ", this->blocks);
     218        uint32_t ea = get_input_uint32(in);
     219        if ((ea == 0) && (errno != EOK))
    231220                return errno;
    232221       
     
    236225        }
    237226       
    238         p->type = type;
    239         p->start_addr = sa;
    240         p->length = ea - sa;
    241 
    242         return EOK;
    243 }
    244 
    245 
    246 
    247 
    248 
    249 
     227        partition->type = type;
     228        partition->start_addr = sa;
     229        partition->length = ea - sa;
     230       
     231        return EOK;
     232}
  • uspace/app/hdisk/func_mbr.h

    rd51beba3 r6453e306  
    11/*
    2  * Copyright (c) 2012, 2013 Dominik Taborsky
     2 * Copyright (c) 2012-2013 Dominik Taborsky
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29  /** @addtogroup hdisk
     29/** @addtogroup hdisk
    3030 * @{
    3131 */
     
    3434
    3535#ifndef __FUNC_MBR_H__
    36 #define __FUNC_MBR_H__
     36#define __FUNC_MBR_H__
    3737
    3838#include <loc.h>
    3939#include <tinput.h>
    4040#include <libmbr.h>
    41 
    4241#include "common.h"
    4342
    4443extern int construct_mbr_label(label_t *);
    45 extern int add_mbr_part     (label_t *, tinput_t *);
    46 extern int delete_mbr_part  (label_t *, tinput_t *);
     44extern int add_mbr_part(label_t *, tinput_t *);
     45extern int delete_mbr_part(label_t *, tinput_t *);
    4746extern int destroy_mbr_label(label_t *);
    48 extern int new_mbr_label    (label_t *);
    49 extern int print_mbr_parts  (label_t *);
    50 extern int read_mbr_parts   (label_t *);
    51 extern int write_mbr_parts  (label_t *);
    52 extern int extra_mbr_funcs  (label_t *, tinput_t *);
     47extern int new_mbr_label(label_t *);
     48extern int print_mbr_parts(label_t *);
     49extern int read_mbr_parts(label_t *);
     50extern int write_mbr_parts(label_t *);
     51extern int extra_mbr_funcs(label_t *, tinput_t *);
    5352
    5453#endif
  • uspace/app/hdisk/func_none.c

    rd51beba3 r6453e306  
    11/*
    2  * Copyright (c) 2012, 2013 Dominik Taborsky
     2 * Copyright (c) 2012-2013 Dominik Taborsky
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29  /** @addtogroup hdisk
     29/** @addtogroup hdisk
    3030 * @{
    3131 */
     
    3333 */
    3434
    35 
    3635#include <errno.h>
    37 
    3836#include "func_none.h"
    3937
    4038static void not_implemented(void);
    41 
    4239
    4340int construct_none_label(label_t *this)
     
    4542        this->layout = LYT_NONE;
    4643       
    47         this->add_part      = add_none_part;
    48         this->delete_part   = delete_none_part;
     44        this->add_part = add_none_part;
     45        this->delete_part = delete_none_part;
    4946        this->destroy_label = destroy_none_label;
    50         this->new_label     = new_none_label;
    51         this->print_parts   = print_none_parts;
    52         this->read_parts    = read_none_parts;
    53         this->write_parts   = write_none_parts;
    54         this->extra_funcs   = extra_none_funcs;
     47        this->new_label = new_none_label;
     48        this->print_parts = print_none_parts;
     49        this->read_parts = read_none_parts;
     50        this->write_parts = write_none_parts;
     51        this->extra_funcs = extra_none_funcs;
    5552       
    5653        return EOK;
    5754}
    5855
    59 int add_none_part(label_t *this, tinput_t * in)
     56int add_none_part(label_t *this, tinput_t *in)
    6057{
    6158        not_implemented();
     
    6360}
    6461
    65 int delete_none_part(label_t *this, tinput_t * in)
     62int delete_none_part(label_t *this, tinput_t *in)
    6663{
    6764        not_implemented();
     
    104101}
    105102
    106 static void not_implemented()
     103static void not_implemented(void)
    107104{
    108105        printf("No format selected.\n");
  • uspace/app/hdisk/func_none.h

    rd51beba3 r6453e306  
    11/*
    2  * Copyright (c) 2012, 2013 Dominik Taborsky
     2 * Copyright (c) 2012-2013 Dominik Taborsky
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29  /** @addtogroup hdisk
     29/** @addtogroup hdisk
    3030 * @{
    3131 */
     
    3434
    3535#ifndef __FUNC_NONE_H__
    36 #define __FUNC_NONE_H__
     36#define __FUNC_NONE_H__
    3737
    3838#include <loc.h>
    3939#include <tinput.h>
    40 
    4140#include "common.h"
    4241
    4342extern int construct_none_label(label_t *);
    44 extern int add_none_part     (label_t *, tinput_t *);
    45 extern int delete_none_part  (label_t *, tinput_t *);
     43extern int add_none_part(label_t *, tinput_t *);
     44extern int delete_none_part(label_t *, tinput_t *);
    4645extern int destroy_none_label(label_t *);
    47 extern int new_none_label    (label_t *);
    48 extern int print_none_parts  (label_t *);
    49 extern int read_none_parts   (label_t *);
    50 extern int write_none_parts  (label_t *);
    51 extern int extra_none_funcs  (label_t *, tinput_t *);
     46extern int new_none_label(label_t *);
     47extern int print_none_parts(label_t *);
     48extern int read_none_parts(label_t *);
     49extern int write_none_parts(label_t *);
     50extern int extra_none_funcs(label_t *, tinput_t *);
    5251
    5352#endif
  • uspace/app/hdisk/hdisk.c

    rd51beba3 r6453e306  
    11/*
    2  * Copyright (c) 2012, 2013 Dominik Taborsky
     2 * Copyright (c) 2012-2013 Dominik Taborsky
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29  /** @addtogroup hdisk
     29/** @addtogroup hdisk
    3030 * @{
    3131 */
     
    4747#include <tinput.h>
    4848#include <str_error.h>
    49 
    5049#include "hdisk.h"
    5150#include "input.h"
     
    5453#include "func_none.h"
    5554
    56 int interact(void);
    57 void print_help(void);
    58 void select_label_format(tinput_t *);
    59 void construct_label(layouts_t);
    60 void free_label(void);
    61 int try_read(void);
    62 int try_read_mbr(void);
    63 int try_read_gpt(void);
    64 void set_alignment(tinput_t *);
    65 
     55static int interact(void);
     56static void print_help(void);
     57static void select_label_format(tinput_t *);
     58static void construct_label(layouts_t);
     59static void free_label(void);
     60static int try_read(void);
     61static int try_read_mbr(void);
     62static int try_read_gpt(void);
     63static void set_alignment(tinput_t *);
    6664
    6765static label_t label;
    6866
    69 int main(int argc, char ** argv)
     67int main(int argc, char *argv[])
    7068{
    7169        if (argc == 1) {
    7270                printf("Missing argument. Please specify a device to operate on.\n");
    73                 return -1;
    74         }
    75        
    76         int rc;
     71                return 1;
     72        }
     73       
    7774        service_id_t dev_handle;
    78        
    79         rc = loc_service_get_id(argv[1], &dev_handle, IPC_FLAG_BLOCKING);
     75        int rc = loc_service_get_id(argv[1], &dev_handle, IPC_FLAG_BLOCKING);
    8076        if (rc != EOK) {
    8177                printf("Unknown device. Exiting.\n");
    82                 return -1;
     78                return 2;
    8379        }
    8480       
     
    8985        if (rc != EOK) {
    9086                printf("Error during libblock init: %d - %s.\n", rc, str_error(rc));
    91                 return -1;
    92         }
    93        
    94         aoff64_t nblocks;
    95         rc = block_get_nblocks(dev_handle, &nblocks);
     87                return 3;
     88        }
     89       
     90        aoff64_t blocks;
     91        rc = block_get_nblocks(dev_handle, &blocks);
    9692        block_fini(dev_handle);
    9793        if (rc != EOK) {
    98                 printf(LIBMBR_NAME ": Error while getting number of blocks: %d - %s.\n", rc, str_error(rc));
    99                 return -1;
    100         }
    101        
    102         label.nblocks = nblocks;
     94                printf("Error while getting number of blocks: %d - %s.\n",
     95                    rc, str_error(rc));
     96                return 4;
     97        }
     98       
     99        label.blocks = blocks;
    103100       
    104101        rc = try_read_mbr();
     
    116113       
    117114interact:
    118        
    119         rc = interact();
    120        
    121         return rc;
     115        return interact();
    122116}
    123117
    124118/** Interact with user */
    125 int interact()
    126 {
    127         int input;
    128         tinput_t *in;
    129        
    130         in = tinput_new();
     119int interact(void)
     120{
     121        tinput_t *in = tinput_new();
    131122        if (in == NULL) {
    132123                printf("Failed initing input. Free some memory.\n");
     
    137128        printf("Welcome to hdisk.\nType 'h' for help.\n");
    138129       
    139         while (1) {
     130        while (true) {
    140131                printf("# ");
    141                 input = getchar();
     132                int input = getchar();
    142133                printf("%c\n", input);
    143134               
     
    187178end:
    188179        tinput_destroy(in);
    189        
    190180        return EOK;
    191181}
     
    194184{
    195185        printf(
    196                 "\t 'a' \t\t Add partition.\n"
    197                 "\t 'd' \t\t Delete partition.\n"
    198                 "\t 'e' \t\t Extra functions (per label format).\n"
    199                 "\t 'f' \t\t Switch the format of the partition label.\n"
    200                 "\t 'h' \t\t Prints help. See help for more.\n"
    201                 "\t 'l' \t\t Set alignment.\n"
    202                 "\t 'n' \t\t Create new label (discarding the old one).\n"
    203                 "\t 'p' \t\t Prints label contents.\n"
    204                 "\t 'q' \t\t Quit.\n"
    205                 "\t 'r' \t\t Read label from disk.\n"
    206                 "\t 'w' \t\t Write label to disk.\n"
    207                 );
    208 
    209 }
    210 
    211 void select_label_format(tinput_t * in)
     186            "\t 'a' \t\t Add partition.\n"
     187            "\t 'd' \t\t Delete partition.\n"
     188            "\t 'e' \t\t Extra functions (per label format).\n"
     189            "\t 'f' \t\t Switch the format of the partition label.\n"
     190            "\t 'h' \t\t Prints help. See help for more.\n"
     191            "\t 'l' \t\t Set alignment.\n"
     192            "\t 'n' \t\t Create new label (discarding the old one).\n"
     193            "\t 'p' \t\t Prints label contents.\n"
     194            "\t 'q' \t\t Quit.\n"
     195            "\t 'r' \t\t Read label from disk.\n"
     196            "\t 'w' \t\t Write label to disk.\n");
     197}
     198
     199void select_label_format(tinput_t *in)
    212200{
    213201        printf("Available formats are: \n"
    214                         "1) MBR\n"
    215                         "2) GPT\n"
    216               );
     202            "1) MBR\n"
     203            "2) GPT\n");
    217204       
    218205        uint8_t val = get_input_uint8(in);
     
    253240}
    254241
    255 int try_read()
    256 {
    257        
     242int try_read(void)
     243{
    258244        return label.read_parts(&label);
    259245}
    260246
    261 int try_read_mbr()
     247int try_read_mbr(void)
    262248{
    263249        construct_label(LYT_MBR);
     
    265251}
    266252
    267 int try_read_gpt()
     253int try_read_gpt(void)
    268254{
    269255        construct_label(LYT_GPT);
     
    277263        printf("Alignment set to %u sectors.\n", label.alignment);
    278264}
    279 
    280 
    281 
  • uspace/app/hdisk/hdisk.h

    rd51beba3 r6453e306  
    11/*
    2  * Copyright (c) 2012, 2013 Dominik Taborsky
     2 * Copyright (c) 2012-2013 Dominik Taborsky
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29  /** @addtogroup hdisk
     29/** @addtogroup hdisk
    3030 * @{
    3131 */
    3232/** @file
    3333 */
     34
     35#ifndef __HDISK_H__
     36#define __HDISK_H__
    3437
    3538#include "common.h"
     
    3841        label.layout = LYT_NONE
    3942
     43#endif
  • uspace/app/hdisk/input.c

    rd51beba3 r6453e306  
    11/*
    2  * Copyright (c) 2012, 2013 Dominik Taborsky
     2 * Copyright (c) 2012-2013 Dominik Taborsky
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29  /** @addtogroup hdisk
     29/** @addtogroup hdisk
    3030 * @{
    3131 */
     
    3636#include <errno.h>
    3737#include <stdlib.h>
    38 
    3938#include "input.h"
    4039
    4140typedef int (*conv_f)(const char *, char **, unsigned int, bool, void *);
    42 static int convert(tinput_t * in, conv_f str_f, void * val);
    4341
    44 int get_input_line(tinput_t * in, char ** str)
     42static int convert(tinput_t *, conv_f, void *);
     43
     44int get_input_line(tinput_t *in, char **str)
    4545{
    46         int rc;
    47         rc = tinput_read(in, str);
    48         if (rc == ENOENT) {
    49                 /* User requested exit */
     46        int rc = tinput_read(in, str);
     47        if (rc == ENOENT)
    5048                return EINTR;
    51         }
    52         if (rc != EOK) {
    53                 /* Error in communication with console */
     49       
     50        if (rc != EOK)
    5451                return rc;
    55         }
     52       
    5653        /* Check for empty input. */
    5754        if (str_cmp(*str, "") == 0) {
     
    6057                return EINVAL;
    6158        }
    62 
     59       
    6360        return EOK;
    6461}
    6562
    66 uint8_t get_input_uint8(tinput_t * in)
     63uint8_t get_input_uint8(tinput_t *in)
    6764{
    68         int rc;
    6965        uint32_t val;
    70        
    71         rc = convert(in, (conv_f) str_uint8_t, &val);
    72         if (rc != EOK) {
    73                 errno = rc;
    74                 return 0;
    75         }
    76        
    77         return val;
    78 }
    79 
    80 uint32_t get_input_uint32(tinput_t * in)
    81 {
    82         int rc;
    83         uint32_t val;
    84        
    85         rc = convert(in, (conv_f) str_uint32_t, &val);
    86         if (rc != EOK) {
    87                 errno = rc;
    88                 return 0;
    89         }
    90        
    91         return val;
    92 }
    93 
    94 uint64_t get_input_uint64(tinput_t * in)
    95 {
    96         int rc;
    97         uint64_t val;
    98        
    99         rc = convert(in, (conv_f) str_uint64_t, &val);
    100         if (rc != EOK) {
    101                 errno = rc;
    102                 return 0;
    103         }
    104        
    105         return val;
    106 }
    107 
    108 size_t get_input_size_t(tinput_t * in)
    109 {
    110         int rc;
    111         size_t val;
    112        
    113         rc = convert(in, (conv_f) str_size_t, &val);
     66        int rc = convert(in, (conv_f) str_uint8_t, &val);
    11467        if (rc != EOK) {
    11568                errno = rc;
     
    12174}
    12275
    123 static int convert(tinput_t * in, conv_f str_f, void * val)
     76uint32_t get_input_uint32(tinput_t *in)
    12477{
    125         int rc;
    126         char * str;
     78        uint32_t val;
     79        int rc = convert(in, (conv_f) str_uint32_t, &val);
     80        if (rc != EOK) {
     81                errno = rc;
     82                return 0;
     83        }
    12784       
    128         rc = get_input_line(in, &str);
     85        errno = EOK;
     86        return val;
     87}
     88
     89uint64_t get_input_uint64(tinput_t *in)
     90{
     91        uint64_t val;
     92        int rc = convert(in, (conv_f) str_uint64_t, &val);
     93        if (rc != EOK) {
     94                errno = rc;
     95                return 0;
     96        }
     97       
     98        errno = EOK;
     99        return val;
     100}
     101
     102size_t get_input_size_t(tinput_t *in)
     103{
     104        size_t val;
     105        int rc = convert(in, (conv_f) str_size_t, &val);
     106        if (rc != EOK) {
     107                errno = rc;
     108                return 0;
     109        }
     110       
     111        errno = EOK;
     112        return val;
     113}
     114
     115static int convert(tinput_t *in, conv_f str_f, void *val)
     116{
     117        char *str;
     118        int rc = get_input_line(in, &str);
    129119        if (rc != EOK) {
    130120                printf("Error reading input.\n");
     
    133123       
    134124        rc = str_f(str, NULL, 10, true, val);
    135         if (rc != EOK) {
     125        if (rc != EOK)
    136126                printf("Invalid value.\n");
    137         }
    138127       
    139128        free(str);
    140129        return rc;
    141130}
    142 
  • uspace/app/hdisk/input.h

    rd51beba3 r6453e306  
    11/*
    2  * Copyright (c) 2012, 2013 Dominik Taborsky
     2 * Copyright (c) 2012-2013 Dominik Taborsky
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29  /** @addtogroup hdisk
     29/** @addtogroup hdisk
    3030 * @{
    3131 */
     
    3434
    3535#ifndef __INPUT_H__
    36 #define __INPUT_H__
     36#define __INPUT_H__
    3737
    3838#include <tinput.h>
    3939
    40 extern int              get_input_line(tinput_t * in, char ** str);
    41 extern uint8_t  get_input_uint8(tinput_t * in);
    42 extern uint32_t get_input_uint32(tinput_t * in);
    43 extern uint64_t get_input_uint64(tinput_t * in);
    44 extern size_t   get_input_size_t(tinput_t * in);
     40extern int get_input_line(tinput_t *, char **);
     41extern uint8_t get_input_uint8(tinput_t *);
     42extern uint32_t get_input_uint32(tinput_t *);
     43extern uint64_t get_input_uint64(tinput_t *);
     44extern size_t get_input_size_t(tinput_t *);
    4545
    4646#endif
  • uspace/lib/gpt/global.c

    rd51beba3 r6453e306  
    11/*
    2  * Copyright (c) 2011, 2012, 2013 Dominik Taborsky
     2 * Copyright (c) 2011-2013 Dominik Taborsky
    33 * All rights reserved.
    44 *
     
    4444};
    4545
    46 const struct partition_type gpt_ptypes[] = {
    47         { "Unused entry",                                       "00000000" "0000" "0000" "0000000000000000" }, /* 0 */
    48         { "HelenOS System",                                     "656C6548" "4F6E" "5320" "53797374656D0000" }, /* 1 It says "HelenOS System\0\0" */
    49         { "MBR partition scheme",                       "024DEE41" "33E7" "11D3" "9D690008C781F39F" },
    50         { "EFI System",                                         "C12A7328" "F81F" "11D2" "BA4B00A0C93EC93B" },
    51         { "BIOS Boot",                                          "21686148" "6449" "6E6F" "744E656564454649" },
    52         { "Windows Reserved",                           "E3C9E316" "0B5C" "4DB8" "817DF92DF00215AE" },
    53         { "Windows Basic data",                         "EBD0A0A2" "B9E5" "4433" "87C068B6B72699C7" },
    54         { "Windows LDM metadata",                       "5808C8AA" "7E8F" "42E0" "85D2E1E90434CFB3" },
    55         { "Windows LDM data",                           "AF9B60A0" "1431" "4F62" "BC683311714A69AD" },
    56         { "Windows Recovery Environment",       "DE94BBA4" "06D1" "4D40" "A16ABFD50179D6AC" },
    57         { "Windows IBM GPFS",                           "37AFFC90" "EF7D" "4E96" "91C32D7AE055B174" }, /* 10 */
    58         { "Windows Cluster metadata",           "DB97DBA9" "0840" "4BAE" "97F0FFB9A327C7E1" },
    59         { "HP-UX Data",                                         "75894C1E" "3AEB" "11D3" "B7C17B03A0000000" },
    60         { "HP-UX Service",                                      "E2A1E728" "32E3" "11D6" "A6827B03A0000000" },
    61         { "Linux filesystem data",                      "0FC63DAF" "8483" "4772" "8E793D69D8477DE4" },
    62         { "Linux RAID",                                         "A19D880F" "05FC" "4D3B" "A006743F0F84911E" },
    63         { "Linux Swap",                                         "0657FD6D" "A4AB" "43C4" "84E50933C84B4F4F" },
    64         { "Linux LVM",                                          "E6D6D379" "F507" "44C2" "A23C238F2A3DF928" },
    65         { "Linux filesystem data",                      "933AC7E1" "2EB4" "4F13" "B8440E14E2AEF915" },
    66         { "Linux Reserved",                                     "8DA63339" "0007" "60C0" "C436083AC8230908" },
    67         { "FreeBSD Boot",                                       "83BD6B9D" "7F41" "11DC" "BE0B001560B84F0F" }, /* 20 */
    68         { "FreeBSD Data",                                       "516E7CB4" "6ECF" "11D6" "8FF800022D09712B" },
    69         { "FreeBSD Swap",                                       "516E7CB5" "6ECF" "11D6" "8FF800022D09712B" },
    70         { "FreeBSD UFS",                                        "516E7CB6" "6ECF" "11D6" "8FF800022D09712B" },
    71         { "FreeBSD Vinum VM",                           "516E7CB8" "6ECF" "11D6" "8FF800022D09712B" },
    72         { "FreeBSD ZFS",                                        "516E7CBA" "6ECF" "11D6" "8FF800022D09712B" },
    73         { "Mac OS X HFS+",                                      "48465300" "0000" "11AA" "AA1100306543ECAC" },
    74         { "Mac OS X UFS",                                       "55465300" "0000" "11AA" "AA1100306543ECAC" },
    75         { "Mac OS X ZFS",                                       "6A898CC3" "1DD2" "11B2" "99A6080020736631" },
    76         { "Mac OS X RAID",                                      "52414944" "0000" "11AA" "AA1100306543ECAC" },
    77         { "Mac OS X RAID, offline",                     "52414944" "5F4F" "11AA" "AA1100306543ECAC" }, /* 30 */
    78         { "Mac OS X Boot",                                      "426F6F74" "0000" "11AA" "AA1100306543ECAC" },
    79         { "Mac OS X Label",                                     "4C616265" "6C00" "11AA" "AA1100306543ECAC" },
    80         { "Mac OS X TV Recovery",                       "5265636F" "7665" "11AA" "AA1100306543ECAC" },
    81         { "Mac OS X Core Storage",                      "53746F72" "6167" "11AA" "AA1100306543ECAC" },
    82         { "Solaris Boot",                                       "6A82CB45" "1DD2" "11B2" "99A6080020736631" },
    83         { "Solaris Root",                                       "6A85CF4D" "1DD2" "11B2" "99A6080020736631" },
    84         { "Solaris Swap",                                       "6A87C46F" "1DD2" "11B2" "99A6080020736631" },
    85         { "Solaris Backup",                                     "6A8B642B" "1DD2" "11B2" "99A6080020736631" },
    86         { "Solaris /usr",                                       "6A898CC3" "1DD2" "11B2" "99A6080020736631" },
    87         { "Solaris /var",                                       "6A8EF2E9" "1DD2" "11B2" "99A6080020736631" }, /* 40 */
    88         { "Solaris /home",                                      "6A90BA39" "1DD2" "11B2" "99A6080020736631" },
    89         { "Solaris Alternate sector",           "6A9283A5" "1DD2" "11B2" "99A6080020736631" },
    90         { "Solaris Reserved",                           "6A945A3B" "1DD2" "11B2" "99A6080020736631" },
    91         { "Solaris Reserved",                           "6A9630D1" "1DD2" "11B2" "99A6080020736631" },
    92         { "Solaris Reserved",                           "6A980767" "1DD2" "11B2" "99A6080020736631" },
    93         { "Solaris Reserved",                           "6A96237F" "1DD2" "11B2" "99A6080020736631" },
    94         { "Solaris Reserved",                           "6A8D2AC7" "1DD2" "11B2" "99A6080020736631" },
    95         { "NetBSD Swap",                                        "49F48D32" "B10E" "11DC" "B99B0019D1879648" },
    96         { "NetBSD FFS",                                         "49F48D5A" "B10E" "11DC" "B99B0019D1879648" },
    97         { "NetBSD LFS",                                         "49F48D82" "B10E" "11DC" "B99B0019D1879648" }, /* 50 */
    98         { "NetBSD RAID",                                        "49F48DAA" "B10E" "11DC" "B99B0019D1879648" },
    99         { "NetBSD Concatenated",                        "2DB519C4" "B10F" "11DC" "B99B0019D1879648" },
    100         { "NetBSD Encrypted",                           "2DB519EC" "B10F" "11DC" "B99B0019D1879648" },
    101         { "ChromeOS ChromeOS kernel",           "FE3A2A5D" "4F32" "41A7" "B725ACCC3285A309" },
    102         { "ChromeOS rootfs",                            "3CB8E202" "3B7E" "47DD" "8A3C7FF2A13CFCEC" },
    103         { "ChromeOS future use",                        "2E0A753D" "9E48" "43B0" "8337B15192CB1B5E" },
    104         { "MidnightBSD Boot",                           "85D5E45E" "237C" "11E1" "B4B3E89A8F7FC3A7" },
    105         { "MidnightBSD Data",                           "85D5E45A" "237C" "11E1" "B4B3E89A8F7FC3A7" },
    106         { "MidnightBSD Swap",                           "85D5E45B" "237C" "11E1" "B4B3E89A8F7FC3A7" },
    107         { "MidnightBSD UFS",                            "0394Ef8B" "237E" "11E1" "B4B3E89A8F7FC3A7" }, /* 60 */
    108         { "MidnightBSD Vinum VM",                       "85D5E45C" "237C" "11E1" "B4B3E89A8F7FC3A7" },
    109         { "MidnightBSD ZFS",                            "85D5E45D" "237C" "11E1" "B4B3E89A8F7FC3A7" },
    110         { "Uknown", NULL} /* keep this as the last one! gpt_get_part_type depends on it! */
     46const partition_type_t gpt_ptypes[] = {
     47        { "unused entry",                 "00000000" "0000" "0000" "0000000000000000" }, /* 0 */
     48        { "HelenOS System",               "3dc61fa0" "cf7a" "3ad8" "ac57615029d81a6b" }, /* "HelenOS System" encoded as RFC 4122 UUID, version 3 (MD5 name-based) */
     49        { "MBR partition scheme",         "024dee41" "33e7" "11d3" "9d690008c781f39f" },
     50        { "EFI System",                   "c12a7328" "f81f" "11d2" "ba4b00a0c93ec93b" },
     51        { "BIOS Boot",                    "21686148" "6449" "6e6f" "744e656564454649" },
     52        { "Windows Reserved",             "e3c9e316" "0b5c" "4db8" "817df92df00215ae" },
     53        { "Windows Basic data",           "ebd0a0a2" "b9e5" "4433" "87c068b6b72699c7" },
     54        { "Windows LDM metadata",         "5808c8aa" "7e8f" "42e0" "85d2e1e90434cfb3" },
     55        { "Windows LDM data",             "af9b60a0" "1431" "4f62" "bc683311714a69ad" },
     56        { "Windows Recovery Environment", "de94bba4" "06d1" "4d40" "a16abfd50179d6ac" },
     57        { "Windows IBM GPFS",             "37affc90" "ef7d" "4e96" "91c32d7ae055b174" }, /* 10 */
     58        { "Windows Cluster metadata",     "db97dba9" "0840" "4bae" "97f0ffb9a327c7e1" },
     59        { "HP-UX Data",                   "75894c1e" "3aeb" "11d3" "b7c17b03a0000000" },
     60        { "HP-UX Service",                "e2a1e728" "32e3" "11d6" "a6827b03a0000000" },
     61        { "Linux filesystem data",        "0fc63daf" "8483" "4772" "8e793d69d8477de4" },
     62        { "Linux RAID",                   "a19d880f" "05fc" "4d3b" "a006743f0f84911e" },
     63        { "Linux Swap",                   "0657fd6d" "a4ab" "43c4" "84e50933c84b4f4f" },
     64        { "Linux LVM",                    "e6d6d379" "f507" "44c2" "a23c238f2a3df928" },
     65        { "Linux filesystem data",        "933ac7e1" "2eb4" "4f13" "b8440e14e2aef915" },
     66        { "Linux Reserved",               "8da63339" "0007" "60c0" "c436083ac8230908" },
     67        { "FreeBSD Boot",                 "83bd6b9d" "7f41" "11dc" "be0b001560b84f0f" }, /* 20 */
     68        { "FreeBSD Data",                 "516e7cb4" "6ecf" "11d6" "8ff800022d09712b" },
     69        { "FreeBSD Swap",                 "516e7cb5" "6ecf" "11d6" "8ff800022d09712b" },
     70        { "FreeBSD UFS",                  "516e7cb6" "6ecf" "11d6" "8ff800022d09712b" },
     71        { "FreeBSD Vinum VM",             "516e7cb8" "6ecf" "11d6" "8ff800022d09712b" },
     72        { "FreeBSD ZFS",                  "516e7cba" "6ecf" "11d6" "8ff800022d09712b" },
     73        { "Mac OS X HFS+",                "48465300" "0000" "11aa" "aa1100306543ecac" },
     74        { "Mac OS X UFS",                 "55465300" "0000" "11aa" "aa1100306543ecac" },
     75        { "Mac OS X ZFS",                 "6a898cc3" "1dd2" "11b2" "99a6080020736631" },
     76        { "Mac OS X RAID",                "52414944" "0000" "11aa" "aa1100306543ecac" },
     77        { "Mac OS X RAID, offline",       "52414944" "5f4f" "11aa" "aa1100306543ecac" }, /* 30 */
     78        { "Mac OS X Boot",                "426f6f74" "0000" "11aa" "aa1100306543ecac" },
     79        { "Mac OS X Label",               "4c616265" "6c00" "11aa" "aa1100306543ecac" },
     80        { "Mac OS X TV Recovery",         "5265636f" "7665" "11aa" "aa1100306543ecac" },
     81        { "Mac OS X Core Storage",        "53746f72" "6167" "11aa" "aa1100306543ecac" },
     82        { "Solaris Boot",                 "6a82cb45" "1dd2" "11b2" "99a6080020736631" },
     83        { "Solaris Root",                 "6a85cf4d" "1dd2" "11b2" "99a6080020736631" },
     84        { "Solaris Swap",                 "6a87c46f" "1dd2" "11b2" "99a6080020736631" },
     85        { "Solaris Backup",               "6a8b642b" "1dd2" "11b2" "99a6080020736631" },
     86        { "Solaris /usr",                 "6a898cc3" "1dd2" "11b2" "99a6080020736631" },
     87        { "Solaris /var",                 "6a8ef2e9" "1dd2" "11b2" "99a6080020736631" }, /* 40 */
     88        { "Solaris /home",                "6a90ba39" "1dd2" "11b2" "99a6080020736631" },
     89        { "Solaris Alternate sector",     "6a9283a5" "1dd2" "11b2" "99a6080020736631" },
     90        { "Solaris Reserved",             "6a945a3b" "1dd2" "11b2" "99a6080020736631" },
     91        { "Solaris Reserved",             "6a9630d1" "1dd2" "11b2" "99a6080020736631" },
     92        { "Solaris Reserved",             "6a980767" "1dd2" "11b2" "99a6080020736631" },
     93        { "Solaris Reserved",             "6a96237f" "1dd2" "11b2" "99a6080020736631" },
     94        { "Solaris Reserved",             "6a8d2ac7" "1dd2" "11b2" "99a6080020736631" },
     95        { "NetBSD Swap",                  "49f48d32" "b10e" "11dc" "b99b0019d1879648" },
     96        { "NetBSD FFS",                   "49f48d5a" "b10e" "11dc" "b99b0019d1879648" },
     97        { "NetBSD LFS",                   "49f48d82" "b10e" "11dc" "b99b0019d1879648" }, /* 50 */
     98        { "NetBSD RAID",                  "49f48daa" "b10e" "11dc" "b99b0019d1879648" },
     99        { "NetBSD Concatenated",          "2db519c4" "b10f" "11dc" "b99b0019d1879648" },
     100        { "NetBSD Encrypted",             "2db519ec" "b10f" "11dc" "b99b0019d1879648" },
     101        { "ChromeOS ChromeOS kernel",     "fe3a2a5d" "4f32" "41a7" "b725accc3285a309" },
     102        { "ChromeOS rootfs",              "3cb8e202" "3b7e" "47dd" "8a3c7ff2a13cfcec" },
     103        { "ChromeOS future use",          "2e0a753d" "9e48" "43b0" "8337b15192cb1b5e" },
     104        { "MidnightBSD Boot",             "85d5e45e" "237c" "11e1" "b4b3e89a8f7fc3a7" },
     105        { "MidnightBSD Data",             "85d5e45a" "237c" "11e1" "b4b3e89a8f7fc3a7" },
     106        { "MidnightBSD Swap",             "85d5e45b" "237c" "11e1" "b4b3e89a8f7fc3a7" },
     107        { "MidnightBSD UFS",              "0394ef8b" "237e" "11e1" "b4b3e89a8f7fc3a7" }, /* 60 */
     108        { "MidnightBSD Vinum VM",         "85d5e45c" "237c" "11e1" "b4b3e89a8f7fc3a7" },
     109        { "MidnightBSD ZFS",              "85d5e45d" "237c" "11e1" "b4b3e89a8f7fc3a7" },
     110        { "unknown entry",                NULL } /* Keep this as the last entry */
    111111};
    112 
    113 
    114 
  • uspace/lib/gpt/gpt.h

    rd51beba3 r6453e306  
    11/*
    22 * Copyright (c) 2009 Jiri Svoboda
    3  * Copyright (c) 2011, 2012, 2013 Dominik Taborsky
     3 * Copyright (c) 2011-2013 Dominik Taborsky
    44 * All rights reserved.
    55 *
     
    4343        AT_UNDEFINED,
    4444        AT_SPECIFIC = 48
    45 } GPT_ATTR;
     45} gpt_attr_t;
    4646
    47 /** GPT header
    48  * - all in little endian.
    49  */
     47/** GPT header */
    5048typedef struct {
    51         uint8_t  efi_signature[8];
    52         uint8_t  revision[4];
     49        uint8_t efi_signature[8];
     50        uint8_t revision[4];
    5351        uint32_t header_size;
    5452        uint32_t header_crc32;
    5553        uint32_t reserved;
    56         uint64_t my_lba;
     54        uint64_t current_lba;
    5755        uint64_t alternate_lba;
    5856        uint64_t first_usable_lba;
    5957        uint64_t last_usable_lba;
    60         uint8_t  disk_guid[16];
     58        uint8_t disk_guid[16];
    6159        uint64_t entry_lba;
    6260        uint32_t fillries;
     
    7674
    7775#endif
    78 
    79 
  • uspace/lib/gpt/libgpt.c

    rd51beba3 r6453e306  
    11/*
    2  * Copyright (c) 2011, 2012, 2013 Dominik Taborsky
     2 * Copyright (c) 2011-2013 Dominik Taborsky
    33 * All rights reserved.
    44 *
     
    3434
    3535/* TODO:
    36  * This implementation only supports fixed size partition entries. Specification
    37  * requires otherwise, though. Use void * array and casting to achieve that.
     36 * The implementation currently supports fixed size partition entries only.
     37 * The specification requires otherwise, though.
    3838 */
    3939
     
    4646#include <assert.h>
    4747#include <byteorder.h>
    48 #include <checksum.h>
     48#include <adt/checksum.h>
    4949#include <mem.h>
    5050#include <sys/typefmt.h>
    5151#include <mbr.h>
    52 
    53 
     52#include <align.h>
    5453#include "libgpt.h"
    5554
    5655static int load_and_check_header(service_id_t, aoff64_t, size_t, gpt_header_t *);
    57 static gpt_partitions_t * alloc_part_array(uint32_t);
     56static gpt_partitions_t *alloc_part_array(uint32_t);
    5857static int extend_part_array(gpt_partitions_t *);
    5958static int reduce_part_array(gpt_partitions_t *);
     
    6261static bool check_encaps(gpt_part_t *, uint64_t, uint64_t);
    6362
    64 /** Allocate memory for gpt label */
    65 gpt_label_t * gpt_alloc_label(void)
     63/** Allocate a GPT label */
     64gpt_label_t *gpt_alloc_label(void)
    6665{
    6766        gpt_label_t *label = malloc(sizeof(gpt_label_t));
     
    6968                return NULL;
    7069       
    71         /* This is necessary so that gpt_part_foreach does not segfault */
    7270        label->parts = gpt_alloc_partitions();
    73         if (label == NULL) {
     71        if (label->parts == NULL) {
    7472                free(label);
    7573                return NULL;
     
    7775       
    7876        label->gpt = NULL;
    79        
    8077        label->device = 0;
    8178       
     
    8380}
    8481
    85 /** Free gpt_label_t structure */
     82/** Free a GPT label */
    8683void gpt_free_label(gpt_label_t *label)
    8784{
     
    9592}
    9693
    97 /** Allocate memory for gpt header */
    98 gpt_t * gpt_alloc_header(size_t size)
     94/** Allocate a GPT header */
     95gpt_t *gpt_alloc_header(size_t size)
    9996{
    10097        gpt_t *gpt = malloc(sizeof(gpt_t));
     
    10299                return NULL;
    103100       
    104         /* 
    105          * We might need only sizeof(gpt_header_t), but we should follow 
     101        /*
     102         * We might need only sizeof(gpt_header_t), but we should follow
    106103         * specs and have zeroes through all the rest of the block
    107104         */
    108         size_t final_size = size > sizeof(gpt_header_t) ? size : sizeof(gpt_header_t);
     105        size_t final_size = max(size, sizeof(gpt_header_t));
    109106        gpt->header = malloc(final_size);
    110107        if (gpt->header == NULL) {
     
    113110        }
    114111       
    115         /* Enter some sane defaults. */
    116112        memset(gpt->header, 0, final_size);
    117113        memcpy(gpt->header->efi_signature, efi_signature, 8);
     
    121117        gpt->header->entry_size = host2uint32_t_le(sizeof(gpt_entry_t));
    122118       
    123        
    124119        return gpt;
    125120}
    126121
    127 /** free() GPT header including gpt->header_lba */
     122/** Free a GPT header */
    128123void gpt_free_gpt(gpt_t *gpt)
    129124{
     
    132127}
    133128
    134 /** Read GPT from specific device
    135  * @param label        label structure to fill
    136  * @param dev_handle   device to read GPT from
    137  *
    138  * @return             EOK on success, errorcode on error
     129/** Read GPT from a device
     130 *
     131 * @param label      Label to read.
     132 * @param dev_handle Device to read GPT from.
     133 *
     134 * @return EOK on success, error code on error.
     135 *
    139136 */
    140137int gpt_read_header(gpt_label_t *label, service_id_t dev_handle)
    141138{
    142         int rc;
    143         size_t b_size;
    144        
    145         rc = block_init(EXCHANGE_ATOMIC, dev_handle, 512);
    146         if (rc != EOK)
    147                 goto fail;
    148        
    149         rc = block_get_bsize(dev_handle, &b_size);
    150         if (rc != EOK)
    151                 goto fini_fail;
     139        int rc = block_init(EXCHANGE_ATOMIC, dev_handle, 512);
     140        if (rc != EOK)
     141                return rc;
     142       
     143        size_t block_size;
     144        rc = block_get_bsize(dev_handle, &block_size);
     145        if (rc != EOK)
     146                goto end;
    152147       
    153148        if (label->gpt == NULL) {
    154                 label->gpt = gpt_alloc_header(b_size);
     149                label->gpt = gpt_alloc_header(block_size);
    155150                if (label->gpt == NULL) {
    156151                        rc = ENOMEM;
    157                         goto fini_fail;
     152                        goto end;
    158153                }
    159154        }
    160155       
    161         rc = load_and_check_header(dev_handle, GPT_HDR_BA, b_size, label->gpt->header);
    162         if (rc == EBADCHECKSUM || rc == EINVAL) {
    163                 aoff64_t n_blocks;
    164                 rc = block_get_nblocks(dev_handle, &n_blocks);
    165                 if (rc != EOK)
    166                         goto free_fail;
    167 
    168                 rc = load_and_check_header(dev_handle, n_blocks - 1, b_size, label->gpt->header);
    169                 if (rc == EBADCHECKSUM || rc == EINVAL)
    170                         goto free_fail;
     156        rc = load_and_check_header(dev_handle, GPT_HDR_BA, block_size,
     157            label->gpt->header);
     158        if ((rc == EBADCHECKSUM) || (rc == EINVAL)) {
     159                aoff64_t blocks;
     160                rc = block_get_nblocks(dev_handle, &blocks);
     161                if (rc != EOK) {
     162                        gpt_free_gpt(label->gpt);
     163                        goto end;
     164                }
     165               
     166                rc = load_and_check_header(dev_handle, blocks - 1, block_size,
     167                    label->gpt->header);
     168                if ((rc == EBADCHECKSUM) || (rc == EINVAL)) {
     169                        gpt_free_gpt(label->gpt);
     170                        goto end;
     171                }
    171172        }
    172173       
    173174        label->device = dev_handle;
     175        rc = EOK;
     176       
     177end:
    174178        block_fini(dev_handle);
    175         return EOK;
    176        
    177 free_fail:
    178         gpt_free_gpt(label->gpt);
    179         label->gpt = NULL;
    180 fini_fail:
    181         block_fini(dev_handle);
    182 fail:
    183179        return rc;
    184180}
    185181
    186182/** Write GPT header to device
    187  * @param label        GPT label header to be written
    188  * @param dev_handle   device handle to write the data to
    189  *
    190  * @return             EOK on success, libblock error code otherwise
    191  *
    192  * Note: Firstly write partitions (if modified), then gpt header.
     183 *
     184 * @param label        Label to be written.
     185 * @param dev_handle   Device to write the GPT to.
     186 *
     187 * @return EOK on success, libblock error code otherwise.
     188 *
    193189 */
    194190int gpt_write_header(gpt_label_t *label, service_id_t dev_handle)
    195191{
    196         int rc;
    197         size_t b_size;
    198        
    199192        /* The comm_size argument (the last one) is ignored */
    200         rc = block_init(EXCHANGE_ATOMIC, dev_handle, 4096);
    201         if (rc != EOK && rc != EEXIST)
     193        int rc = block_init(EXCHANGE_ATOMIC, dev_handle, 4096);
     194        if ((rc != EOK) && (rc != EEXIST))
    202195                return rc;
    203196       
    204         rc = block_get_bsize(dev_handle, &b_size);
    205         if (rc != EOK)
    206                 return rc;
    207        
    208         aoff64_t n_blocks;
    209         rc = block_get_nblocks(dev_handle, &n_blocks);
    210         if (rc != EOK) {
    211                 block_fini(dev_handle);
    212                 return rc;
    213         }
    214        
    215         uint64_t tmp;
     197        size_t block_size;
     198        rc = block_get_bsize(dev_handle, &block_size);
     199        if (rc != EOK)
     200                goto end;
     201       
     202        aoff64_t blocks;
     203        rc = block_get_nblocks(dev_handle, &blocks);
     204        if (rc != EOK)
     205                goto end;
    216206       
    217207        gpt_set_random_uuid(label->gpt->header->disk_guid);
    218208       
    219209        /* Prepare the backup header */
    220         label->gpt->header->alternate_lba = label->gpt->header->my_lba;
    221         label->gpt->header->my_lba = host2uint64_t_le(n_blocks - 1);
    222        
    223         tmp = label->gpt->header->entry_lba;
    224         label->gpt->header->entry_lba = host2uint64_t_le(n_blocks -
    225             (uint32_t_le2host(label->gpt->header->fillries) * sizeof(gpt_entry_t))
    226             / b_size - 1);
     210        label->gpt->header->alternate_lba = label->gpt->header->current_lba;
     211        label->gpt->header->current_lba = host2uint64_t_le(blocks - 1);
     212       
     213        uint64_t lba = label->gpt->header->entry_lba;
     214        label->gpt->header->entry_lba = host2uint64_t_le(blocks -
     215            (uint32_t_le2host(label->gpt->header->fillries) *
     216            sizeof(gpt_entry_t)) / block_size - 1);
    227217       
    228218        label->gpt->header->header_crc32 = 0;
    229         label->gpt->header->header_crc32 = host2uint32_t_le(
    230             compute_crc32((uint8_t *) label->gpt->header,
    231                 uint32_t_le2host(label->gpt->header->header_size)));
     219        label->gpt->header->header_crc32 =
     220            host2uint32_t_le(compute_crc32((uint8_t *) label->gpt->header,
     221            uint32_t_le2host(label->gpt->header->header_size)));
    232222       
    233223        /* Write to backup GPT header location */
    234         rc = block_write_direct(dev_handle, n_blocks - 1, GPT_HDR_BS, label->gpt->header);
    235         if (rc != EOK) {
    236                 block_fini(dev_handle);
    237                 return rc;
    238         }
    239        
     224        rc = block_write_direct(dev_handle, blocks - 1, GPT_HDR_BS,
     225            label->gpt->header);
     226        if (rc != EOK)
     227                goto end;
    240228       
    241229        /* Prepare the main header */
    242         label->gpt->header->entry_lba = tmp;
    243        
    244         tmp = label->gpt->header->alternate_lba;
    245         label->gpt->header->alternate_lba = label->gpt->header->my_lba;
    246         label->gpt->header->my_lba = tmp;
     230        label->gpt->header->entry_lba = lba;
     231       
     232        lba = label->gpt->header->alternate_lba;
     233        label->gpt->header->alternate_lba = label->gpt->header->current_lba;
     234        label->gpt->header->current_lba = lba;
    247235       
    248236        label->gpt->header->header_crc32 = 0;
    249         label->gpt->header->header_crc32 = host2uint32_t_le(
    250             compute_crc32((uint8_t *) label->gpt->header,
    251                 uint32_t_le2host(label->gpt->header->header_size)));
     237        label->gpt->header->header_crc32 =
     238            host2uint32_t_le(compute_crc32((uint8_t *) label->gpt->header,
     239            uint32_t_le2host(label->gpt->header->header_size)));
    252240       
    253241        /* Write to main GPT header location */
    254         rc = block_write_direct(dev_handle, GPT_HDR_BA, GPT_HDR_BS, label->gpt->header);
    255         if (rc != EOK)
    256                 return rc;
     242        rc = block_write_direct(dev_handle, GPT_HDR_BA, GPT_HDR_BS,
     243            label->gpt->header);
     244        if (rc != EOK)
     245                goto end;
    257246       
    258247        /* Write Protective MBR */
    259248        br_block_t mbr;
    260249        memset(&mbr, 0, 512);
     250       
    261251        memset(mbr.pte[0].first_chs, 1, 3);
    262252        mbr.pte[0].ptype = 0xEE;
    263         memset(mbr.pte[0].last_chs, 0xFF, 3);
     253        memset(mbr.pte[0].last_chs, 0xff, 3);
    264254        mbr.pte[0].first_lba = host2uint32_t_le(1);
    265         mbr.pte[0].length = 0xFFFFFFFF;
     255        mbr.pte[0].length = 0xffffffff;
    266256        mbr.signature = host2uint16_t_le(BR_SIGNATURE);
    267257       
    268258        rc = block_write_direct(dev_handle, 0, 1, &mbr);
     259       
     260end:
    269261        block_fini(dev_handle);
    270         if (rc != EOK)
    271                 return rc;
    272        
    273         return 0;
     262        return rc;
    274263}
    275264
    276265/** Alloc partition array */
    277 gpt_partitions_t * gpt_alloc_partitions()
     266gpt_partitions_t *gpt_alloc_partitions(void)
    278267{
    279268        return alloc_part_array(GPT_MIN_PART_NUM);
     
    281270
    282271/** Parse partitions from GPT
    283  * @param label   GPT label to be parsed
    284  *
    285  * @return        EOK on success, errorcode otherwise
     272 *
     273 * @param label GPT label to be parsed.
     274 *
     275 * @return EOK on success, error code otherwise.
     276 *
    286277 */
    287278int gpt_read_partitions(gpt_label_t *label)
    288279{
    289         int rc;
    290         unsigned int i;
    291280        uint32_t fillries = uint32_t_le2host(label->gpt->header->fillries);
    292281        uint32_t ent_size = uint32_t_le2host(label->gpt->header->entry_size);
     
    295284        if (label->parts == NULL) {
    296285                label->parts = alloc_part_array(fillries);
    297                 if (label->parts == NULL) {
     286                if (label->parts == NULL)
    298287                        return ENOMEM;
    299                 }
    300         }
    301 
    302         /* comm_size is ignored */
    303         rc = block_init(EXCHANGE_SERIALIZE, label->device, sizeof(gpt_entry_t));
    304         if (rc != EOK)
    305                 goto fail;
    306 
     288        }
     289       
     290        int rc = block_init(EXCHANGE_SERIALIZE, label->device,
     291            sizeof(gpt_entry_t));
     292        if (rc != EOK) {
     293                gpt_free_partitions(label->parts);
     294                label->parts = NULL;
     295                goto end;
     296        }
     297       
    307298        size_t block_size;
    308299        rc = block_get_bsize(label->device, &block_size);
    309         if (rc != EOK)
    310                 goto fini_fail;
    311 
     300        if (rc != EOK) {
     301                gpt_free_partitions(label->parts);
     302                label->parts = NULL;
     303                goto end;
     304        }
     305       
    312306        aoff64_t pos = ent_lba * block_size;
    313 
    314         /*
    315          * Now we read just sizeof(gpt_entry_t) bytes for each entry from the device.
    316          * Hopefully, this does not bypass cache (no mention in libblock.c),
    317          * and also allows us to have variable partition entry size (but we
    318          * will always read just sizeof(gpt_entry_t) bytes - hopefully they
    319          * don't break backward compatibility)
    320          */
    321         for (i = 0; i < fillries; ++i) {
    322                 /*FIXME: this does bypass cache... */
    323                 rc = block_read_bytes_direct(label->device, pos, sizeof(gpt_entry_t), label->parts->part_array + i);
    324                 /*
    325                  * FIXME: but seqread() is just too complex...
    326                  * rc = block_seqread(gpt->device, &bufpos, &buflen, &pos, res->part_array[i], sizeof(gpt_entry_t));
    327                  */
     307       
     308        for (uint32_t i = 0; i < fillries; i++) {
     309                rc = block_read_bytes_direct(label->device, pos, sizeof(gpt_entry_t),
     310                    label->parts->part_array + i);
    328311                pos += ent_size;
    329 
    330                 if (rc != EOK)
    331                         goto fini_fail;
    332         }
    333        
    334         uint32_t crc = compute_crc32((uint8_t *) label->parts->part_array,
    335                            fillries * ent_size);
    336 
    337         if (uint32_t_le2host(label->gpt->header->pe_array_crc32) != crc)
    338         {
     312               
     313                if (rc != EOK) {
     314                        gpt_free_partitions(label->parts);
     315                        label->parts = NULL;
     316                        goto end;
     317                }
     318        }
     319       
     320        uint32_t crc = compute_crc32((uint8_t *) label->parts->part_array,
     321            fillries * ent_size);
     322       
     323        if (uint32_t_le2host(label->gpt->header->pe_array_crc32) != crc) {
    339324                rc = EBADCHECKSUM;
    340                 goto fini_fail;
    341         }
    342        
     325                gpt_free_partitions(label->parts);
     326                label->parts = NULL;
     327                goto end;
     328        }
     329       
     330        rc = EOK;
     331       
     332end:
    343333        block_fini(label->device);
    344         return EOK;
    345        
    346 fini_fail:
    347         block_fini(label->device);
    348        
    349 fail:
    350         gpt_free_partitions(label->parts);
    351         label->parts = NULL;
    352334        return rc;
    353335}
    354336
    355337/** Write GPT and partitions to device
    356  * Note: also writes the header.
    357  * @param label        label to write
    358  * @param dev_handle   device to write the data to
    359  *
    360  * @return             returns EOK on succes, errorcode otherwise
     338 *
     339 * Note: Also writes the header.
     340 *
     341 * @param label      Label to write.
     342 * @param dev_handle Device to write the data to.
     343 *
     344 * @return EOK on succes, error code otherwise
     345 *
    361346 */
    362347int gpt_write_partitions(gpt_label_t *label, service_id_t dev_handle)
    363348{
    364         int rc;
    365         size_t b_size;
    366        
    367349        /* comm_size of 4096 is ignored */
    368         rc = block_init(EXCHANGE_ATOMIC, dev_handle, 4096);
    369         if (rc != EOK && rc != EEXIST)
     350        int rc = block_init(EXCHANGE_ATOMIC, dev_handle, 4096);
     351        if ((rc != EOK) && (rc != EEXIST))
    370352                return rc;
    371353       
    372         rc = block_get_bsize(dev_handle, &b_size);
     354        size_t block_size;
     355        rc = block_get_bsize(dev_handle, &block_size);
    373356        if (rc != EOK)
    374357                goto fail;
    375358       
    376         aoff64_t n_blocks;
    377         rc = block_get_nblocks(dev_handle, &n_blocks);
     359        aoff64_t blocks;
     360        rc = block_get_nblocks(dev_handle, &blocks);
    378361        if (rc != EOK)
    379362                goto fail;
    380363       
    381         /* When we're creating a new label from scratch, we need to fill
    382          * the header with sensible defaults. */
    383         if (label->gpt == NULL) {
    384                 label->gpt = gpt_alloc_header(b_size);
    385         }
    386        
    387         uint32_t e_size = uint32_t_le2host(label->gpt->header->entry_size);
    388         size_t fillries = label->parts->fill > GPT_MIN_PART_NUM ? label->parts->fill : GPT_MIN_PART_NUM;
    389        
    390         if (e_size != sizeof(gpt_entry_t))
     364        if (label->gpt == NULL)
     365                label->gpt = gpt_alloc_header(block_size);
     366       
     367        uint32_t entry_size =
     368            uint32_t_le2host(label->gpt->header->entry_size);
     369        size_t fillries = (label->parts->fill > GPT_MIN_PART_NUM) ?
     370            label->parts->fill : GPT_MIN_PART_NUM;
     371       
     372        if (entry_size != sizeof(gpt_entry_t))
    391373                return ENOTSUP;
    392 
     374       
    393375        label->gpt->header->fillries = host2uint32_t_le(fillries);
    394         uint64_t arr_blocks = (fillries * sizeof(gpt_entry_t)) / b_size;
    395         uint64_t gpt_space = arr_blocks + GPT_HDR_BS + 1; /* +1 for Protective MBR */
     376       
     377        uint64_t arr_blocks = (fillries * sizeof(gpt_entry_t)) / block_size;
     378       
     379        /* Include Protective MBR */
     380        uint64_t gpt_space = arr_blocks + GPT_HDR_BS + 1;
     381       
    396382        label->gpt->header->first_usable_lba = host2uint64_t_le(gpt_space);
    397         label->gpt->header->last_usable_lba = host2uint64_t_le(n_blocks - gpt_space - 1);
     383        label->gpt->header->last_usable_lba =
     384            host2uint64_t_le(blocks - gpt_space - 1);
    398385       
    399386        /* Perform checks */
     
    402389                        continue;
    403390               
    404                 if (!check_encaps(p, n_blocks, gpt_space)) {
     391                if (!check_encaps(p, blocks, gpt_space)) {
    405392                        rc = ERANGE;
    406393                        goto fail;
     
    420407        }
    421408       
    422         label->gpt->header->pe_array_crc32 = host2uint32_t_le(compute_crc32(
    423                                        (uint8_t *) label->parts->part_array,
    424                                        fillries * e_size));
    425        
     409        label->gpt->header->pe_array_crc32 =
     410            host2uint32_t_le(compute_crc32((uint8_t *) label->parts->part_array,
     411            fillries * entry_size));
    426412       
    427413        /* Write to backup GPT partition array location */
    428         rc = block_write_direct(dev_handle, n_blocks - arr_blocks - 1,
    429                  arr_blocks, label->parts->part_array);
     414        rc = block_write_direct(dev_handle, blocks - arr_blocks - 1,
     415            arr_blocks, label->parts->part_array);
    430416        if (rc != EOK)
    431417                goto fail;
    432418       
    433419        /* Write to main GPT partition array location */
    434         rc = block_write_direct(dev_handle, uint64_t_le2host(label->gpt->header->entry_lba),
    435                  arr_blocks, label->parts->part_array);
     420        rc = block_write_direct(dev_handle,
     421            uint64_t_le2host(label->gpt->header->entry_lba),
     422            arr_blocks, label->parts->part_array);
    436423        if (rc != EOK)
    437424                goto fail;
     
    444431}
    445432
    446 /** Alloc new partition
    447  *
    448  * @return        returns pointer to the new partition or NULL
    449  *
    450  * Note: use either gpt_alloc_partition or gpt_get_partition.
     433/** Allocate a new partition
     434 *
     435 * Note: Use either gpt_alloc_partition() or gpt_get_partition().
    451436 * This returns a memory block (zero-filled) and needs gpt_add_partition()
    452437 * to be called to insert it into a partition array.
    453438 * Requires you to call gpt_free_partition afterwards.
    454  */
    455 gpt_part_t * gpt_alloc_partition(void)
    456 {
    457         gpt_part_t *p = malloc(sizeof(gpt_part_t));
    458         if (p == NULL)
     439 *
     440 * @return Pointer to the new partition or NULL.
     441 *
     442 */
     443gpt_part_t *gpt_alloc_partition(void)
     444{
     445        gpt_part_t *partition = malloc(sizeof(gpt_part_t));
     446        if (partition == NULL)
    459447                return NULL;
    460448       
    461         memset(p, 0, sizeof(gpt_part_t));
    462        
    463         return p;
    464 }
    465 
    466 /** Alloc new partition already inside the label
    467  *
    468  * @param label   label to carry new partition
    469  *
    470  * @return        returns pointer to the new partition or NULL on ENOMEM
    471  *
    472  * Note: use either gpt_alloc_partition or gpt_get_partition.
     449        memset(partition, 0, sizeof(gpt_part_t));
     450       
     451        return partition;
     452}
     453
     454/** Allocate a new partition already inside the label
     455 *
     456 * Note: Use either gpt_alloc_partition() or gpt_get_partition().
    473457 * This one returns a pointer to the first empty structure already
    474458 * inside the array, so don't call gpt_add_partition() afterwards.
    475459 * This is the one you will usually want.
    476  */
    477 gpt_part_t * gpt_get_partition(gpt_label_t *label)
    478 {
    479         gpt_part_t *p;
    480        
     460 *
     461 * @param label Label to carry new partition.
     462 *
     463 * @return Pointer to the new partition or NULL.
     464 *
     465 */
     466gpt_part_t *gpt_get_partition(gpt_label_t *label)
     467{
     468        gpt_part_t *partition;
    481469       
    482470        /* Find the first empty entry */
     
    487475                }
    488476               
    489                 p = label->parts->part_array + label->parts->fill++;
    490                
    491         } while (gpt_get_part_type(p) != GPT_PTE_UNUSED);
    492        
    493         return p;
     477                partition = label->parts->part_array + label->parts->fill++;
     478        } while (gpt_get_part_type(partition) != GPT_PTE_UNUSED);
     479       
     480        return partition;
    494481}
    495482
    496483/** Get partition already inside the label
    497484 *
    498  * @param label   label to carrying the partition
    499  * @param idx     index of the partition
    500  *
    501  * @return        returns pointer to the partition
    502  *                or NULL when out of range
    503  *
    504  * Note: For new partitions use either gpt_alloc_partition or
    505  * gpt_get_partition unless you want a partition at a specific place.
     485 * Note: For new partitions use either gpt_alloc_partition() or
     486 * gpt_get_partition() unless you want a partition at a specific place.
    506487 * This returns a pointer to a structure already inside the array,
    507488 * so don't call gpt_add_partition() afterwards.
     
    510491 * for indexes smaller than either 128 or the actual number of filled
    511492 * entries.
    512  */
    513 gpt_part_t * gpt_get_partition_at(gpt_label_t *label, size_t idx)
    514 {
    515         return NULL;
    516        
    517         if (idx >= GPT_MIN_PART_NUM && idx >= label->parts->fill)
     493 *
     494 * @param label Label to carrying the partition.
     495 * @param idx   Index of the partition.
     496 *
     497 * @return Pointer to the partition or NULL when out of range.
     498 *
     499 */
     500gpt_part_t *gpt_get_partition_at(gpt_label_t *label, size_t idx)
     501{
     502        if ((idx >= GPT_MIN_PART_NUM) && (idx >= label->parts->fill))
    518503                return NULL;
    519504       
     
    523508/** Copy partition into partition array
    524509 *
    525  * @param parts                 target label
    526  * @param partition             source partition to copy
    527  *
    528  * @return                              -1 on error, 0 otherwise
    529  *
    530  * Note: for use with gpt_alloc_partition() only. You will get
     510 * Note: For use with gpt_alloc_partition() only. You will get
    531511 * duplicates with gpt_get_partition().
    532  * Note: does not call gpt_free_partition()!
     512 * Note: Does not call gpt_free_partition()!
     513 *
     514 * @param parts     Target label
     515 * @param partition Source partition to copy
     516 *
     517 * @return EOK on succes, error code otherwise
     518 *
    533519 */
    534520int gpt_add_partition(gpt_label_t *label, gpt_part_t *partition)
    535521{
    536         gpt_part_t *p;
    537522        /* Find the first empty entry */
     523       
     524        gpt_part_t *part;
     525       
    538526        do {
    539527                if (label->parts->fill == label->parts->arr_size) {
     
    542530                }
    543531               
    544                 p = label->parts->part_array + label->parts->fill++;
    545                
    546         } while (gpt_get_part_type(p) != GPT_PTE_UNUSED);
    547        
    548        
    549         memcpy(p, partition, sizeof(gpt_entry_t));
    550        
    551        
     532                part = label->parts->part_array + label->parts->fill++;
     533        } while (gpt_get_part_type(part) != GPT_PTE_UNUSED);
     534       
     535        memcpy(part, partition, sizeof(gpt_entry_t));
    552536        return EOK;
    553537}
    554538
    555539/** Remove partition from array
    556  * @param label   label to remove from
    557  * @param idx     index of the partition to remove
    558  *
    559  * @return        EOK on success, ENOMEM on array reduction failure
    560  *
    561  * Note: even if it fails, the partition still gets removed. Only
     540 *
     541 * Note: Even if it fails, the partition still gets removed. Only
    562542 * reducing the array failed.
     543 *
     544 * @param label Label to remove from
     545 * @param idx   Index of the partition to remove
     546 *
     547 * @return EOK on success, ENOMEM on array reduction failure
     548 *
    563549 */
    564550int gpt_remove_partition(gpt_label_t *label, size_t idx)
     
    567553                return EINVAL;
    568554       
    569         /* 
    570          * FIXME!
     555        /*
     556         * FIXME:
    571557         * If we allow blank spots, we break the array. If we have more than
    572558         * 128 partitions in the array and then remove something from
    573559         * the first 128 partitions, we would forget to write the last one.
    574560         */
     561       
    575562        memset(label->parts->part_array + idx, 0, sizeof(gpt_entry_t));
    576563       
     
    578565                label->parts->fill = idx;
    579566       
    580         /*
    581          * FIXME! HOPEFULLY FIXED.
    582          * We cannot reduce the array so simply. We may have some partitions
    583          * there since we allow blank spots.
    584          */
    585         gpt_part_t * p;
    586        
    587         if (label->parts->fill > GPT_MIN_PART_NUM &&
    588             label->parts->fill < (label->parts->arr_size / 2) - GPT_IGNORE_FILL_NUM) {
    589                 for (p = gpt_get_partition_at(label, label->parts->arr_size / 2);
    590                      p < label->parts->part_array + label->parts->arr_size; ++p) {
    591                                 if (gpt_get_part_type(p) != GPT_PTE_UNUSED)
    592                                         return EOK;
     567        gpt_part_t *partition;
     568       
     569        if ((label->parts->fill > GPT_MIN_PART_NUM) &&
     570            (label->parts->fill < (label->parts->arr_size / 2) -
     571            GPT_IGNORE_FILL_NUM)) {
     572                for (partition = gpt_get_partition_at(label, label->parts->arr_size / 2);
     573                     partition < label->parts->part_array + label->parts->arr_size;
     574                     partition++) {
     575                        if (gpt_get_part_type(partition) != GPT_PTE_UNUSED)
     576                                return EOK;
    593577                }
    594578               
     
    596580                        return ENOMEM;
    597581        }
    598 
     582       
    599583        return EOK;
    600584}
     
    602586/** Free partition list
    603587 *
    604  * @param parts         partition list to be freed
    605  */
    606 void gpt_free_partitions(gpt_partitions_t * parts)
     588 * @param parts Partition list to be freed
     589 *
     590 */
     591void gpt_free_partitions(gpt_partitions_t *parts)
    607592{
    608593        free(parts->part_array);
     
    610595}
    611596
    612 /** Get partition type by linear search
    613  * (hopefully this doesn't get slow)
    614  */
    615 size_t gpt_get_part_type(gpt_part_t * p)
     597/** Get partition type */
     598size_t gpt_get_part_type(gpt_part_t *partition)
    616599{
    617600        size_t i;
    618601       
    619602        for (i = 0; gpt_ptypes[i].guid != NULL; i++) {
    620                 if (p->part_type[3] == get_byte(gpt_ptypes[i].guid +0) &&
    621                         p->part_type[2] == get_byte(gpt_ptypes[i].guid +2) &&
    622                         p->part_type[1] == get_byte(gpt_ptypes[i].guid +4) &&
    623                         p->part_type[0] == get_byte(gpt_ptypes[i].guid +6) &&
    624                        
    625                         p->part_type[5] == get_byte(gpt_ptypes[i].guid +8) &&
    626                         p->part_type[4] == get_byte(gpt_ptypes[i].guid +10) &&
    627                        
    628                         p->part_type[7] == get_byte(gpt_ptypes[i].guid +12) &&
    629                         p->part_type[6] == get_byte(gpt_ptypes[i].guid +14) &&
    630                        
    631                         p->part_type[8] == get_byte(gpt_ptypes[i].guid +16) &&
    632                         p->part_type[9] == get_byte(gpt_ptypes[i].guid +18) &&
    633                         p->part_type[10] == get_byte(gpt_ptypes[i].guid +20) &&
    634                         p->part_type[11] == get_byte(gpt_ptypes[i].guid +22) &&
    635                         p->part_type[12] == get_byte(gpt_ptypes[i].guid +24) &&
    636                         p->part_type[13] == get_byte(gpt_ptypes[i].guid +26) &&
    637                         p->part_type[14] == get_byte(gpt_ptypes[i].guid +28) &&
    638                         p->part_type[15] == get_byte(gpt_ptypes[i].guid +30))
    639                                 break;
     603                if ((partition->part_type[3] == get_byte(gpt_ptypes[i].guid + 0)) &&
     604                    (partition->part_type[2] == get_byte(gpt_ptypes[i].guid + 2)) &&
     605                    (partition->part_type[1] == get_byte(gpt_ptypes[i].guid + 4)) &&
     606                    (partition->part_type[0] == get_byte(gpt_ptypes[i].guid + 6)) &&
     607                    (partition->part_type[5] == get_byte(gpt_ptypes[i].guid + 8)) &&
     608                    (partition->part_type[4] == get_byte(gpt_ptypes[i].guid + 10)) &&
     609                    (partition->part_type[7] == get_byte(gpt_ptypes[i].guid + 12)) &&
     610                    (partition->part_type[6] == get_byte(gpt_ptypes[i].guid + 14)) &&
     611                    (partition->part_type[8] == get_byte(gpt_ptypes[i].guid + 16)) &&
     612                    (partition->part_type[9] == get_byte(gpt_ptypes[i].guid + 18)) &&
     613                    (partition->part_type[10] == get_byte(gpt_ptypes[i].guid + 20)) &&
     614                    (partition->part_type[11] == get_byte(gpt_ptypes[i].guid + 22)) &&
     615                    (partition->part_type[12] == get_byte(gpt_ptypes[i].guid + 24)) &&
     616                    (partition->part_type[13] == get_byte(gpt_ptypes[i].guid + 26)) &&
     617                    (partition->part_type[14] == get_byte(gpt_ptypes[i].guid + 28)) &&
     618                    (partition->part_type[15] == get_byte(gpt_ptypes[i].guid + 30)))
     619                        return i;
    640620        }
    641621       
     
    643623}
    644624
    645 /** Set partition type
    646  * @param p                     partition to be set
    647  * @param type          partition type to set
    648  *                                      - see our fine selection at gpt_ptypes to choose from
    649  */
    650 void gpt_set_part_type(gpt_part_t * p, size_t type)
     625/** Set partition type */
     626void gpt_set_part_type(gpt_part_t *partition, size_t type)
    651627{
    652628        /* Beware: first 3 blocks are byteswapped! */
    653         p->part_type[3] = get_byte(gpt_ptypes[type].guid +0);
    654         p->part_type[2] = get_byte(gpt_ptypes[type].guid +2);
    655         p->part_type[1] = get_byte(gpt_ptypes[type].guid +4);
    656         p->part_type[0] = get_byte(gpt_ptypes[type].guid +6);
    657                        
    658         p->part_type[5] = get_byte(gpt_ptypes[type].guid +8);
    659         p->part_type[4] = get_byte(gpt_ptypes[type].guid +10);
    660                        
    661         p->part_type[7] = get_byte(gpt_ptypes[type].guid +12);
    662         p->part_type[6] = get_byte(gpt_ptypes[type].guid +14);
    663                        
    664         p->part_type[8] = get_byte(gpt_ptypes[type].guid +16);
    665         p->part_type[9] = get_byte(gpt_ptypes[type].guid +18);
    666         p->part_type[10] = get_byte(gpt_ptypes[type].guid +20);
    667         p->part_type[11] = get_byte(gpt_ptypes[type].guid +22);
    668         p->part_type[12] = get_byte(gpt_ptypes[type].guid +24);
    669         p->part_type[13] = get_byte(gpt_ptypes[type].guid +26);
    670         p->part_type[14] = get_byte(gpt_ptypes[type].guid +28);
    671         p->part_type[15] = get_byte(gpt_ptypes[type].guid +30);
     629        partition->part_type[3] = get_byte(gpt_ptypes[type].guid + 0);
     630        partition->part_type[2] = get_byte(gpt_ptypes[type].guid + 2);
     631        partition->part_type[1] = get_byte(gpt_ptypes[type].guid + 4);
     632        partition->part_type[0] = get_byte(gpt_ptypes[type].guid + 6);
     633       
     634        partition->part_type[5] = get_byte(gpt_ptypes[type].guid + 8);
     635        partition->part_type[4] = get_byte(gpt_ptypes[type].guid + 10);
     636       
     637        partition->part_type[7] = get_byte(gpt_ptypes[type].guid + 12);
     638        partition->part_type[6] = get_byte(gpt_ptypes[type].guid + 14);
     639       
     640        partition->part_type[8] = get_byte(gpt_ptypes[type].guid + 16);
     641        partition->part_type[9] = get_byte(gpt_ptypes[type].guid + 18);
     642        partition->part_type[10] = get_byte(gpt_ptypes[type].guid + 20);
     643        partition->part_type[11] = get_byte(gpt_ptypes[type].guid + 22);
     644        partition->part_type[12] = get_byte(gpt_ptypes[type].guid + 24);
     645        partition->part_type[13] = get_byte(gpt_ptypes[type].guid + 26);
     646        partition->part_type[14] = get_byte(gpt_ptypes[type].guid + 28);
     647        partition->part_type[15] = get_byte(gpt_ptypes[type].guid + 30);
    672648}
    673649
    674650/** Get partition starting LBA */
    675 uint64_t gpt_get_start_lba(gpt_part_t * p)
    676 {
    677         return uint64_t_le2host(p->start_lba);
     651uint64_t gpt_get_start_lba(gpt_part_t *partition)
     652{
     653        return uint64_t_le2host(partition->start_lba);
    678654}
    679655
    680656/** Set partition starting LBA */
    681 void gpt_set_start_lba(gpt_part_t * p, uint64_t start)
    682 {
    683         p->start_lba = host2uint64_t_le(start);
     657void gpt_set_start_lba(gpt_part_t *partition, uint64_t start)
     658{
     659        partition->start_lba = host2uint64_t_le(start);
    684660}
    685661
    686662/** Get partition ending LBA */
    687 uint64_t gpt_get_end_lba(gpt_part_t * p)
    688 {
    689         return uint64_t_le2host(p->end_lba);
     663uint64_t gpt_get_end_lba(gpt_part_t *partition)
     664{
     665        return uint64_t_le2host(partition->end_lba);
    690666}
    691667
    692668/** Set partition ending LBA */
    693 void gpt_set_end_lba(gpt_part_t * p, uint64_t end)
    694 {
    695         p->end_lba = host2uint64_t_le(end);
     669void gpt_set_end_lba(gpt_part_t *partition, uint64_t end)
     670{
     671        partition->end_lba = host2uint64_t_le(end);
    696672}
    697673
    698674/** Get partition name */
    699 unsigned char * gpt_get_part_name(gpt_part_t * p)
    700 {
    701         return p->part_name;
     675unsigned char * gpt_get_part_name(gpt_part_t *partition)
     676{
     677        return partition->part_name;
    702678}
    703679
    704680/** Copy partition name */
    705 void gpt_set_part_name(gpt_part_t *p, char *name, size_t length)
     681void gpt_set_part_name(gpt_part_t *partition, char *name, size_t length)
    706682{
    707683        if (length >= 72)
    708684                length = 71;
    709 
    710         memcpy(p->part_name, name, length);
    711         p->part_name[length] = '\0';
     685       
     686        memcpy(partition->part_name, name, length);
     687        partition->part_name[length] = '\0';
    712688}
    713689
    714690/** Get partition attribute */
    715 bool gpt_get_flag(gpt_part_t * p, GPT_ATTR flag)
    716 {
    717         return (p->attributes & (((uint64_t) 1) << flag)) ? 1 : 0;
     691bool gpt_get_flag(gpt_part_t *partition, gpt_attr_t flag)
     692{
     693        return (partition->attributes & (((uint64_t) 1) << flag)) ? 1 : 0;
    718694}
    719695
    720696/** Set partition attribute */
    721 void gpt_set_flag(gpt_part_t * p, GPT_ATTR flag, bool value)
    722 {
    723         uint64_t attr = p->attributes;
    724 
     697void gpt_set_flag(gpt_part_t *partition, gpt_attr_t flag, bool value)
     698{
     699        uint64_t attr = partition->attributes;
     700       
    725701        if (value)
    726702                attr = attr | (((uint64_t) 1) << flag);
    727703        else
    728704                attr = attr ^ (attr & (((uint64_t) 1) << flag));
    729 
    730         p->attributes = attr;
     705       
     706        partition->attributes = attr;
    731707}
    732708
    733709/** Generate a new pseudo-random UUID
    734  * @param uuid Pointer to the UUID to overwrite.
    735  */
    736 void gpt_set_random_uuid(uint8_t * uuid)
     710 *
     711 * FIXME: This UUID generator is not compliant with RFC 4122.
     712 *
     713 */
     714void gpt_set_random_uuid(uint8_t *uuid)
    737715{
    738716        srandom((unsigned int) (size_t) uuid);
    739717       
    740         unsigned int i;
    741         for (i = 0; i < 16/sizeof(long int); ++i)
    742                 ((long int *)uuid)[i] = random();
    743        
     718        for (size_t i = 0; i < 16; i++)
     719                uuid[i] = random();
    744720}
    745721
     
    747723uint64_t gpt_get_next_aligned(uint64_t addr, unsigned int alignment)
    748724{
    749         uint64_t div = addr / alignment;
    750         return (div + 1) * alignment;
    751 }
    752 
    753 /* Internal functions follow */
    754 
    755 static int load_and_check_header(service_id_t dev_handle, aoff64_t addr, size_t b_size, gpt_header_t * header)
    756 {
    757         int rc;
    758 
    759         rc = block_read_direct(dev_handle, addr, GPT_HDR_BS, header);
     725        return ALIGN_UP(addr + 1, alignment);
     726}
     727
     728static int load_and_check_header(service_id_t dev_handle, aoff64_t addr,
     729    size_t block_size, gpt_header_t *header)
     730{
     731        int rc = block_read_direct(dev_handle, addr, GPT_HDR_BS, header);
    760732        if (rc != EOK)
    761733                return rc;
    762 
    763         unsigned int i;
     734       
    764735        /* Check the EFI signature */
    765         for (i = 0; i < 8; ++i) {
     736        for (unsigned int i = 0; i < 8; i++) {
    766737                if (header->efi_signature[i] != efi_signature[i])
    767738                        return EINVAL;
    768739        }
    769 
     740       
    770741        /* Check the CRC32 of the header */
    771742        uint32_t crc = header->header_crc32;
    772743        header->header_crc32 = 0;
     744       
    773745        if (crc != compute_crc32((uint8_t *) header, header->header_size))
    774746                return EBADCHECKSUM;
    775747        else
    776748                header->header_crc32 = crc;
    777 
     749       
    778750        /* Check for zeroes in the rest of the block */
    779         for (i = sizeof(gpt_header_t); i < b_size; ++i) {
     751        for (size_t i = sizeof(gpt_header_t); i < block_size; i++) {
    780752                if (((uint8_t *) header)[i] != 0)
    781753                        return EINVAL;
    782754        }
    783 
     755       
    784756        return EOK;
    785757}
    786758
    787 static gpt_partitions_t * alloc_part_array(uint32_t num)
    788 {
    789         gpt_partitions_t * res = malloc(sizeof(gpt_partitions_t));
    790         if (res == NULL) {
    791                 errno = ENOMEM;
     759static gpt_partitions_t *alloc_part_array(uint32_t num)
     760{
     761        gpt_partitions_t *res = malloc(sizeof(gpt_partitions_t));
     762        if (res == NULL)
    792763                return NULL;
    793         }
    794764       
    795765        uint32_t size = num > GPT_BASE_PART_NUM ? num : GPT_BASE_PART_NUM;
     
    797767        if (res->part_array == NULL) {
    798768                free(res);
    799                 errno = ENOMEM;
    800769                return NULL;
    801770        }
     
    805774        res->fill = 0;
    806775        res->arr_size = num;
    807 
     776       
    808777        return res;
    809778}
    810779
    811 static int extend_part_array(gpt_partitions_t * p)
    812 {
    813         size_t nsize = p->arr_size * 2;
    814         gpt_entry_t * tmp = malloc(nsize * sizeof(gpt_entry_t));
    815         if (tmp == NULL) {
    816                 errno = ENOMEM;
    817                 return -1;
    818         }
    819        
    820         memcpy(tmp, p->part_array, p->fill * sizeof(gpt_entry_t));
    821         free(p->part_array);
    822         p->part_array = tmp;
    823         p->arr_size = nsize;
    824 
    825         return 0;
    826 }
    827 
    828 static int reduce_part_array(gpt_partitions_t * p)
    829 {
    830         if (p->arr_size > GPT_MIN_PART_NUM) {
    831                 unsigned int nsize = p->arr_size / 2;
     780static int extend_part_array(gpt_partitions_t *partition)
     781{
     782        size_t nsize = partition->arr_size * 2;
     783        gpt_entry_t *entry = malloc(nsize * sizeof(gpt_entry_t));
     784        if (entry == NULL)
     785                return ENOMEM;
     786       
     787        memcpy(entry, partition->part_array, partition->fill *
     788            sizeof(gpt_entry_t));
     789        free(partition->part_array);
     790       
     791        partition->part_array = entry;
     792        partition->arr_size = nsize;
     793       
     794        return EOK;
     795}
     796
     797static int reduce_part_array(gpt_partitions_t *partition)
     798{
     799        if (partition->arr_size > GPT_MIN_PART_NUM) {
     800                unsigned int nsize = partition->arr_size / 2;
    832801                nsize = nsize > GPT_MIN_PART_NUM ? nsize : GPT_MIN_PART_NUM;
    833                 gpt_entry_t * tmp = malloc(nsize * sizeof(gpt_entry_t));
    834                 if (tmp == NULL)
     802               
     803                gpt_entry_t *entry = malloc(nsize * sizeof(gpt_entry_t));
     804                if (entry == NULL)
    835805                        return ENOMEM;
    836 
    837                 memcpy(tmp, p->part_array, p->fill < nsize ? p->fill : nsize);
    838                 free(p->part_array);
    839                 p->part_array = tmp;
    840                 p->arr_size = nsize;
    841         }
    842 
    843         return 0;
    844 }
    845 
    846 /* Parse a byte from a string in hexadecimal
    847  * i.e., "FF" => 255
    848  */
    849 static uint8_t get_byte(const char * c)
     806               
     807                memcpy(entry, partition->part_array,
     808                    partition->fill < nsize ? partition->fill : nsize);
     809                free(partition->part_array);
     810               
     811                partition->part_array = entry;
     812                partition->arr_size = nsize;
     813        }
     814       
     815        return EOK;
     816}
     817
     818/* Parse a byte from a string in hexadecimal */
     819static uint8_t get_byte(const char *c)
    850820{
    851821        uint8_t val = 0;
    852         char hex[3] = {*c, *(c+1), 0};
    853        
    854         errno = str_uint8_t(hex, NULL, 16, false, &val);
     822        char hex[3] = {*c, *(c + 1), 0};
     823       
     824        str_uint8_t(hex, NULL, 16, false, &val);
    855825        return val;
    856826}
    857827
    858 static bool check_overlap(gpt_part_t * p1, gpt_part_t * p2)
    859 {
    860         if (gpt_get_start_lba(p1) < gpt_get_start_lba(p2) && gpt_get_end_lba(p1) < gpt_get_start_lba(p2)) {
     828static bool check_overlap(gpt_part_t *part1, gpt_part_t *part2)
     829{
     830        if ((gpt_get_start_lba(part1) < gpt_get_start_lba(part2)) &&
     831            (gpt_get_end_lba(part1) < gpt_get_start_lba(part2)))
    861832                return false;
    862         } else if (gpt_get_start_lba(p1) > gpt_get_start_lba(p2) && gpt_get_end_lba(p2) < gpt_get_start_lba(p1)) {
     833       
     834        if ((gpt_get_start_lba(part1) > gpt_get_start_lba(part2)) &&
     835            (gpt_get_end_lba(part2) < gpt_get_start_lba(part1)))
    863836                return false;
    864         }
    865 
     837       
    866838        return true;
    867839}
    868840
    869 static bool check_encaps(gpt_part_t *p, uint64_t n_blocks, uint64_t first_lba)
    870 {
    871         /*
    872          * We allow "<=" in the second expression because it lacks MBR so
    873          * it's by 1 block smaller.
     841static bool check_encaps(gpt_part_t *part, uint64_t blocks,
     842    uint64_t first_lba)
     843{
     844        /*
     845         * We allow "<=" in the second expression because it lacks
     846         * MBR so it is smaller by 1 block.
    874847         */
    875         if (gpt_get_start_lba(p) >= first_lba && gpt_get_end_lba(p) <= n_blocks - first_lba)
     848        if ((gpt_get_start_lba(part) >= first_lba) &&
     849            (gpt_get_end_lba(part) <= blocks - first_lba))
    876850                return true;
    877851       
  • uspace/lib/gpt/libgpt.h

    rd51beba3 r6453e306  
    11/*
    22 * Copyright (c) 2009 Jiri Svoboda
    3  * Copyright (c) 2011, 2012, 2013 Dominik Taborsky
     3 * Copyright (c) 2011-2013 Dominik Taborsky
    44 * All rights reserved.
    55 *
     
    3737#define LIBGPT_LIBGPT_H_
    3838
    39 #define LIBGPT_NAME     "libgpt"
    40 
    4139#include <loc.h>
    4240#include <sys/types.h>
    43 
    4441#include "gpt.h"
    4542
    4643/** Block address of GPT header. */
    47 #define GPT_HDR_BA      1
     44#define GPT_HDR_BA  1
     45
    4846/** Block size of GPT header. */
    49 #define GPT_HDR_BS      1
     47#define GPT_HDR_BS  1
     48
    5049/** Minimum number of GPT partition entries */
    51 #define GPT_MIN_PART_NUM 128
     50#define GPT_MIN_PART_NUM  128
     51
    5252/** Basic number of GPT partition entries */
    53 #define GPT_BASE_PART_NUM (GPT_MIN_PART_NUM)
     53#define GPT_BASE_PART_NUM  (GPT_MIN_PART_NUM)
     54
    5455/** How much fill we ignore before resizing partition array */
    55 #define GPT_IGNORE_FILL_NUM 10
     56#define GPT_IGNORE_FILL_NUM  10
    5657
    5758/** Unused partition entry */
    58 #define GPT_PTE_UNUSED 0
     59#define GPT_PTE_UNUSED  0
     60
     61/** Raw GPT header.
     62 *
     63 * Uses more bytes than sizeof(gpt_header_t).
     64 */
     65typedef struct {
     66        gpt_header_t *header;
     67} gpt_t;
     68
     69typedef gpt_entry_t gpt_part_t;
     70
     71typedef struct {
     72        /** Number of entries */
     73        size_t fill;
     74       
     75        /** Size of the array */
     76        size_t arr_size;
     77       
     78        /** Resizable partition array */
     79        gpt_part_t *part_array;
     80} gpt_partitions_t;
     81
     82typedef struct {
     83        gpt_t *gpt;
     84        gpt_partitions_t *parts;
     85        service_id_t device;
     86} gpt_label_t;
     87
     88typedef struct {
     89        const char *desc;
     90        const char *guid;
     91} partition_type_t;
    5992
    6093/** GPT header signature ("EFI PART" in ASCII) */
     
    6295extern const uint8_t revision[4];
    6396
    64 typedef struct {
    65         /** Raw header. Has more bytes alloced than sizeof(gpt_header_t)!
    66          * See gpt_alloc_header() to know why. */
    67         gpt_header_t *header;
    68 } gpt_t;
     97extern const partition_type_t gpt_ptypes[];
    6998
    70 typedef gpt_entry_t gpt_part_t;
    71 
    72 typedef struct gpt_parts {
    73         /** Number of entries */
    74         size_t fill;
    75         /** Size of the array */
    76         size_t arr_size;
    77         /** Resizable partition array */
    78         gpt_entry_t *part_array;
    79 } gpt_partitions_t;
    80 
    81 
    82 typedef struct gpt_table {
    83         gpt_t *gpt;
    84         gpt_partitions_t *parts;
    85         service_id_t device;
    86 } gpt_label_t;
    87 
    88 struct partition_type {
    89         const char *desc;
    90         const char *guid;
    91 };
    92 
    93 extern const struct partition_type gpt_ptypes[];
    94 
    95 extern gpt_label_t * gpt_alloc_label(void);
     99extern gpt_label_t *gpt_alloc_label(void);
    96100extern void gpt_free_label(gpt_label_t *);
    97101
    98 extern gpt_t * gpt_alloc_header(size_t);
    99 extern int     gpt_read_header(gpt_label_t *, service_id_t);
    100 extern int     gpt_write_header(gpt_label_t *, service_id_t);
     102extern gpt_t *gpt_alloc_header(size_t);
     103extern int gpt_read_header(gpt_label_t *, service_id_t);
     104extern int gpt_write_header(gpt_label_t *, service_id_t);
    101105
    102 extern gpt_partitions_t * gpt_alloc_partitions(void);
    103 extern int             gpt_read_partitions (gpt_label_t *);
    104 extern int             gpt_write_partitions(gpt_label_t *, service_id_t);
    105 extern gpt_part_t *    gpt_alloc_partition (void);
    106 extern gpt_part_t *    gpt_get_partition   (gpt_label_t *);
    107 extern gpt_part_t *    gpt_get_partition_at(gpt_label_t *, size_t);
    108 extern int             gpt_add_partition   (gpt_label_t *, gpt_part_t *);
    109 extern int             gpt_remove_partition(gpt_label_t *, size_t);
     106extern gpt_partitions_t *gpt_alloc_partitions(void);
     107extern int gpt_read_partitions(gpt_label_t *);
     108extern int gpt_write_partitions(gpt_label_t *, service_id_t);
     109extern gpt_part_t *gpt_alloc_partition(void);
     110extern gpt_part_t *gpt_get_partition(gpt_label_t *);
     111extern gpt_part_t *gpt_get_partition_at(gpt_label_t *, size_t);
     112extern int gpt_add_partition(gpt_label_t *, gpt_part_t *);
     113extern int gpt_remove_partition(gpt_label_t *, size_t);
    110114
    111 extern size_t          gpt_get_part_type(gpt_part_t *);
    112 extern void            gpt_set_part_type(gpt_part_t *, size_t);
    113 extern void            gpt_set_start_lba(gpt_part_t *, uint64_t);
    114 extern uint64_t        gpt_get_start_lba(gpt_part_t *);
    115 extern void            gpt_set_end_lba  (gpt_part_t *, uint64_t);
    116 extern uint64_t        gpt_get_end_lba  (gpt_part_t *);
    117 extern unsigned char * gpt_get_part_name(gpt_part_t *);
    118 extern void            gpt_set_part_name(gpt_part_t *, char *, size_t);
    119 extern bool            gpt_get_flag     (gpt_part_t *, GPT_ATTR);
    120 extern void            gpt_set_flag     (gpt_part_t *, GPT_ATTR, bool);
     115extern size_t gpt_get_part_type(gpt_part_t *);
     116extern void gpt_set_part_type(gpt_part_t *, size_t);
     117extern void gpt_set_start_lba(gpt_part_t *, uint64_t);
     118extern uint64_t gpt_get_start_lba(gpt_part_t *);
     119extern void gpt_set_end_lba(gpt_part_t *, uint64_t);
     120extern uint64_t gpt_get_end_lba(gpt_part_t *);
     121extern unsigned char *gpt_get_part_name(gpt_part_t *);
     122extern void gpt_set_part_name(gpt_part_t *, char *, size_t);
     123extern bool gpt_get_flag(gpt_part_t *, gpt_attr_t);
     124extern void gpt_set_flag(gpt_part_t *, gpt_attr_t, bool);
    121125
    122 extern void            gpt_set_random_uuid(uint8_t *);
    123 extern uint64_t        gpt_get_next_aligned(uint64_t, unsigned int);
     126extern void gpt_set_random_uuid(uint8_t *);
     127extern uint64_t gpt_get_next_aligned(uint64_t, unsigned int);
    124128
    125129
    126130#define gpt_part_foreach(label, iterator) \
    127                 for(gpt_part_t * iterator = (label)->parts->part_array; \
    128                     iterator < (label)->parts->part_array + (label)->parts->arr_size; ++iterator)
     131        for (gpt_part_t *iterator = (label)->parts->part_array; \
     132            iterator < (label)->parts->part_array + (label)->parts->arr_size; \
     133            iterator++)
    129134
    130135extern void gpt_free_gpt(gpt_t *);
     
    132137
    133138#endif
    134 
  • uspace/lib/mbr/Makefile

    rd51beba3 r6453e306  
    2828
    2929USPACE_PREFIX = ../..
    30 EXTRA_CFLAGS = -I$(LIBBLOCK_PREFIX) -DDEBUG_CONFIG
     30EXTRA_CFLAGS = -I$(LIBBLOCK_PREFIX)
    3131LIBRARY = libmbr
    3232
  • uspace/lib/mbr/libmbr.c

    rd51beba3 r6453e306  
    11/*
    2  * Copyright (c) 2011, 2012, 2013 Dominik Taborsky
     2 * Copyright (c) 2011-2013 Dominik Taborsky
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29  /** @addtogroup libmbr
     29/** @addtogroup libmbr
    3030 * @{
    3131 */
     
    4343#include <stdlib.h>
    4444#include <str_error.h>
    45 
     45#include <align.h>
    4646#include "libmbr.h"
    4747
    48 static br_block_t * alloc_br(void);
     48static br_block_t *alloc_br(void);
    4949static int decode_part(pt_entry_t *, mbr_part_t *, uint32_t);
    5050static int decode_logical(mbr_label_t *, mbr_part_t *);
     
    5757
    5858/** Allocate and initialize mbr_label_t structure */
    59 mbr_label_t * mbr_alloc_label(void)
     59mbr_label_t *mbr_alloc_label(void)
    6060{
    6161        mbr_label_t *label = malloc(sizeof(mbr_label_t));
     
    8888
    8989/** Allocate memory for mbr_t */
    90 mbr_t * mbr_alloc_mbr(void)
     90mbr_t *mbr_alloc_mbr(void)
    9191{
    9292        return malloc(sizeof(mbr_t));
     
    9494
    9595/** Read MBR from specific device
    96  * @param   label       label to write data to
    97  * @param   dev_handle  device to read MBR from
    98  *
    99  * @return                              EOK on success, error code on error
     96 *
     97 * @param label      Label to be read.
     98 * @param dev_handle Device to read MBR from.
     99 *
     100 * @return EOK on success, error code on error.
     101 *
    100102 */
    101103int mbr_read_mbr(mbr_label_t *label, service_id_t dev_handle)
    102104{       
    103         int rc;
    104        
    105105        if (label->mbr == NULL) {
    106106                label->mbr = mbr_alloc_mbr();
    107                 if (label->mbr == NULL) {
     107                if (label->mbr == NULL)
    108108                        return ENOMEM;
    109                 }
    110         }
    111 
    112         rc = block_init(EXCHANGE_ATOMIC, dev_handle, 512);
     109        }
     110       
     111        int rc = block_init(EXCHANGE_ATOMIC, dev_handle, 512);
    113112        if (rc != EOK)
    114113                return rc;
    115 
    116         rc = block_read_direct(dev_handle, 0, 1, &(label->mbr->raw_data));
     114       
     115        rc = block_read_direct(dev_handle, 0, 1, &label->mbr->raw_data);
    117116        block_fini(dev_handle);
    118117        if (rc != EOK)
    119118                return rc;
    120 
     119       
    121120        label->device = dev_handle;
    122 
     121       
    123122        return EOK;
    124123}
    125124
    126 /** Write mbr to disk
    127  * @param label                 MBR to be written
    128  * @param dev_handle    device handle to write MBR to (may be different
    129  *                                                      from the device in 'mbr')
    130  *
    131  * @return                              0 on success, otherwise libblock error code
     125/** Write MBR to specific device
     126 *
     127 * @param label      Label to be written.
     128 * @param dev_handle Device to write MBR to.
     129 *
     130 * @return EOK on success, error code on error.
     131 *
    132132 */
    133133int mbr_write_mbr(mbr_label_t *label, service_id_t dev_handle)
    134134{
    135         int rc;
    136 
    137         rc = block_init(EXCHANGE_ATOMIC, dev_handle, 512);
    138         if (rc != EOK) {
     135        int rc = block_init(EXCHANGE_ATOMIC, dev_handle, 512);
     136        if (rc != EOK)
    139137                return rc;
    140         }
    141 
    142         rc = block_write_direct(dev_handle, 0, 1, &(label->mbr->raw_data));
     138       
     139        rc = block_write_direct(dev_handle, 0, 1, &label->mbr->raw_data);
    143140        block_fini(dev_handle);
    144         if (rc != EOK) {
    145                 return rc;
    146         }
    147 
    148         return EOK;
    149 }
    150 
    151 /** Decide whether this is an actual MBR or a Protective MBR from GPT
    152  *
    153  * @param mbr           the actual MBR to decide upon
    154  *
    155  * @return                      1 if MBR, 0 if GPT
     141       
     142        return rc;
     143}
     144
     145/** Decide whether this is an actual MBR or a Protective MBR for GPT
     146 *
     147 * @param label Label to decide upon.
     148 *
     149 * @return True if MBR.
     150 * @return False if Protective MBR for GPT.
     151 *
    156152 */
    157153int mbr_is_mbr(mbr_label_t *label)
    158154{
    159         return (label->mbr->raw_data.pte[0].ptype != PT_GPT) ? 1 : 0;
    160 }
    161 
    162 /** Parse partitions from MBR, freeing previous partitions if any
    163  * NOTE: it is assumed mbr_read_mbr(label) was called before.
    164  * @param label  MBR to be parsed
    165  *
    166  * @return       linked list of partitions or NULL on error
     155        return (label->mbr->raw_data.pte[0].ptype != PT_GPT);
     156}
     157
     158/** Parse partitions from MBR (freeing previous partitions if any)
     159 *
     160 * It is assumed that mbr_read_mbr() was called before.
     161 *
     162 * @param label Label to be parsed.
     163 *
     164 * @return EOK on success, error code on error.
     165 *
    167166 */
    168167int mbr_read_partitions(mbr_label_t *label)
    169168{
    170         if (label == NULL || label->mbr == NULL)
     169        if ((label == NULL) || (label->mbr == NULL))
    171170                return EINVAL;
    172        
    173         int rc, rc_ext;
    174         unsigned int i;
    175         mbr_part_t *p;
    176         mbr_part_t *ext = NULL;
    177171       
    178172        if (label->parts != NULL)
     
    180174       
    181175        label->parts = mbr_alloc_partitions();
    182         if (label->parts == NULL) {
     176        if (label->parts == NULL)
    183177                return ENOMEM;
    184         }
     178       
     179        mbr_part_t *extended = NULL;
    185180       
    186181        /* Generate the primary partitions */
    187         for (i = 0; i < N_PRIMARY; ++i) {
     182        for (unsigned int i = 0; i < N_PRIMARY; i++) {
    188183                if (label->mbr->raw_data.pte[i].ptype == PT_UNUSED)
    189184                        continue;
    190185               
    191                 p = mbr_alloc_partition();
    192                 if (p == NULL) {
    193                         printf(LIBMBR_NAME ": Error on memory allocation.\n");
     186                mbr_part_t *partition = mbr_alloc_partition();
     187                if (partition == NULL) {
    194188                        mbr_free_partitions(label->parts);
    195189                        return ENOMEM;
    196190                }
    197191               
    198                 rc_ext = decode_part(&(label->mbr->raw_data.pte[i]), p, 0);
    199                 mbr_set_flag(p, ST_LOGIC, false);
    200                 rc = mbr_add_partition(label, p);
     192                int is_extended =
     193                    decode_part(&label->mbr->raw_data.pte[i], partition, 0);
     194               
     195                mbr_set_flag(partition, ST_LOGIC, false);
     196               
     197                int rc = mbr_add_partition(label, partition);
    201198                if (rc != ERR_OK) {
    202                         printf(LIBMBR_NAME ": Error occured during decoding the MBR. (%d)\n" \
    203                                LIBMBR_NAME ": MBR is invalid.\n", rc);
    204199                        mbr_free_partitions(label->parts);
    205200                        return EINVAL;
    206201                }
    207202               
    208                 if (rc_ext) {
    209                         ext = p;
    210                         label->parts->l_extended = &p->link;
    211                 }
    212         }
    213        
    214         /* Fill in the primary partitions and generate logical ones, if any */
    215         rc = decode_logical(label, ext);
    216         if (rc != EOK) {
    217                 printf(LIBMBR_NAME ": Error during decoding logical partitions: %d - %s.\n" \
    218                            LIBMBR_NAME ": Partition list may be incomplete.\n", rc, str_error(rc));
    219                 return rc;
    220         }
    221        
    222         return EOK;
     203                if (is_extended) {
     204                        extended = partition;
     205                        label->parts->l_extended = &partition->link;
     206                }
     207        }
     208       
     209        /* Fill in the primary partitions and generate logical ones (if any) */
     210        return decode_logical(label, extended);
    223211}
    224212
    225213/** Write MBR and partitions to device
    226  * @param label        label to write
    227  * @param dev_handle   device to write the data to
    228  *
    229  * @return             returns EOK on succes, specific error code otherwise
     214 *
     215 * @param label      Label to write.
     216 * @param dev_handle Device to write the data to.
     217 *
     218 * @return EOK on success, specific error code otherwise.
     219 *
    230220 */
    231221int mbr_write_partitions(mbr_label_t *label, service_id_t dev_handle)
     
    237227                label->mbr = mbr_alloc_mbr();
    238228       
    239         int i = 0;
    240         int rc;
    241         mbr_part_t *p;
    242         mbr_part_t *ext = (label->parts->l_extended == NULL) ? NULL
    243                                         : list_get_instance(label->parts->l_extended, mbr_part_t, link);
    244        
    245         rc = block_init(EXCHANGE_ATOMIC, dev_handle, 512);
    246         if (rc != EOK) {
    247                 printf(LIBMBR_NAME ": Error while initializing libblock: %d - %s.\n", rc, str_error(rc));
     229        int rc = block_init(EXCHANGE_ATOMIC, dev_handle, 512);
     230        if (rc != EOK)
    248231                return rc;
    249         }
    250        
    251         link_t *l = label->parts->list.head.next;
    252        
    253         /* Encoding primary partitions */
    254         for (i = 0; i < N_PRIMARY; i++) {
    255                 p = list_get_instance(l, mbr_part_t, link);     
    256                 encode_part(p, &(label->mbr->raw_data.pte[i]), 0, false);
    257                 l = l->next;
    258         }
    259        
    260         label->mbr->raw_data.signature = host2uint16_t_le(BR_SIGNATURE);
    261        
    262         /* Writing MBR */
    263         rc = block_write_direct(dev_handle, 0, 1, &(label->mbr->raw_data));
    264         if (rc != EOK) {
    265                 printf(LIBMBR_NAME ": Error while writing MBR : %d - %s.\n", rc, str_error(rc));
     232       
     233        mbr_part_t *partition = NULL;
     234        mbr_part_t *extended = NULL;
     235       
     236        if (label->parts->l_extended != NULL)
     237                extended = list_get_instance(label->parts->l_extended,
     238                    mbr_part_t, link);
     239       
     240        link_t *link = label->parts->list.head.next;
     241       
     242        /* Encode primary partitions */
     243        for (unsigned int i = 0; i < N_PRIMARY; i++) {
     244                partition = list_get_instance(link, mbr_part_t, link);
     245               
     246                encode_part(partition, &label->mbr->raw_data.pte[i], 0, false);
     247                link = link->next;
     248        }
     249       
     250        /* Write MBR */
     251        rc = block_write_direct(dev_handle, 0, 1, &label->mbr->raw_data);
     252        if ((rc != EOK) || (extended == NULL))
    266253                goto end;
    267         }
    268        
    269         if (ext == NULL) {
    270                 rc = EOK;
     254       
     255        uint32_t base = extended->start_addr;
     256        mbr_part_t *prev_partition;
     257       
     258        /* Encode and write first logical partition */
     259        if (link != &label->parts->list.head) {
     260                partition = list_get_instance(link, mbr_part_t, link);
     261               
     262                partition->ebr_addr = base;
     263                encode_part(partition, &partition->ebr->pte[0], base, false);
     264                link = link->next;
     265        } else {
     266                /*
     267                 * If there was an extended partition but no logical partitions,
     268                 * we should overwrite the space where the first logical
     269                 * partitions's EBR would have been. There might be some
     270                 * garbage from the past.
     271                 */
     272               
     273                br_block_t *br = alloc_br();
     274                rc = block_write_direct(dev_handle, base, 1, br);
     275                if (rc != EOK)
     276                        goto end;
     277               
     278                free(br);
    271279                goto end;
    272280        }
    273281       
    274         uint32_t base = ext->start_addr;
    275         mbr_part_t *prev_p;
    276        
    277         /* Note for future changes: Some thought has been put into design
    278          * and implementation. If you don't have to change it, don't. Other
    279          * designs have been tried, this came out as the least horror with
    280          * as much power over it as you can get. */
    281        
    282         /* Encoding and writing first logical partition */
    283         if (l != &(label->parts->list.head)) {
    284                 p = list_get_instance(l, mbr_part_t, link);
    285                 p->ebr_addr = base;
    286                 encode_part(p, &(p->ebr->pte[0]), base, false);
    287                 l = l->next;
    288         } else {
    289                 /* If there was an extended but no logical, we should overwrite
    290                  * the space where the first logical's EBR would have been. There
    291                  * might be some garbage from the past. */
    292                 br_block_t * tmp = alloc_br();
    293                 rc = block_write_direct(dev_handle, base, 1, tmp);
    294                 if (rc != EOK) {
    295                         printf(LIBMBR_NAME ": Error while writing EBR: %d - %s.\n", rc, str_error(rc));
    296                         goto end;
    297                 }
    298                 free(tmp);
    299                 rc = EOK;
    300                 goto end;
    301         }
    302        
    303         prev_p = p;
    304        
    305         /* Check EBR addresses
    306          * This piece of code saves previous EBR placements from other
    307          * software. But if our user modifies the logical partition chain,
    308          * we have to fix those placements if needed.*/
    309         link_t *l_ebr = l;
    310         link_t *l_iter;
    311         mbr_part_t *tmp = mbr_alloc_partition();
    312         tmp->length = 1;
    313         while (l_ebr != &(label->parts->list.head)) {
    314                 p = list_get_instance(l_ebr, mbr_part_t, link);
    315                 tmp->start_addr = p->ebr_addr;
    316                
    317                 l_iter = l;
    318                 while (l_iter != &(label->parts->list.head)) {
    319                         /* Checking whether EBR address makes sense. If not, we take a guess.
    320                          * So far this is simple, we just take the first preceeding sector.
    321                          * Fdisk always reserves at least 2048 sectors (1MiB), so it can have
    322                          * the EBR aligned as well as the partition itself. Parted reserves
    323                          * minimum one sector, like we do.
    324                          *
    325                          * Note that we know there is at least one sector free from previous checks.
    326                          * Also note that the user can set ebr_addr to their liking (if it's valid). */         
    327                         if (p->ebr_addr < base || p->ebr_addr >= base + ext->length ||
    328                           check_overlap(tmp, list_get_instance(l_iter, mbr_part_t, link))) {
    329                                 p->ebr_addr = p->start_addr - 1;
     282        prev_partition = partition;
     283       
     284        /*
     285         * Check EBR addresses: The code saves previous EBR
     286         * placements from other software. But if our user
     287         * modifies the logical partition chain, we have to
     288         * fix those placements if needed.
     289         */
     290       
     291        link_t *link_ebr = link;
     292        link_t *link_iter;
     293       
     294        mbr_part_t tmp_partition;
     295        tmp_partition.length = 1;
     296       
     297        while (link_ebr != &label->parts->list.head) {
     298                partition = list_get_instance(link_ebr, mbr_part_t, link);
     299               
     300                tmp_partition.start_addr = partition->ebr_addr;
     301               
     302                link_iter = link;
     303                while (link_iter != &label->parts->list.head) {
     304                        /*
     305                         * Check whether EBR address makes sense. If not, we take
     306                         * a guess.  So far this is simple, we just take the first
     307                         * preceeding sector. FDisk always reserves at least 2048
     308                         * sectors (1 MiB), so it can have the EBR aligned as well
     309                         * as the partition itself. Parted reserves minimum one
     310                         * sector, like we do.
     311                         *
     312                         * Note that we know there is at least one sector free from
     313                         * previous checks. Also note that the user can set ebr_addr
     314                         * to their liking (if it is valid).
     315                         */
     316                       
     317                        if ((partition->ebr_addr < base) ||
     318                            (partition->ebr_addr >= base + extended->length) ||
     319                            (check_overlap(&tmp_partition,
     320                            list_get_instance(link_iter, mbr_part_t, link)))) {
     321                                partition->ebr_addr = partition->start_addr - 1;
    330322                                break;
    331323                        }
    332324                       
    333                         l_iter = l_iter->next;
    334                 }
    335                
    336                 l_ebr = l_ebr->next;
    337         }
    338         mbr_free_partition(tmp);
    339        
    340         /* Encoding and writing logical partitions */
    341         while (l != &(label->parts->list.head)) {
    342                 p = list_get_instance(l, mbr_part_t, link);
    343                
    344                
    345                 encode_part(p, &(p->ebr->pte[0]), p->ebr_addr, false);
    346                 encode_part(p, &(prev_p->ebr->pte[1]), base, true);
    347                
    348                 rc = block_write_direct(dev_handle, prev_p->ebr_addr, 1, prev_p->ebr);
    349                 if (rc != EOK) {
    350                         printf(LIBMBR_NAME ": Error while writing EBR: %d - %s.\n", rc, str_error(rc));
     325                        link_iter = link_iter->next;
     326                }
     327               
     328                link_ebr = link_ebr->next;
     329        }
     330       
     331        /* Encode and write logical partitions */
     332        while (link != &label->parts->list.head) {
     333                partition = list_get_instance(link, mbr_part_t, link);
     334               
     335                encode_part(partition, &partition->ebr->pte[0],
     336                    partition->ebr_addr, false);
     337                encode_part(partition, &prev_partition->ebr->pte[1],
     338                    base, true);
     339               
     340                rc = block_write_direct(dev_handle, prev_partition->ebr_addr, 1,
     341                    prev_partition->ebr);
     342                if (rc != EOK)
    351343                        goto end;
    352                 }
    353                
    354                 prev_p = p;
    355                 l = l->next;
    356         }
    357        
    358         /* write the last EBR */
    359         encode_part(NULL, &(prev_p->ebr->pte[1]), 0, false);
    360         rc = block_write_direct(dev_handle, prev_p->ebr_addr, 1, prev_p->ebr);
    361         if (rc != EOK) {
    362                 printf(LIBMBR_NAME ": Error while writing EBR: %d - %s.\n", rc, str_error(rc));
    363                 goto end;
    364         }
    365        
    366         rc = EOK;
     344               
     345                prev_partition = partition;
     346                link = link->next;
     347        }
     348       
     349        /* Write the last EBR */
     350        encode_part(NULL, &prev_partition->ebr->pte[1], 0, false);
     351        rc = block_write_direct(dev_handle, prev_partition->ebr_addr,
     352            1, prev_partition->ebr);
    367353       
    368354end:
    369355        block_fini(dev_handle);
    370        
    371356        return rc;
    372357}
    373358
    374 /** mbr_part_t constructor */
    375 mbr_part_t * mbr_alloc_partition(void)
    376 {
    377         mbr_part_t *p = malloc(sizeof(mbr_part_t));
    378         if (p == NULL) {
     359/** Partition constructor */
     360mbr_part_t *mbr_alloc_partition(void)
     361{
     362        mbr_part_t *partition = malloc(sizeof(mbr_part_t));
     363        if (partition == NULL)
    379364                return NULL;
    380         }
    381        
    382         link_initialize(&(p->link));
    383         p->ebr = NULL;
    384         p->type = PT_UNUSED;
    385         p->status = 0;
    386         p->start_addr = 0;
    387         p->length = 0;
    388         p->ebr_addr = 0;
    389        
    390         return p;
    391 }
    392 
    393 /** mbr_partitions_t constructor */
    394 mbr_partitions_t * mbr_alloc_partitions(void)
     365       
     366        link_initialize(&partition->link);
     367        partition->ebr = NULL;
     368        partition->type = PT_UNUSED;
     369        partition->status = 0;
     370        partition->start_addr = 0;
     371        partition->length = 0;
     372        partition->ebr_addr = 0;
     373       
     374        return partition;
     375}
     376
     377/** Partitions constructor */
     378mbr_partitions_t *mbr_alloc_partitions(void)
    395379{
    396380        mbr_partitions_t *parts = malloc(sizeof(mbr_partitions_t));
    397         if (parts == NULL) {
     381        if (parts == NULL)
    398382                return NULL;
    399         }
    400        
    401         list_initialize(&(parts->list));
     383       
     384        list_initialize(&parts->list);
    402385        parts->n_primary = 0;
    403386        parts->n_logical = 0;
    404387        parts->l_extended = NULL;
    405388       
    406         /* add blank primary partitions */
    407         int i;
    408         mbr_part_t *p;
    409         for (i = 0; i < N_PRIMARY; ++i) {
    410                 p = mbr_alloc_partition();
    411                 if (p == NULL) {
     389        /* Add blank primary partitions */
     390        for (unsigned int i = 0; i < N_PRIMARY; ++i) {
     391                mbr_part_t *part = mbr_alloc_partition();
     392                if (part == NULL) {
    412393                        mbr_free_partitions(parts);
    413394                        return NULL;
    414395                }
    415                 list_append(&(p->link), &(parts->list));
    416         }
    417        
    418 
     396               
     397                list_append(&part->link, &parts->list);
     398        }
     399       
    419400        return parts;
    420401}
    421402
    422403/** Add partition
    423  *      Performs checks, sorts the list.
    424  *
    425  * @param label                 label to add to
    426  * @param p                             partition to add
    427  *
    428  * @return                              ERR_OK (0) on success, other MBR_ERR_VAL otherwise
    429  */
    430 mbr_err_val mbr_add_partition(mbr_label_t *label, mbr_part_t *p)
    431 {
    432         int rc1, rc2;
     404 *
     405 * Perform checks, sort the list.
     406 *
     407 * @param label Label to add to.
     408 * @param part  Partition to add.
     409 *
     410 * @return ERR_OK on success, other MBR_ERR_VAL otherwise
     411 *
     412 */
     413mbr_err_val mbr_add_partition(mbr_label_t *label, mbr_part_t *part)
     414{
     415        int rc = block_init(EXCHANGE_ATOMIC, label->device, 512);
     416        if ((rc != EOK) && (rc != EEXIST))
     417                return ERR_LIBBLOCK;
     418       
    433419        aoff64_t nblocks;
    434        
    435         rc1 = block_init(EXCHANGE_ATOMIC, label->device, 512);
    436         if (rc1 != EOK && rc1 != EEXIST) {
    437                 printf(LIBMBR_NAME ": Error during libblock init: %d - %s.\n", rc1, str_error(rc1));
     420        int ret = block_get_nblocks(label->device, &nblocks);
     421       
     422        if (rc != EEXIST)
     423                block_fini(label->device);
     424       
     425        if (ret != EOK)
    438426                return ERR_LIBBLOCK;
    439         }
    440        
    441         rc2 = block_get_nblocks(label->device, &nblocks);
    442        
    443         if (rc1 != EEXIST)
    444                 block_fini(label->device);
    445        
    446         if (rc2 != EOK) {
    447                 printf(LIBMBR_NAME ": Error while getting number of blocks: %d - %s.\n", rc2, str_error(rc2));
    448                 return ERR_LIBBLOCK;
    449         }
    450        
    451         if ((aoff64_t) p->start_addr + p->length > nblocks)
     427       
     428        if ((aoff64_t) part->start_addr + part->length > nblocks)
    452429                return ERR_OUT_BOUNDS;
    453430       
     
    455432                label->parts = mbr_alloc_partitions();
    456433                if (label->parts == NULL)
    457                         return ENOMEM; //FIXME! merge mbr_err_val into errno.h
    458         }
    459        
    460         if (mbr_get_flag(p, ST_LOGIC))
    461                 /* adding logical partition */
    462                 return mbr_add_logical(label, p);
     434                        // FIXME! merge mbr_err_val into errno.h
     435                        return ENOMEM;
     436        }
     437       
     438        if (mbr_get_flag(part, ST_LOGIC))
     439                return mbr_add_logical(label, part);
    463440        else
    464                 /* adding primary */
    465                 return mbr_add_primary(label, p);
     441                return mbr_add_primary(label, part);
    466442}
    467443
    468444/** Remove partition
    469  *      Removes partition by index, indexed from zero. When removing extended
    470  *  partition, all logical partitions get removed as well.
    471  *
    472  * @param label                 label to remove from
    473  * @param idx                   index of the partition to remove
    474  *
    475  * @return                              EOK on success, EINVAL if idx invalid
     445 *
     446 * Remove partition (indexed from zero). When removing the extended
     447 * partition, all logical partitions get removed as well.
     448 *
     449 * @param label Label to remove from.
     450 * @param idx   Index of the partition to remove.
     451 *
     452 * @return EOK on success.
     453 * @return EINVAL if the index is invalid.
     454 *
    476455 */
    477456int mbr_remove_partition(mbr_label_t *label, size_t idx)
    478457{
    479         link_t *l = list_nth(&(label->parts->list), idx);
    480         if (l == NULL)
     458        link_t *link = list_nth(&label->parts->list, idx);
     459        if (link == NULL)
    481460                return EINVAL;
    482461       
    483         mbr_part_t *p;
    484        
    485         /* If we're removing an extended partition, remove all logical as well */
    486         if (l == label->parts->l_extended) {
     462        /*
     463         * If removing the extended partition, remove all
     464         * logical partitions as well.
     465         */
     466        if (link == label->parts->l_extended) {
    487467                label->parts->l_extended = NULL;
    488468               
    489                 link_t *it = l->next;
    490                 link_t *next_it;
    491                 while (it != &(label->parts->list.head)) {
    492                         next_it = it->next;
     469                link_t *iterator = link->next;
     470                link_t *next;
     471               
     472                while (iterator != &label->parts->list.head) {
     473                        next = iterator->next;
     474                        mbr_part_t *partition =
     475                            list_get_instance(iterator, mbr_part_t, link);
    493476                       
    494                         p = list_get_instance(it, mbr_part_t, link);
    495                         if (mbr_get_flag(p, ST_LOGIC)) {
    496                                 list_remove(it);
    497                                 label->parts->n_logical -= 1;
    498                                 mbr_free_partition(p);
     477                        if (mbr_get_flag(partition, ST_LOGIC)) {
     478                                list_remove(iterator);
     479                                label->parts->n_logical--;
     480                                mbr_free_partition(partition);
    499481                        }
    500482                       
    501                         it = next_it;
    502                 }
    503                
     483                        iterator = next;
     484                }
    504485        }
    505486       
    506487        /* Remove the partition itself */
    507         p = list_get_instance(l, mbr_part_t, link);
    508         if (mbr_get_flag(p, ST_LOGIC)) {
    509                 label->parts->n_logical -= 1;
    510                 list_remove(l);
    511                 mbr_free_partition(p);
     488        mbr_part_t *partition =
     489            list_get_instance(link, mbr_part_t, link);
     490       
     491        if (mbr_get_flag(partition, ST_LOGIC)) {
     492                label->parts->n_logical--;
     493                list_remove(link);
     494                mbr_free_partition(partition);
    512495        } else {
    513                 /* Cannot remove primary - it would break ordering, just zero it */
    514                 label->parts->n_primary -= 1;
    515                 p->type = 0;
    516                 p->status = 0;
    517                 p->start_addr = 0;
    518                 p->length = 0;
    519                 p->ebr_addr = 0;
     496                /*
     497                 * Cannot remove a primary partition without
     498                 * breaking the ordering. Just zero it.
     499                 */
     500                label->parts->n_primary--;
     501                partition->type = 0;
     502                partition->status = 0;
     503                partition->start_addr = 0;
     504                partition->length = 0;
     505                partition->ebr_addr = 0;
    520506        }
    521507       
     
    523509}
    524510
    525 /** mbr_part_t destructor */
    526 void mbr_free_partition(mbr_part_t *p)
    527 {
    528         if (p->ebr != NULL)
    529                 free(p->ebr);
    530         free(p);
    531 }
    532 
    533 /** Get flag bool value */
    534 int mbr_get_flag(mbr_part_t *p, MBR_FLAGS flag)
    535 {
    536         return (p->status & (1 << flag)) ? 1 : 0;
    537 }
    538 
    539 /** Set a specifig status flag to a value */
    540 void mbr_set_flag(mbr_part_t *p, MBR_FLAGS flag, bool value)
    541 {
    542         uint16_t status = p->status;
    543 
    544         if (value)
    545                 status = status | (1 << flag);
     511/** Partition destructor */
     512void mbr_free_partition(mbr_part_t *partition)
     513{
     514        if (partition->ebr != NULL)
     515                free(partition->ebr);
     516       
     517        free(partition);
     518}
     519
     520/** Check for flag */
     521int mbr_get_flag(mbr_part_t *partition, mbr_flags_t flag)
     522{
     523        return (partition->status & (1 << flag));
     524}
     525
     526/** Set a specific status flag */
     527void mbr_set_flag(mbr_part_t *partition, mbr_flags_t flag, bool set)
     528{
     529        if (set)
     530                partition->status |= 1 << flag;
    546531        else
    547                 status = status ^ (status & (1 << flag));
    548 
    549         p->status = status;
     532                partition->status &= ~((uint16_t) (1 << flag));
    550533}
    551534
     
    553536uint32_t mbr_get_next_aligned(uint32_t addr, unsigned int alignment)
    554537{
    555         uint32_t div = addr / alignment;
    556         return (div + 1) * alignment;
    557 }
    558 
    559 list_t * mbr_get_list(mbr_label_t *label)
     538        return ALIGN_UP(addr + 1, alignment);
     539}
     540
     541list_t *mbr_get_list(mbr_label_t *label)
    560542{
    561543        if (label->parts != NULL)
    562                 return &(label->parts->list);
     544                return &label->parts->list;
    563545        else
    564546                return NULL;
    565547}
    566548
    567 mbr_part_t * mbr_get_first_partition(mbr_label_t *label)
     549mbr_part_t *mbr_get_first_partition(mbr_label_t *label)
    568550{
    569551        list_t *list = mbr_get_list(label);
    570         if (list != NULL && !list_empty(list))
     552        if ((list != NULL) && (!list_empty(list)))
    571553                return list_get_instance(list->head.next, mbr_part_t, link);
    572554        else
     
    574556}
    575557
    576 mbr_part_t * mbr_get_next_partition(mbr_label_t *label, mbr_part_t *p)
     558mbr_part_t *mbr_get_next_partition(mbr_label_t *label, mbr_part_t *partition)
    577559{
    578560        list_t *list = mbr_get_list(label);
    579         if (list != NULL && &(p->link) != list_last(list))
    580                 return list_get_instance(p->link.next, mbr_part_t, link);
     561        if ((list != NULL) && (&partition->link != list_last(list)))
     562                return list_get_instance(partition->link.next, mbr_part_t, link);
    581563        else
    582564                return NULL;
    583565}
    584566
    585 /** Just a wrapper for free() */
    586567void mbr_free_mbr(mbr_t *mbr)
    587568{
     
    591572/** Free partition list
    592573 *
    593  * @param parts         partition list to be freed
     574 * @param parts Partition list to be freed
     575 *
    594576 */
    595577void mbr_free_partitions(mbr_partitions_t *parts)
    596578{
    597579        list_foreach_safe(parts->list, cur_link, next) {
    598                 mbr_part_t *p = list_get_instance(cur_link, mbr_part_t, link);
     580                mbr_part_t *partition = list_get_instance(cur_link, mbr_part_t, link);
    599581                list_remove(cur_link);
    600                 mbr_free_partition(p);
    601         }
    602 
     582                mbr_free_partition(partition);
     583        }
     584       
    603585        free(parts);
    604586}
    605587
    606 /* Internal functions follow */
    607 
    608 static br_block_t *alloc_br()
     588static br_block_t *alloc_br(void)
    609589{
    610590        br_block_t *br = malloc(sizeof(br_block_t));
     
    618598}
    619599
    620 /** Parse partition entry to mbr_part_t
    621  * @return              returns 1, if extended partition, 0 otherwise
    622  * */
    623 static int decode_part(pt_entry_t *src, mbr_part_t *trgt, uint32_t base)
    624 {
    625         trgt->type = src->ptype;
    626 
    627         trgt->status = (trgt->status & 0xFF00) | (uint16_t) src->status;
    628 
    629         trgt->start_addr = uint32_t_le2host(src->first_lba) + base;
    630         trgt->length = uint32_t_le2host(src->length);
    631 
    632         return (src->ptype == PT_EXTENDED) ? 1 : 0;
    633 }
    634 
    635 /** Parse MBR contents to mbr_part_t list */
    636 static int decode_logical(mbr_label_t *label, mbr_part_t * ext)
    637 {
    638         int rc;
    639         mbr_part_t *p;
    640 
    641         if (ext == NULL)
     600/** Decode partition entry */
     601static int decode_part(pt_entry_t *src, mbr_part_t *partition, uint32_t base)
     602{
     603        partition->type = src->ptype;
     604        partition->status = (partition->status & 0xff00) | (uint16_t) src->status;
     605        partition->start_addr = uint32_t_le2host(src->first_lba) + base;
     606        partition->length = uint32_t_le2host(src->length);
     607       
     608        return (src->ptype == PT_EXTENDED);
     609}
     610
     611/** Parse logical partitions */
     612static int decode_logical(mbr_label_t *label, mbr_part_t *extended)
     613{
     614        if (extended == NULL)
    642615                return EOK;
    643 
    644         uint32_t base = ext->start_addr;
     616       
     617        br_block_t *ebr = alloc_br();
     618        if (ebr == NULL)
     619                return ENOMEM;
     620       
     621        uint32_t base = extended->start_addr;
    645622        uint32_t addr = base;
    646         br_block_t *ebr;
    647        
    648         rc = block_init(EXCHANGE_ATOMIC, label->device, 512);
     623       
     624        int rc = block_init(EXCHANGE_ATOMIC, label->device, 512);
    649625        if (rc != EOK)
    650                 return rc;
    651        
    652         ebr = alloc_br();
    653         if (ebr == NULL) {
     626                goto end;
     627       
     628        rc = block_read_direct(label->device, addr, 1, ebr);
     629        if (rc != EOK)
     630                goto end;
     631       
     632        if (uint16_t_le2host(ebr->signature) != BR_SIGNATURE) {
     633                rc = EINVAL;
     634                goto end;
     635        }
     636       
     637        if (ebr->pte[0].ptype == PT_UNUSED) {
     638                rc = EOK;
     639                goto end;
     640        }
     641       
     642        mbr_part_t *partition = mbr_alloc_partition();
     643        if (partition == NULL) {
    654644                rc = ENOMEM;
    655645                goto end;
    656646        }
    657647       
    658         rc = block_read_direct(label->device, addr, 1, ebr);
    659         if (rc != EOK) {
    660                 goto free_ebr_end;
    661         }
    662        
    663         if (uint16_t_le2host(ebr->signature) != BR_SIGNATURE) {
    664                 rc = EINVAL;
    665                 goto free_ebr_end;
    666         }
    667        
    668         if (ebr->pte[0].ptype == PT_UNUSED) {
    669                 rc = EOK;
    670                 goto free_ebr_end;
    671         }
    672        
    673         p = mbr_alloc_partition();
    674         if (p == NULL) {
    675                 rc = ENOMEM;
    676                 goto free_ebr_end;
    677         }
    678        
    679         decode_part(&(ebr->pte[0]), p, base);
    680         mbr_set_flag(p, ST_LOGIC, true);
    681         p->ebr = ebr;
    682         p->ebr_addr = addr;
    683         rc = mbr_add_partition(label, p);
    684         if (rc != ERR_OK)
    685                 return EINVAL;
     648        decode_part(&ebr->pte[0], partition, base);
     649        mbr_set_flag(partition, ST_LOGIC, true);
     650        partition->ebr = ebr;
     651        partition->ebr_addr = addr;
     652       
     653        rc = mbr_add_partition(label, partition);
     654        if (rc != ERR_OK)
     655                goto end;
    686656       
    687657        addr = uint32_t_le2host(ebr->pte[1].first_lba) + base;
    688658       
    689659        while (ebr->pte[1].ptype != PT_UNUSED) {
    690                
    691                 ebr = alloc_br();
    692                 if (ebr == NULL) {
     660                rc = block_read_direct(label->device, addr, 1, ebr);
     661                if (rc != EOK)
     662                        goto end;
     663               
     664                if (uint16_t_le2host(ebr->signature) != BR_SIGNATURE) {
     665                        rc = EINVAL;
     666                        goto end;
     667                }
     668               
     669                mbr_part_t *partition = mbr_alloc_partition();
     670                if (partition == NULL) {
    693671                        rc = ENOMEM;
    694672                        goto end;
    695673                }
    696674               
    697                 rc = block_read_direct(label->device, addr, 1, ebr);
    698                 if (rc != EOK) {
    699                         goto free_ebr_end;
    700                 }
    701                
    702                 if (uint16_t_le2host(ebr->signature) != BR_SIGNATURE) {
    703                         rc = EINVAL;
    704                         goto free_ebr_end;
    705                 }
    706                
    707                 p = mbr_alloc_partition();
    708                 if (p == NULL) {
    709                         rc = ENOMEM;
    710                         goto free_ebr_end;
    711                 }
    712                
    713                 decode_part(&(ebr->pte[0]), p, addr);
    714                 mbr_set_flag(p, ST_LOGIC, true);
    715                 p->ebr = ebr;
    716                 p->ebr_addr = addr;
    717                 rc = mbr_add_partition(label, p);
     675                decode_part(&ebr->pte[0], partition, addr);
     676                mbr_set_flag(partition, ST_LOGIC, true);
     677                partition->ebr = ebr;
     678                partition->ebr_addr = addr;
     679               
     680                rc = mbr_add_partition(label, partition);
    718681                if (rc != ERR_OK)
    719                         return EINVAL;
     682                        goto end;
    720683               
    721684                addr = uint32_t_le2host(ebr->pte[1].first_lba) + base;
     
    723686       
    724687        rc = EOK;
    725         goto end;
    726        
    727 free_ebr_end:
    728         free(ebr);
    729688       
    730689end:
     690        // FIXME possible memory leaks
    731691        block_fini(label->device);
    732692       
     
    734694}
    735695
    736 /** Convert mbr_part_t to pt_entry_t */
    737 static void encode_part(mbr_part_t * src, pt_entry_t * trgt, uint32_t base, bool ebr)
     696/** Encode partition entry */
     697static void encode_part(mbr_part_t *src, pt_entry_t *entry, uint32_t base,
     698    bool ebr)
    738699{
    739700        if (src != NULL) {
    740                 trgt->status = (uint8_t) (src->status & 0xFF);
    741                 /* ingoring CHS */
    742                 trgt->first_chs[0] = 0xFE;
    743                 trgt->first_chs[1] = 0xFF;
    744                 trgt->first_chs[2] = 0xFF;
    745                 trgt->last_chs[0] = 0xFE;
    746                 trgt->last_chs[1] = 0xFF;
    747                 trgt->last_chs[2] = 0xFF;
    748                 if (ebr) {      /* encoding reference to EBR */
    749                         trgt->ptype = PT_EXTENDED_LBA;
    750                         trgt->first_lba = host2uint32_t_le(src->ebr_addr - base);
    751                         trgt->length = host2uint32_t_le(src->length + src->start_addr - src->ebr_addr);
    752                 } else {        /* encoding reference to partition */
    753                         trgt->ptype = src->type;
    754                         trgt->first_lba = host2uint32_t_le(src->start_addr - base);
    755                         trgt->length = host2uint32_t_le(src->length);
    756                 }
    757                
    758                 if (trgt->ptype == PT_UNUSED)
    759                         memset(trgt, 0, sizeof(pt_entry_t));
    760         } else {
    761                 memset(trgt, 0, sizeof(pt_entry_t));
    762         }
    763 }
    764 
    765 /** Check whether two partitions overlap
    766  *
    767  * @return              true/false
    768  */
    769 static bool check_overlap(mbr_part_t * p1, mbr_part_t * p2)
    770 {
    771         if (p1->start_addr < p2->start_addr && p1->start_addr + p1->length <= p2->start_addr) {
     701                entry->status = (uint8_t) src->status & 0xff;
     702               
     703                /* Ignore CHS */
     704                entry->first_chs[0] = 0xfe;
     705                entry->first_chs[1] = 0xff;
     706                entry->first_chs[2] = 0xff;
     707                entry->last_chs[0] = 0xfe;
     708                entry->last_chs[1] = 0xff;
     709                entry->last_chs[2] = 0xff;
     710               
     711                if (ebr) {
     712                        /* Encode reference to EBR */
     713                        entry->ptype = PT_EXTENDED_LBA;
     714                        entry->first_lba = host2uint32_t_le(src->ebr_addr - base);
     715                        entry->length = host2uint32_t_le(src->length + src->start_addr -
     716                            src->ebr_addr);
     717                } else {
     718                        /* Encode reference to partition */
     719                        entry->ptype = src->type;
     720                        entry->first_lba = host2uint32_t_le(src->start_addr - base);
     721                        entry->length = host2uint32_t_le(src->length);
     722                }
     723               
     724                if (entry->ptype == PT_UNUSED)
     725                        memset(entry, 0, sizeof(pt_entry_t));
     726        } else
     727                memset(entry, 0, sizeof(pt_entry_t));
     728}
     729
     730/** Check whether two partitions overlap */
     731static bool check_overlap(mbr_part_t *part1, mbr_part_t *part2)
     732{
     733        if ((part1->start_addr < part2->start_addr) &&
     734            (part1->start_addr + part1->length <= part2->start_addr))
    772735                return false;
    773         } else if (p1->start_addr > p2->start_addr && p2->start_addr + p2->length <= p1->start_addr) {
     736       
     737        if ((part1->start_addr > part2->start_addr) &&
     738            (part2->start_addr + part2->length <= part1->start_addr))
    774739                return false;
    775         }
    776 
     740       
    777741        return true;
    778742}
    779743
    780 /** Check whether one partition encapsulates the other
    781  *
    782  * @return              true/false
    783  */
    784 static bool check_encaps(mbr_part_t * inner, mbr_part_t * outer)
    785 {
    786         if (inner->start_addr <= outer->start_addr || outer->start_addr + outer->length <= inner->start_addr) {
     744/** Check whether one partition encapsulates the other */
     745static bool check_encaps(mbr_part_t *inner, mbr_part_t *outer)
     746{
     747        if ((inner->start_addr <= outer->start_addr) ||
     748            (outer->start_addr + outer->length <= inner->start_addr))
    787749                return false;
    788         } else if (outer->start_addr + outer->length < inner->start_addr + inner->length) {
     750       
     751        if (outer->start_addr + outer->length < inner->start_addr + inner->length)
    789752                return false;
    790         }
    791 
     753       
    792754        return true;
    793755}
    794756
    795 /** Check whether one partition preceeds the other
    796  *
    797  * @return              true/false
    798  */
    799 static bool check_preceeds(mbr_part_t * preceeder, mbr_part_t * precedee)
     757/** Check whether one partition preceeds the other */
     758static bool check_preceeds(mbr_part_t *preceeder, mbr_part_t *precedee)
    800759{
    801760        return preceeder->start_addr < precedee->start_addr;
    802761}
    803762
    804 mbr_err_val mbr_add_primary(mbr_label_t *label, mbr_part_t *p)
    805 {
    806         if (label->parts->n_primary == 4) {
     763mbr_err_val mbr_add_primary(mbr_label_t *label, mbr_part_t *part)
     764{
     765        if (label->parts->n_primary == 4)
    807766                return ERR_PRIMARY_FULL;
    808         }
    809        
    810         /* Check if partition makes space for MBR itself. */
    811         if (p->start_addr == 0) {
     767       
     768        /* Check if partition makes space for MBR itself */
     769        if (part->start_addr == 0)
    812770                return ERR_OUT_BOUNDS;
    813         }
    814        
    815         /* if it's extended, is there any other one? */
    816         if ((p->type == PT_EXTENDED || p->type == PT_EXTENDED_LBA) && label->parts->l_extended != NULL) {
     771       
     772        /* If it is an extended partition, is there any other one? */
     773        if (((part->type == PT_EXTENDED) || (part->type == PT_EXTENDED_LBA)) &&
     774            (label->parts->l_extended != NULL))
    817775                return ERR_EXTENDED_PRESENT;
    818         }
    819        
    820         /* find a place and add it */
     776       
     777        /* Find a place and add it */
    821778        mbr_part_t *iter;
    822779        mbr_part_t *empty = NULL;
     
    825782                        if (empty == NULL)
    826783                                empty = iter;
    827                 } else if (check_overlap(p, iter))
     784                } else if (check_overlap(part, iter))
    828785                        return ERR_OVERLAP;
    829786        }
    830787       
    831         list_insert_after(&(p->link), &(empty->link));
    832         list_remove(&(empty->link));
     788        list_insert_after(&part->link, &empty->link);
     789        list_remove(&empty->link);
    833790        free(empty);
    834791       
    835         label->parts->n_primary += 1;
    836        
    837         if (p->type == PT_EXTENDED || p->type == PT_EXTENDED_LBA)
    838                 label->parts->l_extended = &(p->link);
     792        label->parts->n_primary++;
     793       
     794        if ((part->type == PT_EXTENDED) || (part->type == PT_EXTENDED_LBA))
     795                label->parts->l_extended = &part->link;
    839796       
    840797        return EOK;
    841798}
    842799
    843 mbr_err_val mbr_add_logical(mbr_label_t *label, mbr_part_t *p)
    844 {
    845         /* is there any extended partition? */
     800mbr_err_val mbr_add_logical(mbr_label_t *label, mbr_part_t *part)
     801{
     802        /* Is there any extended partition? */
    846803        if (label->parts->l_extended == NULL)
    847804                return ERR_NO_EXTENDED;
    848805       
    849         /* is the logical partition inside the extended one? */
    850         mbr_part_t *ext = list_get_instance(label->parts->l_extended, mbr_part_t, link);
    851         if (!check_encaps(p, ext))
     806        /* Is the logical partition inside the extended partition? */
     807        mbr_part_t *extended = list_get_instance(label->parts->l_extended, mbr_part_t, link);
     808        if (!check_encaps(part, extended))
    852809                return ERR_OUT_BOUNDS;
    853810       
    854         /* find a place for the new partition in a sorted linked list */
     811        /* Find a place for the new partition in a sorted linked list */
    855812        bool first_logical = true;
    856813        mbr_part_t *iter;
    857814        mbr_part_foreach (label, iter) {
    858815                if (mbr_get_flag(iter, ST_LOGIC)) {
    859                         if (check_overlap(p, iter))
     816                        if (check_overlap(part, iter))
    860817                                return ERR_OVERLAP;
    861                         if (check_preceeds(iter, p)) {
    862                                 /* checking if there's at least one sector of space preceeding */
    863                                 if ((iter->start_addr + iter->length) >= p->start_addr - 1)
     818                       
     819                        if (check_preceeds(iter, part)) {
     820                                /* Check if there is at least one sector of space preceeding */
     821                                if ((iter->start_addr + iter->length) >= part->start_addr - 1)
    864822                                        return ERR_NO_EBR;
    865                         } else if (first_logical){
    866                                 /* First logical partition's EBR is before every other
    867                                  * logical partition. Thus we don't check if this partition
    868                                  * leaves enough space for it. */
     823                        } else if (first_logical) {
     824                                /*
     825                                 * First logical partition's EBR is before every other
     826                                 * logical partition. Thus we do not check if this partition
     827                                 * leaves enough space for it.
     828                                 */
    869829                                first_logical = false;
    870830                        } else {
    871                                 /* checking if there's at least one sector of space following (for following partitions's EBR) */
    872                                 if ((p->start_addr + p->length) >= iter->start_addr - 1)
     831                                /*
     832                                 * Check if there is at least one sector of space following
     833                                 * (for following partitions's EBR).
     834                                 */
     835                                if ((part->start_addr + part->length) >= iter->start_addr - 1)
    873836                                        return ERR_NO_EBR;
    874837                        }
     
    876839        }
    877840       
    878         /* alloc EBR if it's not already there */
    879         if (p->ebr == NULL) {
    880                 p->ebr = alloc_br();
    881                 if (p->ebr == NULL) {
     841        /* Allocate EBR if it is not already there */
     842        if (part->ebr == NULL) {
     843                part->ebr = alloc_br();
     844                if (part->ebr == NULL)
    882845                        return ERR_NOMEM;
    883                 }
    884         }
    885        
    886         /* add it */
    887         list_append(&(p->link), &(label->parts->list));
    888         label->parts->n_logical += 1;
     846        }
     847       
     848        list_append(&part->link, &label->parts->list);
     849        label->parts->n_logical++;
    889850       
    890851        return EOK;
    891852}
    892 
    893 
    894 
  • uspace/lib/mbr/libmbr.h

    rd51beba3 r6453e306  
    11/*
    22 * Copyright (c) 2009 Jiri Svoboda
    3  * Copyright (c) 2011, 2012, 2013 Dominik Taborsky
     3 * Copyright (c) 2011-2013 Dominik Taborsky
    44 * All rights reserved.
    55 *
     
    2828 */
    2929
    30  /** @addtogroup libmbr
     30/** @addtogroup libmbr
    3131 * @{
    3232 */
     
    4040#include "mbr.h"
    4141
    42 #define LIBMBR_NAME     "libmbr"
     42/*
     43 * WARNING: When changing both header and partitions, write first header,
     44 * then partitions. The MBR headers' raw_data is not updated to follow
     45 * partition changes.
     46 *
     47 * NOTE: Writing partitions writes the complete header as well.
     48 */
    4349
    4450typedef enum {
     
    4854        /** Logical partition, 0 = primary, 1 = logical*/
    4955        ST_LOGIC = 8
    50 } MBR_FLAGS;
     56} mbr_flags_t;
    5157
    5258typedef enum {
     
    7783} mbr_t;
    7884
    79 
    8085/** Partition */
    8186typedef struct mbr_part {
     
    9196        uint32_t length;
    9297        /** Points to Extended Boot Record of logical partition */
    93         br_block_t * ebr;
     98        br_block_t *ebr;
    9499        /** EBR address */
    95100        uint32_t ebr_addr;
     
    101106        unsigned char n_primary;
    102107        /** Index to the extended partition in the array */
    103         link_t * l_extended;
     108        link_t *l_extended;
    104109        /** Number of logical partitions */
    105110        unsigned int n_logical;
     
    111116typedef struct mbr_label {
    112117        /** MBR header */
    113         mbr_t * mbr;
     118        mbr_t *mbr;
    114119        /** Partition list */
    115120        mbr_partitions_t * parts;
     
    118123} mbr_label_t;
    119124
    120 /* Alloc complete label structure */
    121 extern mbr_label_t * mbr_alloc_label(void);
     125#define mbr_part_foreach(label, iterator) \
     126        for (iterator = list_get_instance((label)->parts->list.head.next, mbr_part_t, link); \
     127            iterator != list_get_instance(&((label)->parts->list.head), mbr_part_t, link); \
     128            iterator = list_get_instance(iterator->link.next, mbr_part_t, link))
     129
     130extern mbr_label_t *mbr_alloc_label(void);
     131
    122132extern void mbr_set_device(mbr_label_t *, service_id_t);
    123 
    124 /* Read/Write MBR header.
    125  * WARNING: when changing both header and partitions, write first header,
    126  * then partitions. The MBR headers' raw_data is NOT updated to follow
    127  * partition changes. */
    128 extern mbr_t * mbr_alloc_mbr(void);
     133extern mbr_t *mbr_alloc_mbr(void);
    129134extern int mbr_read_mbr(mbr_label_t *, service_id_t);
    130135extern int mbr_write_mbr(mbr_label_t *, service_id_t);
    131136extern int mbr_is_mbr(mbr_label_t *);
    132137
    133 /* Read/Write/Set MBR partitions.
    134  * NOTE: Writing partitions writes the complete header as well. */
    135 extern int          mbr_read_partitions(mbr_label_t *);
    136 extern int          mbr_write_partitions(mbr_label_t *, service_id_t);
    137 extern mbr_part_t * mbr_alloc_partition(void);
    138 extern mbr_partitions_t * mbr_alloc_partitions(void);
    139 extern mbr_err_val  mbr_add_partition(mbr_label_t *, mbr_part_t *);
    140 extern int          mbr_remove_partition(mbr_label_t *, size_t);
    141 extern int          mbr_get_flag(mbr_part_t *, MBR_FLAGS);
    142 extern void         mbr_set_flag(mbr_part_t *, MBR_FLAGS, bool);
    143 extern uint32_t     mbr_get_next_aligned(uint32_t, unsigned int);
    144 extern list_t *     mbr_get_list(mbr_label_t *);
    145 extern mbr_part_t * mbr_get_first_partition(mbr_label_t *);
    146 extern mbr_part_t * mbr_get_next_partition(mbr_label_t *, mbr_part_t *);
     138extern int mbr_read_partitions(mbr_label_t *);
     139extern int mbr_write_partitions(mbr_label_t *, service_id_t);
     140extern mbr_part_t *mbr_alloc_partition(void);
     141extern mbr_partitions_t *mbr_alloc_partitions(void);
     142extern mbr_err_val mbr_add_partition(mbr_label_t *, mbr_part_t *);
     143extern int mbr_remove_partition(mbr_label_t *, size_t);
     144extern int mbr_get_flag(mbr_part_t *, mbr_flags_t);
     145extern void mbr_set_flag(mbr_part_t *, mbr_flags_t, bool);
     146extern uint32_t mbr_get_next_aligned(uint32_t, unsigned int);
     147extern list_t *mbr_get_list(mbr_label_t *);
     148extern mbr_part_t *mbr_get_first_partition(mbr_label_t *);
     149extern mbr_part_t *mbr_get_next_partition(mbr_label_t *, mbr_part_t *);
    147150
    148 #define mbr_part_foreach(label, iterator) \
    149         for (iterator  = list_get_instance((label)->parts->list.head.next, mbr_part_t, link); \
    150              iterator != list_get_instance(&((label)->parts->list.head), mbr_part_t, link); \
    151              iterator  = list_get_instance(iterator->link.next, mbr_part_t, link))
    152 
    153 
    154 /* free() wrapper functions. */
    155151extern void mbr_free_label(mbr_label_t *);
    156152extern void mbr_free_mbr(mbr_t *);
     
    159155
    160156#endif
    161 
  • uspace/lib/mbr/mbr.h

    rd51beba3 r6453e306  
    11/*
    22 * Copyright (c) 2009 Jiri Svoboda
    3  * Copyright (c) 2011, 2012, 2013 Dominik Taborsky
     3 * Copyright (c) 2011-2013 Dominik Taborsky
    44 * All rights reserved.
    55 *
     
    3939#include <sys/types.h>
    4040
    41 /** Number of primary partition records */
    42 #define N_PRIMARY               4
    43 
    44 /** Boot record signature */
    45 #define BR_SIGNATURE    0xAA55
     41enum {
     42        /** Number of primary partition records */
     43        N_PRIMARY = 4,
     44       
     45        /** Boot record signature */
     46        BR_SIGNATURE = 0xAA55
     47};
    4648
    4749enum {
     
    5557enum {
    5658        /** Unused partition entry */
    57         PT_UNUSED       = 0x00,
     59        PT_UNUSED = 0x00,
    5860        /** Extended partition */
    59         PT_EXTENDED     = 0x05,
     61        PT_EXTENDED = 0x05,
    6062        /** Extended partition with LBA */
    61         PT_EXTENDED_LBA = 0x0F,
     63        PT_EXTENDED_LBA = 0x0F,
    6264        /** GPT Protective partition */
    63         PT_GPT  = 0xEE,
     65        PT_GPT = 0xEE,
    6466};
    6567
Note: See TracChangeset for help on using the changeset viewer.