17b94a
From b3a17b67a69142eef1b4adde3409d5e54dda1e0b Mon Sep 17 00:00:00 2001
17b94a
From: Amar Tumballi <amarts@redhat.com>
17b94a
Date: Sat, 9 Feb 2019 13:23:06 +0530
17b94a
Subject: [PATCH 507/511] inode: make critical section smaller
17b94a
17b94a
do all the 'static' tasks outside of locked region.
17b94a
17b94a
* hash_dentry() and hash_gfid() are now called outside locked region.
17b94a
* remove extra __dentry_hash exported in libglusterfs.sym
17b94a
* avoid checks in locked functions, if the check is done in calling
17b94a
  function.
17b94a
* implement dentry_destroy(), which handles freeing of dentry separately,
17b94a
  from that of dentry_unset (which takes care of separating dentry from
17b94a
  inode, and table)
17b94a
17b94a
> Updates: bz#1670031
17b94a
> Change-Id: I584213e0748464bb427fbdef3c4ab6615d7d5eb0
17b94a
> Signed-off-by: Amar Tumballi <amarts@redhat.com>
17b94a
> (Cherry pick from commit 8a90d346b9d3f69ff11241feb0011c90a8e57e30)
17b94a
> (Review on upstream link https://review.gluster.org/#/c/glusterfs/+/22184/)
17b94a
17b94a
Change-Id: I584213e0748464bb427fbdef3c4ab6615d7d5eb0
17b94a
BUG: 1898777
17b94a
Signed-off-by: Mohit Agrawal <moagrawa@redhat.com>
17b94a
Reviewed-on: https://code.engineering.redhat.com/gerrit/221189
17b94a
Tested-by: RHGS Build Bot <nigelb@redhat.com>
17b94a
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
17b94a
---
17b94a
 libglusterfs/src/glusterfs/inode.h |   3 -
17b94a
 libglusterfs/src/inode.c           | 323 +++++++++++++------------------------
17b94a
 libglusterfs/src/libglusterfs.sym  |   1 -
17b94a
 3 files changed, 111 insertions(+), 216 deletions(-)
17b94a
17b94a
diff --git a/libglusterfs/src/glusterfs/inode.h b/libglusterfs/src/glusterfs/inode.h
17b94a
index 4421c47..c875653 100644
17b94a
--- a/libglusterfs/src/glusterfs/inode.h
17b94a
+++ b/libglusterfs/src/glusterfs/inode.h
17b94a
@@ -167,9 +167,6 @@ inode_rename(inode_table_t *table, inode_t *olddir, const char *oldname,
17b94a
              inode_t *newdir, const char *newname, inode_t *inode,
17b94a
              struct iatt *stbuf);
17b94a
 
17b94a
-dentry_t *
17b94a
-__dentry_grep(inode_table_t *table, inode_t *parent, const char *name);
17b94a
-
17b94a
 inode_t *
17b94a
 inode_grep(inode_table_t *table, inode_t *parent, const char *name);
17b94a
 
17b94a
diff --git a/libglusterfs/src/inode.c b/libglusterfs/src/inode.c
17b94a
index 4c3c546..71b2d2a 100644
17b94a
--- a/libglusterfs/src/inode.c
17b94a
+++ b/libglusterfs/src/inode.c
17b94a
@@ -159,27 +159,15 @@ hash_dentry(inode_t *parent, const char *name, int mod)
17b94a
 static int
17b94a
 hash_gfid(uuid_t uuid, int mod)
17b94a
 {
17b94a
-    int ret = 0;
17b94a
-
17b94a
-    ret = uuid[15] + (uuid[14] << 8);
17b94a
-
17b94a
-    return ret;
17b94a
+    return ((uuid[15] + (uuid[14] << 8)) % mod);
17b94a
 }
17b94a
 
17b94a
 static void
17b94a
-__dentry_hash(dentry_t *dentry)
17b94a
+__dentry_hash(dentry_t *dentry, const int hash)
17b94a
 {
17b94a
     inode_table_t *table = NULL;
17b94a
-    int hash = 0;
17b94a
-
17b94a
-    if (!dentry) {
17b94a
-        gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0, LG_MSG_DENTRY_NOT_FOUND,
17b94a
-                         "dentry not found");
17b94a
-        return;
17b94a
-    }
17b94a
 
17b94a
     table = dentry->inode->table;
17b94a
-    hash = hash_dentry(dentry->parent, dentry->name, table->hashsize);
17b94a
 
17b94a
     list_del_init(&dentry->hash);
17b94a
     list_add(&dentry->hash, &table->name_hash[hash]);
17b94a
@@ -188,49 +176,44 @@ __dentry_hash(dentry_t *dentry)
17b94a
 static int
17b94a
 __is_dentry_hashed(dentry_t *dentry)
17b94a
 {
17b94a
-    if (!dentry) {
17b94a
-        gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0, LG_MSG_DENTRY_NOT_FOUND,
17b94a
-                         "dentry not found");
17b94a
-        return 0;
17b94a
-    }
17b94a
-
17b94a
     return !list_empty(&dentry->hash);
17b94a
 }
17b94a
 
17b94a
 static void
17b94a
 __dentry_unhash(dentry_t *dentry)
17b94a
 {
17b94a
-    if (!dentry) {
17b94a
-        gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0, LG_MSG_DENTRY_NOT_FOUND,
17b94a
-                         "dentry not found");
17b94a
-        return;
17b94a
-    }
17b94a
-
17b94a
     list_del_init(&dentry->hash);
17b94a
 }
17b94a
 
17b94a
 static void
17b94a
-__dentry_unset(dentry_t *dentry)
17b94a
+dentry_destroy(dentry_t *dentry)
17b94a
 {
17b94a
-    if (!dentry) {
17b94a
-        gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0, LG_MSG_DENTRY_NOT_FOUND,
17b94a
-                         "dentry not found");
17b94a
+    if (!dentry)
17b94a
         return;
17b94a
-    }
17b94a
+
17b94a
+    GF_FREE(dentry->name);
17b94a
+    dentry->name = NULL;
17b94a
+    mem_put(dentry);
17b94a
+
17b94a
+    return;
17b94a
+}
17b94a
+
17b94a
+static dentry_t *
17b94a
+__dentry_unset(dentry_t *dentry)
17b94a
+{
17b94a
+    if (!dentry)
17b94a
+        return NULL;
17b94a
 
17b94a
     __dentry_unhash(dentry);
17b94a
 
17b94a
     list_del_init(&dentry->inode_list);
17b94a
 
17b94a
-    GF_FREE(dentry->name);
17b94a
-    dentry->name = NULL;
17b94a
-
17b94a
     if (dentry->parent) {
17b94a
         __inode_unref(dentry->parent, false);
17b94a
         dentry->parent = NULL;
17b94a
     }
17b94a
 
17b94a
-    mem_put(dentry);
17b94a
+    return dentry;
17b94a
 }
17b94a
 
17b94a
 static int
17b94a
@@ -289,22 +272,14 @@ static int
17b94a
 __is_dentry_cyclic(dentry_t *dentry)
17b94a
 {
17b94a
     int ret = 0;
17b94a
-    inode_t *inode = NULL;
17b94a
-    char *name = "<nul>";
17b94a
 
17b94a
     ret = __foreach_ancestor_dentry(dentry, __check_cycle, dentry->inode);
17b94a
     if (ret) {
17b94a
-        inode = dentry->inode;
17b94a
-
17b94a
-        if (dentry->name)
17b94a
-            name = dentry->name;
17b94a
-
17b94a
         gf_msg(dentry->inode->table->name, GF_LOG_CRITICAL, 0,
17b94a
                LG_MSG_DENTRY_CYCLIC_LOOP,
17b94a
-               "detected cyclic loop "
17b94a
-               "formation during inode linkage. inode (%s) linking "
17b94a
-               "under itself as %s",
17b94a
-               uuid_utoa(inode->gfid), name);
17b94a
+               "detected cyclic loop formation during inode linkage. "
17b94a
+               "inode (%s) linking under itself as %s",
17b94a
+               uuid_utoa(dentry->inode->gfid), dentry->name);
17b94a
     }
17b94a
 
17b94a
     return ret;
17b94a
@@ -313,41 +288,19 @@ __is_dentry_cyclic(dentry_t *dentry)
17b94a
 static void
17b94a
 __inode_unhash(inode_t *inode)
17b94a
 {
17b94a
-    if (!inode) {
17b94a
-        gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0, LG_MSG_INODE_NOT_FOUND,
17b94a
-                         "inode not found");
17b94a
-        return;
17b94a
-    }
17b94a
-
17b94a
     list_del_init(&inode->hash);
17b94a
 }
17b94a
 
17b94a
 static int
17b94a
 __is_inode_hashed(inode_t *inode)
17b94a
 {
17b94a
-    if (!inode) {
17b94a
-        gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0, LG_MSG_INODE_NOT_FOUND,
17b94a
-                         "inode not found");
17b94a
-        return 0;
17b94a
-    }
17b94a
-
17b94a
     return !list_empty(&inode->hash);
17b94a
 }
17b94a
 
17b94a
 static void
17b94a
-__inode_hash(inode_t *inode)
17b94a
+__inode_hash(inode_t *inode, const int hash)
17b94a
 {
17b94a
-    inode_table_t *table = NULL;
17b94a
-    int hash = 0;
17b94a
-
17b94a
-    if (!inode) {
17b94a
-        gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0, LG_MSG_INODE_NOT_FOUND,
17b94a
-                         "inode not found");
17b94a
-        return;
17b94a
-    }
17b94a
-
17b94a
-    table = inode->table;
17b94a
-    hash = hash_gfid(inode->gfid, 65536);
17b94a
+    inode_table_t *table = inode->table;
17b94a
 
17b94a
     list_del_init(&inode->hash);
17b94a
     list_add(&inode->hash, &table->inode_hash[hash]);
17b94a
@@ -359,12 +312,6 @@ __dentry_search_for_inode(inode_t *inode, uuid_t pargfid, const char *name)
17b94a
     dentry_t *dentry = NULL;
17b94a
     dentry_t *tmp = NULL;
17b94a
 
17b94a
-    if (!inode || !name) {
17b94a
-        gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
17b94a
-                         "inode || name not found");
17b94a
-        return NULL;
17b94a
-    }
17b94a
-
17b94a
     /* earlier, just the ino was sent, which could have been 0, now
17b94a
        we deal with gfid, and if sent gfid is null or 0, no need to
17b94a
        continue with the check */
17b94a
@@ -390,12 +337,6 @@ __inode_ctx_free(inode_t *inode)
17b94a
     xlator_t *xl = NULL;
17b94a
     xlator_t *old_THIS = NULL;
17b94a
 
17b94a
-    if (!inode) {
17b94a
-        gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0, LG_MSG_INODE_NOT_FOUND,
17b94a
-                         "inode not found");
17b94a
-        return;
17b94a
-    }
17b94a
-
17b94a
     if (!inode->_ctx) {
17b94a
         gf_msg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_CTX_NULL,
17b94a
                "_ctx not found");
17b94a
@@ -424,12 +365,6 @@ noctx:
17b94a
 static void
17b94a
 __inode_destroy(inode_t *inode)
17b94a
 {
17b94a
-    if (!inode) {
17b94a
-        gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0, LG_MSG_INODE_NOT_FOUND,
17b94a
-                         "inode not found");
17b94a
-        return;
17b94a
-    }
17b94a
-
17b94a
     __inode_ctx_free(inode);
17b94a
 
17b94a
     LOCK_DESTROY(&inode->lock);
17b94a
@@ -472,9 +407,6 @@ inode_ctx_merge(fd_t *fd, inode_t *inode, inode_t *linked_inode)
17b94a
 static void
17b94a
 __inode_activate(inode_t *inode)
17b94a
 {
17b94a
-    if (!inode)
17b94a
-        return;
17b94a
-
17b94a
     list_move(&inode->list, &inode->table->active);
17b94a
     inode->table->active_size++;
17b94a
 }
17b94a
@@ -485,19 +417,13 @@ __inode_passivate(inode_t *inode)
17b94a
     dentry_t *dentry = NULL;
17b94a
     dentry_t *t = NULL;
17b94a
 
17b94a
-    if (!inode) {
17b94a
-        gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0, LG_MSG_INODE_NOT_FOUND,
17b94a
-                         "inode not found");
17b94a
-        return;
17b94a
-    }
17b94a
-
17b94a
     list_move_tail(&inode->list, &inode->table->lru);
17b94a
     inode->table->lru_size++;
17b94a
 
17b94a
     list_for_each_entry_safe(dentry, t, &inode->dentry_list, inode_list)
17b94a
     {
17b94a
         if (!__is_dentry_hashed(dentry))
17b94a
-            __dentry_unset(dentry);
17b94a
+            dentry_destroy(__dentry_unset(dentry));
17b94a
     }
17b94a
 }
17b94a
 
17b94a
@@ -507,12 +433,6 @@ __inode_retire(inode_t *inode)
17b94a
     dentry_t *dentry = NULL;
17b94a
     dentry_t *t = NULL;
17b94a
 
17b94a
-    if (!inode) {
17b94a
-        gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0, LG_MSG_INODE_NOT_FOUND,
17b94a
-                         "inode not found");
17b94a
-        return;
17b94a
-    }
17b94a
-
17b94a
     list_move_tail(&inode->list, &inode->table->purge);
17b94a
     inode->table->purge_size++;
17b94a
 
17b94a
@@ -520,7 +440,7 @@ __inode_retire(inode_t *inode)
17b94a
 
17b94a
     list_for_each_entry_safe(dentry, t, &inode->dentry_list, inode_list)
17b94a
     {
17b94a
-        __dentry_unset(dentry);
17b94a
+        dentry_destroy(__dentry_unset(dentry));
17b94a
     }
17b94a
 }
17b94a
 
17b94a
@@ -547,9 +467,6 @@ __inode_unref(inode_t *inode, bool clear)
17b94a
     xlator_t *this = NULL;
17b94a
     uint64_t nlookup = 0;
17b94a
 
17b94a
-    if (!inode)
17b94a
-        return NULL;
17b94a
-
17b94a
     /*
17b94a
      * Root inode should always be in active list of inode table. So unrefs
17b94a
      * on root inode are no-ops.
17b94a
@@ -677,16 +594,10 @@ inode_ref(inode_t *inode)
17b94a
 }
17b94a
 
17b94a
 static dentry_t *
17b94a
-__dentry_create(inode_t *inode, inode_t *parent, const char *name)
17b94a
+dentry_create(inode_t *inode, inode_t *parent, const char *name)
17b94a
 {
17b94a
     dentry_t *newd = NULL;
17b94a
 
17b94a
-    if (!inode || !parent || !name) {
17b94a
-        gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
17b94a
-                         "inode || parent || name not found");
17b94a
-        return NULL;
17b94a
-    }
17b94a
-
17b94a
     newd = mem_get0(parent->table->dentry_pool);
17b94a
     if (newd == NULL) {
17b94a
         goto out;
17b94a
@@ -702,10 +613,6 @@ __dentry_create(inode_t *inode, inode_t *parent, const char *name)
17b94a
         goto out;
17b94a
     }
17b94a
 
17b94a
-    if (parent)
17b94a
-        newd->parent = __inode_ref(parent, false);
17b94a
-
17b94a
-    list_add(&newd->inode_list, &inode->dentry_list);
17b94a
     newd->inode = inode;
17b94a
 
17b94a
 out:
17b94a
@@ -717,14 +624,6 @@ __inode_create(inode_table_t *table)
17b94a
 {
17b94a
     inode_t *newi = NULL;
17b94a
 
17b94a
-    if (!table) {
17b94a
-        gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0,
17b94a
-                         LG_MSG_INODE_TABLE_NOT_FOUND,
17b94a
-                         "table not "
17b94a
-                         "found");
17b94a
-        return NULL;
17b94a
-    }
17b94a
-
17b94a
     newi = mem_get0(table->inode_pool);
17b94a
     if (!newi) {
17b94a
         goto out;
17b94a
@@ -795,9 +694,6 @@ __inode_ref_reduce_by_n(inode_t *inode, uint64_t nref)
17b94a
 {
17b94a
     uint64_t nlookup = 0;
17b94a
 
17b94a
-    if (!inode)
17b94a
-        return NULL;
17b94a
-
17b94a
     GF_ASSERT(inode->ref >= nref);
17b94a
 
17b94a
     inode->ref -= nref;
17b94a
@@ -837,17 +733,12 @@ inode_forget_atomic(inode_t *inode, uint64_t nlookup)
17b94a
 }
17b94a
 
17b94a
 dentry_t *
17b94a
-__dentry_grep(inode_table_t *table, inode_t *parent, const char *name)
17b94a
+__dentry_grep(inode_table_t *table, inode_t *parent, const char *name,
17b94a
+              const int hash)
17b94a
 {
17b94a
-    int hash = 0;
17b94a
     dentry_t *dentry = NULL;
17b94a
     dentry_t *tmp = NULL;
17b94a
 
17b94a
-    if (!table || !name || !parent)
17b94a
-        return NULL;
17b94a
-
17b94a
-    hash = hash_dentry(parent, name, table->hashsize);
17b94a
-
17b94a
     list_for_each_entry(tmp, &table->name_hash[hash], hash)
17b94a
     {
17b94a
         if (tmp->parent == parent && !strcmp(tmp->name, name)) {
17b94a
@@ -872,15 +763,16 @@ inode_grep(inode_table_t *table, inode_t *parent, const char *name)
17b94a
         return NULL;
17b94a
     }
17b94a
 
17b94a
+    int hash = hash_dentry(parent, name, table->hashsize);
17b94a
+
17b94a
     pthread_mutex_lock(&table->lock);
17b94a
     {
17b94a
-        dentry = __dentry_grep(table, parent, name);
17b94a
-
17b94a
-        if (dentry)
17b94a
+        dentry = __dentry_grep(table, parent, name, hash);
17b94a
+        if (dentry) {
17b94a
             inode = dentry->inode;
17b94a
-
17b94a
-        if (inode)
17b94a
-            __inode_ref(inode, false);
17b94a
+            if (inode)
17b94a
+                __inode_ref(inode, false);
17b94a
+        }
17b94a
     }
17b94a
     pthread_mutex_unlock(&table->lock);
17b94a
 
17b94a
@@ -947,17 +839,18 @@ inode_grep_for_gfid(inode_table_t *table, inode_t *parent, const char *name,
17b94a
         return ret;
17b94a
     }
17b94a
 
17b94a
+    int hash = hash_dentry(parent, name, table->hashsize);
17b94a
+
17b94a
     pthread_mutex_lock(&table->lock);
17b94a
     {
17b94a
-        dentry = __dentry_grep(table, parent, name);
17b94a
-
17b94a
-        if (dentry)
17b94a
+        dentry = __dentry_grep(table, parent, name, hash);
17b94a
+        if (dentry) {
17b94a
             inode = dentry->inode;
17b94a
-
17b94a
-        if (inode) {
17b94a
-            gf_uuid_copy(gfid, inode->gfid);
17b94a
-            *type = inode->ia_type;
17b94a
-            ret = 0;
17b94a
+            if (inode) {
17b94a
+                gf_uuid_copy(gfid, inode->gfid);
17b94a
+                *type = inode->ia_type;
17b94a
+                ret = 0;
17b94a
+            }
17b94a
         }
17b94a
     }
17b94a
     pthread_mutex_unlock(&table->lock);
17b94a
@@ -978,25 +871,14 @@ __is_root_gfid(uuid_t gfid)
17b94a
 }
17b94a
 
17b94a
 inode_t *
17b94a
-__inode_find(inode_table_t *table, uuid_t gfid)
17b94a
+__inode_find(inode_table_t *table, uuid_t gfid, const int hash)
17b94a
 {
17b94a
     inode_t *inode = NULL;
17b94a
     inode_t *tmp = NULL;
17b94a
-    int hash = 0;
17b94a
-
17b94a
-    if (!table) {
17b94a
-        gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0,
17b94a
-                         LG_MSG_INODE_TABLE_NOT_FOUND,
17b94a
-                         "table not "
17b94a
-                         "found");
17b94a
-        goto out;
17b94a
-    }
17b94a
 
17b94a
     if (__is_root_gfid(gfid))
17b94a
         return table->root;
17b94a
 
17b94a
-    hash = hash_gfid(gfid, 65536);
17b94a
-
17b94a
     list_for_each_entry(tmp, &table->inode_hash[hash], hash)
17b94a
     {
17b94a
         if (gf_uuid_compare(tmp->gfid, gfid) == 0) {
17b94a
@@ -1005,7 +887,6 @@ __inode_find(inode_table_t *table, uuid_t gfid)
17b94a
         }
17b94a
     }
17b94a
 
17b94a
-out:
17b94a
     return inode;
17b94a
 }
17b94a
 
17b94a
@@ -1022,9 +903,11 @@ inode_find(inode_table_t *table, uuid_t gfid)
17b94a
         return NULL;
17b94a
     }
17b94a
 
17b94a
+    int hash = hash_gfid(gfid, 65536);
17b94a
+
17b94a
     pthread_mutex_lock(&table->lock);
17b94a
     {
17b94a
-        inode = __inode_find(table, gfid);
17b94a
+        inode = __inode_find(table, gfid, hash);
17b94a
         if (inode)
17b94a
             __inode_ref(inode, false);
17b94a
     }
17b94a
@@ -1035,7 +918,7 @@ inode_find(inode_table_t *table, uuid_t gfid)
17b94a
 
17b94a
 static inode_t *
17b94a
 __inode_link(inode_t *inode, inode_t *parent, const char *name,
17b94a
-             struct iatt *iatt)
17b94a
+             struct iatt *iatt, const int dhash)
17b94a
 {
17b94a
     dentry_t *dentry = NULL;
17b94a
     dentry_t *old_dentry = NULL;
17b94a
@@ -1043,16 +926,7 @@ __inode_link(inode_t *inode, inode_t *parent, const char *name,
17b94a
     inode_table_t *table = NULL;
17b94a
     inode_t *link_inode = NULL;
17b94a
 
17b94a
-    if (!inode) {
17b94a
-        errno = EINVAL;
17b94a
-        return NULL;
17b94a
-    }
17b94a
-
17b94a
     table = inode->table;
17b94a
-    if (!table) {
17b94a
-        errno = EINVAL;
17b94a
-        return NULL;
17b94a
-    }
17b94a
 
17b94a
     if (parent) {
17b94a
         /* We should prevent inode linking between different
17b94a
@@ -1090,14 +964,16 @@ __inode_link(inode_t *inode, inode_t *parent, const char *name,
17b94a
             return NULL;
17b94a
         }
17b94a
 
17b94a
-        old_inode = __inode_find(table, iatt->ia_gfid);
17b94a
+        int ihash = hash_gfid(iatt->ia_gfid, 65536);
17b94a
+
17b94a
+        old_inode = __inode_find(table, iatt->ia_gfid, ihash);
17b94a
 
17b94a
         if (old_inode) {
17b94a
             link_inode = old_inode;
17b94a
         } else {
17b94a
             gf_uuid_copy(inode->gfid, iatt->ia_gfid);
17b94a
             inode->ia_type = iatt->ia_type;
17b94a
-            __inode_hash(inode);
17b94a
+            __inode_hash(inode, ihash);
17b94a
         }
17b94a
     } else {
17b94a
         /* @old_inode serves another important purpose - it indicates
17b94a
@@ -1112,22 +988,16 @@ __inode_link(inode_t *inode, inode_t *parent, const char *name,
17b94a
         old_inode = inode;
17b94a
     }
17b94a
 
17b94a
-    if (name) {
17b94a
-        if (!strcmp(name, ".") || !strcmp(name, ".."))
17b94a
-            return link_inode;
17b94a
-
17b94a
-        if (strchr(name, '/')) {
17b94a
-            GF_ASSERT(!"inode link attempted with '/' in name");
17b94a
-            return NULL;
17b94a
-        }
17b94a
+    if (name && (!strcmp(name, ".") || !strcmp(name, ".."))) {
17b94a
+        return link_inode;
17b94a
     }
17b94a
 
17b94a
     /* use only link_inode beyond this point */
17b94a
     if (parent) {
17b94a
-        old_dentry = __dentry_grep(table, parent, name);
17b94a
+        old_dentry = __dentry_grep(table, parent, name, dhash);
17b94a
 
17b94a
         if (!old_dentry || old_dentry->inode != link_inode) {
17b94a
-            dentry = __dentry_create(link_inode, parent, name);
17b94a
+            dentry = dentry_create(link_inode, parent, name);
17b94a
             if (!dentry) {
17b94a
                 gf_msg_callingfn(
17b94a
                     THIS->name, GF_LOG_ERROR, 0, LG_MSG_DENTRY_CREATE_FAILED,
17b94a
@@ -1137,15 +1007,20 @@ __inode_link(inode_t *inode, inode_t *parent, const char *name,
17b94a
                 errno = ENOMEM;
17b94a
                 return NULL;
17b94a
             }
17b94a
+
17b94a
+            /* dentry linking needs to happen inside lock */
17b94a
+            dentry->parent = __inode_ref(parent, false);
17b94a
+            list_add(&dentry->inode_list, &link_inode->dentry_list);
17b94a
+
17b94a
             if (old_inode && __is_dentry_cyclic(dentry)) {
17b94a
                 errno = ELOOP;
17b94a
-                __dentry_unset(dentry);
17b94a
+                dentry_destroy(__dentry_unset(dentry));
17b94a
                 return NULL;
17b94a
             }
17b94a
-            __dentry_hash(dentry);
17b94a
+            __dentry_hash(dentry, dhash);
17b94a
 
17b94a
             if (old_dentry)
17b94a
-                __dentry_unset(old_dentry);
17b94a
+                dentry_destroy(__dentry_unset(old_dentry));
17b94a
         }
17b94a
     }
17b94a
 
17b94a
@@ -1155,6 +1030,7 @@ __inode_link(inode_t *inode, inode_t *parent, const char *name,
17b94a
 inode_t *
17b94a
 inode_link(inode_t *inode, inode_t *parent, const char *name, struct iatt *iatt)
17b94a
 {
17b94a
+    int hash = 0;
17b94a
     inode_table_t *table = NULL;
17b94a
     inode_t *linked_inode = NULL;
17b94a
 
17b94a
@@ -1166,10 +1042,18 @@ inode_link(inode_t *inode, inode_t *parent, const char *name, struct iatt *iatt)
17b94a
 
17b94a
     table = inode->table;
17b94a
 
17b94a
+    if (parent && name) {
17b94a
+        hash = hash_dentry(parent, name, table->hashsize);
17b94a
+    }
17b94a
+
17b94a
+    if (name && strchr(name, '/')) {
17b94a
+        GF_ASSERT(!"inode link attempted with '/' in name");
17b94a
+        return NULL;
17b94a
+    }
17b94a
+
17b94a
     pthread_mutex_lock(&table->lock);
17b94a
     {
17b94a
-        linked_inode = __inode_link(inode, parent, name, iatt);
17b94a
-
17b94a
+        linked_inode = __inode_link(inode, parent, name, iatt, hash);
17b94a
         if (linked_inode)
17b94a
             __inode_ref(linked_inode, false);
17b94a
     }
17b94a
@@ -1312,48 +1196,47 @@ inode_invalidate(inode_t *inode)
17b94a
     return ret;
17b94a
 }
17b94a
 
17b94a
-static void
17b94a
+static dentry_t *
17b94a
 __inode_unlink(inode_t *inode, inode_t *parent, const char *name)
17b94a
 {
17b94a
     dentry_t *dentry = NULL;
17b94a
     char pgfid[64] = {0};
17b94a
     char gfid[64] = {0};
17b94a
 
17b94a
-    if (!inode || !parent || !name)
17b94a
-        return;
17b94a
-
17b94a
     dentry = __dentry_search_for_inode(inode, parent->gfid, name);
17b94a
 
17b94a
     /* dentry NULL for corrupted backend */
17b94a
     if (dentry) {
17b94a
-        __dentry_unset(dentry);
17b94a
+        dentry = __dentry_unset(dentry);
17b94a
     } else {
17b94a
         gf_msg("inode", GF_LOG_WARNING, 0, LG_MSG_DENTRY_NOT_FOUND,
17b94a
                "%s/%s: dentry not found in %s",
17b94a
                uuid_utoa_r(parent->gfid, pgfid), name,
17b94a
                uuid_utoa_r(inode->gfid, gfid));
17b94a
     }
17b94a
+
17b94a
+    return dentry;
17b94a
 }
17b94a
 
17b94a
 void
17b94a
 inode_unlink(inode_t *inode, inode_t *parent, const char *name)
17b94a
 {
17b94a
-    inode_table_t *table = NULL;
17b94a
+    inode_table_t *table;
17b94a
+    dentry_t *dentry;
17b94a
 
17b94a
-    if (!inode) {
17b94a
-        gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0, LG_MSG_INODE_NOT_FOUND,
17b94a
-                         "inode not found");
17b94a
+    if (!inode || !parent || !name)
17b94a
         return;
17b94a
-    }
17b94a
 
17b94a
     table = inode->table;
17b94a
 
17b94a
     pthread_mutex_lock(&table->lock);
17b94a
     {
17b94a
-        __inode_unlink(inode, parent, name);
17b94a
+        dentry = __inode_unlink(inode, parent, name);
17b94a
     }
17b94a
     pthread_mutex_unlock(&table->lock);
17b94a
 
17b94a
+    dentry_destroy(dentry);
17b94a
+
17b94a
     inode_table_prune(table);
17b94a
 }
17b94a
 
17b94a
@@ -1362,6 +1245,9 @@ inode_rename(inode_table_t *table, inode_t *srcdir, const char *srcname,
17b94a
              inode_t *dstdir, const char *dstname, inode_t *inode,
17b94a
              struct iatt *iatt)
17b94a
 {
17b94a
+    int hash = 0;
17b94a
+    dentry_t *dentry = NULL;
17b94a
+
17b94a
     if (!inode) {
17b94a
         gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0, LG_MSG_INODE_NOT_FOUND,
17b94a
                          "inode not found");
17b94a
@@ -1370,13 +1256,26 @@ inode_rename(inode_table_t *table, inode_t *srcdir, const char *srcname,
17b94a
 
17b94a
     table = inode->table;
17b94a
 
17b94a
+    if (dstname && strchr(dstname, '/')) {
17b94a
+        GF_ASSERT(!"inode link attempted with '/' in name");
17b94a
+        return -1;
17b94a
+    }
17b94a
+
17b94a
+    if (dstdir && dstname) {
17b94a
+        hash = hash_dentry(dstdir, dstname, table->hashsize);
17b94a
+    }
17b94a
+
17b94a
     pthread_mutex_lock(&table->lock);
17b94a
     {
17b94a
-        __inode_link(inode, dstdir, dstname, iatt);
17b94a
-        __inode_unlink(inode, srcdir, srcname);
17b94a
+        __inode_link(inode, dstdir, dstname, iatt, hash);
17b94a
+        /* pick the old dentry */
17b94a
+        dentry = __inode_unlink(inode, srcdir, srcname);
17b94a
     }
17b94a
     pthread_mutex_unlock(&table->lock);
17b94a
 
17b94a
+    /* free the old dentry */
17b94a
+    dentry_destroy(dentry);
17b94a
+
17b94a
     inode_table_prune(table);
17b94a
 
17b94a
     return 0;
17b94a
@@ -1447,12 +1346,6 @@ inode_parent(inode_t *inode, uuid_t pargfid, const char *name)
17b94a
 static int
17b94a
 __inode_has_dentry(inode_t *inode)
17b94a
 {
17b94a
-    if (!inode) {
17b94a
-        gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0, LG_MSG_INODE_NOT_FOUND,
17b94a
-                         "inode not found");
17b94a
-        return 0;
17b94a
-    }
17b94a
-
17b94a
     return !list_empty(&inode->dentry_list);
17b94a
 }
17b94a
 
17b94a
@@ -1461,6 +1354,12 @@ inode_has_dentry(inode_t *inode)
17b94a
 {
17b94a
     int dentry_present = 0;
17b94a
 
17b94a
+    if (!inode) {
17b94a
+        gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0, LG_MSG_INODE_NOT_FOUND,
17b94a
+                         "inode not found");
17b94a
+        return 0;
17b94a
+    }
17b94a
+
17b94a
     LOCK(&inode->lock);
17b94a
     {
17b94a
         dentry_present = __inode_has_dentry(inode);
17b94a
@@ -1720,7 +1619,7 @@ __inode_table_init_root(inode_table_t *table)
17b94a
     iatt.ia_ino = 1;
17b94a
     iatt.ia_type = IA_IFDIR;
17b94a
 
17b94a
-    __inode_link(root, NULL, NULL, &iatt);
17b94a
+    __inode_link(root, NULL, NULL, &iatt, 0);
17b94a
     table->root = root;
17b94a
 }
17b94a
 
17b94a
diff --git a/libglusterfs/src/libglusterfs.sym b/libglusterfs/src/libglusterfs.sym
17b94a
index 5a721e0..d060292 100644
17b94a
--- a/libglusterfs/src/libglusterfs.sym
17b94a
+++ b/libglusterfs/src/libglusterfs.sym
17b94a
@@ -357,7 +357,6 @@ default_copy_file_range
17b94a
 default_copy_file_range_cbk
17b94a
 default_copy_file_range_failure_cbk
17b94a
 default_copy_file_range_resume
17b94a
-__dentry_grep
17b94a
 dht_is_linkfile
17b94a
 dict_add
17b94a
 dict_addn
17b94a
-- 
17b94a
1.8.3.1
17b94a