Annotation of sys/dev/raidframe/rf_states.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: rf_states.c,v 1.9 2002/12/16 07:01:05 tdeval Exp $ */
2: /* $NetBSD: rf_states.c,v 1.15 2000/10/20 02:24:45 oster Exp $ */
3:
4: /*
5: * Copyright (c) 1995 Carnegie-Mellon University.
6: * All rights reserved.
7: *
8: * Author: Mark Holland, William V. Courtright II, Robby Findler
9: *
10: * Permission to use, copy, modify and distribute this software and
11: * its documentation is hereby granted, provided that both the copyright
12: * notice and this permission notice appear in all copies of the
13: * software, derivative works or modified versions, and any portions
14: * thereof, and that both notices appear in supporting documentation.
15: *
16: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
17: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
18: * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
19: *
20: * Carnegie Mellon requests users of this software to return to
21: *
22: * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
23: * School of Computer Science
24: * Carnegie Mellon University
25: * Pittsburgh PA 15213-3890
26: *
27: * any improvements or extensions that they make and grant Carnegie the
28: * rights to redistribute these changes.
29: */
30:
31: #include <sys/errno.h>
32:
33: #include "rf_archs.h"
34: #include "rf_threadstuff.h"
35: #include "rf_raid.h"
36: #include "rf_dag.h"
37: #include "rf_desc.h"
38: #include "rf_aselect.h"
39: #include "rf_general.h"
40: #include "rf_states.h"
41: #include "rf_dagutils.h"
42: #include "rf_driver.h"
43: #include "rf_engine.h"
44: #include "rf_map.h"
45: #include "rf_etimer.h"
46: #include "rf_kintf.h"
47:
48: /*
49: * Prototypes for some of the available states.
50: *
51: * States must:
52: *
53: * - not block.
54: *
55: * - either schedule rf_ContinueRaidAccess as a callback and return
56: * RF_TRUE, or complete all of their work and return RF_FALSE.
57: *
58: * - increment desc->state when they have finished their work.
59: */
60:
61: char *StateName(RF_AccessState_t);
62:
63: char *
64: StateName(RF_AccessState_t state)
65: {
66: switch (state) {
67: case rf_QuiesceState:return "QuiesceState";
68: case rf_MapState:
69: return "MapState";
70: case rf_LockState:
71: return "LockState";
72: case rf_CreateDAGState:
73: return "CreateDAGState";
74: case rf_ExecuteDAGState:
75: return "ExecuteDAGState";
76: case rf_ProcessDAGState:
77: return "ProcessDAGState";
78: case rf_CleanupState:
79: return "CleanupState";
80: case rf_LastState:
81: return "LastState";
82: case rf_IncrAccessesCountState:
83: return "IncrAccessesCountState";
84: case rf_DecrAccessesCountState:
85: return "DecrAccessesCountState";
86: default:
87: return "!!! UnnamedState !!!";
88: }
89: }
90:
91: void
92: rf_ContinueRaidAccess(RF_RaidAccessDesc_t *desc)
93: {
94: int suspended = RF_FALSE;
95: int current_state_index = desc->state;
96: RF_AccessState_t current_state = desc->states[current_state_index];
97: int unit = desc->raidPtr->raidid;
98:
99: do {
100: current_state_index = desc->state;
101: current_state = desc->states[current_state_index];
102:
103: switch (current_state) {
104:
105: case rf_QuiesceState:
106: suspended = rf_State_Quiesce(desc);
107: break;
108: case rf_IncrAccessesCountState:
109: suspended = rf_State_IncrAccessCount(desc);
110: break;
111: case rf_MapState:
112: suspended = rf_State_Map(desc);
113: break;
114: case rf_LockState:
115: suspended = rf_State_Lock(desc);
116: break;
117: case rf_CreateDAGState:
118: suspended = rf_State_CreateDAG(desc);
119: break;
120: case rf_ExecuteDAGState:
121: suspended = rf_State_ExecuteDAG(desc);
122: break;
123: case rf_ProcessDAGState:
124: suspended = rf_State_ProcessDAG(desc);
125: break;
126: case rf_CleanupState:
127: suspended = rf_State_Cleanup(desc);
128: break;
129: case rf_DecrAccessesCountState:
130: suspended = rf_State_DecrAccessCount(desc);
131: break;
132: case rf_LastState:
133: suspended = rf_State_LastState(desc);
134: break;
135: }
136:
137: /*
138: * After this point, we cannot dereference desc since desc may
139: * have been freed. desc is only freed in LastState, so if we
140: * reenter this function or loop back up, desc should be valid.
141: */
142:
143: if (rf_printStatesDebug) {
144: printf("raid%d: State: %-24s StateIndex: %3i desc:"
145: " 0x%ld %s.\n", unit, StateName(current_state),
146: current_state_index, (long) desc, suspended ?
147: "callback scheduled" : "looping");
148: }
149: } while (!suspended && current_state != rf_LastState);
150:
151: return;
152: }
153:
154:
155: void
156: rf_ContinueDagAccess(RF_DagList_t *dagList)
157: {
158: RF_AccTraceEntry_t *tracerec = &(dagList->desc->tracerec);
159: RF_RaidAccessDesc_t *desc;
160: RF_DagHeader_t *dag_h;
161: RF_Etimer_t timer;
162: int i;
163:
164: desc = dagList->desc;
165:
166: timer = tracerec->timer;
167: RF_ETIMER_STOP(timer);
168: RF_ETIMER_EVAL(timer);
169: tracerec->specific.user.exec_us = RF_ETIMER_VAL_US(timer);
170: RF_ETIMER_START(tracerec->timer);
171:
172: /* Skip to dag which just finished. */
173: dag_h = dagList->dags;
174: for (i = 0; i < dagList->numDagsDone; i++) {
175: dag_h = dag_h->next;
176: }
177:
178: /* Check to see if retry is required. */
179: if (dag_h->status == rf_rollBackward) {
180: /*
181: * When a dag fails, mark desc status as bad and allow all
182: * other dags in the desc to execute to completion. Then,
183: * free all dags and start over.
184: */
185: desc->status = 1; /* Bad status. */
186: {
187: printf("raid%d: DAG failure: %c addr 0x%lx (%ld)"
188: " nblk 0x%x (%d) buf 0x%lx.\n",
189: desc->raidPtr->raidid, desc->type,
190: (long) desc->raidAddress,
191: (long) desc->raidAddress,
192: (int) desc->numBlocks, (int) desc->numBlocks,
193: (unsigned long) (desc->bufPtr));
194: }
195: }
196: dagList->numDagsDone++;
197: rf_ContinueRaidAccess(desc);
198: }
199:
200: int
201: rf_State_LastState(RF_RaidAccessDesc_t *desc)
202: {
203: void (*callbackFunc) (RF_CBParam_t) = desc->callbackFunc;
204: RF_CBParam_t callbackArg;
205:
206: callbackArg.p = desc->callbackArg;
207:
208: /*
209: * If this is not an async request, wake up the caller.
210: */
211: if (desc->async_flag == 0)
212: wakeup(desc->bp);
213:
214: /*
215: * That's all the IO for this one... Unbusy the 'disk'.
216: */
217:
218: rf_disk_unbusy(desc);
219:
220: /*
221: * Wakeup any requests waiting to go.
222: */
223:
224: RF_LOCK_MUTEX(((RF_Raid_t *) desc->raidPtr)->mutex);
225: ((RF_Raid_t *) desc->raidPtr)->openings++;
226: RF_UNLOCK_MUTEX(((RF_Raid_t *) desc->raidPtr)->mutex);
227:
228: /* Wake up any pending I/O. */
229: raidstart(((RF_Raid_t *) desc->raidPtr));
230:
231: /* printf("%s: Calling biodone on 0x%x.\n", __func__, desc->bp); */
232: splassert(IPL_BIO);
233: biodone(desc->bp); /* Access came through ioctl. */
234:
235: if (callbackFunc)
236: callbackFunc(callbackArg);
237: rf_FreeRaidAccDesc(desc);
238:
239: return RF_FALSE;
240: }
241:
242: int
243: rf_State_IncrAccessCount(RF_RaidAccessDesc_t *desc)
244: {
245: RF_Raid_t *raidPtr;
246:
247: raidPtr = desc->raidPtr;
248: /*
249: * Bummer. We have to do this to be 100% safe w.r.t. the increment
250: * below.
251: */
252: RF_LOCK_MUTEX(raidPtr->access_suspend_mutex);
253: raidPtr->accs_in_flight++; /* Used to detect quiescence. */
254: RF_UNLOCK_MUTEX(raidPtr->access_suspend_mutex);
255:
256: desc->state++;
257: return RF_FALSE;
258: }
259:
260: int
261: rf_State_DecrAccessCount(RF_RaidAccessDesc_t *desc)
262: {
263: RF_Raid_t *raidPtr;
264:
265: raidPtr = desc->raidPtr;
266:
267: RF_LOCK_MUTEX(raidPtr->access_suspend_mutex);
268: raidPtr->accs_in_flight--;
269: if (raidPtr->accesses_suspended && raidPtr->accs_in_flight == 0) {
270: rf_SignalQuiescenceLock(raidPtr, raidPtr->reconDesc);
271: }
272: rf_UpdateUserStats(raidPtr, RF_ETIMER_VAL_US(desc->timer),
273: desc->numBlocks);
274: RF_UNLOCK_MUTEX(raidPtr->access_suspend_mutex);
275:
276: desc->state++;
277: return RF_FALSE;
278: }
279:
280: int
281: rf_State_Quiesce(RF_RaidAccessDesc_t *desc)
282: {
283: RF_AccTraceEntry_t *tracerec = &desc->tracerec;
284: RF_Etimer_t timer;
285: int suspended = RF_FALSE;
286: RF_Raid_t *raidPtr;
287:
288: raidPtr = desc->raidPtr;
289:
290: RF_ETIMER_START(timer);
291: RF_ETIMER_START(desc->timer);
292:
293: RF_LOCK_MUTEX(raidPtr->access_suspend_mutex);
294: if (raidPtr->accesses_suspended) {
295: RF_CallbackDesc_t *cb;
296: cb = rf_AllocCallbackDesc();
297: /*
298: * XXX The following cast is quite bogus...
299: * rf_ContinueRaidAccess takes a (RF_RaidAccessDesc_t *)
300: * as an argument... GO
301: */
302: cb->callbackFunc = (void (*) (RF_CBParam_t))
303: rf_ContinueRaidAccess;
304: cb->callbackArg.p = (void *) desc;
305: cb->next = raidPtr->quiesce_wait_list;
306: raidPtr->quiesce_wait_list = cb;
307: suspended = RF_TRUE;
308: }
309: RF_UNLOCK_MUTEX(raidPtr->access_suspend_mutex);
310:
311: RF_ETIMER_STOP(timer);
312: RF_ETIMER_EVAL(timer);
313: tracerec->specific.user.suspend_ovhd_us += RF_ETIMER_VAL_US(timer);
314:
315: if (suspended && rf_quiesceDebug)
316: printf("Stalling access due to quiescence lock.\n");
317:
318: desc->state++;
319: return suspended;
320: }
321:
322: int
323: rf_State_Map(RF_RaidAccessDesc_t *desc)
324: {
325: RF_Raid_t *raidPtr = desc->raidPtr;
326: RF_AccTraceEntry_t *tracerec = &desc->tracerec;
327: RF_Etimer_t timer;
328:
329: RF_ETIMER_START(timer);
330:
331: if (!(desc->asmap = rf_MapAccess(raidPtr, desc->raidAddress,
332: desc->numBlocks, desc->bufPtr, RF_DONT_REMAP)))
333: RF_PANIC();
334:
335: RF_ETIMER_STOP(timer);
336: RF_ETIMER_EVAL(timer);
337: tracerec->specific.user.map_us = RF_ETIMER_VAL_US(timer);
338:
339: desc->state++;
340: return RF_FALSE;
341: }
342:
343: int
344: rf_State_Lock(RF_RaidAccessDesc_t *desc)
345: {
346: RF_AccTraceEntry_t *tracerec = &desc->tracerec;
347: RF_Raid_t *raidPtr = desc->raidPtr;
348: RF_AccessStripeMapHeader_t *asmh = desc->asmap;
349: RF_AccessStripeMap_t *asm_p;
350: RF_Etimer_t timer;
351: int suspended = RF_FALSE;
352:
353: RF_ETIMER_START(timer);
354: if (!(raidPtr->Layout.map->flags & RF_NO_STRIPE_LOCKS)) {
355: RF_StripeNum_t lastStripeID = -1;
356:
357: /* Acquire each lock that we don't already hold. */
358: for (asm_p = asmh->stripeMap; asm_p; asm_p = asm_p->next) {
359: RF_ASSERT(RF_IO_IS_R_OR_W(desc->type));
360: if (!rf_suppressLocksAndLargeWrites &&
361: asm_p->parityInfo &&
362: !(desc->flags & RF_DAG_SUPPRESS_LOCKS) &&
363: !(asm_p->flags & RF_ASM_FLAGS_LOCK_TRIED)) {
364: asm_p->flags |= RF_ASM_FLAGS_LOCK_TRIED;
365: /* Locks must be acquired hierarchically. */
366: RF_ASSERT(asm_p->stripeID > lastStripeID);
367: lastStripeID = asm_p->stripeID;
368: /*
369: * XXX The cast to (void (*)(RF_CBParam_t))
370: * below is bogus ! GO
371: */
372: RF_INIT_LOCK_REQ_DESC(asm_p->lockReqDesc,
373: desc->type, (void (*) (struct buf *))
374: rf_ContinueRaidAccess, desc, asm_p,
375: raidPtr->Layout.dataSectorsPerStripe);
376: if (rf_AcquireStripeLock(raidPtr->lockTable,
377: asm_p->stripeID, &asm_p->lockReqDesc)) {
378: suspended = RF_TRUE;
379: break;
380: }
381: }
382: if (desc->type == RF_IO_TYPE_WRITE &&
383: raidPtr->status[asm_p->physInfo->row] ==
384: rf_rs_reconstructing) {
385: if (!(asm_p->flags & RF_ASM_FLAGS_FORCE_TRIED))
386: {
387: int val;
388:
389: asm_p->flags |=
390: RF_ASM_FLAGS_FORCE_TRIED;
391: /*
392: * XXX The cast below is quite
393: * bogus !!! XXX GO
394: */
395: val = rf_ForceOrBlockRecon(raidPtr,
396: asm_p,
397: (void (*) (RF_Raid_t *, void *))
398: rf_ContinueRaidAccess, desc);
399: if (val == 0) {
400: asm_p->flags |=
401: RF_ASM_FLAGS_RECON_BLOCKED;
402: } else {
403: suspended = RF_TRUE;
404: break;
405: }
406: } else {
407: if (rf_pssDebug) {
408: printf("raid%d: skipping"
409: " force/block because"
410: " already done, psid"
411: " %ld.\n",
412: desc->raidPtr->raidid,
413: (long) asm_p->stripeID);
414: }
415: }
416: } else {
417: if (rf_pssDebug) {
418: printf("raid%d: skipping force/block"
419: " because not write or not"
420: " under recon, psid %ld.\n",
421: desc->raidPtr->raidid,
422: (long) asm_p->stripeID);
423: }
424: }
425: }
426:
427: RF_ETIMER_STOP(timer);
428: RF_ETIMER_EVAL(timer);
429: tracerec->specific.user.lock_us += RF_ETIMER_VAL_US(timer);
430:
431: if (suspended)
432: return (RF_TRUE);
433: }
434: desc->state++;
435: return (RF_FALSE);
436: }
437:
438: /*
439: * The following three states create, execute, and post-process DAGs.
440: * The error recovery unit is a single DAG.
441: * By default, SelectAlgorithm creates an array of DAGs, one per parity stripe.
442: * In some tricky cases, multiple dags per stripe are created.
443: * - DAGs within a parity stripe are executed sequentially (arbitrary order).
444: * - DAGs for distinct parity stripes are executed concurrently.
445: *
446: * Repeat until all DAGs complete successfully -or- DAG selection fails.
447: *
448: * while !done
449: * create dag(s) (SelectAlgorithm)
450: * if dag
451: * execute dag (DispatchDAG)
452: * if dag successful
453: * done (SUCCESS)
454: * else
455: * !done (RETRY - start over with new dags)
456: * else
457: * done (FAIL)
458: */
459: int
460: rf_State_CreateDAG(RF_RaidAccessDesc_t *desc)
461: {
462: RF_AccTraceEntry_t *tracerec = &desc->tracerec;
463: RF_Etimer_t timer;
464: RF_DagHeader_t *dag_h;
465: int i, selectStatus;
466:
467: /*
468: * Generate a dag for the access, and fire it off. When the dag
469: * completes, we'll get re-invoked in the next state.
470: */
471: RF_ETIMER_START(timer);
472: /* SelectAlgorithm returns one or more dags. */
473: selectStatus = rf_SelectAlgorithm(desc,
474: desc->flags | RF_DAG_SUPPRESS_LOCKS);
475: if (rf_printDAGsDebug)
476: for (i = 0; i < desc->numStripes; i++)
477: rf_PrintDAGList(desc->dagArray[i].dags);
478: RF_ETIMER_STOP(timer);
479: RF_ETIMER_EVAL(timer);
480: /* Update time to create all dags. */
481: tracerec->specific.user.dag_create_us = RF_ETIMER_VAL_US(timer);
482:
483: desc->status = 0; /* Good status. */
484:
485: if (selectStatus) {
486: /* Failed to create a dag. */
487: /*
488: * This happens when there are too many faults or incomplete
489: * dag libraries.
490: */
491: printf("[Failed to create a DAG]\n");
492: RF_PANIC();
493: } else {
494: /* Bind dags to desc. */
495: for (i = 0; i < desc->numStripes; i++) {
496: dag_h = desc->dagArray[i].dags;
497: while (dag_h) {
498: dag_h->bp = (struct buf *) desc->bp;
499: dag_h->tracerec = tracerec;
500: dag_h = dag_h->next;
501: }
502: }
503: desc->flags |= RF_DAG_DISPATCH_RETURNED;
504: desc->state++; /* Next state should be rf_State_ExecuteDAG. */
505: }
506: return RF_FALSE;
507: }
508:
509:
510: /*
511: * The access has an array of dagLists, one dagList per parity stripe.
512: * Fire the first DAG in each parity stripe (dagList).
513: * DAGs within a stripe (dagList) must be executed sequentially.
514: * - This preserves atomic parity update.
515: * DAGs for independents parity groups (stripes) are fired concurrently.
516: */
517: int
518: rf_State_ExecuteDAG(RF_RaidAccessDesc_t *desc)
519: {
520: int i;
521: RF_DagHeader_t *dag_h;
522: RF_DagList_t *dagArray = desc->dagArray;
523:
524: /*
525: * Next state is always rf_State_ProcessDAG. Important to do this
526: * before firing the first dag (it may finish before we leave this
527: * routine).
528: */
529: desc->state++;
530:
531: /*
532: * Sweep dag array, a stripe at a time, firing the first dag in each
533: * stripe.
534: */
535: for (i = 0; i < desc->numStripes; i++) {
536: RF_ASSERT(dagArray[i].numDags > 0);
537: RF_ASSERT(dagArray[i].numDagsDone == 0);
538: RF_ASSERT(dagArray[i].numDagsFired == 0);
539: RF_ETIMER_START(dagArray[i].tracerec.timer);
540: /* Fire first dag in this stripe. */
541: dag_h = dagArray[i].dags;
542: RF_ASSERT(dag_h);
543: dagArray[i].numDagsFired++;
544: /*
545: * XXX Yet another case where we pass in a conflicting
546: * function pointer :-( XXX GO
547: */
548: rf_DispatchDAG(dag_h, (void (*) (void *)) rf_ContinueDagAccess,
549: &dagArray[i]);
550: }
551:
552: /*
553: * The DAG will always call the callback, even if there was no
554: * blocking, so we are always suspended in this state.
555: */
556: return RF_TRUE;
557: }
558:
559:
560: /*
561: * rf_State_ProcessDAG is entered when a dag completes.
562: * First, check that all DAGs in the access have completed.
563: * If not, fire as many DAGs as possible.
564: */
565: int
566: rf_State_ProcessDAG(RF_RaidAccessDesc_t *desc)
567: {
568: RF_AccessStripeMapHeader_t *asmh = desc->asmap;
569: RF_Raid_t *raidPtr = desc->raidPtr;
570: RF_DagHeader_t *dag_h;
571: int i, j, done = RF_TRUE;
572: RF_DagList_t *dagArray = desc->dagArray;
573: RF_Etimer_t timer;
574:
575: /* Check to see if this is the last dag. */
576: for (i = 0; i < desc->numStripes; i++)
577: if (dagArray[i].numDags != dagArray[i].numDagsDone)
578: done = RF_FALSE;
579:
580: if (done) {
581: if (desc->status) {
582: /* A dag failed, retry. */
583: RF_ETIMER_START(timer);
584: /* Free all dags. */
585: for (i = 0; i < desc->numStripes; i++) {
586: rf_FreeDAG(desc->dagArray[i].dags);
587: }
588: rf_MarkFailuresInASMList(raidPtr, asmh);
589: /* Back up to rf_State_CreateDAG. */
590: desc->state = desc->state - 2;
591: return RF_FALSE;
592: } else {
593: /* Move on to rf_State_Cleanup. */
594: desc->state++;
595: }
596: return RF_FALSE;
597: } else {
598: /* More dags to execute. */
599: /* See if any are ready to be fired. If so, fire them. */
600: /*
601: * Don't fire the initial dag in a list, it's fired in
602: * rf_State_ExecuteDAG.
603: */
604: for (i = 0; i < desc->numStripes; i++) {
605: if ((dagArray[i].numDagsDone < dagArray[i].numDags) &&
606: (dagArray[i].numDagsDone ==
607: dagArray[i].numDagsFired) &&
608: (dagArray[i].numDagsFired > 0)) {
609: RF_ETIMER_START(dagArray[i].tracerec.timer);
610: /* Fire next dag in this stripe. */
611: /*
612: * First, skip to next dag awaiting execution.
613: */
614: dag_h = dagArray[i].dags;
615: for (j = 0; j < dagArray[i].numDagsDone; j++)
616: dag_h = dag_h->next;
617: dagArray[i].numDagsFired++;
618: /*
619: * XXX And again we pass a different function
620: * pointer... GO
621: */
622: rf_DispatchDAG(dag_h, (void (*) (void *))
623: rf_ContinueDagAccess, &dagArray[i]);
624: }
625: }
626: return RF_TRUE;
627: }
628: }
629:
630: /* Only make it this far if all dags complete successfully. */
631: int
632: rf_State_Cleanup(RF_RaidAccessDesc_t *desc)
633: {
634: RF_AccTraceEntry_t *tracerec = &desc->tracerec;
635: RF_AccessStripeMapHeader_t *asmh = desc->asmap;
636: RF_Raid_t *raidPtr = desc->raidPtr;
637: RF_AccessStripeMap_t *asm_p;
638: RF_DagHeader_t *dag_h;
639: RF_Etimer_t timer;
640: int i;
641:
642: desc->state++;
643:
644: timer = tracerec->timer;
645: RF_ETIMER_STOP(timer);
646: RF_ETIMER_EVAL(timer);
647: tracerec->specific.user.dag_retry_us = RF_ETIMER_VAL_US(timer);
648:
649: /* The RAID I/O is complete. Clean up. */
650: tracerec->specific.user.dag_retry_us = 0;
651:
652: RF_ETIMER_START(timer);
653: if (desc->flags & RF_DAG_RETURN_DAG) {
654: /* Copy dags into paramDAG. */
655: *(desc->paramDAG) = desc->dagArray[0].dags;
656: dag_h = *(desc->paramDAG);
657: for (i = 1; i < desc->numStripes; i++) {
658: /* Concatenate dags from remaining stripes. */
659: RF_ASSERT(dag_h);
660: while (dag_h->next)
661: dag_h = dag_h->next;
662: dag_h->next = desc->dagArray[i].dags;
663: }
664: } else {
665: /* Free all dags. */
666: for (i = 0; i < desc->numStripes; i++) {
667: rf_FreeDAG(desc->dagArray[i].dags);
668: }
669: }
670:
671: RF_ETIMER_STOP(timer);
672: RF_ETIMER_EVAL(timer);
673: tracerec->specific.user.cleanup_us = RF_ETIMER_VAL_US(timer);
674:
675: RF_ETIMER_START(timer);
676: if (!(raidPtr->Layout.map->flags & RF_NO_STRIPE_LOCKS)) {
677: for (asm_p = asmh->stripeMap; asm_p; asm_p = asm_p->next) {
678: if (!rf_suppressLocksAndLargeWrites &&
679: asm_p->parityInfo &&
680: !(desc->flags & RF_DAG_SUPPRESS_LOCKS)) {
681: RF_ASSERT_VALID_LOCKREQ(&asm_p->lockReqDesc);
682: rf_ReleaseStripeLock(raidPtr->lockTable,
683: asm_p->stripeID, &asm_p->lockReqDesc);
684: }
685: if (asm_p->flags & RF_ASM_FLAGS_RECON_BLOCKED) {
686: rf_UnblockRecon(raidPtr, asm_p);
687: }
688: }
689: }
690: RF_ETIMER_STOP(timer);
691: RF_ETIMER_EVAL(timer);
692: tracerec->specific.user.lock_us += RF_ETIMER_VAL_US(timer);
693:
694: RF_ETIMER_START(timer);
695: if (desc->flags & RF_DAG_RETURN_ASM)
696: *(desc->paramASM) = asmh;
697: else
698: rf_FreeAccessStripeMap(asmh);
699: RF_ETIMER_STOP(timer);
700: RF_ETIMER_EVAL(timer);
701: tracerec->specific.user.cleanup_us += RF_ETIMER_VAL_US(timer);
702:
703: RF_ETIMER_STOP(desc->timer);
704: RF_ETIMER_EVAL(desc->timer);
705:
706: timer = desc->tracerec.tot_timer;
707: RF_ETIMER_STOP(timer);
708: RF_ETIMER_EVAL(timer);
709: desc->tracerec.total_us = RF_ETIMER_VAL_US(timer);
710:
711: rf_LogTraceRec(raidPtr, tracerec);
712:
713: desc->flags |= RF_DAG_ACCESS_COMPLETE;
714:
715: return RF_FALSE;
716: }
CVSweb