[Unionfs] sporadic oops during diskless boot

Hans-Peter Jansen hpj at urpla.net
Sun Mar 26 16:07:33 EST 2006


Am Sonntag, 12. März 2006 23:31 schrieb Hans-Peter Jansen:
> Hi,
>
> during diskless boot on module load, I harvest _sporadic_ oopses
> like this one with unionfs snapshot 20060221-0341:
>
> Unable to handle kernel NULL pointer dereference at virtual address
> 00000008 printing eip:
> f9033c9b
> *pde = 00000000
> Oops: 0000 [#1]
> Modules linked in: via_agp agpgart via_ircc irda crc_ccitt via82cxxx
> ide_core ehci_hcd snd_via82xx gameport snd_ac97_codec snd_pcm
> snd_timer snd_page_alloc snd_mpu401_uart snd_rawmidi snd_seq_device
> snd soundcore ohci1394 ieee1394 uhci_hcd usbcore unionfs af_packet
> 3c59x via_rhine 8139
> too mii e1000
> CPU:    0
> EIP:    0060:[<f9033c9b>]    Tainted: G     U VLI
> EFLAGS: 00010202   (2.6.11.4-21.12.lisa.1-default)
> EIP is at unionfs_link+0x27b/0x880 [unionfs]
> eax: f7200a60   ebx: f7c64294   ecx: 00000000   edx: 00000000
> esi: f72096c8   edi: 00000000   ebp: f728adbc   esp: f74b3ec4
> ds: 007b   es: 007b   ss: 0068
> Process blkid (pid: 4136, threadinfo=f74b2000 task=f7860560)
> Stack: 00000000 f9035430 00000003 00000000 f7c79c48 f7c26b40 00000002
> 0000004d f7258f40 f728af30 f728adbc 00000000 f728aecc f7c79c74
> f71e7a04 f9044840 f9033a20 f7c79c74 f71e7a04 c015f860 f728aecc
> f728aecc f7f1e000 f74b3f70 Call Trace:
>  [<f9035430>] unionfs_permission+0x1b0/0x2c0 [unionfs]
>  [<f9033a20>] unionfs_link+0x0/0x880 [unionfs]
>  [<c015f860>] vfs_link+0xe0/0x1b0
>  [<c015f9f1>] sys_link+0xc1/0xf0
>  [<c0116537>] recalc_task_prio+0x127/0x280
>  [<c015f4e6>] sys_unlink+0xe6/0x130
>  [<c0102ca7>] syscall_call+0x7/0xb
> Code: ff 85 c9 0f 88 b4 05 00 00 8b 54 24 38 8b 42 44 8b 80 60 01 00
> 00 8b 50 18 89 c8 c1 e0 04 f6 44 02 0c 02 74 15 8b 46 24 8b 14 88
> <8b> 72 08 8b 96 94 00 00 00 f6 42 34 01 74 05 bf e2 ff ff ff 85

No feedback :-(. In the meantime, I backported snapshot 20060312-2337 to
the slightly modified SuSE 2.6.11.4 kernel in order to be able to play 
with the mmap option, but this problem persists.

Since it happens often enough to annoy me (and my users), here's what I 
investigated so far. When it happend, it's always triggered by the 
process blkid.

If I read the oops correctly, EIP is where the oops happens, and EIP is 
at offset 0x27b in function unionfs_link. 

After compiling inode.c with the same parameter + -g, objdumping the object 
file with source intermixed, it points to offset 0xa0b (unionfs_link starts
at 0x790 + 0x27b:

/usr/src/packages/BUILD/unionfs-20060312-2337/unionfs.h:645
     9fe:       f6 44 02 0c 02          testb  $0x2,0xc(%edx,%eax,1)
     a03:       74 15                   je     a1a <unionfs_link+0x28a>
/usr/src/packages/BUILD/unionfs-20060312-2337/unionfs_macros.h:127
}

/* Dentry macros */
static inline struct unionfs_dentry_info *dtopd(const struct dentry *dent)
{
     a05:       8b 46 24                mov    0x24(%esi),%eax
     a08:       8b 14 88                mov    (%eax,%ecx,4),%edx
/usr/src/packages/BUILD/unionfs-20060312-2337/unionfs_macros.h:147
        return (struct unionfs_dentry_info *)dent->d_fsdata;
}

#define dtopd_lhs(dent) ((dent)->d_fsdata)
#define dtopd_nocheck(dent) dtopd(dent)
#define dbstart(dent) (dtopd(dent)->udi_bstart)
#define set_dbstart(dent, val) do { dtopd(dent)->udi_bstart = val; } while(0)
#define dbend(dent) (dtopd(dent)->udi_bend)
#define set_dbend(dent, val) do { dtopd(dent)->udi_bend = val; } while(0)
#define dbopaque(dent) (dtopd(dent)->udi_bopaque)
#define set_dbopaque(dent, val) do { dtopd(dent)->udi_bopaque = val; } while (0)

static inline void set_dtohd_index(struct dentry *dent, int index,
                                   struct dentry *val)
{
        dtopd(dent)->udi_dentry[index] = val;
}

static inline struct dentry *dtohd_index(const struct dentry *dent, int index)
{
     a0b:       8b 72 08                mov    0x8(%edx),%esi
     a0e:       8b 96 94 00 00 00       mov    0x94(%esi),%edx
     a14:       f6 42 34 01             testb  $0x1,0x34(%edx)
     a18:       74 05                   je     a1f <unionfs_link+0x28f>
/usr/src/packages/BUILD/unionfs-20060312-2337/unionfs.h:647
        perms = stopd(dentry->d_sb)->usi_data[index].branchperms;

        if ((!(perms & MAY_WRITE))
            || (IS_RDONLY(dtohd_index(dentry, index)->d_inode)))
                err = -EROFS;
     a1a:       bf e2 ff ff ff          mov    $0xffffffe2,%edi
/usr/src/packages/BUILD/unionfs-20060312-2337/unionfs.h:655

        print_util_exit_status(err);

        return err;
}

The last inode.c line mentioned in disassembly above this is 282.
I cannot locate the right source line, where this oops happens in this 
maze of macros.

Are my claims about the location right?
Any ideas anybody on hoe to fix this one this time?

Pete




More information about the unionfs mailing list