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()这个过程中有好些地方去调用,一时也最终找不到原因所在。请问大家又没遇到同样问题,麻烦大家支招。谢谢!