summaryrefslogtreecommitdiffstats
path: root/api/src/glfs-resolve.c
diff options
context:
space:
mode:
authorAnand Avati <avati@redhat.com>2013-03-04 13:22:25 -0800
committerAnand Avati <avati@redhat.com>2013-03-07 19:53:41 -0800
commitb5ab33ccbf55e5fc64bf41357a3833a1b21e7071 (patch)
tree00510b542e3986dfe62e393f47b996842d0f1c03 /api/src/glfs-resolve.c
parentc37546cf11555678be6fefdbfec0007272aeb336 (diff)
gfapi: dict_unref() xattr_req in fop finish instead of dict_destroy()
The current way of calling dict_destroy() at the end of an API fop assumes that xattr_req is not stored/ref'd by any translators in the stack. However when translators like DHT store xattr_req in dht_local_t with a dict_ref() and perform dict_unref() in the unwind path, things get subject to a race. The race is between the woken up thread (by syncop_wake) i.e, the gfapi invoking thread and the thread where the FOP was unwound. As the C stack of STACK_UNWIND unwinds back, dht_local_unref() gets invoked within the DHT_STACK_UNWIND macro. This thread attempts dict_unref, which would be "safe" if it wins the race against the gfapi invoking thread. However if the gfapi invoking thread wins the race, it will perform dict_destroy() first and therefore make dict_unref() within dht_local_unref perform a double free. This is the embarrassing on-screen bug which showed up in a roomful of people during the gluster dev summit demo of qemu/libgfapi integration. Change-Id: I284c93de87cdc128d5801f42c84aa87f753090d4 BUG: 839950 Signed-off-by: Anand Avati <avati@redhat.com> Reviewed-on: http://review.gluster.org/4645 Tested-by: Gluster Build System <jenkins@build.gluster.com>
Diffstat (limited to 'api/src/glfs-resolve.c')
-rw-r--r--api/src/glfs-resolve.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/api/src/glfs-resolve.c b/api/src/glfs-resolve.c
index f7754d201..a9b938186 100644
--- a/api/src/glfs-resolve.c
+++ b/api/src/glfs-resolve.c
@@ -201,7 +201,7 @@ glfs_resolve_component (struct glfs *fs, xlator_t *subvol, inode_t *parent,
*iatt = ciatt;
out:
if (xattr_req)
- dict_destroy (xattr_req);
+ dict_unref (xattr_req);
loc_wipe (&loc);