aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exofs
diff options
context:
space:
mode:
authorBoaz Harrosh <bharrosh@panasas.com>2010-01-19 12:24:45 -0500
committerBoaz Harrosh <bharrosh@panasas.com>2010-02-28 06:35:26 -0500
commit22ddc556380cf5645c52292b6d980766646eb864 (patch)
tree07d498ba10f4393fb4cde6a79b22a50b6a0f7efb /fs/exofs
parent518f167a37b3c53f3cf44d27800455ca24e920f6 (diff)
exofs: Recover in the case of read-passed-end-of-file
In check_io, implement the case of reading passed end of file, by clearing the pages and recover with no error. In a raid arrangement this can become a legitimate situation in case of holes in the file. Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
Diffstat (limited to 'fs/exofs')
-rw-r--r--fs/exofs/ios.c36
1 files changed, 30 insertions, 6 deletions
diff --git a/fs/exofs/ios.c b/fs/exofs/ios.c
index 3cc0dd3f0eb2..439c5d097b27 100644
--- a/fs/exofs/ios.c
+++ b/fs/exofs/ios.c
@@ -173,6 +173,21 @@ static int exofs_io_execute(struct exofs_io_state *ios)
173 return ret; 173 return ret;
174} 174}
175 175
176static void _clear_bio(struct bio *bio)
177{
178 struct bio_vec *bv;
179 unsigned i;
180
181 __bio_for_each_segment(bv, bio, i, 0) {
182 unsigned this_count = bv->bv_len;
183
184 if (likely(PAGE_SIZE == this_count))
185 clear_highpage(bv->bv_page);
186 else
187 zero_user(bv->bv_page, bv->bv_offset, this_count);
188 }
189}
190
176int exofs_check_io(struct exofs_io_state *ios, u64 *resid) 191int exofs_check_io(struct exofs_io_state *ios, u64 *resid)
177{ 192{
178 enum osd_err_priority acumulated_osd_err = 0; 193 enum osd_err_priority acumulated_osd_err = 0;
@@ -181,16 +196,25 @@ int exofs_check_io(struct exofs_io_state *ios, u64 *resid)
181 196
182 for (i = 0; i < ios->numdevs; i++) { 197 for (i = 0; i < ios->numdevs; i++) {
183 struct osd_sense_info osi; 198 struct osd_sense_info osi;
184 int ret = osd_req_decode_sense(ios->per_dev[i].or, &osi); 199 struct osd_request *or = ios->per_dev[i].or;
200 int ret;
201
202 if (unlikely(!or))
203 continue;
185 204
205 ret = osd_req_decode_sense(or, &osi);
186 if (likely(!ret)) 206 if (likely(!ret))
187 continue; 207 continue;
188 208
189 if (unlikely(ret == -EFAULT)) { 209 if (OSD_ERR_PRI_CLEAR_PAGES == osi.osd_err_pri) {
190 EXOFS_DBGMSG("%s: EFAULT Need page clear\n", __func__); 210 /* start read offset passed endof file */
191 /*FIXME: All the pages in this device range should: 211 _clear_bio(ios->per_dev[i].bio);
192 * clear_highpage(page); 212 EXOFS_DBGMSG("start read offset passed end of file "
193 */ 213 "offset=0x%llx, length=0x%llx\n",
214 _LLU(ios->offset),
215 _LLU(ios->length));
216
217 continue; /* we recovered */
194 } 218 }
195 219
196 if (osi.osd_err_pri >= acumulated_osd_err) { 220 if (osi.osd_err_pri >= acumulated_osd_err) {