diff options
Diffstat (limited to 'fs/hpfs/buffer.c')
-rw-r--r-- | fs/hpfs/buffer.c | 39 |
1 files changed, 33 insertions, 6 deletions
diff --git a/fs/hpfs/buffer.c b/fs/hpfs/buffer.c index 8057fe4e6574..f626114449e4 100644 --- a/fs/hpfs/buffer.c +++ b/fs/hpfs/buffer.c | |||
@@ -10,6 +10,30 @@ | |||
10 | #include <linux/blkdev.h> | 10 | #include <linux/blkdev.h> |
11 | #include "hpfs_fn.h" | 11 | #include "hpfs_fn.h" |
12 | 12 | ||
13 | secno hpfs_search_hotfix_map(struct super_block *s, secno sec) | ||
14 | { | ||
15 | unsigned i; | ||
16 | struct hpfs_sb_info *sbi = hpfs_sb(s); | ||
17 | for (i = 0; unlikely(i < sbi->n_hotfixes); i++) { | ||
18 | if (sbi->hotfix_from[i] == sec) { | ||
19 | return sbi->hotfix_to[i]; | ||
20 | } | ||
21 | } | ||
22 | return sec; | ||
23 | } | ||
24 | |||
25 | unsigned hpfs_search_hotfix_map_for_range(struct super_block *s, secno sec, unsigned n) | ||
26 | { | ||
27 | unsigned i; | ||
28 | struct hpfs_sb_info *sbi = hpfs_sb(s); | ||
29 | for (i = 0; unlikely(i < sbi->n_hotfixes); i++) { | ||
30 | if (sbi->hotfix_from[i] >= sec && sbi->hotfix_from[i] < sec + n) { | ||
31 | n = sbi->hotfix_from[i] - sec; | ||
32 | } | ||
33 | } | ||
34 | return n; | ||
35 | } | ||
36 | |||
13 | void hpfs_prefetch_sectors(struct super_block *s, unsigned secno, int n) | 37 | void hpfs_prefetch_sectors(struct super_block *s, unsigned secno, int n) |
14 | { | 38 | { |
15 | struct buffer_head *bh; | 39 | struct buffer_head *bh; |
@@ -18,6 +42,9 @@ void hpfs_prefetch_sectors(struct super_block *s, unsigned secno, int n) | |||
18 | if (n <= 0 || unlikely(secno >= hpfs_sb(s)->sb_fs_size)) | 42 | if (n <= 0 || unlikely(secno >= hpfs_sb(s)->sb_fs_size)) |
19 | return; | 43 | return; |
20 | 44 | ||
45 | if (unlikely(hpfs_search_hotfix_map_for_range(s, secno, n) != n)) | ||
46 | return; | ||
47 | |||
21 | bh = sb_find_get_block(s, secno); | 48 | bh = sb_find_get_block(s, secno); |
22 | if (bh) { | 49 | if (bh) { |
23 | if (buffer_uptodate(bh)) { | 50 | if (buffer_uptodate(bh)) { |
@@ -51,7 +78,7 @@ void *hpfs_map_sector(struct super_block *s, unsigned secno, struct buffer_head | |||
51 | 78 | ||
52 | cond_resched(); | 79 | cond_resched(); |
53 | 80 | ||
54 | *bhp = bh = sb_bread(s, secno); | 81 | *bhp = bh = sb_bread(s, hpfs_search_hotfix_map(s, secno)); |
55 | if (bh != NULL) | 82 | if (bh != NULL) |
56 | return bh->b_data; | 83 | return bh->b_data; |
57 | else { | 84 | else { |
@@ -71,7 +98,7 @@ void *hpfs_get_sector(struct super_block *s, unsigned secno, struct buffer_head | |||
71 | 98 | ||
72 | cond_resched(); | 99 | cond_resched(); |
73 | 100 | ||
74 | if ((*bhp = bh = sb_getblk(s, secno)) != NULL) { | 101 | if ((*bhp = bh = sb_getblk(s, hpfs_search_hotfix_map(s, secno))) != NULL) { |
75 | if (!buffer_uptodate(bh)) wait_on_buffer(bh); | 102 | if (!buffer_uptodate(bh)) wait_on_buffer(bh); |
76 | set_buffer_uptodate(bh); | 103 | set_buffer_uptodate(bh); |
77 | return bh->b_data; | 104 | return bh->b_data; |
@@ -99,10 +126,10 @@ void *hpfs_map_4sectors(struct super_block *s, unsigned secno, struct quad_buffe | |||
99 | 126 | ||
100 | hpfs_prefetch_sectors(s, secno, 4 + ahead); | 127 | hpfs_prefetch_sectors(s, secno, 4 + ahead); |
101 | 128 | ||
102 | if (!(qbh->bh[0] = sb_bread(s, secno + 0))) goto bail0; | 129 | if (!hpfs_map_sector(s, secno + 0, &qbh->bh[0], 0)) goto bail0; |
103 | if (!(qbh->bh[1] = sb_bread(s, secno + 1))) goto bail1; | 130 | if (!hpfs_map_sector(s, secno + 1, &qbh->bh[1], 0)) goto bail1; |
104 | if (!(qbh->bh[2] = sb_bread(s, secno + 2))) goto bail2; | 131 | if (!hpfs_map_sector(s, secno + 2, &qbh->bh[2], 0)) goto bail2; |
105 | if (!(qbh->bh[3] = sb_bread(s, secno + 3))) goto bail3; | 132 | if (!hpfs_map_sector(s, secno + 3, &qbh->bh[3], 0)) goto bail3; |
106 | 133 | ||
107 | if (likely(qbh->bh[1]->b_data == qbh->bh[0]->b_data + 1 * 512) && | 134 | if (likely(qbh->bh[1]->b_data == qbh->bh[0]->b_data + 1 * 512) && |
108 | likely(qbh->bh[2]->b_data == qbh->bh[0]->b_data + 2 * 512) && | 135 | likely(qbh->bh[2]->b_data == qbh->bh[0]->b_data + 2 * 512) && |