Home | History | Annotate | Line # | Download | only in raidframe
rf_cvscan.c revision 1.16
      1  1.16    plunky /*	$NetBSD: rf_cvscan.c,v 1.16 2011/08/31 18:31:02 plunky 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    plunky __KERNEL_RCSID(0, "$NetBSD: rf_cvscan.c,v 1.16 2011/08/31 18:31:02 plunky 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.1     oster 	RF_MallocAndAdd(hdr, sizeof(RF_CvscanHeader_t), (RF_CvscanHeader_t *), clList);
    330   1.6   thorpej 	memset((char *) hdr, 0, sizeof(RF_CvscanHeader_t));
    331   1.4     oster 	hdr->range_for_avg = RF_MAX(range, 1);
    332   1.4     oster 	hdr->change_penalty = RF_MAX(penalty, 0);
    333   1.1     oster 	hdr->direction = rf_cvscan_RIGHT;
    334   1.1     oster 	hdr->cur_block = 0;
    335   1.1     oster 	hdr->left_cnt = hdr->right_cnt = 0;
    336  1.16    plunky 	hdr->left = hdr->right = NULL;
    337  1.16    plunky 	hdr->burner = NULL;
    338   1.1     oster 	DO_CHECK_STATE(hdr);
    339   1.1     oster 
    340   1.4     oster 	return ((void *) hdr);
    341   1.1     oster }
    342   1.1     oster 
    343   1.1     oster 
    344   1.1     oster #if defined(__NetBSD__) && defined(_KERNEL)
    345   1.1     oster /* PrintCvscanQueue is not used, so we ignore it... */
    346   1.1     oster #else
    347  1.12     perry static void
    348  1.11     oster PrintCvscanQueue(RF_CvscanHeader_t *hdr)
    349   1.1     oster {
    350   1.1     oster 	RF_DiskQueueData_t *tmp;
    351   1.1     oster 
    352   1.4     oster 	printf("CVSCAN(%d,%d) at %d going %s\n",
    353   1.4     oster 	    (int) hdr->range_for_avg,
    354   1.4     oster 	    (int) hdr->change_penalty,
    355   1.4     oster 	    (int) hdr->cur_block,
    356   1.4     oster 	    (hdr->direction == rf_cvscan_LEFT) ? "LEFT" : "RIGHT");
    357   1.4     oster 	printf("\tLeft(%d): ", hdr->left_cnt);
    358  1.16    plunky 	for (tmp = hdr->left; tmp != NULL; tmp = tmp->next)
    359   1.4     oster 		printf("(%d,%ld,%d) ",
    360   1.4     oster 		    (int) tmp->sectorOffset,
    361   1.4     oster 		    (long) (tmp->sectorOffset + tmp->numSector),
    362   1.4     oster 		    tmp->priority);
    363   1.4     oster 	printf("\n");
    364   1.4     oster 	printf("\tRight(%d): ", hdr->right_cnt);
    365  1.16    plunky 	for (tmp = hdr->right; tmp != NULL; tmp = tmp->next)
    366   1.4     oster 		printf("(%d,%ld,%d) ",
    367   1.4     oster 		    (int) tmp->sectorOffset,
    368   1.4     oster 		    (long) (tmp->sectorOffset + tmp->numSector),
    369   1.4     oster 		    tmp->priority);
    370   1.4     oster 	printf("\n");
    371   1.4     oster 	printf("\tBurner: ");
    372  1.16    plunky 	for (tmp = hdr->burner; tmp != NULL; tmp = tmp->next)
    373   1.4     oster 		printf("(%d,%ld,%d) ",
    374   1.4     oster 		    (int) tmp->sectorOffset,
    375   1.4     oster 		    (long) (tmp->sectorOffset + tmp->numSector),
    376   1.4     oster 		    tmp->priority);
    377   1.4     oster 	printf("\n");
    378   1.1     oster }
    379   1.1     oster #endif
    380   1.1     oster 
    381   1.1     oster 
    382   1.1     oster /* promotes reconstruction accesses for the given stripeID to normal priority.
    383   1.1     oster  * returns 1 if an access was found and zero otherwise.  Normally, we should
    384   1.1     oster  * only have one or zero entries in the burner queue, so execution time should
    385   1.1     oster  * be short.
    386   1.1     oster  */
    387  1.12     perry int
    388  1.12     perry rf_CvscanPromote(void *q_in, RF_StripeNum_t parityStripeID,
    389  1.11     oster 		 RF_ReconUnitNum_t which_ru)
    390   1.1     oster {
    391   1.4     oster 	RF_CvscanHeader_t *hdr = (RF_CvscanHeader_t *) q_in;
    392   1.4     oster 	RF_DiskQueueData_t *trailer = NULL, *tmp = hdr->burner, *tlist = NULL;
    393   1.4     oster 	int     retval = 0;
    394   1.1     oster 
    395   1.1     oster 	DO_CHECK_STATE(hdr);
    396   1.4     oster 	while (tmp) {		/* handle entries at the front of the list */
    397   1.4     oster 		if (tmp->parityStripeID == parityStripeID && tmp->which_ru == which_ru) {
    398   1.4     oster 			hdr->burner = tmp->next;
    399   1.4     oster 			tmp->priority = RF_IO_NORMAL_PRIORITY;
    400   1.4     oster 			tmp->next = tlist;
    401   1.4     oster 			tlist = tmp;
    402   1.4     oster 			tmp = hdr->burner;
    403   1.4     oster 		} else
    404   1.4     oster 			break;
    405   1.4     oster 	}
    406   1.4     oster 	if (tmp) {
    407   1.4     oster 		trailer = tmp;
    408   1.4     oster 		tmp = tmp->next;
    409   1.4     oster 	}
    410   1.4     oster 	while (tmp) {		/* handle entries on the rest of the list */
    411   1.4     oster 		if (tmp->parityStripeID == parityStripeID && tmp->which_ru == which_ru) {
    412   1.4     oster 			trailer->next = tmp->next;
    413   1.4     oster 			tmp->priority = RF_IO_NORMAL_PRIORITY;
    414   1.4     oster 			tmp->next = tlist;
    415   1.4     oster 			tlist = tmp;	/* insert on a temp queue */
    416   1.4     oster 			tmp = trailer->next;
    417   1.4     oster 		} else {
    418   1.4     oster 			trailer = tmp;
    419   1.4     oster 			tmp = tmp->next;
    420   1.4     oster 		}
    421   1.1     oster 	}
    422   1.4     oster 	while (tlist) {
    423   1.4     oster 		retval++;
    424   1.4     oster 		tmp = tlist->next;
    425   1.4     oster 		RealEnqueue(hdr, tlist);
    426   1.4     oster 		tlist = tmp;
    427   1.4     oster 	}
    428   1.4     oster 	RF_ASSERT(retval == 0 || retval == 1);
    429   1.4     oster 	DO_CHECK_STATE((RF_CvscanHeader_t *) q_in);
    430   1.4     oster 	return (retval);
    431   1.1     oster }
    432