Changeset 38e3c0a7 in mainline
- Timestamp:
- 2024-12-22T15:35:54Z (5 months ago)
- Children:
- 83c8bb2
- Parents:
- f725787
- Location:
- uspace/srv/bd/hr
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/bd/hr/util.c
rf725787 r38e3c0a7 34 34 */ 35 35 36 #include <adt/list.h> 36 37 #include <block.h> 37 38 #include <errno.h> 39 #include <fibril_synch.h> 38 40 #include <hr.h> 39 41 #include <io/log.h> … … 46 48 #include "var.h" 47 49 50 #define HR_RL_LIST_LOCK(vol) (fibril_mutex_lock(&vol->range_lock_list_lock)) 51 #define HR_RL_LIST_UNLOCK(vol) \ 52 (fibril_mutex_unlock(&vol->range_lock_list_lock)) 53 54 static bool hr_range_lock_overlap(hr_range_lock_t *, hr_range_lock_t *); 55 48 56 extern loc_srv_t *hr_srv; 49 57 … … 128 136 129 137 vol->svc_id = new_id; 130 131 138 error: 132 139 free(fullname); … … 258 265 { 259 266 size_t count = 0; 260 for (size_t i = 0; i < vol->extent_no; i++) {267 for (size_t i = 0; i < vol->extent_no; i++) 261 268 if (vol->extents[i].status == status) 262 269 count++; 263 }264 270 265 271 return count; 266 272 } 267 273 274 hr_range_lock_t *hr_range_lock_acquire(hr_volume_t *vol, uint64_t ba, 275 uint64_t cnt) 276 { 277 hr_range_lock_t *rl = malloc(sizeof(hr_range_lock_t)); 278 if (rl == NULL) 279 return NULL; 280 281 rl->vol = vol; 282 rl->off = ba; 283 rl->len = cnt; 284 285 rl->pending = 1; 286 rl->ignore = false; 287 288 link_initialize(&rl->link); 289 fibril_mutex_initialize(&rl->lock); 290 291 fibril_mutex_lock(&rl->lock); 292 293 again: 294 HR_RL_LIST_LOCK(vol); 295 list_foreach(vol->range_lock_list, link, hr_range_lock_t, rlp) { 296 if (rlp->ignore) 297 continue; 298 if (hr_range_lock_overlap(rlp, rl)) { 299 rlp->pending++; 300 301 HR_RL_LIST_UNLOCK(vol); 302 303 fibril_mutex_lock(&rlp->lock); 304 305 HR_RL_LIST_LOCK(vol); 306 307 rlp->pending--; 308 309 /* 310 * when ignore is set, after HR_RL_LIST_UNLOCK(), 311 * noone new is going to be able to start sleeping 312 * on the ignored range lock, only already waiting 313 * IOs will come through here 314 */ 315 rlp->ignore = true; 316 317 fibril_mutex_unlock(&rlp->lock); 318 319 if (rlp->pending == 0) { 320 list_remove(&rlp->link); 321 free(rlp); 322 } 323 324 HR_RL_LIST_UNLOCK(vol); 325 goto again; 326 } 327 } 328 329 list_append(&rl->link, &vol->range_lock_list); 330 331 HR_RL_LIST_UNLOCK(vol); 332 return rl; 333 } 334 335 void hr_range_lock_release(hr_range_lock_t *rl) 336 { 337 HR_RL_LIST_LOCK(rl->vol); 338 339 rl->pending--; 340 341 fibril_mutex_unlock(&rl->lock); 342 343 if (rl->pending == 0) { 344 list_remove(&rl->link); 345 free(rl); 346 } 347 348 HR_RL_LIST_UNLOCK(rl->vol); 349 } 350 351 static bool hr_range_lock_overlap(hr_range_lock_t *rl1, hr_range_lock_t *rl2) 352 { 353 uint64_t rl1_start = rl1->off; 354 uint64_t rl1_end = rl1->off + rl1->len - 1; 355 uint64_t rl2_start = rl2->off; 356 uint64_t rl2_end = rl2->off + rl2->len - 1; 357 358 /* one ends before the other starts */ 359 if (rl1_end < rl2_start || rl2_end < rl1_start) 360 return false; 361 362 return true; 363 } 364 268 365 /** @} 269 366 */ -
uspace/srv/bd/hr/util.h
rf725787 r38e3c0a7 61 61 extern void hr_sync_all_extents(hr_volume_t *); 62 62 extern size_t hr_count_extents(hr_volume_t *, hr_ext_status_t); 63 extern hr_range_lock_t *hr_range_lock_acquire(hr_volume_t *, uint64_t, 64 uint64_t); 65 extern void hr_range_lock_release(hr_range_lock_t *rl); 63 66 64 67 #endif -
uspace/srv/bd/hr/var.h
rf725787 r38e3c0a7 37 37 #define _HR_VAR_H 38 38 39 #include <adt/list.h> 39 40 #include <bd_srv.h> 40 41 #include <errno.h> 42 #include <fibril_synch.h> 41 43 #include <hr.h> 42 44 … … 60 62 link_t lvolumes; 61 63 fibril_mutex_t lock; 64 65 list_t range_lock_list; 66 fibril_mutex_t range_lock_list_lock; 62 67 63 68 size_t extent_no; … … 90 95 } hr_bd_op_type_t; 91 96 97 typedef struct hr_range_lock { 98 fibril_mutex_t lock; 99 link_t link; 100 hr_volume_t *vol; 101 uint64_t off; 102 uint64_t len; 103 size_t pending; /* protected by vol->range_lock_list_lock */ 104 bool ignore; /* protected by vol->range_lock_list_lock */ 105 } hr_range_lock_t; 106 92 107 extern errno_t hr_init_devs(hr_volume_t *); 93 108 extern void hr_fini_devs(hr_volume_t *);
Note:
See TracChangeset
for help on using the changeset viewer.