From patchwork Wed Feb 8 07:16:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jingbo Xu X-Patchwork-Id: 54229 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:eb09:0:0:0:0:0 with SMTP id s9csp3307690wrn; Tue, 7 Feb 2023 23:19:36 -0800 (PST) X-Google-Smtp-Source: AK7set9h90X0ZzokR/Y9BIsS0U60cEaoM8AK9YlC6ZSmSYi58O3HbL+u58PgTWno/OxKONQ5APH8 X-Received: by 2002:aa7:8f04:0:b0:5a8:47e5:bbad with SMTP id x4-20020aa78f04000000b005a847e5bbadmr489370pfr.28.1675840776055; Tue, 07 Feb 2023 23:19:36 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1675840776; cv=none; d=google.com; s=arc-20160816; b=iPxYSoMPlC0G+WBJ1pnixWj+8+dD8cEdrg49LSW+x54DuTUX5H71hCoGTXpLyloN1L 9c1SbwcwqayXVStifSWsAcxyBVjHzExB7U4nC/z8ffmTf49cPmD8jvxpa2iK1pfAQfAG tmVxdTKSkeoowS7Gn88WFL+Ykirx0YhH8mWuAtAE34HHm5a7T/RegOKBEvk7tjyl0wgB 42ylHq/2zIroDSB6yIh4O3M/22oqp+wQv7rikkXLg1YTz+L4j6c4e9713HAupR3fgcD9 iVdVHeRHXhjYm4bHg0B+CJ10m5CcEmGHfUS35U6FUzjt4sJaFipfOeTWA8MNlmmW54EQ ai+A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=3z6Y53q8Q1Dii9Romofged574f7PbB1WxiL69hZV2H0=; b=KM9gKcy4VRulylCDhUShs7twSlDUa/KXsC7gDg5E31WKX6T0+5jHur6zTscrviwRug gK3xQ8RHu2OJtmvJ0F397m7Ou0WdmpTg4CJuCpZYaj4Of9jujniEoN0C8fG8tz6U9LQ3 4sVhNgxOEEk7hIkAM5Jix+6pH8DkK6Z3Iv31919v4s+Bep5UlNGMzHhU+PvxOS8beLcU 70MZgGGK5z62V614Efw9tquZuk8ymQK22uew0CsCEDOSp+QRqDJKuuqvZv8iLkgFkAV6 nlj9v949KJq5Xs0aQKVa7ktJXBNAOqeZDY05/FwbrTIFMYxPkEh9pBc7t4vEio/X6gGZ vOdg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=alibaba.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id o9-20020a056a00214900b0058dea7e1e6esi16164563pfk.281.2023.02.07.23.19.23; Tue, 07 Feb 2023 23:19:36 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=alibaba.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230351AbjBHHQi (ORCPT + 99 others); Wed, 8 Feb 2023 02:16:38 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46156 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230252AbjBHHQh (ORCPT ); Wed, 8 Feb 2023 02:16:37 -0500 Received: from out30-110.freemail.mail.aliyun.com (out30-110.freemail.mail.aliyun.com [115.124.30.110]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0B24E30EAD for ; Tue, 7 Feb 2023 23:16:27 -0800 (PST) X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R121e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=ay29a033018046059;MF=jefflexu@linux.alibaba.com;NM=1;PH=DS;RN=6;SR=0;TI=SMTPD_---0VbAXJP5_1675840583; Received: from localhost(mailfrom:jefflexu@linux.alibaba.com fp:SMTPD_---0VbAXJP5_1675840583) by smtp.aliyun-inc.com; Wed, 08 Feb 2023 15:16:24 +0800 From: Jingbo Xu To: xiang@kernel.org, chao@kernel.org, linux-erofs@lists.ozlabs.org, zhujia.zj@bytedance.com Cc: huyue2@coolpad.com, linux-kernel@vger.kernel.org Subject: [PATCH 2/4] erofs: maintain cookies of share domain in self-contained list Date: Wed, 8 Feb 2023 15:16:23 +0800 Message-Id: <99618b85e5802aacf498387b48c61f1307c6f1f7.1675840368.git.jefflexu@linux.alibaba.com> X-Mailer: git-send-email 2.19.1.6.gb485710b In-Reply-To: References: MIME-Version: 1.0 X-Spam-Status: No, score=-9.9 required=5.0 tests=BAYES_00, ENV_AND_HDR_SPF_MATCH,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, USER_IN_DEF_SPF_WL autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1757246417438785718?= X-GMAIL-MSGID: =?utf-8?q?1757246417438785718?= We'd better not touch sb->s_inodes list and inode->i_count directly. Let's maintain cookies of share domain in a self-contained list in erofs. Besides, relinquish cookie with the mutext held. Otherwise if a cookie is registered when the old cookie with the same name in the same domain has been removed from the list but not relinquished yet, fscache may complain "Duplicate cookie detected". Signed-off-by: Jingbo Xu Reviewed-by: Jia Zhu --- fs/erofs/fscache.c | 48 ++++++++++++++++++++++----------------------- fs/erofs/internal.h | 4 ++++ 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/fs/erofs/fscache.c b/fs/erofs/fscache.c index 03de4dc99302..2f5930e177cc 100644 --- a/fs/erofs/fscache.c +++ b/fs/erofs/fscache.c @@ -7,8 +7,11 @@ #include "internal.h" static DEFINE_MUTEX(erofs_domain_list_lock); -static DEFINE_MUTEX(erofs_domain_cookies_lock); static LIST_HEAD(erofs_domain_list); + +static DEFINE_MUTEX(erofs_domain_cookies_lock); +static LIST_HEAD(erofs_domain_cookies_list); + static struct vfsmount *erofs_pseudo_mnt; struct erofs_fscache_request { @@ -318,8 +321,6 @@ const struct address_space_operations erofs_fscache_access_aops = { static void erofs_fscache_domain_put(struct erofs_domain *domain) { - if (!domain) - return; mutex_lock(&erofs_domain_list_lock); if (refcount_dec_and_test(&domain->ref)) { list_del(&domain->list); @@ -434,6 +435,8 @@ struct erofs_fscache *erofs_fscache_acquire_cookie(struct super_block *sb, ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); if (!ctx) return ERR_PTR(-ENOMEM); + INIT_LIST_HEAD(&ctx->node); + refcount_set(&ctx->ref, 1); cookie = fscache_acquire_cookie(volume, FSCACHE_ADV_WANT_CACHE_SIZE, name, strlen(name), NULL, 0, 0); @@ -479,6 +482,7 @@ static void erofs_fscache_relinquish_cookie(struct erofs_fscache *ctx) fscache_unuse_cookie(ctx->cookie, NULL, NULL); fscache_relinquish_cookie(ctx->cookie, false); iput(ctx->inode); + iput(ctx->anon_inode); kfree(ctx->name); kfree(ctx); } @@ -511,6 +515,7 @@ struct erofs_fscache *erofs_fscache_domain_init_cookie(struct super_block *sb, ctx->domain = domain; ctx->anon_inode = inode; + list_add(&ctx->node, &erofs_domain_cookies_list); inode->i_private = ctx; refcount_inc(&domain->ref); return ctx; @@ -524,29 +529,23 @@ struct erofs_fscache *erofs_domain_register_cookie(struct super_block *sb, char *name, unsigned int flags) { - struct inode *inode; struct erofs_fscache *ctx; struct erofs_domain *domain = EROFS_SB(sb)->domain; - struct super_block *psb = erofs_pseudo_mnt->mnt_sb; mutex_lock(&erofs_domain_cookies_lock); - spin_lock(&psb->s_inode_list_lock); - list_for_each_entry(inode, &psb->s_inodes, i_sb_list) { - ctx = inode->i_private; - if (!ctx || ctx->domain != domain || strcmp(ctx->name, name)) + list_for_each_entry(ctx, &erofs_domain_cookies_list, node) { + if (ctx->domain != domain || strcmp(ctx->name, name)) continue; if (!(flags & EROFS_REG_COOKIE_NEED_NOEXIST)) { - igrab(inode); + refcount_inc(&ctx->ref); } else { erofs_err(sb, "%s already exists in domain %s", name, domain->domain_id); ctx = ERR_PTR(-EEXIST); } - spin_unlock(&psb->s_inode_list_lock); mutex_unlock(&erofs_domain_cookies_lock); return ctx; } - spin_unlock(&psb->s_inode_list_lock); ctx = erofs_fscache_domain_init_cookie(sb, name, flags); mutex_unlock(&erofs_domain_cookies_lock); return ctx; @@ -563,23 +562,22 @@ struct erofs_fscache *erofs_fscache_register_cookie(struct super_block *sb, void erofs_fscache_unregister_cookie(struct erofs_fscache *ctx) { - bool drop; - struct erofs_domain *domain; + struct erofs_domain *domain = NULL; if (!ctx) return; - domain = ctx->domain; - if (domain) { - mutex_lock(&erofs_domain_cookies_lock); - drop = atomic_read(&ctx->anon_inode->i_count) == 1; - iput(ctx->anon_inode); - mutex_unlock(&erofs_domain_cookies_lock); - if (!drop) - return; - } + if (!ctx->domain) + return erofs_fscache_relinquish_cookie(ctx); - erofs_fscache_relinquish_cookie(ctx); - erofs_fscache_domain_put(domain); + mutex_lock(&erofs_domain_cookies_lock); + if (refcount_dec_and_test(&ctx->ref)) { + domain = ctx->domain; + list_del(&ctx->node); + erofs_fscache_relinquish_cookie(ctx); + } + mutex_unlock(&erofs_domain_cookies_lock); + if (domain) + erofs_fscache_domain_put(domain); } int erofs_fscache_register_fs(struct super_block *sb) diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h index 48a2f33de15a..8358cf5f731e 100644 --- a/fs/erofs/internal.h +++ b/fs/erofs/internal.h @@ -109,7 +109,11 @@ struct erofs_fscache { struct fscache_cookie *cookie; struct inode *inode; struct inode *anon_inode; + + /* used for share domain mode */ struct erofs_domain *domain; + struct list_head node; + refcount_t ref; char *name; };