aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/super.c
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2009-07-20 06:12:36 -0400
committerJoel Becker <joel.becker@oracle.com>2009-07-21 18:47:55 -0400
commitf7b1aa69be138ad9d7d3f31fa56f4c9407f56b6a (patch)
tree3d3ca30071d9d92ff3ad5c6d522ea6c05efb3885 /fs/ocfs2/super.c
parent3c5e10683e684ef45614c9071847e48f633d9806 (diff)
ocfs2: Fix deadlock on umount
In commit ea455f8ab68338ba69f5d3362b342c115bea8e13, we moved the dentry lock put process into ocfs2_wq. This causes problems during umount because ocfs2_wq can drop references to inodes while they are being invalidated by invalidate_inodes() causing all sorts of nasty things (invalidate_inodes() ending in an infinite loop, "Busy inodes after umount" messages etc.). We fix the problem by stopping ocfs2_wq from doing any further releasing of inode references on the superblock being unmounted, wait until it finishes the current round of releasing and finally cleaning up all the references in dentry_lock_list from ocfs2_put_super(). The issue was tracked down by Tao Ma <tao.ma@oracle.com>. Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Joel Becker <joel.becker@oracle.com>
Diffstat (limited to 'fs/ocfs2/super.c')
-rw-r--r--fs/ocfs2/super.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 63af2e36d834..f2893878f8ad 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -1213,14 +1213,27 @@ static int ocfs2_get_sb(struct file_system_type *fs_type,
1213 mnt); 1213 mnt);
1214} 1214}
1215 1215
1216static void ocfs2_kill_sb(struct super_block *sb)
1217{
1218 struct ocfs2_super *osb = OCFS2_SB(sb);
1219
1220 /* Prevent further queueing of inode drop events */
1221 spin_lock(&dentry_list_lock);
1222 ocfs2_set_osb_flag(osb, OCFS2_OSB_DROP_DENTRY_LOCK_IMMED);
1223 spin_unlock(&dentry_list_lock);
1224 /* Wait for work to finish and/or remove it */
1225 cancel_work_sync(&osb->dentry_lock_work);
1226
1227 kill_block_super(sb);
1228}
1229
1216static struct file_system_type ocfs2_fs_type = { 1230static struct file_system_type ocfs2_fs_type = {
1217 .owner = THIS_MODULE, 1231 .owner = THIS_MODULE,
1218 .name = "ocfs2", 1232 .name = "ocfs2",
1219 .get_sb = ocfs2_get_sb, /* is this called when we mount 1233 .get_sb = ocfs2_get_sb, /* is this called when we mount
1220 * the fs? */ 1234 * the fs? */
1221 .kill_sb = kill_block_super, /* set to the generic one 1235 .kill_sb = ocfs2_kill_sb,
1222 * right now, but do we 1236
1223 * need to change that? */
1224 .fs_flags = FS_REQUIRES_DEV|FS_RENAME_DOES_D_MOVE, 1237 .fs_flags = FS_REQUIRES_DEV|FS_RENAME_DOES_D_MOVE,
1225 .next = NULL 1238 .next = NULL
1226}; 1239};
@@ -1819,6 +1832,12 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err)
1819 1832
1820 debugfs_remove(osb->osb_ctxt); 1833 debugfs_remove(osb->osb_ctxt);
1821 1834
1835 /*
1836 * Flush inode dropping work queue so that deletes are
1837 * performed while the filesystem is still working
1838 */
1839 ocfs2_drop_all_dl_inodes(osb);
1840
1822 /* Orphan scan should be stopped as early as possible */ 1841 /* Orphan scan should be stopped as early as possible */
1823 ocfs2_orphan_scan_stop(osb); 1842 ocfs2_orphan_scan_stop(osb);
1824 1843