AnsweredAssumed Answered

IMX6D 多次拔插U盘系统重启

Question asked by robin chen on Aug 9, 2017
Latest reply on Aug 27, 2017 by jimmychan
hi,all 
      目前在进行项目开发时遇到多次拔插U盘引起系统重启。目前使用的硬件平台是: i.mx6dl, i.mx6d 软件版本是:Android 版本6.0.1 内核版本:Linux version 4.1.15。拔插U盘过程调用以及相关源码路径:
源码路径                   函数
../kernel/fs/super.c       kill_block_super
                                 
../kernel/fs/super.c       generic_shutdown_super

../kernel/fs/dcache.c      shrink_dcache_for_umount

../kernel/fs/dcache.c      do_one_tree

../kernel/fs/dcache.c      shrink_dcache_parent 

../kernel/fs/dcache.c      shrink_dentry_list

../kernel/fs/dcache.c      __dentry_kill       

../kernel/fs/dcache.c      dentry_iput

../kernel/fs/inode.c       iput

../kernel/fs/inode.c       iput_final

../kernel/fs/inode.c       evict
 
../kernel/fs/fat/inode.c   fat_evict_inode

../kernel/fs/fat/file.c    fat_truncate_blocks

../kernel/fs/fat/file.c    fat_free

../kernel/fs/fat/file.c    fat_sync_inode

../kernel/fs/fat/inode.c   __fat_write_inode

../kernel/fs/buffer.c         mark_buffer_dirty

../kernel/fs/buffer.c          __set_page_dirty

../kernel/mm/page-writeback.c     account_page_dirtied

../kernel/lib/percpu_counter.c      __percpu_counter_add

其中有个关键地方在函数 fat_evict_inode
static void fat_evict_inode(struct inode *inode)
{
truncate_inode_pages_final(&inode->i_data);
if (!inode->i_nlink) {
inode->i_size = 0;
fat_truncate_blocks(inode, 0);
}
invalidate_inode_buffers(inode);
clear_inode(inode);
fat_cache_inval_inode(inode);
fat_detach(inode);
}

系统不重启的情况是在 !inode->i_nlink 为false 不调用 fat_truncate_blocks(inode, 0);

跟踪内核代码发现 __set_page_dirty 这个函数一直被调用。fat_evict_inode 在拔U盘时已经调用很多次,也就是__dentry_kill 早被其他函数调用indode已经被删除。最后当再进行上面过程调用时当条件
!inode->i_nlink由于某种原因为真时再去写inode时导致重启。这也是简单分析,因为 在删除目录dput()这个过程中有好些地方去调用,一时也最终找不到原因所在。请问大家又没遇到同样问题,麻烦大家支招。谢谢!

Outcomes