Changeset 30440ed in mainline


Ignore:
Timestamp:
2013-04-08T23:15:42Z (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:
256cbfe
Parents:
271e24a
Message:

save progress

Location:
uspace
Files:
2 added
10 edited

Legend:

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

    r271e24a r30440ed  
    3535#include <stdio.h>
    3636#include <errno.h>
     37#include <str_error.h>
    3738#include <sys/types.h>
    3839
    3940#include "func_gpt.h"
     41#include "input.h"
     42
     43static int set_gpt_partition(tinput_t *, gpt_part_t *);
    4044
    4145int add_gpt_part(tinput_t * in, union table_data * data)
    4246{
    43         int rc = EOK;
     47        gpt_part_t * p = gpt_alloc_partition(data->gpt.parts);
     48        if (p == NULL) {
     49                return ENOMEM;
     50        }
    4451       
    45         return rc;
     52        return set_gpt_partition(in, p);
    4653}
    4754
    4855int delete_gpt_part(tinput_t * in, union table_data * data)
    4956{
    50         int rc = EOK;
     57        size_t idx;
     58
     59        printf("Number of the partition to delete (counted from 0): ");
     60        idx = get_input_size_t(in);
    5161       
    52         return rc;
     62        if (gpt_remove_partition(data->gpt.parts, idx) == -1) {
     63                printf("Warning: running low on memory, not resizing...\n");
     64        }
     65       
     66        return EOK;
    5367}
    5468
    5569int print_gpt_parts(union table_data * data)
    5670{
    57         int rc = EOK;
     71        printf("Current partition scheme (GPT):\n");
     72        printf("\t\tStart:\tEnd:\tLength:\tType:\tName:\n");
     73       
     74        gpt_foreach(data->gpt.parts, i, iter) {
     75                printf("\t%10u %10u %10u %3d\n", iter->start_addr, iter->start_addr + iter->length,
     76                                iter->length, gpt_get_part_type(iter), gpt_get_part_name(iter));
     77        }
    5878       
    5979        return rc;
     
    6282int write_gpt_parts(service_id_t dev_handle, union table_data * data)
    6383{
    64         int rc = EOK;
     84        int rc;
    6585       
    66         return rc;
     86        rc = gpt_write_partitions(data->gpt.parts, data->gpt.gpt, dev_handle);
     87        if (rc != EOK) {
     88                printf("Error: Writing partitions failed: %d (%s)\n", rc, str_error(rc));
     89                return rc;
     90        }
     91       
     92        rc = gpt_write_gpt_header(data->gpt.gpt, dev_handle);
     93        if (rc != EOK) {
     94                printf("Error: Writing partitions failed: %d (%s)\n", rc, str_error(rc));
     95                return rc;
     96        }
     97       
     98        return EOK;
    6799}
    68100
     101int extra_gpt_funcs(tinput_t * in, service_id_t dev_handle, union table_data * data)
     102{
     103        return EOK;
     104}
     105
     106static int set_gpt_partition(tinput_t * in, gpt_part_t * p)
     107{
     108        int rc;
     109       
     110        uint64_t sa, ea;
     111       
     112        printf("Set starting address (number): ");
     113        sa = get_input_uint64(in);
     114
     115        printf("Set end addres (number): ");
     116        ea = get_input_uint64(in);
     117       
     118        if (ea <= sa) {
     119                printf("Invalid value.\n");
     120                return EINVAL;
     121        }
     122       
     123       
     124        p->start_addr = sa;
     125        p->length = ea - sa;
     126       
     127        return EOK;
     128}
     129
  • uspace/app/hdisk/func_gpt.h

    r271e24a r30440ed  
    4646extern int print_gpt_parts(union table_data * data);
    4747extern int write_gpt_parts(service_id_t dev_handle, union table_data * data);
     48extern int extra_gpt_funcs(tinput_t * in, service_id_t dev_handle, union table_data * data);
    4849
    4950#endif
  • uspace/app/hdisk/func_mbr.c

    r271e24a r30440ed  
    3535#include <stdio.h>
    3636#include <errno.h>
     37#include <str_error.h>
    3738#include <sys/types.h>
    3839
     
    9495                        printf(" ");
    9596
    96                 printf("\t\t%u\t%u\t%u\t%d\n", it->start_addr, it->start_addr + it->length, it->length, it->type);
     97                printf("\t%10u %10u %10u %3d\n", it->start_addr, it->start_addr + it->length, it->length, it->type);
    9798
    9899                ++num;
     
    108109        int rc = mbr_write_partitions(data->mbr.parts, data->mbr.mbr, dev_handle);
    109110        if (rc != EOK) {
    110                 printf("Error occured during writing. (ERR: %d)\n", rc);
     111                printf("Error occured during writing: ERR: %d: %s\n", rc, str_error(rc));
    111112        }
    112113       
     
    114115}
    115116
    116 
     117int extra_mbr_funcs(tinput_t * in, service_id_t dev_handle, union table_data * data)
     118{
     119        return EOK;
     120}
    117121
    118122static int set_mbr_partition(tinput_t * in, mbr_part_t * p)
     
    123127        printf("Primary (p) or logical (l): ");
    124128        c = getchar();
     129        printf("%c\n", c);
    125130
    126131        switch(c) {
    127132                case 'p':
    128133                        mbr_set_flag(p, ST_LOGIC, false);
     134                        break;
    129135                case 'l':
    130136                        mbr_set_flag(p, ST_LOGIC, true);
     137                        break;
    131138                default:
    132139                        printf("Invalid type. Cancelled.");
     
    144151                return EINVAL;
    145152        }
    146        
     153        printf("%c\n", c);
    147154        mbr_set_flag(p, ST_BOOT, (c == 'y' || c == 'Y') ? true : false);
    148155
  • uspace/app/hdisk/func_mbr.h

    r271e24a r30440ed  
    4646extern int print_mbr_parts(union table_data * data);
    4747extern int write_mbr_parts(service_id_t dev_handle, union table_data * data);
     48extern int extra_mbr_funcs(tinput_t * in, service_id_t dev_handle, union table_data * data);
    4849
    4950#endif
  • uspace/app/hdisk/hdisk.c

    r271e24a r30440ed  
    175175                return ENOMEM;
    176176        }
     177        tinput_set_prompt(in, "");
    177178
    178179        printf("Welcome to hdisk.\nType 'h' for help.\n");
     
    184185        while (1) {
    185186
    186                 //printf("# ");
     187                printf("# ");
    187188                input = getchar();
    188                 //printf("%c\n", input);
     189                printf("%c\n", input);
    189190               
    190191
     
    210211                                table.delete_part(in, &table.data);
    211212                                break;
     213                        case 'e':
     214                                table.extra_funcs(in, dev_handle, &table.data);
     215                                break;
    212216                        case 'h':
    213217                                print_help();
     
    259263                        table.print_parts = print_mbr_parts;
    260264                        table.write_parts = write_mbr_parts;
     265                        table.extra_funcs = extra_mbr_funcs;
    261266                        break;
    262267                case LYT_GPT:
     
    265270                        table.print_parts = print_gpt_parts;
    266271                        table.write_parts = write_gpt_parts;
     272                        table.extra_funcs = extra_gpt_funcs;
    267273                        break;
    268274                default:
  • uspace/lib/gpt/libgpt.c

    r271e24a r30440ed  
    117117 *
    118118 * @return                              0 on success, libblock error code otherwise
     119 *
     120 * Note: Firstly write partitions (if changed), then gpt header.
    119121 */
    120122int gpt_write_gpt_header(gpt_t * gpt, service_id_t dev_handle)
     
    167169        unsigned int i;
    168170        gpt_partitions_t * res;
    169         uint32_t num_ent = uint32_t_le2host(gpt->raw_data->num_entries);
     171        uint32_t fill = uint32_t_le2host(gpt->raw_data->fillries);
    170172        uint32_t ent_size = uint32_t_le2host(gpt->raw_data->entry_size);
    171173        uint64_t ent_lba = uint64_t_le2host(gpt->raw_data->entry_lba);
    172174       
    173         res = alloc_part_array(num_ent);
     175        res = alloc_part_array(fill);
    174176        if (res == NULL) {
    175177                //errno = ENOMEM; // already set in alloc_part_array()
     
    204206         * will always read just sizeof(gpt_entry_t) bytes - hopefully they
    205207         * don't break backward compatibility) */
    206         for (i = 0; i < num_ent; ++i) {
     208        for (i = 0; i < fill; ++i) {
    207209                //FIXME: this does bypass cache...
    208210                rc = block_read_bytes_direct(gpt->device, pos, sizeof(gpt_entry_t), res->part_array + i);
     
    223225         * on all of the partition entry array.
    224226         */
    225         uint32_t crc = compute_crc32((uint8_t *) res->part_array, res->num_ent * sizeof(gpt_entry_t));
     227        uint32_t crc = compute_crc32((uint8_t *) res->part_array, res->fill * sizeof(gpt_entry_t));
    226228       
    227229        if(uint32_t_le2host(gpt->raw_data->pe_array_crc32) != crc)
     
    247249        size_t b_size;
    248250       
    249         gpt->raw_data->pe_array_crc32 = compute_crc32((uint8_t *) parts->part_array, parts->num_ent * gpt->raw_data->entry_size);
     251        gpt->raw_data->pe_array_crc32 = compute_crc32((uint8_t *) parts->part_array, parts->fill * gpt->raw_data->entry_size);
    250252       
    251253        rc = block_get_bsize(dev_handle, &b_size);
     
    259261        /* Write to main GPT partition array location */
    260262        rc = block_write_direct(dev_handle, uint64_t_le2host(gpt->raw_data->entry_lba),
    261                         nearest_larger_int((uint64_t_le2host(gpt->raw_data->entry_size) * parts->num_ent) / b_size),
     263                        nearest_larger_int((uint64_t_le2host(gpt->raw_data->entry_size) * parts->fill) / b_size),
    262264                        parts->part_array);
    263265        if (rc != EOK)
     
    277279       
    278280       
    279         gpt_write_gpt_header(gpt, dev_handle);
    280        
    281         return 0;
    282        
    283 }
    284 
    285 gpt_partitions_t * gpt_add_partition(gpt_partitions_t * parts, gpt_part_t * partition)
    286 {
    287        
     281        return gpt_write_gpt_header(gpt, dev_handle);
     282}
     283
     284/** Alloc new partition
     285 *
     286 * @param parts         partition table to carry new partition
     287 *
     288 * @return                      returns pointer to the new partition or NULL on ENOMEM
     289 *
     290 * Note: use either gpt_alloc_partition or gpt_add_partition. The first
     291 * returns a pointer to write your data to, the second copies the data
     292 * (and does not free the memory).
     293 */
     294gpt_part_t * gpt_alloc_partition(gpt_partitions_t * parts)
     295{
     296        if (parts->fill == parts->arr_size) {
     297                if (extend_part_array(parts) == -1)
     298                        return NULL;
     299        }
     300       
     301        return parts->part_array + parts->fill++;
     302}
     303
     304/** Copy partition into partition array
     305 *
     306 * @param parts                 target partition array
     307 * @param partition             source partition to copy
     308 *
     309 * @return                              -1 on error, 0 otherwise
     310 *
     311 * Note: use either gpt_alloc_partition or gpt_add_partition. The first
     312 * returns a pointer to write your data to, the second copies the data
     313 * (and does not free the memory).
     314 */
     315int gpt_add_partition(gpt_partitions_t * parts, gpt_part_t * partition)
     316{
     317        if (parts->fill == parts->arr_size) {
     318                if (extend_part_array(parts) == -1)
     319                        return -1;
     320        }
    288321        extend_part_array(parts);
    289322        return parts;
    290323}
    291324
    292 gpt_partitions_t * gpt_remove_partition(gpt_partitions_t * parts, size_t idx)
    293 {
    294         reduce_part_array(parts);
    295         return parts;
     325/** Remove partition from array
     326 *
     327 * @param idx           index of the partition to remove
     328 *
     329 * @return                      -1 on error, 0 otherwise
     330 *
     331 * Note: even if it fails, the partition still gets removed. Only
     332 * reducing the array failed.
     333 */
     334int gpt_remove_partition(gpt_partitions_t * parts, size_t idx)
     335{
     336        if (idx != parts->fill - 1) {
     337                memcpy(parts->part_array + idx, parts->part_array + fill - 1, sizeof(gpt_entry_t));
     338                parts->fill -= 1;
     339        }
     340       
     341        if (parts->fill < (parts->arr_size / 2) - GPT_IGNORE_FILL_NUM) {
     342                if (reduce_part_array(parts) == -1)
     343                        return -1;
     344        }
     345       
     346        return 0;
    296347}
    297348
     
    311362        free(parts->part_array);
    312363        free(parts);
     364}
     365
     366/** Get partition type by linear search
     367 * (hopefully this doesn't get slow)
     368 */
     369size_t gpt_get_part_type(gpt_part_t * p)
     370{
     371        size_t i;
     372        for (i = 0; gpt_ptypes[i].guid != NULL; i++) {
     373                if (memcmp(p->raw_data.part_type, gpt_ptypes[i].guid, 16) == 0) {
     374                        break;
     375                }
     376        }
     377        return i;
    313378}
    314379
     
    343408}
    344409
     410char * gpt_get_part_name(gpt_entry_t * p)
     411{
     412        return p->raw_data.part_name;
     413}
     414
    345415/** Copy partition name */
    346416void gpt_set_part_name(gpt_entry_t * p, char * name[], size_t length)
    347417{
     418        if (length >= 72)
     419                length = 71;
     420       
    348421        memcpy(p->part_name, name, length);
     422        p->part_name[length] = '\0';
     423}
     424
     425/** Get partition attribute */
     426extern bool gpt_get_flag(gpt_part_t * p, GPT_ATTR flag)
     427{
     428        return (p->raw_data.attributes & (((uint64_t) 1) << flag)) ? 1 : 0;
     429}
     430
     431/** Set partition attribute */
     432extern void gpt_set_flag(gpt_part_t * p, GPT_ATTR flag, bool value)
     433{
     434        uint64_t attr = p->raw_data.attributes;
     435
     436        if (value)
     437                attr = attr | (((uint64_t) 1) << flag);
     438        else
     439                attr = attr ^ (attr & (((uint64_t) 1) << flag));
     440
     441        p->raw_data.attributes = attr;
    349442}
    350443
     
    405498        }
    406499       
    407         res->num_ent = num;
     500        res->fill = num;
    408501        res->arr_size = size;
    409502       
     
    420513        }
    421514       
    422         memcpy(tmp, p->part_array, p->num_ent);
     515        memcpy(tmp, p->part_array, p->fill);
    423516        free(p->part_array);
    424517        p->part_array = tmp;
     
    438531                }
    439532               
    440                 memcpy(tmp, p->part_array, p->num_ent < nsize ? p->num_ent : nsize);
     533                memcpy(tmp, p->part_array, p->fill < nsize ? p->fill : nsize);
    441534                free(p->part_array);
    442535                p->part_array = tmp;
  • uspace/lib/gpt/libgpt.h

    r271e24a r30440ed  
    4949/** Basic number of GPT partition entries */
    5050#define GPT_BASE_PART_NUM (GPT_MIN_PART_NUM)
     51/** How much fill we ignore before resizing partition array */
     52#define GPT_IGNORE_FILL_NUM 10
    5153
    5254/** GPT header signature ("EFI PART" in ASCII) */
    5355extern const uint8_t efi_signature[8];
     56
     57typedef enum {
     58        AT_REQ_PART = 0,
     59        AT_NO_BLOCK_IO,
     60        AT_LEGACY_BOOT,
     61        AT_UNDEFINED,
     62        AT_SPECIFIC = 48
     63} GPT_ATTR;
    5464
    5565/** GPT header
     
    6878        uint8_t disk_guid[16];
    6979        uint64_t entry_lba;
    70         uint32_t num_entries;
     80        uint32_t fillries;
    7181        uint32_t entry_size;
    7282        uint32_t pe_array_crc32;
     
    105115typedef struct gpt_parts {
    106116        /** Number of entries */
    107         unsigned int num_ent;
     117        size_t fill;
    108118        /** Size of the array */
    109         unsigned int arr_size;
     119        size_t arr_size;
    110120        /** Resizable partition array */
    111121        gpt_entry_t * part_array;
     
    132142extern gpt_partitions_t * gpt_read_partitions(gpt_t * gpt);
    133143extern int                                gpt_write_partitions(gpt_partitions_t * parts, gpt_t * header, service_id_t dev_handle);
    134 extern gpt_partitions_t * gpt_add_partition(gpt_partitions_t * parts, gpt_part_t * partition);
    135 extern gpt_partitions_t * gpt_remove_partition(gpt_partitions_t * parts, size_t idx);
    136 extern void                       gpt_set_part_type(gpt_part_t * p, int type);
     144extern gpt_part_t *               gpt_alloc_partition(gpt_partitions_t * parts);
     145extern int                                gpt_add_partition(gpt_partitions_t * parts, gpt_part_t * partition);
     146extern int                                gpt_remove_partition(gpt_partitions_t * parts, size_t idx);
     147extern size_t                     gpt_get_part_type(gpt_part_t * p);
     148extern void                       gpt_set_part_type(gpt_part_t * p, size_t type);
     149extern char *                     gpt_get_part_name(gpt_entry_t * p);
    137150extern void                       gpt_set_part_name(gpt_entry_t * p, char * name[], size_t length);
     151extern bool                               gpt_get_flag(gpt_part_t * p, GPT_ATTR flag);
     152extern void                               gpt_set_flag(gpt_part_t * p, GPT_ATTR flag, bool value);
     153
     154#define gpt_foreach(parts, i, iterator) \
     155                for(size_t i = 0, gpt_part_t * iterator = parts->part_array;
     156                    i < parts->fill; i++, iterator++)
    138157
    139158extern void gpt_free_gpt(gpt_t * gpt);
  • uspace/lib/mbr/Makefile

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

    r271e24a r30440ed  
    150150                        return NULL;
    151151                }
    152                 list_append(&(p->link), &(parts->list));
     152                //list_append(&(p->link), &(parts->list));
    153153                p->ebr = NULL;
    154                 if (decode_part(&(mbr->raw_data.pte[i]), p, 0))
     154                if (decode_part(&(mbr->raw_data.pte[i]), p, 0)) {
    155155                        ext = p;
     156                        parts->l_extended = list_last(&(parts->list));
     157                }
     158                mbr_set_flag(p, ST_LOGIC, false);
     159                mbr_add_partition(parts, p);
    156160        }
    157161
     
    183187       
    184188        br_block_t * last_ebr = NULL;
    185 
    186 
     189        link_t * it;
     190       
     191        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);
     192       
    187193        rc = block_init(EXCHANGE_ATOMIC, dev_handle, 512);
    188194        if (rc != EOK) {
     195                DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc));
    189196                return rc;
    190197        }
     
    193200                goto no_extended;
    194201
    195         aoff64_t addr = ext->start_addr;
     202        uint32_t base = ext->start_addr;
     203        uint32_t addr = base;
     204        uint32_t prev_addr;
    196205        mbr_part_t * prev_part = NULL;
    197206
    198         list_foreach(parts->list, it) {
    199                 p = list_get_instance(it, mbr_part_t, link);
     207        list_foreach(parts->list, iter) {
     208                p = list_get_instance(iter, mbr_part_t, link);
    200209                if (mbr_get_flag(p, ST_LOGIC)) {
    201210                        // writing logical partition
    202 
     211                       
     212                        if (p->start_addr < base || p->start_addr + p->length > base + ext->length) {
     213                                // out of bounds
     214                                return EINVAL;
     215                        }
     216                       
     217                       
    203218                        if (p->ebr == NULL) {
    204219                                p->ebr = alloc_br();
     
    210225                        }
    211226
    212 
    213                         encode_part(p, &(p->ebr->pte[0]), addr);
     227                       
     228                       
     229                       
    214230                        if (prev_part != NULL) {
    215                                 encode_part(p, &(prev_part->ebr->pte[1]), ext->start_addr);
    216                                 rc = block_write_direct(dev_handle, p->start_addr, 1, prev_part->ebr);
    217                                 if (rc != EOK)
     231                                // addr is the address of EBR
     232                                addr = p->start_addr - base;
     233                                // base-1 means start_lba+1
     234                                encode_part(p, &(p->ebr->pte[0]), addr - 1);
     235                                encode_part(p, &(prev_part->ebr->pte[1]), base);
     236                                rc = block_write_direct(dev_handle, prev_addr, 1, prev_part->ebr);
     237                                if (rc != EOK) {
     238                                        DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc));
    218239                                        goto end;
     240                                }
     241                        } else {
     242                                // addr is the address of EBR
     243                                addr = base;
     244                                // base-1 means start_lba+1
     245                                encode_part(p, &(p->ebr->pte[0]), base - 1);
    219246                        }
    220247                       
    221                         addr = p->start_addr;
     248                        //addr = p->start_addr;
     249                        prev_addr = addr;
    222250                        prev_part = p;
    223251                } else {
     
    261289        }
    262290       
    263         if (rc != EOK)
     291        if (rc != EOK) {
     292                DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc));
    264293                goto end;
     294        }
    265295
    266296        goto skip;
     
    268298no_extended:
    269299
    270         list_foreach(parts->list, it) {
     300        /*list_foreach(parts->list, it) {
    271301                p = list_get_instance(it, mbr_part_t, link);
    272302                if (mbr_get_flag(p, ST_LOGIC)) {
     
    282312                        ++i;
    283313                }
    284         }
     314        }*/
     315       
     316        it = parts->list.head.next;
     317        for (i = 0; i < N_PRIMARY; i++) {
     318                if (it != &parts->list.head) {
     319                        p = list_get_instance(it, mbr_part_t, link);
     320                        if (mbr_get_flag(p, ST_LOGIC)) {
     321                                // extended does not exist, fail
     322                                return EINVAL;
     323                        } else {
     324                                // writing primary partition
     325                                if (i >= 4)
     326                                        return EINVAL;
     327
     328                                encode_part(p, &(mbr->raw_data.pte[i]), 0);
     329
     330                        }
     331                       
     332                        it = it->next;
     333                } else {
     334                        encode_part(NULL, &(mbr->raw_data.pte[i]), 0);
     335                }
     336        }
     337       
    285338
    286339skip:
    287340        rc = block_write_direct(dev_handle, 0, 1, &(mbr->raw_data));
    288         if (rc != EOK)
     341        if (rc != EOK) {
     342                DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc));
    289343                goto end;
     344        }
    290345
    291346        /*
     
    382437
    383438        list_initialize(&(parts->list));
     439       
     440        parts->n_primary = 0;
     441        parts->n_logical = 0;
     442        parts->l_extended = NULL;
    384443
    385444        return parts;
     
    387446
    388447/** Add partition */
    389 int mbr_add_partition(mbr_partitions_t * parts, mbr_part_t * partition)
    390 {
    391         list_append(&(partition->link), &(parts->list));
     448int mbr_add_partition(mbr_partitions_t * parts, mbr_part_t * p)
     449{
     450        list_append(&(p->link), &(parts->list));
     451        if (mbr_get_flag(p, ST_LOGIC)) {
     452                parts->n_logical += 1;
     453        } else {
     454                parts->n_primary += 1;
     455        }
     456        /* if we're adding new logical partition, we need 1 sector for the EBR
     457         * for that partition (including the next one); we'd better make sure here
     458         * before writing */
     459        if (mbr_get_flag(p, ST_LOGIC) && p->ebr == NULL) {
     460                p->start_addr += 1;
     461                p->length -= 1;
     462        }
     463        //FIXME: we can have multiple extended partitions! :-(
     464       
    392465        return EOK;
    393466}
     
    396469int mbr_remove_partition(mbr_partitions_t * parts, size_t idx)
    397470{
     471        DEBUG_PRINT_1(LIBMBR_NAME "Removing partition: %d\n", idx);
    398472        link_t * l = list_nth(&(parts->list), idx);
     473        if (l == parts->l_extended) {
     474                DEBUG_PRINT_0(LIBMBR_NAME "Removing extended partition.\n");
     475                parts->l_extended = NULL;
     476        }
    399477        list_remove(l);
    400478        mbr_part_t * p = list_get_instance(l, mbr_part_t, link);
     479        if (mbr_get_flag(p, ST_LOGIC)) {
     480                parts->n_logical -= 1;
     481        } else {
     482                parts->n_primary -= 1;
     483        }
     484       
     485       
    401486        mbr_free_partition(p);
    402487       
     
    448533                mbr_free_partition(p);
    449534        }
     535       
     536        free(parts);
    450537}
    451538
     
    465552}
    466553
    467 /** Parse partition entry to mbr_part_t */
     554/** Parse partition entry to mbr_part_t
     555 * @return              returns 1, if extended partition, 0 otherwise
     556 * */
    468557static int decode_part(pt_entry_t * src, mbr_part_t * trgt, uint32_t base)
    469558{
     
    480569}
    481570
    482 /** Parse MBR contents to mbr_part_t list
    483  * parameter 'p' is allocated for only used primary partitions
    484  */
     571/** Parse MBR contents to mbr_part_t list */
    485572static int decode_logical(mbr_t * mbr, mbr_partitions_t * parts, mbr_part_t * ext)
    486573{
     
    496583
    497584
    498         uint32_t addr = ext->start_addr;
    499         //uint32_t base = ext->start_addr;
     585        uint32_t base = ext->start_addr;
     586        uint32_t addr = base;
    500587        br_block_t * ebr;
    501588
     
    503590        if (rc != EOK)
    504591                return rc;
    505 
    506         do {
     592       
     593        ebr = alloc_br();
     594        if (ebr == NULL) {
     595                rc = ENOMEM;
     596                goto end;
     597        }
     598
     599        rc = block_read_direct(mbr->device, addr, 1, ebr);
     600        if (rc != EOK) {
     601                goto free_ebr_end;
     602        }
     603
     604        if (uint16_t_le2host(ebr->signature) != BR_SIGNATURE) {
     605                rc = EINVAL;
     606                goto free_ebr_end;
     607        }
     608       
     609        if (ebr->pte[0].ptype == PT_UNUSED) {
     610                rc = EOK;
     611                goto free_ebr_end;
     612        }
     613       
     614        p = mbr_alloc_partition();
     615        if (p == NULL) {
     616                rc = ENOMEM;
     617                goto free_ebr_end;
     618        }
     619       
     620
     621        decode_part(&(ebr->pte[0]), p, base);
     622        mbr_set_flag(p, ST_LOGIC, true);
     623        p->ebr = ebr;
     624        mbr_add_partition(parts, p);
     625
     626        addr = uint32_t_le2host(ebr->pte[1].first_lba) + base;
     627       
     628        while (ebr->pte[1].ptype != PT_UNUSED) {
    507629                ebr = alloc_br();
    508630                if (ebr == NULL) {
    509                         return ENOMEM;
     631                        rc = ENOMEM;
     632                        goto end;
    510633                }
    511634
    512635                rc = block_read_direct(mbr->device, addr, 1, ebr);
    513636                if (rc != EOK) {
    514                         return rc;
    515                 }
    516 
    517                 //FIXME: is this the right way?
     637                        goto free_ebr_end;
     638                }
     639
    518640                if (uint16_t_le2host(ebr->signature) != BR_SIGNATURE) {
    519                         return EINVAL;
     641                        rc = EINVAL;
     642                        goto free_ebr_end;
    520643                }
    521644
    522645                p = mbr_alloc_partition();
    523 
    524                 decode_part(&(ebr->pte[0]), p, addr);
     646                if (p == NULL) {
     647                        rc = ENOMEM;
     648                        goto free_ebr_end;
     649                }
     650
     651                decode_part(&(ebr->pte[0]), p, base);
    525652                mbr_set_flag(p, ST_LOGIC, true);
    526653                p->ebr = ebr;
    527654                mbr_add_partition(parts, p);
    528655
    529                 //TODO: Check this code
    530                 addr = ebr->pte[1].first_lba + ext->start_addr;
    531         } while (ebr->pte[1].ptype != PT_UNUSED);
    532 
    533 
     656                addr = uint32_t_le2host(ebr->pte[1].first_lba) + base;
     657        }
     658       
     659        rc = EOK;
     660       
     661free_ebr_end:
     662        free(ebr);
     663       
     664end:
    534665        block_fini(mbr->device);
    535666
    536         return EOK;
     667        return rc;
    537668}
    538669
     
    543674                trgt->status = mbr_get_flag(src, ST_BOOT) ? B_ACTIVE : B_INACTIVE;
    544675                trgt->ptype = src->type;
    545                 trgt->first_lba = host2uint32_t_le(src->start_addr - base + 63); //63 sectors skipped
    546                 trgt->length = host2uint32_t_le(src->length - 64);      //63 + 1 (EBR)
     676                trgt->first_lba = host2uint32_t_le(src->start_addr - base);
     677                trgt->length = host2uint32_t_le(src->length);
    547678        } else {
    548679                trgt->status = 0;
  • uspace/lib/mbr/libmbr.h

    r271e24a r30440ed  
    3939
    4040#define LIBMBR_NAME     "libmbr"
     41
     42#ifdef DEBUG_CONFIG
     43#include <stdio.h>
     44#include <str_error.h>
     45#define DEBUG_PRINT_0(str) \
     46        printf("%s:%d: " str, __FILE__, __LINE__)
     47#define DEBUG_PRINT_1(str, arg1) \
     48        printf("%s:%d: " str, __FILE__, __LINE__, arg1)
     49#define DEBUG_PRINT_2(str, arg1, arg2) \
     50        printf("%s:%d: " str, __FILE__, __LINE__, arg1, arg2)
     51#define DEBUG_PRINT_3(str, arg1, arg2, arg3) \
     52        printf("%s:%d: " str, __FILE__, __LINE__, arg1, arg2, arg3)
     53#else
     54#define DEBUG_PRINT_0(str)
     55#define DEBUG_PRINT_1(str, arg1)
     56#define DEBUG_PRINT_2(str, arg1, arg2)
     57#define DEBUG_PRINT_3(str, arg1, arg2, arg3)
     58#endif
    4159
    4260/** Number of primary partition records */
     
    105123        /** Device where the data are from */
    106124        service_id_t device;
    107         /** Pointer to partition list */
    108         //list of partitions;   //if we keep this in here, we should free() it in mbr_free_mbr()
    109125} mbr_t;
    110126
    111127
    112 //FIXME: make mbr_partitions_t as the linked list for keeping the same interface as with GPT
    113128/** Partition */
    114129typedef struct mbr_part {
     
    127142} mbr_part_t;
    128143
     144/** Partition list structure */
    129145typedef struct mbr_parts {
    130146        /** Number of primary partitions */
     
    138154} mbr_partitions_t;
    139155
     156/** Both header and partition list */
    140157typedef struct mbr_table {
    141158        mbr_t * mbr;
     
    151168extern int mbr_is_mbr(mbr_t * mbr);
    152169
    153 /** Read/Write/Set MBR partitions. */
     170/** Read/Write/Set MBR partitions.
     171 * NOTE: Writing partitions writes the complete header as well. */
    154172extern mbr_partitions_t * mbr_read_partitions(mbr_t * mbr);
    155173extern int                      mbr_write_partitions(mbr_partitions_t * parts, mbr_t * mbr, service_id_t dev_handle);
Note: See TracChangeset for help on using the changeset viewer.