summaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/ocfs2.h
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2014-04-03 14:46:56 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2014-04-03 16:20:54 -0700
commite3a767b60fd8a9f5e133f42f4970cff77ec43173 (patch)
treea8399e9f83f246bcaf7be821da534754d0c37692 /fs/ocfs2/ocfs2.h
parent9f985cb6c45bc3f8b7e161c9658d409d051d576f (diff)
downloadlinux-e3a767b60fd8a9f5e133f42f4970cff77ec43173.tar.bz2
ocfs2: implement delayed dropping of last dquot reference
We cannot drop last dquot reference from downconvert thread as that creates the following deadlock: NODE 1 NODE2 holds dentry lock for 'foo' holds inode lock for GLOBAL_BITMAP_SYSTEM_INODE dquot_initialize(bar) ocfs2_dquot_acquire() ocfs2_inode_lock(USER_QUOTA_SYSTEM_INODE) ... downconvert thread (triggered from another node or a different process from NODE2) ocfs2_dentry_post_unlock() ... iput(foo) ocfs2_evict_inode(foo) ocfs2_clear_inode(foo) dquot_drop(inode) ... ocfs2_dquot_release() ocfs2_inode_lock(USER_QUOTA_SYSTEM_INODE) - blocks finds we need more space in quota file ... ocfs2_extend_no_holes() ocfs2_inode_lock(GLOBAL_BITMAP_SYSTEM_INODE) - deadlocks waiting for downconvert thread We solve the problem by postponing dropping of the last dquot reference to a workqueue if it happens from the downconvert thread. Signed-off-by: Jan Kara <jack@suse.cz> Reviewed-by: Mark Fasheh <mfasheh@suse.de> Reviewed-by: Srinivas Eeda <srinivas.eeda@oracle.com> Cc: Joel Becker <jlbec@evilplan.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/ocfs2/ocfs2.h')
-rw-r--r--fs/ocfs2/ocfs2.h5
1 files changed, 5 insertions, 0 deletions
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h
index 553f53cc73ae..64c02239ba46 100644
--- a/fs/ocfs2/ocfs2.h
+++ b/fs/ocfs2/ocfs2.h
@@ -30,6 +30,7 @@
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/list.h>
+#include <linux/llist.h>
#include <linux/rbtree.h>
#include <linux/workqueue.h>
#include <linux/kref.h>
@@ -419,6 +420,10 @@ struct ocfs2_super
struct ocfs2_dentry_lock *dentry_lock_list;
struct work_struct dentry_lock_work;
+ /* List of dquot structures to drop last reference to */
+ struct llist_head dquot_drop_list;
+ struct work_struct dquot_drop_work;
+
wait_queue_head_t osb_mount_event;
/* Truncate log info */