On Mon 06-02-17 13:26:53, Thiago Jung Bauermann wrote: > Am Montag, 6. Februar 2017, 12:48:42 BRST schrieb Thiago Jung Bauermann: > > 216 static inline void wb_get(struct bdi_writeback *wb) > > 217 { > > 218 if (wb != &wb->bdi->wb) > > 219 percpu_ref_get(&wb->refcnt); > > 220 } > > > > So it looks like wb->bdi is NULL. > > Sorry, looking a little deeper, it's actually wb which is NULL: > > ./include/linux/backing-dev.h: > 371 return inode->i_wb; > 0xc00000000037999c <+76>: ld r31,256(r29) > > ./include/linux/backing-dev-defs.h: > 218 if (wb != &wb->bdi->wb) > 0xc0000000003799a0 <+80>: ld r9,0(r31) > 0xc0000000003799a4 <+84>: addi r9,r9,88 > 0xc0000000003799a8 <+88>: cmpld cr7,r31,r9 > 0xc0000000003799ac <+92>: beq cr7,0xc0000000003799e0 > <locked_inode_to_wb_and_lock_list+144> > > We can see above that inode->i_wb is in r31, and the machine crashed at > 0xc0000000003799a0 so it was trying to dereference wb and crashed. > r31 is NULL in the crash information. Thanks for report and the analysis. After some looking into the code I see where the problem is. Writeback code assumes inode->i_wb can never become invalid once it is set however we still call inode_detach_wb() from __blkdev_put(). So in a way this is a different problem but closely related. It seems to me that instead of calling inode_detach_wb() in __blkdev_put() we may just switch blkdev inode to bdi->wb (it is now guaranteed to stay around). That way bdi_unregister() can complete (destroying all writeback structures except for bdi->wb) while block device inode can still live with a valid i_wb structure. CCed Tejun who is more familar with this code to verify my thoughts. Honza -- Jan Kara <jack@xxxxxxxx> SUSE Labs, CR