Beispiel #1
0
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);
}
Beispiel #2
0
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);
}
Beispiel #3
0
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);
}