diff options
Diffstat (limited to 'fs/nfs/read.c')
-rw-r--r-- | fs/nfs/read.c | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/fs/nfs/read.c b/fs/nfs/read.c index 7bd7cb95c034..c07d0d10d9ed 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c | |||
@@ -483,17 +483,19 @@ int nfs_readpage(struct file *file, struct page *page) | |||
483 | */ | 483 | */ |
484 | error = nfs_wb_page(inode, page); | 484 | error = nfs_wb_page(inode, page); |
485 | if (error) | 485 | if (error) |
486 | goto out_error; | 486 | goto out_unlock; |
487 | if (PageUptodate(page)) | ||
488 | goto out_unlock; | ||
487 | 489 | ||
488 | error = -ESTALE; | 490 | error = -ESTALE; |
489 | if (NFS_STALE(inode)) | 491 | if (NFS_STALE(inode)) |
490 | goto out_error; | 492 | goto out_unlock; |
491 | 493 | ||
492 | if (file == NULL) { | 494 | if (file == NULL) { |
493 | error = -EBADF; | 495 | error = -EBADF; |
494 | ctx = nfs_find_open_context(inode, NULL, FMODE_READ); | 496 | ctx = nfs_find_open_context(inode, NULL, FMODE_READ); |
495 | if (ctx == NULL) | 497 | if (ctx == NULL) |
496 | goto out_error; | 498 | goto out_unlock; |
497 | } else | 499 | } else |
498 | ctx = get_nfs_open_context((struct nfs_open_context *) | 500 | ctx = get_nfs_open_context((struct nfs_open_context *) |
499 | file->private_data); | 501 | file->private_data); |
@@ -502,8 +504,7 @@ int nfs_readpage(struct file *file, struct page *page) | |||
502 | 504 | ||
503 | put_nfs_open_context(ctx); | 505 | put_nfs_open_context(ctx); |
504 | return error; | 506 | return error; |
505 | 507 | out_unlock: | |
506 | out_error: | ||
507 | unlock_page(page); | 508 | unlock_page(page); |
508 | return error; | 509 | return error; |
509 | } | 510 | } |
@@ -520,21 +521,32 @@ readpage_async_filler(void *data, struct page *page) | |||
520 | struct inode *inode = page->mapping->host; | 521 | struct inode *inode = page->mapping->host; |
521 | struct nfs_page *new; | 522 | struct nfs_page *new; |
522 | unsigned int len; | 523 | unsigned int len; |
524 | int error; | ||
525 | |||
526 | error = nfs_wb_page(inode, page); | ||
527 | if (error) | ||
528 | goto out_unlock; | ||
529 | if (PageUptodate(page)) | ||
530 | goto out_unlock; | ||
523 | 531 | ||
524 | nfs_wb_page(inode, page); | ||
525 | len = nfs_page_length(page); | 532 | len = nfs_page_length(page); |
526 | if (len == 0) | 533 | if (len == 0) |
527 | return nfs_return_empty_page(page); | 534 | return nfs_return_empty_page(page); |
535 | |||
528 | new = nfs_create_request(desc->ctx, inode, page, 0, len); | 536 | new = nfs_create_request(desc->ctx, inode, page, 0, len); |
529 | if (IS_ERR(new)) { | 537 | if (IS_ERR(new)) |
530 | SetPageError(page); | 538 | goto out_error; |
531 | unlock_page(page); | 539 | |
532 | return PTR_ERR(new); | ||
533 | } | ||
534 | if (len < PAGE_CACHE_SIZE) | 540 | if (len < PAGE_CACHE_SIZE) |
535 | zero_user_page(page, len, PAGE_CACHE_SIZE - len, KM_USER0); | 541 | zero_user_page(page, len, PAGE_CACHE_SIZE - len, KM_USER0); |
536 | nfs_pageio_add_request(desc->pgio, new); | 542 | nfs_pageio_add_request(desc->pgio, new); |
537 | return 0; | 543 | return 0; |
544 | out_error: | ||
545 | error = PTR_ERR(new); | ||
546 | SetPageError(page); | ||
547 | out_unlock: | ||
548 | unlock_page(page); | ||
549 | return error; | ||
538 | } | 550 | } |
539 | 551 | ||
540 | int nfs_readpages(struct file *filp, struct address_space *mapping, | 552 | int nfs_readpages(struct file *filp, struct address_space *mapping, |