Fixes memory leak with hashtable_iter
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 22 Apr 2011 21:02:20 +0000 (14:02 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 3 Nov 2011 00:36:01 +0000 (17:36 -0700)
Lots of ughs with this.  Had they not typedef'd, it might have been more
obvious.  The best way would be to have the caller provide the memory
too, so we can use stack vars, but whatever.  3rd party code...

Also changed the remaining two users to use hash_for_each.

kern/include/hashtable.h
kern/src/hashtable.c
kern/src/monitor.c
kern/src/resource.c

index 20804fb..2e79a1c 100644 (file)
@@ -235,7 +235,7 @@ typedef struct hashtable_itr {
 } hashtable_itr_t;
 
 /*****************************************************************************/
-/* hashtable_iterator
+/* hashtable_iterator.  Be sure to kfree this when you are done.
  */
 
 hashtable_itr_t *
index d8fc1d8..4ff6ee8 100644 (file)
@@ -276,7 +276,8 @@ hashtable_destroy(hashtable_t *h)
 }
 
 /*****************************************************************************/
-/* hashtable_iterator    - iterator constructor
+/* hashtable_iterator    - iterator constructor, be sure to kfree this when
+ * you're done.
  *
  * If the htable isn't empty, e and index will refer to the first entry. */
 
@@ -428,11 +429,12 @@ hashtable_iterator_search(hashtable_itr_t *itr,
 void hash_for_each(struct hashtable *hash, void func(void*))
 {
        if (hashtable_count(hash)) {
-               hashtable_itr_t *iter = hashtable_iterator(hash);
+               struct hashtable_itr *iter = hashtable_iterator(hash);
                do {
                        void *item = hashtable_iterator_value(iter);
                        func(item);
                } while (hashtable_iterator_advance(iter));
+               kfree(iter);
        }
 }
 
@@ -441,11 +443,12 @@ void hash_for_each(struct hashtable *hash, void func(void*))
 void hash_for_each_remove(struct hashtable *hash, void func(void*))
 {
        if (hashtable_count(hash)) {
-               hashtable_itr_t *iter = hashtable_iterator(hash);
+               struct hashtable_itr *iter = hashtable_iterator(hash);
                do {
                        void *item = hashtable_iterator_value(iter);
                        func(item);
                } while (hashtable_iterator_remove(iter));
+               kfree(iter);
        }
 }
 
index 8d129dd..1dc1c9a 100644 (file)
@@ -810,16 +810,16 @@ int mon_fs(int argc, char *NTS *NT COUNT(argc) argv, trapframe_t *tf)
                printk("Dentry Cache:\n----------------------------\n");
                TAILQ_FOREACH(sb, &super_blocks, s_list) {
                        printk("Superblock for %s\n", sb->s_name);
-                       if (hashtable_count(sb->s_dcache)) {
-                               hashtable_itr_t *dcache_i = hashtable_iterator(sb->s_dcache);
-                               printk("DENTRY     FLAGS      REFCNT NAME\n");
-                               printk("--------------------------------\n");
-                               do {
-                                       struct dentry *d_i = hashtable_iterator_value(dcache_i);
-                                       printk("%08p %08p %02d     %s\n", d_i, d_i->d_flags,
-                                              kref_refcnt(&d_i->d_kref), d_i->d_name.name);
-                               } while (hashtable_iterator_advance(dcache_i));
+                       printk("DENTRY     FLAGS      REFCNT NAME\n");
+                       printk("--------------------------------\n");
+                       /* Hash helper */
+                       void print_dcache_entry(void *item)
+                       {
+                               struct dentry *d_i = (struct dentry*)item;
+                               printk("%08p %08p %02d     %s\n", d_i, d_i->d_flags,
+                                      kref_refcnt(&d_i->d_kref), d_i->d_name.name);
                        }
+                       hash_for_each(sb->s_dcache, print_dcache_entry);
                }
                if (argc < 3)
                        return 0;
index 96c02bc..76bf164 100644 (file)
@@ -235,12 +235,12 @@ void print_resources(struct proc *p)
 
 void print_all_resources(void)
 {
-       spin_lock(&pid_hash_lock);
-       if (hashtable_count(pid_hash)) {
-               hashtable_itr_t *phtable_i = hashtable_iterator(pid_hash);
-               do {
-                       print_resources(hashtable_iterator_value(phtable_i));
-               } while (hashtable_iterator_advance(phtable_i));
+       /* Hash helper */
+       void __print_resources(void *item)
+       {
+               print_resources((struct proc*)item);
        }
+       spin_lock(&pid_hash_lock);
+       hash_for_each(pid_hash, __print_resources);
        spin_unlock(&pid_hash_lock);
 }