Changeset 603c1d1f in mainline for uspace/lib/label/src/gpt.c


Ignore:
Timestamp:
2015-07-05T18:53:00Z (9 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
bf7ddde
Parents:
99c23405
Message:

Persistent partition table creation and destruction.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/label/src/gpt.c

    r99c23405 r603c1d1f  
    120120        }
    121121
    122         rc = block_read_direct(sid, GPT_HDR_BA, 1, gpt_hdr[0]);
     122        rc = block_read_direct(sid, gpt_hdr_ba, 1, gpt_hdr[0]);
    123123        if (rc != EOK) {
    124124                rc = EIO;
     
    200200        label->ops = &gpt_label_ops;
    201201        label->ltype = lt_gpt;
    202         label->svcid = sid;
     202        label->svc_id = sid;
    203203        label->ablock0 = ba_min;
    204204        label->anblocks = ba_max - ba_min + 1;
     
    206206        label->block_size = bsize;
    207207
     208        label->lt.gpt.hdr_ba[0] = gpt_hdr_ba;
     209        label->lt.gpt.hdr_ba[1] = h1ba;
    208210        label->lt.gpt.ptable_ba[0] = ptba[0];
    209211        label->lt.gpt.ptable_ba[1] = ptba[1];
     
    222224static int gpt_create(service_id_t sid, label_t **rlabel)
    223225{
    224         return EOK;
     226        label_t *label = NULL;
     227        gpt_header_t *gpt_hdr = NULL;
     228        uint8_t *etable = NULL;
     229        size_t bsize;
     230        uint32_t num_entries;
     231        uint32_t esize;
     232        uint64_t ptba[2];
     233        uint64_t hdr_ba[2];
     234        uint64_t pt_blocks;
     235        uint64_t ba_min, ba_max;
     236        aoff64_t nblocks;
     237        uint64_t resv_blocks;
     238        int i, j;
     239        int rc;
     240
     241        rc = block_get_bsize(sid, &bsize);
     242        if (rc != EOK) {
     243                rc = EIO;
     244                goto error;
     245        }
     246
     247        if (bsize < 512 || (bsize % 512) != 0) {
     248                rc = EINVAL;
     249                goto error;
     250        }
     251
     252        rc = block_get_nblocks(sid, &nblocks);
     253        if (rc != EOK) {
     254                rc = EIO;
     255                goto error;
     256        }
     257
     258        /* Number of blocks of a partition table */
     259        pt_blocks = gpt_ptable_min_size / bsize;
     260        /* Minimum number of reserved (not allocatable) blocks */
     261        resv_blocks = 3 + 2 * pt_blocks;
     262
     263        if (nblocks <= resv_blocks) {
     264                rc = ENOSPC;
     265                goto error;
     266        }
     267
     268        hdr_ba[0] = gpt_hdr_ba;
     269        hdr_ba[1] = nblocks - 1;
     270        ptba[0] = 2;
     271        ptba[1] = nblocks - 1 - pt_blocks;
     272        ba_min = ptba[0] + pt_blocks;
     273        ba_max = ptba[1] - 1;
     274        esize = sizeof(gpt_entry_t);
     275
     276        num_entries = pt_blocks * bsize / sizeof(gpt_entry_t);
     277
     278        for (i = 0; i < 2; i++) {
     279                gpt_hdr = calloc(1, bsize);
     280                if (gpt_hdr == NULL) {
     281                        rc = ENOMEM;
     282                        goto error;
     283                }
     284
     285                for (j = 0; j < 8; ++j)
     286                        gpt_hdr->efi_signature[j] = efi_signature[j];
     287                gpt_hdr->revision = host2uint32_t_le(gpt_revision);
     288                gpt_hdr->header_size = host2uint32_t_le(sizeof(gpt_header_t));
     289                gpt_hdr->header_crc32 = 0; /* XXX */
     290                gpt_hdr->my_lba = host2uint64_t_le(hdr_ba[i]);
     291                gpt_hdr->alternate_lba = host2uint64_t_le(hdr_ba[1 - i]);
     292                gpt_hdr->first_usable_lba = host2uint64_t_le(ba_min);
     293                gpt_hdr->last_usable_lba = host2uint64_t_le(ba_max);
     294                //gpt_hdr->disk_guid
     295                gpt_hdr->entry_lba = host2uint64_t_le(ptba[i]);
     296                gpt_hdr->num_entries = host2uint32_t_le(num_entries);
     297                gpt_hdr->entry_size = host2uint32_t_le(esize);
     298                gpt_hdr->pe_array_crc32 = 0; /* XXXX */
     299
     300                rc = block_write_direct(sid, hdr_ba[i], 1, gpt_hdr);
     301                if (rc != EOK) {
     302                        rc = EIO;
     303                        goto error;
     304                }
     305
     306                free(gpt_hdr);
     307                gpt_hdr = NULL;
     308
     309                etable = calloc(num_entries, esize);
     310                if (etable == NULL) {
     311                        rc = ENOMEM;
     312                        goto error;
     313                }
     314
     315                rc = block_write_direct(sid, ptba[i], pt_blocks, etable);
     316                if (rc != EOK) {
     317                        rc = EIO;
     318                        goto error;
     319                }
     320
     321                free(etable);
     322                etable = 0;
     323        }
     324
     325        label = calloc(1, sizeof(label_t));
     326        if (label == NULL)
     327                return ENOMEM;
     328
     329        list_initialize(&label->parts);
     330
     331        label->ops = &gpt_label_ops;
     332        label->ltype = lt_gpt;
     333        label->svc_id = sid;
     334        label->ablock0 = ba_min;
     335        label->anblocks = ba_max - ba_min + 1;
     336        label->pri_entries = num_entries;
     337        label->block_size = bsize;
     338
     339        label->lt.gpt.hdr_ba[0] = hdr_ba[0];
     340        label->lt.gpt.hdr_ba[1] = hdr_ba[1];
     341        label->lt.gpt.ptable_ba[0] = ptba[0];
     342        label->lt.gpt.ptable_ba[1] = ptba[1];
     343        label->lt.gpt.esize = esize;
     344
     345        *rlabel = label;
     346        return EOK;
     347error:
     348        free(etable);
     349        free(gpt_hdr);
     350        free(label);
     351        return rc;
    225352}
    226353
    227354static void gpt_close(label_t *label)
    228355{
     356        label_part_t *part;
     357
     358        part = gpt_part_first(label);
     359        while (part != NULL) {
     360                list_remove(&part->llabel);
     361                free(part);
     362                part = gpt_part_first(label);
     363        }
     364
    229365        free(label);
    230366}
     
    232368static int gpt_destroy(label_t *label)
    233369{
    234         return EOK;
     370        gpt_header_t *gpt_hdr = NULL;
     371        uint8_t *etable = NULL;
     372        label_part_t *part;
     373        uint64_t pt_blocks;
     374        int i;
     375        int rc;
     376
     377        part = gpt_part_first(label);
     378        if (part != NULL) {
     379                rc = ENOTEMPTY;
     380                goto error;
     381        }
     382
     383        pt_blocks = label->pri_entries * label->lt.gpt.esize /
     384            label->block_size;
     385
     386        for (i = 0; i < 2; i++) {
     387                gpt_hdr = calloc(1, label->block_size);
     388                if (gpt_hdr == NULL) {
     389                        rc = ENOMEM;
     390                        goto error;
     391                }
     392
     393                rc = block_write_direct(label->svc_id, label->lt.gpt.hdr_ba[i],
     394                    1, gpt_hdr);
     395                if (rc != EOK) {
     396                        rc = EIO;
     397                        goto error;
     398                }
     399
     400                free(gpt_hdr);
     401                gpt_hdr = NULL;
     402
     403                etable = calloc(label->pri_entries, label->lt.gpt.esize);
     404                if (etable == NULL) {
     405                        rc = ENOMEM;
     406                        goto error;
     407                }
     408
     409                rc = block_write_direct(label->svc_id,
     410                    label->lt.gpt.ptable_ba[i], pt_blocks, etable);
     411                if (rc != EOK) {
     412                        rc = EIO;
     413                        goto error;
     414                }
     415
     416                free(etable);
     417                etable = 0;
     418        }
     419
     420        free(label);
     421        return EOK;
     422error:
     423        return rc;
    235424}
    236425
     
    426615                    pos / label->block_size;
    427616
    428                 rc = block_read_direct(label->svcid, ba, 1, buf);
     617                rc = block_read_direct(label->svc_id, ba, 1, buf);
    429618                if (rc != EOK) {
    430619                        rc = EIO;
     
    436625                *e = *pte;
    437626
    438                 rc = block_write_direct(label->svcid, ba, 1, buf);
     627                rc = block_write_direct(label->svc_id, ba, 1, buf);
    439628                if (rc != EOK) {
    440629                        rc = EIO;
Note: See TracChangeset for help on using the changeset viewer.