diff mbox

SUNRPC: Drop all entries left in cache_detail when destroy

Message ID 81c44c62-fa78-de51-faee-994f5592ff7b@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Kinglong Mee Feb. 5, 2017, 1:40 p.m. UTC
User always free the cache_detail after sunrpc_destroy_cache_detail(),
so, it must cleanup up entries that left in the cache_detail,
otherwise, NULL reference may be caused when using the left entries.

Signed-off-by: Kinglong Mee <kinglongmee@gmail.com>
---
 net/sunrpc/cache.c | 23 +++++++++++++++++------
 1 file changed, 17 insertions(+), 6 deletions(-)

Comments

kernel test robot Feb. 5, 2017, 2:13 p.m. UTC | #1
Hi Kinglong,

[auto build test WARNING on nfsd/nfsd-next]
[also build test WARNING on v4.10-rc6 next-20170203]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Kinglong-Mee/SUNRPC-Drop-all-entries-left-in-cache_detail-when-destroy/20170205-214442
base:   git://linux-nfs.org/~bfields/linux.git nfsd-next
config: m68k-sun3_defconfig (attached as .config)
compiler: m68k-linux-gcc (GCC) 4.9.0
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=m68k 

All warnings (new ones prefixed by >>):

   net/sunrpc/cache.c: In function 'sunrpc_destroy_cache_detail':
>> net/sunrpc/cache.c:372:3: warning: format '%d' expects argument of type 'int', but argument 2 has type 'char *' [-Wformat=]
      printk(KERN_ERR "RPC: %d entries left in %s cache\n", cd->name);
      ^
>> net/sunrpc/cache.c:372:3: warning: format '%s' expects a matching 'char *' argument [-Wformat=]

vim +372 net/sunrpc/cache.c

   356		queue_delayed_work(system_power_efficient_wq, &cache_cleaner, 0);
   357	}
   358	EXPORT_SYMBOL_GPL(sunrpc_init_cache_detail);
   359	
   360	void sunrpc_destroy_cache_detail(struct cache_detail *cd)
   361	{
   362		struct cache_head *ch = NULL;
   363		struct hlist_head *head = NULL;
   364		struct hlist_node *tmp = NULL;
   365		int i = 0;
   366	
   367		cache_purge(cd);
   368		spin_lock(&cache_list_lock);
   369		write_lock(&cd->hash_lock);
   370	
   371		if (cd->entries) {
 > 372			printk(KERN_ERR "RPC: %d entries left in %s cache\n", cd->name);
   373			for (i = 0; i < cd->hash_size; i++) {
   374				head = &cd->hash_table[i];
   375				hlist_for_each_entry_safe(ch, tmp, head, cache_list) {
   376					hlist_del_init(&ch->cache_list);
   377					set_bit(CACHE_CLEANED, &ch->flags);
   378					cache_fresh_unlocked(ch, cd);
   379					cache_put(ch, cd);
   380				}

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
kernel test robot Feb. 5, 2017, 2:14 p.m. UTC | #2
Hi Kinglong,

[auto build test WARNING on nfsd/nfsd-next]
[also build test WARNING on v4.10-rc6]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Kinglong-Mee/SUNRPC-Drop-all-entries-left-in-cache_detail-when-destroy/20170205-214442
base:   git://linux-nfs.org/~bfields/linux.git nfsd-next
config: i386-randconfig-x004-201706 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All warnings (new ones prefixed by >>):

   In file included from include/linux/printk.h:6:0,
                    from include/linux/kernel.h:13,
                    from include/linux/list.h:8,
                    from include/linux/wait.h:6,
                    from include/linux/fs.h:5,
                    from net/sunrpc/cache.c:14:
   net/sunrpc/cache.c: In function 'sunrpc_destroy_cache_detail':
>> include/linux/kern_levels.h:4:18: warning: format '%d' expects argument of type 'int', but argument 2 has type 'char *' [-Wformat=]
    #define KERN_SOH "\001"  /* ASCII Start Of Header */
                     ^
   include/linux/kern_levels.h:10:18: note: in expansion of macro 'KERN_SOH'
    #define KERN_ERR KERN_SOH "3" /* error conditions */
                     ^~~~~~~~
>> net/sunrpc/cache.c:372:10: note: in expansion of macro 'KERN_ERR'
      printk(KERN_ERR "RPC: %d entries left in %s cache\n", cd->name);
             ^~~~~~~~
   include/linux/kern_levels.h:4:18: warning: format '%s' expects a matching 'char *' argument [-Wformat=]
    #define KERN_SOH "\001"  /* ASCII Start Of Header */
                     ^
   include/linux/kern_levels.h:10:18: note: in expansion of macro 'KERN_SOH'
    #define KERN_ERR KERN_SOH "3" /* error conditions */
                     ^~~~~~~~
>> net/sunrpc/cache.c:372:10: note: in expansion of macro 'KERN_ERR'
      printk(KERN_ERR "RPC: %d entries left in %s cache\n", cd->name);
             ^~~~~~~~

vim +/KERN_ERR +372 net/sunrpc/cache.c

   356		queue_delayed_work(system_power_efficient_wq, &cache_cleaner, 0);
   357	}
   358	EXPORT_SYMBOL_GPL(sunrpc_init_cache_detail);
   359	
   360	void sunrpc_destroy_cache_detail(struct cache_detail *cd)
   361	{
   362		struct cache_head *ch = NULL;
   363		struct hlist_head *head = NULL;
   364		struct hlist_node *tmp = NULL;
   365		int i = 0;
   366	
   367		cache_purge(cd);
   368		spin_lock(&cache_list_lock);
   369		write_lock(&cd->hash_lock);
   370	
   371		if (cd->entries) {
 > 372			printk(KERN_ERR "RPC: %d entries left in %s cache\n", cd->name);
   373			for (i = 0; i < cd->hash_size; i++) {
   374				head = &cd->hash_table[i];
   375				hlist_for_each_entry_safe(ch, tmp, head, cache_list) {
   376					hlist_del_init(&ch->cache_list);
   377					set_bit(CACHE_CLEANED, &ch->flags);
   378					cache_fresh_unlocked(ch, cd);
   379					cache_put(ch, cd);
   380				}

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
diff mbox

Patch

diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index 8147e8d..a2c6fec 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -359,14 +359,28 @@  EXPORT_SYMBOL_GPL(sunrpc_init_cache_detail);
 
 void sunrpc_destroy_cache_detail(struct cache_detail *cd)
 {
+	struct cache_head *ch = NULL;
+	struct hlist_head *head = NULL;
+	struct hlist_node *tmp = NULL;
+	int i = 0;
+
 	cache_purge(cd);
 	spin_lock(&cache_list_lock);
 	write_lock(&cd->hash_lock);
+
 	if (cd->entries) {
-		write_unlock(&cd->hash_lock);
-		spin_unlock(&cache_list_lock);
-		goto out;
+		printk(KERN_ERR "RPC: %d entries left in %s cache\n", cd->name);
+		for (i = 0; i < cd->hash_size; i++) {
+			head = &cd->hash_table[i];
+			hlist_for_each_entry_safe(ch, tmp, head, cache_list) {
+				hlist_del_init(&ch->cache_list);
+				set_bit(CACHE_CLEANED, &ch->flags);
+				cache_fresh_unlocked(ch, cd);
+				cache_put(ch, cd);
+			}
+		}
 	}
+
 	if (current_detail == cd)
 		current_detail = NULL;
 	list_del_init(&cd->others);
@@ -376,9 +390,6 @@  void sunrpc_destroy_cache_detail(struct cache_detail *cd)
 		/* module must be being unloaded so its safe to kill the worker */
 		cancel_delayed_work_sync(&cache_cleaner);
 	}
-	return;
-out:
-	printk(KERN_ERR "RPC: failed to unregister %s cache\n", cd->name);
 }
 EXPORT_SYMBOL_GPL(sunrpc_destroy_cache_detail);