.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (C) 2004, OGAWA Hirofumi |
---|
3 | | - * Released under GPL v2. |
---|
4 | 4 | */ |
---|
5 | 5 | |
---|
6 | 6 | #include <linux/blkdev.h> |
---|
.. | .. |
---|
93 | 93 | err_brelse: |
---|
94 | 94 | brelse(bhs[0]); |
---|
95 | 95 | err: |
---|
96 | | - fat_msg(sb, KERN_ERR, "FAT read failed (blocknr %llu)", (llu)blocknr); |
---|
| 96 | + fat_msg_ratelimit(sb, KERN_ERR, "FAT read failed (blocknr %llu)", |
---|
| 97 | + (llu)blocknr); |
---|
97 | 98 | return -EIO; |
---|
98 | 99 | } |
---|
99 | 100 | |
---|
.. | .. |
---|
106 | 107 | fatent->fat_inode = MSDOS_SB(sb)->fat_inode; |
---|
107 | 108 | fatent->bhs[0] = sb_bread(sb, blocknr); |
---|
108 | 109 | if (!fatent->bhs[0]) { |
---|
109 | | - fat_msg(sb, KERN_ERR, "FAT read failed (blocknr %llu)", |
---|
110 | | - (llu)blocknr); |
---|
| 110 | + fat_msg_ratelimit(sb, KERN_ERR, "FAT read failed (blocknr %llu)", |
---|
| 111 | + (llu)blocknr); |
---|
111 | 112 | return -EIO; |
---|
112 | 113 | } |
---|
113 | 114 | fatent->nr_bhs = 1; |
---|
.. | .. |
---|
290 | 291 | |
---|
291 | 292 | mutex_init(&sbi->fat_lock); |
---|
292 | 293 | |
---|
293 | | - switch (sbi->fat_bits) { |
---|
294 | | - case 32: |
---|
| 294 | + if (is_fat32(sbi)) { |
---|
295 | 295 | sbi->fatent_shift = 2; |
---|
296 | 296 | sbi->fatent_ops = &fat32_ops; |
---|
297 | | - break; |
---|
298 | | - case 16: |
---|
| 297 | + } else if (is_fat16(sbi)) { |
---|
299 | 298 | sbi->fatent_shift = 1; |
---|
300 | 299 | sbi->fatent_ops = &fat16_ops; |
---|
301 | | - break; |
---|
302 | | - case 12: |
---|
| 300 | + } else if (is_fat12(sbi)) { |
---|
303 | 301 | sbi->fatent_shift = -1; |
---|
304 | 302 | sbi->fatent_ops = &fat12_ops; |
---|
305 | | - break; |
---|
| 303 | + } else { |
---|
| 304 | + fat_fs_error(sb, "invalid FAT variant, %u bits", sbi->fat_bits); |
---|
306 | 305 | } |
---|
307 | 306 | } |
---|
308 | 307 | |
---|
.. | .. |
---|
310 | 309 | { |
---|
311 | 310 | struct msdos_sb_info *sbi = MSDOS_SB(sb); |
---|
312 | 311 | |
---|
313 | | - if (sb_rdonly(sb) || sbi->fat_bits != 32) |
---|
| 312 | + if (sb_rdonly(sb) || !is_fat32(sbi)) |
---|
314 | 313 | return; |
---|
315 | 314 | |
---|
316 | 315 | __mark_inode_dirty(sbi->fsinfo_inode, I_DIRTY_SYNC); |
---|
.. | .. |
---|
327 | 326 | /* Is this fatent's blocks including this entry? */ |
---|
328 | 327 | if (!fatent->nr_bhs || bhs[0]->b_blocknr != blocknr) |
---|
329 | 328 | return 0; |
---|
330 | | - if (sbi->fat_bits == 12) { |
---|
| 329 | + if (is_fat12(sbi)) { |
---|
331 | 330 | if ((offset + 1) < sb->s_blocksize) { |
---|
332 | 331 | /* This entry is on bhs[0]. */ |
---|
333 | 332 | if (fatent->nr_bhs == 2) { |
---|
.. | .. |
---|
634 | 633 | } |
---|
635 | 634 | EXPORT_SYMBOL_GPL(fat_free_clusters); |
---|
636 | 635 | |
---|
637 | | -/* 128kb is the whole sectors for FAT12 and FAT16 */ |
---|
638 | | -#define FAT_READA_SIZE (128 * 1024) |
---|
| 636 | +struct fatent_ra { |
---|
| 637 | + sector_t cur; |
---|
| 638 | + sector_t limit; |
---|
639 | 639 | |
---|
640 | | -static void fat_ent_reada(struct super_block *sb, struct fat_entry *fatent, |
---|
641 | | - unsigned long reada_blocks) |
---|
| 640 | + unsigned int ra_blocks; |
---|
| 641 | + sector_t ra_advance; |
---|
| 642 | + sector_t ra_next; |
---|
| 643 | + sector_t ra_limit; |
---|
| 644 | +}; |
---|
| 645 | + |
---|
| 646 | +static void fat_ra_init(struct super_block *sb, struct fatent_ra *ra, |
---|
| 647 | + struct fat_entry *fatent, int ent_limit) |
---|
642 | 648 | { |
---|
643 | | - const struct fatent_operations *ops = MSDOS_SB(sb)->fatent_ops; |
---|
644 | | - sector_t blocknr; |
---|
645 | | - int i, offset; |
---|
| 649 | + struct msdos_sb_info *sbi = MSDOS_SB(sb); |
---|
| 650 | + const struct fatent_operations *ops = sbi->fatent_ops; |
---|
| 651 | + sector_t blocknr, block_end; |
---|
| 652 | + int offset; |
---|
| 653 | + /* |
---|
| 654 | + * This is the sequential read, so ra_pages * 2 (but try to |
---|
| 655 | + * align the optimal hardware IO size). |
---|
| 656 | + * [BTW, 128kb covers the whole sectors for FAT12 and FAT16] |
---|
| 657 | + */ |
---|
| 658 | + unsigned long ra_pages = sb->s_bdi->ra_pages; |
---|
| 659 | + unsigned int reada_blocks; |
---|
646 | 660 | |
---|
| 661 | + if (fatent->entry >= ent_limit) |
---|
| 662 | + return; |
---|
| 663 | + |
---|
| 664 | + if (ra_pages > sb->s_bdi->io_pages) |
---|
| 665 | + ra_pages = rounddown(ra_pages, sb->s_bdi->io_pages); |
---|
| 666 | + reada_blocks = ra_pages << (PAGE_SHIFT - sb->s_blocksize_bits + 1); |
---|
| 667 | + |
---|
| 668 | + /* Initialize the range for sequential read */ |
---|
647 | 669 | ops->ent_blocknr(sb, fatent->entry, &offset, &blocknr); |
---|
| 670 | + ops->ent_blocknr(sb, ent_limit - 1, &offset, &block_end); |
---|
| 671 | + ra->cur = 0; |
---|
| 672 | + ra->limit = (block_end + 1) - blocknr; |
---|
648 | 673 | |
---|
649 | | - for (i = 0; i < reada_blocks; i++) |
---|
650 | | - sb_breadahead(sb, blocknr + i); |
---|
| 674 | + /* Advancing the window at half size */ |
---|
| 675 | + ra->ra_blocks = reada_blocks >> 1; |
---|
| 676 | + ra->ra_advance = ra->cur; |
---|
| 677 | + ra->ra_next = ra->cur; |
---|
| 678 | + ra->ra_limit = ra->cur + min_t(sector_t, reada_blocks, ra->limit); |
---|
| 679 | +} |
---|
| 680 | + |
---|
| 681 | +/* Assuming to be called before reading a new block (increments ->cur). */ |
---|
| 682 | +static void fat_ent_reada(struct super_block *sb, struct fatent_ra *ra, |
---|
| 683 | + struct fat_entry *fatent) |
---|
| 684 | +{ |
---|
| 685 | + if (ra->ra_next >= ra->ra_limit) |
---|
| 686 | + return; |
---|
| 687 | + |
---|
| 688 | + if (ra->cur >= ra->ra_advance) { |
---|
| 689 | + struct msdos_sb_info *sbi = MSDOS_SB(sb); |
---|
| 690 | + const struct fatent_operations *ops = sbi->fatent_ops; |
---|
| 691 | + struct blk_plug plug; |
---|
| 692 | + sector_t blocknr, diff; |
---|
| 693 | + int offset; |
---|
| 694 | + |
---|
| 695 | + ops->ent_blocknr(sb, fatent->entry, &offset, &blocknr); |
---|
| 696 | + |
---|
| 697 | + diff = blocknr - ra->cur; |
---|
| 698 | + blk_start_plug(&plug); |
---|
| 699 | + /* |
---|
| 700 | + * FIXME: we would want to directly use the bio with |
---|
| 701 | + * pages to reduce the number of segments. |
---|
| 702 | + */ |
---|
| 703 | + for (; ra->ra_next < ra->ra_limit; ra->ra_next++) |
---|
| 704 | + sb_breadahead(sb, ra->ra_next + diff); |
---|
| 705 | + blk_finish_plug(&plug); |
---|
| 706 | + |
---|
| 707 | + /* Advance the readahead window */ |
---|
| 708 | + ra->ra_advance += ra->ra_blocks; |
---|
| 709 | + ra->ra_limit += min_t(sector_t, |
---|
| 710 | + ra->ra_blocks, ra->limit - ra->ra_limit); |
---|
| 711 | + } |
---|
| 712 | + ra->cur++; |
---|
651 | 713 | } |
---|
652 | 714 | |
---|
653 | 715 | int fat_count_free_clusters(struct super_block *sb) |
---|
.. | .. |
---|
655 | 717 | struct msdos_sb_info *sbi = MSDOS_SB(sb); |
---|
656 | 718 | const struct fatent_operations *ops = sbi->fatent_ops; |
---|
657 | 719 | struct fat_entry fatent; |
---|
658 | | - unsigned long reada_blocks, reada_mask, cur_block; |
---|
| 720 | + struct fatent_ra fatent_ra; |
---|
659 | 721 | int err = 0, free; |
---|
660 | 722 | |
---|
661 | 723 | lock_fat(sbi); |
---|
662 | 724 | if (sbi->free_clusters != -1 && sbi->free_clus_valid) |
---|
663 | 725 | goto out; |
---|
664 | 726 | |
---|
665 | | - reada_blocks = FAT_READA_SIZE >> sb->s_blocksize_bits; |
---|
666 | | - reada_mask = reada_blocks - 1; |
---|
667 | | - cur_block = 0; |
---|
668 | | - |
---|
669 | 727 | free = 0; |
---|
670 | 728 | fatent_init(&fatent); |
---|
671 | 729 | fatent_set_entry(&fatent, FAT_START_ENT); |
---|
| 730 | + fat_ra_init(sb, &fatent_ra, &fatent, sbi->max_cluster); |
---|
672 | 731 | while (fatent.entry < sbi->max_cluster) { |
---|
673 | 732 | /* readahead of fat blocks */ |
---|
674 | | - if ((cur_block & reada_mask) == 0) { |
---|
675 | | - unsigned long rest = sbi->fat_length - cur_block; |
---|
676 | | - fat_ent_reada(sb, &fatent, min(reada_blocks, rest)); |
---|
677 | | - } |
---|
678 | | - cur_block++; |
---|
| 733 | + fat_ent_reada(sb, &fatent_ra, &fatent); |
---|
679 | 734 | |
---|
680 | 735 | err = fat_ent_read_block(sb, &fatent); |
---|
681 | 736 | if (err) |
---|
.. | .. |
---|
709 | 764 | struct msdos_sb_info *sbi = MSDOS_SB(sb); |
---|
710 | 765 | const struct fatent_operations *ops = sbi->fatent_ops; |
---|
711 | 766 | struct fat_entry fatent; |
---|
| 767 | + struct fatent_ra fatent_ra; |
---|
712 | 768 | u64 ent_start, ent_end, minlen, trimmed = 0; |
---|
713 | 769 | u32 free = 0; |
---|
714 | | - unsigned long reada_blocks, reada_mask, cur_block = 0; |
---|
715 | 770 | int err = 0; |
---|
716 | 771 | |
---|
717 | 772 | /* |
---|
.. | .. |
---|
729 | 784 | if (ent_end >= sbi->max_cluster) |
---|
730 | 785 | ent_end = sbi->max_cluster - 1; |
---|
731 | 786 | |
---|
732 | | - reada_blocks = FAT_READA_SIZE >> sb->s_blocksize_bits; |
---|
733 | | - reada_mask = reada_blocks - 1; |
---|
734 | | - |
---|
735 | 787 | fatent_init(&fatent); |
---|
736 | 788 | lock_fat(sbi); |
---|
737 | 789 | fatent_set_entry(&fatent, ent_start); |
---|
| 790 | + fat_ra_init(sb, &fatent_ra, &fatent, ent_end + 1); |
---|
738 | 791 | while (fatent.entry <= ent_end) { |
---|
739 | 792 | /* readahead of fat blocks */ |
---|
740 | | - if ((cur_block & reada_mask) == 0) { |
---|
741 | | - unsigned long rest = sbi->fat_length - cur_block; |
---|
742 | | - fat_ent_reada(sb, &fatent, min(reada_blocks, rest)); |
---|
743 | | - } |
---|
744 | | - cur_block++; |
---|
| 793 | + fat_ent_reada(sb, &fatent_ra, &fatent); |
---|
745 | 794 | |
---|
746 | 795 | err = fat_ent_read_block(sb, &fatent); |
---|
747 | 796 | if (err) |
---|