diff options
-rw-r--r-- | fs/hpfs/buffer.c | 96 |
1 files changed, 50 insertions, 46 deletions
diff --git a/fs/hpfs/buffer.c b/fs/hpfs/buffer.c index 4d0a1afa058c..139ef1684d07 100644 --- a/fs/hpfs/buffer.c +++ b/fs/hpfs/buffer.c | |||
@@ -86,7 +86,6 @@ void *hpfs_get_sector(struct super_block *s, unsigned secno, struct buffer_head | |||
86 | void *hpfs_map_4sectors(struct super_block *s, unsigned secno, struct quad_buffer_head *qbh, | 86 | void *hpfs_map_4sectors(struct super_block *s, unsigned secno, struct quad_buffer_head *qbh, |
87 | int ahead) | 87 | int ahead) |
88 | { | 88 | { |
89 | struct buffer_head *bh; | ||
90 | char *data; | 89 | char *data; |
91 | 90 | ||
92 | hpfs_lock_assert(s); | 91 | hpfs_lock_assert(s); |
@@ -100,34 +99,32 @@ void *hpfs_map_4sectors(struct super_block *s, unsigned secno, struct quad_buffe | |||
100 | 99 | ||
101 | hpfs_prefetch_sectors(s, secno, 4 + ahead); | 100 | hpfs_prefetch_sectors(s, secno, 4 + ahead); |
102 | 101 | ||
102 | if (!(qbh->bh[0] = sb_bread(s, secno + 0))) goto bail0; | ||
103 | if (!(qbh->bh[1] = sb_bread(s, secno + 1))) goto bail1; | ||
104 | if (!(qbh->bh[2] = sb_bread(s, secno + 2))) goto bail2; | ||
105 | if (!(qbh->bh[3] = sb_bread(s, secno + 3))) goto bail3; | ||
106 | |||
107 | 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) && | ||
109 | likely(qbh->bh[3]->b_data == qbh->bh[0]->b_data + 3 * 512)) { | ||
110 | return qbh->data = qbh->bh[0]->b_data; | ||
111 | } | ||
112 | |||
103 | qbh->data = data = kmalloc(2048, GFP_NOFS); | 113 | qbh->data = data = kmalloc(2048, GFP_NOFS); |
104 | if (!data) { | 114 | if (!data) { |
105 | printk("HPFS: hpfs_map_4sectors: out of memory\n"); | 115 | printk("HPFS: hpfs_map_4sectors: out of memory\n"); |
106 | goto bail; | 116 | goto bail4; |
107 | } | 117 | } |
108 | 118 | ||
109 | qbh->bh[0] = bh = sb_bread(s, secno); | 119 | memcpy(data + 0 * 512, qbh->bh[0]->b_data, 512); |
110 | if (!bh) | 120 | memcpy(data + 1 * 512, qbh->bh[1]->b_data, 512); |
111 | goto bail0; | 121 | memcpy(data + 2 * 512, qbh->bh[2]->b_data, 512); |
112 | memcpy(data, bh->b_data, 512); | 122 | memcpy(data + 3 * 512, qbh->bh[3]->b_data, 512); |
113 | |||
114 | qbh->bh[1] = bh = sb_bread(s, secno + 1); | ||
115 | if (!bh) | ||
116 | goto bail1; | ||
117 | memcpy(data + 512, bh->b_data, 512); | ||
118 | |||
119 | qbh->bh[2] = bh = sb_bread(s, secno + 2); | ||
120 | if (!bh) | ||
121 | goto bail2; | ||
122 | memcpy(data + 2 * 512, bh->b_data, 512); | ||
123 | |||
124 | qbh->bh[3] = bh = sb_bread(s, secno + 3); | ||
125 | if (!bh) | ||
126 | goto bail3; | ||
127 | memcpy(data + 3 * 512, bh->b_data, 512); | ||
128 | 123 | ||
129 | return data; | 124 | return data; |
130 | 125 | ||
126 | bail4: | ||
127 | brelse(qbh->bh[3]); | ||
131 | bail3: | 128 | bail3: |
132 | brelse(qbh->bh[2]); | 129 | brelse(qbh->bh[2]); |
133 | bail2: | 130 | bail2: |
@@ -135,9 +132,6 @@ void *hpfs_map_4sectors(struct super_block *s, unsigned secno, struct quad_buffe | |||
135 | bail1: | 132 | bail1: |
136 | brelse(qbh->bh[0]); | 133 | brelse(qbh->bh[0]); |
137 | bail0: | 134 | bail0: |
138 | kfree(data); | ||
139 | printk("HPFS: hpfs_map_4sectors: read error\n"); | ||
140 | bail: | ||
141 | return NULL; | 135 | return NULL; |
142 | } | 136 | } |
143 | 137 | ||
@@ -155,44 +149,54 @@ void *hpfs_get_4sectors(struct super_block *s, unsigned secno, | |||
155 | return NULL; | 149 | return NULL; |
156 | } | 150 | } |
157 | 151 | ||
158 | /*return hpfs_map_4sectors(s, secno, qbh, 0);*/ | 152 | if (!hpfs_get_sector(s, secno + 0, &qbh->bh[0])) goto bail0; |
153 | if (!hpfs_get_sector(s, secno + 1, &qbh->bh[1])) goto bail1; | ||
154 | if (!hpfs_get_sector(s, secno + 2, &qbh->bh[2])) goto bail2; | ||
155 | if (!hpfs_get_sector(s, secno + 3, &qbh->bh[3])) goto bail3; | ||
156 | |||
157 | if (likely(qbh->bh[1]->b_data == qbh->bh[0]->b_data + 1 * 512) && | ||
158 | likely(qbh->bh[2]->b_data == qbh->bh[0]->b_data + 2 * 512) && | ||
159 | likely(qbh->bh[3]->b_data == qbh->bh[0]->b_data + 3 * 512)) { | ||
160 | return qbh->data = qbh->bh[0]->b_data; | ||
161 | } | ||
162 | |||
159 | if (!(qbh->data = kmalloc(2048, GFP_NOFS))) { | 163 | if (!(qbh->data = kmalloc(2048, GFP_NOFS))) { |
160 | printk("HPFS: hpfs_get_4sectors: out of memory\n"); | 164 | printk("HPFS: hpfs_get_4sectors: out of memory\n"); |
161 | return NULL; | 165 | goto bail4; |
162 | } | 166 | } |
163 | if (!(hpfs_get_sector(s, secno, &qbh->bh[0]))) goto bail0; | ||
164 | if (!(hpfs_get_sector(s, secno + 1, &qbh->bh[1]))) goto bail1; | ||
165 | if (!(hpfs_get_sector(s, secno + 2, &qbh->bh[2]))) goto bail2; | ||
166 | if (!(hpfs_get_sector(s, secno + 3, &qbh->bh[3]))) goto bail3; | ||
167 | memcpy(qbh->data, qbh->bh[0]->b_data, 512); | ||
168 | memcpy(qbh->data + 512, qbh->bh[1]->b_data, 512); | ||
169 | memcpy(qbh->data + 2*512, qbh->bh[2]->b_data, 512); | ||
170 | memcpy(qbh->data + 3*512, qbh->bh[3]->b_data, 512); | ||
171 | return qbh->data; | 167 | return qbh->data; |
172 | 168 | ||
173 | bail3: brelse(qbh->bh[2]); | 169 | bail4: |
174 | bail2: brelse(qbh->bh[1]); | 170 | brelse(qbh->bh[3]); |
175 | bail1: brelse(qbh->bh[0]); | 171 | bail3: |
176 | bail0: | 172 | brelse(qbh->bh[2]); |
173 | bail2: | ||
174 | brelse(qbh->bh[1]); | ||
175 | bail1: | ||
176 | brelse(qbh->bh[0]); | ||
177 | bail0: | ||
177 | return NULL; | 178 | return NULL; |
178 | } | 179 | } |
179 | 180 | ||
180 | 181 | ||
181 | void hpfs_brelse4(struct quad_buffer_head *qbh) | 182 | void hpfs_brelse4(struct quad_buffer_head *qbh) |
182 | { | 183 | { |
183 | brelse(qbh->bh[3]); | 184 | if (unlikely(qbh->data != qbh->bh[0]->b_data)) |
184 | brelse(qbh->bh[2]); | 185 | kfree(qbh->data); |
185 | brelse(qbh->bh[1]); | ||
186 | brelse(qbh->bh[0]); | 186 | brelse(qbh->bh[0]); |
187 | kfree(qbh->data); | 187 | brelse(qbh->bh[1]); |
188 | brelse(qbh->bh[2]); | ||
189 | brelse(qbh->bh[3]); | ||
188 | } | 190 | } |
189 | 191 | ||
190 | void hpfs_mark_4buffers_dirty(struct quad_buffer_head *qbh) | 192 | void hpfs_mark_4buffers_dirty(struct quad_buffer_head *qbh) |
191 | { | 193 | { |
192 | memcpy(qbh->bh[0]->b_data, qbh->data, 512); | 194 | if (unlikely(qbh->data != qbh->bh[0]->b_data)) { |
193 | memcpy(qbh->bh[1]->b_data, qbh->data + 512, 512); | 195 | memcpy(qbh->bh[0]->b_data, qbh->data + 0 * 512, 512); |
194 | memcpy(qbh->bh[2]->b_data, qbh->data + 2 * 512, 512); | 196 | memcpy(qbh->bh[1]->b_data, qbh->data + 1 * 512, 512); |
195 | memcpy(qbh->bh[3]->b_data, qbh->data + 3 * 512, 512); | 197 | memcpy(qbh->bh[2]->b_data, qbh->data + 2 * 512, 512); |
198 | memcpy(qbh->bh[3]->b_data, qbh->data + 3 * 512, 512); | ||
199 | } | ||
196 | mark_buffer_dirty(qbh->bh[0]); | 200 | mark_buffer_dirty(qbh->bh[0]); |
197 | mark_buffer_dirty(qbh->bh[1]); | 201 | mark_buffer_dirty(qbh->bh[1]); |
198 | mark_buffer_dirty(qbh->bh[2]); | 202 | mark_buffer_dirty(qbh->bh[2]); |