Changeset 99c23405 in mainline
- 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
- Location:
- uspace
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/fdisk/src/fdisk.c
r6bc542b r99c23405 671 671 if (part->index > nidx) 672 672 break; 673 nidx = part->index ;673 nidx = part->index + 1; 674 674 link = list_next(link, &dev->parts_idx); 675 675 } -
uspace/lib/label/include/types/liblabel.h
r6bc542b r99c23405 94 94 /** Number of blocks */ 95 95 aoff64_t nblocks; 96 /** Partition type */ 97 uint64_t ptype; 96 98 }; 97 99 … … 108 110 }; 109 111 112 typedef struct { 113 uint64_t ptable_ba[2]; 114 size_t esize; 115 } label_gpt_t; 116 117 typedef struct { 118 } label_mbr_t; 119 110 120 /** Label instance */ 111 121 struct label { … … 114 124 /** Label type */ 115 125 label_type_t ltype; 126 /** Block device service ID */ 127 service_id_t svcid; 116 128 /** Partitions */ 117 129 list_t parts; /* of label_part_t */ … … 120 132 /** Number of blocks that can be allocated */ 121 133 aoff64_t anblocks; 134 /** Number of primary partition entries */ 135 int pri_entries; 136 /** Block size */ 137 size_t block_size; 138 union { 139 label_gpt_t gpt; 140 label_mbr_t mbr; 141 } lt; 122 142 }; 123 143 -
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 */ -
uspace/lib/label/src/mbr.c
r6bc542b r99c23405 54 54 static int mbr_part_destroy(label_part_t *); 55 55 56 static void mbr_unused_pte(mbr_pte_t *); 57 static int mbr_part_to_pte(label_part_t *, mbr_pte_t *); 56 58 static int mbr_pte_to_part(label_t *, mbr_pte_t *, int); 59 static int mbr_pte_update(label_t *, mbr_pte_t *, int); 57 60 58 61 label_ops_t mbr_label_ops = { … … 141 144 label->ablock0 = mbr_ablock0; 142 145 label->anblocks = nblocks - mbr_ablock0; 146 label->pri_entries = mbr_nprimary; 143 147 *rlabel = label; 144 148 return EOK; … … 207 211 { 208 212 label_part_t *part; 213 mbr_pte_t pte; 214 int rc; 209 215 210 216 part = calloc(1, sizeof(label_part_t)); … … 212 218 return ENOMEM; 213 219 220 /* XXX Verify index, block0, nblocks */ 221 222 if (pspec->index < 1 || pspec->index > label->pri_entries) { 223 rc = EINVAL; 224 goto error; 225 } 226 227 /* XXX Check if index is used */ 228 229 part->label = label; 214 230 part->index = pspec->index; 215 231 part->block0 = pspec->block0; 216 232 part->nblocks = pspec->nblocks; 217 218 part->label = label; 233 part->ptype = pspec->ptype; 234 235 rc = mbr_part_to_pte(part, &pte); 236 if (rc != EOK) { 237 rc = EINVAL; 238 goto error; 239 } 240 241 rc = mbr_pte_update(label, &pte, pspec->index - 1); 242 if (rc != EOK) { 243 rc = EIO; 244 goto error; 245 } 246 247 list_append(&part->llabel, &label->parts); 219 248 220 249 *rpart = part; 221 250 return EOK; 251 error: 252 free(part); 253 return rc; 222 254 } 223 255 224 256 static int mbr_part_destroy(label_part_t *part) 225 257 { 226 return ENOTSUP; 258 mbr_pte_t pte; 259 int rc; 260 261 /* Prepare unused partition table entry */ 262 mbr_unused_pte(&pte); 263 264 /* Modify partition table */ 265 rc = mbr_pte_update(part->label, &pte, part->index - 1); 266 if (rc != EOK) 267 return EIO; 268 269 list_remove(&part->llabel); 270 free(part); 271 return EOK; 272 } 273 274 static void mbr_unused_pte(mbr_pte_t *pte) 275 { 276 memset(pte, 0, sizeof(mbr_pte_t)); 277 } 278 279 static int mbr_part_to_pte(label_part_t *part, mbr_pte_t *pte) 280 { 281 if ((part->block0 >> 32) != 0) 282 return EINVAL; 283 if ((part->nblocks >> 32) != 0) 284 return EINVAL; 285 if ((part->ptype >> 8) != 0) 286 return EINVAL; 287 288 memset(pte, 0, sizeof(mbr_pte_t)); 289 pte->ptype = part->ptype; 290 pte->first_lba = host2uint32_t_le(part->block0); 291 pte->length = host2uint32_t_le(part->nblocks); 292 return EOK; 227 293 } 228 294 … … 260 326 } 261 327 328 /** Update partition table entry at specified index. 329 * 330 * Replace partition entry at index @a index with the contents of 331 * @a pte. 332 */ 333 static int mbr_pte_update(label_t *label, mbr_pte_t *pte, int index) 334 { 335 mbr_br_block_t *br; 336 int rc; 337 338 br = calloc(1, label->block_size); 339 if (br == NULL) 340 return ENOMEM; 341 342 rc = block_read_direct(label->svcid, mbr_ba, 1, br); 343 if (rc != EOK) { 344 rc = EIO; 345 goto error; 346 } 347 348 br->pte[index] = *pte; 349 350 rc = block_write_direct(label->svcid, mbr_ba, 1, br); 351 if (rc != EOK) { 352 rc = EIO; 353 goto error; 354 } 355 356 free(br); 357 return EOK; 358 error: 359 free(br); 360 return rc; 361 } 362 262 363 /** @} 263 364 */ -
uspace/srv/bd/vbd/disk.c
r6bc542b r99c23405 112 112 } 113 113 114 /** Add partition to our inventory based on liblabel partition structure */ 114 115 static int vbds_part_add(vbds_disk_t *disk, label_part_t *lpart, 115 116 vbds_part_t **rpart) … … 119 120 label_part_info_t lpinfo; 120 121 char *name; 121 int pno;122 122 int rc; 123 123 … … 132 132 133 133 /* XXX Proper service name */ 134 pno = list_count(&disk->parts); 135 rc = asprintf(&name, "%sp%u", disk->svc_name, pno); 134 rc = asprintf(&name, "%sp%u", disk->svc_name, lpart->index); 136 135 if (rc < 0) { 137 136 log_msg(LOG_DEFAULT, LVL_ERROR, "Out of memory."); … … 166 165 if (rpart != NULL) 167 166 *rpart = part; 167 return EOK; 168 } 169 170 /** Remove partition from our inventory leaving only the underlying liblabel 171 * partition structure. 172 */ 173 static int vbds_part_remove(vbds_part_t *part, label_part_t **rlpart) 174 { 175 label_part_t *lpart; 176 int rc; 177 178 log_msg(LOG_DEFAULT, LVL_NOTE, "vbds_part_remove(%p)", part); 179 180 lpart = part->lpart; 181 182 if (part->open_cnt > 0) 183 return EBUSY; 184 185 rc = loc_service_unregister((service_id_t)part->id); 186 if (rc != EOK) 187 return EIO; 188 189 list_remove(&part->ldisk); 190 list_remove(&part->lparts); 191 free(part); 192 193 if (rlpart != NULL) 194 *rlpart = lpart; 168 195 return EOK; 169 196 } … … 442 469 { 443 470 vbds_part_t *part; 471 vbds_disk_t *disk; 472 label_part_t *lpart; 444 473 int rc; 445 474 … … 448 477 return rc; 449 478 450 rc = label_part_destroy(part->lpart); 451 if (rc != EOK) 452 return rc; 453 454 list_remove(&part->ldisk); 455 list_remove(&part->lparts); 456 free(part); 479 disk = part->disk; 480 481 rc = vbds_part_remove(part, &lpart); 482 if (rc != EOK) 483 return rc; 484 485 rc = label_part_destroy(lpart); 486 if (rc != EOK) { 487 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed deleting partition"); 488 489 /* Try rolling back */ 490 rc = vbds_part_add(disk, lpart, NULL); 491 if (rc != EOK) 492 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed rolling back."); 493 494 return EIO; 495 } 496 457 497 return EOK; 458 498 }
Note:
See TracChangeset
for help on using the changeset viewer.