Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 52f2c89 in mainline


Ignore:
Timestamp:
2013-06-24T22:29:44Z (7 years ago)
Author:
Dominik Taborsky (AT DOT) <brembyseznamcz>
Branches:
master
Children:
9bdfde73
Parents:
44c4886 (diff), 6317b33 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

hdisk, libmbr and libgpt updates

Location:
uspace
Files:
14 edited

Legend:

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

    r44c4886 r52f2c89  
    3939#include <libgpt.h>
    4040
     41typedef enum {
     42        LYT_NONE,
     43        LYT_MBR,
     44        LYT_GPT,
     45} layouts_t;
     46
    4147union label_data {
    4248        mbr_label_t     *mbr;
     
    4450};
    4551
     52typedef struct label label_t;
     53
     54struct label {
     55        layouts_t layout;
     56        union label_data data;
     57        unsigned int alignment;
     58        int (* destroy_label)(label_t *);
     59        int (* add_part)     (label_t *, tinput_t *);
     60        int (* delete_part)  (label_t *, tinput_t *);
     61        int (* new_label)    (label_t *);
     62        int (* print_parts)  (label_t *);
     63        int (* read_parts)   (label_t *, service_id_t);
     64        int (* write_parts)  (label_t *, service_id_t);
     65        int (* extra_funcs)  (label_t *, tinput_t *, service_id_t);
     66};
     67
    4668#endif
    4769
  • uspace/app/hdisk/func_gpt.c

    r44c4886 r52f2c89  
    3434
    3535#include <stdio.h>
     36#include <str.h>
    3637#include <errno.h>
    3738#include <str_error.h>
     
    4344static int set_gpt_partition(tinput_t *, gpt_part_t *);
    4445
    45 int add_gpt_part(tinput_t * in, union label_data * data)
    46 {
    47         gpt_part_t * p = gpt_alloc_partition(data->gpt->parts);
     46
     47int construct_gpt_label(label_t *this)
     48{
     49        this->layout = LYT_GPT;
     50        this->alignment = 1;
     51       
     52        this->add_part    = add_gpt_part;
     53        this->delete_part = delete_gpt_part;
     54        this->new_label   = new_gpt_label;
     55        this->print_parts = print_gpt_parts;
     56        this->read_parts  = read_gpt_parts;
     57        this->write_parts = write_gpt_parts;
     58        this->extra_funcs = extra_gpt_funcs;
     59       
     60        return this->new_label(this);
     61}
     62
     63int add_gpt_part(label_t *this, tinput_t *in)
     64{
     65        gpt_part_t * p = gpt_get_partition(this->data.gpt);
    4866        if (p == NULL) {
    4967                return ENOMEM;
    5068        }
    51 
     69       
    5270        return set_gpt_partition(in, p);
    5371}
    5472
    55 int delete_gpt_part(tinput_t * in, union label_data * data)
    56 {
     73int delete_gpt_part(label_t *this, tinput_t *in)
     74{
     75        int rc;
    5776        size_t idx;
    58 
     77       
    5978        printf("Number of the partition to delete (counted from 0): ");
    6079        idx = get_input_size_t(in);
    61 
    62         if (gpt_remove_partition(data->gpt->parts, idx) == -1) {
     80       
     81        rc = gpt_remove_partition(this->data.gpt, idx);
     82        if (rc != EOK) {
    6383                printf("Warning: running low on memory, not resizing...\n");
    64         }
    65 
    66         return EOK;
    67 }
    68 
    69 int destroy_gpt_label(union label_data *data)
    70 {
    71         return EOK;
    72 }
    73 
    74 int new_gpt_label(union label_data *data)
    75 {
    76         data->gpt->gpt = gpt_alloc_gpt_header();
    77         data->gpt->parts = gpt_alloc_partitions();
    78         return EOK;
    79 }
    80 
    81 int print_gpt_parts(union label_data *data)
     84                return rc;
     85        }
     86       
     87        return EOK;
     88}
     89
     90int destroy_gpt_label(label_t *this)
     91{
     92        gpt_free_label(this->data.gpt);
     93        return EOK;
     94}
     95
     96int new_gpt_label(label_t *this)
     97{
     98        this->data.gpt = gpt_alloc_label();
     99        return EOK;
     100}
     101
     102int print_gpt_parts(label_t *this)
    82103{
    83104        //int rc;
     
    87108        size_t i = 0;
    88109       
    89         gpt_part_foreach(data->gpt->parts, iter) {
     110        gpt_part_foreach(this->data.gpt, iter) {
     111                i++;
     112                //FIXMEE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
     113                if (gpt_get_part_type(iter) == GPT_PTE_UNUSED)
     114                        continue;
     115               
     116                if (i % 20 == 0)
     117                        printf("%15s %10s %10s Type: Name:\n", "Start:", "End:", "Length:");
     118               
    90119                //printf("\t%10u %10u %10u %3d\n", iter->start_addr, iter->start_addr + iter->length,
    91120                //              iter->length, gpt_get_part_type(iter), gpt_get_part_name(iter));
    92                 printf("%3u\t%10llu %10llu %10llu %3d %s\n", i, gpt_get_start_lba(iter), gpt_get_end_lba(iter),
     121                printf("%3u  %10llu %10llu %10llu    %3d %s\n", i-1, gpt_get_start_lba(iter), gpt_get_end_lba(iter),
    93122                                gpt_get_end_lba(iter) - gpt_get_start_lba(iter), gpt_get_part_type(iter),
    94123                                gpt_get_part_name(iter));
    95                 i++;
    96         }
    97 
     124        }
     125       
    98126        //return rc;
    99127        return EOK;
    100128}
    101129
    102 int read_gpt_parts(service_id_t dev_handle, union label_data *data)
    103 {
    104         return EOK;
    105 }
    106 
    107 int write_gpt_parts(service_id_t dev_handle, union label_data * data)
    108 {
    109         int rc;
    110 
    111         rc = gpt_write_partitions(data->gpt->parts, data->gpt->gpt, dev_handle);
     130int read_gpt_parts(label_t *this, service_id_t dev_handle)
     131{
     132        int rc;
     133       
     134        rc = gpt_read_header(this->data.gpt, dev_handle);
     135        if (rc != EOK) {
     136                printf("Error: Reading header failed: %d (%s)\n", rc, str_error(rc));
     137                return rc;
     138        }
     139       
     140        rc = gpt_read_partitions(this->data.gpt);
     141        if (rc != EOK) {
     142                printf("Error: Reading partitions failed: %d (%s)\n", rc, str_error(rc));
     143                return rc;
     144        }
     145       
     146        return EOK;
     147}
     148
     149int write_gpt_parts(label_t *this, service_id_t dev_handle)
     150{
     151        int rc;
     152       
     153        rc = gpt_write_partitions(this->data.gpt, dev_handle);
    112154        if (rc != EOK) {
    113155                printf("Error: Writing partitions failed: %d (%s)\n", rc, str_error(rc));
    114156                return rc;
    115157        }
    116 
    117         rc = gpt_write_gpt_header(data->gpt->gpt, dev_handle);
    118         if (rc != EOK) {
    119                 printf("Error: Writing partitions failed: %d (%s)\n", rc, str_error(rc));
    120                 return rc;
    121         }
    122 
    123         return EOK;
    124 }
    125 
    126 int extra_gpt_funcs(tinput_t * in, service_id_t dev_handle, union label_data * data)
     158       
     159        rc = gpt_write_header(this->data.gpt, dev_handle);
     160        if (rc != EOK) {
     161                printf("Error: Writing header failed: %d (%s)\n", rc, str_error(rc));
     162                return rc;
     163        }
     164       
     165        return EOK;
     166}
     167
     168int extra_gpt_funcs(label_t *this, tinput_t *in, service_id_t dev_handle)
    127169{
    128170        printf("Not implemented.\n");
     
    130172}
    131173
    132 static int set_gpt_partition(tinput_t * in, gpt_part_t * p)
    133 {
    134         //int rc;
    135 
     174static int set_gpt_partition(tinput_t *in, gpt_part_t *p)
     175{
     176        int rc;
     177       
    136178        uint64_t sa, ea;
    137 
     179       
    138180        printf("Set starting address (number): ");
    139181        sa = get_input_uint64(in);
    140 
     182       
    141183        printf("Set end addres (number): ");
    142184        ea = get_input_uint64(in);
    143 
     185       
    144186        if (ea <= sa) {
    145187                printf("Invalid value.\n");
    146188                return EINVAL;
    147189        }
    148 
    149 
    150         //p->start_addr = sa;
     190       
    151191        gpt_set_start_lba(p, sa);
    152         //p->length = ea - sa;
    153192        gpt_set_end_lba(p, ea);
    154 
    155         return EOK;
    156 }
    157 
     193       
     194       
     195        char *name;
     196        rc = get_input_line(in, &name);
     197        if (rc != EOK) {
     198                printf("Error reading name: %d (%s)\n", rc, str_error(rc));
     199                return rc;
     200        }
     201       
     202        gpt_set_part_name(p, name, str_size(name));
     203       
     204        return EOK;
     205}
     206
  • uspace/app/hdisk/func_gpt.h

    r44c4886 r52f2c89  
    4242#include "common.h"
    4343
    44 extern int add_gpt_part(tinput_t *, union label_data *);
    45 extern int delete_gpt_part(tinput_t *, union label_data *);
    46 extern int destroy_gpt_label(union label_data *);
    47 extern int new_gpt_label(union label_data *);
    48 extern int print_gpt_parts(union label_data *);
    49 extern int read_gpt_parts(service_id_t, union label_data *);
    50 extern int write_gpt_parts(service_id_t, union label_data *);
    51 extern int extra_gpt_funcs(tinput_t *, service_id_t, union label_data *);
     44extern int construct_gpt_label(label_t *);
     45extern int add_gpt_part     (label_t *, tinput_t *);
     46extern int delete_gpt_part  (label_t *, tinput_t *);
     47extern int destroy_gpt_label(label_t *);
     48extern int new_gpt_label    (label_t *);
     49extern int print_gpt_parts  (label_t *);
     50extern int read_gpt_parts   (label_t *, service_id_t);
     51extern int write_gpt_parts  (label_t *, service_id_t);
     52extern int extra_gpt_funcs  (label_t *, tinput_t *, service_id_t);
    5253
    5354#endif
  • uspace/app/hdisk/func_mbr.c

    r44c4886 r52f2c89  
    4141#include "input.h"
    4242
    43 static int set_mbr_partition(tinput_t *in, mbr_part_t *p);
    44 
    45 int add_mbr_part(tinput_t *in, union label_data *data)
     43static int set_mbr_partition(tinput_t *in, mbr_part_t *p, unsigned int alignment);
     44
     45int construct_mbr_label(label_t *this)
     46{
     47        this->layout = LYT_MBR;
     48        this->alignment = 1;
     49       
     50        this->add_part      = add_mbr_part;
     51        this->delete_part   = delete_mbr_part;
     52        this->destroy_label = destroy_mbr_label;
     53        this->new_label     = new_mbr_label;
     54        this->print_parts   = print_mbr_parts;
     55        this->read_parts    = read_mbr_parts;
     56        this->write_parts   = write_mbr_parts;
     57        this->extra_funcs   = extra_mbr_funcs;
     58       
     59        return this->new_label(this);
     60}
     61
     62int add_mbr_part(label_t *this, tinput_t *in)
    4663{
    4764        int rc;
    4865       
    4966        mbr_part_t *part = mbr_alloc_partition();
    50 
    51         set_mbr_partition(in, part);
    52 
    53         rc = mbr_add_partition(data->mbr, part);
    54         if (rc != EOK) {
    55                 printf("Error adding partition.\n");
    56         }
    57        
    58         return EOK;
    59 }
    60 
    61 int delete_mbr_part(tinput_t *in, union label_data *data)
     67       
     68        set_mbr_partition(in, part, this->alignment);
     69       
     70        rc = mbr_add_partition(this->data.mbr, part);
     71        if (rc != ERR_OK) {
     72                printf("Error adding partition: %d\n", rc);
     73        }
     74       
     75        return EOK;
     76}
     77
     78int delete_mbr_part(label_t *this, tinput_t *in)
    6279{
    6380        int rc;
    6481        size_t idx;
    65 
     82       
    6683        printf("Number of the partition to delete (counted from 0): ");
    6784        idx = get_input_size_t(in);
     
    7087                return errno;
    7188       
    72         rc = mbr_remove_partition(data->mbr, idx);
     89        rc = mbr_remove_partition(this->data.mbr, idx);
    7390        if(rc != EOK) {
    7491                printf("Error: something.\n");
    7592        }
    76 
    77         return EOK;
    78 }
    79 
    80 int destroy_mbr_label(union label_data *data)
    81 {
    82         mbr_free_label(data->mbr);
    83         return EOK;
    84 }
    85 
    86 int new_mbr_label(union label_data *data)
    87 {
    88         data->mbr = mbr_alloc_label();
    89         if (data->mbr == NULL)
     93       
     94        return EOK;
     95}
     96
     97int destroy_mbr_label(label_t *this)
     98{
     99        mbr_free_label(this->data.mbr);
     100        return EOK;
     101}
     102
     103int new_mbr_label(label_t *this)
     104{
     105        this->data.mbr = mbr_alloc_label();
     106        if (this->data.mbr == NULL)
    90107                return ENOMEM;
    91108        else
     
    94111
    95112/** Print current partition scheme */
    96 int print_mbr_parts(union label_data *data)
     113int print_mbr_parts(label_t *this)
    97114{
    98115        int num = 0;
    99 
    100         printf("Current partition scheme:\n");
     116       
     117        printf("Current partition scheme (MBR):\n");
    101118        //printf("\t\tBootable:\tStart:\tEnd:\tLength:\tType:\n");
    102119        printf("\t\t%10s  %10s %10s %10s %7s\n", "Bootable:", "Start:", "End:", "Length:", "Type:");
    103120       
    104121        mbr_part_t *it;
    105         mbr_part_foreach(data->mbr->parts, it) {
     122        //mbr_part_foreach(data->mbr, it) {
     123       
     124        for (it = mbr_get_first_partition(this->data.mbr); it != NULL;
     125             it = mbr_get_next_partition(this->data.mbr, it), ++num) {
    106126                if (it->type == PT_UNUSED)
    107127                        continue;
    108 
     128               
    109129                printf("\tP%d:\t", num);
    110130                if (mbr_get_flag(it, ST_BOOT))
     
    112132                else
    113133                        printf(" ");
    114 
     134               
    115135                printf("\t%10u %10u %10u %7u\n", it->start_addr, it->start_addr + it->length, it->length, it->type);
    116 
    117                 ++num;
    118         }
    119 
     136               
     137                //++num;
     138        }
     139       
    120140        printf("%d partitions found.\n", num);
    121141       
     
    123143}
    124144
    125 int read_mbr_parts(service_id_t dev_handle, union label_data *data)
     145int read_mbr_parts(label_t *this, service_id_t dev_handle)
    126146{
    127147        int rc;
    128         printf("mbr\n");
    129         rc = mbr_read_mbr(data->mbr, dev_handle);
     148        rc = mbr_read_mbr(this->data.mbr, dev_handle);
    130149        if (rc != EOK)
    131150                return rc;
    132         printf("ismbr\n");
    133         if (!mbr_is_mbr(data->mbr))
     151       
     152        if (!mbr_is_mbr(this->data.mbr))
    134153                return EINVAL;
    135         printf("parts\n");
    136         rc = mbr_read_partitions(data->mbr);
     154       
     155        rc = mbr_read_partitions(this->data.mbr);
    137156        if (rc != EOK)
    138157                return rc;
    139         printf("end\n");
    140         return EOK;
    141 }
    142 
    143 int write_mbr_parts(service_id_t dev_handle, union label_data *data)
    144 {
    145         int rc = mbr_write_partitions(data->mbr, dev_handle);
     158       
     159        return EOK;
     160}
     161
     162int write_mbr_parts(label_t *this, service_id_t dev_handle)
     163{
     164        int rc = mbr_write_partitions(this->data.mbr, dev_handle);
    146165        if (rc != EOK) {
    147166                printf("Error occured during writing: ERR: %d: %s\n", rc, str_error(rc));
     
    151170}
    152171
    153 int extra_mbr_funcs(tinput_t *in, service_id_t dev_handle, union label_data *data)
     172int extra_mbr_funcs(label_t *this, tinput_t *in, service_id_t dev_handle)
    154173{
    155174        printf("Not implemented.\n");
     
    157176}
    158177
    159 static int set_mbr_partition(tinput_t *in, mbr_part_t *p)
     178static int set_mbr_partition(tinput_t *in, mbr_part_t *p, unsigned int alignment)
    160179{
    161180        int c;
     
    174193                        break;
    175194                default:
    176                         printf("Invalid type. Cancelled.");
     195                        printf("Invalid type. Cancelled.\n");
    177196                        return EINVAL;
    178197        }
     198       
     199        printf("ST_LOGIC: %d, %hd\n", mbr_get_flag(p, ST_LOGIC), p->status);
    179200       
    180201        printf("Set type (0-255): ");
     
    200221        if (sa == 0 && errno != EOK)
    201222                return errno;
     223       
     224        if (alignment != 0 && alignment != 1) {
     225                sa = mbr_get_next_aligned(sa, alignment);
     226                printf("Starting address was aligned to %u.\n", sa);
     227        }
    202228
    203229        printf("Set end addres (number): ");
     
    206232                return errno;
    207233       
     234        /* Align ending address, not in use */
     235        /*if (alignment != 0 && alignment != 1) {
     236                ea = mbr_get_next_aligned(ea, alignment) - alignment;
     237                printf("Starting address was aligned to %u.\n", ea);
     238        }*/
     239       
    208240        if(ea < sa) {
    209241                printf("Invalid value. Canceled.\n");
  • uspace/app/hdisk/func_mbr.h

    r44c4886 r52f2c89  
    4242#include "common.h"
    4343
    44 extern int add_mbr_part(tinput_t *, union label_data *);
    45 extern int delete_mbr_part(tinput_t *, union label_data *);
    46 extern int destroy_mbr_label(union label_data *);
    47 extern int new_mbr_label(union label_data *);
    48 extern int print_mbr_parts(union label_data *);
    49 extern int read_mbr_parts(service_id_t, union label_data *);
    50 extern int write_mbr_parts(service_id_t, union label_data *);
    51 extern int extra_mbr_funcs(tinput_t *, service_id_t, union label_data *);
     44extern int construct_mbr_label(label_t *);
     45extern int add_mbr_part     (label_t *, tinput_t *);
     46extern int delete_mbr_part  (label_t *, tinput_t *);
     47extern int destroy_mbr_label(label_t *);
     48extern int new_mbr_label    (label_t *);
     49extern int print_mbr_parts  (label_t *);
     50extern int read_mbr_parts   (label_t *, service_id_t);
     51extern int write_mbr_parts  (label_t *, service_id_t);
     52extern int extra_mbr_funcs  (label_t *, tinput_t *, service_id_t);
    5253
    5354#endif
  • uspace/app/hdisk/func_none.c

    r44c4886 r52f2c89  
    4141
    4242
    43 int add_none_part(tinput_t *in, union label_data *data)
     43int construct_none_label(label_t *this)
     44{
     45        this->layout = LYT_NONE;
     46       
     47        this->add_part      = add_none_part;
     48        this->delete_part   = delete_none_part;
     49        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;
     55       
     56        return EOK;
     57}
     58
     59int add_none_part(label_t *this, tinput_t * in)
    4460{
    4561        not_implemented();
     
    4763}
    4864
    49 int delete_none_part(tinput_t *in, union label_data *data)
     65int delete_none_part(label_t *this, tinput_t * in)
    5066{
    5167        not_implemented();
     
    5369}
    5470
    55 int destroy_none_label(union label_data *data)
     71int destroy_none_label(label_t *this)
     72{
     73        return EOK;
     74}
     75
     76int new_none_label(label_t *this)
    5677{
    5778        not_implemented();
     
    5980}
    6081
    61 int new_none_label(union label_data *data)
     82int print_none_parts(label_t *this)
    6283{
    6384        not_implemented();
     
    6586}
    6687
    67 int print_none_parts(union label_data *data)
     88int read_none_parts(label_t *this, service_id_t dev_handle)
    6889{
    6990        not_implemented();
     
    7192}
    7293
    73 int read_none_parts(service_id_t dev_handle, union label_data *data)
     94int write_none_parts(label_t *this, service_id_t dev_handle)
    7495{
    7596        not_implemented();
     
    7798}
    7899
    79 int write_none_parts(service_id_t dev_handle, union label_data *data)
    80 {
    81         not_implemented();
    82         return EOK;
    83 }
    84 
    85 int extra_none_funcs(tinput_t *in, service_id_t dev_handle, union label_data *data)
     100int extra_none_funcs(label_t *this, tinput_t * in, service_id_t dev_handle)
    86101{
    87102        not_implemented();
  • uspace/app/hdisk/func_none.h

    r44c4886 r52f2c89  
    4141#include "common.h"
    4242
    43 extern int add_none_part(tinput_t *, union label_data *);
    44 extern int delete_none_part(tinput_t *, union label_data *);
    45 extern int destroy_none_label(union label_data *);
    46 extern int new_none_label(union label_data *);
    47 extern int print_none_parts(union label_data *);
    48 extern int read_none_parts(service_id_t, union label_data *);
    49 extern int write_none_parts(service_id_t, union label_data *);
    50 extern int extra_none_funcs(tinput_t *, service_id_t, union label_data *);
     43extern int construct_none_label(label_t *);
     44extern int add_none_part     (label_t *, tinput_t *);
     45extern int delete_none_part  (label_t *, tinput_t *);
     46extern int destroy_none_label(label_t *);
     47extern int new_none_label    (label_t *);
     48extern int print_none_parts  (label_t *);
     49extern int read_none_parts   (label_t *, service_id_t);
     50extern int write_none_parts  (label_t *, service_id_t);
     51extern int extra_none_funcs  (label_t *, tinput_t *, service_id_t);
    5152
    5253#endif
  • uspace/app/hdisk/hdisk.c

    r44c4886 r52f2c89  
    5656void print_help(void);
    5757void select_label_format(tinput_t *);
    58 void fill_label_funcs(void);
     58void construct_label(layouts_t);
    5959void free_label(void);
    6060int try_read(service_id_t);
    61 
    62 int construct_none_label(void);
    63 
    64 int construct_mbr_label(void);
    6561int try_read_mbr(service_id_t);
    66 
    67 int construct_gpt_label(void);
    6862int try_read_gpt(service_id_t);
     63void set_alignment(tinput_t *);
    6964
    7065
     
    8782        }
    8883       
    89         printf("Init.\n");
    9084        init_label();
    9185       
     
    115109        mbr_free_mbr(mbr);*/
    116110       
    117         printf("Try MBR.\n");
    118111        rc = try_read_mbr(dev_handle);
    119112        if (rc == EOK)
     
    140133        */
    141134       
    142         printf("Try GPT.\n");
    143135        rc = try_read_gpt(dev_handle);
    144136        if (rc == EOK)
     
    149141       
    150142interact:
    151         printf("interact.\n");
     143       
    152144        rc = interact(dev_handle);
    153145       
     
    161153{
    162154        int input;
    163         tinput_t * in;
     155        tinput_t *in;
    164156       
    165157        in = tinput_new();
     
    179171                switch(input) {
    180172                        case 'a':
    181                                 label.add_part(in, &label.data);
    182                                 break;
    183                         case 'b':
    184                                 label.add_part(in, &label.data);
     173                                label.add_part(&label, in);
    185174                                break;
    186175                        case 'd':
    187                                 label.delete_part(in, &label.data);
     176                                label.delete_part(&label, in);
    188177                                break;
    189178                        case 'e':
    190                                 label.extra_funcs(in, dev_handle, &label.data);
     179                                label.extra_funcs(&label, in, dev_handle);
    191180                                break;
    192181                        case 'f':
     
    197186                                print_help();
    198187                                break;
     188                        case 'l':
     189                                set_alignment(in);
     190                                break;
    199191                        case 'n':
     192                                printf("Discarding label...\n");
    200193                                free_label();
    201                                 label.new_label(&label.data);
     194                                label.new_label(&label);
    202195                                break;
    203196                        case 'p':
    204                                 label.print_parts(&label.data);
     197                                label.print_parts(&label);
    205198                                break;
    206199                        case 'q':
    207200                                putchar('\n');
    208201                                goto end;
     202                        case 'r':
     203                                label.read_parts(&label, dev_handle);
    209204                        case 'w':
    210                                 label.write_parts(dev_handle, &label.data);
     205                                label.write_parts(&label, dev_handle);
    211206                                break;
    212207                        default:
     
    228223                "\t 'd' \t\t Delete partition.\n"
    229224                "\t 'e' \t\t Extra functions (per label format).\n"
    230                 "\t 'f' \t\t Switch the format of the partition label."
     225                "\t 'f' \t\t Switch the format of the partition label.\n"
    231226                "\t 'h' \t\t Prints help. See help for more.\n"
    232227                "\t 'l' \t\t Set alignment.\n"
    233228                "\t 'n' \t\t Create new label (discarding the old one).\n"
    234229                "\t 'p' \t\t Prints label contents.\n"
     230                "\t 'q' \t\t Quit.\n"
     231                "\t 'r' \t\t Read label from disk.\n"
    235232                "\t 'w' \t\t Write label to disk.\n"
    236                 "\t 'q' \t\t Quit.\n"
    237233                );
    238234
     
    244240                        "1) MBR\n"
    245241                        "2) GPT\n"
    246                 );
     242              );
    247243       
    248244        uint8_t val = get_input_uint8(in);
     
    250246                case 0:
    251247                        free_label();
    252                         label.layout = LYT_NONE;
    253                         fill_label_funcs();
     248                        construct_label(LYT_NONE);
    254249                        break;
    255250                case 1:
    256251                        free_label();
    257                         label.layout = LYT_MBR;
    258                         fill_label_funcs();
     252                        construct_label(LYT_MBR);
    259253                        break;
    260254                case 2:
    261255                        free_label();
     256                        construct_label(LYT_GPT);
     257                        break;
     258        }
     259}
     260
     261void construct_label(layouts_t layout)
     262{
     263        switch(layout) {
     264                case LYT_MBR:
     265                        label.layout = LYT_MBR;
     266                        construct_mbr_label(&label);
     267                        break;
     268                case LYT_GPT:
    262269                        label.layout = LYT_GPT;
    263                         fill_label_funcs();
    264                         break;
    265         }
    266 }
    267 
    268 void fill_label_funcs(void)
    269 {
    270         switch(label.layout) {
    271                 case LYT_MBR:
    272                         construct_mbr_label();
    273                         break;
    274                 case LYT_GPT:
    275                         construct_gpt_label();
     270                        construct_gpt_label(&label);
    276271                        break;
    277272                default:
    278                         construct_none_label();
     273                        label.layout = LYT_NONE;
     274                        construct_none_label(&label);
    279275                        break;
    280276        }
     
    283279void free_label(void)
    284280{
    285         /*
    286         switch(label.layout) {
    287                 case LYT_MBR:
    288                         destroy_mbr_label(&label);
    289                         break;
    290                 case LYT_GPT:
    291                         destroy_gpt_label(&label);
    292                         break;
    293                 default:
    294                         break;
    295         }
    296         */
    297        
    298         label.destroy_label(&label.data);
     281        label.destroy_label(&label);
    299282}
    300283
    301284int try_read(service_id_t dev_handle)
    302285{
    303         fill_label_funcs();
    304         printf("read_parts\n");
    305         return label.read_parts(dev_handle, &label.data);
    306 }
    307 
    308 int construct_none_label()
    309 {
    310         label.add_part      = add_none_part;
    311         label.delete_part   = delete_none_part;
    312         label.destroy_label = destroy_none_label;
    313         label.new_label     = new_none_label;
    314         label.print_parts   = print_none_parts;
    315         label.read_parts    = read_none_parts;
    316         label.write_parts   = write_none_parts;
    317         label.extra_funcs   = extra_none_funcs;
    318        
    319         return EOK;
    320 }
    321 
    322 int construct_mbr_label()
    323 {
    324         label.add_part      = add_mbr_part;
    325         label.delete_part   = delete_mbr_part;
    326         label.destroy_label = destroy_mbr_label;
    327         label.new_label     = new_mbr_label;
    328         label.print_parts   = print_mbr_parts;
    329         label.read_parts    = read_mbr_parts;
    330         label.write_parts   = write_mbr_parts;
    331         label.extra_funcs   = extra_mbr_funcs;
    332        
    333         return label.new_label(&label.data);
     286        return label.read_parts(&label, dev_handle);
    334287}
    335288
    336289int try_read_mbr(service_id_t dev_handle)
    337290{
    338         label.layout = LYT_MBR;
     291        construct_label(LYT_MBR);
    339292        return try_read(dev_handle);
    340293}
    341294
    342 int construct_gpt_label()
    343 {
    344         label.add_part    = add_gpt_part;
    345         label.delete_part = delete_gpt_part;
    346         label.new_label   = new_gpt_label;
    347         label.print_parts = print_gpt_parts;
    348         label.read_parts  = read_gpt_parts;
    349         label.write_parts = write_gpt_parts;
    350         label.extra_funcs = extra_gpt_funcs;
    351        
    352         return label.new_label(&label.data);
    353 }
    354 
    355295int try_read_gpt(service_id_t dev_handle)
    356296{
    357         label.layout = LYT_GPT;
     297        construct_label(LYT_GPT);
    358298        return try_read(dev_handle);
    359299}
    360300
    361 
    362 
    363 
    364 
    365 
    366 
    367 
    368 
    369 
    370 
    371 
    372 
    373 
    374 
    375 
    376 
    377 
    378 
    379 
    380 
    381 
    382 
    383 
    384 
    385 
     301void set_alignment(tinput_t *in)
     302{
     303        printf("Set alignment to sectors: ");
     304        label.alignment = get_input_uint32(in);
     305        printf("Alignment set to %u sectors.\n", label.alignment);
     306}
     307
     308
     309
     310
     311
     312
     313
     314
     315
     316
  • uspace/app/hdisk/hdisk.h

    r44c4886 r52f2c89  
    3535#include "common.h"
    3636
    37 typedef enum {
    38         LYT_NONE,
    39         LYT_MBR,
    40         LYT_GPT,
    41 } layouts_t;
    42 
    43 typedef struct label {
    44         layouts_t layout;
    45         union label_data data;
    46         int (* add_part)     (tinput_t *,   union label_data *);
    47         int (* delete_part)  (tinput_t *,   union label_data *);
    48         int (* destroy_label)(              union label_data *);
    49         int (* new_label)    (              union label_data *);
    50         int (* print_parts)  (              union label_data *);
    51         int (* read_parts)   (service_id_t, union label_data *);
    52         int (* write_parts)  (service_id_t, union label_data *);
    53         int (* extra_funcs)  (tinput_t *, service_id_t, union label_data *);
    54 } label_t;
    55 
    5637#define init_label() \
    5738        label.layout = LYT_NONE
  • uspace/lib/gpt/global.c

    r44c4886 r52f2c89  
    4141
    4242const struct partition_type gpt_ptypes[] = {
    43         { "Unused entry",                                       "00000000-0000-0000-0000-000000000000" },
    44         { "MBR partition scheme",                       "024DEE41-33E7-11D3-9D69-0008C781F39F" },
    45         { "EFI System",                                         "C12A7328-F81F-11D2-BA4B-00A0C93EC93B" },
    46         { "BIOS Boot",                                          "21686148-6449-6E6F-744E-656564454649" },
    47         { "Windows Reserved",                           "E3C9E316-0B5C-4DB8-817D-F92DF00215AE" },
    48         { "Windows Basic data",                         "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7" },
    49         { "Windows LDM metadata",                       "5808C8AA-7E8F-42E0-85D2-E1E90434CFB3" },
    50         { "Windows LDM data",                           "AF9B60A0-1431-4F62-BC68-3311714A69AD" },
    51         { "Windows Recovery Environment",       "DE94BBA4-06D1-4D40-A16A-BFD50179D6AC" },
    52         { "Windows IBM GPFS",                           "37AFFC90-EF7D-4E96-91C3-2D7AE055B174" },
    53         { "Windows Cluster metadata",           "DB97DBA9-0840-4BAE-97F0-FFB9A327C7E1" },
    54         { "HP-UX Data",                                         "75894C1E-3AEB-11D3-B7C1-7B03A0000000" },
    55         { "HP-UX Service",                                      "E2A1E728-32E3-11D6-A682-7B03A0000000" },
    56         { "Linux filesystem data",                      "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7" },
    57         { "Linux filesystem data",                      "0FC63DAF-8483-4772-8E79-3D69D8477DE4" },
    58         { "Linux RAID",                                         "A19D880F-05FC-4D3B-A006-743F0F84911E" },
    59         { "Linux Swap",                                         "0657FD6D-A4AB-43C4-84E5-0933C84B4F4F" },
    60         { "Linux LVM",                                          "E6D6D379-F507-44C2-A23C-238F2A3DF928" },
    61         { "Linux Reserved",                                     "8DA63339-0007-60C0-C436-083AC8230908" },
    62         { "FreeBSD Boot",                                       "83BD6B9D-7F41-11DC-BE0B-001560B84F0F" },
    63         { "FreeBSD Data",                                       "516E7CB4-6ECF-11D6-8FF8-00022D09712B" },
    64         { "FreeBSD Swap",                                       "516E7CB5-6ECF-11D6-8FF8-00022D09712B" },
    65         { "FreeBSD UFS",                                        "516E7CB6-6ECF-11D6-8FF8-00022D09712B" },
    66         { "FreeBSD Vinum VM",                           "516E7CB8-6ECF-11D6-8FF8-00022D09712B" },
    67         { "FreeBSD ZFS",                                        "516E7CBA-6ECF-11D6-8FF8-00022D09712B" },
    68         { "Mac OS X HFS+",                                      "48465300-0000-11AA-AA11-00306543ECAC" },
    69         { "Mac OS X UFS",                                       "55465300-0000-11AA-AA11-00306543ECAC" },
    70         { "Mac OS X ZFS",                                       "6A898CC3-1DD2-11B2-99A6-080020736631" },
    71         { "Mac OS X RAID",                                      "52414944-0000-11AA-AA11-00306543ECAC" },
    72         { "Mac OS X RAID, offline",                     "52414944-5F4F-11AA-AA11-00306543ECAC" },
    73         { "Mac OS X Boot",                                      "426F6F74-0000-11AA-AA11-00306543ECAC" },
    74         { "Mac OS X Label",                                     "4C616265-6C00-11AA-AA11-00306543ECAC" },
    75         { "Mac OS X TV Recovery",                       "5265636F-7665-11AA-AA11-00306543ECAC" },
    76         { "Mac OS X Core Storage",                      "53746F72-6167-11AA-AA11-00306543ECAC" },
    77         { "Solaris Boot",                                       "6A82CB45-1DD2-11B2-99A6-080020736631" },
    78         { "Solaris Root",                                       "6A85CF4D-1DD2-11B2-99A6-080020736631" },
    79         { "Solaris Swap",                                       "6A87C46F-1DD2-11B2-99A6-080020736631" },
    80         { "Solaris Backup",                                     "6A8B642B-1DD2-11B2-99A6-080020736631" },
    81         { "Solaris /usr",                                       "6A898CC3-1DD2-11B2-99A6-080020736631" },
    82         { "Solaris /var",                                       "6A8EF2E9-1DD2-11B2-99A6-080020736631" },
    83         { "Solaris /home",                                      "6A90BA39-1DD2-11B2-99A6-080020736631" },
    84         { "Solaris Alternate sector",           "6A9283A5-1DD2-11B2-99A6-080020736631" },
    85         { "Solaris Reserved",                           "6A945A3B-1DD2-11B2-99A6-080020736631" },
    86         { "Solaris Reserved",                           "6A9630D1-1DD2-11B2-99A6-080020736631" },
    87         { "Solaris Reserved",                           "6A980767-1DD2-11B2-99A6-080020736631" },
    88         { "Solaris Reserved",                           "6A96237F-1DD2-11B2-99A6-080020736631" },
    89         { "Solaris Reserved",                           "6A8D2AC7-1DD2-11B2-99A6-080020736631" },
    90         { "NetBSD Swap",                                        "49F48D32-B10E-11DC-B99B-0019D1879648" },
    91         { "NetBSD FFS",                                         "49F48D5A-B10E-11DC-B99B-0019D1879648" },
    92         { "NetBSD LFS",                                         "49F48D82-B10E-11DC-B99B-0019D1879648" },
    93         { "NetBSD RAID",                                        "49F48DAA-B10E-11DC-B99B-0019D1879648" },
    94         { "NetBSD Concatenated",                        "2DB519C4-B10F-11DC-B99B-0019D1879648" },
    95         { "NetBSD Encrypted",                           "2DB519EC-B10F-11DC-B99B-0019D1879648" },
    96         { "ChromeOS ChromeOS kernel",           "FE3A2A5D-4F32-41A7-B725-ACCC3285A309" },
    97         { "ChromeOS rootfs",                            "3CB8E202-3B7E-47DD-8A3C-7FF2A13CFCEC" },
    98         { "ChromeOS future use",                        "2E0A753D-9E48-43B0-8337-B15192CB1B5E" },
    99         { "MidnightBSD Boot",                           "85D5E45E-237C-11E1-B4B3-E89A8F7FC3A7" },
    100         { "MidnightBSD Data",                           "85D5E45A-237C-11E1-B4B3-E89A8F7FC3A7" },
    101         { "MidnightBSD Swap",                           "85D5E45B-237C-11E1-B4B3-E89A8F7FC3A7" },
    102         { "MidnightBSD UFS",                            "0394Ef8B-237E-11E1-B4B3-E89A8F7FC3A7" },
    103         { "MidnightBSD Vinum VM",                       "85D5E45C-237C-11E1-B4B3-E89A8F7FC3A7" },
    104         { "MidnightBSD ZFS",                            "85D5E45D-237C-11E1-B4B3-E89A8F7FC3A7" },
    105         { "Uknown", NULL}       // keep this as the last one! gpt_get_part_type depends on it!
     43        { "Unused entry",                                       "00000000" "0000" "0000" "0000" "000000000000" },
     44        { "MBR partition scheme",                       "024DEE41" "33E7" "11D3" "9D69" "0008C781F39F" },
     45        { "EFI System",                                         "C12A7328" "F81F" "11D2" "BA4B" "00A0C93EC93B" },
     46        { "BIOS Boot",                                          "21686148" "6449" "6E6F" "744E" "656564454649" },
     47        { "Windows Reserved",                           "E3C9E316" "0B5C" "4DB8" "817D" "F92DF00215AE" },
     48        { "Windows Basic data",                         "EBD0A0A2" "B9E5" "4433" "87C0" "68B6B72699C7" },
     49        { "Windows LDM metadata",                       "5808C8AA" "7E8F" "42E0" "85D2" "E1E90434CFB3" },
     50        { "Windows LDM data",                           "AF9B60A0" "1431" "4F62" "BC68" "3311714A69AD" },
     51        { "Windows Recovery Environment",       "DE94BBA4" "06D1" "4D40" "A16A" "BFD50179D6AC" },
     52        { "Windows IBM GPFS",                           "37AFFC90" "EF7D" "4E96" "91C3" "2D7AE055B174" },
     53        { "Windows Cluster metadata",           "DB97DBA9" "0840" "4BAE" "97F0" "FFB9A327C7E1" },
     54        { "HP-UX Data",                                         "75894C1E" "3AEB" "11D3" "B7C1" "7B03A0000000" },
     55        { "HP-UX Service",                                      "E2A1E728" "32E3" "11D6" "A682" "7B03A0000000" },
     56        { "Linux filesystem data",                      "EBD0A0A2" "B9E5" "4433" "87C0" "68B6B72699C7" },
     57        { "Linux filesystem data",                      "0FC63DAF" "8483" "4772" "8E79" "3D69D8477DE4" },
     58        { "Linux RAID",                                         "A19D880F" "05FC" "4D3B" "A006" "743F0F84911E" },
     59        { "Linux Swap",                                         "0657FD6D" "A4AB" "43C4" "84E5" "0933C84B4F4F" },
     60        { "Linux LVM",                                          "E6D6D379" "F507" "44C2" "A23C" "238F2A3DF928" },
     61        { "Linux Reserved",                                     "8DA63339" "0007" "60C0" "C436" "083AC8230908" },
     62        { "FreeBSD Boot",                                       "83BD6B9D" "7F41" "11DC" "BE0B" "001560B84F0F" },
     63        { "FreeBSD Data",                                       "516E7CB4" "6ECF" "11D6" "8FF8" "00022D09712B" },
     64        { "FreeBSD Swap",                                       "516E7CB5" "6ECF" "11D6" "8FF8" "00022D09712B" },
     65        { "FreeBSD UFS",                                        "516E7CB6" "6ECF" "11D6" "8FF8" "00022D09712B" },
     66        { "FreeBSD Vinum VM",                           "516E7CB8" "6ECF" "11D6" "8FF8" "00022D09712B" },
     67        { "FreeBSD ZFS",                                        "516E7CBA" "6ECF" "11D6" "8FF8" "00022D09712B" },
     68        { "Mac OS X HFS+",                                      "48465300" "0000" "11AA" "AA11" "00306543ECAC" },
     69        { "Mac OS X UFS",                                       "55465300" "0000" "11AA" "AA11" "00306543ECAC" },
     70        { "Mac OS X ZFS",                                       "6A898CC3" "1DD2" "11B2" "99A6" "080020736631" },
     71        { "Mac OS X RAID",                                      "52414944" "0000" "11AA" "AA11" "00306543ECAC" },
     72        { "Mac OS X RAID, offline",                     "52414944" "5F4F" "11AA" "AA11" "00306543ECAC" },
     73        { "Mac OS X Boot",                                      "426F6F74" "0000" "11AA" "AA11" "00306543ECAC" },
     74        { "Mac OS X Label",                                     "4C616265" "6C00" "11AA" "AA11" "00306543ECAC" },
     75        { "Mac OS X TV Recovery",                       "5265636F" "7665" "11AA" "AA11" "00306543ECAC" },
     76        { "Mac OS X Core Storage",                      "53746F72" "6167" "11AA" "AA11" "00306543ECAC" },
     77        { "Solaris Boot",                                       "6A82CB45" "1DD2" "11B2" "99A6" "080020736631" },
     78        { "Solaris Root",                                       "6A85CF4D" "1DD2" "11B2" "99A6" "080020736631" },
     79        { "Solaris Swap",                                       "6A87C46F" "1DD2" "11B2" "99A6" "080020736631" },
     80        { "Solaris Backup",                                     "6A8B642B" "1DD2" "11B2" "99A6" "080020736631" },
     81        { "Solaris /usr",                                       "6A898CC3" "1DD2" "11B2" "99A6" "080020736631" },
     82        { "Solaris /var",                                       "6A8EF2E9" "1DD2" "11B2" "99A6" "080020736631" },
     83        { "Solaris /home",                                      "6A90BA39" "1DD2" "11B2" "99A6" "080020736631" },
     84        { "Solaris Alternate sector",           "6A9283A5" "1DD2" "11B2" "99A6" "080020736631" },
     85        { "Solaris Reserved",                           "6A945A3B" "1DD2" "11B2" "99A6" "080020736631" },
     86        { "Solaris Reserved",                           "6A9630D1" "1DD2" "11B2" "99A6" "080020736631" },
     87        { "Solaris Reserved",                           "6A980767" "1DD2" "11B2" "99A6" "080020736631" },
     88        { "Solaris Reserved",                           "6A96237F" "1DD2" "11B2" "99A6" "080020736631" },
     89        { "Solaris Reserved",                           "6A8D2AC7" "1DD2" "11B2" "99A6" "080020736631" },
     90        { "NetBSD Swap",                                        "49F48D32" "B10E" "11DC" "B99B" "0019D1879648" },
     91        { "NetBSD FFS",                                         "49F48D5A" "B10E" "11DC" "B99B" "0019D1879648" },
     92        { "NetBSD LFS",                                         "49F48D82" "B10E" "11DC" "B99B" "0019D1879648" },
     93        { "NetBSD RAID",                                        "49F48DAA" "B10E" "11DC" "B99B" "0019D1879648" },
     94        { "NetBSD Concatenated",                        "2DB519C4" "B10F" "11DC" "B99B" "0019D1879648" },
     95        { "NetBSD Encrypted",                           "2DB519EC" "B10F" "11DC" "B99B" "0019D1879648" },
     96        { "ChromeOS ChromeOS kernel",           "FE3A2A5D" "4F32" "41A7" "B725" "ACCC3285A309" },
     97        { "ChromeOS rootfs",                            "3CB8E202" "3B7E" "47DD" "8A3C" "7FF2A13CFCEC" },
     98        { "ChromeOS future use",                        "2E0A753D" "9E48" "43B0" "8337" "B15192CB1B5E" },
     99        { "MidnightBSD Boot",                           "85D5E45E" "237C" "11E1" "B4B3" "E89A8F7FC3A7" },
     100        { "MidnightBSD Data",                           "85D5E45A" "237C" "11E1" "B4B3" "E89A8F7FC3A7" },
     101        { "MidnightBSD Swap",                           "85D5E45B" "237C" "11E1" "B4B3" "E89A8F7FC3A7" },
     102        { "MidnightBSD UFS",                            "0394Ef8B" "237E" "11E1" "B4B3" "E89A8F7FC3A7" },
     103        { "MidnightBSD Vinum VM",                       "85D5E45C" "237C" "11E1" "B4B3" "E89A8F7FC3A7" },
     104        { "MidnightBSD ZFS",                            "85D5E45D" "237C" "11E1" "B4B3" "E89A8F7FC3A7" },
     105        { "Uknown", NULL} /* keep this as the last one! gpt_get_part_type depends on it! */
    106106};
     107
     108
     109
  • uspace/lib/gpt/libgpt.c

    r44c4886 r52f2c89  
    5151#include "libgpt.h"
    5252
    53 static int load_and_check_header(service_id_t handle, aoff64_t addr, size_t b_size, gpt_header_t * header);
     53static int load_and_check_header(service_id_t handle, aoff64_t addr, size_t b_size, gpt_header_t *header);
    5454static gpt_partitions_t * alloc_part_array(uint32_t num);
    55 static int extend_part_array(gpt_partitions_t * p);
    56 static int reduce_part_array(gpt_partitions_t * p);
     55static int extend_part_array(gpt_partitions_t *);
     56static int reduce_part_array(gpt_partitions_t *);
    5757static long long nearest_larger_int(double a);
    58 
     58static uint8_t get_byte(const char *);
    5959
    6060/** Allocate memory for gpt label */
     
    179179
    180180        rc = block_init(EXCHANGE_ATOMIC, dev_handle, b_size);
    181         if (rc != EOK)
     181        if (rc != EOK && rc != EEXIST)
    182182                return rc;
    183183
     
    300300        size_t b_size;
    301301        uint32_t e_size = uint32_t_le2host(label->gpt->header->entry_size);
    302 
     302        size_t fill = label->parts->fill > GPT_MIN_PART_NUM ? label->parts->fill : GPT_MIN_PART_NUM;
     303       
    303304        label->gpt->header->pe_array_crc32 = compute_crc32(
    304305                                       (uint8_t *) label->parts->part_array,
    305                                        label->parts->fill * e_size);
     306                                       fill * e_size);
    306307       
    307308        /* comm_size of 4096 is ignored */
    308309        rc = block_init(EXCHANGE_ATOMIC, dev_handle, 4096);
    309         if (rc != EOK)
    310                 return rc;
    311 
     310        if (rc != EOK && rc != EEXIST)
     311                return rc;
     312       
    312313        rc = block_get_bsize(dev_handle, &b_size);
    313314        if (rc != EOK)
    314315                goto fail;
    315 
     316       
     317        aoff64_t n_blocks;
     318        rc = block_get_nblocks(dev_handle, &n_blocks);
     319        if (rc != EOK)
     320                goto fail;
     321       
     322        /* Write to backup GPT partition array location */
     323        //rc = block_write_direct(dev_handle, n_blocks - 1, GPT_HDR_BS, header->raw_data);
     324        if (rc != EOK)
     325                goto fail;
     326       
    316327        /* Write to main GPT partition array location */
    317328        rc = block_write_direct(dev_handle, uint64_t_le2host(label->gpt->header->entry_lba),
     
    320331        if (rc != EOK)
    321332                goto fail;
    322 
    323         aoff64_t n_blocks;
    324         rc = block_get_nblocks(dev_handle, &n_blocks);
    325         if (rc != EOK)
    326                 goto fail;
    327 
    328         /* Write to backup GPT partition array location */
    329         //rc = block_write_direct(dev_handle, n_blocks - 1, GPT_HDR_BS, header->raw_data);
    330         block_fini(dev_handle);
    331         if (rc != EOK)
    332                 goto fail;
    333 
    334 
     333       
    335334        return gpt_write_header(label, dev_handle);
    336335       
     
    347346 * This returns a memory block (zero-filled) and needs gpt_add_partition()
    348347 * to be called to insert it into a partition array.
    349  * Requires you to call gpt_free_partition after use.
     348 * Requires you to call gpt_free_partition afterwards.
    350349 */
    351350gpt_part_t * gpt_alloc_partition(void)
     
    367366 *
    368367 * Note: use either gpt_alloc_partition or gpt_get_partition.
    369  * This one return a pointer to a structure already inside the array, so
    370  * there's no need to call gpt_add_partition().
     368 * This one returns a pointer to the first empty structure already
     369 * inside the array, so don't call gpt_add_partition() afterwards.
    371370 * This is the one you will usually want.
    372371 */
    373372gpt_part_t * gpt_get_partition(gpt_label_t *label)
    374373{
    375         if (label->parts->fill == label->parts->arr_size) {
    376                 if (extend_part_array(label->parts) == -1)
    377                         return NULL;
    378         }
    379 
    380         return label->parts->part_array + label->parts->fill++;
     374        gpt_part_t *p;
     375       
     376        /* Find the first empty entry */
     377        do {
     378                if (label->parts->fill == label->parts->arr_size) {
     379                        if (extend_part_array(label->parts) == -1)
     380                                return NULL;
     381                }
     382               
     383                p = label->parts->part_array + label->parts->fill++;
     384               
     385        } while (gpt_get_part_type(p) != GPT_PTE_UNUSED);
     386       
     387        return p;
     388}
     389
     390/** Get partition already inside the label
     391 *
     392 * @param label   label to carrying the partition
     393 * @param idx     index of the partition
     394 *
     395 * @return        returns pointer to the partition
     396 *                or NULL when out of range
     397 *
     398 * Note: For new partitions use either gpt_alloc_partition or
     399 * gpt_get_partition unless you want a partition at a specific place.
     400 * This returns a pointer to a structure already inside the array,
     401 * so don't call gpt_add_partition() afterwards.
     402 * This function is handy when you want to change already existing
     403 * partition or to simply write somewhere in the middle. This works only
     404 * for indexes smaller than either 128 or the actual number of filled
     405 * entries.
     406 */
     407gpt_part_t * gpt_get_partition_at(gpt_label_t *label, size_t idx)
     408{
     409        return NULL;
     410       
     411        if (idx >= GPT_MIN_PART_NUM && idx >= label->parts->fill)
     412                return NULL;
     413       
     414        return label->parts->part_array + idx;
    381415}
    382416
     
    415449int gpt_remove_partition(gpt_label_t *label, size_t idx)
    416450{
    417         if (idx != label->parts->fill - 1) {
    418                 memmove(label->parts->part_array + idx,
    419                         label->parts->part_array + idx + 1,
    420                         (label->parts->fill - 1) * sizeof(gpt_entry_t));
    421                 label->parts->fill -= 1;
    422         }
    423        
    424         /* FIXME: This probably shouldn't be here, but instead
    425          * in reduce_part_array() or similar */
     451        if (idx >= label->parts->fill)
     452                return EINVAL;
     453       
     454        /* FIXME!
     455         * If we allow blank spots, we break the array. If we have more than
     456         * 128 partitions in the array and then remove something from
     457         * the first 128 partitions, we would forget to write the last one.*/
     458        memset(label->parts->part_array + idx, 0, sizeof(gpt_entry_t));
     459       
     460        label->parts->fill -= 1;
     461       
     462        /* FIXME!
     463         * We cannot reduce the array so simply. We may have some partitions
     464         * there since we allow blank spots.*/
    426465        if (label->parts->fill < (label->parts->arr_size / 2) - GPT_IGNORE_FILL_NUM) {
    427466                if (reduce_part_array(label->parts) == ENOMEM)
     
    448487{
    449488        size_t i;
     489       
    450490        for (i = 0; gpt_ptypes[i].guid != NULL; i++) {
    451                 if (bcmp(p->part_type, gpt_ptypes[i].guid, 16) == 0) {
    452                         break;
    453                 }
    454         }
     491                if (p->part_type[3] == get_byte(gpt_ptypes[i].guid +0) &&
     492                        p->part_type[2] == get_byte(gpt_ptypes[i].guid +2) &&
     493                        p->part_type[1] == get_byte(gpt_ptypes[i].guid +4) &&
     494                        p->part_type[0] == get_byte(gpt_ptypes[i].guid +6) &&
     495                       
     496                        p->part_type[5] == get_byte(gpt_ptypes[i].guid +8) &&
     497                        p->part_type[4] == get_byte(gpt_ptypes[i].guid +10) &&
     498                       
     499                        p->part_type[7] == get_byte(gpt_ptypes[i].guid +12) &&
     500                        p->part_type[6] == get_byte(gpt_ptypes[i].guid +14) &&
     501                       
     502                        p->part_type[8] == get_byte(gpt_ptypes[i].guid +16) &&
     503                        p->part_type[9] == get_byte(gpt_ptypes[i].guid +18) &&
     504                        p->part_type[10] == get_byte(gpt_ptypes[i].guid +20) &&
     505                        p->part_type[11] == get_byte(gpt_ptypes[i].guid +22) &&
     506                        p->part_type[12] == get_byte(gpt_ptypes[i].guid +24) &&
     507                        p->part_type[13] == get_byte(gpt_ptypes[i].guid +26) &&
     508                        p->part_type[14] == get_byte(gpt_ptypes[i].guid +28) &&
     509                        p->part_type[15] == get_byte(gpt_ptypes[i].guid +30))
     510                                break;
     511        }
     512       
    455513        return i;
    456514}
     
    516574
    517575/** Copy partition name */
    518 void gpt_set_part_name(gpt_part_t * p, char * name[], size_t length)
     576void gpt_set_part_name(gpt_part_t *p, char *name, size_t length)
    519577{
    520578        if (length >= 72)
     
    645703}
    646704
    647 
    648 
    649 
    650 
    651 
     705static uint8_t get_byte(const char * c)
     706{
     707        uint8_t val = 0;
     708        char hex[3] = {*c, *(c+1), 0};
     709       
     710        errno = str_uint8_t(hex, NULL, 16, false, &val);
     711        return val;
     712}
     713
     714
     715
     716
  • uspace/lib/gpt/libgpt.h

    r44c4886 r52f2c89  
    5252/** How much fill we ignore before resizing partition array */
    5353#define GPT_IGNORE_FILL_NUM 10
     54
     55/** Unused partition entry */
     56#define GPT_PTE_UNUSED 0
    5457
    5558/** GPT header signature ("EFI PART" in ASCII) */
     
    149152extern gpt_part_t *    gpt_alloc_partition (void);
    150153extern gpt_part_t *    gpt_get_partition   (gpt_label_t *);
     154extern gpt_part_t *    gpt_get_partition_at(gpt_label_t *, size_t);
    151155extern int             gpt_add_partition   (gpt_label_t *, gpt_part_t *);
    152156extern int             gpt_remove_partition(gpt_label_t *, size_t);
     
    159163extern uint64_t        gpt_get_end_lba  (gpt_part_t *);
    160164extern unsigned char * gpt_get_part_name(gpt_part_t *);
    161 extern void            gpt_set_part_name(gpt_part_t *, char *[], size_t);
     165extern void            gpt_set_part_name(gpt_part_t *, char *, size_t);
    162166extern bool            gpt_get_flag     (gpt_part_t *, GPT_ATTR);
    163167extern void            gpt_set_flag     (gpt_part_t *, GPT_ATTR, bool);
     
    165169
    166170
    167 #define gpt_part_foreach(parts, iterator) \
    168                 for(gpt_part_t * iterator = (parts)->part_array; \
    169                     iterator < (parts)->part_array + (parts)->fill; ++iterator)
     171#define gpt_part_foreach(label, iterator) \
     172                for(gpt_part_t * iterator = (label)->parts->part_array; \
     173                    iterator < (label)->parts->part_array + (label)->parts->fill; ++iterator)
    170174
    171175extern void gpt_free_gpt(gpt_t *);
  • uspace/lib/mbr/libmbr.c

    r44c4886 r52f2c89  
    5252static int check_encaps(mbr_part_t *, mbr_part_t *);
    5353static int check_preceeds(mbr_part_t *, mbr_part_t *);
     54static mbr_err_val mbr_add_primary(mbr_label_t *label, mbr_part_t *p);
     55static mbr_err_val mbr_add_logical(mbr_label_t *label, mbr_part_t *p);
    5456
    5557/** Allocate and initialize mbr_label_t structure */
     
    168170        mbr_part_t *ext = NULL;
    169171        //mbr_partitions_t *parts;
    170         printf("check\n");
     172       
    171173        if (label->parts != NULL)
    172174                mbr_free_partitions(label->parts);
    173         printf("check2\n");
     175       
    174176        label->parts = mbr_alloc_partitions();
    175177        if (label->parts == NULL) {
    176178                return ENOMEM;
    177179        }
    178         printf("primary\n");
     180       
    179181        /* Generate the primary partitions */
    180182        for (i = 0; i < N_PRIMARY; ++i) {
    181183                if (label->mbr->raw_data.pte[i].ptype == PT_UNUSED)
    182184                        continue;
    183                 printf("pcheck1\n");
     185               
    184186                p = mbr_alloc_partition();
    185187                if (p == NULL) {
     
    188190                        return ENOMEM;
    189191                }
    190                 printf("pcheck2\n");
     192               
    191193                rc_ext = decode_part(&(label->mbr->raw_data.pte[i]), p, 0);
    192194                mbr_set_flag(p, ST_LOGIC, false);
     
    198200                        return EINVAL;
    199201                }
    200                 printf("pcheck3\n");
     202               
    201203                if (rc_ext) {
    202204                        ext = p;
    203                         label->parts->l_extended = list_nth(&(label->parts->list), i);
    204                 }
    205                 printf("pcheck4\n");
    206         }
    207         printf("logical\n");
     205                        label->parts->l_extended = &p->link;
     206                }
     207        }
     208       
    208209        /* Fill in the primary partitions and generate logical ones, if any */
    209210        rc = decode_logical(label, ext);
    210211        if (rc != EOK) {
    211                 printf(LIBMBR_NAME ": Error occured during decoding the MBR.\n" \
    212                            LIBMBR_NAME ": Partition list may be incomplete.\n");
     212                printf(LIBMBR_NAME ": Error during decoding logical partitions: %d - %s.\n" \
     213                           LIBMBR_NAME ": Partition list may be incomplete.\n", rc, str_error(rc));
    213214                return rc;
    214215        }
    215         printf("finish\n");
     216       
    216217        return EOK;
    217218}
     
    225226int mbr_write_partitions(mbr_label_t *label, service_id_t dev_handle)
    226227{
     228        if (label->parts == NULL)
     229                return EOK;
     230       
     231        if (label->mbr == NULL)
     232                label->mbr = mbr_alloc_mbr();
     233       
    227234        int i = 0;
    228235        int rc;
     
    240247       
    241248        /* Encoding primary partitions */
    242         for (i = 0; i < label->parts->n_primary; i++) {
     249        for (i = 0; i < N_PRIMARY; i++) {
    243250                p = list_get_instance(l, mbr_part_t, link);     
    244251                encode_part(p, &(label->mbr->raw_data.pte[i]), 0, false);
     
    253260        }
    254261       
    255         if (ext == NULL)
     262        if (ext == NULL) {
     263                rc = EOK;
    256264                goto end;
     265        }
    257266       
    258267        uint32_t base = ext->start_addr;
    259         mbr_part_t * prev_p;
     268        mbr_part_t *prev_p;
    260269       
    261270        /* Note for future changes: Some thought has been put into design
     
    281290                }
    282291                free(tmp);
     292                rc = EOK;
    283293                goto end;
    284294        }
    285295       
    286296        prev_p = p;
     297       
     298        /* Check EBR addresses
     299         * This piece of code saves previous EBR placements from other
     300         * software. But if our user modifies the logical partition chain,
     301         * we have to fix those placements if needed.*/
     302        link_t *l_ebr = l;
     303        link_t *l_iter;
     304        mbr_part_t *tmp = mbr_alloc_partition();
     305        tmp->length = 1;
     306        while (l_ebr != &(label->parts->list.head)) {
     307                p = list_get_instance(l_ebr, mbr_part_t, link);
     308                tmp->start_addr = p->ebr_addr;
     309               
     310                l_iter = l;
     311                while (l_iter != &(label->parts->list.head)) {
     312                        /* Checking whether EBR address makes sense. If not, we take a guess.
     313                         * So far this is simple, we just take the first preceeding sector.
     314                         * Fdisk always reserves at least 2048 sectors (1MiB), so it can have
     315                         * the EBR aligned as well as the partition itself. Parted reserves
     316                         * minimum one sector, like we do.
     317                         *
     318                         * Note that we know there is at least one sector free from previous checks.
     319                         * Also note that the user can set ebr_addr to their liking (if it's valid). */         
     320                        if (p->ebr_addr < base || p->ebr_addr >= base + ext->length ||
     321                          check_overlap(tmp, list_get_instance(l_iter, mbr_part_t, link))) {
     322                                p->ebr_addr = p->start_addr - 1;
     323                                break;
     324                        }
     325                       
     326                        l_iter = l_iter->next;
     327                }
     328               
     329                l_ebr = l_ebr->next;
     330        }
     331        mbr_free_partition(tmp);
    287332       
    288333        /* Encoding and writing logical partitions */
     
    290335                p = list_get_instance(l, mbr_part_t, link);
    291336               
    292                 /* Checking whether EBR address makes sense. If not, we take a guess.
    293                  * So far this is simple, we just take the first preceeding sector.
    294                  * Fdisk always reserves at least 2048 sectors (1MiB), so it can have
    295                  * the EBR aligned as well as the partition itself. Parted reserves
    296                  * minimum one sector, like we do.
    297                  *
    298                  * Note that we know there is at least one sector free from previous checks.
    299                  * Also note that the user can set ebr_addr to their liking (if it's valid). */         
    300                 if (p->ebr_addr >= p->start_addr || p->ebr_addr <= (prev_p->start_addr + prev_p->length)) {
    301                         p->ebr_addr = p->start_addr - 1;
    302                         DEBUG_PRINT_0(LIBMBR_NAME ": Warning: invalid EBR address.\n");
    303                 }
    304337               
    305338                encode_part(p, &(p->ebr->pte[0]), p->ebr_addr, false);
     
    390423mbr_err_val mbr_add_partition(mbr_label_t *label, mbr_part_t *p)
    391424{
    392         int rc;
    393         mbr_partitions_t *parts = label->parts;
    394        
     425        int rc1, rc2;
    395426        aoff64_t nblocks;
    396         printf("add1.\n");
    397         rc = block_init(EXCHANGE_ATOMIC, label->device, 512);
    398         if (rc != EOK) {
    399                 printf(LIBMBR_NAME ": Error while getting number of blocks: %d - %s.\n", rc, str_error(rc));
     427       
     428        rc1 = block_init(EXCHANGE_ATOMIC, label->device, 512);
     429        if (rc1 != EOK && rc1 != EEXIST) {
     430                printf(LIBMBR_NAME ": Error during libblock init: %d - %s.\n", rc1, str_error(rc1));
    400431                return ERR_LIBBLOCK;
    401432        }
    402         printf("add2.\n");
    403         rc = block_get_nblocks(label->device, &nblocks);
    404         block_fini(label->device);
    405         if (rc != EOK) {
    406                 printf(LIBMBR_NAME ": Error while getting number of blocks: %d - %s.\n", rc, str_error(rc));
     433       
     434        rc2 = block_get_nblocks(label->device, &nblocks);
     435       
     436        if (rc1 != EEXIST)
     437                block_fini(label->device);
     438       
     439        if (rc2 != EOK) {
     440                printf(LIBMBR_NAME ": Error while getting number of blocks: %d - %s.\n", rc2, str_error(rc2));
    407441                return ERR_LIBBLOCK;
    408442        }
    409         printf("add3.\n");
    410         if (mbr_get_flag(p, ST_LOGIC)) {
     443       
     444        if ((aoff64_t) p->start_addr + p->length > nblocks)
     445                return ERR_OUT_BOUNDS;
     446       
     447        if (label->parts == NULL) {
     448                label->parts = mbr_alloc_partitions();
     449                if (label->parts == NULL)
     450                        return ENOMEM; //FIXME! merge mbr_err_val into errno.h
     451        }
     452       
     453        if (mbr_get_flag(p, ST_LOGIC))
    411454                /* adding logical partition */
    412                
    413                 /* is there any extended partition? */
    414                 if (parts->l_extended == NULL)
    415                         return ERR_NO_EXTENDED;
    416                
    417                 /* is the logical partition inside the extended one? */
    418                 mbr_part_t *ext = list_get_instance(parts->l_extended, mbr_part_t, link);
    419                 if (!check_encaps(p, ext))
    420                         return ERR_OUT_BOUNDS;
    421                
    422                 /* find a place for the new partition in a sorted linked list */
    423                 //mbr_part_t *last = list_get_instance(list_last(&(parts->list)), mbr_part_t, link);
    424                 mbr_part_t *iter;
    425                 //uint32_t ebr_space = 1;
    426                 mbr_part_foreach(parts, iter) {
    427                         if (mbr_get_flag(iter, ST_LOGIC)) {
    428                                 if (check_overlap(p, iter))
    429                                         return ERR_OVERLAP;
    430                                 if (check_preceeds(iter, p)) {
    431                                         /* checking if there's at least one sector of space preceeding */
    432                                         if ((iter->start_addr + iter->length) >= p->start_addr - 1)
    433                                                 return ERR_NO_EBR;
    434                                 } else {
    435                                         /* checking if there's at least one sector of space following (for following partitions's EBR) */
    436                                         if ((p->start_addr + p->length) >= iter->start_addr - 1)
    437                                                 return ERR_NO_EBR;
    438                                 }
    439                         }
    440                 }
    441                
    442                 /* alloc EBR if it's not already there */
    443                 if (p->ebr == NULL) {
    444                         p->ebr = alloc_br();
    445                         if (p->ebr == NULL) {
    446                                 return ERR_NOMEM;
    447                         }
    448                 }
    449                
    450                 /* add it */
    451                 list_append(&(p->link), &(parts->list));
    452                 parts->n_logical += 1;
    453         } else {
     455                return mbr_add_logical(label, p);
     456        else
    454457                /* adding primary */
    455                
    456                 if (parts->n_primary == 4) {
    457                         return ERR_PRIMARY_FULL;
    458                 }
    459                
    460                 /* Check if partition makes space for MBR itself. */
    461                 if (p->start_addr == 0 || ((aoff64_t) p->start_addr) + p->length >= nblocks) {
    462                         return ERR_OUT_BOUNDS;
    463                 }
    464                 printf("add4.\n");
    465                 /* if it's extended, is there any other one? */
    466                 if ((p->type == PT_EXTENDED || p->type == PT_EXTENDED_LBA) && parts->l_extended != NULL) {
    467                         return ERR_EXTENDED_PRESENT;
    468                 }
    469                 printf("add5.\n");
    470                 /* find a place and add it */
    471                 mbr_part_t *iter;
    472                 mbr_part_t *empty = NULL;
    473                 mbr_part_foreach(parts, iter) {
    474                         printf("type: %x\n", iter->type);
    475                         if (iter->type == PT_UNUSED) {
    476                                 if (empty == NULL)
    477                                         empty = iter;
    478                         } else if (check_overlap(p, iter))
    479                                 return ERR_OVERLAP;
    480                 }
    481                 printf("add6. %p, %p\n", empty, p);
    482                 list_insert_after(&(p->link), &(empty->link));
    483                 printf("add6.1.\n");
    484                 list_remove(&(empty->link));
    485                 printf("add6.2.\n");
    486                 free(empty);
    487                 printf("add7.\n");
    488                 parts->n_primary += 1;
    489                
    490                 if (p->type == PT_EXTENDED || p->type == PT_EXTENDED_LBA)
    491                         parts->l_extended = &(p->link);
    492         }
    493         printf("add8.\n");
    494         return ERR_OK;
     458                return mbr_add_primary(label, p);
    495459}
    496460
     
    569533void mbr_set_flag(mbr_part_t *p, MBR_FLAGS flag, bool value)
    570534{
    571         uint8_t status = p->status;
     535        uint16_t status = p->status;
    572536
    573537        if (value)
     
    579543}
    580544
    581 /** Get next aligned address (in sectors!) */
     545/** Get next aligned address */
    582546uint32_t mbr_get_next_aligned(uint32_t addr, unsigned int alignment)
    583547{
    584548        uint32_t div = addr / alignment;
    585549        return (div + 1) * alignment;
     550}
     551
     552list_t * mbr_get_list(mbr_label_t *label)
     553{
     554        if (label->parts != NULL)
     555                return &(label->parts->list);
     556        else
     557                return NULL;
     558}
     559
     560mbr_part_t * mbr_get_first_partition(mbr_label_t *label)
     561{
     562        list_t *list = mbr_get_list(label);
     563        if (list != NULL && !list_empty(list))
     564                return list_get_instance(list->head.next, mbr_part_t, link);
     565        else
     566                return NULL;
     567}
     568
     569mbr_part_t * mbr_get_next_partition(mbr_label_t *label, mbr_part_t *p)
     570{
     571        list_t *list = mbr_get_list(label);
     572        if (list != NULL && &(p->link) != list_last(list))
     573                return list_get_instance(p->link.next, mbr_part_t, link);
     574        else
     575                return NULL;
    586576}
    587577
     
    627617        trgt->type = src->ptype;
    628618
    629         /* Checking only 0x80; otherwise writing will fix to 0x00 */
    630         trgt->status = (trgt->status & 0xFF00) | src->status;
     619        trgt->status = (trgt->status & 0xFF00) | (uint16_t) src->status;
    631620
    632621        trgt->start_addr = uint32_t_le2host(src->first_lba) + base;
     
    691680       
    692681        while (ebr->pte[1].ptype != PT_UNUSED) {
     682               
    693683                ebr = alloc_br();
    694684                if (ebr == NULL) {
     
    712702                        goto free_ebr_end;
    713703                }
    714                
    715704               
    716705                decode_part(&(ebr->pte[0]), p, addr);
     
    759748                        trgt->length = host2uint32_t_le(src->length);
    760749                }
     750               
     751                if (trgt->ptype == PT_UNUSED)
     752                        memset(trgt, 0, sizeof(pt_entry_t));
    761753        } else {
    762                 trgt->status = 0;
    763                 trgt->first_chs[0] = 0;
    764                 trgt->first_chs[1] = 0;
    765                 trgt->first_chs[2] = 0;
    766                 trgt->ptype = 0;
    767                 trgt->last_chs[0] = 0;
    768                 trgt->last_chs[1] = 0;
    769                 trgt->last_chs[2] = 0;
    770                 trgt->first_lba = 0;
    771                 trgt->length = 0;
     754                memset(trgt, 0, sizeof(pt_entry_t));
    772755        }
    773756}
     
    779762static int check_overlap(mbr_part_t * p1, mbr_part_t * p2)
    780763{
    781         if (p1->start_addr < p2->start_addr && p1->start_addr + p1->length < p2->start_addr) {
     764        if (p1->start_addr < p2->start_addr && p1->start_addr + p1->length <= p2->start_addr) {
    782765                return 0;
    783         } else if (p1->start_addr > p2->start_addr && p2->start_addr + p2->length < p1->start_addr) {
     766        } else if (p1->start_addr > p2->start_addr && p2->start_addr + p2->length <= p1->start_addr) {
    784767                return 0;
    785768        }
     
    812795}
    813796
    814 
    815 
    816 
     797mbr_err_val mbr_add_primary(mbr_label_t *label, mbr_part_t *p)
     798{
     799        if (label->parts->n_primary == 4) {
     800                return ERR_PRIMARY_FULL;
     801        }
     802       
     803        /* Check if partition makes space for MBR itself. */
     804        if (p->start_addr == 0) {
     805                return ERR_OUT_BOUNDS;
     806        }
     807       
     808        /* if it's extended, is there any other one? */
     809        if ((p->type == PT_EXTENDED || p->type == PT_EXTENDED_LBA) && label->parts->l_extended != NULL) {
     810                return ERR_EXTENDED_PRESENT;
     811        }
     812       
     813        /* find a place and add it */
     814        mbr_part_t *iter;
     815        mbr_part_t *empty = NULL;
     816        mbr_part_foreach(label, iter) {
     817                if (iter->type == PT_UNUSED) {
     818                        if (empty == NULL)
     819                                empty = iter;
     820                } else if (check_overlap(p, iter))
     821                        return ERR_OVERLAP;
     822        }
     823       
     824        list_insert_after(&(p->link), &(empty->link));
     825        list_remove(&(empty->link));
     826        free(empty);
     827       
     828        label->parts->n_primary += 1;
     829       
     830        if (p->type == PT_EXTENDED || p->type == PT_EXTENDED_LBA)
     831                label->parts->l_extended = &(p->link);
     832       
     833        return EOK;
     834}
     835
     836mbr_err_val mbr_add_logical(mbr_label_t *label, mbr_part_t *p)
     837{
     838        /* is there any extended partition? */
     839        if (label->parts->l_extended == NULL)
     840                return ERR_NO_EXTENDED;
     841       
     842        /* is the logical partition inside the extended one? */
     843        mbr_part_t *ext = list_get_instance(label->parts->l_extended, mbr_part_t, link);
     844        if (!check_encaps(p, ext))
     845                return ERR_OUT_BOUNDS;
     846       
     847        /* find a place for the new partition in a sorted linked list */
     848        bool first_logical = true;
     849        mbr_part_t *iter;
     850        mbr_part_foreach(label, iter) {
     851                if (mbr_get_flag(iter, ST_LOGIC)) {
     852                        if (check_overlap(p, iter))
     853                                return ERR_OVERLAP;
     854                        if (check_preceeds(iter, p)) {
     855                                /* checking if there's at least one sector of space preceeding */
     856                                if ((iter->start_addr + iter->length) >= p->start_addr - 1)
     857                                        return ERR_NO_EBR;
     858                        } else if (first_logical){
     859                                /* First logical partition's EBR is before every other
     860                                 * logical partition. Thus we don't check if this partition
     861                                 * leaves enough space for it. */
     862                                first_logical = false;
     863                        } else {
     864                                /* checking if there's at least one sector of space following (for following partitions's EBR) */
     865                                if ((p->start_addr + p->length) >= iter->start_addr - 1)
     866                                        return ERR_NO_EBR;
     867                        }
     868                }
     869        }
     870       
     871        /* alloc EBR if it's not already there */
     872        if (p->ebr == NULL) {
     873                p->ebr = alloc_br();
     874                if (p->ebr == NULL) {
     875                        return ERR_NOMEM;
     876                }
     877        }
     878       
     879        /* add it */
     880        list_append(&(p->link), &(label->parts->list));
     881        label->parts->n_logical += 1;
     882       
     883        return EOK;
     884}
     885
     886
     887
  • uspace/lib/mbr/libmbr.h

    r44c4886 r52f2c89  
    213213extern void         mbr_set_flag(mbr_part_t *, MBR_FLAGS, bool);
    214214extern uint32_t     mbr_get_next_aligned(uint32_t, unsigned int);
    215 
    216 #define mbr_part_foreach(parts, iterator)       \
    217         for (iterator  = list_get_instance((parts)->list.head.next, mbr_part_t, link); \
    218              iterator != list_get_instance(&((parts)->list.head), mbr_part_t, link); \
     215extern list_t *     mbr_get_list(mbr_label_t *);
     216extern mbr_part_t * mbr_get_first_partition(mbr_label_t *);
     217extern mbr_part_t * mbr_get_next_partition(mbr_label_t *, mbr_part_t *);
     218
     219#define mbr_part_foreach(label, iterator) \
     220        for (iterator  = list_get_instance((label)->parts->list.head.next, mbr_part_t, link); \
     221             iterator != list_get_instance(&((label)->parts->list.head), mbr_part_t, link); \
    219222             iterator  = list_get_instance(iterator->link.next, mbr_part_t, link))
    220223
Note: See TracChangeset for help on using the changeset viewer.