12a457
From 10585bbac1d1b868599e8262a618e90a26f6558c Mon Sep 17 00:00:00 2001
12a457
From: Soumya Koduri <skoduri@redhat.com>
12a457
Date: Wed, 13 Apr 2016 12:50:49 +0530
12a457
Subject: [PATCH 102/104] inode: Always fetch first entry from the inode lists during inode_table_destroy
12a457
12a457
In inode_table_destroy, we iterate through lru and active lists
12a457
to move the entries to purge list so that they can be destroyed
12a457
during inode_table_prune.
12a457
12a457
But if used "list_for_each_entry" or "list_for_each_entry_safe"
12a457
to iterate, we could end up accessing the entries which may have
12a457
got moved to different(purge) lists in the process and can result
12a457
in either infinite loop or crash. The safe approach seems to fetch
12a457
the first entry of the list in each iteration till it gets empty.
12a457
12a457
This is backport of below fix -
12a457
        http://review.gluster.org/13987 (master)
12a457
        http://review.gluster.org/#/c/14089/ (release-3.7)
12a457
12a457
Change-Id: I24a18881833bd9419c2d8e5e8807bc71ec396479
12a457
BUG: 1325975
12a457
Signed-off-by: Soumya Koduri <skoduri@redhat.com>
12a457
Reviewed-on: http://review.gluster.org/13987
12a457
Reviewed-by: Kaleb KEITHLEY <kkeithle@redhat.com>
12a457
Reviewed-by: Niels de Vos <ndevos@redhat.com>
12a457
Reviewed-by: Jeff Darcy <jdarcy@redhat.com>
12a457
Reviewed-on: https://code.engineering.redhat.com/gerrit/73330
12a457
Tested-by: Niels de Vos <ndevos@redhat.com>
12a457
---
12a457
 libglusterfs/src/inode.c |   16 ++++++++--------
12a457
 1 files changed, 8 insertions(+), 8 deletions(-)
12a457
12a457
diff --git a/libglusterfs/src/inode.c b/libglusterfs/src/inode.c
12a457
index 097b6d3..c45e7d1 100644
12a457
--- a/libglusterfs/src/inode.c
12a457
+++ b/libglusterfs/src/inode.c
12a457
@@ -1731,7 +1731,7 @@ inode_table_destroy_all (glusterfs_ctx_t *ctx) {
12a457
 void
12a457
 inode_table_destroy (inode_table_t *inode_table) {
12a457
 
12a457
-        inode_t  *tmp = NULL, *trav = NULL;
12a457
+        inode_t  *trav = NULL;
12a457
 
12a457
         if (inode_table == NULL)
12a457
                 return;
12a457
@@ -1771,15 +1771,15 @@ inode_table_destroy (inode_table_t *inode_table) {
12a457
                  * traverse the lru list till it gets empty.
12a457
                  */
12a457
                 while (!list_empty (&inode_table->lru)) {
12a457
-                        list_for_each_entry_safe (trav, tmp, &inode_table->lru,
12a457
-                                                  list) {
12a457
-                                __inode_forget (trav, 0);
12a457
-                                __inode_retire (trav);
12a457
-                        }
12a457
+                        trav = list_first_entry (&inode_table->lru,
12a457
+                                                 inode_t, list);
12a457
+                        __inode_forget (trav, 0);
12a457
+                        __inode_retire (trav);
12a457
                 }
12a457
 
12a457
-                list_for_each_entry_safe (trav, tmp, &inode_table->active,
12a457
-                                          list) {
12a457
+                while (!list_empty (&inode_table->active)) {
12a457
+                        trav = list_first_entry (&inode_table->active,
12a457
+                                                 inode_t, list);
12a457
                         /* forget and unref the inode to retire and add it to
12a457
                          * purge list. By this time there should not be any
12a457
                          * inodes present in the active list except for root
12a457
-- 
12a457
1.7.1
12a457