[linux-lvm] Re: raid 1 on a single disk
ashwin chaugule
ashwin.chaugule at gmail.com
Mon Nov 15 06:09:20 UTC 2004
>Then I suggest you attempt to describe what you are doing. The above
>fails!
Its really simple .. dont know why you cant comprehend it.
Hope you understand from the code ...
in __do_rw_disk
if(MINOR(rq->rq_dev)==69 && rq->cmd==WRITE){
rq1 = duplicate_request(rq);
drive->rq=rq1;
}
where duplicate_request , is a simple kmalloc and memcpy of rq.
rq1 is going to be our duplicate request.
then ....
if(MINOR(rq->rq_dev)==69 && rq->cmd==WRITE)
{
block_copy = block;
get_address(drive,rq1,block);
}
else {
hwif->OUTB(0x00, IDE_FEATURE_REG);
hwif->OUTB(nsectors.b.low, IDE_NSECTOR_REG);
hwif->OUTB(block, IDE_SECTOR_REG);
hwif->OUTB(block>>=8, IDE_LCYL_REG);
hwif->OUTB(block>>=8, IDE_HCYL_REG);
hwif->OUTB(((block>>8)&0x0f)|drive->select.all,IDE_SELECT_REG);
}
where get_address will do a block=block + (drive->capacity / 2);
and refill all the above registers.
then
when its a (non DMA) WRITE ...
if(MINOR(rq->rq_dev)==69 && rq->cmd==WRITE)
hwgroup->wrq = *rq1; /* scratchpad */
else
hwgroup->wrq = *rq; /* scratchpad */
then ...
if(MINOR(rq->rq_dev)==69 && rq->cmd==WRITE){
rq1->q->queuedata=(void *)rq;
//queuedata is an unused ptr. so it stores the original rq.
ide_set_handler(drive,
&multwrite_intr_withoutend, WAIT_CMD, NULL);
}
else
ide_set_handler(drive, &multwrite_intr, WAIT_CMD, NULL);
where ... multiwrite_intr_withoutend is my custom handler ...
now in multiwrite_withoutend
if (rq->nr_sectors) {
if (ide_multwrite(drive, drive->mult_count))
return ide_stopped;
ide_set_handler(drive,
&multwrite_intr_withoutend, WAIT_CMD, NULL);
return ide_started;
else
ndelay(400);
HWGROUP(drive)->handler=0;
kfree(drive->rq);
drive->rq=(struct request
*)(drive->rq->q->queuedata);
hwgroup->wrq = *(drive->rq); /* scratchpad */
restore_original_condition(drive);
command = ((drive->mult_count) ?
((lba48) ? WIN_MULTWRITE_EXT : WIN_MULTWRITE) :
((lba48) ? WIN_WRITE_EXT : WIN_WRITE));
hwif->OUTB(command, IDE_COMMAND_REG);
-snip-
ide_set_handler(drive, &multwrite_intr,
WAIT_CMD, NULL);
etc etc
this is where , i reset the original condition , and set the handler back...
so the original request is completed.
... So you see that , when there's a write request coming to my disk ,
1) duplicate the req.
2) set the handler
3) perform the write
4) DO NOT call end_request ... so no end_io
5) after its done , restore original condition
6) let it do its thing
Why wont it unmount ?
Ashwin
More information about the linux-lvm
mailing list