Changeset 6317b33 in mainline for uspace/lib


Ignore:
Timestamp:
2013-06-25T00:29:00Z (13 years ago)
Author:
Dominik Taborsky (AT DOT) <brembyseznamcz>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/fix-logger-deadlock, topic/msim-upgrade, topic/simplify-dev-export
Children:
52f2c89
Parents:
cb328ab (diff), 1c8bfe8 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

hdisk, libmbr and libgpt updates

Location:
uspace/lib
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/gpt/global.c

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

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

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

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

    rcb328ab r6317b33  
    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.