From: "John R. Dunning" <[EMAIL PROTECTED]>
    Date: Wed, 25 Jul 2007 08:06:29 -0400
    
    I've got another odd crash, hoping somebody will have a hint:

Dug a little deeper, and am more confused:

In lustre/ldiskfs/inode.c:

struct buffer_head *ldiskfs_getblk(handle_t *handle, struct inode * inode,
                                long block, int create, int * errp)

around line 875:

        dummy.b_blocknr = -1000;

around line 880:

        if (!*errp && buffer_mapped(&dummy)) {
                struct buffer_head *bh;
                bh = sb_getblk(inode->i_sb, dummy.b_blocknr);

and around line 902

                        BUFFER_TRACE(bh, "call ldiskfs_journal_dirty_metadata");
                        err = ldiskfs_journal_dirty_metadata(handle, bh);
                        if (!fatal)
                                fatal = err;

It's in the call to ldiskfs_journal_dirty_metadata that I seem to be blowing
the ASSERT.

Chasing down the call to sb_getblk, in kernel/fs/buffer.c, around line 1451, I
see

/*
 * __getblk will locate (and, if necessary, create) the buffer_head
 * which corresponds to the passed block_device, block and size. The
 * returned buffer has its reference count incremented.
 *
 * __getblk() cannot fail - it just keeps trying.  If you pass it an
 * illegal block number, __getblk() will happily return a buffer_head
 * which represents the non-existent block.  Very weird.
 *
 * __getblk() will lock up the machine if grow_dev_page's try_to_free_buffers()
 * attempt is failing.  FIXME, perhaps?
 */
struct buffer_head *
__getblk(struct block_device *bdev, sector_t block, int size)
{
        struct buffer_head *bh = __find_get_block(bdev, block, size);

        might_sleep();
        if (bh == NULL)
                bh = __getblk_slow(bdev, block, size);
        return bh;
}


>From the ldiskfs code, it looks to me like we're intentionally calling
__getblk with a bogus block number.  But the comment in __getblk pretty
clearly states that calling it that way will result in a buffer_head pointing
to that illegal block.  Since we then turn around and pass that resultant
buffer_head (returned from sb_getblk) into ldiskfs_journal_dirty_metadata,
that looks to me like a plausible way to end up with a busted bh, and hence
the assertion failure.

Anybody else find this suspect?  Am I missing something?  TIA...

_______________________________________________
Lustre-discuss mailing list
[email protected]
https://mail.clusterfs.com/mailman/listinfo/lustre-discuss

Reply via email to