123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769 |
- /*
- * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
- #include "exfat_config.h"
- #include "exfat_global.h"
- #include "exfat_data.h"
- #include "exfat_cache.h"
- #include "exfat_super.h"
- #include "exfat.h"
- extern FS_STRUCT_T fs_struct[];
- #define sm_P(s)
- #define sm_V(s)
- static INT32 __FAT_read(struct super_block *sb, UINT32 loc, UINT32 *content);
- static INT32 __FAT_write(struct super_block *sb, UINT32 loc, UINT32 content);
- static BUF_CACHE_T *FAT_cache_find(struct super_block *sb, UINT32 sec);
- static BUF_CACHE_T *FAT_cache_get(struct super_block *sb, UINT32 sec);
- static void FAT_cache_insert_hash(struct super_block *sb, BUF_CACHE_T *bp);
- static void FAT_cache_remove_hash(BUF_CACHE_T *bp);
- static UINT8 *__buf_getblk(struct super_block *sb, UINT32 sec);
- static BUF_CACHE_T *buf_cache_find(struct super_block *sb, UINT32 sec);
- static BUF_CACHE_T *buf_cache_get(struct super_block *sb, UINT32 sec);
- static void buf_cache_insert_hash(struct super_block *sb, BUF_CACHE_T *bp);
- static void buf_cache_remove_hash(BUF_CACHE_T *bp);
- static void push_to_mru(BUF_CACHE_T *bp, BUF_CACHE_T *list);
- static void push_to_lru(BUF_CACHE_T *bp, BUF_CACHE_T *list);
- static void move_to_mru(BUF_CACHE_T *bp, BUF_CACHE_T *list);
- static void move_to_lru(BUF_CACHE_T *bp, BUF_CACHE_T *list);
- INT32 buf_init(struct super_block *sb)
- {
- FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
- INT32 i;
- p_fs->FAT_cache_lru_list.next = p_fs->FAT_cache_lru_list.prev = &p_fs->FAT_cache_lru_list;
- for (i = 0; i < FAT_CACHE_SIZE; i++) {
- p_fs->FAT_cache_array[i].drv = -1;
- p_fs->FAT_cache_array[i].sec = ~0;
- p_fs->FAT_cache_array[i].flag = 0;
- p_fs->FAT_cache_array[i].buf_bh = NULL;
- p_fs->FAT_cache_array[i].prev = p_fs->FAT_cache_array[i].next = NULL;
- push_to_mru(&(p_fs->FAT_cache_array[i]), &p_fs->FAT_cache_lru_list);
- }
- p_fs->buf_cache_lru_list.next = p_fs->buf_cache_lru_list.prev = &p_fs->buf_cache_lru_list;
- for (i = 0; i < BUF_CACHE_SIZE; i++) {
- p_fs->buf_cache_array[i].drv = -1;
- p_fs->buf_cache_array[i].sec = ~0;
- p_fs->buf_cache_array[i].flag = 0;
- p_fs->buf_cache_array[i].buf_bh = NULL;
- p_fs->buf_cache_array[i].prev = p_fs->buf_cache_array[i].next = NULL;
- push_to_mru(&(p_fs->buf_cache_array[i]), &p_fs->buf_cache_lru_list);
- }
- for (i = 0; i < FAT_CACHE_HASH_SIZE; i++) {
- p_fs->FAT_cache_hash_list[i].drv = -1;
- p_fs->FAT_cache_hash_list[i].sec = ~0;
- 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]);
- }
- for (i = 0; i < FAT_CACHE_SIZE; i++) {
- FAT_cache_insert_hash(sb, &(p_fs->FAT_cache_array[i]));
- }
- for (i = 0; i < BUF_CACHE_HASH_SIZE; i++) {
- p_fs->buf_cache_hash_list[i].drv = -1;
- p_fs->buf_cache_hash_list[i].sec = ~0;
- 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]);
- }
- for (i = 0; i < BUF_CACHE_SIZE; i++) {
- buf_cache_insert_hash(sb, &(p_fs->buf_cache_array[i]));
- }
- return(FFS_SUCCESS);
- }
- INT32 buf_shutdown(struct super_block *sb)
- {
- return(FFS_SUCCESS);
- }
- INT32 FAT_read(struct super_block *sb, UINT32 loc, UINT32 *content)
- {
- INT32 ret;
- sm_P(&f_sem);
- ret = __FAT_read(sb, loc, content);
- sm_V(&f_sem);
- return(ret);
- }
- INT32 FAT_write(struct super_block *sb, UINT32 loc, UINT32 content)
- {
- INT32 ret;
- sm_P(&f_sem);
- ret = __FAT_write(sb, loc, content);
- sm_V(&f_sem);
- return(ret);
- }
- static INT32 __FAT_read(struct super_block *sb, UINT32 loc, UINT32 *content)
- {
- INT32 off;
- UINT32 sec, _content;
- UINT8 *fat_sector, *fat_entry;
- FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
- BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info);
- if (p_fs->vol_type == FAT12) {
- sec = p_fs->FAT1_start_sector + ((loc + (loc >> 1)) >> p_bd->sector_size_bits);
- off = (loc + (loc >> 1)) & p_bd->sector_size_mask;
- if (off == (p_bd->sector_size-1)) {
- fat_sector = FAT_getblk(sb, sec);
- if (!fat_sector)
- return -1;
- _content = (UINT32) fat_sector[off];
- fat_sector = FAT_getblk(sb, ++sec);
- if (!fat_sector)
- return -1;
- _content |= (UINT32) fat_sector[0] << 8;
- } else {
- fat_sector = FAT_getblk(sb, sec);
- if (!fat_sector)
- return -1;
- fat_entry = &(fat_sector[off]);
- _content = GET16(fat_entry);
- }
- if (loc & 1) _content >>= 4;
- _content &= 0x00000FFF;
- if (_content >= CLUSTER_16(0x0FF8)) {
- *content = CLUSTER_32(~0);
- return 0;
- } else {
- *content = CLUSTER_32(_content);
- return 0;
- }
- } else if (p_fs->vol_type == FAT16) {
- sec = p_fs->FAT1_start_sector + (loc >> (p_bd->sector_size_bits-1));
- off = (loc << 1) & p_bd->sector_size_mask;
- fat_sector = FAT_getblk(sb, sec);
- if
- (!fat_sector)
- return -1;
- fat_entry = &(fat_sector[off]);
- _content = GET16_A(fat_entry);
- _content &= 0x0000FFFF;
- if (_content >= CLUSTER_16(0xFFF8)) {
- *content = CLUSTER_32(~0);
- return 0;
- } else {
- *content = CLUSTER_32(_content);
- return 0;
- }
- } else if (p_fs->vol_type == FAT32) {
- sec = p_fs->FAT1_start_sector + (loc >> (p_bd->sector_size_bits-2));
- off = (loc << 2) & p_bd->sector_size_mask;
- fat_sector = FAT_getblk(sb, sec);
- if (!fat_sector)
- return -1;
- fat_entry = &(fat_sector[off]);
- _content = GET32_A(fat_entry);
- _content &= 0x0FFFFFFF;
- if (_content >= CLUSTER_32(0x0FFFFFF8)) {
- *content = CLUSTER_32(~0);
- return 0;
- } else {
- *content = CLUSTER_32(_content);
- return 0;
- }
- } else {
- sec = p_fs->FAT1_start_sector + (loc >> (p_bd->sector_size_bits-2));
- off = (loc << 2) & p_bd->sector_size_mask;
- fat_sector = FAT_getblk(sb, sec);
- if (!fat_sector)
- return -1;
- fat_entry = &(fat_sector[off]);
- _content = GET32_A(fat_entry);
- if (_content >= CLUSTER_32(0xFFFFFFF8)) {
- *content = CLUSTER_32(~0);
- return 0;
- } else {
- *content = CLUSTER_32(_content);
- return 0;
- }
- }
- *content = CLUSTER_32(~0);
- return 0;
- }
- static INT32 __FAT_write(struct super_block *sb, UINT32 loc, UINT32 content)
- {
- INT32 off;
- UINT32 sec;
- UINT8 *fat_sector, *fat_entry;
- FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
- BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info);
- if (p_fs->vol_type == FAT12) {
- content &= 0x00000FFF;
- sec = p_fs->FAT1_start_sector + ((loc + (loc >> 1)) >> p_bd->sector_size_bits);
- off = (loc + (loc >> 1)) & p_bd->sector_size_mask;
- fat_sector = FAT_getblk(sb, sec);
- if (!fat_sector)
- return -1;
- if (loc & 1) {
- content <<= 4;
- if (off == (p_bd->sector_size-1)) {
- fat_sector[off] = (UINT8)(content | (fat_sector[off] & 0x0F));
- FAT_modify(sb, sec);
- fat_sector = FAT_getblk(sb, ++sec);
- if (!fat_sector)
- return -1;
- fat_sector[0] = (UINT8)(content >> 8);
- } else {
- fat_entry = &(fat_sector[off]);
- content |= GET16(fat_entry) & 0x000F;
- SET16(fat_entry, content);
- }
- } else {
- fat_sector[off] = (UINT8)(content);
- if (off == (p_bd->sector_size-1)) {
- fat_sector[off] = (UINT8)(content);
- FAT_modify(sb, sec);
- fat_sector = FAT_getblk(sb, ++sec);
- fat_sector[0] = (UINT8)((fat_sector[0] & 0xF0) | (content >> 8));
- } else {
- fat_entry = &(fat_sector[off]);
- content |= GET16(fat_entry) & 0xF000;
- SET16(fat_entry, content);
- }
- }
- }
- else if (p_fs->vol_type == FAT16) {
- content &= 0x0000FFFF;
- sec = p_fs->FAT1_start_sector + (loc >> (p_bd->sector_size_bits-1));
- off = (loc << 1) & p_bd->sector_size_mask;
- fat_sector = FAT_getblk(sb, sec);
- if (!fat_sector)
- return -1;
- fat_entry = &(fat_sector[off]);
- SET16_A(fat_entry, content);
- }
- else if (p_fs->vol_type == FAT32) {
- content &= 0x0FFFFFFF;
- sec = p_fs->FAT1_start_sector + (loc >> (p_bd->sector_size_bits-2));
- off = (loc << 2) & p_bd->sector_size_mask;
- fat_sector = FAT_getblk(sb, sec);
- if (!fat_sector)
- return -1;
- fat_entry = &(fat_sector[off]);
- content |= GET32_A(fat_entry) & 0xF0000000;
- SET32_A(fat_entry, content);
- }
- else {
- sec = p_fs->FAT1_start_sector + (loc >> (p_bd->sector_size_bits-2));
- off = (loc << 2) & p_bd->sector_size_mask;
- fat_sector = FAT_getblk(sb, sec);
- if (!fat_sector)
- return -1;
- fat_entry = &(fat_sector[off]);
- SET32_A(fat_entry, content);
- }
- FAT_modify(sb, sec);
- return 0;
- }
- UINT8 *FAT_getblk(struct super_block *sb, UINT32 sec)
- {
- BUF_CACHE_T *bp;
- FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
- bp = FAT_cache_find(sb, sec);
- if (bp != NULL) {
- move_to_mru(bp, &p_fs->FAT_cache_lru_list);
- return(bp->buf_bh->b_data);
- }
- bp = FAT_cache_get(sb, sec);
- FAT_cache_remove_hash(bp);
- bp->drv = p_fs->drv;
- bp->sec = sec;
- bp->flag = 0;
- FAT_cache_insert_hash(sb, bp);
- if (sector_read(sb, sec, &(bp->buf_bh), 1) != FFS_SUCCESS) {
- FAT_cache_remove_hash(bp);
- bp->drv = -1;
- bp->sec = ~0;
- bp->flag = 0;
- bp->buf_bh = NULL;
- move_to_lru(bp, &p_fs->FAT_cache_lru_list);
- return NULL;
- }
- return(bp->buf_bh->b_data);
- }
- void FAT_modify(struct super_block *sb, UINT32 sec)
- {
- BUF_CACHE_T *bp;
- bp = FAT_cache_find(sb, sec);
- if (bp != NULL) {
- sector_write(sb, sec, bp->buf_bh, 0);
- }
- }
- void FAT_release_all(struct super_block *sb)
- {
- BUF_CACHE_T *bp;
- FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
- sm_P(&f_sem);
- bp = p_fs->FAT_cache_lru_list.next;
- while (bp != &p_fs->FAT_cache_lru_list) {
- if (bp->drv == p_fs->drv) {
- bp->drv = -1;
- bp->sec = ~0;
- bp->flag = 0;
- if(bp->buf_bh) {
- __brelse(bp->buf_bh);
- bp->buf_bh = NULL;
- }
- }
- bp = bp->next;
- }
- sm_V(&f_sem);
- }
- void FAT_sync(struct super_block *sb)
- {
- BUF_CACHE_T *bp;
- FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
- sm_P(&f_sem);
- bp = p_fs->FAT_cache_lru_list.next;
- while (bp != &p_fs->FAT_cache_lru_list) {
- if ((bp->drv == p_fs->drv) && (bp->flag & DIRTYBIT)) {
- sync_dirty_buffer(bp->buf_bh);
- bp->flag &= ~(DIRTYBIT);
- }
- bp = bp->next;
- }
- sm_V(&f_sem);
- }
- static BUF_CACHE_T *FAT_cache_find(struct super_block *sb, UINT32 sec)
- {
- INT32 off;
- BUF_CACHE_T *bp, *hp;
- FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
- off = (sec + (sec >> p_fs->sectors_per_clu_bits)) & (FAT_CACHE_HASH_SIZE - 1);
- hp = &(p_fs->FAT_cache_hash_list[off]);
- for (bp = hp->hash_next; bp != hp; bp = bp->hash_next) {
- if ((bp->drv == p_fs->drv) && (bp->sec == sec)) {
- WARN(!bp->buf_bh, "[EXFAT] FAT_cache has no bh. "
- "It will make system panic.\n");
- touch_buffer(bp->buf_bh);
- return(bp);
- }
- }
- return(NULL);
- }
- static BUF_CACHE_T *FAT_cache_get(struct super_block *sb, UINT32 sec)
- {
- BUF_CACHE_T *bp;
- FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
- bp = p_fs->FAT_cache_lru_list.prev;
- move_to_mru(bp, &p_fs->FAT_cache_lru_list);
- return(bp);
- }
- static void FAT_cache_insert_hash(struct super_block *sb, BUF_CACHE_T *bp)
- {
- INT32 off;
- BUF_CACHE_T *hp;
- FS_INFO_T *p_fs;
- p_fs = &(EXFAT_SB(sb)->fs_info);
- off = (bp->sec + (bp->sec >> p_fs->sectors_per_clu_bits)) & (FAT_CACHE_HASH_SIZE-1);
- hp = &(p_fs->FAT_cache_hash_list[off]);
- bp->hash_next = hp->hash_next;
- bp->hash_prev = hp;
- hp->hash_next->hash_prev = bp;
- hp->hash_next = bp;
- }
- static void FAT_cache_remove_hash(BUF_CACHE_T *bp)
- {
- (bp->hash_prev)->hash_next = bp->hash_next;
- (bp->hash_next)->hash_prev = bp->hash_prev;
- }
- UINT8 *buf_getblk(struct super_block *sb, UINT32 sec)
- {
- UINT8 *buf;
- sm_P(&b_sem);
- buf = __buf_getblk(sb, sec);
- sm_V(&b_sem);
- return(buf);
- }
- static UINT8 *__buf_getblk(struct super_block *sb, UINT32 sec)
- {
- BUF_CACHE_T *bp;
- FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
- bp = buf_cache_find(sb, sec);
- if (bp != NULL) {
- move_to_mru(bp, &p_fs->buf_cache_lru_list);
- return(bp->buf_bh->b_data);
- }
- bp = buf_cache_get(sb, sec);
- buf_cache_remove_hash(bp);
- bp->drv = p_fs->drv;
- bp->sec = sec;
- bp->flag = 0;
- buf_cache_insert_hash(sb, bp);
- if (sector_read(sb, sec, &(bp->buf_bh), 1) != FFS_SUCCESS) {
- buf_cache_remove_hash(bp);
- bp->drv = -1;
- bp->sec = ~0;
- bp->flag = 0;
- bp->buf_bh = NULL;
- move_to_lru(bp, &p_fs->buf_cache_lru_list);
- return NULL;
- }
- return(bp->buf_bh->b_data);
- }
- void buf_modify(struct super_block *sb, UINT32 sec)
- {
- BUF_CACHE_T *bp;
- sm_P(&b_sem);
- bp = buf_cache_find(sb, sec);
- if (likely(bp != NULL)) {
- sector_write(sb, sec, bp->buf_bh, 0);
- }
- WARN(!bp, "[EXFAT] failed to find buffer_cache(sector:%u).\n", sec);
- sm_V(&b_sem);
- }
- void buf_lock(struct super_block *sb, UINT32 sec)
- {
- BUF_CACHE_T *bp;
- sm_P(&b_sem);
- bp = buf_cache_find(sb, sec);
- if (likely(bp != NULL)) bp->flag |= LOCKBIT;
- WARN(!bp, "[EXFAT] failed to find buffer_cache(sector:%u).\n", sec);
- sm_V(&b_sem);
- }
- void buf_unlock(struct super_block *sb, UINT32 sec)
- {
- BUF_CACHE_T *bp;
- sm_P(&b_sem);
- bp = buf_cache_find(sb, sec);
- if (likely(bp != NULL)) bp->flag &= ~(LOCKBIT);
- WARN(!bp, "[EXFAT] failed to find buffer_cache(sector:%u).\n", sec);
- sm_V(&b_sem);
- }
- void buf_release(struct super_block *sb, UINT32 sec)
- {
- BUF_CACHE_T *bp;
- FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
- sm_P(&b_sem);
- bp = buf_cache_find(sb, sec);
- if (likely(bp != NULL)) {
- bp->drv = -1;
- bp->sec = ~0;
- bp->flag = 0;
- if(bp->buf_bh) {
- __brelse(bp->buf_bh);
- bp->buf_bh = NULL;
- }
- move_to_lru(bp, &p_fs->buf_cache_lru_list);
- }
- sm_V(&b_sem);
- }
- void buf_release_all(struct super_block *sb)
- {
- BUF_CACHE_T *bp;
- FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
- sm_P(&b_sem);
- bp = p_fs->buf_cache_lru_list.next;
- while (bp != &p_fs->buf_cache_lru_list) {
- if (bp->drv == p_fs->drv) {
- bp->drv = -1;
- bp->sec = ~0;
- bp->flag = 0;
- if(bp->buf_bh) {
- __brelse(bp->buf_bh);
- bp->buf_bh = NULL;
- }
- }
- bp = bp->next;
- }
- sm_V(&b_sem);
- }
- void buf_sync(struct super_block *sb)
- {
- BUF_CACHE_T *bp;
- FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
- sm_P(&b_sem);
- bp = p_fs->buf_cache_lru_list.next;
- while (bp != &p_fs->buf_cache_lru_list) {
- if ((bp->drv == p_fs->drv) && (bp->flag & DIRTYBIT)) {
- sync_dirty_buffer(bp->buf_bh);
- bp->flag &= ~(DIRTYBIT);
- }
- bp = bp->next;
- }
- sm_V(&b_sem);
- }
- static BUF_CACHE_T *buf_cache_find(struct super_block *sb, UINT32 sec)
- {
- INT32 off;
- BUF_CACHE_T *bp, *hp;
- FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
- off = (sec + (sec >> p_fs->sectors_per_clu_bits)) & (BUF_CACHE_HASH_SIZE - 1);
- hp = &(p_fs->buf_cache_hash_list[off]);
- for (bp = hp->hash_next; bp != hp; bp = bp->hash_next) {
- if ((bp->drv == p_fs->drv) && (bp->sec == sec)) {
- touch_buffer(bp->buf_bh);
- return(bp);
- }
- }
- return(NULL);
- }
- static BUF_CACHE_T *buf_cache_get(struct super_block *sb, UINT32 sec)
- {
- BUF_CACHE_T *bp;
- FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
- bp = p_fs->buf_cache_lru_list.prev;
- while (bp->flag & LOCKBIT) bp = bp->prev;
- move_to_mru(bp, &p_fs->buf_cache_lru_list);
- return(bp);
- }
- static void buf_cache_insert_hash(struct super_block *sb, BUF_CACHE_T *bp)
- {
- INT32 off;
- BUF_CACHE_T *hp;
- FS_INFO_T *p_fs;
- p_fs = &(EXFAT_SB(sb)->fs_info);
- off = (bp->sec + (bp->sec >> p_fs->sectors_per_clu_bits)) & (BUF_CACHE_HASH_SIZE-1);
- hp = &(p_fs->buf_cache_hash_list[off]);
- bp->hash_next = hp->hash_next;
- bp->hash_prev = hp;
- hp->hash_next->hash_prev = bp;
- hp->hash_next = bp;
- }
- static void buf_cache_remove_hash(BUF_CACHE_T *bp)
- {
- (bp->hash_prev)->hash_next = bp->hash_next;
- (bp->hash_next)->hash_prev = bp->hash_prev;
- }
- static void push_to_mru(BUF_CACHE_T *bp, BUF_CACHE_T *list)
- {
- bp->next = list->next;
- bp->prev = list;
- list->next->prev = bp;
- list->next = bp;
- }
- static void push_to_lru(BUF_CACHE_T *bp, BUF_CACHE_T *list)
- {
- bp->prev = list->prev;
- bp->next = list;
- list->prev->next = bp;
- list->prev = bp;
- }
- static void move_to_mru(BUF_CACHE_T *bp, BUF_CACHE_T *list)
- {
- bp->prev->next = bp->next;
- bp->next->prev = bp->prev;
- push_to_mru(bp, list);
- }
- static void move_to_lru(BUF_CACHE_T *bp, BUF_CACHE_T *list)
- {
- bp->prev->next = bp->next;
- bp->next->prev = bp->prev;
- push_to_lru(bp, list);
- }
- INT32 buf_cache_readahead(struct super_block * sb, UINT32 sec)
- {
- FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
- struct buffer_head *bh;
- UINT32 max_ra_count = DCACHE_MAX_RA_SIZE >> sb->s_blocksize_bits;
- UINT32 page_ra_count = PAGE_SIZE >> sb->s_blocksize_bits;
- UINT32 adj_ra_count = max(p_fs->sectors_per_clu, page_ra_count);
- UINT32 ra_count = min(adj_ra_count, max_ra_count);
- if (p_fs->sectors_per_clu == 1)
- return 0;
- if (sec < p_fs->data_start_sector)
- return (FFS_MEDIAERR);
- /* Not sector aligned with ra_count, resize ra_count to page size */
- if ((sec - p_fs->data_start_sector) & (ra_count - 1))
- ra_count = page_ra_count;
- bh = sb_find_get_block(sb, sec);
- if (!bh || !buffer_uptodate(bh))
- bdev_reada(sb, sec, ra_count);
- brelse(bh);
- return 0;
- }
|