How to use buffer_head directly for block driver??

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

 



I have been writing a block driver. If I use request queue in my block driver, it's working fine. But, I'm having problems when I try to use buffer_head directly on my own implemented "make_request_fn". I have trying to fix the problem for a long long time, still not successful.
 
I'm using kernel 2.4.27.  I provided part of my source code below. Can anyone please give me some hint about if I handled buffer_head correctly? Thanks!


/*
 * Finally, the module stuff
 */
int npswap_init(void) {


   /*
     * Get the queue set up, and register our (nonexistent) partitions.
     */
       blk_init_queue(BLK_DEFAULT_QUEUE(major), npswap_request);
    // direct operate on buffer_head without using queue
    if (noqueue)
    {
        blk_queue_make_request(BLK_DEFAULT_QUEUE(major),
                               npswap_make_request);
    }
}




/*
 * Transfer a buffer directly, without going through the request queue.
 */
int npswap_make_request(request_queue_t *queue, int rw, struct buffer_head *bh) {
    u8 *ptr;
    // Figure out what we are doing
    Sbull_Dev *device = npswap_devices + MINOR(bh->b_rdev);
    ptr = device->data + bh->b_rsector * npswap_hardsect;

    // Paranoid check, this apparently can really happen
    if (ptr + bh->b_size > device->data + npswap_blksize*npswap_size) {
        static int count = 0;
        if (count++ < 5)
            printk(KERN_WARNING "npswap: request past end of device\n");
        bh->b_end_io(bh, 0);
        return 0;
    }

    spin_lock(&io_request_lock);


    // This could be a high memory buffer, shift it down
#if CONFIG_HIGHMEM
    bh = create_bounce(rw, bh);
    //bh = blk_queue_bounce(queue, rw, bh);
    PDEBUG("Defined: CONFIG_HIGHMEM\n");
#endif

    //PDEBUG("bh->b_rsector: %ld, bh->b_size: %hd, nr_sectors: %d\n",
    //        bh->b_rsector, bh->b_size, (bh->b_size/npswap_hardsect));



    // Do the transfer
    switch(rw) {
      case READ:
      case READA:  // Readahead
        memcpy(bh->b_data, ptr, bh->b_size); // from npswap to buffer
        bh->b_end_io(bh, 1);
        break;
      case WRITE:
        refile_buffer(bh);
        memcpy(ptr, bh->b_data, bh->b_size); // from buffer to npswap
        mark_buffer_uptodate(bh, 1);
        bh->b_end_io(bh, 1);
        break;
      default:
        // can't happen
        bh->b_end_io(bh, 0);
        break;
    }

    spin_unlock(&io_request_lock);

    // Nonzero return means we're done

    return 0;
}


[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