diff options
author | Sakshi <sabansal@redhat.com> | 2015-07-16 14:31:03 +0530 |
---|---|---|
committer | Raghavendra G <rgowdapp@redhat.com> | 2015-08-27 06:25:34 -0700 |
commit | 9e51aa646fdc5840b6fa9b12b35c5cc2af274c3c (patch) | |
tree | a7ff968e51340b9e590805bc721fd8ae43c4b3ad /xlators/cluster/dht/src/dht-common.h | |
parent | cf3d6f14ae031ba2f5269cea6dbf80e60d00cce5 (diff) |
dht : lock on subvols to prevent lookup vs rmdir race
There is a possibility that while an rmdir is completed on
some non-hashed subvol and proceeding to others. A lookup
selfheal can recreate the same directory on those subvols
for which the rmdir had succeeded. The fix is to take a
blocking inodelk on the subvols before starting rmdir.
Since selfheal requires lock on all subvols, if an rmdir
is in progess acquiring locks will fail and vice versa.
Change-Id: I841a44758c3b88f5e04d1cb73ad36e0cac9fdabb
BUG: 1245065
Signed-off-by: Sakshi <sabansal@redhat.com>
Reviewed-on: http://review.gluster.org/11725
Tested-by: NetBSD Build System <jenkins@build.gluster.org>
Reviewed-by: Raghavendra G <rgowdapp@redhat.com>
Diffstat (limited to 'xlators/cluster/dht/src/dht-common.h')
-rw-r--r-- | xlators/cluster/dht/src/dht-common.h | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/xlators/cluster/dht/src/dht-common.h b/xlators/cluster/dht/src/dht-common.h index 6bf8ba1c406..53eb34a9e90 100644 --- a/xlators/cluster/dht/src/dht-common.h +++ b/xlators/cluster/dht/src/dht-common.h @@ -40,7 +40,7 @@ typedef int (*dht_defrag_cbk_fn_t) (xlator_t *this, xlator_t *dst_node, call_frame_t *frame); typedef int (*dht_refresh_layout_unlock) (call_frame_t *frame, xlator_t *this, - int op_ret); + int op_ret, int invoke_cbk); typedef int (*dht_refresh_layout_done_handle) (call_frame_t *frame); @@ -131,6 +131,11 @@ typedef enum { qdstatfs_action_COMPARE, } qdstatfs_action_t; +typedef enum { + FAIL_ON_ANY_ERROR, + IGNORE_ENOENT_ESTALE +} dht_reaction_type_t; + struct dht_skip_linkto_unlink { gf_boolean_t handle_valid_link; @@ -261,6 +266,7 @@ struct dht_local { fop_inodelk_cbk_t inodelk_cbk; dht_lock_t **locks; int lk_count; + dht_reaction_type_t reaction; /* whether locking failed on _any_ of the "locks" above */ int op_ret; @@ -1042,7 +1048,8 @@ dht_fill_dict_to_avoid_unlink_of_migrating_file (dict_t *dict); int dht_nonblocking_inodelk (call_frame_t *frame, dht_lock_t **lk_array, - int lk_count, fop_inodelk_cbk_t inodelk_cbk); + int lk_count, dht_reaction_type_t reaction, + fop_inodelk_cbk_t inodelk_cbk); /* same as dht_nonblocking_inodelk, but issues sequential blocking locks on * @lk_array directly. locks are issued on some order which remains same @@ -1050,7 +1057,8 @@ dht_nonblocking_inodelk (call_frame_t *frame, dht_lock_t **lk_array, */ int dht_blocking_inodelk (call_frame_t *frame, dht_lock_t **lk_array, - int lk_count, fop_inodelk_cbk_t inodelk_cbk); + int lk_count, dht_reaction_type_t reaction, + fop_inodelk_cbk_t inodelk_cbk); int32_t dht_unlock_inodelk (call_frame_t *frame, dht_lock_t **lk_array, int lk_count, |