exfat_cache.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769
  1. /*
  2. * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
  3. *
  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.
  8. *
  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.
  13. *
  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.
  17. */
  18. #include "exfat_config.h"
  19. #include "exfat_global.h"
  20. #include "exfat_data.h"
  21. #include "exfat_cache.h"
  22. #include "exfat_super.h"
  23. #include "exfat.h"
  24. extern FS_STRUCT_T fs_struct[];
  25. #define sm_P(s)
  26. #define sm_V(s)
  27. static INT32 __FAT_read(struct super_block *sb, UINT32 loc, UINT32 *content);
  28. static INT32 __FAT_write(struct super_block *sb, UINT32 loc, UINT32 content);
  29. static BUF_CACHE_T *FAT_cache_find(struct super_block *sb, UINT32 sec);
  30. static BUF_CACHE_T *FAT_cache_get(struct super_block *sb, UINT32 sec);
  31. static void FAT_cache_insert_hash(struct super_block *sb, BUF_CACHE_T *bp);
  32. static void FAT_cache_remove_hash(BUF_CACHE_T *bp);
  33. static UINT8 *__buf_getblk(struct super_block *sb, UINT32 sec);
  34. static BUF_CACHE_T *buf_cache_find(struct super_block *sb, UINT32 sec);
  35. static BUF_CACHE_T *buf_cache_get(struct super_block *sb, UINT32 sec);
  36. static void buf_cache_insert_hash(struct super_block *sb, BUF_CACHE_T *bp);
  37. static void buf_cache_remove_hash(BUF_CACHE_T *bp);
  38. static void push_to_mru(BUF_CACHE_T *bp, BUF_CACHE_T *list);
  39. static void push_to_lru(BUF_CACHE_T *bp, BUF_CACHE_T *list);
  40. static void move_to_mru(BUF_CACHE_T *bp, BUF_CACHE_T *list);
  41. static void move_to_lru(BUF_CACHE_T *bp, BUF_CACHE_T *list);
  42. INT32 buf_init(struct super_block *sb)
  43. {
  44. FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
  45. INT32 i;
  46. p_fs->FAT_cache_lru_list.next = p_fs->FAT_cache_lru_list.prev = &p_fs->FAT_cache_lru_list;
  47. for (i = 0; i < FAT_CACHE_SIZE; i++) {
  48. p_fs->FAT_cache_array[i].drv = -1;
  49. p_fs->FAT_cache_array[i].sec = ~0;
  50. p_fs->FAT_cache_array[i].flag = 0;
  51. p_fs->FAT_cache_array[i].buf_bh = NULL;
  52. p_fs->FAT_cache_array[i].prev = p_fs->FAT_cache_array[i].next = NULL;
  53. push_to_mru(&(p_fs->FAT_cache_array[i]), &p_fs->FAT_cache_lru_list);
  54. }
  55. p_fs->buf_cache_lru_list.next = p_fs->buf_cache_lru_list.prev = &p_fs->buf_cache_lru_list;
  56. for (i = 0; i < BUF_CACHE_SIZE; i++) {
  57. p_fs->buf_cache_array[i].drv = -1;
  58. p_fs->buf_cache_array[i].sec = ~0;
  59. p_fs->buf_cache_array[i].flag = 0;
  60. p_fs->buf_cache_array[i].buf_bh = NULL;
  61. p_fs->buf_cache_array[i].prev = p_fs->buf_cache_array[i].next = NULL;
  62. push_to_mru(&(p_fs->buf_cache_array[i]), &p_fs->buf_cache_lru_list);
  63. }
  64. for (i = 0; i < FAT_CACHE_HASH_SIZE; i++) {
  65. p_fs->FAT_cache_hash_list[i].drv = -1;
  66. p_fs->FAT_cache_hash_list[i].sec = ~0;
  67. 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]);
  68. }
  69. for (i = 0; i < FAT_CACHE_SIZE; i++) {
  70. FAT_cache_insert_hash(sb, &(p_fs->FAT_cache_array[i]));
  71. }
  72. for (i = 0; i < BUF_CACHE_HASH_SIZE; i++) {
  73. p_fs->buf_cache_hash_list[i].drv = -1;
  74. p_fs->buf_cache_hash_list[i].sec = ~0;
  75. 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]);
  76. }
  77. for (i = 0; i < BUF_CACHE_SIZE; i++) {
  78. buf_cache_insert_hash(sb, &(p_fs->buf_cache_array[i]));
  79. }
  80. return(FFS_SUCCESS);
  81. }
  82. INT32 buf_shutdown(struct super_block *sb)
  83. {
  84. return(FFS_SUCCESS);
  85. }
  86. INT32 FAT_read(struct super_block *sb, UINT32 loc, UINT32 *content)
  87. {
  88. INT32 ret;
  89. sm_P(&f_sem);
  90. ret = __FAT_read(sb, loc, content);
  91. sm_V(&f_sem);
  92. return(ret);
  93. }
  94. INT32 FAT_write(struct super_block *sb, UINT32 loc, UINT32 content)
  95. {
  96. INT32 ret;
  97. sm_P(&f_sem);
  98. ret = __FAT_write(sb, loc, content);
  99. sm_V(&f_sem);
  100. return(ret);
  101. }
  102. static INT32 __FAT_read(struct super_block *sb, UINT32 loc, UINT32 *content)
  103. {
  104. INT32 off;
  105. UINT32 sec, _content;
  106. UINT8 *fat_sector, *fat_entry;
  107. FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
  108. BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info);
  109. if (p_fs->vol_type == FAT12) {
  110. sec = p_fs->FAT1_start_sector + ((loc + (loc >> 1)) >> p_bd->sector_size_bits);
  111. off = (loc + (loc >> 1)) & p_bd->sector_size_mask;
  112. if (off == (p_bd->sector_size-1)) {
  113. fat_sector = FAT_getblk(sb, sec);
  114. if (!fat_sector)
  115. return -1;
  116. _content = (UINT32) fat_sector[off];
  117. fat_sector = FAT_getblk(sb, ++sec);
  118. if (!fat_sector)
  119. return -1;
  120. _content |= (UINT32) fat_sector[0] << 8;
  121. } else {
  122. fat_sector = FAT_getblk(sb, sec);
  123. if (!fat_sector)
  124. return -1;
  125. fat_entry = &(fat_sector[off]);
  126. _content = GET16(fat_entry);
  127. }
  128. if (loc & 1) _content >>= 4;
  129. _content &= 0x00000FFF;
  130. if (_content >= CLUSTER_16(0x0FF8)) {
  131. *content = CLUSTER_32(~0);
  132. return 0;
  133. } else {
  134. *content = CLUSTER_32(_content);
  135. return 0;
  136. }
  137. } else if (p_fs->vol_type == FAT16) {
  138. sec = p_fs->FAT1_start_sector + (loc >> (p_bd->sector_size_bits-1));
  139. off = (loc << 1) & p_bd->sector_size_mask;
  140. fat_sector = FAT_getblk(sb, sec);
  141. if
  142. (!fat_sector)
  143. return -1;
  144. fat_entry = &(fat_sector[off]);
  145. _content = GET16_A(fat_entry);
  146. _content &= 0x0000FFFF;
  147. if (_content >= CLUSTER_16(0xFFF8)) {
  148. *content = CLUSTER_32(~0);
  149. return 0;
  150. } else {
  151. *content = CLUSTER_32(_content);
  152. return 0;
  153. }
  154. } else if (p_fs->vol_type == FAT32) {
  155. sec = p_fs->FAT1_start_sector + (loc >> (p_bd->sector_size_bits-2));
  156. off = (loc << 2) & p_bd->sector_size_mask;
  157. fat_sector = FAT_getblk(sb, sec);
  158. if (!fat_sector)
  159. return -1;
  160. fat_entry = &(fat_sector[off]);
  161. _content = GET32_A(fat_entry);
  162. _content &= 0x0FFFFFFF;
  163. if (_content >= CLUSTER_32(0x0FFFFFF8)) {
  164. *content = CLUSTER_32(~0);
  165. return 0;
  166. } else {
  167. *content = CLUSTER_32(_content);
  168. return 0;
  169. }
  170. } else {
  171. sec = p_fs->FAT1_start_sector + (loc >> (p_bd->sector_size_bits-2));
  172. off = (loc << 2) & p_bd->sector_size_mask;
  173. fat_sector = FAT_getblk(sb, sec);
  174. if (!fat_sector)
  175. return -1;
  176. fat_entry = &(fat_sector[off]);
  177. _content = GET32_A(fat_entry);
  178. if (_content >= CLUSTER_32(0xFFFFFFF8)) {
  179. *content = CLUSTER_32(~0);
  180. return 0;
  181. } else {
  182. *content = CLUSTER_32(_content);
  183. return 0;
  184. }
  185. }
  186. *content = CLUSTER_32(~0);
  187. return 0;
  188. }
  189. static INT32 __FAT_write(struct super_block *sb, UINT32 loc, UINT32 content)
  190. {
  191. INT32 off;
  192. UINT32 sec;
  193. UINT8 *fat_sector, *fat_entry;
  194. FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
  195. BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info);
  196. if (p_fs->vol_type == FAT12) {
  197. content &= 0x00000FFF;
  198. sec = p_fs->FAT1_start_sector + ((loc + (loc >> 1)) >> p_bd->sector_size_bits);
  199. off = (loc + (loc >> 1)) & p_bd->sector_size_mask;
  200. fat_sector = FAT_getblk(sb, sec);
  201. if (!fat_sector)
  202. return -1;
  203. if (loc & 1) {
  204. content <<= 4;
  205. if (off == (p_bd->sector_size-1)) {
  206. fat_sector[off] = (UINT8)(content | (fat_sector[off] & 0x0F));
  207. FAT_modify(sb, sec);
  208. fat_sector = FAT_getblk(sb, ++sec);
  209. if (!fat_sector)
  210. return -1;
  211. fat_sector[0] = (UINT8)(content >> 8);
  212. } else {
  213. fat_entry = &(fat_sector[off]);
  214. content |= GET16(fat_entry) & 0x000F;
  215. SET16(fat_entry, content);
  216. }
  217. } else {
  218. fat_sector[off] = (UINT8)(content);
  219. if (off == (p_bd->sector_size-1)) {
  220. fat_sector[off] = (UINT8)(content);
  221. FAT_modify(sb, sec);
  222. fat_sector = FAT_getblk(sb, ++sec);
  223. fat_sector[0] = (UINT8)((fat_sector[0] & 0xF0) | (content >> 8));
  224. } else {
  225. fat_entry = &(fat_sector[off]);
  226. content |= GET16(fat_entry) & 0xF000;
  227. SET16(fat_entry, content);
  228. }
  229. }
  230. }
  231. else if (p_fs->vol_type == FAT16) {
  232. content &= 0x0000FFFF;
  233. sec = p_fs->FAT1_start_sector + (loc >> (p_bd->sector_size_bits-1));
  234. off = (loc << 1) & p_bd->sector_size_mask;
  235. fat_sector = FAT_getblk(sb, sec);
  236. if (!fat_sector)
  237. return -1;
  238. fat_entry = &(fat_sector[off]);
  239. SET16_A(fat_entry, content);
  240. }
  241. else if (p_fs->vol_type == FAT32) {
  242. content &= 0x0FFFFFFF;
  243. sec = p_fs->FAT1_start_sector + (loc >> (p_bd->sector_size_bits-2));
  244. off = (loc << 2) & p_bd->sector_size_mask;
  245. fat_sector = FAT_getblk(sb, sec);
  246. if (!fat_sector)
  247. return -1;
  248. fat_entry = &(fat_sector[off]);
  249. content |= GET32_A(fat_entry) & 0xF0000000;
  250. SET32_A(fat_entry, content);
  251. }
  252. else {
  253. sec = p_fs->FAT1_start_sector + (loc >> (p_bd->sector_size_bits-2));
  254. off = (loc << 2) & p_bd->sector_size_mask;
  255. fat_sector = FAT_getblk(sb, sec);
  256. if (!fat_sector)
  257. return -1;
  258. fat_entry = &(fat_sector[off]);
  259. SET32_A(fat_entry, content);
  260. }
  261. FAT_modify(sb, sec);
  262. return 0;
  263. }
  264. UINT8 *FAT_getblk(struct super_block *sb, UINT32 sec)
  265. {
  266. BUF_CACHE_T *bp;
  267. FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
  268. bp = FAT_cache_find(sb, sec);
  269. if (bp != NULL) {
  270. move_to_mru(bp, &p_fs->FAT_cache_lru_list);
  271. return(bp->buf_bh->b_data);
  272. }
  273. bp = FAT_cache_get(sb, sec);
  274. FAT_cache_remove_hash(bp);
  275. bp->drv = p_fs->drv;
  276. bp->sec = sec;
  277. bp->flag = 0;
  278. FAT_cache_insert_hash(sb, bp);
  279. if (sector_read(sb, sec, &(bp->buf_bh), 1) != FFS_SUCCESS) {
  280. FAT_cache_remove_hash(bp);
  281. bp->drv = -1;
  282. bp->sec = ~0;
  283. bp->flag = 0;
  284. bp->buf_bh = NULL;
  285. move_to_lru(bp, &p_fs->FAT_cache_lru_list);
  286. return NULL;
  287. }
  288. return(bp->buf_bh->b_data);
  289. }
  290. void FAT_modify(struct super_block *sb, UINT32 sec)
  291. {
  292. BUF_CACHE_T *bp;
  293. bp = FAT_cache_find(sb, sec);
  294. if (bp != NULL) {
  295. sector_write(sb, sec, bp->buf_bh, 0);
  296. }
  297. }
  298. void FAT_release_all(struct super_block *sb)
  299. {
  300. BUF_CACHE_T *bp;
  301. FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
  302. sm_P(&f_sem);
  303. bp = p_fs->FAT_cache_lru_list.next;
  304. while (bp != &p_fs->FAT_cache_lru_list) {
  305. if (bp->drv == p_fs->drv) {
  306. bp->drv = -1;
  307. bp->sec = ~0;
  308. bp->flag = 0;
  309. if(bp->buf_bh) {
  310. __brelse(bp->buf_bh);
  311. bp->buf_bh = NULL;
  312. }
  313. }
  314. bp = bp->next;
  315. }
  316. sm_V(&f_sem);
  317. }
  318. void FAT_sync(struct super_block *sb)
  319. {
  320. BUF_CACHE_T *bp;
  321. FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
  322. sm_P(&f_sem);
  323. bp = p_fs->FAT_cache_lru_list.next;
  324. while (bp != &p_fs->FAT_cache_lru_list) {
  325. if ((bp->drv == p_fs->drv) && (bp->flag & DIRTYBIT)) {
  326. sync_dirty_buffer(bp->buf_bh);
  327. bp->flag &= ~(DIRTYBIT);
  328. }
  329. bp = bp->next;
  330. }
  331. sm_V(&f_sem);
  332. }
  333. static BUF_CACHE_T *FAT_cache_find(struct super_block *sb, UINT32 sec)
  334. {
  335. INT32 off;
  336. BUF_CACHE_T *bp, *hp;
  337. FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
  338. off = (sec + (sec >> p_fs->sectors_per_clu_bits)) & (FAT_CACHE_HASH_SIZE - 1);
  339. hp = &(p_fs->FAT_cache_hash_list[off]);
  340. for (bp = hp->hash_next; bp != hp; bp = bp->hash_next) {
  341. if ((bp->drv == p_fs->drv) && (bp->sec == sec)) {
  342. WARN(!bp->buf_bh, "[EXFAT] FAT_cache has no bh. "
  343. "It will make system panic.\n");
  344. touch_buffer(bp->buf_bh);
  345. return(bp);
  346. }
  347. }
  348. return(NULL);
  349. }
  350. static BUF_CACHE_T *FAT_cache_get(struct super_block *sb, UINT32 sec)
  351. {
  352. BUF_CACHE_T *bp;
  353. FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
  354. bp = p_fs->FAT_cache_lru_list.prev;
  355. move_to_mru(bp, &p_fs->FAT_cache_lru_list);
  356. return(bp);
  357. }
  358. static void FAT_cache_insert_hash(struct super_block *sb, BUF_CACHE_T *bp)
  359. {
  360. INT32 off;
  361. BUF_CACHE_T *hp;
  362. FS_INFO_T *p_fs;
  363. p_fs = &(EXFAT_SB(sb)->fs_info);
  364. off = (bp->sec + (bp->sec >> p_fs->sectors_per_clu_bits)) & (FAT_CACHE_HASH_SIZE-1);
  365. hp = &(p_fs->FAT_cache_hash_list[off]);
  366. bp->hash_next = hp->hash_next;
  367. bp->hash_prev = hp;
  368. hp->hash_next->hash_prev = bp;
  369. hp->hash_next = bp;
  370. }
  371. static void FAT_cache_remove_hash(BUF_CACHE_T *bp)
  372. {
  373. (bp->hash_prev)->hash_next = bp->hash_next;
  374. (bp->hash_next)->hash_prev = bp->hash_prev;
  375. }
  376. UINT8 *buf_getblk(struct super_block *sb, UINT32 sec)
  377. {
  378. UINT8 *buf;
  379. sm_P(&b_sem);
  380. buf = __buf_getblk(sb, sec);
  381. sm_V(&b_sem);
  382. return(buf);
  383. }
  384. static UINT8 *__buf_getblk(struct super_block *sb, UINT32 sec)
  385. {
  386. BUF_CACHE_T *bp;
  387. FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
  388. bp = buf_cache_find(sb, sec);
  389. if (bp != NULL) {
  390. move_to_mru(bp, &p_fs->buf_cache_lru_list);
  391. return(bp->buf_bh->b_data);
  392. }
  393. bp = buf_cache_get(sb, sec);
  394. buf_cache_remove_hash(bp);
  395. bp->drv = p_fs->drv;
  396. bp->sec = sec;
  397. bp->flag = 0;
  398. buf_cache_insert_hash(sb, bp);
  399. if (sector_read(sb, sec, &(bp->buf_bh), 1) != FFS_SUCCESS) {
  400. buf_cache_remove_hash(bp);
  401. bp->drv = -1;
  402. bp->sec = ~0;
  403. bp->flag = 0;
  404. bp->buf_bh = NULL;
  405. move_to_lru(bp, &p_fs->buf_cache_lru_list);
  406. return NULL;
  407. }
  408. return(bp->buf_bh->b_data);
  409. }
  410. void buf_modify(struct super_block *sb, UINT32 sec)
  411. {
  412. BUF_CACHE_T *bp;
  413. sm_P(&b_sem);
  414. bp = buf_cache_find(sb, sec);
  415. if (likely(bp != NULL)) {
  416. sector_write(sb, sec, bp->buf_bh, 0);
  417. }
  418. WARN(!bp, "[EXFAT] failed to find buffer_cache(sector:%u).\n", sec);
  419. sm_V(&b_sem);
  420. }
  421. void buf_lock(struct super_block *sb, UINT32 sec)
  422. {
  423. BUF_CACHE_T *bp;
  424. sm_P(&b_sem);
  425. bp = buf_cache_find(sb, sec);
  426. if (likely(bp != NULL)) bp->flag |= LOCKBIT;
  427. WARN(!bp, "[EXFAT] failed to find buffer_cache(sector:%u).\n", sec);
  428. sm_V(&b_sem);
  429. }
  430. void buf_unlock(struct super_block *sb, UINT32 sec)
  431. {
  432. BUF_CACHE_T *bp;
  433. sm_P(&b_sem);
  434. bp = buf_cache_find(sb, sec);
  435. if (likely(bp != NULL)) bp->flag &= ~(LOCKBIT);
  436. WARN(!bp, "[EXFAT] failed to find buffer_cache(sector:%u).\n", sec);
  437. sm_V(&b_sem);
  438. }
  439. void buf_release(struct super_block *sb, UINT32 sec)
  440. {
  441. BUF_CACHE_T *bp;
  442. FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
  443. sm_P(&b_sem);
  444. bp = buf_cache_find(sb, sec);
  445. if (likely(bp != NULL)) {
  446. bp->drv = -1;
  447. bp->sec = ~0;
  448. bp->flag = 0;
  449. if(bp->buf_bh) {
  450. __brelse(bp->buf_bh);
  451. bp->buf_bh = NULL;
  452. }
  453. move_to_lru(bp, &p_fs->buf_cache_lru_list);
  454. }
  455. sm_V(&b_sem);
  456. }
  457. void buf_release_all(struct super_block *sb)
  458. {
  459. BUF_CACHE_T *bp;
  460. FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
  461. sm_P(&b_sem);
  462. bp = p_fs->buf_cache_lru_list.next;
  463. while (bp != &p_fs->buf_cache_lru_list) {
  464. if (bp->drv == p_fs->drv) {
  465. bp->drv = -1;
  466. bp->sec = ~0;
  467. bp->flag = 0;
  468. if(bp->buf_bh) {
  469. __brelse(bp->buf_bh);
  470. bp->buf_bh = NULL;
  471. }
  472. }
  473. bp = bp->next;
  474. }
  475. sm_V(&b_sem);
  476. }
  477. void buf_sync(struct super_block *sb)
  478. {
  479. BUF_CACHE_T *bp;
  480. FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
  481. sm_P(&b_sem);
  482. bp = p_fs->buf_cache_lru_list.next;
  483. while (bp != &p_fs->buf_cache_lru_list) {
  484. if ((bp->drv == p_fs->drv) && (bp->flag & DIRTYBIT)) {
  485. sync_dirty_buffer(bp->buf_bh);
  486. bp->flag &= ~(DIRTYBIT);
  487. }
  488. bp = bp->next;
  489. }
  490. sm_V(&b_sem);
  491. }
  492. static BUF_CACHE_T *buf_cache_find(struct super_block *sb, UINT32 sec)
  493. {
  494. INT32 off;
  495. BUF_CACHE_T *bp, *hp;
  496. FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
  497. off = (sec + (sec >> p_fs->sectors_per_clu_bits)) & (BUF_CACHE_HASH_SIZE - 1);
  498. hp = &(p_fs->buf_cache_hash_list[off]);
  499. for (bp = hp->hash_next; bp != hp; bp = bp->hash_next) {
  500. if ((bp->drv == p_fs->drv) && (bp->sec == sec)) {
  501. touch_buffer(bp->buf_bh);
  502. return(bp);
  503. }
  504. }
  505. return(NULL);
  506. }
  507. static BUF_CACHE_T *buf_cache_get(struct super_block *sb, UINT32 sec)
  508. {
  509. BUF_CACHE_T *bp;
  510. FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
  511. bp = p_fs->buf_cache_lru_list.prev;
  512. while (bp->flag & LOCKBIT) bp = bp->prev;
  513. move_to_mru(bp, &p_fs->buf_cache_lru_list);
  514. return(bp);
  515. }
  516. static void buf_cache_insert_hash(struct super_block *sb, BUF_CACHE_T *bp)
  517. {
  518. INT32 off;
  519. BUF_CACHE_T *hp;
  520. FS_INFO_T *p_fs;
  521. p_fs = &(EXFAT_SB(sb)->fs_info);
  522. off = (bp->sec + (bp->sec >> p_fs->sectors_per_clu_bits)) & (BUF_CACHE_HASH_SIZE-1);
  523. hp = &(p_fs->buf_cache_hash_list[off]);
  524. bp->hash_next = hp->hash_next;
  525. bp->hash_prev = hp;
  526. hp->hash_next->hash_prev = bp;
  527. hp->hash_next = bp;
  528. }
  529. static void buf_cache_remove_hash(BUF_CACHE_T *bp)
  530. {
  531. (bp->hash_prev)->hash_next = bp->hash_next;
  532. (bp->hash_next)->hash_prev = bp->hash_prev;
  533. }
  534. static void push_to_mru(BUF_CACHE_T *bp, BUF_CACHE_T *list)
  535. {
  536. bp->next = list->next;
  537. bp->prev = list;
  538. list->next->prev = bp;
  539. list->next = bp;
  540. }
  541. static void push_to_lru(BUF_CACHE_T *bp, BUF_CACHE_T *list)
  542. {
  543. bp->prev = list->prev;
  544. bp->next = list;
  545. list->prev->next = bp;
  546. list->prev = bp;
  547. }
  548. static void move_to_mru(BUF_CACHE_T *bp, BUF_CACHE_T *list)
  549. {
  550. bp->prev->next = bp->next;
  551. bp->next->prev = bp->prev;
  552. push_to_mru(bp, list);
  553. }
  554. static void move_to_lru(BUF_CACHE_T *bp, BUF_CACHE_T *list)
  555. {
  556. bp->prev->next = bp->next;
  557. bp->next->prev = bp->prev;
  558. push_to_lru(bp, list);
  559. }
  560. INT32 buf_cache_readahead(struct super_block * sb, UINT32 sec)
  561. {
  562. FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
  563. struct buffer_head *bh;
  564. UINT32 max_ra_count = DCACHE_MAX_RA_SIZE >> sb->s_blocksize_bits;
  565. UINT32 page_ra_count = PAGE_SIZE >> sb->s_blocksize_bits;
  566. UINT32 adj_ra_count = max(p_fs->sectors_per_clu, page_ra_count);
  567. UINT32 ra_count = min(adj_ra_count, max_ra_count);
  568. if (p_fs->sectors_per_clu == 1)
  569. return 0;
  570. if (sec < p_fs->data_start_sector)
  571. return (FFS_MEDIAERR);
  572. /* Not sector aligned with ra_count, resize ra_count to page size */
  573. if ((sec - p_fs->data_start_sector) & (ra_count - 1))
  574. ra_count = page_ra_count;
  575. bh = sb_find_get_block(sb, sec);
  576. if (!bh || !buffer_uptodate(bh))
  577. bdev_reada(sb, sec, ra_count);
  578. brelse(bh);
  579. return 0;
  580. }