Changeset 78d50bd in mainline for uspace/srv/bd/vbd/disk.c
- Timestamp:
- 2015-06-29T18:47:07Z (10 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 3faa03d
- Parents:
- 28ed0d9
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/bd/vbd/disk.c
r28ed0d9 r78d50bd 35 35 36 36 #include <adt/list.h> 37 #include <bd_srv.h> 38 #include <block.h> 37 39 #include <errno.h> 38 40 #include <io/log.h> 41 #include <loc.h> 42 #include <stdio.h> 39 43 #include <stdlib.h> 40 44 #include <task.h> … … 44 48 45 49 static list_t vbds_disks; /* of vbds_disk_t */ 50 static list_t vbds_parts; /* of vbds_part_t */ 51 52 static int vbds_bd_open(bd_srvs_t *, bd_srv_t *); 53 static int vbds_bd_close(bd_srv_t *); 54 static int vbds_bd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, size_t); 55 static int vbds_bd_sync_cache(bd_srv_t *, aoff64_t, size_t); 56 static int vbds_bd_write_blocks(bd_srv_t *, aoff64_t, size_t, const void *, 57 size_t); 58 static int vbds_bd_get_block_size(bd_srv_t *, size_t *); 59 static int vbds_bd_get_num_blocks(bd_srv_t *, aoff64_t *); 60 61 static int vbds_bsa_translate(vbds_part_t *, aoff64_t, size_t, aoff64_t *); 62 63 static bd_ops_t vbds_bd_ops = { 64 .open = vbds_bd_open, 65 .close = vbds_bd_close, 66 .read_blocks = vbds_bd_read_blocks, 67 .sync_cache = vbds_bd_sync_cache, 68 .write_blocks = vbds_bd_write_blocks, 69 .get_block_size = vbds_bd_get_block_size, 70 .get_num_blocks = vbds_bd_get_num_blocks 71 }; 72 73 static vbds_part_t *bd_srv_part(bd_srv_t *bd) 74 { 75 return (vbds_part_t *)bd->srvs->sarg; 76 } 46 77 47 78 void vbds_disks_init(void) 48 79 { 49 80 list_initialize(&vbds_disks); 81 list_initialize(&vbds_parts); 50 82 } 51 83 … … 62 94 } 63 95 96 static int vbds_part_by_id(vbds_part_id_t partid, vbds_part_t **rpart) 97 { 98 list_foreach(vbds_parts, lparts, vbds_part_t, part) { 99 if (part->id == partid) { 100 *rpart = part; 101 return EOK; 102 } 103 } 104 105 return ENOENT; 106 } 107 64 108 static int vbds_part_add(vbds_disk_t *disk, label_part_t *lpart) 65 109 { 66 110 vbds_part_t *part; 67 68 log_msg(LOG_DEFAULT, LVL_NOTE, "vbds_part_add(%p, %p)", 69 disk, lpart); 111 service_id_t psid; 112 label_part_info_t lpinfo; 113 char *name; 114 int pno; 115 int rc; 116 117 log_msg(LOG_DEFAULT, LVL_NOTE, "vbds_part_add(%s, %p)", 118 disk->svc_name, lpart); 70 119 71 120 part = calloc(1, sizeof(vbds_part_t)); … … 75 124 } 76 125 126 /* XXX Proper service name */ 127 pno = list_count(&disk->parts); 128 rc = asprintf(&name, "%sp%u", disk->svc_name, pno); 129 if (rc < 0) { 130 log_msg(LOG_DEFAULT, LVL_ERROR, "Out of memory."); 131 return ENOMEM; 132 } 133 134 rc = loc_service_register(name, &psid); 135 if (rc != EOK) { 136 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering " 137 "service %s.", name); 138 free(name); 139 free(part); 140 return EIO; 141 } 142 143 free(name); 144 label_part_get_info(lpart, &lpinfo); 145 77 146 part->lpart = lpart; 78 147 part->disk = disk; 148 part->block0 = lpinfo.block0; 149 part->nblocks = lpinfo.nblocks; 150 151 bd_srvs_init(&part->bds); 152 part->bds.ops = &vbds_bd_ops; 153 part->bds.sarg = part; 154 79 155 list_append(&part->ldisk, &disk->parts); 156 list_append(&part->lparts, &vbds_parts); 80 157 81 158 return EOK; … … 86 163 label_t *label; 87 164 label_part_t *part; 88 vbds_disk_t *disk; 165 vbds_disk_t *disk = NULL; 166 bool block_inited = false; 167 size_t block_size; 89 168 int rc; 90 169 … … 100 179 return ENOMEM; 101 180 181 rc = loc_service_get_name(sid, &disk->svc_name); 182 if (rc != EOK) { 183 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed getting disk service name."); 184 rc = EIO; 185 goto error; 186 } 187 188 rc = block_init(EXCHANGE_SERIALIZE, sid, 2048); 189 if (rc != EOK) { 190 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed opening block device %s.", 191 disk->svc_name); 192 rc = EIO; 193 goto error; 194 } 195 196 rc = block_get_bsize(sid, &block_size); 197 if (rc != EOK) { 198 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed getting block size of %s.", 199 disk->svc_name); 200 rc = EIO; 201 goto error; 202 } 203 204 block_inited = true; 205 102 206 rc = label_open(sid, &label); 103 if (rc != EOK) 104 goto error; 207 if (rc != EOK) { 208 rc = EIO; 209 goto error; 210 } 105 211 106 212 disk->svc_id = sid; 107 213 disk->label = label; 214 disk->block_size = block_size; 215 108 216 list_initialize(&disk->parts); 109 217 list_append(&disk->ldisks, &vbds_disks); … … 113 221 rc = vbds_part_add(disk, part); 114 222 if (rc != EOK) { 115 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed adding partition."); 223 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed adding partitio " 224 "(disk %s)", disk->svc_name); 116 225 } 117 226 … … 121 230 return EOK; 122 231 error: 232 label_close(label); 233 if (block_inited) 234 block_fini(sid); 235 if (disk != NULL) 236 free(disk->svc_name); 123 237 free(disk); 124 238 return rc; … … 181 295 int vbds_label_delete(service_id_t sid) 182 296 { 183 return EOK;184 297 vbds_disk_t *disk; 185 298 int rc; … … 202 315 } 203 316 204 int vbds_part_get_info(vbds_part_id_t part, vbds_part_info_t *pinfo) 205 { 206 return EOK; 207 } 208 209 int vbds_part_create(service_id_t disk, vbds_part_id_t *rpart) 210 { 211 return EOK; 212 } 213 214 int vbds_part_delete(vbds_part_id_t part) 215 { 317 int vbds_part_get_info(vbds_part_id_t partid, vbds_part_info_t *pinfo) 318 { 319 vbds_part_t *part; 320 int rc; 321 322 rc = vbds_part_by_id(partid, &part); 323 if (rc != EOK) 324 return rc; 325 326 return EOK; 327 } 328 329 int vbds_part_create(service_id_t sid, vbds_part_id_t *rpart) 330 { 331 vbds_disk_t *disk; 332 vbds_part_t *part; 333 label_part_spec_t pspec; 334 label_part_t *lpart; 335 int rc; 336 337 part = calloc(1, sizeof(vbds_part_t)); 338 if (part == NULL) 339 return ENOMEM; 340 341 rc = vbds_disk_by_svcid(sid, &disk); 342 if (rc != EOK) { 343 log_msg(LOG_DEFAULT, LVL_NOTE, "Partition %zu not found", 344 sid); 345 goto error; 346 } 347 348 label_pspec_init(&pspec); 349 rc = label_part_create(disk->label, &pspec, &lpart); 350 if (rc != EOK) { 351 log_msg(LOG_DEFAULT, LVL_ERROR, "Error creating partition."); 352 goto error; 353 } 354 355 rc = vbds_part_add(disk, lpart); 356 if (rc != EOK) { 357 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed while creating " 358 "partition."); 359 rc = label_part_destroy(lpart); 360 if (rc != EOK) 361 log_msg(LOG_DEFAULT, LVL_ERROR, 362 "Cannot roll back partition creation."); 363 rc = EIO; 364 goto error; 365 } 366 367 return EOK; 368 error: 369 free(part); 370 return rc; 371 } 372 373 int vbds_part_delete(vbds_part_id_t partid) 374 { 375 vbds_part_t *part; 376 int rc; 377 378 rc = vbds_part_by_id(partid, &part); 379 if (rc != EOK) 380 return rc; 381 382 rc = label_part_destroy(part->lpart); 383 if (rc != EOK) 384 return rc; 385 386 list_remove(&part->ldisk); 387 list_remove(&part->lparts); 388 free(part); 389 return EOK; 390 } 391 392 static int vbds_bd_open(bd_srvs_t *bds, bd_srv_t *bd) 393 { 394 vbds_part_t *part = bd_srv_part(bd); 395 396 log_msg(LOG_DEFAULT, LVL_NOTE, "vbds_bd_open()"); 397 part->open_cnt++; 398 return EOK; 399 } 400 401 static int vbds_bd_close(bd_srv_t *bd) 402 { 403 vbds_part_t *part = bd_srv_part(bd); 404 405 log_msg(LOG_DEFAULT, LVL_NOTE, "vbds_bd_close()"); 406 part->open_cnt--; 407 return EOK; 408 } 409 410 static int vbds_bd_read_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt, 411 void *buf, size_t size) 412 { 413 vbds_part_t *part = bd_srv_part(bd); 414 aoff64_t gba; 415 416 log_msg(LOG_DEFAULT, LVL_NOTE, "vbds_bd_read_blocks()"); 417 418 if (cnt * part->disk->block_size < size) 419 return EINVAL; 420 421 if (vbds_bsa_translate(part, ba, cnt, &gba) != EOK) 422 return ELIMIT; 423 424 return block_read_direct(part->disk->svc_id, gba, cnt, buf); 425 } 426 427 static int vbds_bd_sync_cache(bd_srv_t *bd, aoff64_t ba, size_t cnt) 428 { 429 vbds_part_t *part = bd_srv_part(bd); 430 aoff64_t gba; 431 432 log_msg(LOG_DEFAULT, LVL_NOTE, "vbds_bd_sync_cache()"); 433 434 /* XXX Allow full-disk sync? */ 435 if (ba != 0 || cnt != 0) { 436 if (vbds_bsa_translate(part, ba, cnt, &gba) != EOK) 437 return ELIMIT; 438 } else { 439 gba = 0; 440 } 441 442 return block_sync_cache(part->disk->svc_id, gba, cnt); 443 } 444 445 static int vbds_bd_write_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt, 446 const void *buf, size_t size) 447 { 448 vbds_part_t *part = bd_srv_part(bd); 449 aoff64_t gba; 450 451 log_msg(LOG_DEFAULT, LVL_NOTE, "vbds_bd_write_blocks()"); 452 453 if (cnt * part->disk->block_size < size) 454 return EINVAL; 455 456 if (vbds_bsa_translate(part, ba, cnt, &gba) != EOK) 457 return ELIMIT; 458 459 return block_write_direct(part->disk->svc_id, gba, cnt, buf); 460 } 461 462 static int vbds_bd_get_block_size(bd_srv_t *bd, size_t *rsize) 463 { 464 log_msg(LOG_DEFAULT, LVL_NOTE, "vbds_bd_get_block_size()"); 465 return EOK; 466 } 467 468 static int vbds_bd_get_num_blocks(bd_srv_t *bd, aoff64_t *rnb) 469 { 470 log_msg(LOG_DEFAULT, LVL_NOTE, "vbds_bd_get_num_blocks()"); 471 return EOK; 472 } 473 474 void vbds_bd_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg) 475 { 476 vbds_part_t *part; 477 int rc; 478 service_id_t partid; 479 480 partid = IPC_GET_ARG1(*icall); 481 482 rc = vbds_part_by_id(partid, &part); 483 if (rc != EOK) { 484 async_answer_0(iid, EINVAL); 485 return; 486 } 487 488 bd_conn(iid, icall, &part->bds); 489 } 490 491 /** Translate block segment address with range checking. */ 492 static int vbds_bsa_translate(vbds_part_t *part, aoff64_t ba, size_t cnt, 493 aoff64_t *gba) 494 { 495 if (ba + cnt > part->nblocks) 496 return ELIMIT; 497 498 *gba = part->block0 + ba; 216 499 return EOK; 217 500 }
Note:
See TracChangeset
for help on using the changeset viewer.