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