1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * Written 1992,1993 by Werner Almesberger
7 * Mar 1999. AV. Changed cache, so that it uses the starting cluster instead
9 * May 1999. AV. Fixed the bogosity with FAT32 (read "FAT28"). Fscking lusers.
10 * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
13 #include <linux/slab.h>
14 #include <linux/unaligned.h>
15 #include <linux/buffer_head.h>
17 #include "exfat_raw.h"
20 #define EXFAT_MAX_CACHE 16
23 struct list_head cache_list
;
24 unsigned int nr_contig
; /* number of contiguous clusters */
25 unsigned int fcluster
; /* cluster number in the file. */
26 unsigned int dcluster
; /* cluster number on disk. */
29 struct exfat_cache_id
{
31 unsigned int nr_contig
;
32 unsigned int fcluster
;
33 unsigned int dcluster
;
36 static struct kmem_cache
*exfat_cachep
;
38 static void exfat_cache_init_once(void *c
)
40 struct exfat_cache
*cache
= (struct exfat_cache
*)c
;
42 INIT_LIST_HEAD(&cache
->cache_list
);
45 int exfat_cache_init(void)
47 exfat_cachep
= kmem_cache_create("exfat_cache",
48 sizeof(struct exfat_cache
),
49 0, SLAB_RECLAIM_ACCOUNT
,
50 exfat_cache_init_once
);
56 void exfat_cache_shutdown(void)
60 kmem_cache_destroy(exfat_cachep
);
63 static inline struct exfat_cache
*exfat_cache_alloc(void)
65 return kmem_cache_alloc(exfat_cachep
, GFP_NOFS
);
68 static inline void exfat_cache_free(struct exfat_cache
*cache
)
70 WARN_ON(!list_empty(&cache
->cache_list
));
71 kmem_cache_free(exfat_cachep
, cache
);
74 static inline void exfat_cache_update_lru(struct inode
*inode
,
75 struct exfat_cache
*cache
)
77 struct exfat_inode_info
*ei
= EXFAT_I(inode
);
79 if (ei
->cache_lru
.next
!= &cache
->cache_list
)
80 list_move(&cache
->cache_list
, &ei
->cache_lru
);
83 static unsigned int exfat_cache_lookup(struct inode
*inode
,
84 unsigned int fclus
, struct exfat_cache_id
*cid
,
85 unsigned int *cached_fclus
, unsigned int *cached_dclus
)
87 struct exfat_inode_info
*ei
= EXFAT_I(inode
);
88 static struct exfat_cache nohit
= { .fcluster
= 0, };
89 struct exfat_cache
*hit
= &nohit
, *p
;
90 unsigned int offset
= EXFAT_EOF_CLUSTER
;
92 spin_lock(&ei
->cache_lru_lock
);
93 list_for_each_entry(p
, &ei
->cache_lru
, cache_list
) {
94 /* Find the cache of "fclus" or nearest cache. */
95 if (p
->fcluster
<= fclus
&& hit
->fcluster
< p
->fcluster
) {
97 if (hit
->fcluster
+ hit
->nr_contig
< fclus
) {
98 offset
= hit
->nr_contig
;
100 offset
= fclus
- hit
->fcluster
;
106 exfat_cache_update_lru(inode
, hit
);
108 cid
->id
= ei
->cache_valid_id
;
109 cid
->nr_contig
= hit
->nr_contig
;
110 cid
->fcluster
= hit
->fcluster
;
111 cid
->dcluster
= hit
->dcluster
;
112 *cached_fclus
= cid
->fcluster
+ offset
;
113 *cached_dclus
= cid
->dcluster
+ offset
;
115 spin_unlock(&ei
->cache_lru_lock
);
120 static struct exfat_cache
*exfat_cache_merge(struct inode
*inode
,
121 struct exfat_cache_id
*new)
123 struct exfat_inode_info
*ei
= EXFAT_I(inode
);
124 struct exfat_cache
*p
;
126 list_for_each_entry(p
, &ei
->cache_lru
, cache_list
) {
127 /* Find the same part as "new" in cluster-chain. */
128 if (p
->fcluster
== new->fcluster
) {
129 if (new->nr_contig
> p
->nr_contig
)
130 p
->nr_contig
= new->nr_contig
;
137 static void exfat_cache_add(struct inode
*inode
,
138 struct exfat_cache_id
*new)
140 struct exfat_inode_info
*ei
= EXFAT_I(inode
);
141 struct exfat_cache
*cache
, *tmp
;
143 if (new->fcluster
== EXFAT_EOF_CLUSTER
) /* dummy cache */
146 spin_lock(&ei
->cache_lru_lock
);
147 if (new->id
!= EXFAT_CACHE_VALID
&&
148 new->id
!= ei
->cache_valid_id
)
149 goto unlock
; /* this cache was invalidated */
151 cache
= exfat_cache_merge(inode
, new);
153 if (ei
->nr_caches
< EXFAT_MAX_CACHE
) {
155 spin_unlock(&ei
->cache_lru_lock
);
157 tmp
= exfat_cache_alloc();
159 spin_lock(&ei
->cache_lru_lock
);
161 spin_unlock(&ei
->cache_lru_lock
);
165 spin_lock(&ei
->cache_lru_lock
);
166 cache
= exfat_cache_merge(inode
, new);
169 exfat_cache_free(tmp
);
174 struct list_head
*p
= ei
->cache_lru
.prev
;
176 cache
= list_entry(p
,
177 struct exfat_cache
, cache_list
);
179 cache
->fcluster
= new->fcluster
;
180 cache
->dcluster
= new->dcluster
;
181 cache
->nr_contig
= new->nr_contig
;
184 exfat_cache_update_lru(inode
, cache
);
186 spin_unlock(&ei
->cache_lru_lock
);
190 * Cache invalidation occurs rarely, thus the LRU chain is not updated. It
191 * fixes itself after a while.
193 static void __exfat_cache_inval_inode(struct inode
*inode
)
195 struct exfat_inode_info
*ei
= EXFAT_I(inode
);
196 struct exfat_cache
*cache
;
198 while (!list_empty(&ei
->cache_lru
)) {
199 cache
= list_entry(ei
->cache_lru
.next
,
200 struct exfat_cache
, cache_list
);
201 list_del_init(&cache
->cache_list
);
203 exfat_cache_free(cache
);
205 /* Update. The copy of caches before this id is discarded. */
206 ei
->cache_valid_id
++;
207 if (ei
->cache_valid_id
== EXFAT_CACHE_VALID
)
208 ei
->cache_valid_id
++;
211 void exfat_cache_inval_inode(struct inode
*inode
)
213 struct exfat_inode_info
*ei
= EXFAT_I(inode
);
215 spin_lock(&ei
->cache_lru_lock
);
216 __exfat_cache_inval_inode(inode
);
217 spin_unlock(&ei
->cache_lru_lock
);
220 static inline int cache_contiguous(struct exfat_cache_id
*cid
,
224 return cid
->dcluster
+ cid
->nr_contig
== dclus
;
227 static inline void cache_init(struct exfat_cache_id
*cid
,
228 unsigned int fclus
, unsigned int dclus
)
230 cid
->id
= EXFAT_CACHE_VALID
;
231 cid
->fcluster
= fclus
;
232 cid
->dcluster
= dclus
;
236 int exfat_get_cluster(struct inode
*inode
, unsigned int cluster
,
237 unsigned int *fclus
, unsigned int *dclus
,
238 unsigned int *last_dclus
, int allow_eof
)
240 struct super_block
*sb
= inode
->i_sb
;
241 struct exfat_sb_info
*sbi
= EXFAT_SB(sb
);
242 unsigned int limit
= sbi
->num_clusters
;
243 struct exfat_inode_info
*ei
= EXFAT_I(inode
);
244 struct exfat_cache_id cid
;
245 unsigned int content
;
247 if (ei
->start_clu
== EXFAT_FREE_CLUSTER
) {
249 "invalid access to exfat cache (entry 0x%08x)",
255 *dclus
= ei
->start_clu
;
256 *last_dclus
= *dclus
;
259 * Don`t use exfat_cache if zero offset or non-cluster allocation
261 if (cluster
== 0 || *dclus
== EXFAT_EOF_CLUSTER
)
264 cache_init(&cid
, EXFAT_EOF_CLUSTER
, EXFAT_EOF_CLUSTER
);
266 if (exfat_cache_lookup(inode
, cluster
, &cid
, fclus
, dclus
) ==
269 * dummy, always not contiguous
270 * This is reinitialized by cache_init(), later.
272 WARN_ON(cid
.id
!= EXFAT_CACHE_VALID
||
273 cid
.fcluster
!= EXFAT_EOF_CLUSTER
||
274 cid
.dcluster
!= EXFAT_EOF_CLUSTER
||
278 if (*fclus
== cluster
)
281 while (*fclus
< cluster
) {
282 /* prevent the infinite loop of cluster chain */
283 if (*fclus
> limit
) {
285 "detected the cluster chain loop (i_pos %u)",
290 if (exfat_ent_get(sb
, *dclus
, &content
))
293 *last_dclus
= *dclus
;
297 if (content
== EXFAT_EOF_CLUSTER
) {
300 "invalid cluster chain (i_pos %u, last_clus 0x%08x is EOF)",
301 *fclus
, (*last_dclus
));
308 if (!cache_contiguous(&cid
, *dclus
))
309 cache_init(&cid
, *fclus
, *dclus
);
312 exfat_cache_add(inode
, &cid
);