diff options
-rw-r--r-- | fs/exofs/inode.c | 34 |
1 files changed, 14 insertions, 20 deletions
diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c index 3eadd97324b1..24ab327a20cf 100644 --- a/fs/exofs/inode.c +++ b/fs/exofs/inode.c | |||
@@ -185,7 +185,7 @@ static void update_write_page(struct page *page, int ret) | |||
185 | /* Called at the end of reads, to optionally unlock pages and update their | 185 | /* Called at the end of reads, to optionally unlock pages and update their |
186 | * status. | 186 | * status. |
187 | */ | 187 | */ |
188 | static int __readpages_done(struct page_collect *pcol, bool do_unlock) | 188 | static int __readpages_done(struct page_collect *pcol) |
189 | { | 189 | { |
190 | int i; | 190 | int i; |
191 | u64 resid; | 191 | u64 resid; |
@@ -221,7 +221,7 @@ static int __readpages_done(struct page_collect *pcol, bool do_unlock) | |||
221 | page_stat ? "bad_bytes" : "good_bytes"); | 221 | page_stat ? "bad_bytes" : "good_bytes"); |
222 | 222 | ||
223 | ret = update_read_page(page, page_stat); | 223 | ret = update_read_page(page, page_stat); |
224 | if (do_unlock) | 224 | if (!pcol->read_4_write) |
225 | unlock_page(page); | 225 | unlock_page(page); |
226 | length += PAGE_SIZE; | 226 | length += PAGE_SIZE; |
227 | } | 227 | } |
@@ -236,7 +236,7 @@ static void readpages_done(struct exofs_io_state *ios, void *p) | |||
236 | { | 236 | { |
237 | struct page_collect *pcol = p; | 237 | struct page_collect *pcol = p; |
238 | 238 | ||
239 | __readpages_done(pcol, true); | 239 | __readpages_done(pcol); |
240 | atomic_dec(&pcol->sbi->s_curr_pending); | 240 | atomic_dec(&pcol->sbi->s_curr_pending); |
241 | kfree(pcol); | 241 | kfree(pcol); |
242 | } | 242 | } |
@@ -257,7 +257,7 @@ static void _unlock_pcol_pages(struct page_collect *pcol, int ret, int rw) | |||
257 | } | 257 | } |
258 | } | 258 | } |
259 | 259 | ||
260 | static int read_exec(struct page_collect *pcol, bool is_sync) | 260 | static int read_exec(struct page_collect *pcol) |
261 | { | 261 | { |
262 | struct exofs_i_info *oi = exofs_i(pcol->inode); | 262 | struct exofs_i_info *oi = exofs_i(pcol->inode); |
263 | struct exofs_io_state *ios = pcol->ios; | 263 | struct exofs_io_state *ios = pcol->ios; |
@@ -267,17 +267,14 @@ static int read_exec(struct page_collect *pcol, bool is_sync) | |||
267 | if (!pcol->pages) | 267 | if (!pcol->pages) |
268 | return 0; | 268 | return 0; |
269 | 269 | ||
270 | /* see comment in _readpage() about sync reads */ | ||
271 | WARN_ON(is_sync && (pcol->nr_pages != 1)); | ||
272 | |||
273 | ios->pages = pcol->pages; | 270 | ios->pages = pcol->pages; |
274 | ios->nr_pages = pcol->nr_pages; | 271 | ios->nr_pages = pcol->nr_pages; |
275 | ios->length = pcol->length; | 272 | ios->length = pcol->length; |
276 | ios->offset = pcol->pg_first << PAGE_CACHE_SHIFT; | 273 | ios->offset = pcol->pg_first << PAGE_CACHE_SHIFT; |
277 | 274 | ||
278 | if (is_sync) { | 275 | if (pcol->read_4_write) { |
279 | exofs_oi_read(oi, pcol->ios); | 276 | exofs_oi_read(oi, pcol->ios); |
280 | return __readpages_done(pcol, false); | 277 | return __readpages_done(pcol); |
281 | } | 278 | } |
282 | 279 | ||
283 | pcol_copy = kmalloc(sizeof(*pcol_copy), GFP_KERNEL); | 280 | pcol_copy = kmalloc(sizeof(*pcol_copy), GFP_KERNEL); |
@@ -303,7 +300,7 @@ static int read_exec(struct page_collect *pcol, bool is_sync) | |||
303 | return 0; | 300 | return 0; |
304 | 301 | ||
305 | err: | 302 | err: |
306 | if (!is_sync) | 303 | if (!pcol->read_4_write) |
307 | _unlock_pcol_pages(pcol, ret, READ); | 304 | _unlock_pcol_pages(pcol, ret, READ); |
308 | 305 | ||
309 | pcol_free(pcol); | 306 | pcol_free(pcol); |
@@ -356,7 +353,7 @@ static int readpage_strip(void *data, struct page *page) | |||
356 | EXOFS_DBGMSG("readpage_strip(0x%lx, 0x%lx) empty page," | 353 | EXOFS_DBGMSG("readpage_strip(0x%lx, 0x%lx) empty page," |
357 | " splitting\n", inode->i_ino, page->index); | 354 | " splitting\n", inode->i_ino, page->index); |
358 | 355 | ||
359 | return read_exec(pcol, false); | 356 | return read_exec(pcol); |
360 | } | 357 | } |
361 | 358 | ||
362 | try_again: | 359 | try_again: |
@@ -366,7 +363,7 @@ try_again: | |||
366 | } else if (unlikely((pcol->pg_first + pcol->nr_pages) != | 363 | } else if (unlikely((pcol->pg_first + pcol->nr_pages) != |
367 | page->index)) { | 364 | page->index)) { |
368 | /* Discontinuity detected, split the request */ | 365 | /* Discontinuity detected, split the request */ |
369 | ret = read_exec(pcol, false); | 366 | ret = read_exec(pcol); |
370 | if (unlikely(ret)) | 367 | if (unlikely(ret)) |
371 | goto fail; | 368 | goto fail; |
372 | goto try_again; | 369 | goto try_again; |
@@ -391,7 +388,7 @@ try_again: | |||
391 | page, len, pcol->nr_pages, pcol->length); | 388 | page, len, pcol->nr_pages, pcol->length); |
392 | 389 | ||
393 | /* split the request, and start again with current page */ | 390 | /* split the request, and start again with current page */ |
394 | ret = read_exec(pcol, false); | 391 | ret = read_exec(pcol); |
395 | if (unlikely(ret)) | 392 | if (unlikely(ret)) |
396 | goto fail; | 393 | goto fail; |
397 | 394 | ||
@@ -420,27 +417,24 @@ static int exofs_readpages(struct file *file, struct address_space *mapping, | |||
420 | return ret; | 417 | return ret; |
421 | } | 418 | } |
422 | 419 | ||
423 | return read_exec(&pcol, false); | 420 | return read_exec(&pcol); |
424 | } | 421 | } |
425 | 422 | ||
426 | static int _readpage(struct page *page, bool is_sync) | 423 | static int _readpage(struct page *page, bool read_4_write) |
427 | { | 424 | { |
428 | struct page_collect pcol; | 425 | struct page_collect pcol; |
429 | int ret; | 426 | int ret; |
430 | 427 | ||
431 | _pcol_init(&pcol, 1, page->mapping->host); | 428 | _pcol_init(&pcol, 1, page->mapping->host); |
432 | 429 | ||
433 | /* readpage_strip might call read_exec(,is_sync==false) at several | 430 | pcol.read_4_write = read_4_write; |
434 | * places but not if we have a single page. | ||
435 | */ | ||
436 | pcol.read_4_write = is_sync; | ||
437 | ret = readpage_strip(&pcol, page); | 431 | ret = readpage_strip(&pcol, page); |
438 | if (ret) { | 432 | if (ret) { |
439 | EXOFS_ERR("_readpage => %d\n", ret); | 433 | EXOFS_ERR("_readpage => %d\n", ret); |
440 | return ret; | 434 | return ret; |
441 | } | 435 | } |
442 | 436 | ||
443 | return read_exec(&pcol, is_sync); | 437 | return read_exec(&pcol); |
444 | } | 438 | } |
445 | 439 | ||
446 | /* | 440 | /* |