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 <asm/unaligned.h>
15 #include <linux/buffer_head.h>
17 #include "exfat_raw.h"
20 #define EXFAT_CACHE_VALID 0
21 #define EXFAT_MAX_CACHE 16
24 struct list_head cache_list
;
25 unsigned int nr_contig
; /* number of contiguous clusters */
26 unsigned int fcluster
; /* cluster number in the file. */
27 unsigned int dcluster
; /* cluster number on disk. */
30 struct exfat_cache_id
{
32 unsigned int nr_contig
;
33 unsigned int fcluster
;
34 unsigned int dcluster
;
37 static struct kmem_cache
*exfat_cachep
;
39 static void exfat_cache_init_once(void *c
)
41 struct exfat_cache
*cache
= (struct exfat_cache
*)c
;
43 INIT_LIST_HEAD(&cache
->cache_list
);
46 int exfat_cache_init(void)
48 exfat_cachep
= kmem_cache_create("exfat_cache",
49 sizeof(struct exfat_cache
),
50 0, SLAB_RECLAIM_ACCOUNT
|SLAB_MEM_SPREAD
,
51 exfat_cache_init_once
);
57 void exfat_cache_shutdown(void)
61 kmem_cache_destroy(exfat_cachep
);
64 void exfat_cache_init_inode(struct inode
*inode
)
66 struct exfat_inode_info
*ei
= EXFAT_I(inode
);
68 spin_lock_init(&ei
->cache_lru_lock
);
70 ei
->cache_valid_id
= EXFAT_CACHE_VALID
+ 1;
71 INIT_LIST_HEAD(&ei
->cache_lru
);
74 static inline struct exfat_cache
*exfat_cache_alloc(void)
76 return kmem_cache_alloc(exfat_cachep
, GFP_NOFS
);
79 static inline void exfat_cache_free(struct exfat_cache
*cache
)
81 WARN_ON(!list_empty(&cache
->cache_list
));
82 kmem_cache_free(exfat_cachep
, cache
);
85 static inline void exfat_cache_update_lru(struct inode
*inode
,
86 struct exfat_cache
*cache
)
88 struct exfat_inode_info
*ei
= EXFAT_I(inode
);
90 if (ei
->cache_lru
.next
!= &cache
->cache_list
)
91 list_move(&cache
->cache_list
, &ei
->cache_lru
);
94 static unsigned int exfat_cache_lookup(struct inode
*inode
,
95 unsigned int fclus
, struct exfat_cache_id
*cid
,
96 unsigned int *cached_fclus
, unsigned int *cached_dclus
)
98 struct exfat_inode_info
*ei
= EXFAT_I(inode
);
99 static struct exfat_cache nohit
= { .fcluster
= 0, };
100 struct exfat_cache
*hit
= &nohit
, *p
;
101 unsigned int offset
= EXFAT_EOF_CLUSTER
;
103 spin_lock(&ei
->cache_lru_lock
);
104 list_for_each_entry(p
, &ei
->cache_lru
, cache_list
) {
105 /* Find the cache of "fclus" or nearest cache. */
106 if (p
->fcluster
<= fclus
&& hit
->fcluster
< p
->fcluster
) {
108 if (hit
->fcluster
+ hit
->nr_contig
< fclus
) {
109 offset
= hit
->nr_contig
;
111 offset
= fclus
- hit
->fcluster
;
117 exfat_cache_update_lru(inode
, hit
);
119 cid
->id
= ei
->cache_valid_id
;
120 cid
->nr_contig
= hit
->nr_contig
;
121 cid
->fcluster
= hit
->fcluster
;
122 cid
->dcluster
= hit
->dcluster
;
123 *cached_fclus
= cid
->fcluster
+ offset
;
124 *cached_dclus
= cid
->dcluster
+ offset
;
126 spin_unlock(&ei
->cache_lru_lock
);
131 static struct exfat_cache
*exfat_cache_merge(struct inode
*inode
,
132 struct exfat_cache_id
*new)
134 struct exfat_inode_info
*ei
= EXFAT_I(inode
);
135 struct exfat_cache
*p
;
137 list_for_each_entry(p
, &ei
->cache_lru
, cache_list
) {
138 /* Find the same part as "new" in cluster-chain. */
139 if (p
->fcluster
== new->fcluster
) {
140 if (new->nr_contig
> p
->nr_contig
)
141 p
->nr_contig
= new->nr_contig
;
148 static void exfat_cache_add(struct inode
*inode
,
149 struct exfat_cache_id
*new)
151 struct exfat_inode_info
*ei
= EXFAT_I(inode
);
152 struct exfat_cache
*cache
, *tmp
;
154 if (new->fcluster
== EXFAT_EOF_CLUSTER
) /* dummy cache */
157 spin_lock(&ei
->cache_lru_lock
);
158 if (new->id
!= EXFAT_CACHE_VALID
&&
159 new->id
!= ei
->cache_valid_id
)
160 goto unlock
; /* this cache was invalidated */
162 cache
= exfat_cache_merge(inode
, new);
164 if (ei
->nr_caches
< EXFAT_MAX_CACHE
) {
166 spin_unlock(&ei
->cache_lru_lock
);
168 tmp
= exfat_cache_alloc();
170 spin_lock(&ei
->cache_lru_lock
);
172 spin_unlock(&ei
->cache_lru_lock
);
176 spin_lock(&ei
->cache_lru_lock
);
177 cache
= exfat_cache_merge(inode
, new);
180 exfat_cache_free(tmp
);
185 struct list_head
*p
= ei
->cache_lru
.prev
;
187 cache
= list_entry(p
,
188 struct exfat_cache
, cache_list
);
190 cache
->fcluster
= new->fcluster
;
191 cache
->dcluster
= new->dcluster
;
192 cache
->nr_contig
= new->nr_contig
;
195 exfat_cache_update_lru(inode
, cache
);
197 spin_unlock(&ei
->cache_lru_lock
);
201 * Cache invalidation occurs rarely, thus the LRU chain is not updated. It
202 * fixes itself after a while.
204 static void __exfat_cache_inval_inode(struct inode
*inode
)
206 struct exfat_inode_info
*ei
= EXFAT_I(inode
);
207 struct exfat_cache
*cache
;
209 while (!list_empty(&ei
->cache_lru
)) {
210 cache
= list_entry(ei
->cache_lru
.next
,
211 struct exfat_cache
, cache_list
);
212 list_del_init(&cache
->cache_list
);
214 exfat_cache_free(cache
);
216 /* Update. The copy of caches before this id is discarded. */
217 ei
->cache_valid_id
++;
218 if (ei
->cache_valid_id
== EXFAT_CACHE_VALID
)
219 ei
->cache_valid_id
++;
222 void exfat_cache_inval_inode(struct inode
*inode
)
224 struct exfat_inode_info
*ei
= EXFAT_I(inode
);
226 spin_lock(&ei
->cache_lru_lock
);
227 __exfat_cache_inval_inode(inode
);
228 spin_unlock(&ei
->cache_lru_lock
);
231 static inline int cache_contiguous(struct exfat_cache_id
*cid
,
235 return cid
->dcluster
+ cid
->nr_contig
== dclus
;
238 static inline void cache_init(struct exfat_cache_id
*cid
,
239 unsigned int fclus
, unsigned int dclus
)
241 cid
->id
= EXFAT_CACHE_VALID
;
242 cid
->fcluster
= fclus
;
243 cid
->dcluster
= dclus
;
247 int exfat_get_cluster(struct inode
*inode
, unsigned int cluster
,
248 unsigned int *fclus
, unsigned int *dclus
,
249 unsigned int *last_dclus
, int allow_eof
)
251 struct super_block
*sb
= inode
->i_sb
;
252 struct exfat_sb_info
*sbi
= EXFAT_SB(sb
);
253 unsigned int limit
= sbi
->num_clusters
;
254 struct exfat_inode_info
*ei
= EXFAT_I(inode
);
255 struct exfat_cache_id cid
;
256 unsigned int content
;
258 if (ei
->start_clu
== EXFAT_FREE_CLUSTER
) {
260 "invalid access to exfat cache (entry 0x%08x)",
266 *dclus
= ei
->start_clu
;
267 *last_dclus
= *dclus
;
270 * Don`t use exfat_cache if zero offset or non-cluster allocation
272 if (cluster
== 0 || *dclus
== EXFAT_EOF_CLUSTER
)
275 cache_init(&cid
, EXFAT_EOF_CLUSTER
, EXFAT_EOF_CLUSTER
);
277 if (exfat_cache_lookup(inode
, cluster
, &cid
, fclus
, dclus
) ==
280 * dummy, always not contiguous
281 * This is reinitialized by cache_init(), later.
283 WARN_ON(cid
.id
!= EXFAT_CACHE_VALID
||
284 cid
.fcluster
!= EXFAT_EOF_CLUSTER
||
285 cid
.dcluster
!= EXFAT_EOF_CLUSTER
||
289 if (*fclus
== cluster
)
292 while (*fclus
< cluster
) {
293 /* prevent the infinite loop of cluster chain */
294 if (*fclus
> limit
) {
296 "detected the cluster chain loop (i_pos %u)",
301 if (exfat_ent_get(sb
, *dclus
, &content
))
304 *last_dclus
= *dclus
;
308 if (content
== EXFAT_EOF_CLUSTER
) {
311 "invalid cluster chain (i_pos %u, last_clus 0x%08x is EOF)",
312 *fclus
, (*last_dclus
));
319 if (!cache_contiguous(&cid
, *dclus
))
320 cache_init(&cid
, *fclus
, *dclus
);
323 exfat_cache_add(inode
, &cid
);