4 * Written 1992,1993 by Werner Almesberger
6 * Mar 1999. AV. Changed cache, so that it uses the starting cluster instead
8 * May 1999. AV. Fixed the bogosity with FAT32 (read "FAT28"). Fscking lusers.
12 #include <linux/msdos_fs.h>
13 #include <linux/buffer_head.h>
15 //#define MAXFATHEADTEST 1000000
18 #define debug_pr(fmt, args...) printk(fmt, ##args)
20 #define debug_pr(fmt, args...)
23 /* this must be > 0. */
24 #define FAT_MAX_CACHE 8
27 struct list_head cache_list
;
28 int nr_contig
; /* number of contiguous clusters */
29 int fcluster
; /* cluster number in the file. */
30 int dcluster
; /* cluster number on disk. */
33 static inline int fat_max_cache(struct inode
*inode
)
38 static kmem_cache_t
*fat_cache_cachep
;
40 static void init_once(void *foo
, kmem_cache_t
*cachep
, unsigned long flags
)
42 struct fat_cache
*cache
= (struct fat_cache
*)foo
;
44 if ((flags
& (SLAB_CTOR_VERIFY
|SLAB_CTOR_CONSTRUCTOR
)) ==
45 SLAB_CTOR_CONSTRUCTOR
)
46 INIT_LIST_HEAD(&cache
->cache_list
);
49 int __init
fat_cache_init(void)
51 fat_cache_cachep
= kmem_cache_create("fat_cache",
52 sizeof(struct fat_cache
),
53 0, SLAB_RECLAIM_ACCOUNT
,
55 if (fat_cache_cachep
== NULL
)
60 void __exit
fat_cache_destroy(void)
62 if (kmem_cache_destroy(fat_cache_cachep
))
63 printk(KERN_INFO
"fat_cache: not all structures were freed\n");
66 static inline struct fat_cache
*fat_cache_alloc(struct inode
*inode
)
68 return kmem_cache_alloc(fat_cache_cachep
, SLAB_KERNEL
);
71 static inline void fat_cache_free(struct fat_cache
*cache
)
73 BUG_ON(!list_empty(&cache
->cache_list
));
74 kmem_cache_free(fat_cache_cachep
, cache
);
77 static inline void fat_cache_update_lru(struct inode
*inode
,
78 struct fat_cache
*cache
)
80 if (MSDOS_I(inode
)->cache_lru
.next
!= &cache
->cache_list
)
81 list_move(&cache
->cache_list
, &MSDOS_I(inode
)->cache_lru
);
84 static int fat_cache_lookup(struct inode
*inode
, int fclus
,
85 struct fat_cache
*cache
,
86 int *cached_fclus
, int *cached_dclus
)
88 static struct fat_cache nohit
= { .fcluster
= 0, };
90 struct msdos_sb_info
*sbi
= MSDOS_SB(inode
->i_sb
);
91 struct fat_cache
*hit
= &nohit
, *p
;
94 spin_lock(&sbi
->cache_lock
);
95 debug_pr("FAT: %s, fclus %d", __FUNCTION__
, fclus
);
96 list_for_each_entry(p
, &MSDOS_I(inode
)->cache_lru
, cache_list
) {
97 if (p
->fcluster
<= fclus
&& hit
->fcluster
< p
->fcluster
) {
99 debug_pr(", fclus %d, dclus %d, cont %d",
100 p
->fcluster
, p
->dcluster
, p
->nr_contig
);
101 if ((hit
->fcluster
+ hit
->nr_contig
) < fclus
) {
102 offset
= hit
->nr_contig
;
103 debug_pr(" (off %d, hit)", offset
);
105 offset
= fclus
- hit
->fcluster
;
106 debug_pr(" (off %d, full hit)", offset
);
112 fat_cache_update_lru(inode
, hit
);
114 *cached_fclus
= cache
->fcluster
+ offset
;
115 *cached_dclus
= cache
->dcluster
+ offset
;
118 spin_unlock(&sbi
->cache_lock
);
123 static struct fat_cache
*fat_cache_merge(struct inode
*inode
,
124 struct fat_cache
*new)
126 struct fat_cache
*p
, *hit
= NULL
;
128 list_for_each_entry(p
, &MSDOS_I(inode
)->cache_lru
, cache_list
) {
129 if (p
->fcluster
== new->fcluster
) {
130 BUG_ON(p
->dcluster
!= new->dcluster
);
131 debug_pr("FAT: %s: merged fclus %d, dclus %d, "
132 "cur cont %d => new cont %d\n", __FUNCTION__
,
133 p
->fcluster
, p
->dcluster
, p
->nr_contig
,
135 if (new->nr_contig
> p
->nr_contig
)
136 p
->nr_contig
= new->nr_contig
;
144 static void fat_cache_add(struct inode
*inode
, struct fat_cache
*new)
146 struct msdos_sb_info
*sbi
= MSDOS_SB(inode
->i_sb
);
147 struct fat_cache
*cache
, *tmp
;
149 debug_pr("FAT: %s: fclus %d, dclus %d, cont %d\n", __FUNCTION__
,
150 new->fcluster
, new->dcluster
, new->nr_contig
);
152 if (new->fcluster
== -1) /* dummy cache */
155 spin_lock(&sbi
->cache_lock
);
156 cache
= fat_cache_merge(inode
, new);
158 if (MSDOS_I(inode
)->nr_caches
< fat_max_cache(inode
)) {
159 MSDOS_I(inode
)->nr_caches
++;
160 spin_unlock(&sbi
->cache_lock
);
162 tmp
= fat_cache_alloc(inode
);
163 spin_lock(&sbi
->cache_lock
);
164 cache
= fat_cache_merge(inode
, new);
166 MSDOS_I(inode
)->nr_caches
--;
172 struct list_head
*p
= MSDOS_I(inode
)->cache_lru
.prev
;
173 cache
= list_entry(p
, struct fat_cache
, cache_list
);
175 cache
->fcluster
= new->fcluster
;
176 cache
->dcluster
= new->dcluster
;
177 cache
->nr_contig
= new->nr_contig
;
180 fat_cache_update_lru(inode
, cache
);
183 list_for_each_entry(cache
, &MSDOS_I(inode
)->cache_lru
, cache_list
) {
184 debug_pr("(fclus %d, dclus %d, cont %d), ",
185 cache
->fcluster
, cache
->dcluster
, cache
->nr_contig
);
188 spin_unlock(&sbi
->cache_lock
);
192 * Cache invalidation occurs rarely, thus the LRU chain is not updated. It
193 * fixes itself after a while.
195 static void __fat_cache_inval_inode(struct inode
*inode
)
197 struct msdos_inode_info
*i
= MSDOS_I(inode
);
198 struct fat_cache
*cache
;
199 while (!list_empty(&i
->cache_lru
)) {
200 cache
= list_entry(i
->cache_lru
.next
, struct fat_cache
, cache_list
);
201 list_del_init(&cache
->cache_list
);
202 MSDOS_I(inode
)->nr_caches
--;
203 fat_cache_free(cache
);
205 debug_pr("FAT: %s\n", __FUNCTION__
);
208 void fat_cache_inval_inode(struct inode
*inode
)
210 spin_lock(&MSDOS_SB(inode
->i_sb
)->cache_lock
);
211 __fat_cache_inval_inode(inode
);
212 spin_unlock(&MSDOS_SB(inode
->i_sb
)->cache_lock
);
215 //prince add debug end
217 int __fat_access(struct super_block
*sb
, int nr
, int new_value
)
219 struct msdos_sb_info
*sbi
= MSDOS_SB(sb
);
220 struct buffer_head
*bh
, *bh2
, *c_bh
, *c_bh2
;
221 unsigned char *p_first
, *p_last
;
222 int copy
, first
, last
, next
, b
;
224 if (sbi
->fat_bits
== 32) {
226 } else if (sbi
->fat_bits
== 16) {
232 b
= sbi
->fat_start
+ (first
>> sb
->s_blocksize_bits
);
233 if (!(bh
= sb_bread(sb
, b
))) {
234 printk(KERN_ERR
"FAT: bread(block %d) in"
235 " fat_access failed\n", b
);
238 if ((first
>> sb
->s_blocksize_bits
) == (last
>> sb
->s_blocksize_bits
)) {
241 if (!(bh2
= sb_bread(sb
, b
+ 1))) {
243 printk(KERN_ERR
"FAT: bread(block %d) in"
244 " fat_access failed\n", b
+ 1);
248 if (sbi
->fat_bits
== 32) {
249 p_first
= p_last
= NULL
; // GCC needs that stuff
250 next
= CF_LE_L(((__le32
*) bh
->b_data
)[(first
&
251 (sb
->s_blocksize
- 1)) >> 2]);
252 // Fscking Microsoft marketing department. Their "32" is 28.
254 } else if (sbi
->fat_bits
== 16) {
255 p_first
= p_last
= NULL
; // GCC needs that stuff
256 next
= CF_LE_W(((__le16
*) bh
->b_data
)[(first
&
257 (sb
->s_blocksize
- 1)) >> 1]);
259 p_first
= &((__u8
*)bh
->b_data
)[first
& (sb
->s_blocksize
- 1)];
260 p_last
= &((__u8
*)bh2
->b_data
)[(first
+ 1) & (sb
->s_blocksize
- 1)];
262 next
= ((*p_first
>> 4) | (*p_last
<< 4)) & 0xfff;
264 next
= (*p_first
+(*p_last
<< 8)) & 0xfff;
266 if (new_value
!= -1) {
267 if (sbi
->fat_bits
== 32) {
268 ((__le32
*)bh
->b_data
)[(first
& (sb
->s_blocksize
- 1)) >> 2]
269 = CT_LE_L(new_value
);
270 } else if (sbi
->fat_bits
== 16) {
271 ((__le16
*)bh
->b_data
)[(first
& (sb
->s_blocksize
- 1)) >> 1]
272 = CT_LE_W(new_value
);
275 *p_first
= (*p_first
& 0xf) | (new_value
<< 4);
276 *p_last
= new_value
>> 4;
279 *p_first
= new_value
& 0xff;
280 *p_last
= (*p_last
& 0xf0) | (new_value
>> 8);
282 mark_buffer_dirty(bh2
);
284 mark_buffer_dirty(bh
);
285 for (copy
= 1; copy
< sbi
->fats
; copy
++) {
286 b
= sbi
->fat_start
+ (first
>> sb
->s_blocksize_bits
)
287 + sbi
->fat_length
* copy
;
288 if (!(c_bh
= sb_bread(sb
, b
)))
291 if (!(c_bh2
= sb_bread(sb
, b
+1))) {
295 memcpy(c_bh2
->b_data
, bh2
->b_data
, sb
->s_blocksize
);
296 mark_buffer_dirty(c_bh2
);
299 memcpy(c_bh
->b_data
, bh
->b_data
, sb
->s_blocksize
);
300 mark_buffer_dirty(c_bh
);
311 * Returns the this'th FAT entry, -1 if it is an end-of-file entry. If
312 * new_value is != -1, that FAT entry is replaced by it.
314 int fat_access(struct super_block
*sb
, int nr
, int new_value
)
326 if (nr
< 2 || MSDOS_SB(sb
)->clusters
+ 2 <= nr
) {
329 //if ( count <= MAXFATHEADTEST )
332 fat_fs_panic(sb
, "invalid access to FAT (entry 0x%08x)", nr
);
335 if (new_value
== FAT_ENT_EOF
)
336 new_value
= EOF_FAT(sb
);
338 next
= __fat_access(sb
, nr
, new_value
);
341 if (next
>= BAD_FAT(sb
))
347 /*===========prince delete debug
348 void fat_cache_init(struct super_block *sb)
350 struct msdos_sb_info *sbi = MSDOS_SB(sb);
353 spin_lock_init(&sbi->cache_lock);
355 for (count = 0; count < FAT_CACHE_NR - 1; count++) {
356 sbi->cache_array[count].start_cluster = 0;
357 sbi->cache_array[count].next = &sbi->cache_array[count + 1];
359 sbi->cache_array[count].start_cluster = 0;
360 sbi->cache_array[count].next = NULL;
361 sbi->cache = sbi->cache_array;
365 fat_cache_lookup(struct inode *inode, int cluster, int *f_clu, int *d_clu)
367 struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
368 struct fat_cache *walk;
371 BUG_ON(cluster == 0);
373 first = MSDOS_I(inode)->i_start;
377 spin_lock(&sbi->cache_lock);
379 if (MSDOS_I(inode)->disk_cluster &&
380 MSDOS_I(inode)->file_cluster <= cluster) {
381 *d_clu = MSDOS_I(inode)->disk_cluster;
382 *f_clu = MSDOS_I(inode)->file_cluster;
385 for (walk = sbi->cache; walk; walk = walk->next) {
386 if (walk->start_cluster == first
387 && walk->file_cluster <= cluster
388 && walk->file_cluster > *f_clu) {
389 *d_clu = walk->disk_cluster;
390 *f_clu = walk->file_cluster;
392 printk("cache hit: %d (%d)\n", *f_clu, *d_clu);
394 if (*f_clu == cluster)
399 printk("cache miss\n");
402 spin_unlock(&sbi->cache_lock);
406 static void list_cache(struct super_block *sb)
408 struct msdos_sb_info *sbi = MSDOS_SB(sb);
409 struct fat_cache *walk;
411 for (walk = sbi->cache; walk; walk = walk->next) {
412 if (walk->start_cluster)
413 printk("<%s,%d>(%d,%d) ", sb->s_id,
414 walk->start_cluster, walk->file_cluster,
424 // Cache invalidation occurs rarely, thus the LRU chain is not updated. It
425 // fixes itself after a while.
426 ===========prince delete debug*/
427 //prince delete debug
428 //static void __fat_cache_inval_inode(struct inode *inode)
429 //prince add debug begin
430 static inline int cache_contiguous(struct fat_cache
*cache
, int dclus
)
431 //prince add debug end
433 /*=====prince delete debug begin
434 struct fat_cache *walk;
435 int first = MSDOS_I(inode)->i_start;
436 MSDOS_I(inode)->file_cluster = MSDOS_I(inode)->disk_cluster = 0;
437 for (walk = MSDOS_SB(inode->i_sb)->cache; walk; walk = walk->next)
438 if (walk->start_cluster == first)
439 walk->start_cluster = 0;
440 ========prince delete debug end */
441 //prince add debug begin
443 return ((cache
->dcluster
+ cache
->nr_contig
) == dclus
);
444 //prince add debug end
448 /*=====prince delete debug begin
449 void fat_cache_inval_inode(struct inode *inode)
450 ==============================*/
451 //prince add debug begin
452 static inline void cache_init(struct fat_cache
*cache
, int fclus
, int dclus
)
453 //prince add debug end
455 /*======prince delete debug begin
456 struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
457 spin_lock(&sbi->cache_lock);
458 __fat_cache_inval_inode(inode);
459 spin_unlock(&sbi->cache_lock);
462 void fat_cache_add(struct inode *inode, int f_clu, int d_clu)
464 struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
465 struct fat_cache *walk, *last;
466 int first, prev_f_clu, prev_d_clu;
470 first = MSDOS_I(inode)->i_start;
475 spin_lock(&sbi->cache_lock);
477 if (MSDOS_I(inode)->file_cluster == f_clu)
480 prev_f_clu = MSDOS_I(inode)->file_cluster;
481 prev_d_clu = MSDOS_I(inode)->disk_cluster;
482 MSDOS_I(inode)->file_cluster = f_clu;
483 MSDOS_I(inode)->disk_cluster = d_clu;
490 for (walk = sbi->cache; walk->next; walk = (last = walk)->next) {
491 if (walk->start_cluster == first &&
492 walk->file_cluster == f_clu) {
493 if (walk->disk_cluster != d_clu) {
494 printk(KERN_ERR "FAT: cache corruption "
495 "(i_pos %lld)\n", MSDOS_I(inode)->i_pos);
496 __fat_cache_inval_inode(inode);
503 last->next = walk->next;
504 walk->next = sbi->cache;
512 walk->start_cluster = first;
513 walk->file_cluster = f_clu;
514 walk->disk_cluster = d_clu;
516 walk->next = sbi->cache;
522 spin_unlock(&sbi->cache_lock);
523 ===prince delete debug end*/
524 //prince add debug begin
525 cache
->fcluster
= fclus
;
526 cache
->dcluster
= dclus
;
527 cache
->nr_contig
= 0;
528 //prince add debug end
531 int fat_get_cluster(struct inode
*inode
, int cluster
, int *fclus
, int *dclus
)
533 struct super_block
*sb
= inode
->i_sb
;
534 const int limit
= sb
->s_maxbytes
>> MSDOS_SB(sb
)->cluster_bits
;
535 //prince add debug begin
536 struct fat_cache cache
;
537 //prince add debug end
541 BUG_ON(MSDOS_I(inode
)->i_start
== 0);
544 *dclus
= MSDOS_I(inode
)->i_start
;
547 /*==prince delete debug begin
548 fat_cache_lookup(inode, cluster, fclus, dclus);
549 ====prince delete debug end=*/
550 //prince add debug begin
551 if (fat_cache_lookup(inode
, cluster
, &cache
, fclus
, dclus
) < 0)
552 cache_init(&cache
, -1, -1); /* dummy, always not contiguous */
554 //prince add debug end
555 while (*fclus
< cluster
) {
556 /* prevent the infinite loop of cluster chain */
557 if (*fclus
> limit
) {
558 fat_fs_panic(sb
, "%s: detected the cluster chain loop"
559 " (i_pos %lld)", __FUNCTION__
,
560 MSDOS_I(inode
)->i_pos
);
564 nr
= fat_access(sb
, *dclus
, -1);
567 else if (nr
== FAT_ENT_FREE
) {
568 fat_fs_panic(sb
, "%s: invalid cluster chain"
569 " (i_pos %lld)", __FUNCTION__
,
570 MSDOS_I(inode
)->i_pos
);
572 } else if (nr
== FAT_ENT_EOF
) {
573 /*===prince delete debug begin
574 fat_cache_add(inode, *fclus, *dclus);
575 =====prince delete debug end*/
576 //pricce add debug begin
577 fat_cache_add(inode
, &cache
);
578 //prince add debug end
583 //prince add debug begin
584 if (!cache_contiguous(&cache
, *dclus
))
585 cache_init(&cache
, *fclus
, *dclus
);
586 //prince add debug end
589 /*==prince delete debug begin
590 fat_cache_add(inode, *fclus, *dclus);
591 ====prince delete debug end*/
592 //prince add debug begin
593 fat_cache_add(inode
, &cache
);
594 //prince add debug end
598 static int fat_bmap_cluster(struct inode
*inode
, int cluster
)
600 struct super_block
*sb
= inode
->i_sb
;
601 int ret
, fclus
, dclus
;
603 if (MSDOS_I(inode
)->i_start
== 0)
606 ret
= fat_get_cluster(inode
, cluster
, &fclus
, &dclus
);
609 else if (ret
== FAT_ENT_EOF
) {
610 fat_fs_panic(sb
, "%s: request beyond EOF (i_pos %lld)",
611 __FUNCTION__
, MSDOS_I(inode
)->i_pos
);
617 int fat_bmap(struct inode
*inode
, sector_t sector
, sector_t
*phys
)
619 struct super_block
*sb
= inode
->i_sb
;
620 struct msdos_sb_info
*sbi
= MSDOS_SB(sb
);
625 if ((sbi
->fat_bits
!= 32) &&
626 (inode
->i_ino
== MSDOS_ROOT_INO
|| (S_ISDIR(inode
->i_mode
) &&
627 !MSDOS_I(inode
)->i_start
))) {
628 if (sector
< (sbi
->dir_entries
>> sbi
->dir_per_block_bits
))
629 *phys
= sector
+ sbi
->dir_start
;
632 last_block
= (MSDOS_I(inode
)->mmu_private
+ (sb
->s_blocksize
- 1))
633 >> sb
->s_blocksize_bits
;
634 if (sector
>= last_block
)
637 cluster
= sector
>> (sbi
->cluster_bits
- sb
->s_blocksize_bits
);
638 offset
= sector
& (sbi
->sec_per_clus
- 1);
639 cluster
= fat_bmap_cluster(inode
, cluster
);
643 *phys
= ((sector_t
)cluster
- 2) * sbi
->sec_per_clus
644 + sbi
->data_start
+ offset
;
649 /* Free all clusters after the skip'th cluster. */
650 int fat_free(struct inode
*inode
, int skip
)
652 struct super_block
*sb
= inode
->i_sb
;
653 int nr
, ret
, fclus
, dclus
;
658 if (MSDOS_I(inode
)->i_start
== 0)
662 ret
= fat_get_cluster(inode
, skip
- 1, &fclus
, &dclus
);
665 else if (ret
== FAT_ENT_EOF
)
668 nr
= fat_access(sb
, dclus
, -1);
669 if (nr
== FAT_ENT_EOF
)
673 * write a new EOF, and get the remaining cluster
676 nr
= fat_access(sb
, dclus
, FAT_ENT_EOF
);
681 fat_cache_inval_inode(inode
);
683 fat_cache_inval_inode(inode
);
685 nr
= MSDOS_I(inode
)->i_start
;
686 MSDOS_I(inode
)->i_start
= 0;
687 MSDOS_I(inode
)->i_logstart
= 0;
688 mark_inode_dirty(inode
);
695 nr
= fat_access(sb
, nr
, FAT_ENT_FREE
);
698 else if (nr
== FAT_ENT_FREE
) {
701 //if ( count <= MAXFATHEADTEST )
704 fat_fs_panic(sb
, "%s: deleting beyond EOF (i_pos %lld)",
705 __FUNCTION__
, MSDOS_I(inode
)->i_pos
);
709 if (MSDOS_SB(sb
)->free_clusters
!= -1)
710 MSDOS_SB(sb
)->free_clusters
++;
711 inode
->i_blocks
-= MSDOS_SB(sb
)->cluster_size
>> 9;
712 } while (nr
!= FAT_ENT_EOF
);
713 fat_clusters_flush(sb
);