summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/debugging/statedump.md3
-rw-r--r--libglusterfs/src/inode.c76
-rw-r--r--libglusterfs/src/inode.h4
3 files changed, 67 insertions, 16 deletions
diff --git a/doc/debugging/statedump.md b/doc/debugging/statedump.md
index f34a5c3436a..18437f1144c 100644
--- a/doc/debugging/statedump.md
+++ b/doc/debugging/statedump.md
@@ -215,6 +215,7 @@ nlookup=13 #Number of times lookups happened from the client or from fuse kernel
fd-count=4 #Number of fds opened on the inode
ref=11 #Number of refs taken on the inode
ia_type=1 #Type of the inode. This should be changed to some string :-(
+Ref by xl:.patchy-md-cache=11 #Further this there will be a list of xlators, and the ref count taken by each of them on this inode at the time of statedump
[conn.1.bound_xl./data/brick01a/homegfs.lru.1] #1st inode in lru list. Note that ref count is zero for these inodes.
gfid=5114574e-69bc-412b-9e52-f13ff087c6fc
@@ -222,6 +223,8 @@ nlookup=5
fd-count=0
ref=0
ia_type=2
+Ref by xl:.fuse=1
+Ref by xl:.patchy-client-0=-1
```
###Inode context
For each inode per xlator some context could be stored. This context can also be printed in the statedump. Here is the inode ctx of locks xlator
diff --git a/libglusterfs/src/inode.c b/libglusterfs/src/inode.c
index 841f0b63f16..d39a2194921 100644
--- a/libglusterfs/src/inode.c
+++ b/libglusterfs/src/inode.c
@@ -324,7 +324,7 @@ __inode_ctx_free (inode_t *inode)
}
for (index = 0; index < inode->table->xl->graph->xl_count; index++) {
- if (inode->_ctx[index].xl_key) {
+ if (inode->_ctx[index].value1 || inode->_ctx[index].value2) {
xl = (xlator_t *)(long)inode->_ctx[index].xl_key;
old_THIS = THIS;
THIS = xl;
@@ -447,12 +447,40 @@ __inode_retire (inode_t *inode)
}
+static int
+__inode_get_xl_index (inode_t *inode, xlator_t *xlator)
+{
+ int set_idx = -1;
+ int index = 0;
+
+ for (index = 0; index < inode->table->ctxcount; index++) {
+ if (!inode->_ctx[index].xl_key) {
+ if (set_idx == -1)
+ set_idx = index;
+ /* dont break, to check if key already exists
+ further on */
+ }
+ if (inode->_ctx[index].xl_key == xlator) {
+ set_idx = index;
+ break;
+ }
+ }
+
+ return set_idx;
+}
+
+
static inode_t *
__inode_unref (inode_t *inode)
{
+ int index = 0;
+ xlator_t *this = NULL;
+
if (!inode)
return NULL;
+ this = THIS;
+
/*
* Root inode should always be in active list of inode table. So unrefs
* on root inode are no-ops.
@@ -464,6 +492,12 @@ __inode_unref (inode_t *inode)
--inode->ref;
+ index = __inode_get_xl_index (inode, this);
+ if (index >= 0) {
+ inode->_ctx[index].xl_key = this;
+ inode->_ctx[index].ref--;
+ }
+
if (!inode->ref) {
inode->table->active_size--;
@@ -480,9 +514,14 @@ __inode_unref (inode_t *inode)
static inode_t *
__inode_ref (inode_t *inode)
{
+ int index = 0;
+ xlator_t *this = NULL;
+
if (!inode)
return NULL;
+ this = THIS;
+
if (!inode->ref) {
inode->table->lru_size--;
__inode_activate (inode);
@@ -501,6 +540,12 @@ __inode_ref (inode_t *inode)
inode->ref++;
+ index = __inode_get_xl_index (inode, this);
+ if (index >= 0) {
+ inode->_ctx[index].xl_key = this;
+ inode->_ctx[index].ref++;
+ }
+
return inode;
}
@@ -1935,25 +1980,12 @@ __inode_ctx_set2 (inode_t *inode, xlator_t *xlator, uint64_t *value1_p,
uint64_t *value2_p)
{
int ret = 0;
- int index = 0;
int set_idx = -1;
if (!inode || !xlator || !inode->_ctx)
return -1;
- for (index = 0; index < inode->table->ctxcount; index++) {
- if (!inode->_ctx[index].xl_key) {
- if (set_idx == -1)
- set_idx = index;
- /* dont break, to check if key already exists
- further on */
- }
- if (inode->_ctx[index].xl_key == xlator) {
- set_idx = index;
- break;
- }
- }
-
+ set_idx = __inode_get_xl_index (inode, xlator);
if (set_idx == -1) {
ret = -1;
goto out;;
@@ -2313,11 +2345,14 @@ inode_dump (inode_t *inode, char *prefix)
int i = 0;
fd_t *fd = NULL;
struct _inode_ctx *inode_ctx = NULL;
- struct list_head fd_list;
+ struct list_head fd_list;
+ int ref = 0;
+ char key[GF_DUMP_MAX_BUF_LEN];
if (!inode)
return;
+ memset(key, 0, sizeof(key));
INIT_LIST_HEAD (&fd_list);
ret = TRY_LOCK(&inode->lock);
@@ -2342,6 +2377,15 @@ inode_dump (inode_t *inode, char *prefix)
for (i = 0; i < inode->table->ctxcount;
i++) {
inode_ctx[i] = inode->_ctx[i];
+ xl = inode_ctx[i].xl_key;
+ ref = inode_ctx[i].ref;
+ if (ref != 0 && xl) {
+ gf_proc_dump_build_key (key,
+ "ref_by_xl:",
+ "%s",
+ xl->name);
+ gf_proc_dump_write (key, "%d", ref);
+ }
}
}
diff --git a/libglusterfs/src/inode.h b/libglusterfs/src/inode.h
index 5289b15bca6..cdc2095a0e8 100644
--- a/libglusterfs/src/inode.h
+++ b/libglusterfs/src/inode.h
@@ -81,6 +81,10 @@ struct _inode_ctx {
uint64_t value2;
void *ptr2;
};
+ int ref; /* This is for debugging inode ref leaks,
+ basically helps in identifying the xlator
+ causing th ref leak, it is printed in
+ statedump */
};
struct _inode {