From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C35A247F77A; Thu, 20 Aug 2026 17:56:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787248570; cv=none; b=u9EBb4J183+P+8Lp6l4FMrNJpDPyFay6PJMmdieVO3J2/FO5+X+CgiZaS7Va3yndFw//b+jIa2VrKugnHiVHtX0FBK6iEx+afKcAB9fIq0FJmpT/xoF9ynJX+MGwN6fVwemasw2nX7VEnHv6/bFluON6RQNc5MabTN62BxFQ1vE= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787248570; c=relaxed/simple; bh=QtVTvK+B5ccsUUHnSl6EfjJpdlEoNmlWtTFdOaPmirQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=fBvPAQa2gdKrb0v0mceJfR+XuxCucaATZ/nb5JxQ7iFQqDj9qIXzYWThvFGzU4dctAEnD5BIJtHrALGdaGfLHkqbkm8IYXG44KA7MCh7lkSpPXls2zUfbEBvqjGEn8NY1b4YYh9bEHSP9uQtY6DnvAd1h3G7mfAZXSaLDmcx81c= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=Y3GoYp+Z; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="Y3GoYp+Z" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2CEEF1F000E9; Thu, 20 Aug 2026 17:56:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1787248568; bh=WnqXsSMsfWszZtdIGJ+23ya2Y6KDHTQsH64pMpptkD0=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=Y3GoYp+Z4ao2KbzRXOO6vHyAmUWkBZqJDNLcmYX3DuUICVnN/Qk+R3ds9Ul1YH+X3 cBTxvoRt5m0a5O8hueWGJ0xYndLU2K3RDivgu0ZOqDYhOZp3IwH7zso9SMddYhzVmK RdrnFUsB+rrb32H7bqPr8wRQWfzwI+ZNiACButEA= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Jingbo Xu , Jia Zhu , Gao Xiang , Sasha Levin Subject: [PATCH 6.1 234/303] erofs: maintain cookies of share domain in self-contained list Date: Thu, 20 Aug 2026 16:56:10 +0200 Message-ID: <20260820145300.482712120@linuxfoundation.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260820145253.200766705@linuxfoundation.org> References: <20260820145253.200766705@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.1-stable review patch. If anyone has any objections, please let me know. ------------------ From: Jingbo Xu [ Upstream commit 2dfb8c3b122fad4504a92c34ba68f2fe4444b3f6 ] 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 mutex 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 Link: https://lore.kernel.org/r/20230209063913.46341-3-jefflexu@linux.alibaba.com Signed-off-by: Gao Xiang Stable-dep-of: c9b47e6b2311 ("erofs: cap LZMA stream pool size") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- fs/erofs/fscache.c | 44 ++++++++++++++++++++------------------------ fs/erofs/internal.h | 4 ++++ 2 files changed, 24 insertions(+), 24 deletions(-) --- a/fs/erofs/fscache.c +++ b/fs/erofs/fscache.c @@ -9,6 +9,7 @@ static DEFINE_MUTEX(erofs_domain_list_lock); static DEFINE_MUTEX(erofs_domain_cookies_lock); static LIST_HEAD(erofs_domain_list); +static LIST_HEAD(erofs_domain_cookies_list); static struct vfsmount *erofs_pseudo_mnt; static struct netfs_io_request *erofs_fscache_alloc_request(struct address_space *mapping, @@ -389,8 +390,6 @@ const struct address_space_operations er 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); @@ -505,6 +504,8 @@ struct erofs_fscache *erofs_fscache_acqu 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); @@ -550,6 +551,7 @@ static void erofs_fscache_relinquish_coo 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); } @@ -582,6 +584,7 @@ struct erofs_fscache *erofs_fscache_doma 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; @@ -595,29 +598,23 @@ struct erofs_fscache *erofs_domain_regis 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; @@ -634,23 +631,22 @@ struct erofs_fscache *erofs_fscache_regi 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) --- a/fs/erofs/internal.h +++ b/fs/erofs/internal.h @@ -108,7 +108,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; };