Changeset 700f89e in mainline
- Timestamp:
- 2013-05-02T00:51:28Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 9bda5d90
- Parents:
- 8f6c7785
- Location:
- uspace
- Files:
-
- 2 added
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/hdisk/func_gpt.c
r8f6c7785 r700f89e 65 65 66 66 return EOK; 67 } 68 69 int new_gpt_table(tinput_t * in, union table_data * data) 70 { 71 data->gpt.gpt = gpt_alloc_gpt_header(); 72 data->gpt.parts = gpt_alloc_partitions(); 67 73 } 68 74 -
uspace/app/hdisk/func_gpt.h
r8f6c7785 r700f89e 44 44 extern int add_gpt_part(tinput_t * in, union table_data * data); 45 45 extern int delete_gpt_part(tinput_t * in, union table_data * data); 46 extern int new_gpt_table(tinput_t *, union table_data *); 46 47 extern int print_gpt_parts(union table_data * data); 47 48 extern int write_gpt_parts(service_id_t dev_handle, union table_data * data); -
uspace/app/hdisk/func_mbr.c
r8f6c7785 r700f89e 75 75 76 76 return EOK; 77 } 78 79 int new_mbr_table(tinput_t * in, union table_data * data) 80 { 81 data->mbr.mbr = mbr_alloc_mbr(); 82 data->mbr.parts = mbr_alloc_partitions(); 77 83 } 78 84 -
uspace/app/hdisk/func_mbr.h
r8f6c7785 r700f89e 44 44 extern int add_mbr_part(tinput_t * in, union table_data * data); 45 45 extern int delete_mbr_part(tinput_t * in, union table_data * data); 46 extern int new_mbr_table(tinput_t *, union table_data *); 46 47 extern int print_mbr_parts(union table_data * data); 47 48 extern int write_mbr_parts(service_id_t dev_handle, union table_data * data); -
uspace/app/hdisk/hdisk.c
r8f6c7785 r700f89e 53 53 int interact(service_id_t dev_handle); 54 54 void print_help(void); 55 void select_table_format(void); 55 56 void fill_table_funcs(void); 56 57 void free_table(void); … … 94 95 set_table_mbr_parts(parts); 95 96 fill_table_funcs(); 96 } else { 97 goto interact; 98 } 99 100 101 mbr_free_mbr(mbr); 102 gpt_t * gpt = gpt_read_gpt_header(dev_handle); 103 104 if(gpt != NULL) { 97 105 table.layout = LYT_GPT; 98 mbr_free_mbr(mbr);99 gpt_t * gpt = gpt_read_gpt_header(dev_handle);100 printf("here3\n");101 if(gpt == NULL) {102 printf("Failed to read and parse GPT header. Exiting.\n");103 return -1;104 }105 106 set_table_gpt(gpt); 106 printf("here4\n");107 107 108 gpt_partitions_t * parts = gpt_read_partitions(gpt); 108 printf("here5\n");109 109 110 if(parts == NULL) { 110 111 printf("Failed to read and parse partitions.\n" \ 111 112 "Creating new partition table."); 112 //parts = gpt_alloc_partitions();113 parts = gpt_alloc_partitions(); 113 114 } 114 115 set_table_gpt_parts(parts); 115 116 fill_table_funcs(); 116 } 117 117 goto interact; 118 } 119 printf("No partition table recognized. Create a new one.\n"); 120 table.layout = LYT_NONE; 121 122 interact: 118 123 rc = interact(dev_handle); 119 124 … … 122 127 return rc; 123 128 } 124 125 /*126 int get_input(tinput_t * in, char ** str)127 {128 int c;129 size_tat130 131 pos = 0;132 size_t size = 256;133 134 *str = malloc(size * sizeof(char));135 if (*str == NULL)136 return ENOMEM;137 138 while ((c = getchar()) != '\n') {139 if (c >= 32 && c <= 126) { //a printable character140 141 (*str)[pos] = c;142 ++pos;143 putchar(c);144 145 if (pos == size) {146 char * temp = malloc(2 * size * sizeof(char));147 memcpy(temp, *str, size);148 free(*str);149 *str = temp;150 size *= 2;151 }152 } else if (c == 8) { //backspace153 (*str)[pos] = 0;154 --pos;155 putchar(c);156 }157 }158 159 putchar('\n');160 161 (*str)[pos] = 0;162 163 return EOK;164 }165 */166 167 129 168 130 /** Interact with user */ 169 131 int interact(service_id_t dev_handle) 170 132 { 171 //int rc;172 133 int input; 173 134 tinput_t * in; 174 135 175 136 in = tinput_new(); 176 137 if (in == NULL) { … … 179 140 } 180 141 tinput_set_prompt(in, ""); 181 142 182 143 printf("Welcome to hdisk.\nType 'h' for help.\n"); 183 184 //printf("# "); 185 //input = getchar(); 186 //printf("%c\n", input); 187 144 188 145 while (1) { 189 190 146 printf("# "); 191 147 input = getchar(); 192 148 printf("%c\n", input); 193 194 195 //rc = tinput_read(in, &str); 196 //if (rc == ENOENT) { 197 //// User requested exit 198 //putchar('\n'); 199 //return rc; 200 //} 201 //if (rc != EOK) { 202 //printf("Failed reading input. Exiting...\n"); 203 //return rc; 204 //} 205 //// Check for empty input. 206 //if (str_cmp(str, "") == 0) 207 //continue; 208 149 209 150 switch(input) { 210 151 case 'a': … … 217 158 table.extra_funcs(in, dev_handle, &table.data); 218 159 break; 160 case 'f': 161 free_table(); 162 select_table_format(in); 163 break; 219 164 case 'h': 220 165 print_help(); 166 break; 167 case 'n': 168 free_table(); 169 table.new_table(in); 221 170 break; 222 171 case 'p': … … 233 182 break; 234 183 } 235 //printf("# "); 236 //input = getchar(); 237 //printf("%c\n", input); 238 239 } 240 184 } 185 241 186 end: 242 187 tinput_destroy(in); 243 188 244 189 return EOK; 245 190 } … … 250 195 "\t 'a' \t\t Add partition.\n" 251 196 "\t 'd' \t\t Delete partition.\n" 252 "\t 'h' \t\t Prints help. See help for more.\n" \ 253 "\t 'p' \t\t Prints the table contents.\n" \ 254 "\t 'w' \t\t Write table to disk.\n" \ 255 "\t 'q' \t\t Quit.\n" \ 197 "\t 'e' \t\t Extra functions (per table format).\n" 198 "\t 'f' \t\t Switch the format of the partition table." 199 "\t 'h' \t\t Prints help. See help for more.\n" 200 "\t 'n' \t\t Create new partition table (discarding the old one).\n" 201 "\t 'p' \t\t Prints the table contents.\n" 202 "\t 'w' \t\t Write table to disk.\n" 203 "\t 'q' \t\t Quit.\n" 256 204 ); 257 205 206 } 207 208 void select_table_format(tinput_t * in) 209 { 210 printf("Available formats are: \n" 211 "1) MBR\n" 212 "2) GPT\n" 213 ); 214 215 uint8_t val = get_input_uint8(in); 216 switch(val) { 217 case 0: 218 table.layout = LYT_NONE; 219 fill_table_funcs(); 220 break; 221 case 1: 222 table.layout = LYT_MBR; 223 fill_table_funcs(); 224 break; 225 case 2: 226 table.layout = LYT_GPT; 227 fill_table_funcs(); 228 break; 229 } 258 230 } 259 231 … … 264 236 table.add_part = add_mbr_part; 265 237 table.delete_part = delete_mbr_part; 238 table.new_table = new_mbr_table; 266 239 table.print_parts = print_mbr_parts; 267 240 table.write_parts = write_mbr_parts; … … 271 244 table.add_part = add_gpt_part; 272 245 table.delete_part = delete_gpt_part; 246 table.new_table = new_gpt_table; 273 247 table.print_parts = print_gpt_parts; 274 248 table.write_parts = write_gpt_parts; … … 276 250 break; 277 251 default: 252 table.add_part = add_none_part; 253 table.delete_part = delete_none_part; 254 table.new_table = new_none_table; 255 table.print_parts = print_none_parts; 256 table.write_parts = write_none_parts; 257 table.extra_funcs = extra_none_funcs; 278 258 break; 279 259 } … … 284 264 switch(table.layout) { 285 265 case LYT_MBR: 286 mbr_free_partitions(table.data.mbr.parts); 287 mbr_free_mbr(table.data.mbr.mbr); 266 if (table.data.mbr.parts != NULL) { 267 mbr_free_partitions(table.data.mbr.parts); 268 table.data.mbr.parts = NULL; 269 } 270 if (table.data.mbr.mbr != NULL) { 271 mbr_free_mbr(table.data.mbr.mbr); 272 table.data.mbr.mbr = NULL; 273 } 288 274 break; 289 275 case LYT_GPT: 290 gpt_free_partitions(table.data.gpt.parts); 291 gpt_free_gpt(table.data.gpt.gpt); 276 if (table.data.gpt.parts != NULL) { 277 gpt_free_partitions(table.data.gpt.parts); 278 table.data.gpt.parts = NULL; 279 } 280 if (table.data.gpt.gpt != NULL) { 281 gpt_free_gpt(table.data.gpt.gpt); 282 table.data.gpt.gpt = NULL; 283 } 292 284 break; 293 285 default: … … 296 288 } 297 289 290 291 -
uspace/app/hdisk/hdisk.h
r8f6c7785 r700f89e 46 46 int (* add_part)(tinput_t *, union table_data *); 47 47 int (* delete_part)(tinput_t *, union table_data *); 48 int (* new_table)(tinput_t *, union table_data *); 48 49 int (* print_parts)(); 49 50 int (* write_parts)(service_id_t, union table_data *); -
uspace/lib/gpt/libgpt.c
r8f6c7785 r700f89e 58 58 static int gpt_memcmp(const void * a, const void * b, size_t len); 59 59 60 /** Allocate memory for gpt header */ 61 gpt_t * gpt_alloc_gpt_header() 62 { 63 return malloc(sizeof(gpt_t)); 64 } 65 60 66 /** Read GPT from specific device 61 67 * @param dev_handle device to read GPT from … … 162 168 163 169 return 0; 170 } 171 172 /** Alloc partition array */ 173 gpt_partitions_t * gpt_alloc_partitions() 174 { 175 return alloc_part_array(128); 164 176 } 165 177 -
uspace/lib/gpt/libgpt.h
r8f6c7785 r700f89e 139 139 140 140 141 141 extern gpt_t * gpt_alloc_gpt_header(); 142 142 extern gpt_t * gpt_read_gpt_header(service_id_t dev_handle); 143 143 extern int gpt_write_gpt_header(gpt_t * header, service_id_t dev_handle); 144 144 145 extern gpt_partitions_t * gpt_alloc_partitions(); 145 146 extern gpt_partitions_t * gpt_read_partitions (gpt_t * gpt); 146 147 extern int gpt_write_partitions (gpt_partitions_t * parts, gpt_t * header, service_id_t dev_handle); -
uspace/lib/mbr/libmbr.c
r8f6c7785 r700f89e 53 53 static int check_preceeds(mbr_part_t * preceeder, mbr_part_t * precedee); 54 54 55 static void debug_print(unsigned char * data, size_t bytes); 55 /** Allocate memory for mbr_t */ 56 mbr_t * mbr_alloc_mbr() 57 { 58 return alloc_br(); 59 } 56 60 57 61 /** Read MBR from specific device … … 71 75 rc = block_init(EXCHANGE_ATOMIC, dev_handle, 512); 72 76 if (rc != EOK) { 77 free(mbr); 73 78 return NULL; 74 79 } … … 76 81 rc = block_read_direct(dev_handle, 0, 1, &(mbr->raw_data)); 77 82 if (rc != EOK) { 83 free(mbr); 78 84 block_fini(dev_handle); 79 85 return NULL; … … 83 89 84 90 mbr->device = dev_handle; 85 //mbr->partitions = NULL;86 91 87 92 return mbr; … … 93 98 * from the device in 'mbr') 94 99 * 95 * @return 0 on success, -1 on block_init error, -2 on write error100 * @return 0 on success, otherwise libblock error code 96 101 */ 97 102 int mbr_write_mbr(mbr_t * mbr, service_id_t dev_handle) … … 149 154 continue; 150 155 151 //p = malloc(sizeof(mbr_part_t));152 156 p = mbr_alloc_partition(); 153 157 if (p == NULL) { … … 156 160 return NULL; 157 161 } 158 //list_append(&(p->link), &(parts->list));162 159 163 rc_ext = decode_part(&(mbr->raw_data.pte[i]), p, 0); 160 164 mbr_set_flag(p, ST_LOGIC, false); … … 179 183 } 180 184 181 //DEBUG:182 //debug_print((unsigned char *) list_get_instance(list_last(&(parts->list)), mbr_part_t, link)->ebr, 512);183 185 return parts; 184 186 } … … 193 195 int mbr_write_partitions(mbr_partitions_t * parts, mbr_t * mbr, service_id_t dev_handle) 194 196 { 195 //bool logical = false;196 197 int i = 0; 197 198 int rc; … … 200 201 : list_get_instance(parts->l_extended, mbr_part_t, link); 201 202 202 //br_block_t * last_ebr = NULL;203 //link_t * it;204 205 DEBUG_PRINT_3(LIBMBR_NAME "Writing partitions: n_primary: %u, n_logical:%u, l_extended:%p", parts->n_primary, parts->n_logical, parts->l_extended);206 207 203 rc = block_init(EXCHANGE_ATOMIC, dev_handle, 512); 208 204 if (rc != EOK) { 209 DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d):%s.\n", rc, str_error(rc));205 printf(LIBMBR_NAME ": Error while initializing libblock: %d - %s.\n", rc, str_error(rc)); 210 206 return rc; 211 207 } 212 /*213 // Encoding primary partitions214 for (i = 0; i < parts->n_primary; i++) {215 encode_part(p, &(mbr->raw_data.pte[i]), 0);216 }217 218 // Writing MBR219 rc = block_write_direct(dev_handle, 0, 1, &(mbr->raw_data));220 if (rc != EOK) {221 DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc));222 goto end;223 }224 225 uint32_t base = ext->start_addr;226 uint32_t addr = base;227 228 // Encoding and writing logical partitions229 mbr_part_foreach(parts, p) {230 if (p->ebr == NULL) {231 p->ebr = alloc_br();232 if (p->ebr == NULL)233 {234 rc = ENOMEM;235 goto end;236 }237 }238 239 240 }*/241 208 242 209 link_t * l = parts->list.head.next; … … 252 219 rc = block_write_direct(dev_handle, 0, 1, &(mbr->raw_data)); 253 220 if (rc != EOK) { 254 DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d):%s.\n", rc, str_error(rc));221 printf(LIBMBR_NAME ": Error while writing MBR : %d - %s.\n", rc, str_error(rc)); 255 222 goto end; 256 223 } 257 224 258 225 if (ext == NULL) 259 goto no_extended; 260 261 //DEBUG: 262 //debug_print((unsigned char *) list_get_instance(list_last(&(parts->list)), mbr_part_t, link)->ebr, 512); 226 goto end; 227 263 228 uint32_t base = ext->start_addr; 264 //uint32_t addr = base;265 //uint32_t prev_addr;266 //mbr_part_t * tmp;267 229 mbr_part_t * prev_p; 230 231 /* Note for future changes: Some thought has been put into design 232 * and implementation. If you don't have to change it, don't. Other 233 * designs have been tried, this came out as the least horror with 234 * as much power over it as you can get. Thanks. */ 235 268 236 // Encoding and writing first logical partition 269 237 if (l != &(parts->list.head)) { … … 271 239 p->ebr_addr = base; 272 240 encode_part(p, &(p->ebr->pte[0]), base, false); 273 274 /*if (l->next == &(parts->list.head)) 275 encode_part(NULL, &(p->ebr->pte[1]), base, false); 276 else { 277 tmp = list_get_instance(l->next, mbr_part_t, link); 278 //debug_print((unsigned char*) p->ebr, 512); 279 printf("DEBUG: base: %u, tmp: start: %u, end: %u\n", base, tmp->start_addr, tmp->start_addr + tmp->length); 280 //encode_part(tmp, &(p->ebr->pte[1]), base); 281 encode_part(tmp, &(p->ebr->pte[1]), base, true); 282 debug_print(((unsigned char*) p->ebr) + 446, 32); 283 } 284 285 rc = block_write_direct(dev_handle, base, 1, p->ebr); 241 l = l->next; 242 } else { 243 /* If there was an extended but no logical, we should overwrite 244 * the space where the first logical's EBR would have been. There 245 * might be some garbage from the past. */ 246 br_block_t * tmp = alloc_br(); 247 rc = block_write_direct(dev_handle, base, 1, tmp); 286 248 if (rc != EOK) { 287 DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d):%s.\n", rc, str_error(rc));249 printf(LIBMBR_NAME ": Error while writing EBR: %d - %s.\n", rc, str_error(rc)); 288 250 goto end; 289 }*/ 290 291 l = l->next; 292 } else 293 goto no_logical; 294 295 //prev_addr = base; 251 } 252 free(tmp); 253 goto end; 254 } 255 296 256 prev_p = p; 297 257 … … 314 274 315 275 encode_part(p, &(p->ebr->pte[0]), p->ebr_addr, false); 316 debug_print(((unsigned char*) p->ebr) + 446, 32);317 276 encode_part(p, &(prev_p->ebr->pte[1]), base, true); 318 debug_print(((unsigned char*) prev_p->ebr) + 446, 32);319 /*if (l->next == &(parts->list.head))320 encode_part(NULL, &(p->ebr->pte[1]), base, false);321 else322 encode_part(list_get_instance(l->next, mbr_part_t, link), &(p->ebr->pte[1]), base, true);323 */324 277 325 278 rc = block_write_direct(dev_handle, prev_p->ebr_addr, 1, prev_p->ebr); 326 279 if (rc != EOK) { 327 DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d):%s.\n", rc, str_error(rc));280 printf(LIBMBR_NAME ": Error while writing EBR: %d - %s.\n", rc, str_error(rc)); 328 281 goto end; 329 282 } … … 333 286 } 334 287 288 // write the last EBR 335 289 encode_part(NULL, &(prev_p->ebr->pte[1]), 0, false); 336 290 rc = block_write_direct(dev_handle, prev_p->ebr_addr, 1, prev_p->ebr); 337 291 if (rc != EOK) { 338 DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d):%s.\n", rc, str_error(rc));292 printf(LIBMBR_NAME ": Error while writing EBR: %d - %s.\n", rc, str_error(rc)); 339 293 goto end; 340 294 } 341 342 no_logical:343 no_extended:344 345 /*if (ext == NULL)346 goto no_extended;347 348 uint32_t base = ext->start_addr;349 uint32_t addr;// = base;350 uint32_t prev_addr;351 mbr_part_t * prev_part = NULL;352 353 list_foreach(parts->list, iter) {354 p = list_get_instance(iter, mbr_part_t, link);355 if (mbr_get_flag(p, ST_LOGIC)) {356 // writing logical partition357 logical = true;358 359 if (p->ebr == NULL) {360 p->ebr = alloc_br();361 if (p->ebr == NULL)362 {363 rc = ENOMEM;364 goto end;365 }366 }367 368 if (prev_part != NULL) {369 // addr is the address of EBR370 addr = p->start_addr - base;371 // base-1 means start_lba+1372 encode_part(p, &(p->ebr->pte[0]), addr - 1);373 encode_part(p, &(prev_part->ebr->pte[1]), base);374 rc = block_write_direct(dev_handle, prev_addr, 1, prev_part->ebr);375 if (rc != EOK) {376 DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc));377 goto end;378 }379 } else {380 // addr is the address of EBR381 addr = base;382 // base-1 means start_lba+1383 // Fixed: mbr_add_partition now performs checks!nevim384 encode_part(p, &(p->ebr->pte[0]), base);385 }386 387 //addr = p->start_addr;388 prev_addr = addr;389 prev_part = p;390 } else {391 // writing primary partition392 if (i >= 4) {393 rc = EINVAL;394 goto end;395 }396 397 encode_part(p, &(mbr->raw_data.pte[i]), 0);398 399 ++i;400 }401 } //*/402 403 /* If there was an extended but no logical, we should overwrite404 * the space where the first logical's EBR would have been. There405 * might be some garbage from the past.406 */407 /*408 last_ebr = prev_part->ebr;409 410 if (!logical)411 {412 last_ebr = alloc_br();413 if (last_ebr == NULL) {414 rc = ENOMEM;415 goto end;416 }417 418 last_ebr->pte[0].ptype = PT_UNUSED;419 }420 421 422 encode_part(NULL, &(last_ebr->pte[1]), 0);423 rc = block_write_direct(dev_handle, addr, 1, last_ebr);424 425 if (!logical)426 {427 free(last_ebr);428 }429 */430 /*431 if (rc != EOK) {432 DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc));433 goto end;434 }435 436 goto skip;437 438 no_extended:439 */440 /*list_foreach(parts->list, it) {441 p = list_get_instance(it, mbr_part_t, link);442 if (mbr_get_flag(p, ST_LOGIC)) {443 // extended does not exist, fail444 return EINVAL;445 } else {446 // writing primary partition447 if (i >= 4)448 return EINVAL;449 450 encode_part(p, &(mbr->raw_data.pte[i]), 0);451 452 ++i;453 }454 }*/455 /*456 it = parts->list.head.next;457 for (i = 0; i < N_PRIMARY; i++) {458 if (it != &parts->list.head) {459 p = list_get_instance(it, mbr_part_t, link);460 if (mbr_get_flag(p, ST_LOGIC)) {461 // extended does not exist, fail462 return EINVAL;463 } else {464 // writing primary partition465 if (i >= 4)466 return EINVAL;467 468 encode_part(p, &(mbr->raw_data.pte[i]), 0);469 470 }471 472 it = it->next;473 } else {474 encode_part(NULL, &(mbr->raw_data.pte[i]), 0);475 }476 }477 478 479 skip:480 rc = block_write_direct(dev_handle, 0, 1, &(mbr->raw_data));481 if (rc != EOK) {482 DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc));483 goto end;484 }485 */486 487 /*488 for (i = 0; i < N_PRIMARY; ++i) {489 encode_part(&(p->partition), &(mbr->raw_data.pte[i]), 0);490 if (p->type == PT_EXTENDED)491 ext = p;492 493 //p = list_get_instance(p->link.next, mbr_partitions_t, link);494 p = p->next;495 }496 497 rc = block_write_direct(dev_handle, 0, 1, &(mbr->raw_data));498 if (rc != EOK) {499 block_fini(dev_handle);500 return rc;501 }502 503 //writing logical partitions504 505 if (p == NULL && ext != NULL) {506 //we need an empty EBR to rewrite the old EBR on disk, if we need to delete it507 br_block_t * temp_ebr = alloc_br();508 if (temp_ebr == NULL) {509 block_fini(dev_handle);510 return ENOMEM;511 }512 513 temp_ebr->pte[0].ptype = PT_UNUSED;514 encode_part(NULL, &(temp_ebr->pte[1]), 0);515 rc = block_write_direct(dev_handle, ext->start_addr, 1, temp_ebr);516 free(temp_ebr);517 block_fini(dev_handle);518 return rc;519 }520 521 if (p != NULL && ext == NULL) {522 block_fini(dev_handle);523 //no extended but one or more logical? EINVAL to the rescue!524 return EINVAL;525 }526 527 aoff64_t addr = ext->start_addr;528 529 while (p != NULL) {530 if (p->type == PT_UNUSED) {531 p = p->next;532 continue;533 }534 //encode_part(p, &(p->ebr->pte[0]), p->start_addr - 63 * 512);535 encode_part(p, &(p->ebr->pte[0]), addr);536 encode_part(p->next, &(p->ebr->pte[1]), ext->start_addr);537 538 rc = block_write_direct(dev_handle, p->start_addr, 1, p->ebr);539 if (rc != EOK) {540 block_fini(dev_handle);541 return rc;542 }543 addr = p->start_addr;544 p = p->next;545 }*/546 295 547 296 rc = EOK; … … 560 309 return NULL; 561 310 } 311 562 312 link_initialize(&(p->link)); 563 313 p->ebr = NULL; … … 571 321 } 572 322 323 /** mbr_partitions_t constructor */ 573 324 mbr_partitions_t * mbr_alloc_partitions(void) 574 325 { … … 579 330 580 331 list_initialize(&(parts->list)); 581 582 332 parts->n_primary = 0; 583 333 parts->n_logical = 0; … … 589 339 /** Add partition 590 340 * Performs checks, sorts the list. 591 */ 592 int mbr_add_partition(mbr_partitions_t * parts, mbr_part_t * p) 341 * 342 * @param parts partition list to add to 343 * @param p partition to add 344 * 345 * @return ERR_OK (0) on success, other MBR_ERR_VAL otherwise 346 */ 347 MBR_ERR_VAL mbr_add_partition(mbr_partitions_t * parts, mbr_part_t * p) 593 348 { 594 349 if (mbr_get_flag(p, ST_LOGIC)) { // adding logical part 595 if (parts->l_extended == NULL) { 350 // is there any extended partition? 351 if (parts->l_extended == NULL) 596 352 return ERR_NO_EXTENDED; 597 } 353 354 // is the logical partition inside the extended one? 598 355 mbr_part_t * ext = list_get_instance(parts->l_extended, mbr_part_t, link); 599 if (!check_encaps(p, ext)) { 600 //printf("DEBUG: OOB: start: %u, end: %u\n", h->start_addr, h->start_addr + h->length); 601 //printf("DEBUG: OOB: start: %u, end: %u\n", p->start_addr, p->start_addr + p->length); 356 if (!check_encaps(p, ext)) 602 357 return ERR_OUT_BOUNDS; 603 }604 358 359 // find a place for the new partition in a sorted linked list 605 360 mbr_part_t * last = list_get_instance(list_last(&(parts->list)), mbr_part_t, link); 606 361 mbr_part_t * iter; … … 608 363 mbr_part_foreach(parts, iter) { 609 364 if (mbr_get_flag(iter, ST_LOGIC)) { 610 if (check_overlap(p, iter)) { 611 //printf("DEBUG: overlap: start: %u, end: %u\n", iter->start_addr, iter->start_addr + iter->length); 612 //printf("DEBUG: overlap: start: %u, end: %u\n", p->start_addr, p->start_addr + p->length); 365 if (check_overlap(p, iter)) 613 366 return ERR_OVERLAP; 614 }615 367 if (check_preceeds(iter, p)) { 616 368 last = iter; … … 622 374 623 375 // checking if there's at least one sector of space preceeding 624 625 376 if (ebr_space < 1) 626 377 return ERR_NO_EBR; … … 628 379 // checking if there's at least one sector of space following (for following partitions's EBR) 629 380 if (last->link.next != &(parts->list.head)) { 630 if (list_get_instance(&(last->link.next), mbr_part_t, link)->start_addr <= p->start_addr + p->length + 1) {381 if (list_get_instance(&(last->link.next), mbr_part_t, link)->start_addr <= p->start_addr + p->length + 1) 631 382 return ERR_NO_EBR; 632 633 }634 383 } 384 385 // alloc EBR if it's not already there 635 386 if (p->ebr == NULL) { 636 387 p->ebr = alloc_br(); … … 640 391 } 641 392 642 //printf("DEBUG: last: start: %u\n", last->start_addr); 643 //list_prepend(&(p->link), &(parts->list)); 393 // add it 644 394 list_insert_after(&(p->link), &(last->link)); 645 395 parts->n_logical += 1; 646 } else { 647 // adding primary 396 } else { // adding primary 648 397 if (parts->n_primary == 4) { 649 398 return ERR_PRIMARY_FULL; 650 399 } 651 400 652 // should we check if it's inside the drive's upper boundary?401 // TODO: should we check if it's inside the drive's upper boundary? 653 402 if (p->start_addr == 0) { 654 403 return ERR_OUT_BOUNDS; 655 404 } 656 405 406 // if it's extended, is there any other one? 657 407 if (p->type == PT_EXTENDED && parts->l_extended != NULL) { 658 408 return ERR_EXTENDED_PRESENT; 659 409 } 660 410 411 // find a place and add it 661 412 if (list_empty(&(parts->list))) { 662 413 list_append(&(p->link), &(parts->list)); … … 667 418 list_insert_before(&(p->link), &(iter->link)); 668 419 break; 669 } else if (check_overlap(p, iter)) {420 } else if (check_overlap(p, iter)) 670 421 return ERR_OVERLAP; 671 }672 422 } 673 if (iter == list_get_instance(&(parts->list.head.prev), mbr_part_t, link)) {423 if (iter == list_get_instance(&(parts->list.head.prev), mbr_part_t, link)) 674 424 list_append(&(p->link), &(parts->list)); 425 } 426 parts->n_primary += 1; 427 } 428 429 return ERR_OK; 430 } 431 432 /** Remove partition 433 * Removes partition by index, indexed from zero. When removing extended 434 * partition, all logical partitions get removed as well. 435 * 436 * @param parts partition list to remove from 437 * @param idx index of the partition to remove 438 * 439 * @return EOK on success, EINVAL if idx invalid 440 */ 441 int mbr_remove_partition(mbr_partitions_t * parts, size_t idx) 442 { 443 link_t * l = list_nth(&(parts->list), idx); 444 if (l == NULL) 445 return EINVAL; 446 447 mbr_part_t * p; 448 449 /* TODO: if it is extended partition, should we also remove all logical? 450 * If we don't, we break the consistency of the list. If we do, 451 * the user will have to input them all over again. So yes. */ 452 if (l == parts->l_extended) { 453 parts->l_extended = NULL; 454 455 link_t * it = l->next; 456 link_t * next_it; 457 while (it != &(parts->list.head)) { 458 next_it = it->next; 459 460 p = list_get_instance(it, mbr_part_t, link); 461 if (mbr_get_flag(p, ST_LOGIC)) { 462 list_remove(it); 463 parts->n_logical -= 1; 464 mbr_free_partition(p); 675 465 } 676 466 677 } 678 parts->n_primary += 1; 679 } 680 681 return ERR_OK; 682 } 683 684 /** Remove partition */ 685 int mbr_remove_partition(mbr_partitions_t * parts, size_t idx) 686 { 687 DEBUG_PRINT_1(LIBMBR_NAME "Removing partition: %zu\n", idx); 688 link_t * l = list_nth(&(parts->list), idx); 689 if (l == parts->l_extended) { 690 DEBUG_PRINT_0(LIBMBR_NAME "Removing extended partition.\n"); 691 parts->l_extended = NULL; 692 } 467 it = next_it; 468 } 469 470 } 471 693 472 list_remove(l); 694 mbr_part_t * p = list_get_instance(l, mbr_part_t, link); 695 if (mbr_get_flag(p, ST_LOGIC)) { 473 474 p = list_get_instance(l, mbr_part_t, link); 475 if (mbr_get_flag(p, ST_LOGIC)) 696 476 parts->n_logical -= 1; 697 } else {477 else 698 478 parts->n_primary -= 1; 699 } 700 701 479 480 702 481 mbr_free_partition(p); 703 482 704 483 return EOK; 705 484 } … … 769 548 770 549 memset(br, 0, 512); 771 br->media_id = 0;772 br->pad0 = 0;773 550 br->signature = host2uint16_t_le(BR_SIGNATURE); 774 551 … … 847 624 p->ebr_addr = addr; 848 625 rc = mbr_add_partition(parts, p); 849 if (rc != ERR_OK) { 850 printf(LIBMBR_NAME ": Error occured during decoding the MBR. (%d)\n" \ 851 LIBMBR_NAME ": Partition list may be incomplete.\n", rc); 626 if (rc != ERR_OK) 852 627 return EINVAL; 853 }854 628 855 629 addr = uint32_t_le2host(ebr->pte[1].first_lba) + base; 856 printf("DEBUG: b: %u, a: %u, start: %u\n", base, addr, ebr->pte[1].first_lba);857 630 858 631 while (ebr->pte[1].ptype != PT_UNUSED) { … … 879 652 } 880 653 881 //printf("DEBUG: b: %u, a: %u, start: %u\n", base, addr, ebr->pte[0].first_lba);654 882 655 decode_part(&(ebr->pte[0]), p, addr); 883 656 mbr_set_flag(p, ST_LOGIC, true); … … 885 658 p->ebr_addr = addr; 886 659 rc = mbr_add_partition(parts, p); 887 if (rc != ERR_OK) { 888 printf(LIBMBR_NAME ": Error occured during decoding the MBR. (%d)\n" \ 889 LIBMBR_NAME ": Partition list may be incomplete.\n", rc); 660 if (rc != ERR_OK) 890 661 return EINVAL; 891 }892 662 893 663 addr = uint32_t_le2host(ebr->pte[1].first_lba) + base; … … 934 704 } 935 705 706 /** Check whether two partitions overlap 707 * 708 * @return 1 for yes, 0 for no 709 */ 936 710 static int check_overlap(mbr_part_t * p1, mbr_part_t * p2) 937 711 { … … 945 719 } 946 720 721 /** Check whether one partition encapsulates the other 722 * 723 * @return 1 for yes, 0 for no 724 */ 947 725 static int check_encaps(mbr_part_t * inner, mbr_part_t * outer) 948 726 { … … 956 734 } 957 735 736 /** Check whether one partition preceeds the other 737 * 738 * @return 1 for yes, 0 for no 739 */ 958 740 static int check_preceeds(mbr_part_t * preceeder, mbr_part_t * precedee) 959 741 { … … 961 743 } 962 744 963 static void debug_print(unsigned char * data, size_t bytes) 964 { 965 size_t addr = 0; 966 int i; 967 968 while (bytes >= 16) { 969 printf("%8x ", addr); 970 for (i = 0; i < 8; i++) { 971 printf(" %2hhx", data[addr + i]); 972 } 973 printf(" "); 974 for (i = 0; i < 8; i++) { 975 printf(" %2hhx", data[addr + i + 8]); 976 } 977 printf("\n"); 978 979 bytes -= 16; 980 addr += 16; 981 } 982 983 984 } 985 986 987 745 746 747 -
uspace/lib/mbr/libmbr.h
r8f6c7785 r700f89e 188 188 * then partitions. The MBR headers' raw_data is NOT updated to follow 189 189 * partition changes. */ 190 extern mbr_t * mbr_alloc_mbr(); 190 191 extern mbr_t * mbr_read_mbr(service_id_t dev_handle); 191 192 extern int mbr_write_mbr(mbr_t * mbr, service_id_t dev_handle); … … 198 199 extern mbr_part_t * mbr_alloc_partition(void); 199 200 extern mbr_partitions_t * mbr_alloc_partitions(void); 200 extern intmbr_add_partition(mbr_partitions_t * parts, mbr_part_t * partition);201 extern MBR_ERR_VAL mbr_add_partition(mbr_partitions_t * parts, mbr_part_t * partition); 201 202 extern int mbr_remove_partition(mbr_partitions_t * parts, size_t idx); 202 203 extern int mbr_get_flag(mbr_part_t * p, MBR_FLAGS flag);
Note:
See TracChangeset
for help on using the changeset viewer.