CD exfat support for Tomato. https://github.com/dorimanx/exfat-nofuse.
[tomato.git] / release / src-rt / linux / linux-2.6 / fs / exfat / exfat_cache.c
blob05c613653010c3f19c05d992e9e0693ba7d58f36
1 /*
2 * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 /************************************************************************/
20 /* */
21 /* PROJECT : exFAT & FAT12/16/32 File System */
22 /* FILE : exfat_cache.c */
23 /* PURPOSE : exFAT Cache Manager */
24 /* (FAT Cache & Buffer Cache) */
25 /* */
26 /*----------------------------------------------------------------------*/
27 /* NOTES */
28 /* */
29 /*----------------------------------------------------------------------*/
30 /* REVISION HISTORY (Ver 0.9) */
31 /* */
32 /* - 2010.11.15 [Sung-Kwan Kim] : first writing */
33 /* */
34 /************************************************************************/
36 #include "exfat_config.h"
37 #include "exfat_global.h"
38 #include "exfat_data.h"
40 #include "exfat_cache.h"
41 #include "exfat_super.h"
42 #include "exfat.h"
44 /*----------------------------------------------------------------------*/
45 /* Global Variable Definitions */
46 /*----------------------------------------------------------------------*/
48 extern FS_STRUCT_T fs_struct[];
50 #define sm_P(s)
51 #define sm_V(s)
53 static INT32 __FAT_read(struct super_block *sb, UINT32 loc, UINT32 *content);
54 static INT32 __FAT_write(struct super_block *sb, UINT32 loc, UINT32 content);
56 static BUF_CACHE_T *FAT_cache_find(struct super_block *sb, UINT32 sec);
57 static BUF_CACHE_T *FAT_cache_get(struct super_block *sb, UINT32 sec);
58 static void FAT_cache_insert_hash(struct super_block *sb, BUF_CACHE_T *bp);
59 static void FAT_cache_remove_hash(BUF_CACHE_T *bp);
61 static UINT8 *__buf_getblk(struct super_block *sb, UINT32 sec);
63 static BUF_CACHE_T *buf_cache_find(struct super_block *sb, UINT32 sec);
64 static BUF_CACHE_T *buf_cache_get(struct super_block *sb, UINT32 sec);
65 static void buf_cache_insert_hash(struct super_block *sb, BUF_CACHE_T *bp);
66 static void buf_cache_remove_hash(BUF_CACHE_T *bp);
68 static void push_to_mru(BUF_CACHE_T *bp, BUF_CACHE_T *list);
69 static void push_to_lru(BUF_CACHE_T *bp, BUF_CACHE_T *list);
70 static void move_to_mru(BUF_CACHE_T *bp, BUF_CACHE_T *list);
71 static void move_to_lru(BUF_CACHE_T *bp, BUF_CACHE_T *list);
73 /*======================================================================*/
74 /* Cache Initialization Functions */
75 /*======================================================================*/
77 INT32 buf_init(struct super_block *sb)
79 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
81 INT32 i;
83 /* LRU list */
84 p_fs->FAT_cache_lru_list.next = p_fs->FAT_cache_lru_list.prev = &p_fs->FAT_cache_lru_list;
86 for (i = 0; i < FAT_CACHE_SIZE; i++) {
87 p_fs->FAT_cache_array[i].drv = -1;
88 p_fs->FAT_cache_array[i].sec = ~0;
89 p_fs->FAT_cache_array[i].flag = 0;
90 p_fs->FAT_cache_array[i].buf_bh = NULL;
91 p_fs->FAT_cache_array[i].prev = p_fs->FAT_cache_array[i].next = NULL;
92 push_to_mru(&(p_fs->FAT_cache_array[i]), &p_fs->FAT_cache_lru_list);
95 p_fs->buf_cache_lru_list.next = p_fs->buf_cache_lru_list.prev = &p_fs->buf_cache_lru_list;
97 for (i = 0; i < BUF_CACHE_SIZE; i++) {
98 p_fs->buf_cache_array[i].drv = -1;
99 p_fs->buf_cache_array[i].sec = ~0;
100 p_fs->buf_cache_array[i].flag = 0;
101 p_fs->buf_cache_array[i].buf_bh = NULL;
102 p_fs->buf_cache_array[i].prev = p_fs->buf_cache_array[i].next = NULL;
103 push_to_mru(&(p_fs->buf_cache_array[i]), &p_fs->buf_cache_lru_list);
106 /* HASH list */
107 for (i = 0; i < FAT_CACHE_HASH_SIZE; i++) {
108 p_fs->FAT_cache_hash_list[i].drv = -1;
109 p_fs->FAT_cache_hash_list[i].sec = ~0;
110 p_fs->FAT_cache_hash_list[i].hash_next = p_fs->FAT_cache_hash_list[i].hash_prev = &(p_fs->FAT_cache_hash_list[i]);
113 for (i = 0; i < FAT_CACHE_SIZE; i++) {
114 FAT_cache_insert_hash(sb, &(p_fs->FAT_cache_array[i]));
117 for (i = 0; i < BUF_CACHE_HASH_SIZE; i++) {
118 p_fs->buf_cache_hash_list[i].drv = -1;
119 p_fs->buf_cache_hash_list[i].sec = ~0;
120 p_fs->buf_cache_hash_list[i].hash_next = p_fs->buf_cache_hash_list[i].hash_prev = &(p_fs->buf_cache_hash_list[i]);
123 for (i = 0; i < BUF_CACHE_SIZE; i++) {
124 buf_cache_insert_hash(sb, &(p_fs->buf_cache_array[i]));
127 return(FFS_SUCCESS);
128 } /* end of buf_init */
130 INT32 buf_shutdown(struct super_block *sb)
132 return(FFS_SUCCESS);
133 } /* end of buf_shutdown */
135 /*======================================================================*/
136 /* FAT Read/Write Functions */
137 /*======================================================================*/
139 /* in : sb, loc
140 * out: content
141 * returns 0 on success
142 * -1 on error
144 INT32 FAT_read(struct super_block *sb, UINT32 loc, UINT32 *content)
146 INT32 ret;
148 sm_P(&f_sem);
150 ret = __FAT_read(sb, loc, content);
152 sm_V(&f_sem);
154 return(ret);
155 } /* end of FAT_read */
157 INT32 FAT_write(struct super_block *sb, UINT32 loc, UINT32 content)
159 INT32 ret;
161 sm_P(&f_sem);
163 ret = __FAT_write(sb, loc, content);
165 sm_V(&f_sem);
167 return(ret);
168 } /* end of FAT_write */
170 static INT32 __FAT_read(struct super_block *sb, UINT32 loc, UINT32 *content)
172 INT32 off;
173 UINT32 sec, _content;
174 UINT8 *fat_sector, *fat_entry;
175 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
176 BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info);
178 if (p_fs->vol_type == FAT12) {
179 sec = p_fs->FAT1_start_sector + ((loc + (loc >> 1)) >> p_bd->sector_size_bits);
180 off = (loc + (loc >> 1)) & p_bd->sector_size_mask;
182 if (off == (p_bd->sector_size-1)) {
183 fat_sector = FAT_getblk(sb, sec);
184 if (!fat_sector)
185 return -1;
187 _content = (UINT32) fat_sector[off];
189 fat_sector = FAT_getblk(sb, ++sec);
190 if (!fat_sector)
191 return -1;
193 _content |= (UINT32) fat_sector[0] << 8;
194 } else {
195 fat_sector = FAT_getblk(sb, sec);
196 if (!fat_sector)
197 return -1;
199 fat_entry = &(fat_sector[off]);
200 _content = GET16(fat_entry);
203 if (loc & 1) _content >>= 4;
205 _content &= 0x00000FFF;
207 if (_content >= CLUSTER_16(0x0FF8)) {
208 *content = CLUSTER_32(~0);
209 return 0;
210 } else {
211 *content = CLUSTER_32(_content);
212 return 0;
214 } else if (p_fs->vol_type == FAT16) {
215 sec = p_fs->FAT1_start_sector + (loc >> (p_bd->sector_size_bits-1));
216 off = (loc << 1) & p_bd->sector_size_mask;
218 fat_sector = FAT_getblk(sb, sec);
219 if (!fat_sector)
220 return -1;
222 fat_entry = &(fat_sector[off]);
224 _content = GET16_A(fat_entry);
226 _content &= 0x0000FFFF;
228 if (_content >= CLUSTER_16(0xFFF8)) {
229 *content = CLUSTER_32(~0);
230 return 0;
231 } else {
232 *content = CLUSTER_32(_content);
233 return 0;
235 } else if (p_fs->vol_type == FAT32) {
236 sec = p_fs->FAT1_start_sector + (loc >> (p_bd->sector_size_bits-2));
237 off = (loc << 2) & p_bd->sector_size_mask;
239 fat_sector = FAT_getblk(sb, sec);
240 if (!fat_sector)
241 return -1;
243 fat_entry = &(fat_sector[off]);
245 _content = GET32_A(fat_entry);
247 _content &= 0x0FFFFFFF;
249 if (_content >= CLUSTER_32(0x0FFFFFF8)) {
250 *content = CLUSTER_32(~0);
251 return 0;
252 } else {
253 *content = CLUSTER_32(_content);
254 return 0;
256 } else {
257 sec = p_fs->FAT1_start_sector + (loc >> (p_bd->sector_size_bits-2));
258 off = (loc << 2) & p_bd->sector_size_mask;
260 fat_sector = FAT_getblk(sb, sec);
261 if (!fat_sector)
262 return -1;
264 fat_entry = &(fat_sector[off]);
265 _content = GET32_A(fat_entry);
267 if (_content >= CLUSTER_32(0xFFFFFFF8)) {
268 *content = CLUSTER_32(~0);
269 return 0;
270 } else {
271 *content = CLUSTER_32(_content);
272 return 0;
276 *content = CLUSTER_32(~0);
277 return 0;
278 } /* end of __FAT_read */
280 static INT32 __FAT_write(struct super_block *sb, UINT32 loc, UINT32 content)
282 INT32 off;
283 UINT32 sec;
284 UINT8 *fat_sector, *fat_entry;
285 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
286 BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info);
288 if (p_fs->vol_type == FAT12) {
290 content &= 0x00000FFF;
292 sec = p_fs->FAT1_start_sector + ((loc + (loc >> 1)) >> p_bd->sector_size_bits);
293 off = (loc + (loc >> 1)) & p_bd->sector_size_mask;
295 fat_sector = FAT_getblk(sb, sec);
296 if (!fat_sector)
297 return -1;
299 if (loc & 1) { /* odd */
301 content <<= 4;
303 if (off == (p_bd->sector_size-1)) {
304 fat_sector[off] = (UINT8)(content | (fat_sector[off] & 0x0F));
305 FAT_modify(sb, sec);
307 fat_sector = FAT_getblk(sb, ++sec);
308 if (!fat_sector)
309 return -1;
311 fat_sector[0] = (UINT8)(content >> 8);
312 } else {
313 fat_entry = &(fat_sector[off]);
314 content |= GET16(fat_entry) & 0x000F;
316 SET16(fat_entry, content);
318 } else { /* even */
319 fat_sector[off] = (UINT8)(content);
321 if (off == (p_bd->sector_size-1)) {
322 fat_sector[off] = (UINT8)(content);
323 FAT_modify(sb, sec);
325 fat_sector = FAT_getblk(sb, ++sec);
326 fat_sector[0] = (UINT8)((fat_sector[0] & 0xF0) | (content >> 8));
327 } else {
328 fat_entry = &(fat_sector[off]);
329 content |= GET16(fat_entry) & 0xF000;
331 SET16(fat_entry, content);
336 else if (p_fs->vol_type == FAT16) {
338 content &= 0x0000FFFF;
340 sec = p_fs->FAT1_start_sector + (loc >> (p_bd->sector_size_bits-1));
341 off = (loc << 1) & p_bd->sector_size_mask;
343 fat_sector = FAT_getblk(sb, sec);
344 if (!fat_sector)
345 return -1;
347 fat_entry = &(fat_sector[off]);
349 SET16_A(fat_entry, content);
352 else if (p_fs->vol_type == FAT32) {
354 content &= 0x0FFFFFFF;
356 sec = p_fs->FAT1_start_sector + (loc >> (p_bd->sector_size_bits-2));
357 off = (loc << 2) & p_bd->sector_size_mask;
359 fat_sector = FAT_getblk(sb, sec);
360 if (!fat_sector)
361 return -1;
363 fat_entry = &(fat_sector[off]);
365 content |= GET32_A(fat_entry) & 0xF0000000;
367 SET32_A(fat_entry, content);
370 else { /* p_fs->vol_type == EXFAT */
372 sec = p_fs->FAT1_start_sector + (loc >> (p_bd->sector_size_bits-2));
373 off = (loc << 2) & p_bd->sector_size_mask;
375 fat_sector = FAT_getblk(sb, sec);
376 if (!fat_sector)
377 return -1;
379 fat_entry = &(fat_sector[off]);
381 SET32_A(fat_entry, content);
384 FAT_modify(sb, sec);
385 return 0;
386 } /* end of __FAT_write */
388 UINT8 *FAT_getblk(struct super_block *sb, UINT32 sec)
390 BUF_CACHE_T *bp;
391 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
393 bp = FAT_cache_find(sb, sec);
394 if (bp != NULL) {
395 move_to_mru(bp, &p_fs->FAT_cache_lru_list);
396 return(bp->buf_bh->b_data);
399 bp = FAT_cache_get(sb, sec);
401 FAT_cache_remove_hash(bp);
403 bp->drv = p_fs->drv;
404 bp->sec = sec;
405 bp->flag = 0;
407 FAT_cache_insert_hash(sb, bp);
409 if (sector_read(sb, sec, &(bp->buf_bh), 1) != FFS_SUCCESS) {
410 FAT_cache_remove_hash(bp);
411 bp->drv = -1;
412 bp->sec = ~0;
413 bp->flag = 0;
414 bp->buf_bh = NULL;
416 move_to_lru(bp, &p_fs->FAT_cache_lru_list);
417 return NULL;
420 return(bp->buf_bh->b_data);
421 } /* end of FAT_getblk */
423 void FAT_modify(struct super_block *sb, UINT32 sec)
425 BUF_CACHE_T *bp;
427 bp = FAT_cache_find(sb, sec);
428 if (bp != NULL) {
429 sector_write(sb, sec, bp->buf_bh, 0);
431 } /* end of FAT_modify */
433 void FAT_release_all(struct super_block *sb)
435 BUF_CACHE_T *bp;
436 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
438 sm_P(&f_sem);
440 bp = p_fs->FAT_cache_lru_list.next;
441 while (bp != &p_fs->FAT_cache_lru_list) {
442 if (bp->drv == p_fs->drv) {
443 bp->drv = -1;
444 bp->sec = ~0;
445 bp->flag = 0;
447 if(bp->buf_bh) {
448 __brelse(bp->buf_bh);
449 bp->buf_bh = NULL;
452 bp = bp->next;
455 sm_V(&f_sem);
456 } /* end of FAT_release_all */
458 void FAT_sync(struct super_block *sb)
460 BUF_CACHE_T *bp;
461 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
463 sm_P(&f_sem);
465 bp = p_fs->FAT_cache_lru_list.next;
466 while (bp != &p_fs->FAT_cache_lru_list) {
467 if ((bp->drv == p_fs->drv) && (bp->flag & DIRTYBIT)) {
468 sync_dirty_buffer(bp->buf_bh);
469 bp->flag &= ~(DIRTYBIT);
471 bp = bp->next;
474 sm_V(&f_sem);
475 } /* end of FAT_sync */
477 static BUF_CACHE_T *FAT_cache_find(struct super_block *sb, UINT32 sec)
479 INT32 off;
480 BUF_CACHE_T *bp, *hp;
481 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
483 off = (sec + (sec >> p_fs->sectors_per_clu_bits)) & (FAT_CACHE_HASH_SIZE - 1);
485 hp = &(p_fs->FAT_cache_hash_list[off]);
486 for (bp = hp->hash_next; bp != hp; bp = bp->hash_next) {
487 if ((bp->drv == p_fs->drv) && (bp->sec == sec)) {
489 WARN(!bp->buf_bh, "[EXFAT] FAT_cache has no bh. "
490 "It will make system panic.\n");
492 touch_buffer(bp->buf_bh);
493 return(bp);
496 return(NULL);
497 } /* end of FAT_cache_find */
499 static BUF_CACHE_T *FAT_cache_get(struct super_block *sb, UINT32 sec)
501 BUF_CACHE_T *bp;
502 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
504 bp = p_fs->FAT_cache_lru_list.prev;
507 move_to_mru(bp, &p_fs->FAT_cache_lru_list);
508 return(bp);
509 } /* end of FAT_cache_get */
511 static void FAT_cache_insert_hash(struct super_block *sb, BUF_CACHE_T *bp)
513 INT32 off;
514 BUF_CACHE_T *hp;
515 FS_INFO_T *p_fs;
517 p_fs = &(EXFAT_SB(sb)->fs_info);
518 off = (bp->sec + (bp->sec >> p_fs->sectors_per_clu_bits)) & (FAT_CACHE_HASH_SIZE-1);
520 hp = &(p_fs->FAT_cache_hash_list[off]);
521 bp->hash_next = hp->hash_next;
522 bp->hash_prev = hp;
523 hp->hash_next->hash_prev = bp;
524 hp->hash_next = bp;
525 } /* end of FAT_cache_insert_hash */
527 static void FAT_cache_remove_hash(BUF_CACHE_T *bp)
529 (bp->hash_prev)->hash_next = bp->hash_next;
530 (bp->hash_next)->hash_prev = bp->hash_prev;
531 } /* end of FAT_cache_remove_hash */
533 /*======================================================================*/
534 /* Buffer Read/Write Functions */
535 /*======================================================================*/
537 UINT8 *buf_getblk(struct super_block *sb, UINT32 sec)
539 UINT8 *buf;
541 sm_P(&b_sem);
543 buf = __buf_getblk(sb, sec);
545 sm_V(&b_sem);
547 return(buf);
548 } /* end of buf_getblk */
550 static UINT8 *__buf_getblk(struct super_block *sb, UINT32 sec)
552 BUF_CACHE_T *bp;
553 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
555 bp = buf_cache_find(sb, sec);
556 if (bp != NULL) {
557 move_to_mru(bp, &p_fs->buf_cache_lru_list);
558 return(bp->buf_bh->b_data);
561 bp = buf_cache_get(sb, sec);
563 buf_cache_remove_hash(bp);
565 bp->drv = p_fs->drv;
566 bp->sec = sec;
567 bp->flag = 0;
569 buf_cache_insert_hash(sb, bp);
571 if (sector_read(sb, sec, &(bp->buf_bh), 1) != FFS_SUCCESS) {
572 buf_cache_remove_hash(bp);
573 bp->drv = -1;
574 bp->sec = ~0;
575 bp->flag = 0;
576 bp->buf_bh = NULL;
578 move_to_lru(bp, &p_fs->buf_cache_lru_list);
579 return NULL;
582 return(bp->buf_bh->b_data);
584 } /* end of __buf_getblk */
586 void buf_modify(struct super_block *sb, UINT32 sec)
588 BUF_CACHE_T *bp;
590 sm_P(&b_sem);
592 bp = buf_cache_find(sb, sec);
593 if (likely(bp != NULL)) {
594 sector_write(sb, sec, bp->buf_bh, 0);
597 WARN(!bp, "[EXFAT] failed to find buffer_cache(sector:%u).\n", sec);
599 sm_V(&b_sem);
600 } /* end of buf_modify */
602 void buf_lock(struct super_block *sb, UINT32 sec)
604 BUF_CACHE_T *bp;
606 sm_P(&b_sem);
608 bp = buf_cache_find(sb, sec);
609 if (likely(bp != NULL)) bp->flag |= LOCKBIT;
611 WARN(!bp, "[EXFAT] failed to find buffer_cache(sector:%u).\n", sec);
613 sm_V(&b_sem);
614 } /* end of buf_lock */
616 void buf_unlock(struct super_block *sb, UINT32 sec)
618 BUF_CACHE_T *bp;
620 sm_P(&b_sem);
622 bp = buf_cache_find(sb, sec);
623 if (likely(bp != NULL)) bp->flag &= ~(LOCKBIT);
625 WARN(!bp, "[EXFAT] failed to find buffer_cache(sector:%u).\n", sec);
627 sm_V(&b_sem);
628 } /* end of buf_unlock */
630 void buf_release(struct super_block *sb, UINT32 sec)
632 BUF_CACHE_T *bp;
633 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
635 sm_P(&b_sem);
637 bp = buf_cache_find(sb, sec);
638 if (likely(bp != NULL)) {
639 bp->drv = -1;
640 bp->sec = ~0;
641 bp->flag = 0;
643 if(bp->buf_bh) {
644 __brelse(bp->buf_bh);
645 bp->buf_bh = NULL;
648 move_to_lru(bp, &p_fs->buf_cache_lru_list);
651 sm_V(&b_sem);
652 } /* end of buf_release */
654 void buf_release_all(struct super_block *sb)
656 BUF_CACHE_T *bp;
657 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
659 sm_P(&b_sem);
661 bp = p_fs->buf_cache_lru_list.next;
662 while (bp != &p_fs->buf_cache_lru_list) {
663 if (bp->drv == p_fs->drv) {
664 bp->drv = -1;
665 bp->sec = ~0;
666 bp->flag = 0;
668 if(bp->buf_bh) {
669 __brelse(bp->buf_bh);
670 bp->buf_bh = NULL;
673 bp = bp->next;
676 sm_V(&b_sem);
677 } /* end of buf_release_all */
679 void buf_sync(struct super_block *sb)
681 BUF_CACHE_T *bp;
682 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
684 sm_P(&b_sem);
686 bp = p_fs->buf_cache_lru_list.next;
687 while (bp != &p_fs->buf_cache_lru_list) {
688 if ((bp->drv == p_fs->drv) && (bp->flag & DIRTYBIT)) {
689 sync_dirty_buffer(bp->buf_bh);
690 bp->flag &= ~(DIRTYBIT);
692 bp = bp->next;
695 sm_V(&b_sem);
696 } /* end of buf_sync */
698 static BUF_CACHE_T *buf_cache_find(struct super_block *sb, UINT32 sec)
700 INT32 off;
701 BUF_CACHE_T *bp, *hp;
702 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
704 off = (sec + (sec >> p_fs->sectors_per_clu_bits)) & (BUF_CACHE_HASH_SIZE - 1);
706 hp = &(p_fs->buf_cache_hash_list[off]);
707 for (bp = hp->hash_next; bp != hp; bp = bp->hash_next) {
708 if ((bp->drv == p_fs->drv) && (bp->sec == sec)) {
709 touch_buffer(bp->buf_bh);
710 return(bp);
713 return(NULL);
714 } /* end of buf_cache_find */
716 static BUF_CACHE_T *buf_cache_get(struct super_block *sb, UINT32 sec)
718 BUF_CACHE_T *bp;
719 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
721 bp = p_fs->buf_cache_lru_list.prev;
722 while (bp->flag & LOCKBIT) bp = bp->prev;
725 move_to_mru(bp, &p_fs->buf_cache_lru_list);
726 return(bp);
727 } /* end of buf_cache_get */
729 static void buf_cache_insert_hash(struct super_block *sb, BUF_CACHE_T *bp)
731 INT32 off;
732 BUF_CACHE_T *hp;
733 FS_INFO_T *p_fs;
735 p_fs = &(EXFAT_SB(sb)->fs_info);
736 off = (bp->sec + (bp->sec >> p_fs->sectors_per_clu_bits)) & (BUF_CACHE_HASH_SIZE-1);
738 hp = &(p_fs->buf_cache_hash_list[off]);
739 bp->hash_next = hp->hash_next;
740 bp->hash_prev = hp;
741 hp->hash_next->hash_prev = bp;
742 hp->hash_next = bp;
743 } /* end of buf_cache_insert_hash */
745 static void buf_cache_remove_hash(BUF_CACHE_T *bp)
747 (bp->hash_prev)->hash_next = bp->hash_next;
748 (bp->hash_next)->hash_prev = bp->hash_prev;
749 } /* end of buf_cache_remove_hash */
751 /*======================================================================*/
752 /* Local Function Definitions */
753 /*======================================================================*/
755 static void push_to_mru(BUF_CACHE_T *bp, BUF_CACHE_T *list)
757 bp->next = list->next;
758 bp->prev = list;
759 list->next->prev = bp;
760 list->next = bp;
761 } /* end of buf_cache_push_to_mru */
763 static void push_to_lru(BUF_CACHE_T *bp, BUF_CACHE_T *list)
765 bp->prev = list->prev;
766 bp->next = list;
767 list->prev->next = bp;
768 list->prev = bp;
769 } /* end of buf_cache_push_to_lru */
771 static void move_to_mru(BUF_CACHE_T *bp, BUF_CACHE_T *list)
773 bp->prev->next = bp->next;
774 bp->next->prev = bp->prev;
775 push_to_mru(bp, list);
776 } /* end of buf_cache_move_to_mru */
778 static void move_to_lru(BUF_CACHE_T *bp, BUF_CACHE_T *list)
780 bp->prev->next = bp->next;
781 bp->next->prev = bp->prev;
782 push_to_lru(bp, list);
783 } /* end of buf_cache_move_to_lru */
785 /* end of exfat_cache.c */