From patchwork Wed Feb 8 01:54:33 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kinglong Mee X-Patchwork-Id: 9561591 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 00D4A60547 for ; Wed, 8 Feb 2017 01:54:56 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E8496283F6 for ; Wed, 8 Feb 2017 01:54:55 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DD49928490; Wed, 8 Feb 2017 01:54:55 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.3 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7779E283F6 for ; Wed, 8 Feb 2017 01:54:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932913AbdBHByy (ORCPT ); Tue, 7 Feb 2017 20:54:54 -0500 Received: from mail-io0-f193.google.com ([209.85.223.193]:33487 "EHLO mail-io0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932282AbdBHByw (ORCPT ); Tue, 7 Feb 2017 20:54:52 -0500 Received: by mail-io0-f193.google.com with SMTP id 101so14607691iom.0 for ; Tue, 07 Feb 2017 17:54:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=to:cc:from:subject:message-id:date:user-agent:mime-version :content-transfer-encoding; bh=zkPWoL1WSOfIA6cjt4keADMc/Dt6L119ddfwLvPjihU=; b=QOLHebv91xv9CDx1/XC4ZnbHVhUx0df3FmVs6EWTwyjdsgY/sT7XDq5J87KIQk8cqW 7r99UrPEfXvYMHbV7EX14nDfcTIeByaLNOIKmPD55VdoaFZCIoqGE3T+8FjtoGlOKOFc odaHXnNsSh/uzEA//zfdcq/parNrNLlAHSvBGXPTTlNFk36+TfHtYALX2JbXRZVB/5G3 gbbQgOismVkZ+G94unAO8cmFy9UjLNyE8ZmdzxMDdwW8tdhGAvFozWG1mzrGpVtZm23l Ge+NQ5TRq6z3K6NLPch36Pkz3YBAtX0TqwEN5Dg9k6/3JBtYW6bOkEkD1jXId8L3TpjC xMzQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:to:cc:from:subject:message-id:date:user-agent :mime-version:content-transfer-encoding; bh=zkPWoL1WSOfIA6cjt4keADMc/Dt6L119ddfwLvPjihU=; b=Cp5Pya9M2KMM621FgR5RkpxIIp5EXNMoebJG71QJbGzTrRdIZU4HLrp3MepiS/ZL7K kcwkDf5S0OkEmE8aBYXs0KYmtfisGEbgi34jjuv7L/hUzuye7KTJY3RxWgoM55H6QcFp fcAtf3tBJL0t0Sk0tHQQjpaYBDTyRoJn3o/0repCif+bLkjBlbFYO5Empm+tfnWePCRv qZ+m1pIT1AvDdE0gPoLPAFCCmIQCd4mb2dx/Zji9fJGW1lBJ7MlTtSfBBZXLNmJbvukC 1j7kpBDrTCZicTr0u9I3UWybUNeMLKuHano4g7EOaTiFTLpb/c3lLc3ZwPjXTZiVxiz+ R5qQ== X-Gm-Message-State: AMke39n6gDF8EGySbY8LZG4xbc/FTl++NP+OmV7VMOhvAmi8fmSaXuVG7XQzXXey07Edlw== X-Received: by 10.107.6.210 with SMTP id f79mr7699534ioi.140.1486518881963; Tue, 07 Feb 2017 17:54:41 -0800 (PST) Received: from [192.168.0.107] ([182.139.118.29]) by smtp.gmail.com with ESMTPSA id m77sm251912ita.16.2017.02.07.17.54.39 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 07 Feb 2017 17:54:41 -0800 (PST) To: "J. Bruce Fields" , linux-nfs@vger.kernel.org Cc: Trond Myklebust , NeilBrown , Kinglong Mee From: Kinglong Mee Subject: [PATCH 1/2 v3] SUNRPC: Drop all entries from cache_detail when cache_purge() Message-ID: <99f0c881-f7bc-e548-8694-c68f11afde68@gmail.com> Date: Wed, 8 Feb 2017 09:54:33 +0800 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.7.0 MIME-Version: 1.0 Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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. Also, NeriBrown suggests "write a stand-alone cache_purge()." v3, move the cache_fresh_unlocked() out of write lock, v2, a stand-alone cache_purge(), not only for sunrpc_destroy_cache_detail Signed-off-by: Kinglong Mee Reviewed-by: NeilBrown --- net/sunrpc/cache.c | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c index 8147e8d..f0a7390 100644 --- a/net/sunrpc/cache.c +++ b/net/sunrpc/cache.c @@ -362,11 +362,6 @@ void sunrpc_destroy_cache_detail(struct cache_detail *cd) 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; - } if (current_detail == cd) current_detail = NULL; list_del_init(&cd->others); @@ -376,9 +371,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); @@ -497,13 +489,32 @@ EXPORT_SYMBOL_GPL(cache_flush); void cache_purge(struct cache_detail *detail) { - time_t now = seconds_since_boot(); - if (detail->flush_time >= now) - now = detail->flush_time + 1; - /* 'now' is the maximum value any 'last_refresh' can have */ - detail->flush_time = now; - detail->nextcheck = seconds_since_boot(); - cache_flush(); + struct cache_head *ch = NULL; + struct hlist_head *head = NULL; + struct hlist_node *tmp = NULL; + int i = 0; + + write_lock(&detail->hash_lock); + if (!detail->entries) { + write_unlock(&detail->hash_lock); + return; + } + + dprintk("RPC: %d entries in %s cache\n", detail->entries, detail->name); + for (i = 0; i < detail->hash_size; i++) { + head = &detail->hash_table[i]; + hlist_for_each_entry_safe(ch, tmp, head, cache_list) { + hlist_del_init(&ch->cache_list); + detail->entries--; + + set_bit(CACHE_CLEANED, &ch->flags); + write_unlock(&detail->hash_lock); + cache_fresh_unlocked(ch, detail); + cache_put(ch, detail); + write_lock(&detail->hash_lock); + } + } + write_unlock(&detail->hash_lock); } EXPORT_SYMBOL_GPL(cache_purge);