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

Changeset a2aa81cb in mainline


Ignore:
Timestamp:
2013-05-30T11:52:31Z (7 years ago)
Author:
Dominik Taborsky (AT DOT) <brembyseznamcz>
Branches:
master
Children:
44c4886, 469739f
Parents:
622a50b
Message:

API changes, bug fixing

Location:
uspace
Files:
12 edited

Legend:

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

    r622a50b ra2aa81cb  
    3939#include <libgpt.h>
    4040
    41 union table_data {
    42         mbr_table_t     mbr;
    43         gpt_table_t     gpt;
     41union label_data {
     42        mbr_label_t     *mbr;
     43        gpt_label_t     *gpt;
    4444};
    4545
  • uspace/app/hdisk/func_gpt.c

    r622a50b ra2aa81cb  
    4343static int set_gpt_partition(tinput_t *, gpt_part_t *);
    4444
    45 int add_gpt_part(tinput_t * in, union table_data * data)
     45int add_gpt_part(tinput_t * in, union label_data * data)
    4646{
    47         gpt_part_t * p = gpt_alloc_partition(data->gpt.parts);
     47        gpt_part_t * p = gpt_alloc_partition(data->gpt->parts);
    4848        if (p == NULL) {
    4949                return ENOMEM;
     
    5353}
    5454
    55 int delete_gpt_part(tinput_t * in, union table_data * data)
     55int delete_gpt_part(tinput_t * in, union label_data * data)
    5656{
    5757        size_t idx;
     
    6060        idx = get_input_size_t(in);
    6161
    62         if (gpt_remove_partition(data->gpt.parts, idx) == -1) {
     62        if (gpt_remove_partition(data->gpt->parts, idx) == -1) {
    6363                printf("Warning: running low on memory, not resizing...\n");
    6464        }
     
    6767}
    6868
    69 int new_gpt_table(tinput_t * in, union table_data * data)
     69int destroy_gpt_label(union label_data *data)
    7070{
    71         data->gpt.gpt = gpt_alloc_gpt_header();
    72         data->gpt.parts = gpt_alloc_partitions();
    7371        return EOK;
    7472}
    7573
    76 int print_gpt_parts(union table_data * data)
     74int 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
     81int print_gpt_parts(union label_data *data)
    7782{
    7883        //int rc;
     
    8287        size_t i = 0;
    8388       
    84         gpt_part_foreach(data->gpt.parts, iter) {
     89        gpt_part_foreach(data->gpt->parts, iter) {
    8590                //printf("\t%10u %10u %10u %3d\n", iter->start_addr, iter->start_addr + iter->length,
    8691                //              iter->length, gpt_get_part_type(iter), gpt_get_part_name(iter));
     
    95100}
    96101
    97 int write_gpt_parts(service_id_t dev_handle, union table_data * data)
     102int read_gpt_parts(service_id_t dev_handle, union label_data *data)
     103{
     104        return EOK;
     105}
     106
     107int write_gpt_parts(service_id_t dev_handle, union label_data * data)
    98108{
    99109        int rc;
    100110
    101         rc = gpt_write_partitions(data->gpt.parts, data->gpt.gpt, dev_handle);
     111        rc = gpt_write_partitions(data->gpt->parts, data->gpt->gpt, dev_handle);
    102112        if (rc != EOK) {
    103113                printf("Error: Writing partitions failed: %d (%s)\n", rc, str_error(rc));
     
    105115        }
    106116
    107         rc = gpt_write_gpt_header(data->gpt.gpt, dev_handle);
     117        rc = gpt_write_gpt_header(data->gpt->gpt, dev_handle);
    108118        if (rc != EOK) {
    109119                printf("Error: Writing partitions failed: %d (%s)\n", rc, str_error(rc));
     
    114124}
    115125
    116 int extra_gpt_funcs(tinput_t * in, service_id_t dev_handle, union table_data * data)
     126int extra_gpt_funcs(tinput_t * in, service_id_t dev_handle, union label_data * data)
    117127{
    118128        printf("Not implemented.\n");
  • uspace/app/hdisk/func_gpt.h

    r622a50b ra2aa81cb  
    4242#include "common.h"
    4343
    44 extern int add_gpt_part(tinput_t * in, union table_data * data);
    45 extern int delete_gpt_part(tinput_t * in, union table_data * data);
    46 extern int new_gpt_table(tinput_t *, union table_data *);
    47 extern int print_gpt_parts(union table_data * data);
    48 extern int write_gpt_parts(service_id_t dev_handle, union table_data * data);
    49 extern int extra_gpt_funcs(tinput_t * in, service_id_t dev_handle, union table_data * data);
     44extern int add_gpt_part(tinput_t *, union label_data *);
     45extern int delete_gpt_part(tinput_t *, union label_data *);
     46extern int destroy_gpt_label(union label_data *);
     47extern int new_gpt_label(union label_data *);
     48extern int print_gpt_parts(union label_data *);
     49extern int read_gpt_parts(service_id_t, union label_data *);
     50extern int write_gpt_parts(service_id_t, union label_data *);
     51extern int extra_gpt_funcs(tinput_t *, service_id_t, union label_data *);
    5052
    5153#endif
  • uspace/app/hdisk/func_mbr.c

    r622a50b ra2aa81cb  
    4141#include "input.h"
    4242
    43 static int set_mbr_partition(tinput_t * in, mbr_part_t * p);
    44 
    45 
    46 int add_mbr_part(tinput_t * in, union table_data * data)
     43static int set_mbr_partition(tinput_t *in, mbr_part_t *p);
     44
     45int add_mbr_part(tinput_t *in, union label_data *data)
    4746{
    4847        int rc;
    4948       
    50         mbr_part_t * part = mbr_alloc_partition();
     49        mbr_part_t *part = mbr_alloc_partition();
    5150
    5251        set_mbr_partition(in, part);
    5352
    54         rc = mbr_add_partition(data->mbr.parts, part);
     53        rc = mbr_add_partition(data->mbr, part);
    5554        if (rc != EOK) {
    5655                printf("Error adding partition.\n");
    5756        }
    5857       
    59        
    60         return rc;
    61 }
    62 
    63 int delete_mbr_part(tinput_t * in, union table_data * data)
     58        return EOK;
     59}
     60
     61int delete_mbr_part(tinput_t *in, union label_data *data)
    6462{
    6563        int rc;
     
    7270                return errno;
    7371       
    74         rc = mbr_remove_partition(data->mbr.parts, idx);
     72        rc = mbr_remove_partition(data->mbr, idx);
    7573        if(rc != EOK) {
    7674                printf("Error: something.\n");
     
    8078}
    8179
    82 int new_mbr_table(tinput_t * in, union table_data * data)
    83 {
    84         data->mbr.mbr = mbr_alloc_mbr();
    85         data->mbr.parts = mbr_alloc_partitions();
    86         return EOK;
     80int destroy_mbr_label(union label_data *data)
     81{
     82        mbr_free_label(data->mbr);
     83        return EOK;
     84}
     85
     86int new_mbr_label(union label_data *data)
     87{
     88        data->mbr = mbr_alloc_label();
     89        if (data->mbr == NULL)
     90                return ENOMEM;
     91        else
     92                return EOK;
    8793}
    8894
    8995/** Print current partition scheme */
    90 int print_mbr_parts(union table_data * data)
     96int print_mbr_parts(union label_data *data)
    9197{
    9298        int num = 0;
     
    96102        printf("\t\t%10s  %10s %10s %10s %7s\n", "Bootable:", "Start:", "End:", "Length:", "Type:");
    97103       
    98         mbr_part_t * it;
    99         mbr_part_foreach(data->mbr.parts, it) {
     104        mbr_part_t *it;
     105        mbr_part_foreach(data->mbr->parts, it) {
    100106                if (it->type == PT_UNUSED)
    101107                        continue;
     
    117123}
    118124
    119 int write_mbr_parts(service_id_t dev_handle, union table_data * data)
    120 {
    121         int rc = mbr_write_partitions(data->mbr.parts, data->mbr.mbr, dev_handle);
     125int read_mbr_parts(service_id_t dev_handle, union label_data *data)
     126{
     127        int rc;
     128        printf("mbr\n");
     129        rc = mbr_read_mbr(data->mbr, dev_handle);
     130        if (rc != EOK)
     131                return rc;
     132        printf("ismbr\n");
     133        if (!mbr_is_mbr(data->mbr))
     134                return EINVAL;
     135        printf("parts\n");
     136        rc = mbr_read_partitions(data->mbr);
     137        if (rc != EOK)
     138                return rc;
     139        printf("end\n");
     140        return EOK;
     141}
     142
     143int write_mbr_parts(service_id_t dev_handle, union label_data *data)
     144{
     145        int rc = mbr_write_partitions(data->mbr, dev_handle);
    122146        if (rc != EOK) {
    123147                printf("Error occured during writing: ERR: %d: %s\n", rc, str_error(rc));
     
    127151}
    128152
    129 int extra_mbr_funcs(tinput_t * in, service_id_t dev_handle, union table_data * data)
     153int extra_mbr_funcs(tinput_t *in, service_id_t dev_handle, union label_data *data)
    130154{
    131155        printf("Not implemented.\n");
     
    133157}
    134158
    135 static int set_mbr_partition(tinput_t * in, mbr_part_t * p)
     159static int set_mbr_partition(tinput_t *in, mbr_part_t *p)
    136160{
    137161        int c;
     
    159183                return errno;
    160184
    161         ///TODO: there can only be one bootable partition; let's do it just like fdisk
     185        ///TODO: there can only be one boolabel partition; let's do it just like fdisk
    162186        printf("Bootable? (y/n): ");
    163187        c = getchar();
  • uspace/app/hdisk/func_mbr.h

    r622a50b ra2aa81cb  
    4242#include "common.h"
    4343
    44 extern int add_mbr_part(tinput_t * in, union table_data * data);
    45 extern int delete_mbr_part(tinput_t * in, union table_data * data);
    46 extern int new_mbr_table(tinput_t *, union table_data *);
    47 extern int print_mbr_parts(union table_data * data);
    48 extern int write_mbr_parts(service_id_t dev_handle, union table_data * data);
    49 extern int extra_mbr_funcs(tinput_t * in, service_id_t dev_handle, union table_data * data);
     44extern int add_mbr_part(tinput_t *, union label_data *);
     45extern int delete_mbr_part(tinput_t *, union label_data *);
     46extern int destroy_mbr_label(union label_data *);
     47extern int new_mbr_label(union label_data *);
     48extern int print_mbr_parts(union label_data *);
     49extern int read_mbr_parts(service_id_t, union label_data *);
     50extern int write_mbr_parts(service_id_t, union label_data *);
     51extern int extra_mbr_funcs(tinput_t *, service_id_t, union label_data *);
    5052
    5153#endif
  • uspace/app/hdisk/func_none.c

    r622a50b ra2aa81cb  
    4040static void not_implemented(void);
    4141
    42 int add_none_part(tinput_t * in, union table_data * data)
     42
     43int add_none_part(tinput_t *in, union label_data *data)
    4344{
    4445        not_implemented();
     
    4647}
    4748
    48 int delete_none_part(tinput_t * in, union table_data * data)
     49int delete_none_part(tinput_t *in, union label_data *data)
    4950{
    5051        not_implemented();
     
    5253}
    5354
    54 int new_none_table(tinput_t * in, union table_data * data)
     55int destroy_none_label(union label_data *data)
    5556{
    5657        not_implemented();
     
    5859}
    5960
    60 int print_none_parts(union table_data * data)
     61int new_none_label(union label_data *data)
    6162{
    6263        not_implemented();
     
    6465}
    6566
    66 int write_none_parts(service_id_t dev_handle, union table_data * data)
     67int print_none_parts(union label_data *data)
    6768{
    6869        not_implemented();
     
    7071}
    7172
    72 int extra_none_funcs(tinput_t * in, service_id_t dev_handle, union table_data * data)
     73int read_none_parts(service_id_t dev_handle, union label_data *data)
     74{
     75        not_implemented();
     76        return EOK;
     77}
     78
     79int write_none_parts(service_id_t dev_handle, union label_data *data)
     80{
     81        not_implemented();
     82        return EOK;
     83}
     84
     85int extra_none_funcs(tinput_t *in, service_id_t dev_handle, union label_data *data)
    7386{
    7487        not_implemented();
  • uspace/app/hdisk/func_none.h

    r622a50b ra2aa81cb  
    4141#include "common.h"
    4242
    43 extern int add_none_part(tinput_t * in, union table_data * data);
    44 extern int delete_none_part(tinput_t * in, union table_data * data);
    45 extern int new_none_table(tinput_t *, union table_data *);
    46 extern int print_none_parts(union table_data * data);
    47 extern int write_none_parts(service_id_t dev_handle, union table_data * data);
    48 extern int extra_none_funcs(tinput_t * in, service_id_t dev_handle, union table_data * data);
     43extern int add_none_part(tinput_t *, union label_data *);
     44extern int delete_none_part(tinput_t *, union label_data *);
     45extern int destroy_none_label(union label_data *);
     46extern int new_none_label(union label_data *);
     47extern int print_none_parts(union label_data *);
     48extern int read_none_parts(service_id_t, union label_data *);
     49extern int write_none_parts(service_id_t, union label_data *);
     50extern int extra_none_funcs(tinput_t *, service_id_t, union label_data *);
    4951
    5052#endif
  • uspace/app/hdisk/hdisk.c

    r622a50b ra2aa81cb  
    5353#include "func_none.h"
    5454
    55 int interact(service_id_t dev_handle);
     55int interact(service_id_t);
    5656void print_help(void);
    57 void select_table_format(tinput_t * in);
    58 void fill_table_funcs(void);
    59 void free_table(void);
    60 
    61 static table_t table;
     57void select_label_format(tinput_t *);
     58void fill_label_funcs(void);
     59void free_label(void);
     60int try_read(service_id_t);
     61
     62int construct_none_label(void);
     63
     64int construct_mbr_label(void);
     65int try_read_mbr(service_id_t);
     66
     67int construct_gpt_label(void);
     68int try_read_gpt(service_id_t);
     69
     70
     71static label_t label;
    6272
    6373int main(int argc, char ** argv)
    6474{
    6575        if (argc == 1) {
    66                 printf("I'd like to have an argument, please.\n");
    67                 return 1;
    68         }
    69 
     76                printf("Missing argument. Please specify a device to operate on.\n");
     77                return -1;
     78        }
     79       
    7080        int rc;
    7181        service_id_t dev_handle;
    72 
     82       
    7383        rc = loc_service_get_id(argv[1], &dev_handle, IPC_FLAG_BLOCKING);
    7484        if (rc != EOK) {
     
    7686                return -1;
    7787        }
    78 
    79         init_table();
    80 
     88       
     89        printf("Init.\n");
     90        init_label();
     91       
     92        /*
    8193        mbr_t * mbr = mbr_read_mbr(dev_handle);
    8294        if(mbr == NULL) {
     
    8799
    88100        if(mbr_is_mbr(mbr)) {
    89                 table.layout = LYT_MBR;
    90                 set_table_mbr(mbr);
     101                label.layout = LYT_MBR;
     102                set_label_mbr(mbr);
    91103                mbr_partitions_t * parts = mbr_read_partitions(mbr);
    92104                if(parts == NULL) {
     
    95107                        parts = mbr_alloc_partitions();
    96108                }
    97                 set_table_mbr_parts(parts);
    98                 fill_table_funcs();
     109                set_label_mbr_parts(parts);
     110                fill_label_funcs();
    99111                goto interact;
    100112        }
    101113       
    102114       
    103         mbr_free_mbr(mbr);
     115        mbr_free_mbr(mbr);*/
     116       
     117        printf("Try MBR.\n");
     118        rc = try_read_mbr(dev_handle);
     119        if (rc == EOK)
     120                goto interact;
     121       
     122        /*
    104123        gpt_t * gpt = gpt_read_gpt_header(dev_handle);
    105124       
    106125        if(gpt != NULL) {
    107                 table.layout = LYT_GPT;
    108                 set_table_gpt(gpt);
     126                label.layout = LYT_GPT;
     127                set_label_gpt(gpt);
    109128               
    110129                gpt_partitions_t * parts = gpt_read_partitions(gpt);
     
    115134                        parts = gpt_alloc_partitions();
    116135                }
    117                 set_table_gpt_parts(parts);
    118                 fill_table_funcs();
     136                set_label_gpt_parts(parts);
     137                fill_label_funcs();
    119138                goto interact;
    120139        }
    121         printf("No partition table recognized. Create a new one.\n");
    122         table.layout = LYT_NONE;
     140        */
     141       
     142        printf("Try GPT.\n");
     143        rc = try_read_gpt(dev_handle);
     144        if (rc == EOK)
     145                goto interact;
     146       
     147        printf("No label recognized. Create a new one.\n");
     148        label.layout = LYT_NONE;
    123149       
    124150interact:
     151        printf("interact.\n");
    125152        rc = interact(dev_handle);
    126153       
    127         free_table();
     154        free_label();
    128155       
    129156        return rc;
     
    152179                switch(input) {
    153180                        case 'a':
    154                                 table.add_part(in, &table.data);
     181                                label.add_part(in, &label.data);
     182                                break;
     183                        case 'b':
     184                                label.add_part(in, &label.data);
    155185                                break;
    156186                        case 'd':
    157                                 table.delete_part(in, &table.data);
     187                                label.delete_part(in, &label.data);
    158188                                break;
    159189                        case 'e':
    160                                 table.extra_funcs(in, dev_handle, &table.data);
     190                                label.extra_funcs(in, dev_handle, &label.data);
    161191                                break;
    162192                        case 'f':
    163                                 free_table();
    164                                 select_table_format(in);
     193                                free_label();
     194                                select_label_format(in);
    165195                                break;
    166196                        case 'h':
     
    168198                                break;
    169199                        case 'n':
    170                                 free_table();
    171                                 table.new_table(in, &table.data);
     200                                free_label();
     201                                label.new_label(&label.data);
    172202                                break;
    173203                        case 'p':
    174                                 table.print_parts(&table.data);
     204                                label.print_parts(&label.data);
    175205                                break;
    176206                        case 'q':
     
    178208                                goto end;
    179209                        case 'w':
    180                                 table.write_parts(dev_handle, &table.data);
     210                                label.write_parts(dev_handle, &label.data);
    181211                                break;
    182212                        default:
     
    197227                "\t 'a' \t\t Add partition.\n"
    198228                "\t 'd' \t\t Delete partition.\n"
    199                 "\t 'e' \t\t Extra functions (per table format).\n"
    200                 "\t 'f' \t\t Switch the format of the partition table."
     229                "\t 'e' \t\t Extra functions (per label format).\n"
     230                "\t 'f' \t\t Switch the format of the partition label."
    201231                "\t 'h' \t\t Prints help. See help for more.\n"
    202                 "\t 'n' \t\t Create new table (discarding the old one).\n"
    203                 "\t 'p' \t\t Prints the table contents.\n"
    204                 "\t 'w' \t\t Write table to disk.\n"
     232                "\t 'l' \t\t Set alignment.\n"
     233                "\t 'n' \t\t Create new label (discarding the old one).\n"
     234                "\t 'p' \t\t Prints label contents.\n"
     235                "\t 'w' \t\t Write label to disk.\n"
    205236                "\t 'q' \t\t Quit.\n"
    206237                );
     
    208239}
    209240
    210 void select_table_format(tinput_t * in)
     241void select_label_format(tinput_t * in)
    211242{
    212243        printf("Available formats are: \n"
     
    218249        switch(val) {
    219250                case 0:
    220                         table.layout = LYT_NONE;
    221                         fill_table_funcs();
     251                        free_label();
     252                        label.layout = LYT_NONE;
     253                        fill_label_funcs();
    222254                        break;
    223255                case 1:
    224                         table.layout = LYT_MBR;
    225                         fill_table_funcs();
     256                        free_label();
     257                        label.layout = LYT_MBR;
     258                        fill_label_funcs();
    226259                        break;
    227260                case 2:
    228                         table.layout = LYT_GPT;
    229                         fill_table_funcs();
    230                         break;
    231         }
    232 }
    233 
    234 void fill_table_funcs(void)
    235 {
    236         switch(table.layout) {
     261                        free_label();
     262                        label.layout = LYT_GPT;
     263                        fill_label_funcs();
     264                        break;
     265        }
     266}
     267
     268void fill_label_funcs(void)
     269{
     270        switch(label.layout) {
    237271                case LYT_MBR:
    238                         table.add_part = add_mbr_part;
    239                         table.delete_part = delete_mbr_part;
    240                         table.new_table = new_mbr_table;
    241                         table.print_parts = print_mbr_parts;
    242                         table.write_parts = write_mbr_parts;
    243                         table.extra_funcs = extra_mbr_funcs;
     272                        construct_mbr_label();
    244273                        break;
    245274                case LYT_GPT:
    246                         table.add_part = add_gpt_part;
    247                         table.delete_part = delete_gpt_part;
    248                         table.new_table = new_gpt_table;
    249                         table.print_parts = print_gpt_parts;
    250                         table.write_parts = write_gpt_parts;
    251                         table.extra_funcs = extra_gpt_funcs;
     275                        construct_gpt_label();
    252276                        break;
    253277                default:
    254                         table.add_part = add_none_part;
    255                         table.delete_part = delete_none_part;
    256                         table.new_table = new_none_table;
    257                         table.print_parts = print_none_parts;
    258                         table.write_parts = write_none_parts;
    259                         table.extra_funcs = extra_none_funcs;
    260                         break;
    261         }
    262 }
    263 
    264 void free_table(void)
    265 {
    266         switch(table.layout) {
     278                        construct_none_label();
     279                        break;
     280        }
     281}
     282
     283void free_label(void)
     284{
     285        /*
     286        switch(label.layout) {
    267287                case LYT_MBR:
    268                         if (table.data.mbr.parts != NULL) {
    269                                 mbr_free_partitions(table.data.mbr.parts);
    270                                 table.data.mbr.parts = NULL;
    271                         }
    272                         if (table.data.mbr.mbr != NULL) {
    273                                 mbr_free_mbr(table.data.mbr.mbr);
    274                                 table.data.mbr.mbr = NULL;
    275                         }
     288                        destroy_mbr_label(&label);
    276289                        break;
    277290                case LYT_GPT:
    278                         if (table.data.gpt.parts != NULL) {
    279                                 gpt_free_partitions(table.data.gpt.parts);
    280                                 table.data.gpt.parts = NULL;
    281                         }
    282                         if (table.data.gpt.gpt != NULL) {
    283                                 gpt_free_gpt(table.data.gpt.gpt);
    284                                 table.data.gpt.gpt = NULL;
    285                         }
     291                        destroy_gpt_label(&label);
    286292                        break;
    287293                default:
    288294                        break;
    289295        }
    290 }
    291 
    292 
    293 
     296        */
     297       
     298        label.destroy_label(&label.data);
     299}
     300
     301int try_read(service_id_t dev_handle)
     302{
     303        fill_label_funcs();
     304        printf("read_parts\n");
     305        return label.read_parts(dev_handle, &label.data);
     306}
     307
     308int 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
     322int 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);
     334}
     335
     336int try_read_mbr(service_id_t dev_handle)
     337{
     338        label.layout = LYT_MBR;
     339        return try_read(dev_handle);
     340}
     341
     342int 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
     355int try_read_gpt(service_id_t dev_handle)
     356{
     357        label.layout = LYT_GPT;
     358        return try_read(dev_handle);
     359}
     360
     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
  • uspace/app/hdisk/hdisk.h

    r622a50b ra2aa81cb  
    3939        LYT_MBR,
    4040        LYT_GPT,
    41 } LAYOUTS;
     41} layouts_t;
    4242
    43 typedef struct table {
    44         LAYOUTS layout;
    45         union table_data data;
    46         int (* add_part)(tinput_t *, union table_data *);
    47         int (* delete_part)(tinput_t *, union table_data *);
    48         int (* new_table)(tinput_t *, union table_data *);
    49         int (* print_parts)();
    50         int (* write_parts)(service_id_t, union table_data *);
    51         int (* extra_funcs)(tinput_t *, service_id_t, union table_data *);
    52 } table_t;
     43typedef 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;
    5355
    54 #define init_table() \
    55         table.layout = LYT_NONE
     56#define init_label() \
     57        label.layout = LYT_NONE
    5658
    57 #define set_table_mbr(m) \
    58         table.data.mbr.mbr = (m)
    59 
    60 #define set_table_mbr_parts(p) \
    61         table.data.mbr.parts = (p)
    62 
    63 #define set_table_gpt(g) \
    64         table.data.gpt.gpt = (g)
    65 
    66 #define set_table_gpt_parts(p) \
    67         table.data.gpt.parts = (p)
  • uspace/lib/gpt/libgpt.h

    r622a50b ra2aa81cb  
    11/*
     2 * Copyright (c) 2009 Jiri Svoboda
    23 * Copyright (c) 2011, 2012, 2013 Dominik Taborsky
    3  * Copyright (c) 2009 Jiri Svoboda (for some definitions from uspace/srv/bd/part/guid_part)
    44 * All rights reserved.
    55 *
     
    130130        gpt_t * gpt;
    131131        gpt_partitions_t * parts;
    132 } gpt_table_t;
     132} gpt_label_t;
    133133
    134134struct partition_type {
     
    142142extern gpt_t * gpt_alloc_gpt_header(void);
    143143extern gpt_t * gpt_read_gpt_header(service_id_t dev_handle);
    144 extern int gpt_write_gpt_header(gpt_t * header, service_id_t dev_handle);
     144extern int     gpt_write_gpt_header(gpt_t * header, service_id_t dev_handle);
    145145
    146 extern gpt_partitions_t *       gpt_alloc_partitions(void);
    147 extern gpt_partitions_t *       gpt_read_partitions     (gpt_t * gpt);
    148 extern int                                      gpt_write_partitions    (gpt_partitions_t * parts, gpt_t * header, service_id_t dev_handle);
    149 extern gpt_part_t *                     gpt_alloc_partition             (gpt_partitions_t * parts);
    150 extern int                                      gpt_add_partition       (gpt_partitions_t * parts, gpt_part_t * partition);
    151 extern int                                      gpt_remove_partition(gpt_partitions_t * parts, size_t idx);
     146extern gpt_partitions_t * gpt_alloc_partitions(void);
     147extern gpt_partitions_t * gpt_read_partitions(gpt_t * gpt);
     148extern int             gpt_write_partitions(gpt_partitions_t * parts, gpt_t * header, service_id_t dev_handle);
     149extern gpt_part_t *    gpt_alloc_partition (gpt_partitions_t * parts);
     150extern int             gpt_add_partition   (gpt_partitions_t * parts, gpt_part_t * partition);
     151extern int             gpt_remove_partition(gpt_partitions_t * parts, size_t idx);
    152152
    153 extern size_t                           gpt_get_part_type       (gpt_part_t * p);
    154 extern void                             gpt_set_part_type       (gpt_part_t * p, size_t type);
    155 extern void                                     gpt_set_start_lba       (gpt_part_t * p, uint64_t start);
    156 extern uint64_t                         gpt_get_start_lba       (gpt_part_t * p);
    157 extern void                                     gpt_set_end_lba         (gpt_part_t * p, uint64_t end);
    158 extern uint64_t                         gpt_get_end_lba         (gpt_part_t * p);
    159 extern unsigned char *          gpt_get_part_name       (gpt_part_t * p);
    160 extern void                             gpt_set_part_name       (gpt_part_t * p, char * name[], size_t length);
    161 extern bool                                     gpt_get_flag            (gpt_part_t * p, GPT_ATTR flag);
    162 extern void                                     gpt_set_flag            (gpt_part_t * p, GPT_ATTR flag, bool value);
     153extern size_t          gpt_get_part_type(gpt_part_t * p);
     154extern void            gpt_set_part_type(gpt_part_t * p, size_t type);
     155extern void            gpt_set_start_lba(gpt_part_t * p, uint64_t start);
     156extern uint64_t        gpt_get_start_lba(gpt_part_t * p);
     157extern void            gpt_set_end_lba  (gpt_part_t * p, uint64_t end);
     158extern uint64_t        gpt_get_end_lba  (gpt_part_t * p);
     159extern unsigned char * gpt_get_part_name(gpt_part_t * p);
     160extern void            gpt_set_part_name(gpt_part_t * p, char * name[], size_t length);
     161extern bool            gpt_get_flag     (gpt_part_t * p, GPT_ATTR flag);
     162extern void            gpt_set_flag     (gpt_part_t * p, GPT_ATTR flag, bool value);
    163163
    164164
  • uspace/lib/mbr/libmbr.c

    r622a50b ra2aa81cb  
    4646
    4747static br_block_t * alloc_br(void);
    48 static int decode_part(pt_entry_t * src, mbr_part_t * trgt, uint32_t base);
    49 static int decode_logical(mbr_t * mbr, mbr_partitions_t * p, mbr_part_t * ext);
    50 static void encode_part(mbr_part_t * src, pt_entry_t * trgt, uint32_t base, bool ebr);
    51 static int check_overlap(mbr_part_t * p1, mbr_part_t * p2);
    52 static int check_encaps(mbr_part_t * inner, mbr_part_t * outer);
    53 static int check_preceeds(mbr_part_t * preceeder, mbr_part_t * precedee);
     48static int decode_part(pt_entry_t *, mbr_part_t *, uint32_t);
     49static int decode_logical(mbr_label_t *, mbr_part_t *);
     50static void encode_part(mbr_part_t *, pt_entry_t *, uint32_t, bool);
     51static int check_overlap(mbr_part_t *, mbr_part_t *);
     52static int check_encaps(mbr_part_t *, mbr_part_t *);
     53static int check_preceeds(mbr_part_t *, mbr_part_t *);
     54
     55/** Allocate and initialize mbr_label_t structure */
     56mbr_label_t * mbr_alloc_label(void)
     57{
     58        mbr_label_t *label = malloc(sizeof(mbr_label_t));
     59        if (label == NULL)
     60                return NULL;
     61       
     62        label->mbr = NULL;
     63        label->parts = NULL;
     64        label->device = 0;
     65       
     66        return label;
     67}
     68
     69/** Free mbr_label_t structure */
     70void mbr_free_label(mbr_label_t *label)
     71{
     72        if (label->mbr != NULL)
     73                mbr_free_mbr(label->mbr);
     74       
     75        if (label->parts != NULL)
     76                mbr_free_partitions(label->parts);
     77       
     78        free(label);
     79}
    5480
    5581/** Allocate memory for mbr_t */
     
    6086
    6187/** Read MBR from specific device
    62  * @param       dev_handle      device to read MBR from
    63  *
    64  * @return                              mbr record on success, NULL on error
    65  */
    66 mbr_t * mbr_read_mbr(service_id_t dev_handle)
    67 {
     88 * @param   label       label to write data to
     89 * @param   dev_handle  device to read MBR from
     90 *
     91 * @return                              EOK on success, error code on error
     92 */
     93int mbr_read_mbr(mbr_label_t *label, service_id_t dev_handle)
     94{
     95        if (label == NULL)
     96                return EINVAL;
     97       
    6898        int rc;
    69 
    70         mbr_t * mbr = malloc(sizeof(mbr_t));
    71         if (mbr == NULL) {
    72                 return NULL;
     99       
     100        if (label->mbr == NULL) {
     101                label->mbr = mbr_alloc_mbr();
     102                if (label->mbr == NULL) {
     103                        return ENOMEM;
     104                }
    73105        }
    74106
    75107        rc = block_init(EXCHANGE_ATOMIC, dev_handle, 512);
    76         if (rc != EOK) {
    77                 free(mbr);
    78                 return NULL;
    79         }
    80 
    81         rc = block_read_direct(dev_handle, 0, 1, &(mbr->raw_data));
    82         if (rc != EOK) {
    83                 free(mbr);
    84                 block_fini(dev_handle);
    85                 return NULL;
    86         }
    87 
     108        if (rc != EOK)
     109                return rc;
     110
     111        rc = block_read_direct(dev_handle, 0, 1, &(label->mbr->raw_data));
    88112        block_fini(dev_handle);
    89 
    90         mbr->device = dev_handle;
    91 
    92         return mbr;
     113        if (rc != EOK)
     114                return rc;
     115
     116        label->device = dev_handle;
     117
     118        return EOK;
    93119}
    94120
    95121/** Write mbr to disk
    96  * @param mbr                   MBR to be written
     122 * @param label                 MBR to be written
    97123 * @param dev_handle    device handle to write MBR to (may be different
    98124 *                                                      from the device in 'mbr')
     
    100126 * @return                              0 on success, otherwise libblock error code
    101127 */
    102 int mbr_write_mbr(mbr_t * mbr, service_id_t dev_handle)
     128int mbr_write_mbr(mbr_label_t *label, service_id_t dev_handle)
    103129{
    104130        int rc;
     
    109135        }
    110136
    111         rc = block_write_direct(dev_handle, 0, 1, &(mbr->raw_data));
     137        rc = block_write_direct(dev_handle, 0, 1, &(label->mbr->raw_data));
    112138        block_fini(dev_handle);
    113139        if (rc != EOK) {
     
    115141        }
    116142
    117         return 0;
     143        return EOK;
    118144}
    119145
     
    124150 * @return                      1 if MBR, 0 if GPT
    125151 */
    126 int mbr_is_mbr(mbr_t * mbr)
    127 {
    128         return (mbr->raw_data.pte[0].ptype != PT_GPT) ? 1 : 0;
    129 }
    130 
    131 /** Parse partitions from MBR
    132  * @param mbr   MBR to be parsed
    133  *
    134  * @return              linked list of partitions or NULL on error
    135  */
    136 mbr_partitions_t * mbr_read_partitions(mbr_t * mbr)
    137 {
    138         int rc, i, rc_ext;
    139         mbr_part_t * p;
    140         mbr_part_t * ext = NULL;
    141         mbr_partitions_t * parts;
    142        
    143         if (mbr == NULL)
    144                 return NULL;
    145        
    146         parts = mbr_alloc_partitions();
    147         if (parts == NULL) {
    148                 return NULL;
    149         }
    150 
    151         // Generate the primary partitions
     152int mbr_is_mbr(mbr_label_t *label)
     153{
     154        return (label->mbr->raw_data.pte[0].ptype != PT_GPT) ? 1 : 0;
     155}
     156
     157/** Parse partitions from MBR, freeing previous partitions if any
     158 * NOTE: it is assumed mbr_read_mbr(label) was called before.
     159 * @param label  MBR to be parsed
     160 *
     161 * @return       linked list of partitions or NULL on error
     162 */
     163int mbr_read_partitions(mbr_label_t *label)
     164{
     165        if (label == NULL || label->mbr == NULL)
     166                return EINVAL;
     167       
     168        int rc, rc_ext;
     169        unsigned int i;
     170        mbr_part_t *p;
     171        mbr_part_t *ext = NULL;
     172        //mbr_partitions_t *parts;
     173        printf("check\n");
     174        if (label->parts != NULL)
     175                mbr_free_partitions(label->parts);
     176        printf("check2\n");
     177        label->parts = mbr_alloc_partitions();
     178        if (label->parts == NULL) {
     179                return ENOMEM;
     180        }
     181        printf("primary\n");
     182        /* Generate the primary partitions */
    152183        for (i = 0; i < N_PRIMARY; ++i) {
    153                 if (mbr->raw_data.pte[i].ptype == PT_UNUSED)
     184                if (label->mbr->raw_data.pte[i].ptype == PT_UNUSED)
    154185                        continue;
    155                
     186                printf("pcheck1\n");
    156187                p = mbr_alloc_partition();
    157188                if (p == NULL) {
    158189                        printf(LIBMBR_NAME ": Error on memory allocation.\n");
    159                         mbr_free_partitions(parts);
    160                         return NULL;
    161                 }
    162                
    163                 rc_ext = decode_part(&(mbr->raw_data.pte[i]), p, 0);
     190                        mbr_free_partitions(label->parts);
     191                        return ENOMEM;
     192                }
     193                printf("pcheck2\n");
     194                rc_ext = decode_part(&(label->mbr->raw_data.pte[i]), p, 0);
    164195                mbr_set_flag(p, ST_LOGIC, false);
    165                 rc = mbr_add_partition(parts, p);
     196                rc = mbr_add_partition(label, p);
    166197                if (rc != ERR_OK) {
    167198                        printf(LIBMBR_NAME ": Error occured during decoding the MBR. (%d)\n" \
    168                                    LIBMBR_NAME ": Partition list may be incomplete.\n", rc);
    169                         return NULL;
    170                 }
    171                
     199                               LIBMBR_NAME ": MBR is invalid.\n", rc);
     200                        mbr_free_partitions(label->parts);
     201                        return EINVAL;
     202                }
     203                printf("pcheck3\n");
    172204                if (rc_ext) {
    173205                        ext = p;
    174                         parts->l_extended = list_last(&(parts->list));
    175                 }
    176         }
    177        
    178         // Fill in the primary partitions and generate logical ones, if any
    179         rc = decode_logical(mbr, parts, ext);
     206                        label->parts->l_extended = list_nth(&(label->parts->list), i);
     207                }
     208                printf("pcheck4\n");
     209        }
     210        printf("logical\n");
     211        /* Fill in the primary partitions and generate logical ones, if any */
     212        rc = decode_logical(label, ext);
    180213        if (rc != EOK) {
    181214                printf(LIBMBR_NAME ": Error occured during decoding the MBR.\n" \
    182215                           LIBMBR_NAME ": Partition list may be incomplete.\n");
    183         }
    184        
    185         return parts;
     216                return rc;
     217        }
     218        printf("finish\n");
     219        return EOK;
    186220}
    187221
    188222/** Write MBR and partitions to device
    189  * @param parts                 partition list to be written
    190  * @param mbr                   MBR to be written with 'parts' partitions
    191  * @param dev_handle    device to write the data to
    192  *
    193  * @return                              returns EOK on succes, specific error code otherwise
    194  */
    195 int mbr_write_partitions(mbr_partitions_t * parts, mbr_t * mbr, service_id_t dev_handle)
     223 * @param label        label to write
     224 * @param dev_handle   device to write the data to
     225 *
     226 * @return             returns EOK on succes, specific error code otherwise
     227 */
     228int mbr_write_partitions(mbr_label_t *label, service_id_t dev_handle)
    196229{
    197230        int i = 0;
    198231        int rc;
    199         mbr_part_t * p;
    200         mbr_part_t * ext = (parts->l_extended == NULL) ? NULL
    201                                         : list_get_instance(parts->l_extended, mbr_part_t, link);
     232        mbr_part_t *p;
     233        mbr_part_t *ext = (label->parts->l_extended == NULL) ? NULL
     234                                        : list_get_instance(label->parts->l_extended, mbr_part_t, link);
    202235       
    203236        rc = block_init(EXCHANGE_ATOMIC, dev_handle, 512);
     
    207240        }
    208241       
    209         link_t * l = parts->list.head.next;
    210        
    211         // Encoding primary partitions
    212         for (i = 0; i < parts->n_primary; i++) {
    213                 p = list_get_instance(l, mbr_part_t, link);
    214                 encode_part(p, &(mbr->raw_data.pte[i]), 0, false);
     242        link_t *l = label->parts->list.head.next;
     243       
     244        /* Encoding primary partitions */
     245        for (i = 0; i < label->parts->n_primary; i++) {
     246                p = list_get_instance(l, mbr_part_t, link);     
     247                encode_part(p, &(label->mbr->raw_data.pte[i]), 0, false);
    215248                l = l->next;
    216249        }
    217250       
    218         // Writing MBR
    219         rc = block_write_direct(dev_handle, 0, 1, &(mbr->raw_data));
     251        /* Writing MBR */
     252        rc = block_write_direct(dev_handle, 0, 1, &(label->mbr->raw_data));
    220253        if (rc != EOK) {
    221254                printf(LIBMBR_NAME ": Error while writing MBR : %d - %s.\n", rc, str_error(rc));
     
    234267         * as much power over it as you can get. Thanks. */
    235268       
    236         // Encoding and writing first logical partition
    237         if (l != &(parts->list.head)) {
     269        /* Encoding and writing first logical partition */
     270        if (l != &(label->parts->list.head)) {
    238271                p = list_get_instance(l, mbr_part_t, link);
    239272                p->ebr_addr = base;
     
    256289        prev_p = p;
    257290       
    258         // Encoding and writing logical partitions
    259         while (l != &(parts->list.head)) {
     291        /* Encoding and writing logical partitions */
     292        while (l != &(label->parts->list.head)) {
    260293                p = list_get_instance(l, mbr_part_t, link);
    261294               
     
    286319        }
    287320       
    288         // write the last EBR
     321        /* write the last EBR */
    289322        encode_part(NULL, &(prev_p->ebr->pte[1]), 0, false);
    290323        rc = block_write_direct(dev_handle, prev_p->ebr_addr, 1, prev_p->ebr);
     
    305338mbr_part_t * mbr_alloc_partition(void)
    306339{
    307         mbr_part_t * p = malloc(sizeof(mbr_part_t));
     340        mbr_part_t *p = malloc(sizeof(mbr_part_t));
    308341        if (p == NULL) {
    309342                return NULL;
     
    312345        link_initialize(&(p->link));
    313346        p->ebr = NULL;
    314         p->type = 0;
     347        p->type = PT_UNUSED;
    315348        p->status = 0;
    316349        p->start_addr = 0;
    317350        p->length = 0;
    318351        p->ebr_addr = 0;
    319 
     352       
    320353        return p;
    321354}
     
    324357mbr_partitions_t * mbr_alloc_partitions(void)
    325358{
    326         mbr_partitions_t * parts = malloc(sizeof(mbr_partitions_t));
     359        mbr_partitions_t *parts = malloc(sizeof(mbr_partitions_t));
    327360        if (parts == NULL) {
    328361                return NULL;
    329362        }
    330 
     363       
    331364        list_initialize(&(parts->list));
    332365        parts->n_primary = 0;
    333366        parts->n_logical = 0;
    334367        parts->l_extended = NULL;
     368       
     369        /* add blank primary partitions */
     370        int i;
     371        mbr_part_t *p;
     372        for (i = 0; i < N_PRIMARY; ++i) {
     373                p = mbr_alloc_partition();
     374                if (p == NULL) {
     375                        mbr_free_partitions(parts);
     376                        return NULL;
     377                }
     378                list_append(&(p->link), &(parts->list));
     379        }
     380       
    335381
    336382        return parts;
     
    340386 *      Performs checks, sorts the list.
    341387 *
    342  * @param parts                 partition list to add to
     388 * @param label                 label to add to
    343389 * @param p                             partition to add
    344390 *
    345391 * @return                              ERR_OK (0) on success, other MBR_ERR_VAL otherwise
    346392 */
    347 MBR_ERR_VAL mbr_add_partition(mbr_partitions_t * parts, mbr_part_t * p)
    348 {
    349         if (mbr_get_flag(p, ST_LOGIC)) { // adding logical part
    350                 // is there any extended partition?
     393mbr_err_val mbr_add_partition(mbr_label_t *label, mbr_part_t *p)
     394{
     395        int rc;
     396        mbr_partitions_t *parts = label->parts;
     397       
     398        aoff64_t nblocks;
     399        printf("add1.\n");
     400        rc = block_init(EXCHANGE_ATOMIC, label->device, 512);
     401        if (rc != EOK) {
     402                printf(LIBMBR_NAME ": Error while getting number of blocks: %d - %s.\n", rc, str_error(rc));
     403                return ERR_LIBBLOCK;
     404        }
     405        printf("add2.\n");
     406        rc = block_get_nblocks(label->device, &nblocks);
     407        block_fini(label->device);
     408        if (rc != EOK) {
     409                printf(LIBMBR_NAME ": Error while getting number of blocks: %d - %s.\n", rc, str_error(rc));
     410                return ERR_LIBBLOCK;
     411        }
     412        printf("add3.\n");
     413        if (mbr_get_flag(p, ST_LOGIC)) {
     414                /* adding logical partition */
     415               
     416                /* is there any extended partition? */
    351417                if (parts->l_extended == NULL)
    352418                        return ERR_NO_EXTENDED;
    353419               
    354                 // is the logical partition inside the extended one?
    355                 mbr_part_t * ext = list_get_instance(parts->l_extended, mbr_part_t, link);
     420                /* is the logical partition inside the extended one? */
     421                mbr_part_t *ext = list_get_instance(parts->l_extended, mbr_part_t, link);
    356422                if (!check_encaps(p, ext))
    357423                        return ERR_OUT_BOUNDS;
    358424               
    359                 // find a place for the new partition in a sorted linked list
    360                 mbr_part_t * last = list_get_instance(list_last(&(parts->list)), mbr_part_t, link);
    361                 mbr_part_t * iter;
    362                 uint32_t ebr_space = 1;
     425                /* find a place for the new partition in a sorted linked list */
     426                //mbr_part_t *last = list_get_instance(list_last(&(parts->list)), mbr_part_t, link);
     427                mbr_part_t *iter;
     428                //uint32_t ebr_space = 1;
    363429                mbr_part_foreach(parts, iter) {
    364430                        if (mbr_get_flag(iter, ST_LOGIC)) {
     
    366432                                        return ERR_OVERLAP;
    367433                                if (check_preceeds(iter, p)) {
    368                                         last = iter;
    369                                         ebr_space = p->start_addr - (last->start_addr + last->length);
    370                                 } else
    371                                         break;
     434                                        /* checking if there's at least one sector of space preceeding */
     435                                        if ((iter->start_addr + iter->length) >= p->start_addr - 1)
     436                                                return ERR_NO_EBR;
     437                                } else {
     438                                        /* checking if there's at least one sector of space following (for following partitions's EBR) */
     439                                        if ((p->start_addr + p->length) >= iter->start_addr - 1)
     440                                                return ERR_NO_EBR;
     441                                }
    372442                        }
    373443                }
    374444               
    375                 // checking if there's at least one sector of space preceeding
    376                 if (ebr_space < 1)
    377                         return ERR_NO_EBR;
    378                
    379                 // checking if there's at least one sector of space following (for following partitions's EBR)
    380                 if (last->link.next != &(parts->list.head)) {
    381                         if (list_get_instance(&(last->link.next), mbr_part_t, link)->start_addr <= p->start_addr + p->length + 1)
    382                                 return ERR_NO_EBR;
    383                 }
    384                
    385                 // alloc EBR if it's not already there
     445                /* alloc EBR if it's not already there */
    386446                if (p->ebr == NULL) {
    387447                        p->ebr = alloc_br();
     
    391451                }
    392452               
    393                 // add it
    394                 list_insert_after(&(p->link), &(last->link));
     453                /* add it */
     454                list_append(&(p->link), &(parts->list));
    395455                parts->n_logical += 1;
    396         } else { // adding primary
     456        } else {
     457                /* adding primary */
     458               
    397459                if (parts->n_primary == 4) {
    398460                        return ERR_PRIMARY_FULL;
    399461                }
    400462               
    401                 // TODO: should we check if it's inside the drive's upper boundary?
    402                 if (p->start_addr == 0) {
     463                /* Check if partition makes space for MBR itself. */
     464                if (p->start_addr == 0 || ((aoff64_t) p->start_addr) + p->length >= nblocks) {
    403465                        return ERR_OUT_BOUNDS;
    404466                }
    405                
    406                 // if it's extended, is there any other one?
     467                printf("add4.\n");
     468                /* if it's extended, is there any other one? */
    407469                if ((p->type == PT_EXTENDED || p->type == PT_EXTENDED_LBA) && parts->l_extended != NULL) {
    408470                        return ERR_EXTENDED_PRESENT;
    409471                }
    410                
    411                 // find a place and add it
    412                 if (list_empty(&(parts->list))) {
    413                         list_append(&(p->link), &(parts->list));
    414                 } else {
    415                         mbr_part_t * iter;
    416                         mbr_part_foreach(parts, iter) {
    417                                 if (mbr_get_flag(iter, ST_LOGIC)) {
    418                                         list_insert_before(&(p->link), &(iter->link));
    419                                         break;
    420                                 } else if (check_overlap(p, iter))
    421                                         return ERR_OVERLAP;
    422                         }
    423                         if (iter == list_get_instance(&(parts->list.head.prev), mbr_part_t, link))
    424                                 list_append(&(p->link), &(parts->list));
    425                 }
     472                printf("add5.\n");
     473                /* find a place and add it */
     474                mbr_part_t *iter;
     475                mbr_part_t *empty = NULL;
     476                mbr_part_foreach(parts, iter) {
     477                        printf("type: %x\n", iter->type);
     478                        if (iter->type == PT_UNUSED) {
     479                                if (empty == NULL)
     480                                        empty = iter;
     481                        } else if (check_overlap(p, iter))
     482                                return ERR_OVERLAP;
     483                }
     484                printf("add6. %p, %p\n", empty, p);
     485                list_insert_after(&(p->link), &(empty->link));
     486                printf("add6.1.\n");
     487                list_remove(&(empty->link));
     488                printf("add6.2.\n");
     489                free(empty);
     490                printf("add7.\n");
    426491                parts->n_primary += 1;
    427492               
     
    429494                        parts->l_extended = &(p->link);
    430495        }
    431 
     496        printf("add8.\n");
    432497        return ERR_OK;
    433498}
     
    435500/** Remove partition
    436501 *      Removes partition by index, indexed from zero. When removing extended
    437  * partition, all logical partitions get removed as well.
     502 *  partition, all logical partitions get removed as well.
    438503 *
    439  * @param parts                 partition list to remove from
     504 * @param label                 label to remove from
    440505 * @param idx                   index of the partition to remove
    441506 *
    442507 * @return                              EOK on success, EINVAL if idx invalid
    443508 */
    444 int mbr_remove_partition(mbr_partitions_t * parts, size_t idx)
    445 {
    446         link_t * l = list_nth(&(parts->list), idx);
     509int mbr_remove_partition(mbr_label_t *label, size_t idx)
     510{
     511        link_t *l = list_nth(&(label->parts->list), idx);
    447512        if (l == NULL)
    448513                return EINVAL;
    449514       
    450         mbr_part_t * p;
    451        
    452         /* TODO: if it is extended partition, should we also remove all logical?
    453          * If we don't, we break the consistency of the list. If we do,
    454          * the user will have to input them all over again. So yes. */
    455         if (l == parts->l_extended) {
    456                 parts->l_extended = NULL;
    457                
    458                 link_t * it = l->next;
    459                 link_t * next_it;
    460                 while (it != &(parts->list.head)) {
     515        mbr_part_t *p;
     516       
     517        /* If we're removing an extended partition, remove all logical as well */
     518        if (l == label->parts->l_extended) {
     519                label->parts->l_extended = NULL;
     520               
     521                link_t *it = l->next;
     522                link_t *next_it;
     523                while (it != &(label->parts->list.head)) {
    461524                        next_it = it->next;
    462525                       
     
    464527                        if (mbr_get_flag(p, ST_LOGIC)) {
    465528                                list_remove(it);
    466                                 parts->n_logical -= 1;
     529                                label->parts->n_logical -= 1;
    467530                                mbr_free_partition(p);
    468531                        }
     
    473536        }
    474537       
    475         list_remove(l);
    476        
     538        /* Remove the partition itself */
    477539        p = list_get_instance(l, mbr_part_t, link);
    478         if (mbr_get_flag(p, ST_LOGIC))
    479                 parts->n_logical -= 1;
    480         else
    481                 parts->n_primary -= 1;
    482        
    483        
    484         mbr_free_partition(p);
     540        if (mbr_get_flag(p, ST_LOGIC)) {
     541                label->parts->n_logical -= 1;
     542                list_remove(l);
     543                mbr_free_partition(p);
     544        } else {
     545                /* Cannot remove primary - it would break ordering, just zero it */
     546                label->parts->n_primary -= 1;
     547                p->type = 0;
     548                p->status = 0;
     549                p->start_addr = 0;
     550                p->length = 0;
     551                p->ebr_addr = 0;
     552        }
    485553       
    486554        return EOK;
     
    488556
    489557/** mbr_part_t destructor */
    490 void mbr_free_partition(mbr_part_t * p)
     558void mbr_free_partition(mbr_part_t *p)
    491559{
    492560        if (p->ebr != NULL)
     
    496564
    497565/** Get flag bool value */
    498 int mbr_get_flag(mbr_part_t * p, MBR_FLAGS flag)
     566int mbr_get_flag(mbr_part_t *p, MBR_FLAGS flag)
    499567{
    500568        return (p->status & (1 << flag)) ? 1 : 0;
     
    502570
    503571/** Set a specifig status flag to a value */
    504 void mbr_set_flag(mbr_part_t * p, MBR_FLAGS flag, bool value)
     572void mbr_set_flag(mbr_part_t *p, MBR_FLAGS flag, bool value)
    505573{
    506574        uint8_t status = p->status;
     
    522590
    523591/** Just a wrapper for free() */
    524 void mbr_free_mbr(mbr_t * mbr)
     592void mbr_free_mbr(mbr_t *mbr)
    525593{
    526594        free(mbr);
     
    531599 * @param parts         partition list to be freed
    532600 */
    533 void mbr_free_partitions(mbr_partitions_t * parts)
     601void mbr_free_partitions(mbr_partitions_t *parts)
    534602{
    535603        list_foreach_safe(parts->list, cur_link, next) {
    536                 mbr_part_t * p = list_get_instance(cur_link, mbr_part_t, link);
    537                 list_remove(cur_link);
     604                mbr_part_t *p = list_get_instance(cur_link, mbr_part_t, link);
    538605                mbr_free_partition(p);
    539606        }
     
    544611// Internal functions follow //
    545612
    546 static br_block_t * alloc_br()
    547 {
    548         br_block_t * br = malloc(sizeof(br_block_t));
     613static br_block_t *alloc_br()
     614{
     615        br_block_t *br = malloc(sizeof(br_block_t));
    549616        if (br == NULL)
    550617                return NULL;
     
    559626 * @return              returns 1, if extended partition, 0 otherwise
    560627 * */
    561 static int decode_part(pt_entry_t * src, mbr_part_t * trgt, uint32_t base)
     628static int decode_part(pt_entry_t *src, mbr_part_t *trgt, uint32_t base)
    562629{
    563630        trgt->type = src->ptype;
    564631
    565632        /* Checking only 0x80; otherwise writing will fix to 0x00 */
    566         //trgt->bootable = (src->status == B_ACTIVE) ? true : false;
    567         mbr_set_flag(trgt, ST_BOOT, (src->status == B_ACTIVE) ? true : false);
     633        trgt->status = (trgt->status & 0xFF00) | src->status;
    568634
    569635        trgt->start_addr = uint32_t_le2host(src->first_lba) + base;
     
    574640
    575641/** Parse MBR contents to mbr_part_t list */
    576 static int decode_logical(mbr_t * mbr, mbr_partitions_t * parts, mbr_part_t * ext)
     642static int decode_logical(mbr_label_t *label, mbr_part_t * ext)
    577643{
    578644        int rc;
    579         mbr_part_t * p;
    580 
    581         if (mbr == NULL || parts == NULL)
    582                 return EINVAL;
    583 
     645        mbr_part_t *p;
    584646
    585647        if (ext == NULL)
    586648                return EOK;
    587649
    588 
    589650        uint32_t base = ext->start_addr;
    590651        uint32_t addr = base;
    591         br_block_t * ebr;
    592        
    593         rc = block_init(EXCHANGE_ATOMIC, mbr->device, 512);
     652        br_block_t *ebr;
     653       
     654        rc = block_init(EXCHANGE_ATOMIC, label->device, 512);
    594655        if (rc != EOK)
    595656                return rc;
     
    601662        }
    602663       
    603         rc = block_read_direct(mbr->device, addr, 1, ebr);
     664        rc = block_read_direct(label->device, addr, 1, ebr);
    604665        if (rc != EOK) {
    605666                goto free_ebr_end;
     
    626687        p->ebr = ebr;
    627688        p->ebr_addr = addr;
    628         rc = mbr_add_partition(parts, p);
     689        rc = mbr_add_partition(label, p);
    629690        if (rc != ERR_OK)
    630691                return EINVAL;
     
    639700                }
    640701               
    641                 rc = block_read_direct(mbr->device, addr, 1, ebr);
     702                rc = block_read_direct(label->device, addr, 1, ebr);
    642703                if (rc != EOK) {
    643704                        goto free_ebr_end;
     
    660721                p->ebr = ebr;
    661722                p->ebr_addr = addr;
    662                 rc = mbr_add_partition(parts, p);
     723                rc = mbr_add_partition(label, p);
    663724                if (rc != ERR_OK)
    664725                        return EINVAL;
     
    674735       
    675736end:
    676         block_fini(mbr->device);
     737        block_fini(label->device);
    677738       
    678739        return rc;
     
    683744{
    684745        if (src != NULL) {
    685                 trgt->status = mbr_get_flag(src, ST_BOOT) ? B_ACTIVE : B_INACTIVE;
     746                //trgt->status = mbr_get_flag(src, ST_BOOT) ? B_ACTIVE : B_INACTIVE;
     747                trgt->status = (uint8_t) (src->status & 0xFF);
     748                /* ingoring CHS */
     749                trgt->first_chs[0] = 0xFE;
     750                trgt->first_chs[1] = 0xFF;
     751                trgt->first_chs[2] = 0xFF;
     752                trgt->last_chs[0] = 0xFE;
     753                trgt->last_chs[1] = 0xFF;
     754                trgt->last_chs[2] = 0xFF;
    686755                if (ebr) {      // encoding reference to EBR
    687756                        trgt->ptype = PT_EXTENDED_LBA;
  • uspace/lib/mbr/libmbr.h

    r622a50b ra2aa81cb  
    11/*
     2 * Copyright (c) 2009 Jiri Svoboda
    23 * Copyright (c) 2011, 2012, 2013 Dominik Taborsky
    3  * Copyright (c) 2009 Jiri Svoboda (for some definitions from uspace/srv/bd/part/mbr_part)
    44 * All rights reserved.
    55 *
     
    7474
    7575typedef enum {
     76        /** Other flags unknown - saving previous state */
    7677        /** Bootability */
    77         ST_BOOT = 0,
     78        ST_BOOT = 7,
    7879        /** Logical partition, 0 = primary, 1 = logical*/
    79         ST_LOGIC = 1
     80        ST_LOGIC = 8
    8081} MBR_FLAGS;
    8182
     
    102103        /** Partition overlapping */
    103104        ERR_OVERLAP,
    104         /** Logical partition out of bounds */
     105        /** Partition out of bounds */
    105106        ERR_OUT_BOUNDS,
    106107        /** No space left for EBR */
     
    108109        /** Out of memory */
    109110        ERR_NOMEM,
    110 } MBR_ERR_VAL;
     111        /** Libblock error */
     112        ERR_LIBBLOCK,
     113} mbr_err_val;
    111114
    112115
     
    144147        /** Raw access to data */
    145148        br_block_t raw_data;
    146         /** Device where the data are from */
    147         service_id_t device;
    148149} mbr_t;
    149150
     
    156157        uint8_t type;
    157158        /** Flags */
    158         uint8_t status;
     159        uint16_t status;
    159160        /** Address of first block */
    160161        uint32_t start_addr;
     
    180181
    181182/** Both header and partition list */
    182 typedef struct mbr_table {
     183typedef struct mbr_label {
     184        /** MBR header */
    183185        mbr_t * mbr;
     186        /** Partition list */
    184187        mbr_partitions_t * parts;
    185 } mbr_table_t;
    186 
    187 /** Read/Write MBR header.
     188        /** Device where the data are from (or for) */
     189        service_id_t device;
     190} mbr_label_t;
     191
     192/* Alloc complete label structure */
     193extern mbr_label_t * mbr_alloc_label(void);
     194
     195/* Read/Write MBR header.
    188196 * WARNING: when changing both header and partitions, write first header,
    189197 * then partitions. The MBR headers' raw_data is NOT updated to follow
    190198 * partition changes. */
    191199extern mbr_t * mbr_alloc_mbr(void);
    192 extern mbr_t * mbr_read_mbr(service_id_t dev_handle);
    193 extern int mbr_write_mbr(mbr_t * mbr, service_id_t dev_handle);
    194 extern int mbr_is_mbr(mbr_t * mbr);
    195 
    196 /** Read/Write/Set MBR partitions.
     200extern int mbr_read_mbr(mbr_label_t *, service_id_t);
     201extern int mbr_write_mbr(mbr_label_t *, service_id_t);
     202extern int mbr_is_mbr(mbr_label_t *);
     203
     204/* Read/Write/Set MBR partitions.
    197205 * NOTE: Writing partitions writes the complete header as well. */
    198 extern mbr_partitions_t * mbr_read_partitions(mbr_t * mbr);
    199 extern int                      mbr_write_partitions(mbr_partitions_t * parts, mbr_t * mbr, service_id_t dev_handle);
    200 extern mbr_part_t *     mbr_alloc_partition(void);
     206extern int mbr_read_partitions(mbr_label_t *);
     207extern int          mbr_write_partitions(mbr_label_t *, service_id_t);
     208extern mbr_part_t * mbr_alloc_partition(void);
    201209extern mbr_partitions_t * mbr_alloc_partitions(void);
    202 extern MBR_ERR_VAL      mbr_add_partition(mbr_partitions_t * parts, mbr_part_t * partition);
    203 extern int                      mbr_remove_partition(mbr_partitions_t * parts, size_t idx);
    204 extern int                      mbr_get_flag(mbr_part_t * p, MBR_FLAGS flag);
    205 extern void                     mbr_set_flag(mbr_part_t * p, MBR_FLAGS flag, bool value);
    206 extern uint32_t         mbr_get_next_aligned(uint32_t addr, unsigned int alignment);
     210extern mbr_err_val  mbr_add_partition(mbr_label_t *, mbr_part_t *);
     211extern int          mbr_remove_partition(mbr_label_t *, size_t);
     212extern int          mbr_get_flag(mbr_part_t *, MBR_FLAGS);
     213extern void         mbr_set_flag(mbr_part_t *, MBR_FLAGS, bool);
     214extern uint32_t     mbr_get_next_aligned(uint32_t, unsigned int);
    207215
    208216#define mbr_part_foreach(parts, iterator)       \
    209                         for (iterator  = list_get_instance((parts)->list.head.next, mbr_part_t, link); \
    210                                  iterator != list_get_instance(&((parts)->list.head), mbr_part_t, link); \
    211                                  iterator  = list_get_instance(iterator->link.next, mbr_part_t, link))
    212 
    213 
    214 /** free() wrapper functions. */
    215 extern void mbr_free_mbr(mbr_t * mbr);
    216 extern void mbr_free_partition(mbr_part_t * p);
    217 extern void mbr_free_partitions(mbr_partitions_t * parts);
     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); \
     219             iterator  = list_get_instance(iterator->link.next, mbr_part_t, link))
     220
     221
     222/* free() wrapper functions. */
     223extern void mbr_free_label(mbr_label_t *);
     224extern void mbr_free_mbr(mbr_t *);
     225extern void mbr_free_partition(mbr_part_t *);
     226extern void mbr_free_partitions(mbr_partitions_t *);
    218227
    219228#endif
Note: See TracChangeset for help on using the changeset viewer.