hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/fs/fat/fatent.c
....@@ -1,6 +1,6 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (C) 2004, OGAWA Hirofumi
3
- * Released under GPL v2.
44 */
55
66 #include <linux/blkdev.h>
....@@ -93,7 +93,8 @@
9393 err_brelse:
9494 brelse(bhs[0]);
9595 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);
9798 return -EIO;
9899 }
99100
....@@ -106,8 +107,8 @@
106107 fatent->fat_inode = MSDOS_SB(sb)->fat_inode;
107108 fatent->bhs[0] = sb_bread(sb, blocknr);
108109 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);
111112 return -EIO;
112113 }
113114 fatent->nr_bhs = 1;
....@@ -290,19 +291,17 @@
290291
291292 mutex_init(&sbi->fat_lock);
292293
293
- switch (sbi->fat_bits) {
294
- case 32:
294
+ if (is_fat32(sbi)) {
295295 sbi->fatent_shift = 2;
296296 sbi->fatent_ops = &fat32_ops;
297
- break;
298
- case 16:
297
+ } else if (is_fat16(sbi)) {
299298 sbi->fatent_shift = 1;
300299 sbi->fatent_ops = &fat16_ops;
301
- break;
302
- case 12:
300
+ } else if (is_fat12(sbi)) {
303301 sbi->fatent_shift = -1;
304302 sbi->fatent_ops = &fat12_ops;
305
- break;
303
+ } else {
304
+ fat_fs_error(sb, "invalid FAT variant, %u bits", sbi->fat_bits);
306305 }
307306 }
308307
....@@ -310,7 +309,7 @@
310309 {
311310 struct msdos_sb_info *sbi = MSDOS_SB(sb);
312311
313
- if (sb_rdonly(sb) || sbi->fat_bits != 32)
312
+ if (sb_rdonly(sb) || !is_fat32(sbi))
314313 return;
315314
316315 __mark_inode_dirty(sbi->fsinfo_inode, I_DIRTY_SYNC);
....@@ -327,7 +326,7 @@
327326 /* Is this fatent's blocks including this entry? */
328327 if (!fatent->nr_bhs || bhs[0]->b_blocknr != blocknr)
329328 return 0;
330
- if (sbi->fat_bits == 12) {
329
+ if (is_fat12(sbi)) {
331330 if ((offset + 1) < sb->s_blocksize) {
332331 /* This entry is on bhs[0]. */
333332 if (fatent->nr_bhs == 2) {
....@@ -634,20 +633,83 @@
634633 }
635634 EXPORT_SYMBOL_GPL(fat_free_clusters);
636635
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;
639639
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)
642648 {
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;
646660
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 */
647669 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;
648673
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++;
651713 }
652714
653715 int fat_count_free_clusters(struct super_block *sb)
....@@ -655,27 +717,20 @@
655717 struct msdos_sb_info *sbi = MSDOS_SB(sb);
656718 const struct fatent_operations *ops = sbi->fatent_ops;
657719 struct fat_entry fatent;
658
- unsigned long reada_blocks, reada_mask, cur_block;
720
+ struct fatent_ra fatent_ra;
659721 int err = 0, free;
660722
661723 lock_fat(sbi);
662724 if (sbi->free_clusters != -1 && sbi->free_clus_valid)
663725 goto out;
664726
665
- reada_blocks = FAT_READA_SIZE >> sb->s_blocksize_bits;
666
- reada_mask = reada_blocks - 1;
667
- cur_block = 0;
668
-
669727 free = 0;
670728 fatent_init(&fatent);
671729 fatent_set_entry(&fatent, FAT_START_ENT);
730
+ fat_ra_init(sb, &fatent_ra, &fatent, sbi->max_cluster);
672731 while (fatent.entry < sbi->max_cluster) {
673732 /* 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);
679734
680735 err = fat_ent_read_block(sb, &fatent);
681736 if (err)
....@@ -709,9 +764,9 @@
709764 struct msdos_sb_info *sbi = MSDOS_SB(sb);
710765 const struct fatent_operations *ops = sbi->fatent_ops;
711766 struct fat_entry fatent;
767
+ struct fatent_ra fatent_ra;
712768 u64 ent_start, ent_end, minlen, trimmed = 0;
713769 u32 free = 0;
714
- unsigned long reada_blocks, reada_mask, cur_block = 0;
715770 int err = 0;
716771
717772 /*
....@@ -729,19 +784,13 @@
729784 if (ent_end >= sbi->max_cluster)
730785 ent_end = sbi->max_cluster - 1;
731786
732
- reada_blocks = FAT_READA_SIZE >> sb->s_blocksize_bits;
733
- reada_mask = reada_blocks - 1;
734
-
735787 fatent_init(&fatent);
736788 lock_fat(sbi);
737789 fatent_set_entry(&fatent, ent_start);
790
+ fat_ra_init(sb, &fatent_ra, &fatent, ent_end + 1);
738791 while (fatent.entry <= ent_end) {
739792 /* 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);
745794
746795 err = fat_ent_read_block(sb, &fatent);
747796 if (err)