diff options
author | N Balachandran <nbalacha@redhat.com> | 2018-04-17 15:37:05 +0530 |
---|---|---|
committer | Raghavendra G <rgowdapp@redhat.com> | 2018-04-23 01:43:12 +0000 |
commit | 62437c99618551d531103023883b5cabcca20fa6 (patch) | |
tree | 71c7cef654f99cd1898d558869e9aac6a185e013 /xlators/cluster/dht/src/dht-rename.c | |
parent | bca55ab1bfcd2889f8387ba8bcab27766e1b94ac (diff) |
cluster/dht: Fix dht_rename lock order
Fixed dht_order_rename_lock to use the same inodelk ordering
as that of the dht selfheal locks (dictionary order of
lock subvolumes).
Change-Id: Ia3f8353b33ea2fd3bc1ba7e8e777dda6c1d33e0d
fixes: bz#1568348
Signed-off-by: N Balachandran <nbalacha@redhat.com>
Diffstat (limited to 'xlators/cluster/dht/src/dht-rename.c')
-rw-r--r-- | xlators/cluster/dht/src/dht-rename.c | 65 |
1 files changed, 47 insertions, 18 deletions
diff --git a/xlators/cluster/dht/src/dht-rename.c b/xlators/cluster/dht/src/dht-rename.c index e61d67ca6d8..3dc042e3ce5 100644 --- a/xlators/cluster/dht/src/dht-rename.c +++ b/xlators/cluster/dht/src/dht-rename.c @@ -490,37 +490,66 @@ err: return 0; } + +/* + * If the hashed subvolumes of both source and dst are the different, + * lock in dictionary order of hashed subvol->name. This is important + * in case the parent directory is the same for both src and dst to + * prevent inodelk deadlocks when racing with a fix-layout op on the parent. + * + * If the hashed subvols are the same, use the gfid/name to determine + * the order of taking locks to prevent entrylk deadlocks when the parent + * dirs are the same. + * + */ static void dht_order_rename_lock (call_frame_t *frame, loc_t **loc, xlator_t **subvol) { - dht_local_t *local = NULL; - char src[GF_UUID_BNAME_BUF_SIZE] = {0}; - char dst[GF_UUID_BNAME_BUF_SIZE] = {0}; + int ret = 0; + dht_local_t *local = NULL; + char src[GF_UUID_BNAME_BUF_SIZE] = {0}; + char dst[GF_UUID_BNAME_BUF_SIZE] = {0}; + local = frame->local; - if (local->loc.pargfid) - uuid_utoa_r (local->loc.pargfid, src); - else if (local->loc.parent) - uuid_utoa_r (local->loc.parent->gfid, src); + if (local->src_hashed->name == local->dst_hashed->name) { + ret = 0; + } else { + ret = strcmp (local->src_hashed->name, local->dst_hashed->name); + } - strcat (src, local->loc.name); + if (ret == 0) { - if (local->loc2.pargfid) - uuid_utoa_r (local->loc2.pargfid, dst); - else if (local->loc2.parent) - uuid_utoa_r (local->loc2.parent->gfid, dst); + /* hashed subvols are the same for src and dst */ + /* Entrylks need to be ordered*/ + if (local->loc.pargfid) + uuid_utoa_r (local->loc.pargfid, src); + else if (local->loc.parent) + uuid_utoa_r (local->loc.parent->gfid, src); - strcat (dst, local->loc2.name); + strcat (src, local->loc.name); - if (strcmp(src, dst) > 0) { - local->current = &local->lock[1]; - *loc = &local->loc2; - *subvol = local->dst_hashed; - } else { + if (local->loc2.pargfid) + uuid_utoa_r (local->loc2.pargfid, dst); + else if (local->loc2.parent) + uuid_utoa_r (local->loc2.parent->gfid, dst); + + strcat (dst, local->loc2.name); + ret = strcmp (src, dst); + } + + if (ret <= 0) { + /*inodelk in dictionary order of hashed subvol names*/ + /*entrylk in dictionary order of gfid/basename */ local->current = &local->lock[0]; *loc = &local->loc; *subvol = local->src_hashed; + + } else { + local->current = &local->lock[1]; + *loc = &local->loc2; + *subvol = local->dst_hashed; } return; |