Changeset 30440ed in mainline for uspace/lib/gpt
- Timestamp:
- 2013-04-08T23:15:42Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 256cbfe
- Parents:
- 271e24a
- Location:
- uspace/lib/gpt
- Files:
-
- 1 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/gpt/libgpt.c
r271e24a r30440ed 117 117 * 118 118 * @return 0 on success, libblock error code otherwise 119 * 120 * Note: Firstly write partitions (if changed), then gpt header. 119 121 */ 120 122 int gpt_write_gpt_header(gpt_t * gpt, service_id_t dev_handle) … … 167 169 unsigned int i; 168 170 gpt_partitions_t * res; 169 uint32_t num_ent = uint32_t_le2host(gpt->raw_data->num_entries);171 uint32_t fill = uint32_t_le2host(gpt->raw_data->fillries); 170 172 uint32_t ent_size = uint32_t_le2host(gpt->raw_data->entry_size); 171 173 uint64_t ent_lba = uint64_t_le2host(gpt->raw_data->entry_lba); 172 174 173 res = alloc_part_array( num_ent);175 res = alloc_part_array(fill); 174 176 if (res == NULL) { 175 177 //errno = ENOMEM; // already set in alloc_part_array() … … 204 206 * will always read just sizeof(gpt_entry_t) bytes - hopefully they 205 207 * don't break backward compatibility) */ 206 for (i = 0; i < num_ent; ++i) {208 for (i = 0; i < fill; ++i) { 207 209 //FIXME: this does bypass cache... 208 210 rc = block_read_bytes_direct(gpt->device, pos, sizeof(gpt_entry_t), res->part_array + i); … … 223 225 * on all of the partition entry array. 224 226 */ 225 uint32_t crc = compute_crc32((uint8_t *) res->part_array, res-> num_ent* sizeof(gpt_entry_t));227 uint32_t crc = compute_crc32((uint8_t *) res->part_array, res->fill * sizeof(gpt_entry_t)); 226 228 227 229 if(uint32_t_le2host(gpt->raw_data->pe_array_crc32) != crc) … … 247 249 size_t b_size; 248 250 249 gpt->raw_data->pe_array_crc32 = compute_crc32((uint8_t *) parts->part_array, parts-> num_ent* gpt->raw_data->entry_size);251 gpt->raw_data->pe_array_crc32 = compute_crc32((uint8_t *) parts->part_array, parts->fill * gpt->raw_data->entry_size); 250 252 251 253 rc = block_get_bsize(dev_handle, &b_size); … … 259 261 /* Write to main GPT partition array location */ 260 262 rc = block_write_direct(dev_handle, uint64_t_le2host(gpt->raw_data->entry_lba), 261 nearest_larger_int((uint64_t_le2host(gpt->raw_data->entry_size) * parts-> num_ent) / b_size),263 nearest_larger_int((uint64_t_le2host(gpt->raw_data->entry_size) * parts->fill) / b_size), 262 264 parts->part_array); 263 265 if (rc != EOK) … … 277 279 278 280 279 gpt_write_gpt_header(gpt, dev_handle); 280 281 return 0; 282 283 } 284 285 gpt_partitions_t * gpt_add_partition(gpt_partitions_t * parts, gpt_part_t * partition) 286 { 287 281 return gpt_write_gpt_header(gpt, dev_handle); 282 } 283 284 /** Alloc new partition 285 * 286 * @param parts partition table to carry new partition 287 * 288 * @return returns pointer to the new partition or NULL on ENOMEM 289 * 290 * Note: use either gpt_alloc_partition or gpt_add_partition. The first 291 * returns a pointer to write your data to, the second copies the data 292 * (and does not free the memory). 293 */ 294 gpt_part_t * gpt_alloc_partition(gpt_partitions_t * parts) 295 { 296 if (parts->fill == parts->arr_size) { 297 if (extend_part_array(parts) == -1) 298 return NULL; 299 } 300 301 return parts->part_array + parts->fill++; 302 } 303 304 /** Copy partition into partition array 305 * 306 * @param parts target partition array 307 * @param partition source partition to copy 308 * 309 * @return -1 on error, 0 otherwise 310 * 311 * Note: use either gpt_alloc_partition or gpt_add_partition. The first 312 * returns a pointer to write your data to, the second copies the data 313 * (and does not free the memory). 314 */ 315 int gpt_add_partition(gpt_partitions_t * parts, gpt_part_t * partition) 316 { 317 if (parts->fill == parts->arr_size) { 318 if (extend_part_array(parts) == -1) 319 return -1; 320 } 288 321 extend_part_array(parts); 289 322 return parts; 290 323 } 291 324 292 gpt_partitions_t * gpt_remove_partition(gpt_partitions_t * parts, size_t idx) 293 { 294 reduce_part_array(parts); 295 return parts; 325 /** Remove partition from array 326 * 327 * @param idx index of the partition to remove 328 * 329 * @return -1 on error, 0 otherwise 330 * 331 * Note: even if it fails, the partition still gets removed. Only 332 * reducing the array failed. 333 */ 334 int gpt_remove_partition(gpt_partitions_t * parts, size_t idx) 335 { 336 if (idx != parts->fill - 1) { 337 memcpy(parts->part_array + idx, parts->part_array + fill - 1, sizeof(gpt_entry_t)); 338 parts->fill -= 1; 339 } 340 341 if (parts->fill < (parts->arr_size / 2) - GPT_IGNORE_FILL_NUM) { 342 if (reduce_part_array(parts) == -1) 343 return -1; 344 } 345 346 return 0; 296 347 } 297 348 … … 311 362 free(parts->part_array); 312 363 free(parts); 364 } 365 366 /** Get partition type by linear search 367 * (hopefully this doesn't get slow) 368 */ 369 size_t gpt_get_part_type(gpt_part_t * p) 370 { 371 size_t i; 372 for (i = 0; gpt_ptypes[i].guid != NULL; i++) { 373 if (memcmp(p->raw_data.part_type, gpt_ptypes[i].guid, 16) == 0) { 374 break; 375 } 376 } 377 return i; 313 378 } 314 379 … … 343 408 } 344 409 410 char * gpt_get_part_name(gpt_entry_t * p) 411 { 412 return p->raw_data.part_name; 413 } 414 345 415 /** Copy partition name */ 346 416 void gpt_set_part_name(gpt_entry_t * p, char * name[], size_t length) 347 417 { 418 if (length >= 72) 419 length = 71; 420 348 421 memcpy(p->part_name, name, length); 422 p->part_name[length] = '\0'; 423 } 424 425 /** Get partition attribute */ 426 extern bool gpt_get_flag(gpt_part_t * p, GPT_ATTR flag) 427 { 428 return (p->raw_data.attributes & (((uint64_t) 1) << flag)) ? 1 : 0; 429 } 430 431 /** Set partition attribute */ 432 extern void gpt_set_flag(gpt_part_t * p, GPT_ATTR flag, bool value) 433 { 434 uint64_t attr = p->raw_data.attributes; 435 436 if (value) 437 attr = attr | (((uint64_t) 1) << flag); 438 else 439 attr = attr ^ (attr & (((uint64_t) 1) << flag)); 440 441 p->raw_data.attributes = attr; 349 442 } 350 443 … … 405 498 } 406 499 407 res-> num_ent= num;500 res->fill = num; 408 501 res->arr_size = size; 409 502 … … 420 513 } 421 514 422 memcpy(tmp, p->part_array, p-> num_ent);515 memcpy(tmp, p->part_array, p->fill); 423 516 free(p->part_array); 424 517 p->part_array = tmp; … … 438 531 } 439 532 440 memcpy(tmp, p->part_array, p-> num_ent < nsize ? p->num_ent: nsize);533 memcpy(tmp, p->part_array, p->fill < nsize ? p->fill : nsize); 441 534 free(p->part_array); 442 535 p->part_array = tmp; -
uspace/lib/gpt/libgpt.h
r271e24a r30440ed 49 49 /** Basic number of GPT partition entries */ 50 50 #define GPT_BASE_PART_NUM (GPT_MIN_PART_NUM) 51 /** How much fill we ignore before resizing partition array */ 52 #define GPT_IGNORE_FILL_NUM 10 51 53 52 54 /** GPT header signature ("EFI PART" in ASCII) */ 53 55 extern const uint8_t efi_signature[8]; 56 57 typedef enum { 58 AT_REQ_PART = 0, 59 AT_NO_BLOCK_IO, 60 AT_LEGACY_BOOT, 61 AT_UNDEFINED, 62 AT_SPECIFIC = 48 63 } GPT_ATTR; 54 64 55 65 /** GPT header … … 68 78 uint8_t disk_guid[16]; 69 79 uint64_t entry_lba; 70 uint32_t num_entries;80 uint32_t fillries; 71 81 uint32_t entry_size; 72 82 uint32_t pe_array_crc32; … … 105 115 typedef struct gpt_parts { 106 116 /** Number of entries */ 107 unsigned int num_ent;117 size_t fill; 108 118 /** Size of the array */ 109 unsigned int arr_size;119 size_t arr_size; 110 120 /** Resizable partition array */ 111 121 gpt_entry_t * part_array; … … 132 142 extern gpt_partitions_t * gpt_read_partitions(gpt_t * gpt); 133 143 extern int gpt_write_partitions(gpt_partitions_t * parts, gpt_t * header, service_id_t dev_handle); 134 extern gpt_partitions_t * gpt_add_partition(gpt_partitions_t * parts, gpt_part_t * partition); 135 extern gpt_partitions_t * gpt_remove_partition(gpt_partitions_t * parts, size_t idx); 136 extern void gpt_set_part_type(gpt_part_t * p, int type); 144 extern gpt_part_t * gpt_alloc_partition(gpt_partitions_t * parts); 145 extern int gpt_add_partition(gpt_partitions_t * parts, gpt_part_t * partition); 146 extern int gpt_remove_partition(gpt_partitions_t * parts, size_t idx); 147 extern size_t gpt_get_part_type(gpt_part_t * p); 148 extern void gpt_set_part_type(gpt_part_t * p, size_t type); 149 extern char * gpt_get_part_name(gpt_entry_t * p); 137 150 extern void gpt_set_part_name(gpt_entry_t * p, char * name[], size_t length); 151 extern bool gpt_get_flag(gpt_part_t * p, GPT_ATTR flag); 152 extern void gpt_set_flag(gpt_part_t * p, GPT_ATTR flag, bool value); 153 154 #define gpt_foreach(parts, i, iterator) \ 155 for(size_t i = 0, gpt_part_t * iterator = parts->part_array; 156 i < parts->fill; i++, iterator++) 138 157 139 158 extern void gpt_free_gpt(gpt_t * gpt);
Note:
See TracChangeset
for help on using the changeset viewer.