lkml.org 
[lkml]   [2000]   [Oct]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
From
Subjectll_rw_block() changes buffer_heads to NULL?
Date
> 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? I'm trying to read 1 sector (which succeeds
> just fine), then 32 sectors, one at a time, which fails.
> 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.
>
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
>
> 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/

\
 
 \ /
  Last update: 2005-03-22 12:39    [W:0.050 / U:0.984 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site