Changeset 99c23405 in mainline for uspace/lib/label/src/gpt.c
- Timestamp:
- 2015-07-04T15:18:06Z (9 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 603c1d1f
- Parents:
- 6bc542b
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/label/src/gpt.c
r6bc542b r99c23405 54 54 static int gpt_part_destroy(label_part_t *); 55 55 56 static void gpt_unused_pte(gpt_entry_t *); 57 static int gpt_part_to_pte(label_part_t *, gpt_entry_t *); 56 58 static int gpt_pte_to_part(label_t *, gpt_entry_t *, int); 59 static int gpt_pte_update(label_t *, gpt_entry_t *, int); 57 60 58 61 const uint8_t efi_signature[8] = { … … 77 80 { 78 81 label_t *label = NULL; 79 gpt_header_t *gpt_hdr = NULL;82 gpt_header_t *gpt_hdr[2]; 80 83 gpt_entry_t *eptr; 81 84 uint8_t *etable = NULL; … … 84 87 uint32_t esize; 85 88 uint32_t bcnt; 86 uint64_t ba; 89 uint64_t ptba[2]; 90 uint64_t h1ba; 87 91 uint32_t entry; 88 92 uint64_t ba_min, ba_max; 89 int i ;93 int i, j; 90 94 int rc; 91 95 96 gpt_hdr[0] = NULL; 97 gpt_hdr[1] = NULL; 98 92 99 rc = block_get_bsize(sid, &bsize); 93 100 if (rc != EOK) { … … 101 108 } 102 109 103 gpt_hdr = calloc(1, bsize);104 if (gpt_hdr == NULL) {110 gpt_hdr[0] = calloc(1, bsize); 111 if (gpt_hdr[0] == NULL) { 105 112 rc = ENOMEM; 106 113 goto error; 107 114 } 108 115 109 rc = block_read_direct(sid, GPT_HDR_BA, 1, gpt_hdr); 116 gpt_hdr[1] = calloc(1, bsize); 117 if (gpt_hdr[1] == NULL) { 118 rc = ENOMEM; 119 goto error; 120 } 121 122 rc = block_read_direct(sid, GPT_HDR_BA, 1, gpt_hdr[0]); 123 if (rc != EOK) { 124 rc = EIO; 125 goto error; 126 } 127 128 h1ba = uint64_t_le2host(gpt_hdr[0]->alternate_lba); 129 130 rc = block_read_direct(sid, h1ba, 1, gpt_hdr[1]); 110 131 if (rc != EOK) { 111 132 rc = EIO; … … 119 140 list_initialize(&label->parts); 120 141 121 for (i = 0; i < 8; ++i) { 122 if (gpt_hdr->efi_signature[i] != efi_signature[i]) { 123 rc = EINVAL; 124 goto error; 142 for (j = 0; j < 2; j++) { 143 for (i = 0; i < 8; ++i) { 144 if (gpt_hdr[j]->efi_signature[i] != efi_signature[i]) { 145 rc = EINVAL; 146 goto error; 147 } 125 148 } 126 149 } 127 150 128 num_entries = uint32_t_le2host(gpt_hdr ->num_entries);129 esize = uint32_t_le2host(gpt_hdr ->entry_size);151 num_entries = uint32_t_le2host(gpt_hdr[0]->num_entries); 152 esize = uint32_t_le2host(gpt_hdr[0]->entry_size); 130 153 bcnt = (num_entries + esize - 1) / esize; 131 ba = uint64_t_le2host(gpt_hdr->entry_lba); 132 ba_min = uint64_t_le2host(gpt_hdr->first_usable_lba); 133 ba_max = uint64_t_le2host(gpt_hdr->last_usable_lba); 154 ptba[0] = uint64_t_le2host(gpt_hdr[0]->entry_lba); 155 ptba[1] = uint64_t_le2host(gpt_hdr[1]->entry_lba); 156 ba_min = uint64_t_le2host(gpt_hdr[0]->first_usable_lba); 157 ba_max = uint64_t_le2host(gpt_hdr[0]->last_usable_lba); 134 158 135 159 if (num_entries < 1) { … … 154 178 } 155 179 156 rc = block_read_direct(sid, ba, bcnt, etable);180 rc = block_read_direct(sid, ptba[0], bcnt, etable); 157 181 if (rc != EOK) { 158 182 rc = EIO; … … 169 193 free(etable); 170 194 etable = NULL; 171 free(gpt_hdr); 172 gpt_hdr = NULL; 195 free(gpt_hdr[0]); 196 gpt_hdr[0] = NULL; 197 free(gpt_hdr[1]); 198 gpt_hdr[1] = NULL; 173 199 174 200 label->ops = &gpt_label_ops; 175 201 label->ltype = lt_gpt; 202 label->svcid = sid; 176 203 label->ablock0 = ba_min; 177 204 label->anblocks = ba_max - ba_min + 1; 205 label->pri_entries = num_entries; 206 label->block_size = bsize; 207 208 label->lt.gpt.ptable_ba[0] = ptba[0]; 209 label->lt.gpt.ptable_ba[1] = ptba[1]; 210 label->lt.gpt.esize = esize; 211 178 212 *rlabel = label; 179 213 return EOK; 180 214 error: 181 215 free(etable); 182 free(gpt_hdr); 216 free(gpt_hdr[0]); 217 free(gpt_hdr[1]); 183 218 free(label); 184 219 return rc; … … 243 278 { 244 279 label_part_t *part; 280 gpt_entry_t pte; 281 int rc; 245 282 246 283 part = calloc(1, sizeof(label_part_t)); 247 if (part == NULL) 248 return ENOMEM; 284 if (part == NULL) { 285 rc = ENOMEM; 286 goto error; 287 } 249 288 250 289 /* XXX Verify index, block0, nblocks */ 251 290 291 if (pspec->index < 1 || pspec->index > label->pri_entries) { 292 rc = EINVAL; 293 goto error; 294 } 295 296 /* XXX Check if index is used */ 297 298 part->label = label; 252 299 part->index = pspec->index; 253 300 part->block0 = pspec->block0; 254 301 part->nblocks = pspec->nblocks; 255 256 /* XXX Modify partition table */ 257 258 part->label = label; 302 part->ptype = pspec->ptype; 303 304 /* Prepare partition table entry */ 305 rc = gpt_part_to_pte(part, &pte); 306 if (rc != EOK) { 307 rc = EINVAL; 308 goto error; 309 } 310 311 /* Modify partition tables */ 312 rc = gpt_pte_update(label, &pte, pspec->index - 1); 313 if (rc != EOK) { 314 rc = EIO; 315 goto error; 316 } 317 259 318 list_append(&part->llabel, &label->parts); 260 319 261 320 *rpart = part; 262 321 return EOK; 322 error: 323 free(part); 324 return rc; 263 325 } 264 326 265 327 static int gpt_part_destroy(label_part_t *part) 266 328 { 267 return ENOTSUP; 329 gpt_entry_t pte; 330 int rc; 331 332 /* Prepare unused partition table entry */ 333 gpt_unused_pte(&pte); 334 335 /* Modify partition tables */ 336 rc = gpt_pte_update(part->label, &pte, part->index - 1); 337 if (rc != EOK) 338 return EIO; 339 340 list_remove(&part->llabel); 341 free(part); 342 return EOK; 343 } 344 345 static void gpt_unused_pte(gpt_entry_t *pte) 346 { 347 memset(pte, 0, sizeof(gpt_entry_t)); 348 } 349 350 static int gpt_part_to_pte(label_part_t *part, gpt_entry_t *pte) 351 { 352 uint64_t eblock; 353 354 eblock = part->block0 + part->nblocks - 1; 355 if (eblock < part->block0) 356 return EINVAL; 357 358 memset(pte, 0, sizeof(gpt_entry_t)); 359 pte->part_type[0] = 0x12; 360 pte->part_id[0] = 0x34; 361 pte->start_lba = host2uint64_t_le(part->block0); 362 pte->end_lba = host2uint64_t_le(eblock); 363 // pte->attributes 364 // pte->part_name 365 return EOK; 268 366 } 269 367 … … 301 399 } 302 400 401 /** Update partition table entry at specified index. 402 * 403 * Replace partition entry at index @a index with the contents of 404 * @a pte. 405 */ 406 static int gpt_pte_update(label_t *label, gpt_entry_t *pte, int index) 407 { 408 size_t pos; 409 size_t offs; 410 uint64_t ba; 411 uint8_t *buf; 412 gpt_entry_t *e; 413 int i; 414 int rc; 415 416 pos = index * label->lt.gpt.esize; 417 offs = pos % label->block_size; 418 419 buf = calloc(1, label->block_size); 420 if (buf == NULL) 421 return ENOMEM; 422 423 /* For both partition tables: read, modify, write */ 424 for (i = 0; i < 2; i++) { 425 ba = label->lt.gpt.ptable_ba[i] + 426 pos / label->block_size; 427 428 rc = block_read_direct(label->svcid, ba, 1, buf); 429 if (rc != EOK) { 430 rc = EIO; 431 goto error; 432 } 433 434 /* Replace single entry */ 435 e = (gpt_entry_t *)(&buf[offs]); 436 *e = *pte; 437 438 rc = block_write_direct(label->svcid, ba, 1, buf); 439 if (rc != EOK) { 440 rc = EIO; 441 goto error; 442 } 443 } 444 445 free(buf); 446 return EOK; 447 error: 448 free(buf); 449 return rc; 450 } 451 303 452 /** @} 304 453 */
Note:
See TracChangeset
for help on using the changeset viewer.