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