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>
This commit is contained in:
@@ -28,6 +28,7 @@ struct ocfs2_dquot {
|
||||
unsigned int dq_use_count; /* Number of nodes having reference to this entry in global quota file */
|
||||
s64 dq_origspace; /* Last globally synced space usage */
|
||||
s64 dq_originodes; /* Last globally synced inode usage */
|
||||
struct llist_node list; /* Member of list of dquots to drop */
|
||||
};
|
||||
|
||||
/* Description of one chunk to recover in memory */
|
||||
@@ -110,6 +111,7 @@ int ocfs2_read_quota_phys_block(struct inode *inode, u64 p_block,
|
||||
int ocfs2_create_local_dquot(struct dquot *dquot);
|
||||
int ocfs2_local_release_dquot(handle_t *handle, struct dquot *dquot);
|
||||
int ocfs2_local_write_dquot(struct dquot *dquot);
|
||||
void ocfs2_drop_dquot_refs(struct work_struct *work);
|
||||
|
||||
extern const struct dquot_operations ocfs2_quota_operations;
|
||||
extern struct quota_format_type ocfs2_quota_format;
|
||||
|
Reference in New Issue
Block a user