diff options
-rw-r--r-- | doc/debugging/statedump.md | 3 | ||||
-rw-r--r-- | libglusterfs/src/inode.c | 76 | ||||
-rw-r--r-- | libglusterfs/src/inode.h | 4 |
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 { |