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

Changeset 6e8e4e19 in mainline


Ignore:
Timestamp:
2013-06-16T14:50:59Z (7 years ago)
Author:
Dominik Taborsky (AT DOT) <brembyseznamcz>
Branches:
master
Children:
1c8bfe8
Parents:
c9f61150
Message:

libmbr & hdisk changes, fixes, updates

Location:
uspace
Files:
11 edited

Legend:

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

    rc9f61150 r6e8e4e19  
    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

    rc9f61150 r6e8e4e19  
    4343static int set_gpt_partition(tinput_t *, gpt_part_t *);
    4444
    45 int add_gpt_part(tinput_t * in, union label_data * data)
     45
     46int construct_gpt_label(label_t *this)
    4647{
    47         gpt_part_t * p = gpt_alloc_partition(data->gpt->parts);
     48        this->layout = LYT_GPT;
     49        this->alignment = 1;
     50       
     51        this->add_part    = add_gpt_part;
     52        this->delete_part = delete_gpt_part;
     53        this->new_label   = new_gpt_label;
     54        this->print_parts = print_gpt_parts;
     55        this->read_parts  = read_gpt_parts;
     56        this->write_parts = write_gpt_parts;
     57        this->extra_funcs = extra_gpt_funcs;
     58       
     59        return this->new_label(this);
     60}
     61
     62int add_gpt_part(label_t *this, tinput_t * in)
     63{
     64        gpt_part_t * p = gpt_alloc_partition(this->data.gpt->parts);
    4865        if (p == NULL) {
    4966                return ENOMEM;
     
    5370}
    5471
    55 int delete_gpt_part(tinput_t * in, union label_data * data)
     72int delete_gpt_part(label_t *this, tinput_t * in)
    5673{
    5774        size_t idx;
     
    6077        idx = get_input_size_t(in);
    6178
    62         if (gpt_remove_partition(data->gpt->parts, idx) == -1) {
     79        if (gpt_remove_partition(this->data.gpt->parts, idx) == -1) {
    6380                printf("Warning: running low on memory, not resizing...\n");
    6481        }
     
    6784}
    6885
    69 int destroy_gpt_label(union label_data *data)
     86int destroy_gpt_label(label_t *this)
    7087{
    7188        return EOK;
    7289}
    7390
    74 int new_gpt_label(union label_data *data)
     91int new_gpt_label(label_t *this)
    7592{
    76         data->gpt->gpt = gpt_alloc_gpt_header();
    77         data->gpt->parts = gpt_alloc_partitions();
     93        this->data.gpt->gpt = gpt_alloc_gpt_header();
     94        this->data.gpt->parts = gpt_alloc_partitions();
    7895        return EOK;
    7996}
    8097
    81 int print_gpt_parts(union label_data *data)
     98int print_gpt_parts(label_t *this)
    8299{
    83100        //int rc;
     
    87104        size_t i = 0;
    88105       
    89         gpt_part_foreach(data->gpt->parts, iter) {
     106        gpt_part_foreach(this->data.gpt->parts, iter) {
     107                //FIXMEE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
     108                if (gpt_get_part_type(iter) == 62)
     109                        continue;
     110               
    90111                //printf("\t%10u %10u %10u %3d\n", iter->start_addr, iter->start_addr + iter->length,
    91112                //              iter->length, gpt_get_part_type(iter), gpt_get_part_name(iter));
     
    100121}
    101122
    102 int read_gpt_parts(service_id_t dev_handle, union label_data *data)
     123int read_gpt_parts(label_t *this, service_id_t dev_handle)
    103124{
    104125        return EOK;
    105126}
    106127
    107 int write_gpt_parts(service_id_t dev_handle, union label_data * data)
     128int write_gpt_parts(label_t *this, service_id_t dev_handle)
    108129{
    109130        int rc;
    110131
    111         rc = gpt_write_partitions(data->gpt->parts, data->gpt->gpt, dev_handle);
     132        rc = gpt_write_partitions(this->data.gpt->parts, this->data.gpt->gpt, dev_handle);
    112133        if (rc != EOK) {
    113134                printf("Error: Writing partitions failed: %d (%s)\n", rc, str_error(rc));
     
    115136        }
    116137
    117         rc = gpt_write_gpt_header(data->gpt->gpt, dev_handle);
     138        rc = gpt_write_gpt_header(this->data.gpt->gpt, dev_handle);
    118139        if (rc != EOK) {
    119140                printf("Error: Writing partitions failed: %d (%s)\n", rc, str_error(rc));
     
    124145}
    125146
    126 int extra_gpt_funcs(tinput_t * in, service_id_t dev_handle, union label_data * data)
     147int extra_gpt_funcs(label_t *this, tinput_t * in, service_id_t dev_handle)
    127148{
    128149        printf("Not implemented.\n");
  • uspace/app/hdisk/func_gpt.h

    rc9f61150 r6e8e4e19  
    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

    rc9f61150 r6e8e4e19  
    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

    rc9f61150 r6e8e4e19  
    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

    rc9f61150 r6e8e4e19  
    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

    rc9f61150 r6e8e4e19  
    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

    rc9f61150 r6e8e4e19  
    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

    rc9f61150 r6e8e4e19  
    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/mbr/libmbr.c

    rc9f61150 r6e8e4e19  
    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 */
     
    171173        mbr_part_t *ext = NULL;
    172174        //mbr_partitions_t *parts;
    173         printf("check\n");
     175       
    174176        if (label->parts != NULL)
    175177                mbr_free_partitions(label->parts);
    176         printf("check2\n");
     178       
    177179        label->parts = mbr_alloc_partitions();
    178180        if (label->parts == NULL) {
    179181                return ENOMEM;
    180182        }
    181         printf("primary\n");
     183       
    182184        /* Generate the primary partitions */
    183185        for (i = 0; i < N_PRIMARY; ++i) {
    184186                if (label->mbr->raw_data.pte[i].ptype == PT_UNUSED)
    185187                        continue;
    186                 printf("pcheck1\n");
     188               
    187189                p = mbr_alloc_partition();
    188190                if (p == NULL) {
     
    191193                        return ENOMEM;
    192194                }
    193                 printf("pcheck2\n");
     195               
    194196                rc_ext = decode_part(&(label->mbr->raw_data.pte[i]), p, 0);
     197                printf("p: %d %u %u\n", rc_ext, p->start_addr, p->length);
    195198                mbr_set_flag(p, ST_LOGIC, false);
    196199                rc = mbr_add_partition(label, p);
     
    201204                        return EINVAL;
    202205                }
    203                 printf("pcheck3\n");
     206               
    204207                if (rc_ext) {
    205208                        ext = p;
    206                         label->parts->l_extended = list_nth(&(label->parts->list), i);
    207                 }
    208                 printf("pcheck4\n");
    209         }
    210         printf("logical\n");
     209                        printf("ext: %u %u\n", p->start_addr, p->length);
     210                        label->parts->l_extended = &p->link;
     211                }
     212        }
     213       
    211214        /* Fill in the primary partitions and generate logical ones, if any */
    212215        rc = decode_logical(label, ext);
    213216        if (rc != EOK) {
    214                 printf(LIBMBR_NAME ": Error occured during decoding the MBR.\n" \
    215                            LIBMBR_NAME ": Partition list may be incomplete.\n");
     217                printf(LIBMBR_NAME ": Error during decoding logical partitions: %d - %s.\n" \
     218                           LIBMBR_NAME ": Partition list may be incomplete.\n", rc, str_error(rc));
    216219                return rc;
    217220        }
    218         printf("finish\n");
     221       
    219222        return EOK;
    220223}
     
    243246       
    244247        /* Encoding primary partitions */
    245         for (i = 0; i < label->parts->n_primary; i++) {
     248        for (i = 0; i < N_PRIMARY; i++) {
    246249                p = list_get_instance(l, mbr_part_t, link);     
     250                printf("status: %hu\n", p->status);
    247251                encode_part(p, &(label->mbr->raw_data.pte[i]), 0, false);
    248252                l = l->next;
     
    256260        }
    257261       
    258         if (ext == NULL)
     262        if (ext == NULL) {
     263                rc = EOK;
    259264                goto end;
     265        }
    260266       
    261267        uint32_t base = ext->start_addr;
    262         mbr_part_t * prev_p;
     268        mbr_part_t *prev_p;
    263269       
    264270        /* Note for future changes: Some thought has been put into design
     
    284290                }
    285291                free(tmp);
     292                rc = EOK;
    286293                goto end;
    287294        }
    288295       
    289296        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);
    290332       
    291333        /* Encoding and writing logical partitions */
     
    293335                p = list_get_instance(l, mbr_part_t, link);
    294336               
    295                 /* Checking whether EBR address makes sense. If not, we take a guess.
    296                  * So far this is simple, we just take the first preceeding sector.
    297                  * Fdisk always reserves at least 2048 sectors (1MiB), so it can have
    298                  * the EBR aligned as well as the partition itself. Parted reserves
    299                  * minimum one sector, like we do.
    300                  *
    301                  * Note that we know there is at least one sector free from previous checks.
    302                  * Also note that the user can set ebr_addr to their liking (if it's valid). */         
    303                 if (p->ebr_addr >= p->start_addr || p->ebr_addr <= (prev_p->start_addr + prev_p->length)) {
    304                         p->ebr_addr = p->start_addr - 1;
    305                         DEBUG_PRINT_0(LIBMBR_NAME ": Warning: invalid EBR address.\n");
    306                 }
    307337               
    308338                encode_part(p, &(p->ebr->pte[0]), p->ebr_addr, false);
     
    393423mbr_err_val mbr_add_partition(mbr_label_t *label, mbr_part_t *p)
    394424{
    395         int rc;
    396         mbr_partitions_t *parts = label->parts;
    397        
     425        int rc1, rc2;
    398426        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));
     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));
    403431                return ERR_LIBBLOCK;
    404432        }
    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));
     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));
    410441                return ERR_LIBBLOCK;
    411442        }
    412         printf("add3.\n");
    413         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))
    414454                /* adding logical partition */
    415                
    416                 /* is there any extended partition? */
    417                 if (parts->l_extended == NULL)
    418                         return ERR_NO_EXTENDED;
    419                
    420                 /* is the logical partition inside the extended one? */
    421                 mbr_part_t *ext = list_get_instance(parts->l_extended, mbr_part_t, link);
    422                 if (!check_encaps(p, ext))
    423                         return ERR_OUT_BOUNDS;
    424                
    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;
    429                 mbr_part_foreach(parts, iter) {
    430                         if (mbr_get_flag(iter, ST_LOGIC)) {
    431                                 if (check_overlap(p, iter))
    432                                         return ERR_OVERLAP;
    433                                 if (check_preceeds(iter, p)) {
    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                                 }
    442                         }
    443                 }
    444                
    445                 /* alloc EBR if it's not already there */
    446                 if (p->ebr == NULL) {
    447                         p->ebr = alloc_br();
    448                         if (p->ebr == NULL) {
    449                                 return ERR_NOMEM;
    450                         }
    451                 }
    452                
    453                 /* add it */
    454                 list_append(&(p->link), &(parts->list));
    455                 parts->n_logical += 1;
    456         } else {
     455                return mbr_add_logical(label, p);
     456        else
    457457                /* adding primary */
    458                
    459                 if (parts->n_primary == 4) {
    460                         return ERR_PRIMARY_FULL;
    461                 }
    462                
    463                 /* Check if partition makes space for MBR itself. */
    464                 if (p->start_addr == 0 || ((aoff64_t) p->start_addr) + p->length >= nblocks) {
    465                         return ERR_OUT_BOUNDS;
    466                 }
    467                 printf("add4.\n");
    468                 /* if it's extended, is there any other one? */
    469                 if ((p->type == PT_EXTENDED || p->type == PT_EXTENDED_LBA) && parts->l_extended != NULL) {
    470                         return ERR_EXTENDED_PRESENT;
    471                 }
    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");
    491                 parts->n_primary += 1;
    492                
    493                 if (p->type == PT_EXTENDED || p->type == PT_EXTENDED_LBA)
    494                         parts->l_extended = &(p->link);
    495         }
    496         printf("add8.\n");
    497         return ERR_OK;
     458                return mbr_add_primary(label, p);
    498459}
    499460
     
    572533void mbr_set_flag(mbr_part_t *p, MBR_FLAGS flag, bool value)
    573534{
    574         uint8_t status = p->status;
     535        uint16_t status = p->status;
    575536
    576537        if (value)
     
    582543}
    583544
    584 /** Get next aligned address (in sectors!) */
     545/** Get next aligned address */
    585546uint32_t mbr_get_next_aligned(uint32_t addr, unsigned int alignment)
    586547{
    587548        uint32_t div = addr / alignment;
    588549        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;
    589576}
    590577
     
    630617        trgt->type = src->ptype;
    631618
    632         /* Checking only 0x80; otherwise writing will fix to 0x00 */
    633         trgt->status = (trgt->status & 0xFF00) | src->status;
     619        trgt->status = (trgt->status & 0xFF00) | (uint16_t) src->status;
    634620
    635621        trgt->start_addr = uint32_t_le2host(src->first_lba) + base;
     
    694680       
    695681        while (ebr->pte[1].ptype != PT_UNUSED) {
     682               
    696683                ebr = alloc_br();
    697684                if (ebr == NULL) {
     
    715702                        goto free_ebr_end;
    716703                }
    717                
    718704               
    719705                decode_part(&(ebr->pte[0]), p, addr);
     
    762748                        trgt->length = host2uint32_t_le(src->length);
    763749                }
     750               
     751                if (trgt->ptype == PT_UNUSED)
     752                        memset(trgt, 0, sizeof(pt_entry_t));
    764753        } else {
    765                 trgt->status = 0;
    766                 trgt->first_chs[0] = 0;
    767                 trgt->first_chs[1] = 0;
    768                 trgt->first_chs[2] = 0;
    769                 trgt->ptype = 0;
    770                 trgt->last_chs[0] = 0;
    771                 trgt->last_chs[1] = 0;
    772                 trgt->last_chs[2] = 0;
    773                 trgt->first_lba = 0;
    774                 trgt->length = 0;
     754                memset(trgt, 0, sizeof(pt_entry_t));
    775755        }
    776756}
     
    782762static int check_overlap(mbr_part_t * p1, mbr_part_t * p2)
    783763{
    784         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) {
    785765                return 0;
    786         } 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) {
    787767                return 0;
    788768        }
     
    815795}
    816796
    817 
    818 
    819 
     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

    rc9f61150 r6e8e4e19  
    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.