From: Chi Zhiling <chizhiling@163.com>
To: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: Namjae Jeon <linkinjeon@kernel.org>,
Sungjong Seo <sj1557.seo@samsung.com>,
Yuezhang Mo <yuezhang.mo@sony.com>,
Chi Zhiling <chizhiling@kylinos.cn>
Subject: [PATCH v2 12/13] exfat: return the start of next cache in exfat_cache_lookup
Date: Thu, 8 Jan 2026 15:59:37 +0800 [thread overview]
Message-ID: <20260108075938.360282-2-chizhiling@163.com> (raw)
In-Reply-To: <20260108075938.360282-1-chizhiling@163.com>
From: Chi Zhiling <chizhiling@kylinos.cn>
Change exfat_cache_lookup to return the cluster number of the last
cluster before the next cache (i.e., the end of the current cache range)
or the given 'end' if there is no next cache. This allows the caller to
know whether the next cluster after the current cache is cached.
The function signature is changed to accept an 'end' parameter, which
is the upper bound of the search range. The function now stops early
if it finds a cache that starts within the current cache's tail, meaning
caches are contiguous. The return value is the cluster number at which
the next cache starts (minus one) or the original 'end' if no next cache
is found.
The new behavior is illustrated as follows:
cache: [ccccccc-------ccccccccc]
search: [..................]
return: ^
Signed-off-by: Chi Zhiling <chizhiling@kylinos.cn>
---
fs/exfat/cache.c | 49 ++++++++++++++++++++++++++++++++++++------------
1 file changed, 37 insertions(+), 12 deletions(-)
diff --git a/fs/exfat/cache.c b/fs/exfat/cache.c
index 73147e153c2c..5cdeac014a3d 100644
--- a/fs/exfat/cache.c
+++ b/fs/exfat/cache.c
@@ -80,41 +80,66 @@ static inline void exfat_cache_update_lru(struct inode *inode,
list_move(&cache->cache_list, &ei->cache_lru);
}
-static unsigned int exfat_cache_lookup(struct inode *inode,
- unsigned int fclus, struct exfat_cache_id *cid,
+/*
+ * Find the cache that covers or precedes 'fclus' and return the last
+ * cluster before the next cache range.
+ */
+static inline unsigned int
+exfat_cache_lookup(struct inode *inode, struct exfat_cache_id *cid,
+ unsigned int fclus, unsigned int end,
unsigned int *cached_fclus, unsigned int *cached_dclus)
{
struct exfat_inode_info *ei = EXFAT_I(inode);
static struct exfat_cache nohit = { .fcluster = 0, };
struct exfat_cache *hit = &nohit, *p;
- unsigned int offset = EXFAT_EOF_CLUSTER;
+ unsigned int tail = 0; /* End boundary of hit cache */
+ /*
+ * Search range [fclus, end]. Stop early if:
+ * 1. Cache covers entire range, or
+ * 2. Next cache starts at current cache tail
+ */
spin_lock(&ei->cache_lru_lock);
list_for_each_entry(p, &ei->cache_lru, cache_list) {
/* Find the cache of "fclus" or nearest cache. */
- if (p->fcluster <= fclus && hit->fcluster <= p->fcluster) {
+ if (p->fcluster <= fclus) {
+ if (p->fcluster < hit->fcluster)
+ continue;
+
hit = p;
- if (hit->fcluster + hit->nr_contig < fclus) {
- offset = hit->nr_contig;
- } else {
- offset = fclus - hit->fcluster;
+ tail = hit->fcluster + hit->nr_contig;
+
+ /* Current cache covers [fclus, end] completely */
+ if (tail >= end)
+ break;
+ } else if (p->fcluster <= end) {
+ end = p->fcluster - 1;
+
+ /*
+ * If we have a hit and next cache starts within/at
+ * its tail, caches are contiguous, stop searching.
+ */
+ if (tail && tail >= end)
break;
- }
}
}
if (hit != &nohit) {
- exfat_cache_update_lru(inode, hit);
+ unsigned int offset;
+ exfat_cache_update_lru(inode, hit);
cid->id = ei->cache_valid_id;
cid->nr_contig = hit->nr_contig;
cid->fcluster = hit->fcluster;
cid->dcluster = hit->dcluster;
+
+ offset = min(cid->nr_contig, fclus - cid->fcluster);
*cached_fclus = cid->fcluster + offset;
*cached_dclus = cid->dcluster + offset;
}
spin_unlock(&ei->cache_lru_lock);
- return offset;
+ /* Return next cache start or 'end' if no more caches */
+ return end;
}
static struct exfat_cache *exfat_cache_merge(struct inode *inode,
@@ -260,7 +285,7 @@ int exfat_get_cluster(struct inode *inode, unsigned int cluster,
return 0;
cache_init(&cid, fclus, *dclus);
- exfat_cache_lookup(inode, cluster, &cid, &fclus, dclus);
+ exfat_cache_lookup(inode, &cid, cluster, cluster, &fclus, dclus);
if (fclus == cluster)
return 0;
--
2.43.0
next prev parent reply other threads:[~2026-01-08 8:00 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-08 7:49 [PATCH v2 00/13] Enable multi-cluster fetching for exfat_get_block Chi Zhiling
2026-01-08 7:49 ` [PATCH v2 01/13] exfat: add cache option for __exfat_ent_get Chi Zhiling
2026-01-08 7:49 ` [PATCH v2 02/13] exfat: support reuse buffer head for exfat_ent_get Chi Zhiling
2026-01-08 7:49 ` [PATCH v2 03/13] exfat: improve exfat_count_num_clusters Chi Zhiling
2026-01-08 7:49 ` [PATCH v2 04/13] exfat: improve exfat_find_last_cluster Chi Zhiling
2026-01-08 7:49 ` [PATCH v2 05/13] exfat: remove the check for infinite cluster chain loop Chi Zhiling
2026-01-08 7:49 ` [PATCH v2 06/13] exfat: remove the unreachable warning for cache miss cases Chi Zhiling
2026-01-08 7:49 ` [PATCH v2 07/13] exfat: reduce the number of parameters for exfat_get_cluster() Chi Zhiling
2026-01-08 7:49 ` [PATCH v2 08/13] exfat: reuse cache to improve exfat_get_cluster Chi Zhiling
2026-01-08 7:49 ` [PATCH v2 09/13] exfat: remove handling of non-file types in exfat_map_cluster Chi Zhiling
2026-01-08 7:49 ` [PATCH v2 10/13] exfat: support multi-cluster for exfat_map_cluster Chi Zhiling
2026-01-13 6:37 ` Yuezhang.Mo
2026-01-13 8:53 ` Chi Zhiling
2026-01-13 10:26 ` Yuezhang.Mo
2026-01-14 3:07 ` Chi Zhiling
2026-01-08 7:59 ` [PATCH v2 11/13] exfat: tweak cluster cache to support zero offset Chi Zhiling
2026-01-08 7:59 ` Chi Zhiling [this message]
2026-01-08 7:59 ` [PATCH v2 13/13] exfat: support multi-cluster for exfat_get_cluster Chi Zhiling
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260108075938.360282-2-chizhiling@163.com \
--to=chizhiling@163.com \
--cc=chizhiling@kylinos.cn \
--cc=linkinjeon@kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=sj1557.seo@samsung.com \
--cc=yuezhang.mo@sony.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®