Changes in / [cb328ab:469739f] in mainline
- Location:
- uspace/lib
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/gpt/libgpt.c
rcb328ab r469739f 56 56 static int reduce_part_array(gpt_partitions_t * p); 57 57 static long long nearest_larger_int(double a); 58 59 60 /** Allocate memory for gpt label */ 61 gpt_label_t * gpt_alloc_label(void) 62 { 63 gpt_label_t *label = malloc(sizeof(gpt_label_t)); 64 if (label == NULL) 65 return NULL; 66 67 label->gpt = NULL; 68 label->parts = NULL; 69 label->device = 0; 70 71 return label; 72 } 73 74 /** Free gpt_label_t structure */ 75 void gpt_free_label(gpt_label_t *label) 76 { 77 if (label->gpt != NULL) 78 gpt_free_gpt(label->gpt); 79 80 if (label->parts != NULL) 81 gpt_free_partitions(label->parts); 82 83 free(label); 84 } 58 static int gpt_memcmp(const void * a, const void * b, size_t len); 85 59 86 60 /** Allocate memory for gpt header */ 87 gpt_t * gpt_alloc_header(size_t size) 88 { 89 gpt_t *gpt = malloc(sizeof(gpt_t)); 90 if (gpt == NULL) 91 return NULL; 92 93 // We might need only sizeof(gpt_header_t), 94 // but we should follow specs and have 95 // zeroes through all the rest of the block 96 size_t final_size = size > sizeof(gpt_header_t) ? size : sizeof(gpt_header_t); 97 gpt->header = malloc(final_size); 98 if (gpt->header == NULL) { 99 free(gpt); 100 return NULL; 101 } 102 103 memset(gpt->header, 0, final_size); 104 105 return gpt; 106 } 107 108 /** free() GPT header including gpt->header_lba */ 109 void gpt_free_gpt(gpt_t *gpt) 110 { 111 free(gpt->header); 112 free(gpt); 61 gpt_t * gpt_alloc_gpt_header(void) 62 { 63 return malloc(sizeof(gpt_t)); 113 64 } 114 65 115 66 /** Read GPT from specific device 116 * @param label label structure to fill 117 * @param dev_handle device to read GPT from 118 * 119 * @return EOK on success, errorcode on error 120 */ 121 int gpt_read_header(gpt_label_t *label, service_id_t dev_handle) 67 * @param dev_handle device to read GPT from 68 * 69 * @return GPT record on success, NULL on error 70 */ 71 gpt_t * gpt_read_gpt_header(service_id_t dev_handle) 122 72 { 123 73 int rc; … … 126 76 rc = block_init(EXCHANGE_ATOMIC, dev_handle, 512); 127 77 if (rc != EOK) 128 return rc;78 return NULL; 129 79 130 80 rc = block_get_bsize(dev_handle, &b_size); 131 if (rc != EOK) 132 return rc; 81 if (rc != EOK) { 82 errno = rc; 83 return NULL; 84 } 133 85 134 if (label->gpt == NULL) { 135 label->gpt = gpt_alloc_header(b_size); 136 if (label->gpt == NULL) 137 return ENOMEM; 86 gpt_t * gpt = malloc(sizeof(gpt_t)); 87 if (gpt == NULL) { 88 errno = ENOMEM; 89 return NULL; 90 } 91 92 gpt->raw_data = malloc(b_size); // We might need only sizeof(gpt_header_t), 93 if (gpt == NULL) { // but we should follow specs and have 94 free(gpt); // zeroes through all the rest of the block 95 errno = ENOMEM; 96 return NULL; 138 97 } 139 98 140 rc = load_and_check_header(dev_handle, GPT_HDR_BA, b_size, label->gpt->header); 99 100 rc = load_and_check_header(dev_handle, GPT_HDR_BA, b_size, gpt->raw_data); 141 101 if (rc == EBADCHECKSUM || rc == EINVAL) { 142 102 aoff64_t n_blocks; 143 103 rc = block_get_nblocks(dev_handle, &n_blocks); 144 if (rc != EOK) 104 if (rc != EOK) { 105 errno = rc; 145 106 goto fail; 146 147 rc = load_and_check_header(dev_handle, n_blocks - 1, b_size, label->gpt->header); 148 if (rc == EBADCHECKSUM || rc == EINVAL) 107 } 108 109 rc = load_and_check_header(dev_handle, n_blocks - 1, b_size, gpt->raw_data); 110 if (rc == EBADCHECKSUM || rc == EINVAL) { 111 errno = rc; 149 112 goto fail; 113 } 150 114 } 151 115 152 label->device = dev_handle;116 gpt->device = dev_handle; 153 117 block_fini(dev_handle); 154 return EOK;118 return gpt; 155 119 156 120 fail: 157 121 block_fini(dev_handle); 158 gpt_free_gpt(label->gpt); 159 label->gpt = NULL; 160 return rc; 122 gpt_free_gpt(gpt); 123 return NULL; 161 124 } 162 125 163 126 /** Write GPT header to device 164 * @param label GPT labelheader to be written165 * @param dev_handle 166 * 167 * @return EOKon success, libblock error code otherwise168 * 169 * Note: Firstly write partitions (if modified), then gpt header.170 */ 171 int gpt_write_ header(gpt_label_t *label, service_id_t dev_handle)127 * @param header GPT header to be written 128 * @param dev_handle device handle to write the data to 129 * 130 * @return 0 on success, libblock error code otherwise 131 * 132 * Note: Firstly write partitions (if changed), then gpt header. 133 */ 134 int gpt_write_gpt_header(gpt_t * gpt, service_id_t dev_handle) 172 135 { 173 136 int rc; 174 137 size_t b_size; 175 138 176 label->gpt->header->header_crc32 = 0;177 label->gpt->header->header_crc32 = compute_crc32((uint8_t *) label->gpt->header,178 uint32_t_le2host( label->gpt->header->header_size));139 gpt->raw_data->header_crc32 = 0; 140 gpt->raw_data->header_crc32 = compute_crc32((uint8_t *) gpt->raw_data, 141 uint32_t_le2host(gpt->raw_data->header_size)); 179 142 180 143 rc = block_init(EXCHANGE_ATOMIC, dev_handle, b_size); … … 187 150 188 151 /* Write to main GPT header location */ 189 rc = block_write_direct(dev_handle, GPT_HDR_BA, GPT_HDR_BS, label->gpt->header);190 if (rc != EOK) {152 rc = block_write_direct(dev_handle, GPT_HDR_BA, GPT_HDR_BS, gpt->raw_data); 153 if (rc != EOK) 191 154 block_fini(dev_handle); 192 155 return rc; 193 }194 156 195 157 aoff64_t n_blocks; 196 158 rc = block_get_nblocks(dev_handle, &n_blocks); 197 if (rc != EOK) { 198 block_fini(dev_handle); 199 return rc; 200 } 159 if (rc != EOK) 160 return rc; 201 161 202 162 /* Write to backup GPT header location */ 203 163 //FIXME: those idiots thought it would be cool to have these fields in reverse order... 204 rc = block_write_direct(dev_handle, n_blocks - 1, GPT_HDR_BS, label->gpt->header);164 rc = block_write_direct(dev_handle, n_blocks - 1, GPT_HDR_BS, gpt->raw_data); 205 165 block_fini(dev_handle); 206 166 if (rc != EOK) … … 211 171 212 172 /** Alloc partition array */ 213 gpt_partitions_t * 173 gpt_partitions_t * gpt_alloc_partitions() 214 174 { 215 175 return alloc_part_array(128); … … 217 177 218 178 /** Parse partitions from GPT 219 * @param label GPT label to be parsed 220 * 221 * @return EOK on success, errorcode otherwise 222 */ 223 int gpt_read_partitions(gpt_label_t *label) 179 * @param gpt GPT to be parsed 180 * 181 * @return partition linked list pointer or NULL on error 182 * error code is stored in errno 183 */ 184 gpt_partitions_t * gpt_read_partitions(gpt_t * gpt) 224 185 { 225 186 int rc; 226 187 unsigned int i; 227 uint32_t fill = uint32_t_le2host(label->gpt->header->fillries);228 uint32_t ent_size = uint32_t_le2host(label->gpt->header->entry_size);229 uint 64_t ent_lba = uint64_t_le2host(label->gpt->header->entry_lba);230 231 if (label->parts == NULL) { 232 label->parts = alloc_part_array(fill);233 if (label->parts == NULL) {234 return ENOMEM;235 }188 gpt_partitions_t * res; 189 uint32_t fill = uint32_t_le2host(gpt->raw_data->fillries); 190 uint32_t ent_size = uint32_t_le2host(gpt->raw_data->entry_size); 191 uint64_t ent_lba = uint64_t_le2host(gpt->raw_data->entry_lba); 192 193 res = alloc_part_array(fill); 194 if (res == NULL) { 195 //errno = ENOMEM; // already set in alloc_part_array() 196 return NULL; 236 197 } 237 198 … … 239 200 * - we don't need more bytes 240 201 * - the size of GPT partition entry can be different to 128 bytes */ 241 rc = block_init(EXCHANGE_SERIALIZE, label->device, sizeof(gpt_entry_t)); 242 if (rc != EOK) 243 goto fail; 202 rc = block_init(EXCHANGE_SERIALIZE, gpt->device, sizeof(gpt_entry_t)); 203 if (rc != EOK) { 204 gpt_free_partitions(res); 205 errno = rc; 206 return NULL; 207 } 244 208 245 209 size_t block_size; 246 rc = block_get_bsize(label->device, &block_size); 247 if (rc != EOK) 248 goto fail; 210 rc = block_get_bsize(gpt->device, &block_size); 211 if (rc != EOK) { 212 gpt_free_partitions(res); 213 errno = rc; 214 return NULL; 215 } 249 216 250 217 //size_t bufpos = 0; … … 259 226 for (i = 0; i < fill; ++i) { 260 227 //FIXME: this does bypass cache... 261 rc = block_read_bytes_direct( label->device, pos, sizeof(gpt_entry_t), label->parts->part_array + i);228 rc = block_read_bytes_direct(gpt->device, pos, sizeof(gpt_entry_t), res->part_array + i); 262 229 //FIXME: but seqread() is just too complex... 263 230 //rc = block_seqread(gpt->device, &bufpos, &buflen, &pos, res->part_array[i], sizeof(gpt_entry_t)); 264 231 pos += ent_size; 265 232 266 if (rc != EOK) 267 goto fail; 233 if (rc != EOK) { 234 gpt_free_partitions(res); 235 errno = rc; 236 return NULL; 237 } 268 238 } 269 239 … … 273 243 * on all of the partition entry array. 274 244 */ 275 uint32_t crc = compute_crc32((uint8_t *) label->parts->part_array, label->parts->fill * sizeof(gpt_entry_t));276 277 if(uint32_t_le2host( label->gpt->header->pe_array_crc32) != crc)245 uint32_t crc = compute_crc32((uint8_t *) res->part_array, res->fill * sizeof(gpt_entry_t)); 246 247 if(uint32_t_le2host(gpt->raw_data->pe_array_crc32) != crc) 278 248 { 279 rc = EBADCHECKSUM; 280 goto fail; 281 } 282 283 return EOK; 284 285 fail: 286 gpt_free_partitions(label->parts); 287 label->parts = NULL; 288 return rc; 249 gpt_free_partitions(res); 250 errno = EBADCHECKSUM; 251 return NULL; 252 } 253 254 return res; 289 255 } 290 256 291 257 /** Write GPT and partitions to device 292 * @param label label to write 293 * @param dev_handle device to write the data to 294 * 295 * @return returns EOK on succes, errorcode otherwise 296 */ 297 int gpt_write_partitions(gpt_label_t *label, service_id_t dev_handle) 258 * @param parts partition list to be written 259 * @param header GPT header belonging to the 'parts' partitions 260 * @param dev_handle device to write the data to 261 * 262 * @return returns EOK on succes, specific error code otherwise 263 */ 264 int gpt_write_partitions(gpt_partitions_t * parts, gpt_t * gpt, service_id_t dev_handle) 298 265 { 299 266 int rc; 300 267 size_t b_size; 301 uint32_t e_size = uint32_t_le2host(label->gpt->header->entry_size); 302 303 label->gpt->header->pe_array_crc32 = compute_crc32( 304 (uint8_t *) label->parts->part_array, 305 label->parts->fill * e_size); 306 307 /* comm_size of 4096 is ignored */ 308 rc = block_init(EXCHANGE_ATOMIC, dev_handle, 4096); 268 269 gpt->raw_data->pe_array_crc32 = compute_crc32((uint8_t *) parts->part_array, parts->fill * gpt->raw_data->entry_size); 270 271 rc = block_init(EXCHANGE_ATOMIC, dev_handle, b_size); 309 272 if (rc != EOK) 310 273 return rc; … … 312 275 rc = block_get_bsize(dev_handle, &b_size); 313 276 if (rc != EOK) 314 goto fail;277 return rc; 315 278 316 279 /* Write to main GPT partition array location */ 317 rc = block_write_direct(dev_handle, uint64_t_le2host(label->gpt->header->entry_lba), 318 nearest_larger_int((uint64_t_le2host(label->gpt->header->entry_size) * label->parts->fill) / b_size), 319 label->parts->part_array); 320 if (rc != EOK) 321 goto fail; 280 rc = block_write_direct(dev_handle, uint64_t_le2host(gpt->raw_data->entry_lba), 281 nearest_larger_int((uint64_t_le2host(gpt->raw_data->entry_size) * parts->fill) / b_size), 282 parts->part_array); 283 if (rc != EOK) 284 block_fini(dev_handle); 285 return rc; 322 286 323 287 aoff64_t n_blocks; 324 288 rc = block_get_nblocks(dev_handle, &n_blocks); 325 289 if (rc != EOK) 326 goto fail;290 return rc; 327 291 328 292 /* Write to backup GPT partition array location */ … … 330 294 block_fini(dev_handle); 331 295 if (rc != EOK) 332 goto fail; 333 334 335 return gpt_write_header(label, dev_handle); 336 337 fail: 338 block_fini(dev_handle); 339 return rc; 296 return rc; 297 298 299 return gpt_write_gpt_header(gpt, dev_handle); 340 300 } 341 301 342 302 /** Alloc new partition 343 303 * 344 * @return returns pointer to the new partition or NULL 345 * 346 * Note: use either gpt_alloc_partition or gpt_get_partition. 347 * This returns a memory block (zero-filled) and needs gpt_add_partition() 348 * to be called to insert it into a partition array. 349 * Requires you to call gpt_free_partition after use. 350 */ 351 gpt_part_t * gpt_alloc_partition(void) 352 { 353 gpt_part_t *p = malloc(sizeof(gpt_part_t)); 354 if (p == NULL) 355 return NULL; 356 357 memset(p, 0, sizeof(gpt_part_t)); 358 359 return p; 360 } 361 362 /** Alloc new partition already inside the label 363 * 364 * @param label label to carry new partition 365 * 366 * @return returns pointer to the new partition or NULL on ENOMEM 367 * 368 * 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(). 371 * This is the one you will usually want. 372 */ 373 gpt_part_t * gpt_get_partition(gpt_label_t *label) 374 { 375 if (label->parts->fill == label->parts->arr_size) { 376 if (extend_part_array(label->parts) == -1) 304 * @param parts partition table to carry new partition 305 * 306 * @return returns pointer to the new partition or NULL on ENOMEM 307 * 308 * Note: use either gpt_alloc_partition or gpt_add_partition. The first 309 * returns a pointer to write your data to, the second copies the data 310 * (and does not free the memory). 311 */ 312 gpt_part_t * gpt_alloc_partition(gpt_partitions_t * parts) 313 { 314 if (parts->fill == parts->arr_size) { 315 if (extend_part_array(parts) == -1) 377 316 return NULL; 378 317 } 379 318 380 return label->parts->part_array + label->parts->fill++;319 return parts->part_array + parts->fill++; 381 320 } 382 321 383 322 /** Copy partition into partition array 384 323 * 385 * @param parts target label324 * @param parts target partition array 386 325 * @param partition source partition to copy 387 326 * 388 327 * @return -1 on error, 0 otherwise 389 328 * 390 * Note: for use with gpt_alloc_partition() only. You will get 391 * duplicates with gpt_get_partition(). 392 */ 393 int gpt_add_partition(gpt_label_t *label, gpt_part_t *partition) 394 { 395 if (label->parts->fill == label->parts->arr_size) { 396 if (extend_part_array(label->parts) == -1) 329 * Note: use either gpt_alloc_partition or gpt_add_partition. The first 330 * returns a pointer to write your data to, the second copies the data 331 * (and does not free the memory). 332 */ 333 int gpt_add_partition(gpt_partitions_t * parts, gpt_part_t * partition) 334 { 335 if (parts->fill == parts->arr_size) { 336 if (extend_part_array(parts) == -1) 397 337 return ENOMEM; 398 338 } 399 400 memcpy(label->parts->part_array + label->parts->fill++, 401 partition, sizeof(gpt_part_t)); 402 403 return EOK; 339 extend_part_array(parts); 340 return EOK;; 404 341 } 405 342 406 343 /** Remove partition from array 407 * @param label label to remove from408 * @param idx 409 * 410 * @return EOK on success, ENOMEM on array reduction failure344 * 345 * @param idx index of the partition to remove 346 * 347 * @return -1 on error, 0 otherwise 411 348 * 412 349 * Note: even if it fails, the partition still gets removed. Only 413 350 * reducing the array failed. 414 351 */ 415 int gpt_remove_partition(gpt_label_t *label, size_t idx) 416 { 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 */ 426 if (label->parts->fill < (label->parts->arr_size / 2) - GPT_IGNORE_FILL_NUM) { 427 if (reduce_part_array(label->parts) == ENOMEM) 428 return ENOMEM; 429 } 430 431 return EOK; 352 int gpt_remove_partition(gpt_partitions_t * parts, size_t idx) 353 { 354 if (idx != parts->fill - 1) { 355 memcpy(parts->part_array + idx, parts->part_array + parts->fill - 1, sizeof(gpt_entry_t)); 356 parts->fill -= 1; 357 } 358 359 if (parts->fill < (parts->arr_size / 2) - GPT_IGNORE_FILL_NUM) { 360 if (reduce_part_array(parts) == -1) 361 return -1; 362 } 363 364 return 0; 365 } 366 367 /** free() GPT header including gpt->header_lba */ 368 void gpt_free_gpt(gpt_t * gpt) 369 { 370 free(gpt->raw_data); 371 free(gpt); 432 372 } 433 373 … … 449 389 size_t i; 450 390 for (i = 0; gpt_ptypes[i].guid != NULL; i++) { 451 if ( bcmp(p->part_type, gpt_ptypes[i].guid, 16) == 0) {391 if (gpt_memcmp(p->part_type, gpt_ptypes[i].guid, 16) == 0) { 452 392 break; 453 393 } … … 509 449 } 510 450 511 /** Get partition name */ 451 512 452 unsigned char * gpt_get_part_name(gpt_part_t * p) 513 453 { … … 621 561 if(p->arr_size > GPT_MIN_PART_NUM) { 622 562 unsigned int nsize = p->arr_size / 2; 623 nsize = nsize > GPT_MIN_PART_NUM ? nsize : GPT_MIN_PART_NUM;624 563 gpt_entry_t * tmp = malloc(nsize * sizeof(gpt_entry_t)); 625 if(tmp == NULL) 626 return ENOMEM; 564 if(tmp == NULL) { 565 errno = ENOMEM; 566 return -1; 567 } 627 568 628 569 memcpy(tmp, p->part_array, p->fill < nsize ? p->fill : nsize); … … 645 586 } 646 587 647 648 649 650 651 588 static int gpt_memcmp(const void * a, const void * b, size_t len) 589 { 590 size_t i; 591 int diff; 592 const unsigned char * x = a; 593 const unsigned char * y = b; 594 595 for (i = 0; i < len; i++) { 596 diff = (int)*(x++) - (int)*(y++); 597 if (diff != 0) { 598 return diff; 599 } 600 } 601 return 0; 602 } 603 604 605 606 -
uspace/lib/gpt/libgpt.h
rcb328ab r469739f 86 86 typedef struct { 87 87 /** Raw header. Has more bytes alloced than sizeof(gpt_header_t)! 88 * See gpt_alloc_header() to know why. */ 89 gpt_header_t *header; 88 * See gpt_read_gpt_header() to know why. */ 89 gpt_header_t * raw_data; 90 /** Device where the data are from */ 91 service_id_t device; 92 /** Linked list of partitions (initially NULL) */ 90 93 } gpt_t; 91 94 … … 120 123 size_t arr_size; 121 124 /** Resizable partition array */ 122 gpt_entry_t * part_array;125 gpt_entry_t * part_array; 123 126 } gpt_partitions_t; 124 127 125 128 126 129 typedef struct gpt_table { 127 gpt_t *gpt; 128 gpt_partitions_t *parts; 129 service_id_t device; 130 gpt_t * gpt; 131 gpt_partitions_t * parts; 130 132 } gpt_label_t; 131 133 132 134 struct partition_type { 133 const char * desc;134 const char * guid;135 const char * desc; 136 const char * guid; 135 137 }; 136 138 137 139 extern const struct partition_type gpt_ptypes[]; 138 140 139 extern gpt_label_t * gpt_alloc_label(void);140 extern void gpt_free_label(gpt_label_t *);141 141 142 extern gpt_t * gpt_alloc_ header(size_t);143 extern int gpt_read_header(gpt_label_t *, service_id_t);144 extern int gpt_write_ header(gpt_label_t *, service_id_t);142 extern gpt_t * gpt_alloc_gpt_header(void); 143 extern gpt_t * gpt_read_gpt_header(service_id_t dev_handle); 144 extern int gpt_write_gpt_header(gpt_t * header, service_id_t dev_handle); 145 145 146 146 extern gpt_partitions_t * gpt_alloc_partitions(void); 147 extern int gpt_read_partitions (gpt_label_t *); 148 extern int gpt_write_partitions(gpt_label_t *, service_id_t); 149 extern gpt_part_t * gpt_alloc_partition (void); 150 extern gpt_part_t * gpt_get_partition (gpt_label_t *); 151 extern int gpt_add_partition (gpt_label_t *, gpt_part_t *); 152 extern int gpt_remove_partition(gpt_label_t *, size_t); 147 extern gpt_partitions_t * gpt_read_partitions(gpt_t * gpt); 148 extern int gpt_write_partitions(gpt_partitions_t * parts, gpt_t * header, service_id_t dev_handle); 149 extern gpt_part_t * gpt_alloc_partition (gpt_partitions_t * parts); 150 extern int gpt_add_partition (gpt_partitions_t * parts, gpt_part_t * partition); 151 extern int gpt_remove_partition(gpt_partitions_t * parts, size_t idx); 153 152 154 extern size_t gpt_get_part_type(gpt_part_t * );155 extern void gpt_set_part_type(gpt_part_t * , size_t);156 extern void gpt_set_start_lba(gpt_part_t * , uint64_t);157 extern uint64_t gpt_get_start_lba(gpt_part_t * );158 extern void gpt_set_end_lba (gpt_part_t * , uint64_t);159 extern uint64_t gpt_get_end_lba (gpt_part_t * );160 extern unsigned char * gpt_get_part_name(gpt_part_t * );161 extern void gpt_set_part_name(gpt_part_t * , char *[], size_t);162 extern bool gpt_get_flag (gpt_part_t * , GPT_ATTR);163 extern void gpt_set_flag (gpt_part_t * , GPT_ATTR, bool);153 extern size_t gpt_get_part_type(gpt_part_t * p); 154 extern void gpt_set_part_type(gpt_part_t * p, size_t type); 155 extern void gpt_set_start_lba(gpt_part_t * p, uint64_t start); 156 extern uint64_t gpt_get_start_lba(gpt_part_t * p); 157 extern void gpt_set_end_lba (gpt_part_t * p, uint64_t end); 158 extern uint64_t gpt_get_end_lba (gpt_part_t * p); 159 extern unsigned char * gpt_get_part_name(gpt_part_t * p); 160 extern void gpt_set_part_name(gpt_part_t * p, char * name[], size_t length); 161 extern bool gpt_get_flag (gpt_part_t * p, GPT_ATTR flag); 162 extern void gpt_set_flag (gpt_part_t * p, GPT_ATTR flag, bool value); 164 163 165 164 … … 169 168 iterator < (parts)->part_array + (parts)->fill; ++iterator) 170 169 171 extern void gpt_free_gpt(gpt_t * );172 extern void gpt_free_partitions(gpt_partitions_t * );170 extern void gpt_free_gpt(gpt_t * gpt); 171 extern void gpt_free_partitions(gpt_partitions_t * parts); 173 172 174 173 #endif -
uspace/lib/mbr/libmbr.c
rcb328ab r469739f 92 92 */ 93 93 int mbr_read_mbr(mbr_label_t *label, service_id_t dev_handle) 94 { 94 { 95 if (label == NULL) 96 return EINVAL; 97 95 98 int rc; 96 99
Note:
See TracChangeset
for help on using the changeset viewer.