Messages in this thread |  | | From | Matt_Domsch@Dell ... | Subject | | Date | Thu, 5 Oct 2000 17:34:56 -0500 |
| |
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/
|  |