From: Johann Lombardi Date: Thu, 28 Apr 2011 18:44:59 +0000 (+0200) Subject: LU-118 Workaround for race causing assertion failure in clear_inode() X-Git-Tag: 1.8.5.56~22 X-Git-Url: https://git.whamcloud.com/gitweb?a=commitdiff_plain;h=27a980a8ed357962a57ace062d697615645d6d36;p=fs%2Flustre-release.git LU-118 Workaround for race causing assertion failure in clear_inode() This patch is just a *workaround* to avoid a race found in recent kernel causing the following assertion in clear_inode(): BUG_ON(inode->i_data.nrpages). The race can still occur when truncate_inode_pages() & clear_inode() are called directly by the VFS, but the problem should be harder to reproduce. A more complete fix is considered for 2.x. Change-Id: If0df4b1cba00de7cf43f1b3510d54d35525c5e14 Signed-off-by: Johann Lombardi Reviewed-on: http://review.whamcloud.com/475 Tested-by: Hudson Reviewed-by: Jinshan Xiong Reviewed-by: Andrew Perepechko Reviewed-by: Oleg Drokin --- diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index c63b3dd..a3458b7 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -827,6 +827,7 @@ void ll_kill_super(struct super_block *sb); int ll_cache_shrink(SHRINKER_FIRST_ARG int nr_to_scan, gfp_t gfp_mask); struct inode *ll_inode_from_lock(struct ldlm_lock *lock); void ll_clear_inode(struct inode *inode); +void ll_delete_inode(struct inode *inode); int ll_setattr_raw(struct inode *inode, struct iattr *attr); int ll_setattr(struct dentry *de, struct iattr *attr); #ifndef HAVE_STATFS_DENTRY_PARAM diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 14bbf2a..95fc4c0 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -1345,6 +1345,31 @@ void ll_clear_inode(struct inode *inode) EXIT; } + +void ll_delete_inode(struct inode *inode) +{ + CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p)\n", inode->i_ino, + inode->i_generation, inode); + + truncate_inode_pages(&inode->i_data, 0); + if (inode->i_data.nrpages) { + /* Workaround for LU-118 */ +#ifdef HAVE_RW_TREE_LOCK + write_lock_irq(&inode->i_data.tree_lock); + write_unlock_irq(&inode->i_data.tree_lock); +#else + spin_lock_irq(&inode->i_data.tree_lock); + spin_unlock_irq(&inode->i_data.tree_lock); +#endif + LASSERTF(inode->i_data.nrpages == 0, + "inode=%lu/%u(%p) nrpages=%lu, see " + "http://jira.whamcloud.com/browse/LU-118\n", + inode->i_ino, inode->i_generation, inode, + inode->i_data.nrpages); + } + clear_inode(inode); +} + static int ll_setattr_do_truncate(struct inode *inode, loff_t new_size) { struct ll_sb_info *sbi = ll_i2sbi(inode); diff --git a/lustre/llite/super25.c b/lustre/llite/super25.c index 8275464..3bc4065 100644 --- a/lustre/llite/super25.c +++ b/lustre/llite/super25.c @@ -99,6 +99,7 @@ struct super_operations lustre_super_operations = .umount_begin = ll_umount_begin, .remount_fs = ll_remount_fs, .show_options = ll_show_options, + .delete_inode = ll_delete_inode, };