Re: Request queues and bio structures

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



http://docs.blackfin.uclinux.org/doku.php?id=block_io_subsystem
http://docs.blackfin.uclinux.org/doku.php?id=basic_block_drivers
http://blog.chinaunix.net/u/15620/showart_510592.html
http://blog.chinaunix.net/u2/74194/showart_1089971.html
http://lwn.net/Articles/27361/

etc....

On Thu, Sep 11, 2008 at 1:47 AM, Rohit Sharma <imreckless@xxxxxxxxx> wrote:
> ---------- Forwarded message ----------
> From: Rohit Sharma <imreckless@xxxxxxxxx>
> Date: Wed, Sep 10, 2008 at 10:57 PM
> Subject: Re: Request queues and bio structures
> To: Peter Teoh <htmldeveloper@xxxxxxxxx>
>
>
> What i figured out is when a request for reading blocks is made
> then two possibilities are there
> 1. Requested block is available in the buffer.
> 2.The requested block has to be read from memory.
>
> we are concerned with the second case.
>
> So block to be read is identified from device mapper
> and then generic block layer starts I/O operation
> This request is given to the I/O scheduler
> Now our block device driver will actually transfer data by
> giving appropriate commands to the device.
>
> So , how does the kernel figure out from device mapper the requested block ?
> What are the entries in mapping layer for this ?
>
>
>
> On Wed, Sep 10, 2008 at 7:05 AM, Peter Teoh <htmldeveloper@xxxxxxxxx> wrote:
>> Further information here:
>>
>> http://www.kernel-labs.org/?q=blockdriver
>> http://www.kernel-labs.org/?q=blockiolayer
>>
>> and kernel source drivers/block subdirectory, looking for all the
>> register_blkdev() caller, all these can be your potential block
>> devices examples.   whether they used BIO or not it depends.
>>
>> For example:
>>
>> ./brd.c:
>>        if (register_blkdev(RAMDISK_MAJOR, "ramdisk"))
>>        unregister_blkdev(RAMDISK_MAJOR, "ramdisk");
>>
>>
>> And inside brd.c look at how the API blk_queue_make_request() is used
>> for customization of special request structure, so bio is manipulated
>> in this brd.c.
>>
>> But others like DAC960.c, virtio_blk.c etc does not touch the bio
>> internals, but deals at the request and request_queue level instead.
>>  It leave the internals at the block/*.c implementation.   For
>> example, for virtio_blk.c, it uses blk_rq_map_sg():
>>
>> /*
>>  * map a request to scatterlist, return number of sg entries setup. Caller
>>  * must make sure sg can hold rq->nr_phys_segments entries
>>  */
>> int blk_rq_map_sg(struct request_queue *q, struct request *rq,
>>                  struct scatterlist *sglist)
>> {
>>        struct bio_vec *bvec, *bvprv;
>>        struct req_iterator iter;
>>        struct scatterlist *sg;
>>
>> for BIO mapping.
>>
>> but then my generalization may be wrong?
>>
>> On Wed, Sep 10, 2008 at 7:37 AM, Peter Teoh <htmldeveloper@xxxxxxxxx> wrote:
>>> On Wed, Sep 10, 2008 at 12:51 AM, Rohit Sharma <imreckless@xxxxxxxxx> wrote:
>>>> I was going through block drivers,
>>>> i am not able to associate request queues and bio structures.
>>>> How are the requests processed using bio structures.
>>>> Can anyone provide me with block driver example or tutorial.
>>>>
>>>
>>> looking at block/scsi_ioctl.c:sg_io() function - does line 207 and 241
>>> answer your question?
>>>
>>> 207         rq = blk_get_request(q, writing ? WRITE : READ, GFP_KERNEL);
>>> 208         if (!rq)
>>> 209                 return -ENOMEM;
>>> 210
>>> 211         if (blk_fill_sghdr_rq(q, rq, hdr, file)) {
>>> 212                 blk_put_request(rq);
>>> 213                 return -EFAULT;
>>> 214         }
>>> 215
>>> 216         if (hdr->iovec_count) {
>>> 217                 const int size = sizeof(struct sg_iovec) * hdr->iovec_count;
>>> 218                 struct sg_iovec *iov;
>>> 219
>>> 220                 iov = kmalloc(size, GFP_KERNEL);
>>> 221                 if (!iov) {
>>> 222                         ret = -ENOMEM;
>>> 223                         goto out;
>>> 224                 }
>>> 225
>>> 226                 if (copy_from_user(iov, hdr->dxferp, size)) {
>>> 227                         kfree(iov);
>>> 228                         ret = -EFAULT;
>>> 229                         goto out;
>>> 230                 }
>>> 231
>>> 232                 ret = blk_rq_map_user_iov(q, rq, iov, hdr->iovec_count,
>>> 233                                           hdr->dxfer_len);
>>> 234                 kfree(iov);
>>> 235         } else if (hdr->dxfer_len)
>>> 236                 ret = blk_rq_map_user(q, rq, hdr->dxferp, hdr->dxfer_len);
>>> 237
>>> 238         if (ret)
>>> 239                 goto out;
>>> 240
>>> 241         bio = rq->bio;
>>> 242         memset(sense, 0, sizeof(sense));
>>> 243         rq->sense = sense;
>>> 244         rq->sense_len = 0;
>>> 245         rq->retries = 0;
>>> 246
>>> 247         start_time = jiffies;
>>> 248
>>> 249         /* ignore return value. All information is passed back to caller
>>> 250          * (if he doesn't check that is his problem).
>>> 251          * N.B. a non-zero SCSI status is _not_ necessarily an error.
>>> 252          */
>>> 253         blk_execute_rq(q, bd_disk, rq, 0);
>>> 254
>>> 255         hdr->duration = jiffies_to_msecs(jiffies - start_time);
>>> 256
>>> 257         return blk_complete_sghdr_rq(rq, hdr, bio);
>>>
>>>
>>>
>>> --
>>> Regards,
>>> Peter Teoh
>>>
>>
>>
>>
>> --
>> Regards,
>> Peter Teoh
>>
>
> --
> To unsubscribe from this list: send an email with
> "unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
> Please read the FAQ at http://kernelnewbies.org/FAQ
>
>



-- 
Regards,
Peter Teoh

--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
Please read the FAQ at http://kernelnewbies.org/FAQ


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux