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 | /* |
