(no subject)

From: Matt_Domsch@Dell.com
Date: Thu Oct 05 2000 - 17:34:56 EST


I'm still trying to read physical sectors, and have made progress. Thanks
for the pointers on set_blocksize(), that seems to do the trick.

However, now I've got another problem. When I read blocks "too quickly", I
guess the elevator algorithm in ll_rw_block() kicks in and re-organizes my
buffer_head structures?
ReadLBA(2) - OK
ReadLBA(3) - OK
ReadLBA(4) - fails, kernel dereferences NULL,

All calls to getblk() succeed, and none of my buffer heads are NULL. I pass
this array to ll_rw_block(), which rewrites my array, leaving most of my
buffer_head pointers as NULL. So, I thought, that for each buffer head that
isn't NULL, maybe my next buffer head is in b_reqnext, but nope. It's NULL
too.

oops and my function are below. FWIW, this is the second version of my
function. Originally, I just looped, calling bread(dev, lba++, blocksize),
which oops in the same way. Both IA-32 and IA-64, kernel 2.4.0-test9.

TIA for your help.
-Matt

Unable to handle kernel NULL pointer dereference at virtual address 00000000
00000000
*pde = 37b11001
Oops: 0000
CPU: 0
EIP: 0010:[<00000000>]
Using defaults from ksymoops -t elf32-i386 -a i386
EFLAGS: 00010202
eax: 00000000 ebx: c211dba0 ecx: 00000000 edx: c029bfa8
esi: 00000000 edi: 00000001 ebp: 0000001f esp: c029bf60
ds: 0018 es: 0018 ss: 0018
Process swapper (pid: 0, stackpage=c029b000)
Stack: c010d4c0 0000001f 00000000 c029bfa8 c029bfa8 c02d8be0 0000001f
c211dba0
       c010d6c1 0000001f c029bfa8 c211dba0 00000000 c029a000 c0109bf0
c029a000
       ffffe000 c010bbf8 c029a000 c029a000 00000000 c0109bf0 c029a000
ffffe000
Call Trace: [<c010d4c0>] [<c010d6c1>] [<c0109bf0>] [<c010bbf8>] [<c0109bf0>]
[<c0100018>] [<c0109c1e>]
       [<c0109ca2>] [<c0105000>] [<c01001d0>]
Code: Bad EIP value.

>>EIP; 00000000 Before first symbol
Trace; c010d4c0 <handle_IRQ_event+60/90>
Trace; c010d6c1 <do_IRQ+a1/100>
Trace; c0109bf0 <default_idle+0/40>
Trace; c010bbf8 <ret_from_intr+0/20>
Trace; c0109bf0 <default_idle+0/40>
Trace; c0100018 <startup_32+18/cc>
Trace; c0109c1e <default_idle+2e/40>
Trace; c0109ca2 <cpu_idle+52/70>
Trace; c0105000 <empty_bad_page+0/1000>
Trace; c01001d0 <L6+0/2>

Aiee, killing interrupt handler
Kernel panic: Attempted to kill the idle task!

struct buffer_head ** my_bread(kdev_t dev, u64 lba, u64 blockstoread)
{
  struct buffer_head **bh, *thisbh;
        
  unsigned int blocksize = get_hardblocksize(dev);
  unsigned int i;
  if (!blocksize) blocksize = 512;
  printk(KERN_INFO "about to getblk %d blocks\n", blockstoread);
  
  bh = kmalloc(GFP_KERNEL, blockstoread * sizeof(struct buffer_head *));
  if (!bh) return NULL;

  for (i=0; i<blockstoread; i++) {
    bh[i] = getblk(dev, lba+i, blocksize);
    if (!bh[i]) {
      printk(KERN_WARNING, "getblk(lba=%x) failed.\n", lba);
    }
  }

 /* at this point, none of the bh[i]s are NULL. */

    ll_rw_block(READ, blockstoread, bh);

  /* now, all but the first 3 bh[i]s are NULL, and all bh[i]->b_reqnext ==
NULL */

  /* Walk the chain */
  for (i=0; i<blockstoread; i++) {
    if (!bh[i]) continue;

    thisbh = bh[i];
    do {
      wait_on_buffer(thisbh);
      if (!buffer_uptodate(thisbh)) {
        printk(KERN_WARNING "bh is not uptodate after waiting!\n");
      }
      thisbh = thisbh->b_reqnext;
      if (thisbh) printk(KERN_INFO "my_bread walking the chain...\n");
    } while (thisbh);
  }

  return bh;
}

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Sat Oct 07 2000 - 21:00:18 EST