> > Hi!
> >
> > For swsusp, I kind of need to read 4K from given block device.
> >
> > Here's my attempt:
> >
> > static int bdev_read_page(kdev_t dev, long pos, void *buf)
> > {
> > struct buffer_head *bh;
> > struct block_device *bdev;
> >
> > if (pos%PAGE_SIZE) panic("Sorry, dave, I can't let you do
> > that!\n");
>
> It's possible I guess that someone has a pinned buffer against
> the same page which has a different block size. See the "lock up"
> comment over __getblk().
>
> > bdev = bdget(kdev_t_to_nr(dev));
> > if (!bdev) {
> > printk("No block device for %s\n", __bdevname(dev));
> > BUG();
> > }
> > printk("C");
> > bh = __bread(bdev, pos/PAGE_SIZE, PAGE_SIZE);
> > printk("D");
> > bdput(bdev);
> > if (!bh || (!bh->b_data)) {
> > return -1;
> > }
> > memcpy(buf, bh->b_data, PAGE_SIZE);
>
> You'll need to kmap bh->b_page before copying the data.
>
> >
> > It works *once*, second time it deadlocks in __bread(). I tried both
> > bforget() and brelse(). Kernel is 2.5.13. What am I doing wrong/what's
> > wrong?
>
> brelse is safer.
>
> Please try 2.5.14. 2.5.13 had a few leaky problems which
> could perhaps result in a pinned buffer which will cause
> try_to_free_buffers() to fail, which triggers the __getblk()
> nastiness.
Went with brelse(), and switched to 2.5.14; still deadlocks on second
read.
Pavel
-- Casualities in World Trade Center: ~3k dead inside the building, cryptography in U.S.A. and free speech in Czech Republic. - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/