Commit Graph

683 Commits

Author SHA1 Message Date
oster bce42a3095 Move pss_pool to rf_pools. Will save a bit of extra memory at
run-time, and we can only do one reconstruction at a time anyway.
Nuke pss_issued_pool - move it to an internal structure in pss.
2004-03-08 02:25:27 +00:00
oster 8cbd53826e A few more cleanups missed in last commit. 2004-03-08 01:59:26 +00:00
oster acce07be62 Minor cleanup. No functional change. 2004-03-08 01:55:14 +00:00
oster c25748c684 Rename rf_rad_pool_lock to rf_rad_lock. The latter is far more
accurate.
2004-03-07 23:17:44 +00:00
oster f95359dd19 - Introduce rf_pools which contains all of the various global pools used
by RAIDframe.  Convert all other RAIDframe global pools to use pools
defined within this new structure.
- Introduce rf_pool_init(), used for initializing a single pool in
RAIDframe.  Teach each of the configuration routines to use
rf_pool_init().
- Cleanup a few pool-related comments.
- Cleanup revent initialization and #defines.
- Add a missing pool_destroy() for the reconbuffer pool.

(Saves another 1K off of an i386 GENERIC kernel, and makes
stuff a lot more readable)
2004-03-07 22:15:19 +00:00
oster 834d494bb2 - Introduce rf_pools which contains all of the various global pools used
by RAIDframe.  Convert all other RAIDframe global pools to use pools
defined within this new structure.
- Introduce rf_pool_init(), used for initializing a single pool in
RAIDframe.  Teach each of the configuration routines to use
rf_pool_init().
- Cleanup a few pool-related comments.
- Cleanup revent initialization and #defines.
- Add a missing pool_destroy() for the reconbuffer pool.

(Saves another 1K off of an i386 GENERIC kernel, and makes
stuff a lot more readable)
2004-03-07 21:57:44 +00:00
oster c31c7c5652 Cleanup function prototypes. 2004-03-07 05:01:15 +00:00
oster dd0716f291 We don't need 2-fault tollerant stuff here in the default case.
Use #if's to conditionalize the code compilation.
(Saves another 1K on i386 GENERIC kernels)
2004-03-07 02:59:25 +00:00
oster 43648c8525 Minor cleanups. No functional changes. 2004-03-07 02:49:23 +00:00
oster d02f580adf - fix up initialization of rf_recond_pool
- introduce rf_reconbuffer_pool and teach rf_MakeReconBuffer() to use it
2004-03-07 02:46:58 +00:00
oster 3f36d142d8 Re-work rf_GenerateFailedAccessASMs() to simplify things a bit.
rf_AllocBuffer() is available, so use it to get buffer space instead
of the previous RF_Malloc() bits.  Saves a few bytes, but more
importantly makes the code much more readable.
2004-03-07 02:25:36 +00:00
oster 9e4fc614fc Pretty up a bit of unused code. 2004-03-06 23:53:31 +00:00
oster 967b00b4ec rf_AllocBuffer() doesn't do anything with its dag_h parameter. Nuke
it, and adjust callers.
2004-03-06 23:52:20 +00:00
oster 54eab15188 Sprinkle a few #if's to ignore some bits that are only used for RAID 6 or PQ stuff. Saves another 3K on i386 GENERIC. 2004-03-06 23:34:27 +00:00
oster dc76c4b111 Minor tabbing cleanup. No functional change. 2004-03-06 22:59:42 +00:00
oster bfeeabba13 Use RF_INCLUDE_PARITY_DECLUSTERING_DS to #if-out more unneeded bits.
(We can't do RF_DISTRIBUTE_SPARE bits without the parity declustering stuff.)
2004-03-05 03:58:21 +00:00
oster 7bd09b0f2b Introduce RF_DEBUG_DAG and use it to #if-out rf_dagDebug sections.
(i386 GENERIC kernel shrinks by 1.6K)
2004-03-05 03:22:05 +00:00
oster a0413593bc - remove the RF_*_INC's, as necessary. They are not needed any more.
- introduce RF_MIN_*'s, as necessary.  These will indicate the
low-water mark for pools as well as the pool_prime() value.
- add pool_setlowat() for the critical pools.
- pool_prime() and pool_setlowat() the raidframe_cbufpool.
- re-order some pool_prime()'s and pool_sethiwat()'s for clarity.
2004-03-05 02:53:55 +00:00
oster a57d045808 Remove a comment that is no longer relevant. 2004-03-04 03:27:30 +00:00
oster b6ec2bc708 Cleanup function prototypes. 2004-03-04 03:14:02 +00:00
oster 516b22a972 Another variable that was only ever initialized. Turf. 2004-03-04 03:02:01 +00:00
oster 5d768c003f Cleanup function prototypes. 2004-03-04 02:55:58 +00:00
oster 708c19adaf Fix mcpair locking issues -- we really don't need the lock held
the entire time we spend in calling rf_DiskIOEnqueue().
2004-03-04 02:49:58 +00:00
oster 409f2e3222 More function prototype cleanups. 2004-03-04 02:26:50 +00:00
oster 5102542bf2 Cleanup function prototype. 2004-03-04 02:25:13 +00:00
oster 65f967653e More leftover 'row' bits now removed. 2004-03-04 01:57:54 +00:00
oster 55cb2c9a0d Cleanup one more leftover 'row' variable. Cleanup function prototypes
in rf_diskqueue.h
2004-03-04 01:53:25 +00:00
oster 6e2928d6d5 resultNum isn't used anywhere. Good-bye. 2004-03-04 00:56:13 +00:00
oster 8b515e1496 rf_bwd1 and rf_bwd2 are holdovers from the "backward" error recovery.
Nuke them, and the little bit of code associated with them.
2004-03-04 00:54:30 +00:00
oster 2fb9f8db54 Nuke some unnecessary casts. No functional changes. 2004-03-03 17:14:46 +00:00
oster 28bd6c8ea2 Introduce RF_REVENT_READ_FAILED, RF_REVENT_WRITE_FAILED and RF_REVENT_FORCEREAD_FAILED.
This removes 3 more RF_PANIC()'s (but we'll currently still panic if any of these cases occur).
fix up a few printf's.
XXX: still needs more cleanup and testing (and be taught to not panic).
2004-03-03 16:59:54 +00:00
oster b2784ea2d7 Cleanup function prototypes. 2004-03-03 16:12:28 +00:00
oster 992f7c8269 - cleanup unneeded 'row' from RF_CallbackDesc_s.
- remove callbackArg2 from RF_CallbackDesc_s -- it is only ever set,
never read.
- now that this is done, all callbacks should only take a single argument,
and we can simplify things further.
2004-03-03 13:29:00 +00:00
oster dc851b8e23 Improve comments on rf_LookupRUStatus(). No functional changes. 2004-03-03 01:02:44 +00:00
oster edf3711f4e Cleanup function prototypes. 2004-03-03 00:58:03 +00:00
oster b3eae139eb - cleanup memory allocation in rf_AllocPSStatus()
- change function signature of rf_LookupRUStatus().  The last argument
is now a pointer to a new PSS, in case one is needed.  Rather than
having rf_LookupRUStatus() allocate a new PSS, we pre-allocate one
beforehand, where necessary, just in case.
- change callers of rf_lookupRUStatus() to deal with the new way of
calling rf_lookupRUStatus().

[no improvement or worsening of parity rebuild/initialization performance.]
2004-03-03 00:45:20 +00:00
oster 564980b994 Another spot where we're willing to wait for pool_get to give us something
useful.
2004-03-02 19:36:21 +00:00
oster a37cdad459 A few more cases where RF_DEBUG_PSS can be used. 2004-03-02 16:40:10 +00:00
oster 79a5cbaf41 DO_WAIT and DO_SIGNAL macros are a bit much, as they are only each used
in one place.  Simplify things a bit.  No functional change.
2004-03-02 16:03:00 +00:00
oster a7e422ac7f We're willing to wait, so we should always get something valid from
pool_get().
2004-03-02 15:55:56 +00:00
oster d2accf5991 Fix more cases where mutex locks were being held longer than necessary.
[For the record: The mcpair mutex is being used to protect mcpair->flag.
mcpair gets allocated before each call to rf_DispatchDAG(), so there is no
other process/thread that could be mucking with it.  It is only used to
detect the completion of a given parity unit, and rf_DispatchDAG()
only uses it to setup the callback argument for rf_MCPairWakeupFunc()
which will be called when the IO completes.  The code after the call
to rf_DispatchDAG() sits and waits for a 'wakeup' on mcpair->cond
(rf_MCPairWakeupFunc() does that).  If mcpair->flag is 0 when
rf_DispatchDAG() completes, then rf_MCPairWakeupFunc() hasn't been
called yet (the IO hasn't completed).  If it is 1, then the IO is
already done, and we continue on our merry way without sleeping.
Thus, we don't need to hold any lock on mcpair while calling
rf_DispatchDAG().]
2004-03-02 15:47:35 +00:00
oster c7eaad6a14 Use RF_ACC_TRACE to #if out more chunks of code related only
to access tracing.  (not turned on yet)
2004-03-01 23:30:57 +00:00
oster e35e293611 We always wait until we get memory, so the NULL check doesn't buy us anything. 2004-03-01 01:12:22 +00:00
oster 63e07285f8 Bah. RF_ACC_TRACE bits need a bit more work before they can be turned off.
Re-enable until all parts can be disabled at the same time.
2004-02-29 23:27:24 +00:00
oster b5e62ef069 As a LOCK_DEBUG kernel complains, we should really initialze
rf_tracing_mutex.
2004-02-29 23:10:58 +00:00
oster 4b8d5fc8b6 Unlock the mcpair mutex before we call rf_DispatchDAG(), and re-lock it once
we are back.  Makes things much happier on SMP boxen.  Problem noted
by SimonB. (Thanks!)
2004-02-29 23:03:30 +00:00
oster e9ec029612 Oops.. might still need this mutex in a few places. 2004-02-29 22:32:37 +00:00
oster 65ba8db490 Minor shuffling of variable declarations to clean RF_ACC_TRACE #defines
up a bit.  No functional changes.
2004-02-29 22:11:54 +00:00
oster 0d2f3606aa Add "RF_ACC_TRACE" as a new #define to rf_archs.h.
Use it to conditionalize some of the access tracing and tracerec bits.
Chops about 4 K off of an i386 GENERIC kernel.
2004-02-29 21:38:41 +00:00
oster cf01eb78b2 Minor comment reformatting. 2004-02-29 20:47:37 +00:00
oster d272af6ed2 When the 'if' condition is true, the function will return, so there
is no need for this chunk of code to be in the 'else' part.
Remove the 'else', and left-shift the code.

No functional changes.
2004-02-29 20:11:26 +00:00
oster 5a02af5b21 Adjust _rf_ShutdownCreate() so that it is willing to wait for more
memory.  Since we only now ever "return(0)", just return (void)
instead.

Cleanup all uses of rf_ShutdownCreate() to not worry about
it ever failing.  Shaves another 600 bytes off of an i386 GENERIC kernel.
2004-02-29 04:03:50 +00:00
oster da96c7f542 InitHdrNode() might as well return 'void'. Nothing ever pays attention
to what it returns anyway!
2004-02-29 01:50:23 +00:00
oster 4907fd699b rf_MakeAllocList() will always get memory. No point in checking for
a case that won't ever occur.
2004-02-29 01:49:13 +00:00
oster d4a8e64b16 We'd better have gotten a dag header from the pool. In any event, callers
arn't checking what we return anyway. (Cleanup memory allocations.)
2004-02-29 01:47:45 +00:00
oster 2e0cff190a TransferDagMemory() doesn't exist, so these lines are just wasting space. 2004-02-29 01:37:04 +00:00
oster 5e23bfcf9b Stripe functions are now handled by a linked-list instead of a
runtime-variable array.

Fix a bug where stripeFuncs was being freed, and then being used after
(in the case of numStripesBailed > 0).
2004-02-29 01:24:34 +00:00
oster 873f4a20f5 Add forgotten pool_destroy(). 2004-02-27 03:18:02 +00:00
oster 24099528e9 Use a dynamically allocated linked list of dagLists instead of using a
dynamically allocated variable-sized array (dagArray).  Convert code
to use the new linked list stuff instead of the array stuff (the ratio
of one dagList per stripe still applies).  The big advantage is in
being able to more efficiently allocate the dagLists on-the-fly, and
not have to know the size(s) of the array beforehand.
2004-02-27 02:55:17 +00:00
oster d3f3b25e8d Poolify alloclist stuff. Saves a whopping 32 bytes while decreasing code
complexity.
2004-02-25 02:15:52 +00:00
wiz f05e6f1a3a occured -> occurred. From Peter Postma. 2004-02-24 15:12:51 +00:00
oster 8bf9613af8 unlockQNodes, unlockDataNodes, and unlockParityNodes are not used. Turf. 2004-02-21 20:06:29 +00:00
oster 2eaec068c9 Relegate some printf's to DEBUG land. 2004-02-08 04:37:56 +00:00
hannken 3db4e2acd8 Make VOP_STRATEGY(bp) a real VOP as discussed on tech-kern.
VOP_STRATEGY(bp) is replaced by one of two new functions:

- VOP_STRATEGY(vp, bp)  Call the strategy routine of vp for bp.
- DEV_STRATEGY(bp)      Call the d_strategy routine of bp->b_dev for bp.

DEV_STRATEGY(bp) is used only for block-to-block device situations.
2004-01-25 18:06:48 +00:00
oster b68ecaf95f Always ask for a new RF_StripeLockDesc_t "just in case", and then
give it back if we don't need it.  If we don't allocate it before
we take our lock, LOCKDEBUG (rightfully) complains that we're trying
to grab something from the pool with PR_WAITOK.  This code (and the
PR_WAITOK in particular) really needs to be revisited at some point.
2004-01-23 01:57:08 +00:00
oster 1a5bc3eb34 Add missing simple_lock_init(). Noted by skrueger-at-europe-dot-com. 2004-01-15 20:27:27 +00:00
oster 7ab3e4e2e3 Add 2 missing RF_LOCK_MUTEX()es. Problem pointed out by
skrueger-at-europe-dot-com.  (It turns out that the mutex used to
serve two different purposes, not just one, and for its current use,
it's actually miss-named.  Will fix that some other time.)
2004-01-14 15:10:55 +00:00
oster 6297e36a60 Since the LOCK and UNLOCK flags are never used, no need in extracting them.
Collapse the related variables down to zero.  That means 'flags' is 0
as well.  Nuke the extraction macros, a bunch of the variables, and replace
'flags' as well.
2004-01-10 17:04:44 +00:00
yamt 7266a95907 store a i/o priority hint in struct buf for buffer queue discipline. 2004-01-10 14:39:50 +00:00
oster 2e19186660 iCleanup the RF_CREATE_PARAM3(). Middle two "arguments" were nothing
but 0 in all cases.
2004-01-10 00:56:27 +00:00
oster 5b7e949cbf More lu_flags disappear into oblivion. 2004-01-10 00:53:08 +00:00
oster 7edb3013bb Nuke lu_flag and code associated with it being non-zero.
The compiler already knew that these chunks of code
could never be reached (since lu_flag was always 0), so it
already ignored them.
No functional changes.
2004-01-09 23:35:59 +00:00
oster ac6b86acbb [This file should have been committed with the other
rf_enableAtomicRMW changes.]

Cleanup rf_enableAtomicRMW and its use.  According to the comments, we
can't set this to anything other than zero anyway.  Shaves off another
900 bytes.  lu_flag's days are numbered now, as are the middle
parameters of RF_CREATE_PARAM3.
2004-01-09 23:31:37 +00:00
oster 35d7c1ee7e Cleanup rf_enableAtomicRMW and its use. According to the comments, we
can't set this to anything other than zero anyway.  Shaves off another
900 bytes.  lu_flag's days are numbered now, as are the middle
parameters of RF_CREATE_PARAM3.
2004-01-09 23:26:17 +00:00
oster d9ff8342a0 Clean up a few comments, and improve code formatting somewhat.
Makes things a bit more readable.

No functional changes.
2004-01-06 03:27:13 +00:00
oster 181f2eebee remove terminate_disk_queues from RF_Raid_s. The hist_diskreq[]
stuff is only used for the CHAINDECLUSTERING, so hide it with an #if.
2004-01-05 01:19:07 +00:00
oster 290ef1fca7 raidPtr->reconControl->percentCompleted only gets used in one
debugging printf, and in rf_netbsdkintf.c.  We can do the calculations
inside of RF_DEBUG_RECON for the one debugging printf, and only
perform the percentCompleted calculation "on demand" in the
rf_netbsdkintf.c case.  Shaves a few more bytes off an i386 GENERIC
kernel, and ever-so-slightly decreases the amount of work performed
during a reconstruct.
2004-01-04 21:06:04 +00:00
oster 87e6ffb752 As noted by Thierry Deval in a posting to misc/at/openbsd.org,
rf_DecrAccessesCountState wasn't in the correct spot in
RF_AccessState_e.  Following up on that has resulted in one other
correction.  Changing orderings of these states is tricky, and
shouldn't be attempted without some thorough analysis.  For the
changes committed, the following analysis is offerred:

1) RAIDframe uses a little state machine to take care of building,
executing, and processing the DAGs used to direct IO.

2) The rf_DecrAccessesCountState state is handled by the function
rf_State_DecrAccessCount().  The purpose of this state is to
decrement the number of "accesses-in-flight".

3) rf_Cleanup_State is handled by rf_State_Cleanup().  Its job is to
do general cleanup of DAG arrays and any stripe locks.

4) DefaultStates[] in rf_layout.c indicates that the right spot
for rf_DecrAccessesCountState is just before rf_Cleanup_State.
Analysis of code for both states indicates that the order doesn't
matter too much, although rf_State_DecrAccessCount() should probably
take place *after* rf_State_Cleanup() to be more correct.

5) Comments in rf_State_ProcessDAG() indicates that the next state
should be rf_Cleanup_State.  However: it attempts to get there by using

 desc->state++;

which actually takes it to just rf_DecrAccessesCountState! This turned
out to be OK before, since rf_Cleanup_State would follow right after,
and all would be taken careof (albeit in arguably the "less correct"
order).

6) With the current ordering, if we head directly to rf_Cleanup_State
(as we do, for example, if multiple components fail in a RAID 5 set),
then we'll actually miss going trough rf_DecrAccessesCountState), and
could end up never being able to reach quiescence!  Perhaps not too
big of a deal, given that the RAID set is pretty much toast by that
point at which such a drastic state change happens, but might as well
have this correct.

The changes made are:
1) Since having rf_State_DecrAccessCount() come after
rf_State_Cleanup() is just fine, change rf_layout.c to reflect that
rf_DecrAccessesCountState comes after rf_Cleanup_State (i.e. they swap
positions in the state list).  This means that going to
rf_Cleanup_State after bailing on a failed DAG access will do all the
right things -- the state will get cleaned up, and then the access
counts will get decremented properly.  The comment in
rf_State_ProcessDAG() is now actually correct -- the next state *will*
be rf_Cleanup_State.

2) Move rf_DecrAccessesCountState in RF_AccessState_e to just after
rf_CleanupState.  This puts RF_AccessState_e in sync with
DefaultStates[].  Fortunately, these states are rarely referred to by
name, and so this change ends up being mostly cosmetic -- it really
only fixes cleanup behaviour for the recent "Failed to create a DAG"
changes.
2004-01-04 06:37:16 +00:00
oster 24b034a69e Fix the "We panic if we can't create a DAG" problem that's existed
~forever.  This requires a number of things:

1) If we can't create a DAG, set desc->numStripes to 0 in
rf_SelectAlgorithm.  This will ensure that we don't attempt to free
any dagArray[] elements in rf_StateCleanup.

2) Modify rf_State_CreateDAG() to not panic in the event of a DAG
failure.  Instead, set the bp->b_flags and bp->b_error, and set things
up to skip to rf_State_Cleanup().

3) Need to mark desc->status as "bad" so that we actually stop looking
for a different DAG.  (which we won't find... no matter how many times
we try).

4) rf_State_LastState() will then do the biodone(), and return EIO for
the IO in question.

5) Remove some " || 1 "'s from ProcessNode().  These were for
debugging, and we don't need the failure notices spewing
over and over again as the failing DAGs are processed.

6) Needed to change

       if (asmap->numDataFailed + asmap->numParityFailed > 1)

to

        if ((asmap->numDataFailed + asmap->numParityFailed > 1) ||
            (raidPtr->numFailures > 1)){

in rf_raid5.c so that it doesn't try to return
rf_CreateNonRedundantWriteDAG as the creation function.

7) Note that we can't apply the above change to the RAID 1 code as
with the silly "fake 2-D" RAID 1 sets, it is possible to have 2 failed
components in the RAID 1 set, and that would stop them from working.
(I really don't know why/how those "fake 2-D" RAID 1 sets even work
with all the "single-fault" assumptions present in the rest of the
code.)

8) Needed to protect rf_RAID0DagSelect() in a similar way -- it should
return NULL as the createFunc.

9) No point printing out "Multiple disks failed..." a zillion times.
2004-01-02 21:41:08 +00:00
hannken 897a1fc008 Remove "row" from DEBUG statements. 2004-01-02 11:52:15 +00:00
oster 5b70d1d979 Cleanup some unused desc->flags:
RF_DAG_RETURN_DAG
RF_DAG_RETURN_ASM
RF_DAG_TEST_ACCESS
and the code that goes with them.  A couple more of these
can probably go too, but I might need them in a bit.
2004-01-01 23:35:08 +00:00
oster f025a0425c Finally cleanup RF_BZERO. Turns out that 'bp' was only used to obtain
bp->b_proc for mapping userspace buffers to kernelspace in the
original rf_kintf.c.  That means bp isn't of any use in RF_BZERO()
for us, and the macro can be replaced with just the memset().

No functional changes.
2004-01-01 20:39:58 +00:00
oster da4ed88ce1 Tidy up the #includes a bit. 2004-01-01 19:37:17 +00:00
oster f2512ce061 Nuke a few more 'row'-related bits that were missed in the row-removal. 2004-01-01 19:32:55 +00:00
oster d3aa064253 Nuke a bunch of unused variables:
- node_queue_cond
 - quiescent_cond
 - eq_cond
 - desc->cond
 - desc->head
 - diskqueue->numWaiting

Nuke rf_print_unable_to_init_cond().
Nuke rf_TerminateDiskQueues prototype from rf_diskqueue.h.
2004-01-01 19:27:35 +00:00
oster 2c490b5588 Remove 3 unused debugging options:
RF_DBG_OPTION(accessTraceBufSize, 0)
RF_DBG_OPTION(disableAsyncAccs, 0)
RF_DBG_OPTION(suppressTraceDelays, 0)
2003-12-31 22:25:38 +00:00
oster 7ea5de8a08 Clean up a bunch of comments. 2003-12-31 17:47:53 +00:00
oster 7f9bbe325c Replace the DO_FREE() macro with just RF_Free(). No functional changes,
just less confusion.
2003-12-31 16:32:50 +00:00
oster 8ff567e586 Fix comments and make function declarations conform.
No functional changes.
2003-12-31 16:23:50 +00:00
oster a5c20197a4 Add in a bunch of RF_SIGNAL_COND()'s that were missing. Tidy up
a few lines.
2003-12-31 04:13:52 +00:00
oster abbecc25a2 Left-shift another else{} chunk. No functional changes. 2003-12-31 04:00:01 +00:00
oster b7bb3e3c62 left-shift the "else" part of the if(!lp_SubmitReconBuffer) condition.
Cleanup.  No real functional changes, just more readable.
2003-12-31 03:51:28 +00:00
oster 824f2ed930 Negate a condition, and flip if/else parts. Preparation for left-shifting
the (now) else part.  No real functional change.
2003-12-31 03:29:11 +00:00
oster 00515ece62 Remove a couple of incorrect comments. (rf_recon_req needs to be
passed to rf_ReconThread(), and there's no way around that for now.)
2003-12-31 03:02:57 +00:00
oster 4283fdd054 init_dqd and clean_dqd don't do enough to be their own functions,
and just serve to cause confusion.  Back-merge their contents to their
(only) calling spots and nuke them.
2003-12-31 02:47:58 +00:00
oster 7c465d22a7 Increase the scope of RF_DEBUG_PSS to cover a bit more stuff. 2003-12-31 00:42:46 +00:00
oster 4635d077cf nuke the 'bp' argument to rf_bxor and friends since it is no longer used.
In fact, bp was being set to "NULL" when passed rf_bxor() in
rf_parityscan.c:rf_VerifyParityBasic().
2003-12-31 00:00:06 +00:00
oster 6e2bbdfcc9 Very carefully remove REMAP_VA() macro. It's only doing a simple
assignement, and the 'bp' argument isn't used. (Guess what's going to
disappear next?)  No functional changes.
2003-12-30 23:40:20 +00:00
oster f5e96bf53e Nuke a forgotten 'row' from struct RF_PerDiskReconCtrl_s. 2003-12-30 23:23:17 +00:00
oster dd05ba5c10 sparediskids isn't used anywhere. turf. 2003-12-30 22:56:40 +00:00