Changeset e11c527 in mainline
- Timestamp:
- 2016-02-18T14:31:00Z (9 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 53e3950
- Parents:
- 8e670dd
- Location:
- uspace/srv/bd/vbd
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/bd/vbd/disk.c
r8e670dd re11c527 1 1 /* 2 * Copyright (c) 201 5Jiri Svoboda2 * Copyright (c) 2016 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 50 50 static fibril_mutex_t vbds_disks_lock; 51 51 static list_t vbds_disks; /* of vbds_disk_t */ 52 static fibril_mutex_t vbds_parts_lock; 52 53 static list_t vbds_parts; /* of vbds_part_t */ 53 54 … … 55 56 56 57 static int vbds_disk_parts_add(vbds_disk_t *, label_t *); 57 static int vbds_disk_parts_remove(vbds_disk_t * );58 static int vbds_disk_parts_remove(vbds_disk_t *, vbds_rem_flag_t); 58 59 59 60 static int vbds_bd_open(bd_srvs_t *, bd_srv_t *); … … 120 121 fibril_mutex_initialize(&vbds_disks_lock); 121 122 list_initialize(&vbds_disks); 123 fibril_mutex_initialize(&vbds_parts_lock); 122 124 list_initialize(&vbds_parts); 123 125 … … 222 224 } 223 225 226 static void vbds_part_add_ref(vbds_part_t *part) 227 { 228 log_msg(LOG_DEFAULT, LVL_DEBUG2, "vbds_part_add_ref"); 229 atomic_inc(&part->refcnt); 230 } 231 232 static void vbds_part_del_ref(vbds_part_t *part) 233 { 234 log_msg(LOG_DEFAULT, LVL_DEBUG2, "vbds_part_del_ref"); 235 if (atomic_predec(&part->refcnt) == 0) { 236 log_msg(LOG_DEFAULT, LVL_DEBUG2, " - free part"); 237 free(part); 238 } 239 } 240 224 241 static int vbds_part_by_pid(vbds_part_id_t partid, vbds_part_t **rpart) 225 242 { 226 243 log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_part_by_pid(%zu)", partid); 244 245 fibril_mutex_lock(&vbds_parts_lock); 227 246 228 247 list_foreach(vbds_parts, lparts, vbds_part_t, part) { … … 230 249 if (part->pid == partid) { 231 250 log_msg(LOG_DEFAULT, LVL_DEBUG, "Found match."); 251 vbds_part_add_ref(part); 252 fibril_mutex_unlock(&vbds_parts_lock); 232 253 *rpart = part; 233 254 return EOK; … … 235 256 } 236 257 258 fibril_mutex_unlock(&vbds_parts_lock); 237 259 log_msg(LOG_DEFAULT, LVL_DEBUG, "No match."); 238 260 return ENOENT; … … 242 264 { 243 265 log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_part_by_svcid(%zu)", svcid); 266 267 fibril_mutex_lock(&vbds_parts_lock); 244 268 245 269 list_foreach(vbds_parts, lparts, vbds_part_t, part) { … … 247 271 if (part->svc_id == svcid) { 248 272 log_msg(LOG_DEFAULT, LVL_DEBUG, "Found match."); 273 vbds_part_add_ref(part); 274 fibril_mutex_unlock(&vbds_parts_lock); 249 275 *rpart = part; 250 276 return EOK; … … 252 278 } 253 279 280 fibril_mutex_unlock(&vbds_parts_lock); 254 281 log_msg(LOG_DEFAULT, LVL_DEBUG, "No match."); 255 282 return ENOENT; … … 275 302 return ENOMEM; 276 303 } 304 305 fibril_rwlock_initialize(&part->lock); 277 306 278 307 part->lpart = lpart; … … 282 311 part->block0 = lpinfo.block0; 283 312 part->nblocks = lpinfo.nblocks; 313 atomic_set(&part->refcnt, 1); 284 314 285 315 bd_srvs_init(&part->bds); … … 289 319 if (lpinfo.pkind != lpk_extended) { 290 320 rc = vbds_part_svc_register(part); 291 if (rc != EOK) 321 if (rc != EOK) { 322 free(part); 292 323 return EIO; 324 } 293 325 } 294 326 295 327 list_append(&part->ldisk, &disk->parts); 328 fibril_mutex_lock(&vbds_parts_lock); 296 329 list_append(&part->lparts, &vbds_parts); 330 fibril_mutex_unlock(&vbds_parts_lock); 297 331 298 332 log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_part_add -> %p", part); … … 305 339 /** Remove partition from our inventory leaving only the underlying liblabel 306 340 * partition structure. 341 * 342 * @param part Partition 343 * @param flag If set to @c vrf_force, force removal even if partition is in use 344 * @param rlpart Place to store pointer to liblabel partition 307 345 */ 308 static int vbds_part_remove(vbds_part_t *part, label_part_t **rlpart) 346 static int vbds_part_remove(vbds_part_t *part, vbds_rem_flag_t flag, 347 label_part_t **rlpart) 309 348 { 310 349 label_part_t *lpart; … … 313 352 log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_part_remove(%p)", part); 314 353 354 fibril_rwlock_write_lock(&part->lock); 315 355 lpart = part->lpart; 316 356 317 if (part->open_cnt > 0) { 357 if ((flag & vrf_force) == 0 && part->open_cnt > 0) { 358 fibril_rwlock_write_unlock(&part->lock); 318 359 log_msg(LOG_DEFAULT, LVL_DEBUG, "part->open_cnt = %d", 319 360 part->open_cnt); … … 323 364 if (part->svc_id != 0) { 324 365 rc = vbds_part_svc_unregister(part); 325 if (rc != EOK) 366 if (rc != EOK) { 367 fibril_rwlock_write_unlock(&part->lock); 326 368 return EIO; 369 } 327 370 } 328 371 329 372 list_remove(&part->ldisk); 373 fibril_mutex_lock(&vbds_parts_lock); 330 374 list_remove(&part->lparts); 331 free(part); 375 fibril_mutex_unlock(&vbds_parts_lock); 376 377 vbds_part_del_ref(part); 378 part->lpart = NULL; 379 fibril_rwlock_write_unlock(&part->lock); 332 380 333 381 if (rlpart != NULL) … … 360 408 /** Remove all disk partitions from our inventory leaving only the underlying 361 409 * liblabel partition structures. */ 362 static int vbds_disk_parts_remove(vbds_disk_t *disk )410 static int vbds_disk_parts_remove(vbds_disk_t *disk, vbds_rem_flag_t flag) 363 411 { 364 412 link_t *link; … … 369 417 while (link != NULL) { 370 418 part = list_get_instance(link, vbds_part_t, ldisk); 371 rc = vbds_part_remove(part, NULL);419 rc = vbds_part_remove(part, flag, NULL); 372 420 if (rc != EOK) 373 421 return rc; … … 486 534 return rc; 487 535 488 rc = vbds_disk_parts_remove(disk );536 rc = vbds_disk_parts_remove(disk, vrf_force); 489 537 if (rc != EOK) { 490 538 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed removing disk."); … … 612 660 613 661 /* Close dummy label first */ 614 rc = vbds_disk_parts_remove(disk );662 rc = vbds_disk_parts_remove(disk, vrf_none); 615 663 if (rc != EOK) { 616 664 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed removing disk."); … … 661 709 return rc; 662 710 663 rc = vbds_disk_parts_remove(disk );711 rc = vbds_disk_parts_remove(disk, vrf_none); 664 712 if (rc != EOK) { 665 713 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed deleting label."); … … 696 744 if (rc != EOK) 697 745 return rc; 746 747 fibril_rwlock_read_lock(&part->lock); 748 if (part->lpart == NULL) { 749 fibril_rwlock_read_unlock(&part->lock); 750 return ENOENT; 751 } 698 752 699 753 label_part_get_info(part->lpart, &lpinfo); … … 704 758 pinfo->nblocks = lpinfo.nblocks; 705 759 pinfo->svc_id = part->svc_id; 760 vbds_part_del_ref(part); 761 fibril_rwlock_read_unlock(&part->lock); 762 706 763 return EOK; 707 764 } … … 783 840 disk = part->disk; 784 841 785 rc = vbds_part_remove(part, &lpart);842 rc = vbds_part_remove(part, vrf_none, &lpart); 786 843 if (rc != EOK) 787 844 return rc; 788 845 789 846 rc = label_part_destroy(lpart); 847 vbds_part_del_ref(part); 790 848 if (rc != EOK) { 791 849 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed deleting partition"); … … 837 895 838 896 log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_bd_open()"); 897 fibril_rwlock_write_lock(&part->lock); 839 898 part->open_cnt++; 899 fibril_rwlock_write_unlock(&part->lock); 840 900 return EOK; 841 901 } … … 846 906 847 907 log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_bd_close()"); 908 909 /* Grabbing writer lock also forces all I/O to complete */ 910 911 fibril_rwlock_write_lock(&part->lock); 848 912 part->open_cnt--; 913 fibril_rwlock_write_unlock(&part->lock); 849 914 return EOK; 850 915 } … … 855 920 vbds_part_t *part = bd_srv_part(bd); 856 921 aoff64_t gba; 922 int rc; 857 923 858 924 log_msg(LOG_DEFAULT, LVL_DEBUG2, "vbds_bd_read_blocks()"); 859 860 if (cnt * part->disk->block_size < size) 925 fibril_rwlock_read_lock(&part->lock); 926 927 if (cnt * part->disk->block_size < size) { 928 fibril_rwlock_read_unlock(&part->lock); 861 929 return EINVAL; 862 863 if (vbds_bsa_translate(part, ba, cnt, &gba) != EOK) 930 } 931 932 if (vbds_bsa_translate(part, ba, cnt, &gba) != EOK) { 933 fibril_rwlock_read_unlock(&part->lock); 864 934 return ELIMIT; 865 866 return block_read_direct(part->disk->svc_id, gba, cnt, buf); 935 } 936 937 rc = block_read_direct(part->disk->svc_id, gba, cnt, buf); 938 fibril_rwlock_read_unlock(&part->lock); 939 940 return rc; 867 941 } 868 942 … … 871 945 vbds_part_t *part = bd_srv_part(bd); 872 946 aoff64_t gba; 947 int rc; 873 948 874 949 log_msg(LOG_DEFAULT, LVL_DEBUG2, "vbds_bd_sync_cache()"); 950 fibril_rwlock_read_lock(&part->lock); 875 951 876 952 /* XXX Allow full-disk sync? */ 877 953 if (ba != 0 || cnt != 0) { 878 if (vbds_bsa_translate(part, ba, cnt, &gba) != EOK) 954 if (vbds_bsa_translate(part, ba, cnt, &gba) != EOK) { 955 fibril_rwlock_read_unlock(&part->lock); 879 956 return ELIMIT; 957 } 880 958 } else { 881 959 gba = 0; 882 960 } 883 961 884 return block_sync_cache(part->disk->svc_id, gba, cnt); 962 rc = block_sync_cache(part->disk->svc_id, gba, cnt); 963 fibril_rwlock_read_unlock(&part->lock); 964 return rc; 885 965 } 886 966 … … 890 970 vbds_part_t *part = bd_srv_part(bd); 891 971 aoff64_t gba; 972 int rc; 892 973 893 974 log_msg(LOG_DEFAULT, LVL_DEBUG2, "vbds_bd_write_blocks()"); 894 895 if (cnt * part->disk->block_size < size) 975 fibril_rwlock_read_lock(&part->lock); 976 977 if (cnt * part->disk->block_size < size) { 978 fibril_rwlock_read_unlock(&part->lock); 896 979 return EINVAL; 897 898 if (vbds_bsa_translate(part, ba, cnt, &gba) != EOK) 980 } 981 982 if (vbds_bsa_translate(part, ba, cnt, &gba) != EOK) { 983 fibril_rwlock_read_unlock(&part->lock); 899 984 return ELIMIT; 900 901 return block_write_direct(part->disk->svc_id, gba, cnt, buf); 985 } 986 987 rc = block_write_direct(part->disk->svc_id, gba, cnt, buf); 988 fibril_rwlock_read_unlock(&part->lock); 989 return rc; 902 990 } 903 991 … … 907 995 908 996 log_msg(LOG_DEFAULT, LVL_DEBUG2, "vbds_bd_get_block_size()"); 997 998 fibril_rwlock_read_lock(&part->lock); 909 999 *rsize = part->disk->block_size; 1000 fibril_rwlock_read_unlock(&part->lock); 1001 910 1002 return EOK; 911 1003 } … … 916 1008 917 1009 log_msg(LOG_DEFAULT, LVL_DEBUG2, "vbds_bd_get_num_blocks()"); 1010 1011 fibril_rwlock_read_lock(&part->lock); 918 1012 *rnb = part->nblocks; 1013 fibril_rwlock_read_unlock(&part->lock); 1014 919 1015 return EOK; 920 1016 } … … 942 1038 log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_bd_conn() - call bd_conn"); 943 1039 bd_conn(iid, icall, &part->bds); 1040 vbds_part_del_ref(part); 944 1041 } 945 1042 … … 1028 1125 log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_part_indices_update()"); 1029 1126 1127 fibril_mutex_lock(&vbds_parts_lock); 1128 1030 1129 /* First unregister services for partitions whose index has changed */ 1031 1130 list_foreach(disk->parts, ldisk, vbds_part_t, part) { 1131 fibril_rwlock_write_lock(&part->lock); 1032 1132 if (part->svc_id != 0 && part->lpart->index != part->reg_idx) { 1033 1133 rc = vbds_part_svc_unregister(part); 1034 1134 if (rc != EOK) { 1135 fibril_rwlock_write_unlock(&part->lock); 1136 fibril_mutex_unlock(&vbds_parts_lock); 1035 1137 log_msg(LOG_DEFAULT, LVL_ERROR, "Error " 1036 1138 "un-registering partition."); … … 1038 1140 } 1039 1141 } 1142 1143 fibril_rwlock_write_unlock(&part->lock); 1040 1144 } 1041 1145 1042 1146 /* Now re-register those services under the new indices */ 1043 1147 list_foreach(disk->parts, ldisk, vbds_part_t, part) { 1148 fibril_rwlock_write_lock(&part->lock); 1044 1149 label_part_get_info(part->lpart, &lpinfo); 1045 1150 if (part->svc_id == 0 && lpinfo.pkind != lpk_extended) { 1046 1151 rc = vbds_part_svc_register(part); 1047 1152 if (rc != EOK) { 1153 fibril_rwlock_write_unlock(&part->lock); 1154 fibril_mutex_unlock(&vbds_parts_lock); 1048 1155 log_msg(LOG_DEFAULT, LVL_ERROR, "Error " 1049 1156 "re-registering partition."); … … 1051 1158 } 1052 1159 } 1053 } 1160 1161 fibril_rwlock_write_unlock(&part->lock); 1162 } 1163 1164 fibril_mutex_unlock(&vbds_parts_lock); 1054 1165 1055 1166 return EOK; -
uspace/srv/bd/vbd/types/vbd.h
r8e670dd re11c527 1 1 /* 2 * Copyright (c) 201 5Jiri Svoboda2 * Copyright (c) 2016 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 39 39 40 40 #include <adt/list.h> 41 #include <atomic.h> 41 42 #include <bd_srv.h> 42 43 #include <label.h> … … 48 49 typedef sysarg_t vbds_part_id_t; 49 50 51 typedef enum { 52 /** No flags */ 53 vrf_none = 0, 54 /** Force removal */ 55 vrf_force = 0x1 56 } vbds_rem_flag_t; 57 50 58 /** Partition */ 51 59 typedef struct { 60 /** Reader held during I/O */ 61 fibril_rwlock_t lock; 52 62 /** Disk this partition belongs to */ 53 63 struct vbds_disk *disk; … … 72 82 /** Number of blocks */ 73 83 aoff64_t nblocks; 84 /** Reference count */ 85 atomic_t refcnt; 74 86 } vbds_part_t; 75 87
Note:
See TracChangeset
for help on using the changeset viewer.