From fb8dd8d780140a3f0e9074831a59054fec6cc451 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Wed, 31 Mar 2010 16:25:37 +0200 Subject: ocfs2: Fix quota locking OCFS2 had three issues with quota locking: a) When reading dquot from global quota file, we started a transaction while holding dqio_mutex which is prone to deadlocks because other paths do it the other way around b) During ocfs2_sync_dquot we were not protected against concurrent writers on the same node. Because we first copy data to local buffer, a race could happen resulting in old data being written to global quota file and thus causing quota inconsistency after a crash. c) ip_alloc_sem of quota files was acquired while a transaction is started in ocfs2_quota_write which can deadlock because we first get ip_alloc_sem and then start a transaction when extending quota files. We fix the problem a) by pulling all necessary code to ocfs2_acquire_dquot and ocfs2_release_dquot. Thus we no longer depend on generic dquot_acquire to do the locking and can force proper lock ordering. Problems b) and c) are fixed by locking i_mutex and ip_alloc_sem of global quota file in ocfs2_lock_global_qf and removing ip_alloc_sem from ocfs2_quota_read and ocfs2_quota_write. Acked-by: Joel Becker Signed-off-by: Jan Kara --- fs/ocfs2/quota.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'fs/ocfs2/quota.h') diff --git a/fs/ocfs2/quota.h b/fs/ocfs2/quota.h index c7623430ca3c..903ffa933d53 100644 --- a/fs/ocfs2/quota.h +++ b/fs/ocfs2/quota.h @@ -104,10 +104,11 @@ static inline int ocfs2_global_release_dquot(struct dquot *dquot) int ocfs2_lock_global_qf(struct ocfs2_mem_dqinfo *oinfo, int ex); void ocfs2_unlock_global_qf(struct ocfs2_mem_dqinfo *oinfo, int ex); -int ocfs2_read_quota_block(struct inode *inode, u64 v_block, - struct buffer_head **bh); +int ocfs2_validate_quota_block(struct super_block *sb, struct buffer_head *bh); int ocfs2_read_quota_phys_block(struct inode *inode, u64 p_block, struct buffer_head **bh); +int ocfs2_create_local_dquot(struct dquot *dquot); +int ocfs2_local_release_dquot(handle_t *handle, struct dquot *dquot); extern const struct dquot_operations ocfs2_quota_operations; extern struct quota_format_type ocfs2_quota_format; -- cgit v1.2.3