root/drivers/staging/exfat/exfat_cache.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. FAT_cache_find
  2. push_to_mru
  3. push_to_lru
  4. move_to_mru
  5. move_to_lru
  6. FAT_cache_get
  7. FAT_cache_insert_hash
  8. FAT_cache_remove_hash
  9. buf_cache_insert_hash
  10. buf_cache_remove_hash
  11. buf_init
  12. buf_shutdown
  13. __FAT_read
  14. FAT_read
  15. __FAT_write
  16. FAT_write
  17. FAT_getblk
  18. FAT_modify
  19. FAT_release_all
  20. FAT_sync
  21. buf_cache_find
  22. buf_cache_get
  23. __buf_getblk
  24. buf_getblk
  25. buf_modify
  26. buf_lock
  27. buf_unlock
  28. buf_release
  29. buf_release_all
  30. buf_sync

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *  Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
   4  */
   5 
   6 #include <linux/buffer_head.h>
   7 #include <linux/fs.h>
   8 #include <linux/mutex.h>
   9 #include "exfat.h"
  10 
  11 #define LOCKBIT         0x01
  12 #define DIRTYBIT        0x02
  13 
  14 /* Local variables */
  15 static DEFINE_SEMAPHORE(f_sem);
  16 static DEFINE_SEMAPHORE(b_sem);
  17 
  18 static struct buf_cache_t *FAT_cache_find(struct super_block *sb, sector_t sec)
  19 {
  20         s32 off;
  21         struct buf_cache_t *bp, *hp;
  22         struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
  23 
  24         off = (sec +
  25                (sec >> p_fs->sectors_per_clu_bits)) & (FAT_CACHE_HASH_SIZE - 1);
  26 
  27         hp = &p_fs->FAT_cache_hash_list[off];
  28         for (bp = hp->hash_next; bp != hp; bp = bp->hash_next) {
  29                 if ((bp->drv == p_fs->drv) && (bp->sec == sec)) {
  30                         WARN(!bp->buf_bh,
  31                              "[EXFAT] FAT_cache has no bh. It will make system panic.\n");
  32 
  33                         touch_buffer(bp->buf_bh);
  34                         return bp;
  35                 }
  36         }
  37         return NULL;
  38 }
  39 
  40 static void push_to_mru(struct buf_cache_t *bp, struct buf_cache_t *list)
  41 {
  42         bp->next = list->next;
  43         bp->prev = list;
  44         list->next->prev = bp;
  45         list->next = bp;
  46 }
  47 
  48 static void push_to_lru(struct buf_cache_t *bp, struct buf_cache_t *list)
  49 {
  50         bp->prev = list->prev;
  51         bp->next = list;
  52         list->prev->next = bp;
  53         list->prev = bp;
  54 }
  55 
  56 static void move_to_mru(struct buf_cache_t *bp, struct buf_cache_t *list)
  57 {
  58         bp->prev->next = bp->next;
  59         bp->next->prev = bp->prev;
  60         push_to_mru(bp, list);
  61 }
  62 
  63 static void move_to_lru(struct buf_cache_t *bp, struct buf_cache_t *list)
  64 {
  65         bp->prev->next = bp->next;
  66         bp->next->prev = bp->prev;
  67         push_to_lru(bp, list);
  68 }
  69 
  70 static struct buf_cache_t *FAT_cache_get(struct super_block *sb, sector_t sec)
  71 {
  72         struct buf_cache_t *bp;
  73         struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
  74 
  75         bp = p_fs->FAT_cache_lru_list.prev;
  76 
  77         move_to_mru(bp, &p_fs->FAT_cache_lru_list);
  78         return bp;
  79 }
  80 
  81 static void FAT_cache_insert_hash(struct super_block *sb,
  82                                   struct buf_cache_t *bp)
  83 {
  84         s32 off;
  85         struct buf_cache_t *hp;
  86         struct fs_info_t *p_fs;
  87 
  88         p_fs = &(EXFAT_SB(sb)->fs_info);
  89         off = (bp->sec +
  90                (bp->sec >> p_fs->sectors_per_clu_bits)) &
  91                 (FAT_CACHE_HASH_SIZE - 1);
  92 
  93         hp = &p_fs->FAT_cache_hash_list[off];
  94         bp->hash_next = hp->hash_next;
  95         bp->hash_prev = hp;
  96         hp->hash_next->hash_prev = bp;
  97         hp->hash_next = bp;
  98 }
  99 
 100 static void FAT_cache_remove_hash(struct buf_cache_t *bp)
 101 {
 102         (bp->hash_prev)->hash_next = bp->hash_next;
 103         (bp->hash_next)->hash_prev = bp->hash_prev;
 104 }
 105 
 106 static void buf_cache_insert_hash(struct super_block *sb,
 107                                   struct buf_cache_t *bp)
 108 {
 109         s32 off;
 110         struct buf_cache_t *hp;
 111         struct fs_info_t *p_fs;
 112 
 113         p_fs = &(EXFAT_SB(sb)->fs_info);
 114         off = (bp->sec +
 115                (bp->sec >> p_fs->sectors_per_clu_bits)) &
 116                 (BUF_CACHE_HASH_SIZE - 1);
 117 
 118         hp = &p_fs->buf_cache_hash_list[off];
 119         bp->hash_next = hp->hash_next;
 120         bp->hash_prev = hp;
 121         hp->hash_next->hash_prev = bp;
 122         hp->hash_next = bp;
 123 }
 124 
 125 static void buf_cache_remove_hash(struct buf_cache_t *bp)
 126 {
 127         (bp->hash_prev)->hash_next = bp->hash_next;
 128         (bp->hash_next)->hash_prev = bp->hash_prev;
 129 }
 130 
 131 void buf_init(struct super_block *sb)
 132 {
 133         struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
 134 
 135         int i;
 136 
 137         /* LRU list */
 138         p_fs->FAT_cache_lru_list.next = &p_fs->FAT_cache_lru_list;
 139         p_fs->FAT_cache_lru_list.prev = &p_fs->FAT_cache_lru_list;
 140 
 141         for (i = 0; i < FAT_CACHE_SIZE; i++) {
 142                 p_fs->FAT_cache_array[i].drv = -1;
 143                 p_fs->FAT_cache_array[i].sec = ~0;
 144                 p_fs->FAT_cache_array[i].flag = 0;
 145                 p_fs->FAT_cache_array[i].buf_bh = NULL;
 146                 p_fs->FAT_cache_array[i].prev = NULL;
 147                 p_fs->FAT_cache_array[i].next = NULL;
 148                 push_to_mru(&p_fs->FAT_cache_array[i],
 149                             &p_fs->FAT_cache_lru_list);
 150         }
 151 
 152         p_fs->buf_cache_lru_list.next = &p_fs->buf_cache_lru_list;
 153         p_fs->buf_cache_lru_list.prev = &p_fs->buf_cache_lru_list;
 154 
 155         for (i = 0; i < BUF_CACHE_SIZE; i++) {
 156                 p_fs->buf_cache_array[i].drv = -1;
 157                 p_fs->buf_cache_array[i].sec = ~0;
 158                 p_fs->buf_cache_array[i].flag = 0;
 159                 p_fs->buf_cache_array[i].buf_bh = NULL;
 160                 p_fs->buf_cache_array[i].prev = NULL;
 161                 p_fs->buf_cache_array[i].next = NULL;
 162                 push_to_mru(&p_fs->buf_cache_array[i],
 163                             &p_fs->buf_cache_lru_list);
 164         }
 165 
 166         /* HASH list */
 167         for (i = 0; i < FAT_CACHE_HASH_SIZE; i++) {
 168                 p_fs->FAT_cache_hash_list[i].drv = -1;
 169                 p_fs->FAT_cache_hash_list[i].sec = ~0;
 170                 p_fs->FAT_cache_hash_list[i].hash_next =
 171                         &p_fs->FAT_cache_hash_list[i];
 172                 p_fs->FAT_cache_hash_list[i].hash_prev =
 173                         &p_fs->FAT_cache_hash_list[i];
 174         }
 175 
 176         for (i = 0; i < FAT_CACHE_SIZE; i++)
 177                 FAT_cache_insert_hash(sb, &p_fs->FAT_cache_array[i]);
 178 
 179         for (i = 0; i < BUF_CACHE_HASH_SIZE; i++) {
 180                 p_fs->buf_cache_hash_list[i].drv = -1;
 181                 p_fs->buf_cache_hash_list[i].sec = ~0;
 182                 p_fs->buf_cache_hash_list[i].hash_next =
 183                         &p_fs->buf_cache_hash_list[i];
 184                 p_fs->buf_cache_hash_list[i].hash_prev =
 185                         &p_fs->buf_cache_hash_list[i];
 186         }
 187 
 188         for (i = 0; i < BUF_CACHE_SIZE; i++)
 189                 buf_cache_insert_hash(sb, &p_fs->buf_cache_array[i]);
 190 }
 191 
 192 void buf_shutdown(struct super_block *sb)
 193 {
 194 }
 195 
 196 static int __FAT_read(struct super_block *sb, u32 loc, u32 *content)
 197 {
 198         s32 off;
 199         u32 _content;
 200         sector_t sec;
 201         u8 *fat_sector, *fat_entry;
 202         struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
 203         struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
 204 
 205         if (p_fs->vol_type == FAT12) {
 206                 sec = p_fs->FAT1_start_sector +
 207                         ((loc + (loc >> 1)) >> p_bd->sector_size_bits);
 208                 off = (loc + (loc >> 1)) & p_bd->sector_size_mask;
 209 
 210                 if (off == (p_bd->sector_size - 1)) {
 211                         fat_sector = FAT_getblk(sb, sec);
 212                         if (!fat_sector)
 213                                 return -1;
 214 
 215                         _content = (u32)fat_sector[off];
 216 
 217                         fat_sector = FAT_getblk(sb, ++sec);
 218                         if (!fat_sector)
 219                                 return -1;
 220 
 221                         _content |= (u32)fat_sector[0] << 8;
 222                 } else {
 223                         fat_sector = FAT_getblk(sb, sec);
 224                         if (!fat_sector)
 225                                 return -1;
 226 
 227                         fat_entry = &fat_sector[off];
 228                         _content = GET16(fat_entry);
 229                 }
 230 
 231                 if (loc & 1)
 232                         _content >>= 4;
 233 
 234                 _content &= 0x00000FFF;
 235 
 236                 if (_content >= CLUSTER_16(0x0FF8)) {
 237                         *content = CLUSTER_32(~0);
 238                         return 0;
 239                 }
 240                 *content = CLUSTER_32(_content);
 241                 return 0;
 242         } else if (p_fs->vol_type == FAT16) {
 243                 sec = p_fs->FAT1_start_sector +
 244                         (loc >> (p_bd->sector_size_bits - 1));
 245                 off = (loc << 1) & p_bd->sector_size_mask;
 246 
 247                 fat_sector = FAT_getblk(sb, sec);
 248                 if (!fat_sector)
 249                         return -1;
 250 
 251                 fat_entry = &fat_sector[off];
 252 
 253                 _content = GET16_A(fat_entry);
 254 
 255                 _content &= 0x0000FFFF;
 256 
 257                 if (_content >= CLUSTER_16(0xFFF8)) {
 258                         *content = CLUSTER_32(~0);
 259                         return 0;
 260                 }
 261                 *content = CLUSTER_32(_content);
 262                 return 0;
 263         } else if (p_fs->vol_type == FAT32) {
 264                 sec = p_fs->FAT1_start_sector +
 265                         (loc >> (p_bd->sector_size_bits - 2));
 266                 off = (loc << 2) & p_bd->sector_size_mask;
 267 
 268                 fat_sector = FAT_getblk(sb, sec);
 269                 if (!fat_sector)
 270                         return -1;
 271 
 272                 fat_entry = &fat_sector[off];
 273 
 274                 _content = GET32_A(fat_entry);
 275 
 276                 _content &= 0x0FFFFFFF;
 277 
 278                 if (_content >= CLUSTER_32(0x0FFFFFF8)) {
 279                         *content = CLUSTER_32(~0);
 280                         return 0;
 281                 }
 282                 *content = CLUSTER_32(_content);
 283                 return 0;
 284         } else if (p_fs->vol_type == EXFAT) {
 285                 sec = p_fs->FAT1_start_sector +
 286                         (loc >> (p_bd->sector_size_bits - 2));
 287                 off = (loc << 2) & p_bd->sector_size_mask;
 288 
 289                 fat_sector = FAT_getblk(sb, sec);
 290                 if (!fat_sector)
 291                         return -1;
 292 
 293                 fat_entry = &fat_sector[off];
 294                 _content = GET32_A(fat_entry);
 295 
 296                 if (_content >= CLUSTER_32(0xFFFFFFF8)) {
 297                         *content = CLUSTER_32(~0);
 298                         return 0;
 299                 }
 300                 *content = CLUSTER_32(_content);
 301                 return 0;
 302         }
 303 
 304         /* Unknown volume type, throw in the towel and go home */
 305         *content = CLUSTER_32(~0);
 306         return 0;
 307 }
 308 
 309 /* in : sb, loc
 310  * out: content
 311  * returns 0 on success
 312  *            -1 on error
 313  */
 314 int FAT_read(struct super_block *sb, u32 loc, u32 *content)
 315 {
 316         s32 ret;
 317 
 318         down(&f_sem);
 319         ret = __FAT_read(sb, loc, content);
 320         up(&f_sem);
 321 
 322         return ret;
 323 }
 324 
 325 static s32 __FAT_write(struct super_block *sb, u32 loc, u32 content)
 326 {
 327         s32 off;
 328         sector_t sec;
 329         u8 *fat_sector, *fat_entry;
 330         struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
 331         struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
 332 
 333         if (p_fs->vol_type == FAT12) {
 334                 content &= 0x00000FFF;
 335 
 336                 sec = p_fs->FAT1_start_sector +
 337                         ((loc + (loc >> 1)) >> p_bd->sector_size_bits);
 338                 off = (loc + (loc >> 1)) & p_bd->sector_size_mask;
 339 
 340                 fat_sector = FAT_getblk(sb, sec);
 341                 if (!fat_sector)
 342                         return -1;
 343 
 344                 if (loc & 1) { /* odd */
 345                         content <<= 4;
 346 
 347                         if (off == (p_bd->sector_size - 1)) {
 348                                 fat_sector[off] = (u8)(content |
 349                                                        (fat_sector[off] &
 350                                                         0x0F));
 351                                 FAT_modify(sb, sec);
 352 
 353                                 fat_sector = FAT_getblk(sb, ++sec);
 354                                 if (!fat_sector)
 355                                         return -1;
 356 
 357                                 fat_sector[0] = (u8)(content >> 8);
 358                         } else {
 359                                 fat_entry = &fat_sector[off];
 360                                 content |= GET16(fat_entry) & 0x000F;
 361 
 362                                 SET16(fat_entry, content);
 363                         }
 364                 } else { /* even */
 365                         fat_sector[off] = (u8)(content);
 366 
 367                         if (off == (p_bd->sector_size - 1)) {
 368                                 fat_sector[off] = (u8)(content);
 369                                 FAT_modify(sb, sec);
 370 
 371                                 fat_sector = FAT_getblk(sb, ++sec);
 372                                 if (!fat_sector)
 373                                         return -1;
 374                                 fat_sector[0] = (u8)((fat_sector[0] & 0xF0) |
 375                                                      (content >> 8));
 376                         } else {
 377                                 fat_entry = &fat_sector[off];
 378                                 content |= GET16(fat_entry) & 0xF000;
 379 
 380                                 SET16(fat_entry, content);
 381                         }
 382                 }
 383         }
 384 
 385         else if (p_fs->vol_type == FAT16) {
 386                 content &= 0x0000FFFF;
 387 
 388                 sec = p_fs->FAT1_start_sector + (loc >>
 389                                                  (p_bd->sector_size_bits - 1));
 390                 off = (loc << 1) & p_bd->sector_size_mask;
 391 
 392                 fat_sector = FAT_getblk(sb, sec);
 393                 if (!fat_sector)
 394                         return -1;
 395 
 396                 fat_entry = &fat_sector[off];
 397 
 398                 SET16_A(fat_entry, content);
 399         } else if (p_fs->vol_type == FAT32) {
 400                 content &= 0x0FFFFFFF;
 401 
 402                 sec = p_fs->FAT1_start_sector + (loc >>
 403                                                  (p_bd->sector_size_bits - 2));
 404                 off = (loc << 2) & p_bd->sector_size_mask;
 405 
 406                 fat_sector = FAT_getblk(sb, sec);
 407                 if (!fat_sector)
 408                         return -1;
 409 
 410                 fat_entry = &fat_sector[off];
 411 
 412                 content |= GET32_A(fat_entry) & 0xF0000000;
 413 
 414                 SET32_A(fat_entry, content);
 415         } else { /* p_fs->vol_type == EXFAT */
 416                 sec = p_fs->FAT1_start_sector + (loc >>
 417                                                  (p_bd->sector_size_bits - 2));
 418                 off = (loc << 2) & p_bd->sector_size_mask;
 419 
 420                 fat_sector = FAT_getblk(sb, sec);
 421                 if (!fat_sector)
 422                         return -1;
 423 
 424                 fat_entry = &fat_sector[off];
 425 
 426                 SET32_A(fat_entry, content);
 427         }
 428 
 429         FAT_modify(sb, sec);
 430         return 0;
 431 }
 432 
 433 int FAT_write(struct super_block *sb, u32 loc, u32 content)
 434 {
 435         s32 ret;
 436 
 437         down(&f_sem);
 438         ret = __FAT_write(sb, loc, content);
 439         up(&f_sem);
 440 
 441         return ret;
 442 }
 443 
 444 u8 *FAT_getblk(struct super_block *sb, sector_t sec)
 445 {
 446         struct buf_cache_t *bp;
 447         struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
 448 
 449         bp = FAT_cache_find(sb, sec);
 450         if (bp) {
 451                 move_to_mru(bp, &p_fs->FAT_cache_lru_list);
 452                 return bp->buf_bh->b_data;
 453         }
 454 
 455         bp = FAT_cache_get(sb, sec);
 456 
 457         FAT_cache_remove_hash(bp);
 458 
 459         bp->drv = p_fs->drv;
 460         bp->sec = sec;
 461         bp->flag = 0;
 462 
 463         FAT_cache_insert_hash(sb, bp);
 464 
 465         if (sector_read(sb, sec, &bp->buf_bh, 1) != FFS_SUCCESS) {
 466                 FAT_cache_remove_hash(bp);
 467                 bp->drv = -1;
 468                 bp->sec = ~0;
 469                 bp->flag = 0;
 470                 bp->buf_bh = NULL;
 471 
 472                 move_to_lru(bp, &p_fs->FAT_cache_lru_list);
 473                 return NULL;
 474         }
 475 
 476         return bp->buf_bh->b_data;
 477 }
 478 
 479 void FAT_modify(struct super_block *sb, sector_t sec)
 480 {
 481         struct buf_cache_t *bp;
 482 
 483         bp = FAT_cache_find(sb, sec);
 484         if (bp)
 485                 sector_write(sb, sec, bp->buf_bh, 0);
 486 }
 487 
 488 void FAT_release_all(struct super_block *sb)
 489 {
 490         struct buf_cache_t *bp;
 491         struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
 492 
 493         down(&f_sem);
 494 
 495         bp = p_fs->FAT_cache_lru_list.next;
 496         while (bp != &p_fs->FAT_cache_lru_list) {
 497                 if (bp->drv == p_fs->drv) {
 498                         bp->drv = -1;
 499                         bp->sec = ~0;
 500                         bp->flag = 0;
 501 
 502                         if (bp->buf_bh) {
 503                                 __brelse(bp->buf_bh);
 504                                 bp->buf_bh = NULL;
 505                         }
 506                 }
 507                 bp = bp->next;
 508         }
 509 
 510         up(&f_sem);
 511 }
 512 
 513 void FAT_sync(struct super_block *sb)
 514 {
 515         struct buf_cache_t *bp;
 516         struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
 517 
 518         down(&f_sem);
 519 
 520         bp = p_fs->FAT_cache_lru_list.next;
 521         while (bp != &p_fs->FAT_cache_lru_list) {
 522                 if ((bp->drv == p_fs->drv) && (bp->flag & DIRTYBIT)) {
 523                         sync_dirty_buffer(bp->buf_bh);
 524                         bp->flag &= ~(DIRTYBIT);
 525                 }
 526                 bp = bp->next;
 527         }
 528 
 529         up(&f_sem);
 530 }
 531 
 532 static struct buf_cache_t *buf_cache_find(struct super_block *sb, sector_t sec)
 533 {
 534         s32 off;
 535         struct buf_cache_t *bp, *hp;
 536         struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
 537 
 538         off = (sec + (sec >> p_fs->sectors_per_clu_bits)) &
 539                 (BUF_CACHE_HASH_SIZE - 1);
 540 
 541         hp = &p_fs->buf_cache_hash_list[off];
 542         for (bp = hp->hash_next; bp != hp; bp = bp->hash_next) {
 543                 if ((bp->drv == p_fs->drv) && (bp->sec == sec)) {
 544                         touch_buffer(bp->buf_bh);
 545                         return bp;
 546                 }
 547         }
 548         return NULL;
 549 }
 550 
 551 static struct buf_cache_t *buf_cache_get(struct super_block *sb, sector_t sec)
 552 {
 553         struct buf_cache_t *bp;
 554         struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
 555 
 556         bp = p_fs->buf_cache_lru_list.prev;
 557         while (bp->flag & LOCKBIT)
 558                 bp = bp->prev;
 559 
 560         move_to_mru(bp, &p_fs->buf_cache_lru_list);
 561         return bp;
 562 }
 563 
 564 static u8 *__buf_getblk(struct super_block *sb, sector_t sec)
 565 {
 566         struct buf_cache_t *bp;
 567         struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
 568 
 569         bp = buf_cache_find(sb, sec);
 570         if (bp) {
 571                 move_to_mru(bp, &p_fs->buf_cache_lru_list);
 572                 return bp->buf_bh->b_data;
 573         }
 574 
 575         bp = buf_cache_get(sb, sec);
 576 
 577         buf_cache_remove_hash(bp);
 578 
 579         bp->drv = p_fs->drv;
 580         bp->sec = sec;
 581         bp->flag = 0;
 582 
 583         buf_cache_insert_hash(sb, bp);
 584 
 585         if (sector_read(sb, sec, &bp->buf_bh, 1) != FFS_SUCCESS) {
 586                 buf_cache_remove_hash(bp);
 587                 bp->drv = -1;
 588                 bp->sec = ~0;
 589                 bp->flag = 0;
 590                 bp->buf_bh = NULL;
 591 
 592                 move_to_lru(bp, &p_fs->buf_cache_lru_list);
 593                 return NULL;
 594         }
 595 
 596         return bp->buf_bh->b_data;
 597 }
 598 
 599 u8 *buf_getblk(struct super_block *sb, sector_t sec)
 600 {
 601         u8 *buf;
 602 
 603         down(&b_sem);
 604         buf = __buf_getblk(sb, sec);
 605         up(&b_sem);
 606 
 607         return buf;
 608 }
 609 
 610 void buf_modify(struct super_block *sb, sector_t sec)
 611 {
 612         struct buf_cache_t *bp;
 613 
 614         down(&b_sem);
 615 
 616         bp = buf_cache_find(sb, sec);
 617         if (likely(bp))
 618                 sector_write(sb, sec, bp->buf_bh, 0);
 619 
 620         WARN(!bp, "[EXFAT] failed to find buffer_cache(sector:%llu).\n",
 621              (unsigned long long)sec);
 622 
 623         up(&b_sem);
 624 }
 625 
 626 void buf_lock(struct super_block *sb, sector_t sec)
 627 {
 628         struct buf_cache_t *bp;
 629 
 630         down(&b_sem);
 631 
 632         bp = buf_cache_find(sb, sec);
 633         if (likely(bp))
 634                 bp->flag |= LOCKBIT;
 635 
 636         WARN(!bp, "[EXFAT] failed to find buffer_cache(sector:%llu).\n",
 637              (unsigned long long)sec);
 638 
 639         up(&b_sem);
 640 }
 641 
 642 void buf_unlock(struct super_block *sb, sector_t sec)
 643 {
 644         struct buf_cache_t *bp;
 645 
 646         down(&b_sem);
 647 
 648         bp = buf_cache_find(sb, sec);
 649         if (likely(bp))
 650                 bp->flag &= ~(LOCKBIT);
 651 
 652         WARN(!bp, "[EXFAT] failed to find buffer_cache(sector:%llu).\n",
 653              (unsigned long long)sec);
 654 
 655         up(&b_sem);
 656 }
 657 
 658 void buf_release(struct super_block *sb, sector_t sec)
 659 {
 660         struct buf_cache_t *bp;
 661         struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
 662 
 663         down(&b_sem);
 664 
 665         bp = buf_cache_find(sb, sec);
 666         if (likely(bp)) {
 667                 bp->drv = -1;
 668                 bp->sec = ~0;
 669                 bp->flag = 0;
 670 
 671                 if (bp->buf_bh) {
 672                         __brelse(bp->buf_bh);
 673                         bp->buf_bh = NULL;
 674                 }
 675 
 676                 move_to_lru(bp, &p_fs->buf_cache_lru_list);
 677         }
 678 
 679         up(&b_sem);
 680 }
 681 
 682 void buf_release_all(struct super_block *sb)
 683 {
 684         struct buf_cache_t *bp;
 685         struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
 686 
 687         down(&b_sem);
 688 
 689         bp = p_fs->buf_cache_lru_list.next;
 690         while (bp != &p_fs->buf_cache_lru_list) {
 691                 if (bp->drv == p_fs->drv) {
 692                         bp->drv = -1;
 693                         bp->sec = ~0;
 694                         bp->flag = 0;
 695 
 696                         if (bp->buf_bh) {
 697                                 __brelse(bp->buf_bh);
 698                                 bp->buf_bh = NULL;
 699                         }
 700                 }
 701                 bp = bp->next;
 702         }
 703 
 704         up(&b_sem);
 705 }
 706 
 707 void buf_sync(struct super_block *sb)
 708 {
 709         struct buf_cache_t *bp;
 710         struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
 711 
 712         down(&b_sem);
 713 
 714         bp = p_fs->buf_cache_lru_list.next;
 715         while (bp != &p_fs->buf_cache_lru_list) {
 716                 if ((bp->drv == p_fs->drv) && (bp->flag & DIRTYBIT)) {
 717                         sync_dirty_buffer(bp->buf_bh);
 718                         bp->flag &= ~(DIRTYBIT);
 719                 }
 720                 bp = bp->next;
 721         }
 722 
 723         up(&b_sem);
 724 }

/* [<][>][^][v][top][bottom][index][help] */