Home | History | Annotate | Line # | Download | only in raidframe
rf_cvscan.c revision 1.16.54.1
      1  1.16.54.1  christos /*	$NetBSD: rf_cvscan.c,v 1.16.54.1 2019/06/10 22:07:31 christos Exp $	*/
      2        1.1     oster /*
      3        1.1     oster  * Copyright (c) 1995 Carnegie-Mellon University.
      4        1.1     oster  * All rights reserved.
      5        1.1     oster  *
      6        1.1     oster  * Author: Mark Holland
      7        1.1     oster  *
      8        1.1     oster  * Permission to use, copy, modify and distribute this software and
      9        1.1     oster  * its documentation is hereby granted, provided that both the copyright
     10        1.1     oster  * notice and this permission notice appear in all copies of the
     11        1.1     oster  * software, derivative works or modified versions, and any portions
     12        1.1     oster  * thereof, and that both notices appear in supporting documentation.
     13        1.1     oster  *
     14        1.1     oster  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
     15        1.1     oster  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
     16        1.1     oster  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
     17        1.1     oster  *
     18        1.1     oster  * Carnegie Mellon requests users of this software to return to
     19        1.1     oster  *
     20        1.1     oster  *  Software Distribution Coordinator  or  Software.Distribution (at) CS.CMU.EDU
     21        1.1     oster  *  School of Computer Science
     22        1.1     oster  *  Carnegie Mellon University
     23        1.1     oster  *  Pittsburgh PA 15213-3890
     24        1.1     oster  *
     25        1.1     oster  * any improvements or extensions that they make and grant Carnegie the
     26        1.1     oster  * rights to redistribute these changes.
     27        1.1     oster  */
     28        1.1     oster 
     29        1.1     oster /*******************************************************************************
     30        1.1     oster  *
     31        1.4     oster  * cvscan.c --  prioritized cvscan disk queueing code.
     32        1.1     oster  *
     33        1.1     oster  * Nov 9, 1994, adapted from raidSim version (MCH)
     34        1.1     oster  *
     35        1.1     oster  ******************************************************************************/
     36        1.8     lukem 
     37        1.8     lukem #include <sys/cdefs.h>
     38  1.16.54.1  christos __KERNEL_RCSID(0, "$NetBSD: rf_cvscan.c,v 1.16.54.1 2019/06/10 22:07:31 christos Exp $");
     39        1.1     oster 
     40        1.7     oster #include <dev/raidframe/raidframevar.h>
     41        1.1     oster #include "rf_alloclist.h"
     42        1.1     oster #include "rf_stripelocks.h"
     43        1.1     oster #include "rf_layout.h"
     44        1.1     oster #include "rf_diskqueue.h"
     45        1.1     oster #include "rf_cvscan.h"
     46        1.1     oster #include "rf_debugMem.h"
     47        1.1     oster #include "rf_general.h"
     48        1.1     oster 
     49       1.10     oster #define DO_CHECK_STATE(_hdr_) CheckCvscanState((_hdr_))
     50        1.1     oster 
     51        1.1     oster #define pri_ok(p)  ( ((p) == RF_IO_NORMAL_PRIORITY) || ((p) == RF_IO_LOW_PRIORITY))
     52        1.1     oster 
     53       1.12     perry static void
     54       1.11     oster CheckCvscanState(RF_CvscanHeader_t *hdr)
     55        1.1     oster {
     56        1.4     oster 	long    i, key;
     57        1.1     oster 	RF_DiskQueueData_t *tmp;
     58        1.1     oster 
     59       1.16    plunky 	if (hdr->left != NULL)
     60        1.4     oster 		RF_ASSERT(hdr->left->sectorOffset < hdr->cur_block);
     61        1.4     oster 	for (key = hdr->cur_block, i = 0, tmp = hdr->left;
     62       1.16    plunky 	    tmp != NULL;
     63        1.4     oster 	    key = tmp->sectorOffset, i++, tmp = tmp->next)
     64        1.4     oster 		RF_ASSERT(tmp->sectorOffset <= key
     65        1.4     oster 		    && tmp->priority == hdr->nxt_priority && pri_ok(tmp->priority));
     66        1.4     oster 	RF_ASSERT(i == hdr->left_cnt);
     67        1.4     oster 
     68        1.4     oster 	for (key = hdr->cur_block, i = 0, tmp = hdr->right;
     69       1.16    plunky 	    tmp != NULL;
     70        1.4     oster 	    key = tmp->sectorOffset, i++, tmp = tmp->next) {
     71        1.1     oster 		RF_ASSERT(key <= tmp->sectorOffset);
     72        1.1     oster 		RF_ASSERT(tmp->priority == hdr->nxt_priority);
     73        1.1     oster 		RF_ASSERT(pri_ok(tmp->priority));
     74        1.1     oster 	}
     75        1.4     oster 	RF_ASSERT(i == hdr->right_cnt);
     76        1.1     oster 
     77        1.4     oster 	for (key = hdr->nxt_priority - 1, tmp = hdr->burner;
     78       1.16    plunky 	    tmp != NULL;
     79        1.4     oster 	    key = tmp->priority, tmp = tmp->next) {
     80        1.1     oster 		RF_ASSERT(tmp);
     81        1.1     oster 		RF_ASSERT(hdr);
     82        1.1     oster 		RF_ASSERT(pri_ok(tmp->priority));
     83        1.1     oster 		RF_ASSERT(key >= tmp->priority);
     84        1.1     oster 		RF_ASSERT(tmp->priority < hdr->nxt_priority);
     85        1.1     oster 	}
     86        1.1     oster }
     87        1.1     oster 
     88        1.1     oster 
     89        1.1     oster 
     90       1.12     perry static void
     91       1.11     oster PriorityInsert(RF_DiskQueueData_t **list_ptr, RF_DiskQueueData_t *req)
     92        1.1     oster {
     93        1.4     oster 	/* * insert block pointed to by req in to list whose first * entry is
     94        1.4     oster 	 * pointed to by the pointer that list_ptr points to * ie., list_ptr
     95        1.4     oster 	 * is a grandparent of the first entry */
     96        1.4     oster 
     97       1.16    plunky 	for (; (*list_ptr) != NULL && (*list_ptr)->priority > req->priority;
     98        1.4     oster 	    list_ptr = &((*list_ptr)->next)) {
     99        1.4     oster 	}
    100        1.1     oster 	req->next = (*list_ptr);
    101        1.1     oster 	(*list_ptr) = req;
    102        1.1     oster }
    103        1.1     oster 
    104        1.1     oster 
    105        1.1     oster 
    106       1.12     perry static void
    107       1.11     oster ReqInsert(RF_DiskQueueData_t **list_ptr, RF_DiskQueueData_t *req, RF_CvscanArmDir_t order)
    108        1.1     oster {
    109        1.4     oster 	/* * insert block pointed to by req in to list whose first * entry is
    110        1.4     oster 	 * pointed to by the pointer that list_ptr points to * ie., list_ptr
    111        1.4     oster 	 * is a grandparent of the first entry */
    112        1.4     oster 
    113       1.16    plunky 	for (; (*list_ptr) != NULL &&
    114        1.4     oster 	    ((order == rf_cvscan_RIGHT && (*list_ptr)->sectorOffset <= req->sectorOffset)
    115        1.4     oster 		|| (order == rf_cvscan_LEFT && (*list_ptr)->sectorOffset > req->sectorOffset));
    116        1.4     oster 	    list_ptr = &((*list_ptr)->next)) {
    117        1.4     oster 	}
    118        1.1     oster 	req->next = (*list_ptr);
    119        1.1     oster 	(*list_ptr) = req;
    120        1.1     oster }
    121        1.1     oster 
    122        1.1     oster 
    123        1.1     oster 
    124        1.4     oster static RF_DiskQueueData_t *
    125       1.11     oster ReqDequeue(RF_DiskQueueData_t **list_ptr)
    126        1.1     oster {
    127        1.4     oster 	RF_DiskQueueData_t *ret = (*list_ptr);
    128       1.16    plunky 	if ((*list_ptr) != NULL) {
    129        1.1     oster 		(*list_ptr) = (*list_ptr)->next;
    130        1.1     oster 	}
    131        1.4     oster 	return (ret);
    132        1.1     oster }
    133        1.1     oster 
    134        1.1     oster 
    135        1.1     oster 
    136       1.12     perry static void
    137       1.11     oster ReBalance(RF_CvscanHeader_t *hdr)
    138        1.1     oster {
    139        1.1     oster 	/* DO_CHECK_STATE(hdr); */
    140       1.16    plunky 	while (hdr->right != NULL
    141        1.4     oster 	    && hdr->right->sectorOffset < hdr->cur_block) {
    142        1.1     oster 		hdr->right_cnt--;
    143        1.1     oster 		hdr->left_cnt++;
    144        1.4     oster 		ReqInsert(&hdr->left, ReqDequeue(&hdr->right), rf_cvscan_LEFT);
    145        1.1     oster 	}
    146        1.1     oster 	/* DO_CHECK_STATE(hdr); */
    147        1.1     oster }
    148        1.1     oster 
    149        1.1     oster 
    150        1.1     oster 
    151       1.12     perry static void
    152       1.11     oster Transfer(RF_DiskQueueData_t **to_list_ptr, RF_DiskQueueData_t **from_list_ptr)
    153        1.1     oster {
    154        1.1     oster 	RF_DiskQueueData_t *gp;
    155       1.16    plunky 	for (gp = (*from_list_ptr); gp != NULL;) {
    156        1.1     oster 		RF_DiskQueueData_t *p = gp->next;
    157        1.4     oster 		PriorityInsert(to_list_ptr, gp);
    158        1.1     oster 		gp = p;
    159        1.1     oster 	}
    160       1.16    plunky 	(*from_list_ptr) = NULL;
    161        1.1     oster }
    162        1.1     oster 
    163        1.1     oster 
    164        1.1     oster 
    165       1.12     perry static void
    166       1.11     oster RealEnqueue(RF_CvscanHeader_t *hdr, RF_DiskQueueData_t *req)
    167        1.1     oster {
    168        1.1     oster 	RF_ASSERT(req->priority == RF_IO_NORMAL_PRIORITY || req->priority == RF_IO_LOW_PRIORITY);
    169        1.4     oster 
    170        1.1     oster 	DO_CHECK_STATE(hdr);
    171        1.4     oster 	if (hdr->left_cnt == 0 && hdr->right_cnt == 0) {
    172        1.1     oster 		hdr->nxt_priority = req->priority;
    173        1.1     oster 	}
    174        1.4     oster 	if (req->priority > hdr->nxt_priority) {
    175        1.1     oster 		/*
    176        1.1     oster 		** dump all other outstanding requests on the back burner
    177        1.1     oster 		*/
    178        1.4     oster 		Transfer(&hdr->burner, &hdr->left);
    179        1.4     oster 		Transfer(&hdr->burner, &hdr->right);
    180        1.1     oster 		hdr->left_cnt = 0;
    181        1.1     oster 		hdr->right_cnt = 0;
    182        1.1     oster 		hdr->nxt_priority = req->priority;
    183        1.1     oster 	}
    184        1.4     oster 	if (req->priority < hdr->nxt_priority) {
    185        1.1     oster 		/*
    186        1.1     oster 		** yet another low priority task!
    187        1.1     oster 		*/
    188        1.4     oster 		PriorityInsert(&hdr->burner, req);
    189        1.1     oster 	} else {
    190        1.4     oster 		if (req->sectorOffset < hdr->cur_block) {
    191        1.1     oster 			/* this request is to the left of the current arms */
    192        1.4     oster 			ReqInsert(&hdr->left, req, rf_cvscan_LEFT);
    193        1.1     oster 			hdr->left_cnt++;
    194        1.1     oster 		} else {
    195        1.1     oster 			/* this request is to the right of the current arms */
    196        1.4     oster 			ReqInsert(&hdr->right, req, rf_cvscan_RIGHT);
    197        1.1     oster 			hdr->right_cnt++;
    198        1.1     oster 		}
    199        1.1     oster 	}
    200        1.1     oster 	DO_CHECK_STATE(hdr);
    201        1.1     oster }
    202        1.1     oster 
    203        1.1     oster 
    204        1.1     oster 
    205       1.12     perry void
    206       1.15  christos rf_CvscanEnqueue(void *q_in, RF_DiskQueueData_t * elem, int priority)
    207        1.1     oster {
    208        1.4     oster 	RF_CvscanHeader_t *hdr = (RF_CvscanHeader_t *) q_in;
    209        1.4     oster 	RealEnqueue(hdr, elem /* req */ );
    210        1.1     oster }
    211        1.1     oster 
    212        1.1     oster 
    213        1.1     oster 
    214        1.4     oster RF_DiskQueueData_t *
    215        1.4     oster rf_CvscanDequeue(void *q_in)
    216        1.1     oster {
    217        1.4     oster 	RF_CvscanHeader_t *hdr = (RF_CvscanHeader_t *) q_in;
    218        1.4     oster 	long    range, i, sum_dist_left, sum_dist_right;
    219        1.1     oster 	RF_DiskQueueData_t *ret;
    220        1.1     oster 	RF_DiskQueueData_t *tmp;
    221        1.1     oster 
    222        1.1     oster 	DO_CHECK_STATE(hdr);
    223        1.1     oster 
    224        1.4     oster 	if (hdr->left_cnt == 0 && hdr->right_cnt == 0)
    225       1.16    plunky 		return (NULL);
    226        1.4     oster 
    227        1.4     oster 	range = RF_MIN(hdr->range_for_avg, RF_MIN(hdr->left_cnt, hdr->right_cnt));
    228        1.4     oster 	for (i = 0, tmp = hdr->left, sum_dist_left =
    229        1.4     oster 	    ((hdr->direction == rf_cvscan_RIGHT) ? range * hdr->change_penalty : 0);
    230       1.16    plunky 	    tmp != NULL && i < range;
    231        1.4     oster 	    tmp = tmp->next, i++) {
    232        1.1     oster 		sum_dist_left += hdr->cur_block - tmp->sectorOffset;
    233        1.1     oster 	}
    234        1.4     oster 	for (i = 0, tmp = hdr->right, sum_dist_right =
    235        1.4     oster 	    ((hdr->direction == rf_cvscan_LEFT) ? range * hdr->change_penalty : 0);
    236       1.16    plunky 	    tmp != NULL && i < range;
    237        1.4     oster 	    tmp = tmp->next, i++) {
    238        1.1     oster 		sum_dist_right += tmp->sectorOffset - hdr->cur_block;
    239        1.1     oster 	}
    240        1.1     oster 
    241        1.4     oster 	if (hdr->right_cnt == 0 || sum_dist_left < sum_dist_right) {
    242        1.1     oster 		hdr->direction = rf_cvscan_LEFT;
    243        1.1     oster 		hdr->cur_block = hdr->left->sectorOffset + hdr->left->numSector;
    244        1.4     oster 		hdr->left_cnt = RF_MAX(hdr->left_cnt - 1, 0);
    245        1.1     oster 		tmp = hdr->left;
    246        1.4     oster 		ret = (ReqDequeue(&hdr->left)) /*->parent*/ ;
    247        1.1     oster 	} else {
    248        1.1     oster 		hdr->direction = rf_cvscan_RIGHT;
    249        1.1     oster 		hdr->cur_block = hdr->right->sectorOffset + hdr->right->numSector;
    250        1.4     oster 		hdr->right_cnt = RF_MAX(hdr->right_cnt - 1, 0);
    251        1.1     oster 		tmp = hdr->right;
    252        1.4     oster 		ret = (ReqDequeue(&hdr->right)) /*->parent*/ ;
    253        1.1     oster 	}
    254        1.4     oster 	ReBalance(hdr);
    255        1.1     oster 
    256        1.4     oster 	if (hdr->left_cnt == 0 && hdr->right_cnt == 0
    257       1.16    plunky 	    && hdr->burner != NULL) {
    258        1.1     oster 		/*
    259        1.1     oster 		** restore low priority requests for next dequeue
    260        1.1     oster 		*/
    261        1.1     oster 		RF_DiskQueueData_t *burner = hdr->burner;
    262        1.1     oster 		hdr->nxt_priority = burner->priority;
    263       1.16    plunky 		while (burner != NULL
    264        1.4     oster 		    && burner->priority == hdr->nxt_priority) {
    265        1.1     oster 			RF_DiskQueueData_t *next = burner->next;
    266        1.4     oster 			RealEnqueue(hdr, burner);
    267        1.1     oster 			burner = next;
    268        1.1     oster 		}
    269        1.1     oster 		hdr->burner = burner;
    270        1.1     oster 	}
    271        1.1     oster 	DO_CHECK_STATE(hdr);
    272        1.4     oster 	return (ret);
    273        1.1     oster }
    274        1.1     oster 
    275        1.1     oster 
    276        1.1     oster 
    277        1.4     oster RF_DiskQueueData_t *
    278        1.4     oster rf_CvscanPeek(void *q_in)
    279        1.1     oster {
    280        1.4     oster 	RF_CvscanHeader_t *hdr = (RF_CvscanHeader_t *) q_in;
    281        1.4     oster 	long    range, i, sum_dist_left, sum_dist_right;
    282        1.4     oster 	RF_DiskQueueData_t *tmp, *headElement;
    283        1.4     oster 
    284        1.4     oster 	DO_CHECK_STATE(hdr);
    285        1.4     oster 
    286        1.4     oster 	if (hdr->left_cnt == 0 && hdr->right_cnt == 0)
    287        1.4     oster 		headElement = NULL;
    288        1.4     oster 	else {
    289        1.4     oster 		range = RF_MIN(hdr->range_for_avg, RF_MIN(hdr->left_cnt, hdr->right_cnt));
    290        1.4     oster 		for (i = 0, tmp = hdr->left, sum_dist_left =
    291        1.4     oster 		    ((hdr->direction == rf_cvscan_RIGHT) ? range * hdr->change_penalty : 0);
    292       1.16    plunky 		    tmp != NULL && i < range;
    293        1.4     oster 		    tmp = tmp->next, i++) {
    294        1.4     oster 			sum_dist_left += hdr->cur_block - tmp->sectorOffset;
    295        1.4     oster 		}
    296        1.4     oster 		for (i = 0, tmp = hdr->right, sum_dist_right =
    297        1.4     oster 		    ((hdr->direction == rf_cvscan_LEFT) ? range * hdr->change_penalty : 0);
    298       1.16    plunky 		    tmp != NULL && i < range;
    299        1.4     oster 		    tmp = tmp->next, i++) {
    300        1.4     oster 			sum_dist_right += tmp->sectorOffset - hdr->cur_block;
    301        1.4     oster 		}
    302        1.4     oster 
    303        1.4     oster 		if (hdr->right_cnt == 0 || sum_dist_left < sum_dist_right)
    304        1.4     oster 			headElement = hdr->left;
    305        1.4     oster 		else
    306        1.4     oster 			headElement = hdr->right;
    307        1.4     oster 	}
    308        1.4     oster 	return (headElement);
    309        1.1     oster }
    310        1.1     oster 
    311        1.1     oster 
    312        1.1     oster 
    313        1.1     oster /*
    314        1.1     oster ** CVSCAN( 1, 0 ) is Shortest Seek Time First (SSTF)
    315        1.1     oster **				lowest average response time
    316        1.1     oster ** CVSCAN( 1, infinity ) is SCAN
    317        1.1     oster **				lowest response time standard deviation
    318        1.1     oster */
    319        1.1     oster 
    320        1.4     oster void   *
    321        1.4     oster rf_CvscanCreate(RF_SectorCount_t sectPerDisk,
    322       1.11     oster     RF_AllocListElem_t *clList,
    323       1.15  christos     RF_ShutdownList_t **listp)
    324        1.1     oster {
    325        1.1     oster 	RF_CvscanHeader_t *hdr;
    326        1.4     oster 	long    range = 2;	/* Currently no mechanism to change these */
    327        1.4     oster 	long    penalty = sectPerDisk / 5;
    328        1.1     oster 
    329  1.16.54.1  christos 	hdr = RF_MallocAndAdd(sizeof(*hdr), clList);
    330        1.4     oster 	hdr->range_for_avg = RF_MAX(range, 1);
    331        1.4     oster 	hdr->change_penalty = RF_MAX(penalty, 0);
    332        1.1     oster 	hdr->direction = rf_cvscan_RIGHT;
    333        1.1     oster 	hdr->cur_block = 0;
    334        1.1     oster 	hdr->left_cnt = hdr->right_cnt = 0;
    335       1.16    plunky 	hdr->left = hdr->right = NULL;
    336       1.16    plunky 	hdr->burner = NULL;
    337        1.1     oster 	DO_CHECK_STATE(hdr);
    338        1.1     oster 
    339        1.4     oster 	return ((void *) hdr);
    340        1.1     oster }
    341        1.1     oster 
    342        1.1     oster 
    343        1.1     oster #if defined(__NetBSD__) && defined(_KERNEL)
    344        1.1     oster /* PrintCvscanQueue is not used, so we ignore it... */
    345        1.1     oster #else
    346       1.12     perry static void
    347       1.11     oster PrintCvscanQueue(RF_CvscanHeader_t *hdr)
    348        1.1     oster {
    349        1.1     oster 	RF_DiskQueueData_t *tmp;
    350        1.1     oster 
    351        1.4     oster 	printf("CVSCAN(%d,%d) at %d going %s\n",
    352        1.4     oster 	    (int) hdr->range_for_avg,
    353        1.4     oster 	    (int) hdr->change_penalty,
    354        1.4     oster 	    (int) hdr->cur_block,
    355        1.4     oster 	    (hdr->direction == rf_cvscan_LEFT) ? "LEFT" : "RIGHT");
    356        1.4     oster 	printf("\tLeft(%d): ", hdr->left_cnt);
    357       1.16    plunky 	for (tmp = hdr->left; tmp != NULL; tmp = tmp->next)
    358        1.4     oster 		printf("(%d,%ld,%d) ",
    359        1.4     oster 		    (int) tmp->sectorOffset,
    360        1.4     oster 		    (long) (tmp->sectorOffset + tmp->numSector),
    361        1.4     oster 		    tmp->priority);
    362        1.4     oster 	printf("\n");
    363        1.4     oster 	printf("\tRight(%d): ", hdr->right_cnt);
    364       1.16    plunky 	for (tmp = hdr->right; tmp != NULL; tmp = tmp->next)
    365        1.4     oster 		printf("(%d,%ld,%d) ",
    366        1.4     oster 		    (int) tmp->sectorOffset,
    367        1.4     oster 		    (long) (tmp->sectorOffset + tmp->numSector),
    368        1.4     oster 		    tmp->priority);
    369        1.4     oster 	printf("\n");
    370        1.4     oster 	printf("\tBurner: ");
    371       1.16    plunky 	for (tmp = hdr->burner; tmp != NULL; tmp = tmp->next)
    372        1.4     oster 		printf("(%d,%ld,%d) ",
    373        1.4     oster 		    (int) tmp->sectorOffset,
    374        1.4     oster 		    (long) (tmp->sectorOffset + tmp->numSector),
    375        1.4     oster 		    tmp->priority);
    376        1.4     oster 	printf("\n");
    377        1.1     oster }
    378        1.1     oster #endif
    379        1.1     oster 
    380        1.1     oster 
    381        1.1     oster /* promotes reconstruction accesses for the given stripeID to normal priority.
    382        1.1     oster  * returns 1 if an access was found and zero otherwise.  Normally, we should
    383        1.1     oster  * only have one or zero entries in the burner queue, so execution time should
    384        1.1     oster  * be short.
    385        1.1     oster  */
    386       1.12     perry int
    387       1.12     perry rf_CvscanPromote(void *q_in, RF_StripeNum_t parityStripeID,
    388       1.11     oster 		 RF_ReconUnitNum_t which_ru)
    389        1.1     oster {
    390        1.4     oster 	RF_CvscanHeader_t *hdr = (RF_CvscanHeader_t *) q_in;
    391        1.4     oster 	RF_DiskQueueData_t *trailer = NULL, *tmp = hdr->burner, *tlist = NULL;
    392        1.4     oster 	int     retval = 0;
    393        1.1     oster 
    394        1.1     oster 	DO_CHECK_STATE(hdr);
    395        1.4     oster 	while (tmp) {		/* handle entries at the front of the list */
    396        1.4     oster 		if (tmp->parityStripeID == parityStripeID && tmp->which_ru == which_ru) {
    397        1.4     oster 			hdr->burner = tmp->next;
    398        1.4     oster 			tmp->priority = RF_IO_NORMAL_PRIORITY;
    399        1.4     oster 			tmp->next = tlist;
    400        1.4     oster 			tlist = tmp;
    401        1.4     oster 			tmp = hdr->burner;
    402        1.4     oster 		} else
    403        1.4     oster 			break;
    404        1.4     oster 	}
    405        1.4     oster 	if (tmp) {
    406        1.4     oster 		trailer = tmp;
    407        1.4     oster 		tmp = tmp->next;
    408        1.4     oster 	}
    409        1.4     oster 	while (tmp) {		/* handle entries on the rest of the list */
    410        1.4     oster 		if (tmp->parityStripeID == parityStripeID && tmp->which_ru == which_ru) {
    411        1.4     oster 			trailer->next = tmp->next;
    412        1.4     oster 			tmp->priority = RF_IO_NORMAL_PRIORITY;
    413        1.4     oster 			tmp->next = tlist;
    414        1.4     oster 			tlist = tmp;	/* insert on a temp queue */
    415        1.4     oster 			tmp = trailer->next;
    416        1.4     oster 		} else {
    417        1.4     oster 			trailer = tmp;
    418        1.4     oster 			tmp = tmp->next;
    419        1.4     oster 		}
    420        1.1     oster 	}
    421        1.4     oster 	while (tlist) {
    422        1.4     oster 		retval++;
    423        1.4     oster 		tmp = tlist->next;
    424        1.4     oster 		RealEnqueue(hdr, tlist);
    425        1.4     oster 		tlist = tmp;
    426        1.4     oster 	}
    427        1.4     oster 	RF_ASSERT(retval == 0 || retval == 1);
    428        1.4     oster 	DO_CHECK_STATE((RF_CvscanHeader_t *) q_in);
    429        1.4     oster 	return (retval);
    430        1.1     oster }
    431