[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