e3c68b
From 2f5969a77493814e242e6bac3c6bf7acf3202e0f Mon Sep 17 00:00:00 2001
e3c68b
From: Xavi Hernandez <xhernandez@redhat.com>
e3c68b
Date: Tue, 5 Mar 2019 18:58:20 +0100
e3c68b
Subject: [PATCH 209/221] core: avoid dynamic TLS allocation when possible
e3c68b
e3c68b
Some interdependencies between logging and memory management functions
e3c68b
make it impossible to use the logging framework before initializing
e3c68b
memory subsystem because they both depend on Thread Local Storage
e3c68b
allocated through pthread_key_create() during initialization.
e3c68b
e3c68b
This causes a crash when we try to log something very early in the
e3c68b
initialization phase.
e3c68b
e3c68b
To prevent this, several dynamically allocated TLS structures have
e3c68b
been replaced by static TLS reserved at compile time using '__thread'
e3c68b
keyword. This also reduces the number of error sources, making
e3c68b
initialization simpler.
e3c68b
e3c68b
Upstream patch:
e3c68b
> BUG: 1193929
e3c68b
> Upstream patch link: https://review.gluster.org/c/glusterfs/+/22302
e3c68b
> Change-Id: I8ea2e072411e30790d50084b6b7e909c7bb01d50
e3c68b
> Signed-off-by: Xavi Hernandez <xhernandez@redhat.com>
e3c68b
e3c68b
Change-Id: I8ea2e072411e30790d50084b6b7e909c7bb01d50
e3c68b
Updates: bz#1722801
e3c68b
Signed-off-by: Xavi Hernandez <xhernandez@redhat.com>
e3c68b
Reviewed-on: https://code.engineering.redhat.com/gerrit/174711
e3c68b
Tested-by: RHGS Build Bot <nigelb@redhat.com>
e3c68b
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
e3c68b
---
e3c68b
 api/src/glfs.c                                     |   3 +-
e3c68b
 cli/src/cli.c                                      |   3 +-
e3c68b
 glusterfsd/src/glusterfsd.c                        |   4 +-
e3c68b
 libglusterfs/src/globals.c                         | 289 ++++-----------------
e3c68b
 libglusterfs/src/glusterfs/globals.h               |   6 +-
e3c68b
 libglusterfs/src/glusterfs/mem-pool.h              |   7 +-
e3c68b
 libglusterfs/src/libglusterfs.sym                  |   3 +-
e3c68b
 libglusterfs/src/mem-pool.c                        |  98 +++----
e3c68b
 libglusterfs/src/syncop.c                          | 133 ++--------
e3c68b
 .../changelog/lib/src/gf-changelog-helpers.c       |  51 +---
e3c68b
 xlators/features/changelog/lib/src/gf-changelog.c  |   3 +-
e3c68b
 xlators/nfs/server/src/mount3udp_svc.c             |   6 +-
e3c68b
 12 files changed, 114 insertions(+), 492 deletions(-)
e3c68b
e3c68b
diff --git a/api/src/glfs.c b/api/src/glfs.c
e3c68b
index 6bbb620..f36616d 100644
e3c68b
--- a/api/src/glfs.c
e3c68b
+++ b/api/src/glfs.c
e3c68b
@@ -829,8 +829,7 @@ pub_glfs_new(const char *volname)
e3c68b
      * Do this as soon as possible in case something else depends on
e3c68b
      * pool allocations.
e3c68b
      */
e3c68b
-    mem_pools_init_early();
e3c68b
-    mem_pools_init_late();
e3c68b
+    mem_pools_init();
e3c68b
 
e3c68b
     fs = glfs_new_fs(volname);
e3c68b
     if (!fs)
e3c68b
diff --git a/cli/src/cli.c b/cli/src/cli.c
e3c68b
index ff39a98..99a16a0 100644
e3c68b
--- a/cli/src/cli.c
e3c68b
+++ b/cli/src/cli.c
e3c68b
@@ -795,8 +795,7 @@ main(int argc, char *argv[])
e3c68b
     int ret = -1;
e3c68b
     glusterfs_ctx_t *ctx = NULL;
e3c68b
 
e3c68b
-    mem_pools_init_early();
e3c68b
-    mem_pools_init_late();
e3c68b
+    mem_pools_init();
e3c68b
 
e3c68b
     ctx = glusterfs_ctx_new();
e3c68b
     if (!ctx)
e3c68b
diff --git a/glusterfsd/src/glusterfsd.c b/glusterfsd/src/glusterfsd.c
e3c68b
index 6aee4c1..2172af4 100644
e3c68b
--- a/glusterfsd/src/glusterfsd.c
e3c68b
+++ b/glusterfsd/src/glusterfsd.c
e3c68b
@@ -2722,8 +2722,6 @@ main(int argc, char *argv[])
e3c68b
     };
e3c68b
     cmd_args_t *cmd = NULL;
e3c68b
 
e3c68b
-    mem_pools_init_early();
e3c68b
-
e3c68b
     gf_check_and_set_mem_acct(argc, argv);
e3c68b
 
e3c68b
     ctx = glusterfs_ctx_new();
e3c68b
@@ -2838,7 +2836,7 @@ main(int argc, char *argv[])
e3c68b
      * the parent, but we want to do it as soon as possible after that in
e3c68b
      * case something else depends on pool allocations.
e3c68b
      */
e3c68b
-    mem_pools_init_late();
e3c68b
+    mem_pools_init();
e3c68b
 
e3c68b
 #ifdef GF_LINUX_HOST_OS
e3c68b
     ret = set_oom_score_adj(ctx);
e3c68b
diff --git a/libglusterfs/src/globals.c b/libglusterfs/src/globals.c
e3c68b
index 4fec063..02098e6 100644
e3c68b
--- a/libglusterfs/src/globals.c
e3c68b
+++ b/libglusterfs/src/globals.c
e3c68b
@@ -99,16 +99,19 @@ const char *gf_upcall_list[GF_UPCALL_FLAGS_MAXVALUE] = {
e3c68b
 glusterfs_ctx_t *global_ctx = NULL;
e3c68b
 pthread_mutex_t global_ctx_mutex = PTHREAD_MUTEX_INITIALIZER;
e3c68b
 xlator_t global_xlator;
e3c68b
-static pthread_key_t this_xlator_key;
e3c68b
-static pthread_key_t synctask_key;
e3c68b
-static pthread_key_t uuid_buf_key;
e3c68b
-static char global_uuid_buf[GF_UUID_BUF_SIZE];
e3c68b
-static pthread_key_t lkowner_buf_key;
e3c68b
-static char global_lkowner_buf[GF_LKOWNER_BUF_SIZE];
e3c68b
-static pthread_key_t leaseid_buf_key;
e3c68b
 static int gf_global_mem_acct_enable = 1;
e3c68b
 static pthread_once_t globals_inited = PTHREAD_ONCE_INIT;
e3c68b
 
e3c68b
+static pthread_key_t free_key;
e3c68b
+
e3c68b
+static __thread xlator_t *thread_xlator = NULL;
e3c68b
+static __thread void *thread_synctask = NULL;
e3c68b
+static __thread void *thread_leaseid = NULL;
e3c68b
+static __thread struct syncopctx thread_syncopctx = {};
e3c68b
+static __thread char thread_uuid_buf[GF_UUID_BUF_SIZE] = {};
e3c68b
+static __thread char thread_lkowner_buf[GF_LKOWNER_BUF_SIZE] = {};
e3c68b
+static __thread char thread_leaseid_buf[GF_LEASE_ID_BUF_SIZE] = {};
e3c68b
+
e3c68b
 int
e3c68b
 gf_global_mem_acct_enable_get(void)
e3c68b
 {
e3c68b
@@ -122,12 +125,6 @@ gf_global_mem_acct_enable_set(int val)
e3c68b
     return 0;
e3c68b
 }
e3c68b
 
e3c68b
-void
e3c68b
-glusterfs_this_destroy(void *ptr)
e3c68b
-{
e3c68b
-    FREE(ptr);
e3c68b
-}
e3c68b
-
e3c68b
 static struct xlator_cbks global_cbks = {
e3c68b
     .forget = NULL,
e3c68b
     .release = NULL,
e3c68b
@@ -212,18 +209,9 @@ struct volume_options global_xl_options[] = {
e3c68b
 
e3c68b
 static volume_opt_list_t global_xl_opt_list;
e3c68b
 
e3c68b
-int
e3c68b
+void
e3c68b
 glusterfs_this_init()
e3c68b
 {
e3c68b
-    int ret = 0;
e3c68b
-    ret = pthread_key_create(&this_xlator_key, glusterfs_this_destroy);
e3c68b
-    if (ret != 0) {
e3c68b
-        gf_msg("", GF_LOG_WARNING, ret, LG_MSG_PTHREAD_KEY_CREATE_FAILED,
e3c68b
-               "failed to create "
e3c68b
-               "the pthread key");
e3c68b
-        return ret;
e3c68b
-    }
e3c68b
-
e3c68b
     global_xlator.name = "glusterfs";
e3c68b
     global_xlator.type = GF_GLOBAL_XLATOR_NAME;
e3c68b
     global_xlator.cbks = &global_cbks;
e3c68b
@@ -237,301 +225,120 @@ glusterfs_this_init()
e3c68b
     global_xl_opt_list.given_opt = global_xl_options;
e3c68b
 
e3c68b
     list_add_tail(&global_xl_opt_list.list, &global_xlator.volume_options);
e3c68b
-
e3c68b
-    return ret;
e3c68b
 }
e3c68b
 
e3c68b
 xlator_t **
e3c68b
 __glusterfs_this_location()
e3c68b
 {
e3c68b
-    xlator_t **this_location = NULL;
e3c68b
-    int ret = 0;
e3c68b
-
e3c68b
-    this_location = pthread_getspecific(this_xlator_key);
e3c68b
-
e3c68b
-    if (!this_location) {
e3c68b
-        this_location = CALLOC(1, sizeof(*this_location));
e3c68b
-        if (!this_location)
e3c68b
-            goto out;
e3c68b
+    xlator_t **this_location;
e3c68b
 
e3c68b
-        ret = pthread_setspecific(this_xlator_key, this_location);
e3c68b
-        if (ret != 0) {
e3c68b
-            FREE(this_location);
e3c68b
-            this_location = NULL;
e3c68b
-            goto out;
e3c68b
-        }
e3c68b
-    }
e3c68b
-out:
e3c68b
-    if (this_location) {
e3c68b
-        if (!*this_location)
e3c68b
-            *this_location = &global_xlator;
e3c68b
+    this_location = &thread_xlator;
e3c68b
+    if (*this_location == NULL) {
e3c68b
+        thread_xlator = &global_xlator;
e3c68b
     }
e3c68b
+
e3c68b
     return this_location;
e3c68b
 }
e3c68b
 
e3c68b
 xlator_t *
e3c68b
 glusterfs_this_get()
e3c68b
 {
e3c68b
-    xlator_t **this_location = NULL;
e3c68b
-
e3c68b
-    this_location = __glusterfs_this_location();
e3c68b
-    if (!this_location)
e3c68b
-        return &global_xlator;
e3c68b
-
e3c68b
-    return *this_location;
e3c68b
+    return *__glusterfs_this_location();
e3c68b
 }
e3c68b
 
e3c68b
-int
e3c68b
+void
e3c68b
 glusterfs_this_set(xlator_t *this)
e3c68b
 {
e3c68b
-    xlator_t **this_location = NULL;
e3c68b
-
e3c68b
-    this_location = __glusterfs_this_location();
e3c68b
-    if (!this_location)
e3c68b
-        return -ENOMEM;
e3c68b
-
e3c68b
-    *this_location = this;
e3c68b
-
e3c68b
-    return 0;
e3c68b
+    thread_xlator = this;
e3c68b
 }
e3c68b
 
e3c68b
 /* SYNCOPCTX */
e3c68b
-static pthread_key_t syncopctx_key;
e3c68b
-
e3c68b
-static void
e3c68b
-syncopctx_key_destroy(void *ptr)
e3c68b
-{
e3c68b
-    struct syncopctx *opctx = ptr;
e3c68b
-
e3c68b
-    if (opctx) {
e3c68b
-        if (opctx->groups)
e3c68b
-            GF_FREE(opctx->groups);
e3c68b
-
e3c68b
-        GF_FREE(opctx);
e3c68b
-    }
e3c68b
-
e3c68b
-    return;
e3c68b
-}
e3c68b
 
e3c68b
 void *
e3c68b
 syncopctx_getctx()
e3c68b
 {
e3c68b
-    void *opctx = NULL;
e3c68b
-
e3c68b
-    opctx = pthread_getspecific(syncopctx_key);
e3c68b
-
e3c68b
-    return opctx;
e3c68b
-}
e3c68b
-
e3c68b
-int
e3c68b
-syncopctx_setctx(void *ctx)
e3c68b
-{
e3c68b
-    int ret = 0;
e3c68b
-
e3c68b
-    ret = pthread_setspecific(syncopctx_key, ctx);
e3c68b
-
e3c68b
-    return ret;
e3c68b
-}
e3c68b
-
e3c68b
-static int
e3c68b
-syncopctx_init(void)
e3c68b
-{
e3c68b
-    int ret;
e3c68b
-
e3c68b
-    ret = pthread_key_create(&syncopctx_key, syncopctx_key_destroy);
e3c68b
-
e3c68b
-    return ret;
e3c68b
+    return &thread_syncopctx;
e3c68b
 }
e3c68b
 
e3c68b
 /* SYNCTASK */
e3c68b
 
e3c68b
-int
e3c68b
-synctask_init()
e3c68b
-{
e3c68b
-    int ret = 0;
e3c68b
-
e3c68b
-    ret = pthread_key_create(&synctask_key, NULL);
e3c68b
-
e3c68b
-    return ret;
e3c68b
-}
e3c68b
-
e3c68b
 void *
e3c68b
 synctask_get()
e3c68b
 {
e3c68b
-    void *synctask = NULL;
e3c68b
-
e3c68b
-    synctask = pthread_getspecific(synctask_key);
e3c68b
-
e3c68b
-    return synctask;
e3c68b
+    return thread_synctask;
e3c68b
 }
e3c68b
 
e3c68b
-int
e3c68b
+void
e3c68b
 synctask_set(void *synctask)
e3c68b
 {
e3c68b
-    int ret = 0;
e3c68b
-
e3c68b
-    pthread_setspecific(synctask_key, synctask);
e3c68b
-
e3c68b
-    return ret;
e3c68b
+    thread_synctask = synctask;
e3c68b
 }
e3c68b
 
e3c68b
 // UUID_BUFFER
e3c68b
 
e3c68b
-void
e3c68b
-glusterfs_uuid_buf_destroy(void *ptr)
e3c68b
-{
e3c68b
-    FREE(ptr);
e3c68b
-}
e3c68b
-
e3c68b
-int
e3c68b
-glusterfs_uuid_buf_init()
e3c68b
-{
e3c68b
-    int ret = 0;
e3c68b
-
e3c68b
-    ret = pthread_key_create(&uuid_buf_key, glusterfs_uuid_buf_destroy);
e3c68b
-    return ret;
e3c68b
-}
e3c68b
-
e3c68b
 char *
e3c68b
 glusterfs_uuid_buf_get()
e3c68b
 {
e3c68b
-    char *buf;
e3c68b
-    int ret = 0;
e3c68b
-
e3c68b
-    buf = pthread_getspecific(uuid_buf_key);
e3c68b
-    if (!buf) {
e3c68b
-        buf = MALLOC(GF_UUID_BUF_SIZE);
e3c68b
-        ret = pthread_setspecific(uuid_buf_key, (void *)buf);
e3c68b
-        if (ret)
e3c68b
-            buf = global_uuid_buf;
e3c68b
-    }
e3c68b
-    return buf;
e3c68b
+    return thread_uuid_buf;
e3c68b
 }
e3c68b
 
e3c68b
 /* LKOWNER_BUFFER */
e3c68b
 
e3c68b
-void
e3c68b
-glusterfs_lkowner_buf_destroy(void *ptr)
e3c68b
-{
e3c68b
-    FREE(ptr);
e3c68b
-}
e3c68b
-
e3c68b
-int
e3c68b
-glusterfs_lkowner_buf_init()
e3c68b
-{
e3c68b
-    int ret = 0;
e3c68b
-
e3c68b
-    ret = pthread_key_create(&lkowner_buf_key, glusterfs_lkowner_buf_destroy);
e3c68b
-    return ret;
e3c68b
-}
e3c68b
-
e3c68b
 char *
e3c68b
 glusterfs_lkowner_buf_get()
e3c68b
 {
e3c68b
-    char *buf;
e3c68b
-    int ret = 0;
e3c68b
-
e3c68b
-    buf = pthread_getspecific(lkowner_buf_key);
e3c68b
-    if (!buf) {
e3c68b
-        buf = MALLOC(GF_LKOWNER_BUF_SIZE);
e3c68b
-        ret = pthread_setspecific(lkowner_buf_key, (void *)buf);
e3c68b
-        if (ret)
e3c68b
-            buf = global_lkowner_buf;
e3c68b
-    }
e3c68b
-    return buf;
e3c68b
+    return thread_lkowner_buf;
e3c68b
 }
e3c68b
 
e3c68b
 /* Leaseid buffer */
e3c68b
-void
e3c68b
-glusterfs_leaseid_buf_destroy(void *ptr)
e3c68b
-{
e3c68b
-    FREE(ptr);
e3c68b
-}
e3c68b
-
e3c68b
-int
e3c68b
-glusterfs_leaseid_buf_init()
e3c68b
-{
e3c68b
-    int ret = 0;
e3c68b
-
e3c68b
-    ret = pthread_key_create(&leaseid_buf_key, glusterfs_leaseid_buf_destroy);
e3c68b
-    return ret;
e3c68b
-}
e3c68b
 
e3c68b
 char *
e3c68b
 glusterfs_leaseid_buf_get()
e3c68b
 {
e3c68b
     char *buf = NULL;
e3c68b
-    int ret = 0;
e3c68b
 
e3c68b
-    buf = pthread_getspecific(leaseid_buf_key);
e3c68b
-    if (!buf) {
e3c68b
-        buf = CALLOC(1, GF_LEASE_ID_BUF_SIZE);
e3c68b
-        ret = pthread_setspecific(leaseid_buf_key, (void *)buf);
e3c68b
-        if (ret) {
e3c68b
-            FREE(buf);
e3c68b
-            buf = NULL;
e3c68b
-        }
e3c68b
+    buf = thread_leaseid;
e3c68b
+    if (buf == NULL) {
e3c68b
+        buf = thread_leaseid_buf;
e3c68b
+        thread_leaseid = buf;
e3c68b
     }
e3c68b
+
e3c68b
     return buf;
e3c68b
 }
e3c68b
 
e3c68b
 char *
e3c68b
 glusterfs_leaseid_exist()
e3c68b
 {
e3c68b
-    return pthread_getspecific(leaseid_buf_key);
e3c68b
+    return thread_leaseid;
e3c68b
 }
e3c68b
 
e3c68b
 static void
e3c68b
-gf_globals_init_once()
e3c68b
+glusterfs_cleanup(void *ptr)
e3c68b
 {
e3c68b
-    int ret = 0;
e3c68b
-
e3c68b
-    ret = glusterfs_this_init();
e3c68b
-    if (ret) {
e3c68b
-        gf_msg("", GF_LOG_CRITICAL, 0, LG_MSG_TRANSLATOR_INIT_FAILED,
e3c68b
-               "ERROR: glusterfs-translator init failed");
e3c68b
-        goto out;
e3c68b
-    }
e3c68b
-
e3c68b
-    ret = glusterfs_uuid_buf_init();
e3c68b
-    if (ret) {
e3c68b
-        gf_msg("", GF_LOG_CRITICAL, 0, LG_MSG_UUID_BUF_INIT_FAILED,
e3c68b
-               "ERROR: glusterfs uuid buffer init failed");
e3c68b
-        goto out;
e3c68b
+    if (thread_syncopctx.groups != NULL) {
e3c68b
+        GF_FREE(thread_syncopctx.groups);
e3c68b
     }
e3c68b
 
e3c68b
-    ret = glusterfs_lkowner_buf_init();
e3c68b
-    if (ret) {
e3c68b
-        gf_msg("", GF_LOG_CRITICAL, 0, LG_MSG_LKOWNER_BUF_INIT_FAILED,
e3c68b
-               "ERROR: glusterfs lkowner buffer init failed");
e3c68b
-        goto out;
e3c68b
-    }
e3c68b
+    mem_pool_thread_destructor();
e3c68b
+}
e3c68b
 
e3c68b
-    ret = glusterfs_leaseid_buf_init();
e3c68b
-    if (ret) {
e3c68b
-        gf_msg("", GF_LOG_CRITICAL, 0, LG_MSG_LEASEID_BUF_INIT_FAILED,
e3c68b
-               "ERROR: glusterfs leaseid buffer init failed");
e3c68b
-        goto out;
e3c68b
-    }
e3c68b
+static void
e3c68b
+gf_globals_init_once()
e3c68b
+{
e3c68b
+    int ret = 0;
e3c68b
 
e3c68b
-    ret = synctask_init();
e3c68b
-    if (ret) {
e3c68b
-        gf_msg("", GF_LOG_CRITICAL, 0, LG_MSG_SYNCTASK_INIT_FAILED,
e3c68b
-               "ERROR: glusterfs synctask init failed");
e3c68b
-        goto out;
e3c68b
-    }
e3c68b
+    glusterfs_this_init();
e3c68b
 
e3c68b
-    ret = syncopctx_init();
e3c68b
-    if (ret) {
e3c68b
-        gf_msg("", GF_LOG_CRITICAL, 0, LG_MSG_SYNCOPCTX_INIT_FAILED,
e3c68b
-               "ERROR: glusterfs syncopctx init failed");
e3c68b
-        goto out;
e3c68b
-    }
e3c68b
-out:
e3c68b
+    /* This is needed only to cleanup the potential allocation of
e3c68b
+     * thread_syncopctx.groups. */
e3c68b
+    ret = pthread_key_create(&free_key, glusterfs_cleanup);
e3c68b
+    if (ret != 0) {
e3c68b
+        gf_msg("", GF_LOG_ERROR, ret, LG_MSG_PTHREAD_KEY_CREATE_FAILED,
e3c68b
+               "failed to create the pthread key");
e3c68b
 
e3c68b
-    if (ret) {
e3c68b
         gf_msg("", GF_LOG_CRITICAL, 0, LG_MSG_GLOBAL_INIT_FAILED,
e3c68b
                "Exiting as global initialization failed");
e3c68b
+
e3c68b
         exit(ret);
e3c68b
     }
e3c68b
 }
e3c68b
diff --git a/libglusterfs/src/glusterfs/globals.h b/libglusterfs/src/glusterfs/globals.h
e3c68b
index e45db14..55476f6 100644
e3c68b
--- a/libglusterfs/src/glusterfs/globals.h
e3c68b
+++ b/libglusterfs/src/glusterfs/globals.h
e3c68b
@@ -147,7 +147,7 @@ xlator_t **
e3c68b
 __glusterfs_this_location(void);
e3c68b
 xlator_t *
e3c68b
 glusterfs_this_get(void);
e3c68b
-int
e3c68b
+void
e3c68b
 glusterfs_this_set(xlator_t *);
e3c68b
 
e3c68b
 extern xlator_t global_xlator;
e3c68b
@@ -156,13 +156,11 @@ extern struct volume_options global_xl_options[];
e3c68b
 /* syncopctx */
e3c68b
 void *
e3c68b
 syncopctx_getctx(void);
e3c68b
-int
e3c68b
-syncopctx_setctx(void *ctx);
e3c68b
 
e3c68b
 /* task */
e3c68b
 void *
e3c68b
 synctask_get(void);
e3c68b
-int
e3c68b
+void
e3c68b
 synctask_set(void *);
e3c68b
 
e3c68b
 /* uuid_buf */
e3c68b
diff --git a/libglusterfs/src/glusterfs/mem-pool.h b/libglusterfs/src/glusterfs/mem-pool.h
e3c68b
index 0250b59..c5a486b 100644
e3c68b
--- a/libglusterfs/src/glusterfs/mem-pool.h
e3c68b
+++ b/libglusterfs/src/glusterfs/mem-pool.h
e3c68b
@@ -279,9 +279,7 @@ struct mem_pool_shared {
e3c68b
 };
e3c68b
 
e3c68b
 void
e3c68b
-mem_pools_init_early(void); /* basic initialization of memory pools */
e3c68b
-void
e3c68b
-mem_pools_init_late(void); /* start the pool_sweeper thread */
e3c68b
+mem_pools_init(void); /* start the pool_sweeper thread */
e3c68b
 void
e3c68b
 mem_pools_fini(void); /* cleanup memory pools */
e3c68b
 
e3c68b
@@ -306,6 +304,9 @@ void
e3c68b
 mem_pool_destroy(struct mem_pool *pool);
e3c68b
 
e3c68b
 void
e3c68b
+mem_pool_thread_destructor(void);
e3c68b
+
e3c68b
+void
e3c68b
 gf_mem_acct_enable_set(void *ctx);
e3c68b
 
e3c68b
 #endif /* _MEM_POOL_H */
e3c68b
diff --git a/libglusterfs/src/libglusterfs.sym b/libglusterfs/src/libglusterfs.sym
e3c68b
index 7a2edef..86215d2 100644
e3c68b
--- a/libglusterfs/src/libglusterfs.sym
e3c68b
+++ b/libglusterfs/src/libglusterfs.sym
e3c68b
@@ -872,8 +872,7 @@ mem_get0
e3c68b
 mem_pool_destroy
e3c68b
 mem_pool_new_fn
e3c68b
 mem_pools_fini
e3c68b
-mem_pools_init_early
e3c68b
-mem_pools_init_late
e3c68b
+mem_pools_init
e3c68b
 mem_put
e3c68b
 mkdir_p
e3c68b
 next_token
e3c68b
diff --git a/libglusterfs/src/mem-pool.c b/libglusterfs/src/mem-pool.c
e3c68b
index 9b4ea52..ab78804 100644
e3c68b
--- a/libglusterfs/src/mem-pool.c
e3c68b
+++ b/libglusterfs/src/mem-pool.c
e3c68b
@@ -353,7 +353,6 @@ free:
e3c68b
     FREE(ptr);
e3c68b
 }
e3c68b
 
e3c68b
-static pthread_key_t pool_key;
e3c68b
 static pthread_mutex_t pool_lock = PTHREAD_MUTEX_INITIALIZER;
e3c68b
 static struct list_head pool_threads;
e3c68b
 static pthread_mutex_t pool_free_lock = PTHREAD_MUTEX_INITIALIZER;
e3c68b
@@ -361,6 +360,8 @@ static struct list_head pool_free_threads;
e3c68b
 static struct mem_pool_shared pools[NPOOLS];
e3c68b
 static size_t pool_list_size;
e3c68b
 
e3c68b
+static __thread per_thread_pool_list_t *thread_pool_list = NULL;
e3c68b
+
e3c68b
 #if !defined(GF_DISABLE_MEMPOOL)
e3c68b
 #define N_COLD_LISTS 1024
e3c68b
 #define POOL_SWEEP_SECS 30
e3c68b
@@ -373,7 +374,6 @@ typedef struct {
e3c68b
 
e3c68b
 enum init_state {
e3c68b
     GF_MEMPOOL_INIT_NONE = 0,
e3c68b
-    GF_MEMPOOL_INIT_PREINIT,
e3c68b
     GF_MEMPOOL_INIT_EARLY,
e3c68b
     GF_MEMPOOL_INIT_LATE,
e3c68b
     GF_MEMPOOL_INIT_DESTROY
e3c68b
@@ -486,9 +486,9 @@ pool_sweeper(void *arg)
e3c68b
 }
e3c68b
 
e3c68b
 void
e3c68b
-pool_destructor(void *arg)
e3c68b
+mem_pool_thread_destructor(void)
e3c68b
 {
e3c68b
-    per_thread_pool_list_t *pool_list = arg;
e3c68b
+    per_thread_pool_list_t *pool_list = thread_pool_list;
e3c68b
 
e3c68b
     /* The pool-sweeper thread will take it from here.
e3c68b
      *
e3c68b
@@ -499,7 +499,10 @@ pool_destructor(void *arg)
e3c68b
      * This change can modify what mem_put() does, but both possibilities are
e3c68b
      * fine until the sweeper thread kicks in. The real synchronization must be
e3c68b
      * between mem_put() and the sweeper thread. */
e3c68b
-    pool_list->poison = 1;
e3c68b
+    if (pool_list != NULL) {
e3c68b
+        pool_list->poison = 1;
e3c68b
+        thread_pool_list = NULL;
e3c68b
+    }
e3c68b
 }
e3c68b
 
e3c68b
 static __attribute__((constructor)) void
e3c68b
@@ -522,46 +525,14 @@ mem_pools_preinit(void)
e3c68b
     pool_list_size = sizeof(per_thread_pool_list_t) +
e3c68b
                      sizeof(per_thread_pool_t) * (NPOOLS - 1);
e3c68b
 
e3c68b
-    init_done = GF_MEMPOOL_INIT_PREINIT;
e3c68b
+    init_done = GF_MEMPOOL_INIT_EARLY;
e3c68b
 }
e3c68b
 
e3c68b
-/* Use mem_pools_init_early() function for basic initialization. There will be
e3c68b
- * no cleanup done by the pool_sweeper thread until mem_pools_init_late() has
e3c68b
- * been called. Calling mem_get() will be possible after this function has
e3c68b
- * setup the basic structures. */
e3c68b
+/* Call mem_pools_init() once threading has been configured completely. This
e3c68b
+ * prevent the pool_sweeper thread from getting killed once the main() thread
e3c68b
+ * exits during deamonizing. */
e3c68b
 void
e3c68b
-mem_pools_init_early(void)
e3c68b
-{
e3c68b
-    pthread_mutex_lock(&init_mutex);
e3c68b
-    /* Use a pthread_key destructor to clean up when a thread exits.
e3c68b
-     *
e3c68b
-     * We won't increase init_count here, that is only done when the
e3c68b
-     * pool_sweeper thread is started too.
e3c68b
-     */
e3c68b
-    if (init_done == GF_MEMPOOL_INIT_PREINIT ||
e3c68b
-        init_done == GF_MEMPOOL_INIT_DESTROY) {
e3c68b
-        /* key has not been created yet */
e3c68b
-        if (pthread_key_create(&pool_key, pool_destructor) != 0) {
e3c68b
-            gf_log("mem-pool", GF_LOG_CRITICAL,
e3c68b
-                   "failed to initialize mem-pool key");
e3c68b
-        }
e3c68b
-
e3c68b
-        init_done = GF_MEMPOOL_INIT_EARLY;
e3c68b
-    } else {
e3c68b
-        gf_log("mem-pool", GF_LOG_CRITICAL,
e3c68b
-               "incorrect order of mem-pool initialization "
e3c68b
-               "(init_done=%d)",
e3c68b
-               init_done);
e3c68b
-    }
e3c68b
-
e3c68b
-    pthread_mutex_unlock(&init_mutex);
e3c68b
-}
e3c68b
-
e3c68b
-/* Call mem_pools_init_late() once threading has been configured completely.
e3c68b
- * This prevent the pool_sweeper thread from getting killed once the main()
e3c68b
- * thread exits during deamonizing. */
e3c68b
-void
e3c68b
-mem_pools_init_late(void)
e3c68b
+mem_pools_init(void)
e3c68b
 {
e3c68b
     pthread_mutex_lock(&init_mutex);
e3c68b
     if ((init_count++) == 0) {
e3c68b
@@ -580,13 +551,12 @@ mem_pools_fini(void)
e3c68b
     switch (init_count) {
e3c68b
         case 0:
e3c68b
             /*
e3c68b
-             * If init_count is already zero (as e.g. if somebody called
e3c68b
-             * this before mem_pools_init_late) then the sweeper was
e3c68b
-             * probably never even started so we don't need to stop it.
e3c68b
-             * Even if there's some crazy circumstance where there is a
e3c68b
-             * sweeper but init_count is still zero, that just means we'll
e3c68b
-             * leave it running.  Not perfect, but far better than any
e3c68b
-             * known alternative.
e3c68b
+             * If init_count is already zero (as e.g. if somebody called this
e3c68b
+             * before mem_pools_init) then the sweeper was probably never even
e3c68b
+             * started so we don't need to stop it. Even if there's some crazy
e3c68b
+             * circumstance where there is a sweeper but init_count is still
e3c68b
+             * zero, that just means we'll leave it running. Not perfect, but
e3c68b
+             * far better than any known alternative.
e3c68b
              */
e3c68b
             break;
e3c68b
         case 1: {
e3c68b
@@ -594,20 +564,17 @@ mem_pools_fini(void)
e3c68b
             per_thread_pool_list_t *next_pl;
e3c68b
             unsigned int i;
e3c68b
 
e3c68b
-            /* if only mem_pools_init_early() was called, sweeper_tid will
e3c68b
-             * be invalid and the functions will error out. That is not
e3c68b
-             * critical. In all other cases, the sweeper_tid will be valid
e3c68b
-             * and the thread gets stopped. */
e3c68b
+            /* if mem_pools_init() was not called, sweeper_tid will be invalid
e3c68b
+             * and the functions will error out. That is not critical. In all
e3c68b
+             * other cases, the sweeper_tid will be valid and the thread gets
e3c68b
+             * stopped. */
e3c68b
             (void)pthread_cancel(sweeper_tid);
e3c68b
             (void)pthread_join(sweeper_tid, NULL);
e3c68b
 
e3c68b
-            /* Need to clean the pool_key to prevent further usage of the
e3c68b
-             * per_thread_pool_list_t structure that is stored for each
e3c68b
-             * thread.
e3c68b
-             * This also prevents calling pool_destructor() when a thread
e3c68b
-             * exits, so there is no chance on a use-after-free of the
e3c68b
-             * per_thread_pool_list_t structure. */
e3c68b
-            (void)pthread_key_delete(pool_key);
e3c68b
+            /* At this point all threads should have already terminated, so
e3c68b
+             * it should be safe to destroy all pending per_thread_pool_list_t
e3c68b
+             * structures that are stored for each thread. */
e3c68b
+            mem_pool_thread_destructor();
e3c68b
 
e3c68b
             /* free all objects from all pools */
e3c68b
             list_for_each_entry_safe(pool_list, next_pl, &pool_threads,
e3c68b
@@ -642,11 +609,7 @@ mem_pools_fini(void)
e3c68b
 
e3c68b
 #else
e3c68b
 void
e3c68b
-mem_pools_init_early(void)
e3c68b
-{
e3c68b
-}
e3c68b
-void
e3c68b
-mem_pools_init_late(void)
e3c68b
+mem_pools_init(void)
e3c68b
 {
e3c68b
 }
e3c68b
 void
e3c68b
@@ -734,7 +697,7 @@ mem_get_pool_list(void)
e3c68b
     per_thread_pool_list_t *pool_list;
e3c68b
     unsigned int i;
e3c68b
 
e3c68b
-    pool_list = pthread_getspecific(pool_key);
e3c68b
+    pool_list = thread_pool_list;
e3c68b
     if (pool_list) {
e3c68b
         return pool_list;
e3c68b
     }
e3c68b
@@ -767,7 +730,8 @@ mem_get_pool_list(void)
e3c68b
     list_add(&pool_list->thr_list, &pool_threads);
e3c68b
     (void)pthread_mutex_unlock(&pool_lock);
e3c68b
 
e3c68b
-    (void)pthread_setspecific(pool_key, pool_list);
e3c68b
+    thread_pool_list = pool_list;
e3c68b
+
e3c68b
     return pool_list;
e3c68b
 }
e3c68b
 
e3c68b
diff --git a/libglusterfs/src/syncop.c b/libglusterfs/src/syncop.c
e3c68b
index c05939a..2eb7b49 100644
e3c68b
--- a/libglusterfs/src/syncop.c
e3c68b
+++ b/libglusterfs/src/syncop.c
e3c68b
@@ -26,28 +26,10 @@ syncopctx_setfsuid(void *uid)
e3c68b
 
e3c68b
     opctx = syncopctx_getctx();
e3c68b
 
e3c68b
-    /* alloc for this thread the first time */
e3c68b
-    if (!opctx) {
e3c68b
-        opctx = GF_CALLOC(1, sizeof(*opctx), gf_common_mt_syncopctx);
e3c68b
-        if (!opctx) {
e3c68b
-            ret = -1;
e3c68b
-            goto out;
e3c68b
-        }
e3c68b
-
e3c68b
-        ret = syncopctx_setctx(opctx);
e3c68b
-        if (ret != 0) {
e3c68b
-            GF_FREE(opctx);
e3c68b
-            opctx = NULL;
e3c68b
-            goto out;
e3c68b
-        }
e3c68b
-    }
e3c68b
+    opctx->uid = *(uid_t *)uid;
e3c68b
+    opctx->valid |= SYNCOPCTX_UID;
e3c68b
 
e3c68b
 out:
e3c68b
-    if (opctx && uid) {
e3c68b
-        opctx->uid = *(uid_t *)uid;
e3c68b
-        opctx->valid |= SYNCOPCTX_UID;
e3c68b
-    }
e3c68b
-
e3c68b
     return ret;
e3c68b
 }
e3c68b
 
e3c68b
@@ -66,28 +48,10 @@ syncopctx_setfsgid(void *gid)
e3c68b
 
e3c68b
     opctx = syncopctx_getctx();
e3c68b
 
e3c68b
-    /* alloc for this thread the first time */
e3c68b
-    if (!opctx) {
e3c68b
-        opctx = GF_CALLOC(1, sizeof(*opctx), gf_common_mt_syncopctx);
e3c68b
-        if (!opctx) {
e3c68b
-            ret = -1;
e3c68b
-            goto out;
e3c68b
-        }
e3c68b
-
e3c68b
-        ret = syncopctx_setctx(opctx);
e3c68b
-        if (ret != 0) {
e3c68b
-            GF_FREE(opctx);
e3c68b
-            opctx = NULL;
e3c68b
-            goto out;
e3c68b
-        }
e3c68b
-    }
e3c68b
+    opctx->gid = *(gid_t *)gid;
e3c68b
+    opctx->valid |= SYNCOPCTX_GID;
e3c68b
 
e3c68b
 out:
e3c68b
-    if (opctx && gid) {
e3c68b
-        opctx->gid = *(gid_t *)gid;
e3c68b
-        opctx->valid |= SYNCOPCTX_GID;
e3c68b
-    }
e3c68b
-
e3c68b
     return ret;
e3c68b
 }
e3c68b
 
e3c68b
@@ -107,43 +71,20 @@ syncopctx_setfsgroups(int count, const void *groups)
e3c68b
 
e3c68b
     opctx = syncopctx_getctx();
e3c68b
 
e3c68b
-    /* alloc for this thread the first time */
e3c68b
-    if (!opctx) {
e3c68b
-        opctx = GF_CALLOC(1, sizeof(*opctx), gf_common_mt_syncopctx);
e3c68b
-        if (!opctx) {
e3c68b
-            ret = -1;
e3c68b
-            goto out;
e3c68b
-        }
e3c68b
-
e3c68b
-        ret = syncopctx_setctx(opctx);
e3c68b
-        if (ret != 0) {
e3c68b
-            GF_FREE(opctx);
e3c68b
-            opctx = NULL;
e3c68b
-            goto out;
e3c68b
-        }
e3c68b
-    }
e3c68b
-
e3c68b
     /* resize internal groups as required */
e3c68b
     if (count && opctx->grpsize < count) {
e3c68b
         if (opctx->groups) {
e3c68b
-            tmpgroups = GF_REALLOC(opctx->groups, (sizeof(gid_t) * count));
e3c68b
-            /* NOTE: Not really required to zero the reallocation,
e3c68b
-             * as ngrps controls the validity of data,
e3c68b
-             * making a note irrespective */
e3c68b
-            if (tmpgroups == NULL) {
e3c68b
-                opctx->grpsize = 0;
e3c68b
-                GF_FREE(opctx->groups);
e3c68b
-                opctx->groups = NULL;
e3c68b
-                ret = -1;
e3c68b
-                goto out;
e3c68b
-            }
e3c68b
-        } else {
e3c68b
-            tmpgroups = GF_CALLOC(count, sizeof(gid_t), gf_common_mt_syncopctx);
e3c68b
-            if (tmpgroups == NULL) {
e3c68b
-                opctx->grpsize = 0;
e3c68b
-                ret = -1;
e3c68b
-                goto out;
e3c68b
-            }
e3c68b
+            /* Group list will be updated later, so no need to keep current
e3c68b
+             * data and waste time copying it. It's better to free the current
e3c68b
+             * allocation and then allocate a fresh new memory block. */
e3c68b
+            GF_FREE(opctx->groups);
e3c68b
+            opctx->groups = NULL;
e3c68b
+            opctx->grpsize = 0;
e3c68b
+        }
e3c68b
+        tmpgroups = GF_MALLOC(count * sizeof(gid_t), gf_common_mt_syncopctx);
e3c68b
+        if (tmpgroups == NULL) {
e3c68b
+            ret = -1;
e3c68b
+            goto out;
e3c68b
         }
e3c68b
 
e3c68b
         opctx->groups = tmpgroups;
e3c68b
@@ -177,28 +118,10 @@ syncopctx_setfspid(void *pid)
e3c68b
 
e3c68b
     opctx = syncopctx_getctx();
e3c68b
 
e3c68b
-    /* alloc for this thread the first time */
e3c68b
-    if (!opctx) {
e3c68b
-        opctx = GF_CALLOC(1, sizeof(*opctx), gf_common_mt_syncopctx);
e3c68b
-        if (!opctx) {
e3c68b
-            ret = -1;
e3c68b
-            goto out;
e3c68b
-        }
e3c68b
-
e3c68b
-        ret = syncopctx_setctx(opctx);
e3c68b
-        if (ret != 0) {
e3c68b
-            GF_FREE(opctx);
e3c68b
-            opctx = NULL;
e3c68b
-            goto out;
e3c68b
-        }
e3c68b
-    }
e3c68b
+    opctx->pid = *(pid_t *)pid;
e3c68b
+    opctx->valid |= SYNCOPCTX_PID;
e3c68b
 
e3c68b
 out:
e3c68b
-    if (opctx && pid) {
e3c68b
-        opctx->pid = *(pid_t *)pid;
e3c68b
-        opctx->valid |= SYNCOPCTX_PID;
e3c68b
-    }
e3c68b
-
e3c68b
     return ret;
e3c68b
 }
e3c68b
 
e3c68b
@@ -217,28 +140,10 @@ syncopctx_setfslkowner(gf_lkowner_t *lk_owner)
e3c68b
 
e3c68b
     opctx = syncopctx_getctx();
e3c68b
 
e3c68b
-    /* alloc for this thread the first time */
e3c68b
-    if (!opctx) {
e3c68b
-        opctx = GF_CALLOC(1, sizeof(*opctx), gf_common_mt_syncopctx);
e3c68b
-        if (!opctx) {
e3c68b
-            ret = -1;
e3c68b
-            goto out;
e3c68b
-        }
e3c68b
-
e3c68b
-        ret = syncopctx_setctx(opctx);
e3c68b
-        if (ret != 0) {
e3c68b
-            GF_FREE(opctx);
e3c68b
-            opctx = NULL;
e3c68b
-            goto out;
e3c68b
-        }
e3c68b
-    }
e3c68b
+    opctx->lk_owner = *lk_owner;
e3c68b
+    opctx->valid |= SYNCOPCTX_LKOWNER;
e3c68b
 
e3c68b
 out:
e3c68b
-    if (opctx && lk_owner) {
e3c68b
-        opctx->lk_owner = *lk_owner;
e3c68b
-        opctx->valid |= SYNCOPCTX_LKOWNER;
e3c68b
-    }
e3c68b
-
e3c68b
     return ret;
e3c68b
 }
e3c68b
 
e3c68b
diff --git a/xlators/features/changelog/lib/src/gf-changelog-helpers.c b/xlators/features/changelog/lib/src/gf-changelog-helpers.c
e3c68b
index 03dac5e..e5a9db4 100644
e3c68b
--- a/xlators/features/changelog/lib/src/gf-changelog-helpers.c
e3c68b
+++ b/xlators/features/changelog/lib/src/gf-changelog-helpers.c
e3c68b
@@ -64,20 +64,7 @@ gf_rfc3986_encode_space_newline(unsigned char *s, char *enc, char *estr)
e3c68b
  *       made a part of libglusterfs.
e3c68b
  */
e3c68b
 
e3c68b
-static pthread_key_t rl_key;
e3c68b
-static pthread_once_t rl_once = PTHREAD_ONCE_INIT;
e3c68b
-
e3c68b
-static void
e3c68b
-readline_destructor(void *ptr)
e3c68b
-{
e3c68b
-    GF_FREE(ptr);
e3c68b
-}
e3c68b
-
e3c68b
-static void
e3c68b
-readline_once(void)
e3c68b
-{
e3c68b
-    pthread_key_create(&rl_key, readline_destructor);
e3c68b
-}
e3c68b
+static __thread read_line_t thread_tsd = {};
e3c68b
 
e3c68b
 static ssize_t
e3c68b
 my_read(read_line_t *tsd, int fd, char *ptr)
e3c68b
@@ -97,27 +84,6 @@ my_read(read_line_t *tsd, int fd, char *ptr)
e3c68b
     return 1;
e3c68b
 }
e3c68b
 
e3c68b
-static int
e3c68b
-gf_readline_init_once(read_line_t **tsd)
e3c68b
-{
e3c68b
-    if (pthread_once(&rl_once, readline_once) != 0)
e3c68b
-        return -1;
e3c68b
-
e3c68b
-    *tsd = pthread_getspecific(rl_key);
e3c68b
-    if (*tsd)
e3c68b
-        goto out;
e3c68b
-
e3c68b
-    *tsd = GF_CALLOC(1, sizeof(**tsd), gf_changelog_mt_libgfchangelog_rl_t);
e3c68b
-    if (!*tsd)
e3c68b
-        return -1;
e3c68b
-
e3c68b
-    if (pthread_setspecific(rl_key, *tsd) != 0)
e3c68b
-        return -1;
e3c68b
-
e3c68b
-out:
e3c68b
-    return 0;
e3c68b
-}
e3c68b
-
e3c68b
 ssize_t
e3c68b
 gf_readline(int fd, void *vptr, size_t maxlen)
e3c68b
 {
e3c68b
@@ -125,10 +91,7 @@ gf_readline(int fd, void *vptr, size_t maxlen)
e3c68b
     size_t rc = 0;
e3c68b
     char c = ' ';
e3c68b
     char *ptr = NULL;
e3c68b
-    read_line_t *tsd = NULL;
e3c68b
-
e3c68b
-    if (gf_readline_init_once(&tsd))
e3c68b
-        return -1;
e3c68b
+    read_line_t *tsd = &thread_tsd;
e3c68b
 
e3c68b
     ptr = vptr;
e3c68b
     for (n = 1; n < maxlen; n++) {
e3c68b
@@ -151,10 +114,7 @@ off_t
e3c68b
 gf_lseek(int fd, off_t offset, int whence)
e3c68b
 {
e3c68b
     off_t off = 0;
e3c68b
-    read_line_t *tsd = NULL;
e3c68b
-
e3c68b
-    if (gf_readline_init_once(&tsd))
e3c68b
-        return -1;
e3c68b
+    read_line_t *tsd = &thread_tsd;
e3c68b
 
e3c68b
     off = sys_lseek(fd, offset, whence);
e3c68b
     if (off == -1)
e3c68b
@@ -169,10 +129,7 @@ gf_lseek(int fd, off_t offset, int whence)
e3c68b
 int
e3c68b
 gf_ftruncate(int fd, off_t length)
e3c68b
 {
e3c68b
-    read_line_t *tsd = NULL;
e3c68b
-
e3c68b
-    if (gf_readline_init_once(&tsd))
e3c68b
-        return -1;
e3c68b
+    read_line_t *tsd = &thread_tsd;
e3c68b
 
e3c68b
     if (sys_ftruncate(fd, 0))
e3c68b
         return -1;
e3c68b
diff --git a/xlators/features/changelog/lib/src/gf-changelog.c b/xlators/features/changelog/lib/src/gf-changelog.c
e3c68b
index 7ed9e55..d6acb37 100644
e3c68b
--- a/xlators/features/changelog/lib/src/gf-changelog.c
e3c68b
+++ b/xlators/features/changelog/lib/src/gf-changelog.c
e3c68b
@@ -237,9 +237,8 @@ gf_changelog_init_master()
e3c68b
 {
e3c68b
     int ret = 0;
e3c68b
 
e3c68b
-    mem_pools_init_early();
e3c68b
     ret = gf_changelog_init_context();
e3c68b
-    mem_pools_init_late();
e3c68b
+    mem_pools_init();
e3c68b
 
e3c68b
     return ret;
e3c68b
 }
e3c68b
diff --git a/xlators/nfs/server/src/mount3udp_svc.c b/xlators/nfs/server/src/mount3udp_svc.c
e3c68b
index d5e4169..0688779eb 100644
e3c68b
--- a/xlators/nfs/server/src/mount3udp_svc.c
e3c68b
+++ b/xlators/nfs/server/src/mount3udp_svc.c
e3c68b
@@ -216,11 +216,7 @@ mount3udp_thread(void *argv)
e3c68b
 
e3c68b
     GF_ASSERT(nfsx);
e3c68b
 
e3c68b
-    if (glusterfs_this_set(nfsx)) {
e3c68b
-        gf_msg(GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_XLATOR_SET_FAIL,
e3c68b
-               "Failed to set xlator, nfs.mount-udp will not work");
e3c68b
-        return NULL;
e3c68b
-    }
e3c68b
+    glusterfs_this_set(nfsx);
e3c68b
 
e3c68b
     transp = svcudp_create(RPC_ANYSOCK);
e3c68b
     if (transp == NULL) {
e3c68b
-- 
e3c68b
1.8.3.1
e3c68b