From 4e2e497479a37ea659163ec8a84b8876b61ee1f3 Mon Sep 17 00:00:00 2001 From: Vikas Gorur Date: Fri, 16 Oct 2009 03:10:08 +0000 Subject: cluster/afr: Hold lock on all names under "victim" in rmdir When an rmdir is being done, hold a lock on all names under it, so that new entries cannot be created while the rmdir is in progress. Without this lock, rmdir and create operations under the victim directory race with each other leading to inconsistencies among the subvolumes. Signed-off-by: Anand V. Avati BUG: 112 (parallel deletion of files mounted by different clients on the same back-end hangs and/or does not completely delete) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=112 --- xlators/cluster/afr/src/afr-dir-write.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'xlators') diff --git a/xlators/cluster/afr/src/afr-dir-write.c b/xlators/cluster/afr/src/afr-dir-write.c index 66f9f1d1f..7b33d336f 100644 --- a/xlators/cluster/afr/src/afr-dir-write.c +++ b/xlators/cluster/afr/src/afr-dir-write.c @@ -1821,10 +1821,31 @@ afr_rmdir (call_frame_t *frame, xlator_t *this, afr_build_parent_loc (&local->transaction.parent_loc, loc); + /* + * We need to hold a lock on all names under the + * "victim" (directory being removed) to prevent + * attempts at creating entries. Without this lock + * rmdir on some subvolumes can fail because of + * entries that have been created under it. + * This leads to inconsistencies among subvolumes. + * + * Since the ENTRY_RENAME transaction already + * has the mechanism to hold locks on two loc_t's, + * we just use the same mechanism here. + * + * See http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=112 + * for details. + */ + + loc_copy (&local->transaction.new_parent_loc, loc); + local->transaction.new_basename = NULL; + local->transaction.main_frame = frame; - local->transaction.basename = AFR_BASENAME (loc->path); - afr_transaction (transaction_frame, this, AFR_ENTRY_TRANSACTION); + local->transaction.basename = AFR_BASENAME (loc->path); + + + afr_transaction (transaction_frame, this, AFR_ENTRY_RENAME_TRANSACTION); op_ret = 0; out: -- cgit