Changeset 603c1d1f in mainline for uspace/lib/label/src


Ignore:
Timestamp:
2015-07-05T18:53:00Z (10 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.

Location:
uspace/lib/label/src
Files:
3 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;
  • uspace/lib/label/src/label.c

    r99c23405 r603c1d1f  
    4141
    4242#include "gpt.h"
     43#include "mbr.h"
    4344
    4445static label_ops_t *probe_list[] = {
    4546        &gpt_label_ops,
     47        &mbr_label_ops,
    4648        NULL
    4749};
     
    7274                break;
    7375        case lt_mbr:
    74                 ops = NULL;
     76                ops = &mbr_label_ops;
    7577                break;
    7678        }
  • uspace/lib/label/src/mbr.c

    r99c23405 r603c1d1f  
    142142        label->ops = &mbr_label_ops;
    143143        label->ltype = lt_mbr;
     144        label->svc_id = sid;
     145        label->block_size = bsize;
    144146        label->ablock0 = mbr_ablock0;
    145147        label->anblocks = nblocks - mbr_ablock0;
     
    155157static int mbr_create(service_id_t sid, label_t **rlabel)
    156158{
    157         return EOK;
     159        label_t *label = NULL;
     160        mbr_br_block_t *mbr = NULL;
     161        aoff64_t nblocks;
     162        size_t bsize;
     163        int i;
     164        int rc;
     165
     166        rc = block_get_bsize(sid, &bsize);
     167        if (rc != EOK) {
     168                rc = EIO;
     169                goto error;
     170        }
     171
     172        rc = block_get_nblocks(sid, &nblocks);
     173        if (rc != EOK) {
     174                rc = EIO;
     175                goto error;
     176        }
     177
     178        mbr = calloc(1, bsize);
     179        if (mbr == NULL) {
     180                rc = ENOMEM;
     181                goto error;
     182        }
     183
     184        label = calloc(1, sizeof(label_t));
     185        if (label == NULL)
     186                return ENOMEM;
     187
     188        list_initialize(&label->parts);
     189
     190        mbr->media_id = 0;
     191        mbr->pad0 = 0;
     192        for (i = 0; i < mbr_nprimary; i++)
     193                mbr_unused_pte(&mbr->pte[i]);
     194        mbr->signature = host2uint16_t_le(mbr_br_signature);
     195
     196        rc = block_write_direct(sid, mbr_ba, 1, mbr);
     197        if (rc != EOK) {
     198                rc = EIO;
     199                goto error;
     200        }
     201
     202        free(mbr);
     203        mbr = NULL;
     204
     205        label->ops = &mbr_label_ops;
     206        label->ltype = lt_mbr;
     207        label->block_size = bsize;
     208        label->svc_id = sid;
     209        label->ablock0 = mbr_ablock0;
     210        label->anblocks = nblocks - mbr_ablock0;
     211        label->pri_entries = mbr_nprimary;
     212
     213        *rlabel = label;
     214        return EOK;
     215error:
     216        free(mbr);
     217        free(label);
     218        return rc;
    158219}
    159220
    160221static void mbr_close(label_t *label)
    161222{
     223        label_part_t *part;
     224
     225        part = mbr_part_first(label);
     226        while (part != NULL) {
     227                list_remove(&part->llabel);
     228                free(part);
     229
     230                part = mbr_part_first(label);
     231        }
     232
    162233        free(label);
    163234}
     
    165236static int mbr_destroy(label_t *label)
    166237{
    167         return EOK;
     238        mbr_br_block_t *mbr = NULL;
     239        label_part_t *part;
     240        int rc;
     241
     242        part = mbr_part_first(label);
     243        if (part != NULL) {
     244                rc = ENOTEMPTY;
     245                goto error;
     246        }
     247
     248        mbr = calloc(1, label->block_size);
     249        if (mbr == NULL) {
     250                rc = ENOMEM;
     251                goto error;
     252        }
     253
     254        rc = block_write_direct(label->svc_id, mbr_ba, 1, mbr);
     255        if (rc != EOK) {
     256                rc = EIO;
     257                goto error;
     258        }
     259
     260        free(mbr);
     261        mbr = NULL;
     262
     263        free(label);
     264        return EOK;
     265error:
     266        free(mbr);
     267        return rc;
    168268}
    169269
     
    340440                return ENOMEM;
    341441
    342         rc = block_read_direct(label->svcid, mbr_ba, 1, br);
     442        rc = block_read_direct(label->svc_id, mbr_ba, 1, br);
    343443        if (rc != EOK) {
    344444                rc = EIO;
     
    348448        br->pte[index] = *pte;
    349449
    350         rc = block_write_direct(label->svcid, mbr_ba, 1, br);
     450        rc = block_write_direct(label->svc_id, mbr_ba, 1, br);
    351451        if (rc != EOK) {
    352452                rc = EIO;
Note: See TracChangeset for help on using the changeset viewer.