RF_DiskQueueData_t * rf_CvscanDequeue(void *q_in) { RF_CvscanHeader_t *hdr = (RF_CvscanHeader_t *) q_in; long range, i, sum_dist_left, sum_dist_right; RF_DiskQueueData_t *ret; RF_DiskQueueData_t *tmp; DO_CHECK_STATE(hdr); if (hdr->left_cnt == 0 && hdr->right_cnt == 0) return ((RF_DiskQueueData_t *) NULL); range = RF_MIN(hdr->range_for_avg, RF_MIN(hdr->left_cnt, hdr->right_cnt)); for (i = 0, tmp = hdr->left, sum_dist_left = ((hdr->direction == rf_cvscan_RIGHT) ? range * hdr->change_penalty : 0); tmp != (RF_DiskQueueData_t *) NULL && i < range; tmp = tmp->next, i++) { sum_dist_left += hdr->cur_block - tmp->sectorOffset; } for (i = 0, tmp = hdr->right, sum_dist_right = ((hdr->direction == rf_cvscan_LEFT) ? range * hdr->change_penalty : 0); tmp != (RF_DiskQueueData_t *) NULL && i < range; tmp = tmp->next, i++) { sum_dist_right += tmp->sectorOffset - hdr->cur_block; } if (hdr->right_cnt == 0 || sum_dist_left < sum_dist_right) { hdr->direction = rf_cvscan_LEFT; hdr->cur_block = hdr->left->sectorOffset + hdr->left->numSector; hdr->left_cnt = RF_MAX(hdr->left_cnt - 1, 0); tmp = hdr->left; ret = (ReqDequeue(&hdr->left)) /*->parent*/ ; } else { hdr->direction = rf_cvscan_RIGHT; hdr->cur_block = hdr->right->sectorOffset + hdr->right->numSector; hdr->right_cnt = RF_MAX(hdr->right_cnt - 1, 0); tmp = hdr->right; ret = (ReqDequeue(&hdr->right)) /*->parent*/ ; } ReBalance(hdr); if (hdr->left_cnt == 0 && hdr->right_cnt == 0 && hdr->burner != (RF_DiskQueueData_t *) NULL) { /* ** restore low priority requests for next dequeue */ RF_DiskQueueData_t *burner = hdr->burner; hdr->nxt_priority = burner->priority; while (burner != (RF_DiskQueueData_t *) NULL && burner->priority == hdr->nxt_priority) { RF_DiskQueueData_t *next = burner->next; RealEnqueue(hdr, burner); burner = next; } hdr->burner = burner; } DO_CHECK_STATE(hdr); return (ret); }
RF_DiskQueueData_t * rf_CvscanPeek(void *q_in) { RF_CvscanHeader_t *hdr = (RF_CvscanHeader_t *) q_in; long range, i, sum_dist_left, sum_dist_right; RF_DiskQueueData_t *tmp, *headElement; DO_CHECK_STATE(hdr); if (hdr->left_cnt == 0 && hdr->right_cnt == 0) headElement = NULL; else { range = RF_MIN(hdr->range_for_avg, RF_MIN(hdr->left_cnt, hdr->right_cnt)); for (i = 0, tmp = hdr->left, sum_dist_left = ((hdr->direction == rf_cvscan_RIGHT) ? range * hdr->change_penalty : 0); tmp != (RF_DiskQueueData_t *) NULL && i < range; tmp = tmp->next, i++) { sum_dist_left += hdr->cur_block - tmp->sectorOffset; } for (i = 0, tmp = hdr->right, sum_dist_right = ((hdr->direction == rf_cvscan_LEFT) ? range * hdr->change_penalty : 0); tmp != (RF_DiskQueueData_t *) NULL && i < range; tmp = tmp->next, i++) { sum_dist_right += tmp->sectorOffset - hdr->cur_block; } if (hdr->right_cnt == 0 || sum_dist_left < sum_dist_right) headElement = hdr->left; else headElement = hdr->right; } return (headElement); }
void rf_ReconMapUpdate(RF_Raid_t *raidPtr, RF_ReconMap_t *mapPtr, RF_SectorNum_t startSector, RF_SectorNum_t stopSector) { RF_SectorCount_t sectorsPerReconUnit = mapPtr->sectorsPerReconUnit; RF_SectorNum_t i, first_in_RU, last_in_RU; RF_ReconMapListElem_t *p, *pt; RF_LOCK_MUTEX(mapPtr->mutex); RF_ASSERT(startSector >= 0 && stopSector < mapPtr->sectorsInDisk && stopSector >= startSector); while (startSector <= stopSector) { i = startSector / mapPtr->sectorsPerReconUnit; first_in_RU = i * sectorsPerReconUnit; last_in_RU = first_in_RU + sectorsPerReconUnit - 1; p = mapPtr->status[i]; if (p != RU_ALL) { if (p == RU_NOTHING || p->startSector > startSector) { /* Insert at front of list. */ mapPtr->status[i] = rf_MakeReconMapListElem(startSector, RF_MIN(stopSector, last_in_RU), (p == RU_NOTHING) ? NULL : p); rf_update_size(mapPtr, sizeof(RF_ReconMapListElem_t)); } else {/* General case. */ do { /* Search for place to insert. */ pt = p; p = p->next; } while (p && (p->startSector < startSector)); pt->next = rf_MakeReconMapListElem(startSector, RF_MIN(stopSector, last_in_RU), p); rf_update_size(mapPtr, sizeof(RF_ReconMapListElem_t)); } rf_compact_stat_entry(raidPtr, mapPtr, i); } startSector = RF_MIN(stopSector, last_in_RU) + 1; } RF_UNLOCK_MUTEX(mapPtr->mutex); }