|author||Vikas Gorur <email@example.com>||2009-10-16 03:10:08 +0000|
|committer||Anand V. Avati <firstname.lastname@example.org>||2009-10-16 03:12:59 -0700|
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 <email@example.com> 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
Diffstat (limited to 'xlators/cluster/afr/src/afr-dir-write.c')
1 files changed, 23 insertions, 2 deletions
diff --git a/xlators/cluster/afr/src/afr-dir-write.c b/xlators/cluster/afr/src/afr-dir-write.c
index 66f9f1d1f..7b33d336f 100644
@@ -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;