Block driver without using request_queue?

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

 



I'm using the block driver provided by <<Linux Device Driver, 2ed>>, on Chapter 12. And I'm using kernel 2.4.27.

I'm trying to use let the driver deal with each buffer_head directly, rather than using a request_queue. Everytime I load the driver into the kernel and staring to transfer some sectors, I always get the same Oops message(provided below). It looks like something wrong with the way the function make_request works (also provided below). Can anyone point out what's wrong with the function and how should I fix it. Thanks!!!

Fei



Mar 10 16:58:47 milhouse kernel: Unable to handle kernel NULL pointer dereference at virtual address 00000000
Mar 10 16:58:47 milhouse kernel:  printing eip:
Mar 10 16:58:47 milhouse kernel: c01ad340
Mar 10 16:58:47 milhouse kernel: *pde = 00000000
Mar 10 16:58:47 milhouse kernel: Oops: 0000
Mar 10 16:58:47 milhouse kernel: CPU:    0
Mar 10 16:58:47 milhouse kernel: EIP:    0010:[__blk_cleanup_queue+32/112]    Not tainted
Mar 10 16:58:47 milhouse kernel: EFLAGS: 00210213
Mar 10 16:58:47 milhouse kernel: eax: 00000000   ebx: c02eceb4   ecx: 00000000  edx: 000000fe
Mar 10 16:58:47 milhouse kernel: esi: 00000000   edi: c02ecea8   ebp: c27d3f8c  esp: c27d3f48
Mar 10 16:58:47 milhouse kernel: ds: 0018   es: 0018   ss: 0018
Mar 10 16:58:47 milhouse kernel: Process rmmod (pid: 1868, stackpage=c27d3000)
Mar 10 16:58:47 milhouse kernel: Stack: c013f62b 0000fe00 00000000 fffffff0 c02ecea8 c01ad3aa c02ecea8 0000fe00
Mar 10 16:58:47 milhouse kernel:        00000001 00000000 d4a50f7b c02ecea8 d4a51157 c025ec38 c025ec38 c1030020
Mar 10 16:58:47 milhouse kernel:        d4a4f000 bfffeb68 c011e10a d4a4f000 d4a4f000 fffffff0 c63b3000 c011d47f
Mar 10 16:58:47 milhouse kernel: Call Trace:    [sync_buffers+107/112] [blk_cleanup_queue+26/112] [bttv:__insmod_bttv_S.data_L19772+523131/48618029] [bttv:__insmod_bttv_S.data_L19772+523607/48617553] [free_module+170/192]
Mar 10 16:58:47 milhouse kernel:   [sys_delete_module+159/464] [system_call+51/56]
Mar 10 16:58:47 milhouse kernel:
Mar 10 16:58:47 milhouse kernel: Code: 8b 01 46 8b 51 04 89 50 04 89 02 c7 41 04 00 00 00 00 c7 01




/*
 * 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;
    }


    // This could be a high memory buffer, shift it down
#if CONFIG_HIGHMEM
    bh = create_bounce(rw, bh);
#endif


    // 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;
    }

    // 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