Whamcloud - gitweb
LU-118 Workaround for race causing assertion failure in clear_inode()
authorJohann Lombardi <johann@whamcloud.com>
Thu, 28 Apr 2011 18:44:59 +0000 (20:44 +0200)
committerJohann Lombardi <johann@whamcloud.com>
Fri, 6 May 2011 06:20:26 +0000 (23:20 -0700)
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 <johann@whamcloud.com>
Reviewed-on: http://review.whamcloud.com/475
Tested-by: Hudson
Reviewed-by: Jinshan Xiong <jay@whamcloud.com>
Reviewed-by: Andrew Perepechko <andrew_perepechko@xyratex.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/llite/llite_internal.h
lustre/llite/llite_lib.c
lustre/llite/super25.c

index c63b3dd..a3458b7 100644 (file)
@@ -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
index 14bbf2a..95fc4c0 100644 (file)
@@ -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);
index 8275464..3bc4065 100644 (file)
@@ -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,
 };