Changeset 700f89e in mainline


Ignore:
Timestamp:
2013-05-02T00:51:28Z (11 years ago)
Author:
Dominik Taborsky (AT DOT) <brembyseznamcz>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
9bda5d90
Parents:
8f6c7785
Message:

libmbr semifinal, hdisk enhancements

Location:
uspace
Files:
2 added
10 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/hdisk/func_gpt.c

    r8f6c7785 r700f89e  
    6565
    6666        return EOK;
     67}
     68
     69int new_gpt_table(tinput_t * in, union table_data * data)
     70{
     71        data->gpt.gpt = gpt_alloc_gpt_header();
     72        data->gpt.parts = gpt_alloc_partitions();
    6773}
    6874
  • uspace/app/hdisk/func_gpt.h

    r8f6c7785 r700f89e  
    4444extern int add_gpt_part(tinput_t * in, union table_data * data);
    4545extern int delete_gpt_part(tinput_t * in, union table_data * data);
     46extern int new_gpt_table(tinput_t *, union table_data *);
    4647extern int print_gpt_parts(union table_data * data);
    4748extern int write_gpt_parts(service_id_t dev_handle, union table_data * data);
  • uspace/app/hdisk/func_mbr.c

    r8f6c7785 r700f89e  
    7575
    7676        return EOK;
     77}
     78
     79int new_mbr_table(tinput_t * in, union table_data * data)
     80{
     81        data->mbr.mbr = mbr_alloc_mbr();
     82        data->mbr.parts = mbr_alloc_partitions();
    7783}
    7884
  • uspace/app/hdisk/func_mbr.h

    r8f6c7785 r700f89e  
    4444extern int add_mbr_part(tinput_t * in, union table_data * data);
    4545extern int delete_mbr_part(tinput_t * in, union table_data * data);
     46extern int new_mbr_table(tinput_t *, union table_data *);
    4647extern int print_mbr_parts(union table_data * data);
    4748extern int write_mbr_parts(service_id_t dev_handle, union table_data * data);
  • uspace/app/hdisk/hdisk.c

    r8f6c7785 r700f89e  
    5353int interact(service_id_t dev_handle);
    5454void print_help(void);
     55void select_table_format(void);
    5556void fill_table_funcs(void);
    5657void free_table(void);
     
    9495                set_table_mbr_parts(parts);
    9596                fill_table_funcs();
    96         } else {
     97                goto interact;
     98        }
     99       
     100       
     101        mbr_free_mbr(mbr);
     102        gpt_t * gpt = gpt_read_gpt_header(dev_handle);
     103       
     104        if(gpt != NULL) {
    97105                table.layout = LYT_GPT;
    98                 mbr_free_mbr(mbr);
    99                 gpt_t * gpt = gpt_read_gpt_header(dev_handle);
    100                 printf("here3\n");
    101                 if(gpt == NULL) {
    102                         printf("Failed to read and parse GPT header. Exiting.\n");
    103                         return -1;
    104                 }
    105106                set_table_gpt(gpt);
    106                 printf("here4\n");
     107               
    107108                gpt_partitions_t * parts = gpt_read_partitions(gpt);
    108                 printf("here5\n");
     109               
    109110                if(parts == NULL) {
    110111                        printf("Failed to read and parse partitions.\n" \
    111112                                   "Creating new partition table.");
    112                         //parts = gpt_alloc_partitions();
     113                        parts = gpt_alloc_partitions();
    113114                }
    114115                set_table_gpt_parts(parts);
    115116                fill_table_funcs();
    116         }
    117 
     117                goto interact;
     118        }
     119        printf("No partition table recognized. Create a new one.\n");
     120        table.layout = LYT_NONE;
     121       
     122interact:
    118123        rc = interact(dev_handle);
    119124       
     
    122127        return rc;
    123128}
    124 
    125 /*
    126 int get_input(tinput_t * in, char ** str)
    127 {
    128         int c;
    129         size_tat
    130 
    131          pos = 0;
    132         size_t size = 256;
    133 
    134         *str = malloc(size * sizeof(char));
    135         if (*str == NULL)
    136                 return ENOMEM;
    137 
    138         while ((c = getchar()) != '\n') {
    139                 if (c >= 32 && c <= 126) {      //a printable character
    140 
    141                         (*str)[pos] = c;
    142                         ++pos;
    143                         putchar(c);
    144 
    145                         if (pos == size) {
    146                                 char * temp = malloc(2 * size * sizeof(char));
    147                                 memcpy(temp, *str, size);
    148                                 free(*str);
    149                                 *str = temp;
    150                                 size *= 2;
    151                         }
    152                 } else if (c == 8) {            //backspace
    153                         (*str)[pos] = 0;
    154                         --pos;
    155                         putchar(c);
    156                 }
    157         }
    158 
    159         putchar('\n');
    160 
    161         (*str)[pos] = 0;
    162 
    163         return EOK;
    164 }
    165 */
    166 
    167129
    168130/** Interact with user */
    169131int interact(service_id_t dev_handle)
    170132{
    171         //int rc;
    172133        int input;
    173134        tinput_t * in;
    174 
     135       
    175136        in = tinput_new();
    176137        if (in == NULL) {
     
    179140        }
    180141        tinput_set_prompt(in, "");
    181 
     142       
    182143        printf("Welcome to hdisk.\nType 'h' for help.\n");
    183 
    184         //printf("# ");
    185         //input = getchar();
    186         //printf("%c\n", input);
    187 
     144       
    188145        while (1) {
    189 
    190146                printf("# ");
    191147                input = getchar();
    192148                printf("%c\n", input);
    193 
    194 
    195                 //rc = tinput_read(in, &str);
    196                 //if (rc == ENOENT) {
    197                         //// User requested exit
    198                         //putchar('\n');
    199                         //return rc;
    200                 //}
    201                 //if (rc != EOK) {
    202                         //printf("Failed reading input. Exiting...\n");
    203                         //return rc;
    204                 //}
    205                 //// Check for empty input.
    206                 //if (str_cmp(str, "") == 0)
    207                         //continue;
    208 
     149               
    209150                switch(input) {
    210151                        case 'a':
     
    217158                                table.extra_funcs(in, dev_handle, &table.data);
    218159                                break;
     160                        case 'f':
     161                                free_table();
     162                                select_table_format(in);
     163                                break;
    219164                        case 'h':
    220165                                print_help();
     166                                break;
     167                        case 'n':
     168                                free_table();
     169                                table.new_table(in);
    221170                                break;
    222171                        case 'p':
     
    233182                                break;
    234183                }
    235                 //printf("# ");
    236                 //input = getchar();
    237                 //printf("%c\n", input);
    238 
    239         }
    240 
     184        }
     185       
    241186end:
    242187        tinput_destroy(in);
    243 
     188       
    244189        return EOK;
    245190}
     
    250195                "\t 'a' \t\t Add partition.\n"
    251196                "\t 'd' \t\t Delete partition.\n"
    252                 "\t 'h' \t\t Prints help. See help for more.\n" \
    253                 "\t 'p' \t\t Prints the table contents.\n" \
    254                 "\t 'w' \t\t Write table to disk.\n" \
    255                 "\t 'q' \t\t Quit.\n" \
     197                "\t 'e' \t\t Extra functions (per table format).\n"
     198                "\t 'f' \t\t Switch the format of the partition table."
     199                "\t 'h' \t\t Prints help. See help for more.\n"
     200                "\t 'n' \t\t Create new partition table (discarding the old one).\n"
     201                "\t 'p' \t\t Prints the table contents.\n"
     202                "\t 'w' \t\t Write table to disk.\n"
     203                "\t 'q' \t\t Quit.\n"
    256204                );
    257205
     206}
     207
     208void select_table_format(tinput_t * in)
     209{
     210        printf("Available formats are: \n"
     211                        "1) MBR\n"
     212                        "2) GPT\n"
     213                );
     214       
     215        uint8_t val = get_input_uint8(in);
     216        switch(val) {
     217                case 0:
     218                        table.layout = LYT_NONE;
     219                        fill_table_funcs();
     220                        break;
     221                case 1:
     222                        table.layout = LYT_MBR;
     223                        fill_table_funcs();
     224                        break;
     225                case 2:
     226                        table.layout = LYT_GPT;
     227                        fill_table_funcs();
     228                        break;
     229        }
    258230}
    259231
     
    264236                        table.add_part = add_mbr_part;
    265237                        table.delete_part = delete_mbr_part;
     238                        table.new_table = new_mbr_table;
    266239                        table.print_parts = print_mbr_parts;
    267240                        table.write_parts = write_mbr_parts;
     
    271244                        table.add_part = add_gpt_part;
    272245                        table.delete_part = delete_gpt_part;
     246                        table.new_table = new_gpt_table;
    273247                        table.print_parts = print_gpt_parts;
    274248                        table.write_parts = write_gpt_parts;
     
    276250                        break;
    277251                default:
     252                        table.add_part = add_none_part;
     253                        table.delete_part = delete_none_part;
     254                        table.new_table = new_none_table;
     255                        table.print_parts = print_none_parts;
     256                        table.write_parts = write_none_parts;
     257                        table.extra_funcs = extra_none_funcs;
    278258                        break;
    279259        }
     
    284264        switch(table.layout) {
    285265                case LYT_MBR:
    286                         mbr_free_partitions(table.data.mbr.parts);
    287                         mbr_free_mbr(table.data.mbr.mbr);
     266                        if (table.data.mbr.parts != NULL) {
     267                                mbr_free_partitions(table.data.mbr.parts);
     268                                table.data.mbr.parts = NULL;
     269                        }
     270                        if (table.data.mbr.mbr != NULL) {
     271                                mbr_free_mbr(table.data.mbr.mbr);
     272                                table.data.mbr.mbr = NULL;
     273                        }
    288274                        break;
    289275                case LYT_GPT:
    290                         gpt_free_partitions(table.data.gpt.parts);
    291                         gpt_free_gpt(table.data.gpt.gpt);
     276                        if (table.data.gpt.parts != NULL) {
     277                                gpt_free_partitions(table.data.gpt.parts);
     278                                table.data.gpt.parts = NULL;
     279                        }
     280                        if (table.data.gpt.gpt != NULL) {
     281                                gpt_free_gpt(table.data.gpt.gpt);
     282                                table.data.gpt.gpt = NULL;
     283                        }
    292284                        break;
    293285                default:
     
    296288}
    297289
     290
     291
  • uspace/app/hdisk/hdisk.h

    r8f6c7785 r700f89e  
    4646        int (* add_part)(tinput_t *, union table_data *);
    4747        int (* delete_part)(tinput_t *, union table_data *);
     48        int (* new_table)(tinput_t *, union table_data *);
    4849        int (* print_parts)();
    4950        int (* write_parts)(service_id_t, union table_data *);
  • uspace/lib/gpt/libgpt.c

    r8f6c7785 r700f89e  
    5858static int gpt_memcmp(const void * a, const void * b, size_t len);
    5959
     60/** Allocate memory for gpt header */
     61gpt_t * gpt_alloc_gpt_header()
     62{
     63        return malloc(sizeof(gpt_t));
     64}
     65
    6066/** Read GPT from specific device
    6167 * @param       dev_handle      device to read GPT from
     
    162168
    163169        return 0;
     170}
     171
     172/** Alloc partition array */
     173gpt_partitions_t *      gpt_alloc_partitions()
     174{
     175        return alloc_part_array(128);
    164176}
    165177
  • uspace/lib/gpt/libgpt.h

    r8f6c7785 r700f89e  
    139139
    140140
    141 
     141extern gpt_t * gpt_alloc_gpt_header();
    142142extern gpt_t * gpt_read_gpt_header(service_id_t dev_handle);
    143143extern int gpt_write_gpt_header(gpt_t * header, service_id_t dev_handle);
    144144
     145extern gpt_partitions_t *       gpt_alloc_partitions();
    145146extern gpt_partitions_t *       gpt_read_partitions     (gpt_t * gpt);
    146147extern int                                      gpt_write_partitions    (gpt_partitions_t * parts, gpt_t * header, service_id_t dev_handle);
  • uspace/lib/mbr/libmbr.c

    r8f6c7785 r700f89e  
    5353static int check_preceeds(mbr_part_t * preceeder, mbr_part_t * precedee);
    5454
    55 static void debug_print(unsigned char * data, size_t bytes);
     55/** Allocate memory for mbr_t */
     56mbr_t * mbr_alloc_mbr()
     57{
     58        return alloc_br();
     59}
    5660
    5761/** Read MBR from specific device
     
    7175        rc = block_init(EXCHANGE_ATOMIC, dev_handle, 512);
    7276        if (rc != EOK) {
     77                free(mbr);
    7378                return NULL;
    7479        }
     
    7681        rc = block_read_direct(dev_handle, 0, 1, &(mbr->raw_data));
    7782        if (rc != EOK) {
     83                free(mbr);
    7884                block_fini(dev_handle);
    7985                return NULL;
     
    8389
    8490        mbr->device = dev_handle;
    85         //mbr->partitions = NULL;
    8691
    8792        return mbr;
     
    9398 *                                                      from the device in 'mbr')
    9499 *
    95  * @return                              0 on success, -1 on block_init error, -2 on write error
     100 * @return                              0 on success, otherwise libblock error code
    96101 */
    97102int mbr_write_mbr(mbr_t * mbr, service_id_t dev_handle)
     
    149154                        continue;
    150155               
    151                 //p = malloc(sizeof(mbr_part_t));
    152156                p = mbr_alloc_partition();
    153157                if (p == NULL) {
     
    156160                        return NULL;
    157161                }
    158                 //list_append(&(p->link), &(parts->list));
     162               
    159163                rc_ext = decode_part(&(mbr->raw_data.pte[i]), p, 0);
    160164                mbr_set_flag(p, ST_LOGIC, false);
     
    179183        }
    180184       
    181         //DEBUG:
    182         //debug_print((unsigned char *) list_get_instance(list_last(&(parts->list)), mbr_part_t, link)->ebr, 512);
    183185        return parts;
    184186}
     
    193195int mbr_write_partitions(mbr_partitions_t * parts, mbr_t * mbr, service_id_t dev_handle)
    194196{
    195         //bool logical = false;
    196197        int i = 0;
    197198        int rc;
     
    200201                                        : list_get_instance(parts->l_extended, mbr_part_t, link);
    201202       
    202         //br_block_t * last_ebr = NULL;
    203         //link_t * it;
    204        
    205         DEBUG_PRINT_3(LIBMBR_NAME "Writing partitions: n_primary: %u, n_logical:%u, l_extended:%p", parts->n_primary, parts->n_logical, parts->l_extended);
    206        
    207203        rc = block_init(EXCHANGE_ATOMIC, dev_handle, 512);
    208204        if (rc != EOK) {
    209                 DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc));
     205                printf(LIBMBR_NAME ": Error while initializing libblock: %d - %s.\n", rc, str_error(rc));
    210206                return rc;
    211207        }
    212         /*
    213         // Encoding primary partitions
    214         for (i = 0; i < parts->n_primary; i++) {
    215                 encode_part(p, &(mbr->raw_data.pte[i]), 0);
    216         }
    217 
    218         // Writing MBR
    219         rc = block_write_direct(dev_handle, 0, 1, &(mbr->raw_data));
    220         if (rc != EOK) {
    221                 DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc));
    222                 goto end;
    223         }
    224 
    225         uint32_t base = ext->start_addr;
    226         uint32_t addr = base;
    227 
    228         // Encoding and writing logical partitions
    229         mbr_part_foreach(parts, p) {
    230                 if (p->ebr == NULL) {
    231                         p->ebr = alloc_br();
    232                         if (p->ebr == NULL)
    233                         {
    234                                 rc = ENOMEM;
    235                                 goto end;
    236                         }
    237                 }
    238 
    239 
    240         }*/
    241208       
    242209        link_t * l = parts->list.head.next;
     
    252219        rc = block_write_direct(dev_handle, 0, 1, &(mbr->raw_data));
    253220        if (rc != EOK) {
    254                 DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc));
     221                printf(LIBMBR_NAME ": Error while writing MBR : %d - %s.\n", rc, str_error(rc));
    255222                goto end;
    256223        }
    257224       
    258225        if (ext == NULL)
    259                 goto no_extended;
    260        
    261         //DEBUG:
    262         //debug_print((unsigned char *) list_get_instance(list_last(&(parts->list)), mbr_part_t, link)->ebr, 512);
     226                goto end;
     227       
    263228        uint32_t base = ext->start_addr;
    264         //uint32_t addr = base;
    265         //uint32_t prev_addr;
    266         //mbr_part_t * tmp;
    267229        mbr_part_t * prev_p;
     230       
     231        /* Note for future changes: Some thought has been put into design
     232         * and implementation. If you don't have to change it, don't. Other
     233         * designs have been tried, this came out as the least horror with
     234         * as much power over it as you can get. Thanks. */
     235       
    268236        // Encoding and writing first logical partition
    269237        if (l != &(parts->list.head)) {
     
    271239                p->ebr_addr = base;
    272240                encode_part(p, &(p->ebr->pte[0]), base, false);
    273                
    274                 /*if (l->next == &(parts->list.head))
    275                         encode_part(NULL, &(p->ebr->pte[1]), base, false);
    276                 else {
    277                         tmp = list_get_instance(l->next, mbr_part_t, link);
    278                         //debug_print((unsigned char*) p->ebr, 512);
    279                         printf("DEBUG: base: %u, tmp: start: %u, end: %u\n", base, tmp->start_addr, tmp->start_addr + tmp->length);
    280                         //encode_part(tmp, &(p->ebr->pte[1]), base);
    281                         encode_part(tmp, &(p->ebr->pte[1]), base, true);
    282                         debug_print(((unsigned char*) p->ebr) + 446, 32);
    283                 }
    284                
    285                 rc = block_write_direct(dev_handle, base, 1, p->ebr);
     241                l = l->next;
     242        } else {
     243                /* If there was an extended but no logical, we should overwrite
     244                 * the space where the first logical's EBR would have been. There
     245                 * might be some garbage from the past. */
     246                br_block_t * tmp = alloc_br();
     247                rc = block_write_direct(dev_handle, base, 1, tmp);
    286248                if (rc != EOK) {
    287                         DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc));
     249                        printf(LIBMBR_NAME ": Error while writing EBR: %d - %s.\n", rc, str_error(rc));
    288250                        goto end;
    289                 }*/
    290                
    291                 l = l->next;
    292         } else
    293                 goto no_logical;
    294        
    295         //prev_addr = base;
     251                }
     252                free(tmp);
     253                goto end;
     254        }
     255       
    296256        prev_p = p;
    297257       
     
    314274               
    315275                encode_part(p, &(p->ebr->pte[0]), p->ebr_addr, false);
    316                 debug_print(((unsigned char*) p->ebr) + 446, 32);
    317276                encode_part(p, &(prev_p->ebr->pte[1]), base, true);
    318                 debug_print(((unsigned char*) prev_p->ebr) + 446, 32);
    319                 /*if (l->next == &(parts->list.head))
    320                         encode_part(NULL, &(p->ebr->pte[1]), base, false);
    321                 else
    322                         encode_part(list_get_instance(l->next, mbr_part_t, link), &(p->ebr->pte[1]), base, true);
    323                 */
    324277               
    325278                rc = block_write_direct(dev_handle, prev_p->ebr_addr, 1, prev_p->ebr);
    326279                if (rc != EOK) {
    327                         DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc));
     280                        printf(LIBMBR_NAME ": Error while writing EBR: %d - %s.\n", rc, str_error(rc));
    328281                        goto end;
    329282                }
     
    333286        }
    334287       
     288        // write the last EBR
    335289        encode_part(NULL, &(prev_p->ebr->pte[1]), 0, false);
    336290        rc = block_write_direct(dev_handle, prev_p->ebr_addr, 1, prev_p->ebr);
    337291        if (rc != EOK) {
    338                 DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc));
     292                printf(LIBMBR_NAME ": Error while writing EBR: %d - %s.\n", rc, str_error(rc));
    339293                goto end;
    340294        }
    341        
    342 no_logical:
    343 no_extended:
    344        
    345         /*if (ext == NULL)
    346                 goto no_extended;
    347 
    348         uint32_t base = ext->start_addr;
    349         uint32_t addr;// = base;
    350         uint32_t prev_addr;
    351         mbr_part_t * prev_part = NULL;
    352 
    353         list_foreach(parts->list, iter) {
    354                 p = list_get_instance(iter, mbr_part_t, link);
    355                 if (mbr_get_flag(p, ST_LOGIC)) {
    356                         // writing logical partition
    357                         logical = true;
    358 
    359                         if (p->ebr == NULL) {
    360                                 p->ebr = alloc_br();
    361                                 if (p->ebr == NULL)
    362                                 {
    363                                         rc = ENOMEM;
    364                                         goto end;
    365                                 }
    366                         }
    367 
    368                         if (prev_part != NULL) {
    369                                 // addr is the address of EBR
    370                                 addr = p->start_addr - base;
    371                                 // base-1 means start_lba+1
    372                                 encode_part(p, &(p->ebr->pte[0]), addr - 1);
    373                                 encode_part(p, &(prev_part->ebr->pte[1]), base);
    374                                 rc = block_write_direct(dev_handle, prev_addr, 1, prev_part->ebr);
    375                                 if (rc != EOK) {
    376                                         DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc));
    377                                         goto end;
    378                                 }
    379                         } else {
    380                                 // addr is the address of EBR
    381                                 addr = base;
    382                                 // base-1 means start_lba+1
    383                                 // Fixed: mbr_add_partition now performs checks!nevim
    384                                 encode_part(p, &(p->ebr->pte[0]), base);
    385                         }
    386 
    387                         //addr = p->start_addr;
    388                         prev_addr = addr;
    389                         prev_part = p;
    390                 } else {
    391                         // writing primary partition
    392                         if (i >= 4) {
    393                                 rc = EINVAL;
    394                                 goto end;
    395                         }
    396 
    397                         encode_part(p, &(mbr->raw_data.pte[i]), 0);
    398 
    399                         ++i;
    400                 }
    401         } //*/
    402 
    403         /* If there was an extended but no logical, we should overwrite
    404          * the space where the first logical's EBR would have been. There
    405          * might be some garbage from the past.
    406          */
    407         /*
    408         last_ebr = prev_part->ebr;
    409 
    410         if (!logical)
    411         {
    412                 last_ebr = alloc_br();
    413                 if (last_ebr == NULL) {
    414                         rc = ENOMEM;
    415                         goto end;
    416                 }
    417 
    418                 last_ebr->pte[0].ptype = PT_UNUSED;
    419         }
    420 
    421 
    422         encode_part(NULL, &(last_ebr->pte[1]), 0);
    423         rc = block_write_direct(dev_handle, addr, 1, last_ebr);
    424 
    425         if (!logical)
    426         {
    427                 free(last_ebr);
    428         }
    429         */
    430         /*
    431         if (rc != EOK) {
    432                 DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc));
    433                 goto end;
    434         }
    435 
    436         goto skip;
    437 
    438 no_extended:
    439         */
    440         /*list_foreach(parts->list, it) {
    441                 p = list_get_instance(it, mbr_part_t, link);
    442                 if (mbr_get_flag(p, ST_LOGIC)) {
    443                         // extended does not exist, fail
    444                         return EINVAL;
    445                 } else {
    446                         // writing primary partition
    447                         if (i >= 4)
    448                                 return EINVAL;
    449 
    450                         encode_part(p, &(mbr->raw_data.pte[i]), 0);
    451 
    452                         ++i;
    453                 }
    454         }*/
    455         /*
    456         it = parts->list.head.next;
    457         for (i = 0; i < N_PRIMARY; i++) {
    458                 if (it != &parts->list.head) {
    459                         p = list_get_instance(it, mbr_part_t, link);
    460                         if (mbr_get_flag(p, ST_LOGIC)) {
    461                                 // extended does not exist, fail
    462                                 return EINVAL;
    463                         } else {
    464                                 // writing primary partition
    465                                 if (i >= 4)
    466                                         return EINVAL;
    467 
    468                                 encode_part(p, &(mbr->raw_data.pte[i]), 0);
    469 
    470                         }
    471 
    472                         it = it->next;
    473                 } else {
    474                         encode_part(NULL, &(mbr->raw_data.pte[i]), 0);
    475                 }
    476         }
    477 
    478 
    479 skip:
    480         rc = block_write_direct(dev_handle, 0, 1, &(mbr->raw_data));
    481         if (rc != EOK) {
    482                 DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc));
    483                 goto end;
    484         }
    485         */
    486 
    487         /*
    488         for (i = 0; i < N_PRIMARY; ++i) {
    489                 encode_part(&(p->partition), &(mbr->raw_data.pte[i]), 0);
    490                 if (p->type == PT_EXTENDED)
    491                         ext = p;
    492 
    493                 //p = list_get_instance(p->link.next, mbr_partitions_t, link);
    494                 p = p->next;
    495         }
    496 
    497         rc = block_write_direct(dev_handle, 0, 1, &(mbr->raw_data));
    498         if (rc != EOK) {
    499                 block_fini(dev_handle);
    500                 return rc;
    501         }
    502 
    503         //writing logical partitions
    504 
    505         if (p == NULL && ext != NULL) {
    506                 //we need an empty EBR to rewrite the old EBR on disk, if we need to delete it
    507                 br_block_t * temp_ebr = alloc_br();
    508                 if (temp_ebr == NULL) {
    509                         block_fini(dev_handle);
    510                         return ENOMEM;
    511                 }
    512 
    513                 temp_ebr->pte[0].ptype = PT_UNUSED;
    514                 encode_part(NULL, &(temp_ebr->pte[1]), 0);
    515                 rc = block_write_direct(dev_handle, ext->start_addr, 1, temp_ebr);
    516                 free(temp_ebr);
    517                 block_fini(dev_handle);
    518                 return rc;
    519         }
    520 
    521         if (p != NULL && ext == NULL) {
    522                 block_fini(dev_handle);
    523                 //no extended but one or more logical? EINVAL to the rescue!
    524                 return EINVAL;
    525         }
    526 
    527         aoff64_t addr = ext->start_addr;
    528 
    529         while (p != NULL) {
    530                 if (p->type == PT_UNUSED) {
    531                         p = p->next;
    532                         continue;
    533                 }
    534                 //encode_part(p, &(p->ebr->pte[0]), p->start_addr - 63 * 512);
    535                 encode_part(p, &(p->ebr->pte[0]), addr);
    536                 encode_part(p->next, &(p->ebr->pte[1]), ext->start_addr);
    537 
    538                 rc = block_write_direct(dev_handle, p->start_addr, 1, p->ebr);
    539                 if (rc != EOK) {
    540                         block_fini(dev_handle);
    541                         return rc;
    542                 }
    543                 addr = p->start_addr;
    544                 p = p->next;
    545         }*/
    546295       
    547296        rc = EOK;
     
    560309                return NULL;
    561310        }
     311       
    562312        link_initialize(&(p->link));
    563313        p->ebr = NULL;
     
    571321}
    572322
     323/** mbr_partitions_t constructor */
    573324mbr_partitions_t * mbr_alloc_partitions(void)
    574325{
     
    579330
    580331        list_initialize(&(parts->list));
    581 
    582332        parts->n_primary = 0;
    583333        parts->n_logical = 0;
     
    589339/** Add partition
    590340 *      Performs checks, sorts the list.
    591  */
    592 int mbr_add_partition(mbr_partitions_t * parts, mbr_part_t * p)
     341 *
     342 * @param parts                 partition list to add to
     343 * @param p                             partition to add
     344 *
     345 * @return                              ERR_OK (0) on success, other MBR_ERR_VAL otherwise
     346 */
     347MBR_ERR_VAL mbr_add_partition(mbr_partitions_t * parts, mbr_part_t * p)
    593348{
    594349        if (mbr_get_flag(p, ST_LOGIC)) { // adding logical part
    595                 if (parts->l_extended == NULL) {
     350                // is there any extended partition?
     351                if (parts->l_extended == NULL)
    596352                        return ERR_NO_EXTENDED;
    597                 }
     353               
     354                // is the logical partition inside the extended one?
    598355                mbr_part_t * ext = list_get_instance(parts->l_extended, mbr_part_t, link);
    599                 if (!check_encaps(p, ext)) {
    600                         //printf("DEBUG: OOB: start: %u, end: %u\n", h->start_addr, h->start_addr + h->length);
    601                         //printf("DEBUG: OOB: start: %u, end: %u\n", p->start_addr, p->start_addr + p->length);
     356                if (!check_encaps(p, ext))
    602357                        return ERR_OUT_BOUNDS;
    603                 }
    604 
     358               
     359                // find a place for the new partition in a sorted linked list
    605360                mbr_part_t * last = list_get_instance(list_last(&(parts->list)), mbr_part_t, link);
    606361                mbr_part_t * iter;
     
    608363                mbr_part_foreach(parts, iter) {
    609364                        if (mbr_get_flag(iter, ST_LOGIC)) {
    610                                 if (check_overlap(p, iter)) {
    611                                         //printf("DEBUG: overlap: start: %u, end: %u\n", iter->start_addr, iter->start_addr + iter->length);
    612                                         //printf("DEBUG: overlap: start: %u, end: %u\n", p->start_addr, p->start_addr + p->length);
     365                                if (check_overlap(p, iter))
    613366                                        return ERR_OVERLAP;
    614                                 }
    615367                                if (check_preceeds(iter, p)) {
    616368                                        last = iter;
     
    622374               
    623375                // checking if there's at least one sector of space preceeding
    624                
    625376                if (ebr_space < 1)
    626377                        return ERR_NO_EBR;
     
    628379                // checking if there's at least one sector of space following (for following partitions's EBR)
    629380                if (last->link.next != &(parts->list.head)) {
    630                         if (list_get_instance(&(last->link.next), mbr_part_t, link)->start_addr <= p->start_addr + p->length + 1) {
     381                        if (list_get_instance(&(last->link.next), mbr_part_t, link)->start_addr <= p->start_addr + p->length + 1)
    631382                                return ERR_NO_EBR;
    632                         }
    633                 }
    634                
     383                }
     384               
     385                // alloc EBR if it's not already there
    635386                if (p->ebr == NULL) {
    636387                        p->ebr = alloc_br();
     
    640391                }
    641392               
    642                 //printf("DEBUG: last: start: %u\n", last->start_addr);
    643                 //list_prepend(&(p->link), &(parts->list));
     393                // add it
    644394                list_insert_after(&(p->link), &(last->link));
    645395                parts->n_logical += 1;
    646         } else {
    647                 // adding primary
     396        } else { // adding primary
    648397                if (parts->n_primary == 4) {
    649398                        return ERR_PRIMARY_FULL;
    650399                }
    651400               
    652                 // should we check if it's inside the drive's upper boundary?
     401                // TODO: should we check if it's inside the drive's upper boundary?
    653402                if (p->start_addr == 0) {
    654403                        return ERR_OUT_BOUNDS;
    655404                }
    656405               
     406                // if it's extended, is there any other one?
    657407                if (p->type == PT_EXTENDED && parts->l_extended != NULL) {
    658408                        return ERR_EXTENDED_PRESENT;
    659409                }
    660 
     410               
     411                // find a place and add it
    661412                if (list_empty(&(parts->list))) {
    662413                        list_append(&(p->link), &(parts->list));
     
    667418                                        list_insert_before(&(p->link), &(iter->link));
    668419                                        break;
    669                                 } else if (check_overlap(p, iter)) {
     420                                } else if (check_overlap(p, iter))
    670421                                        return ERR_OVERLAP;
    671                                 }
    672422                        }
    673                         if (iter == list_get_instance(&(parts->list.head.prev), mbr_part_t, link)) {
     423                        if (iter == list_get_instance(&(parts->list.head.prev), mbr_part_t, link))
    674424                                list_append(&(p->link), &(parts->list));
     425                }
     426                parts->n_primary += 1;
     427        }
     428
     429        return ERR_OK;
     430}
     431
     432/** Remove partition
     433 *      Removes partition by index, indexed from zero. When removing extended
     434 * partition, all logical partitions get removed as well.
     435 *
     436 * @param parts                 partition list to remove from
     437 * @param idx                   index of the partition to remove
     438 *
     439 * @return                              EOK on success, EINVAL if idx invalid
     440 */
     441int mbr_remove_partition(mbr_partitions_t * parts, size_t idx)
     442{
     443        link_t * l = list_nth(&(parts->list), idx);
     444        if (l == NULL)
     445                return EINVAL;
     446       
     447        mbr_part_t * p;
     448       
     449        /* TODO: if it is extended partition, should we also remove all logical?
     450         * If we don't, we break the consistency of the list. If we do,
     451         * the user will have to input them all over again. So yes. */
     452        if (l == parts->l_extended) {
     453                parts->l_extended = NULL;
     454               
     455                link_t * it = l->next;
     456                link_t * next_it;
     457                while (it != &(parts->list.head)) {
     458                        next_it = it->next;
     459                       
     460                        p = list_get_instance(it, mbr_part_t, link);
     461                        if (mbr_get_flag(p, ST_LOGIC)) {
     462                                list_remove(it);
     463                                parts->n_logical -= 1;
     464                                mbr_free_partition(p);
    675465                        }
    676466                       
    677                 }
    678                 parts->n_primary += 1;
    679         }
    680 
    681         return ERR_OK;
    682 }
    683 
    684 /** Remove partition */
    685 int mbr_remove_partition(mbr_partitions_t * parts, size_t idx)
    686 {
    687         DEBUG_PRINT_1(LIBMBR_NAME "Removing partition: %zu\n", idx);
    688         link_t * l = list_nth(&(parts->list), idx);
    689         if (l == parts->l_extended) {
    690                 DEBUG_PRINT_0(LIBMBR_NAME "Removing extended partition.\n");
    691                 parts->l_extended = NULL;
    692         }
     467                        it = next_it;
     468                }
     469               
     470        }
     471       
    693472        list_remove(l);
    694         mbr_part_t * p = list_get_instance(l, mbr_part_t, link);
    695         if (mbr_get_flag(p, ST_LOGIC)) {
     473       
     474        p = list_get_instance(l, mbr_part_t, link);
     475        if (mbr_get_flag(p, ST_LOGIC))
    696476                parts->n_logical -= 1;
    697         } else {
     477        else
    698478                parts->n_primary -= 1;
    699         }
    700 
    701 
     479       
     480       
    702481        mbr_free_partition(p);
    703 
     482       
    704483        return EOK;
    705484}
     
    769548       
    770549        memset(br, 0, 512);
    771         br->media_id = 0;
    772         br->pad0 = 0;
    773550        br->signature = host2uint16_t_le(BR_SIGNATURE);
    774551       
     
    847624        p->ebr_addr = addr;
    848625        rc = mbr_add_partition(parts, p);
    849         if (rc != ERR_OK) {
    850                 printf(LIBMBR_NAME ": Error occured during decoding the MBR. (%d)\n" \
    851                            LIBMBR_NAME ": Partition list may be incomplete.\n", rc);
     626        if (rc != ERR_OK)
    852627                return EINVAL;
    853         }
    854628       
    855629        addr = uint32_t_le2host(ebr->pte[1].first_lba) + base;
    856         printf("DEBUG: b: %u, a: %u, start: %u\n", base, addr, ebr->pte[1].first_lba);
    857630       
    858631        while (ebr->pte[1].ptype != PT_UNUSED) {
     
    879652                }
    880653               
    881                 //printf("DEBUG: b: %u, a: %u, start: %u\n", base, addr, ebr->pte[0].first_lba);
     654               
    882655                decode_part(&(ebr->pte[0]), p, addr);
    883656                mbr_set_flag(p, ST_LOGIC, true);
     
    885658                p->ebr_addr = addr;
    886659                rc = mbr_add_partition(parts, p);
    887                 if (rc != ERR_OK) {
    888                         printf(LIBMBR_NAME ": Error occured during decoding the MBR. (%d)\n" \
    889                                    LIBMBR_NAME ": Partition list may be incomplete.\n", rc);
     660                if (rc != ERR_OK)
    890661                        return EINVAL;
    891                 }
    892662               
    893663                addr = uint32_t_le2host(ebr->pte[1].first_lba) + base;
     
    934704}
    935705
     706/** Check whether two partitions overlap
     707 *
     708 * @return              1 for yes, 0 for no
     709 */
    936710static int check_overlap(mbr_part_t * p1, mbr_part_t * p2)
    937711{
     
    945719}
    946720
     721/** Check whether one partition encapsulates the other
     722 *
     723 * @return              1 for yes, 0 for no
     724 */
    947725static int check_encaps(mbr_part_t * inner, mbr_part_t * outer)
    948726{
     
    956734}
    957735
     736/** Check whether one partition preceeds the other
     737 *
     738 * @return              1 for yes, 0 for no
     739 */
    958740static int check_preceeds(mbr_part_t * preceeder, mbr_part_t * precedee)
    959741{
     
    961743}
    962744
    963 static void debug_print(unsigned char * data, size_t bytes)
    964 {
    965         size_t addr = 0;
    966         int i;
    967        
    968         while (bytes >= 16) {
    969                 printf("%8x ", addr);
    970                 for (i = 0; i < 8; i++) {
    971                         printf(" %2hhx", data[addr + i]);
    972                 }
    973                 printf(" ");
    974                 for (i = 0; i < 8; i++) {
    975                         printf(" %2hhx", data[addr + i + 8]);
    976                 }
    977                 printf("\n");
    978                
    979                 bytes -= 16;
    980                 addr += 16;
    981         }
    982        
    983        
    984 }
    985 
    986 
    987 
     745
     746
     747
  • uspace/lib/mbr/libmbr.h

    r8f6c7785 r700f89e  
    188188 * then partitions. The MBR headers' raw_data is NOT updated to follow
    189189 * partition changes. */
     190extern mbr_t * mbr_alloc_mbr();
    190191extern mbr_t * mbr_read_mbr(service_id_t dev_handle);
    191192extern int mbr_write_mbr(mbr_t * mbr, service_id_t dev_handle);
     
    198199extern mbr_part_t *     mbr_alloc_partition(void);
    199200extern mbr_partitions_t * mbr_alloc_partitions(void);
    200 extern int                      mbr_add_partition(mbr_partitions_t * parts, mbr_part_t * partition);
     201extern MBR_ERR_VAL      mbr_add_partition(mbr_partitions_t * parts, mbr_part_t * partition);
    201202extern int                      mbr_remove_partition(mbr_partitions_t * parts, size_t idx);
    202203extern int                      mbr_get_flag(mbr_part_t * p, MBR_FLAGS flag);
Note: See TracChangeset for help on using the changeset viewer.