diff options
Diffstat (limited to 'fs/nfs/read.c')
-rw-r--r-- | fs/nfs/read.c | 42 |
1 files changed, 27 insertions, 15 deletions
diff --git a/fs/nfs/read.c b/fs/nfs/read.c index 7bd7cb95c034..19e05633f4e3 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c | |||
@@ -145,8 +145,8 @@ static void nfs_readpage_release(struct nfs_page *req) | |||
145 | unlock_page(req->wb_page); | 145 | unlock_page(req->wb_page); |
146 | 146 | ||
147 | dprintk("NFS: read done (%s/%Ld %d@%Ld)\n", | 147 | dprintk("NFS: read done (%s/%Ld %d@%Ld)\n", |
148 | req->wb_context->dentry->d_inode->i_sb->s_id, | 148 | req->wb_context->path.dentry->d_inode->i_sb->s_id, |
149 | (long long)NFS_FILEID(req->wb_context->dentry->d_inode), | 149 | (long long)NFS_FILEID(req->wb_context->path.dentry->d_inode), |
150 | req->wb_bytes, | 150 | req->wb_bytes, |
151 | (long long)req_offset(req)); | 151 | (long long)req_offset(req)); |
152 | nfs_clear_request(req); | 152 | nfs_clear_request(req); |
@@ -164,7 +164,7 @@ static void nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data, | |||
164 | int flags; | 164 | int flags; |
165 | 165 | ||
166 | data->req = req; | 166 | data->req = req; |
167 | data->inode = inode = req->wb_context->dentry->d_inode; | 167 | data->inode = inode = req->wb_context->path.dentry->d_inode; |
168 | data->cred = req->wb_context->cred; | 168 | data->cred = req->wb_context->cred; |
169 | 169 | ||
170 | data->args.fh = NFS_FH(inode); | 170 | data->args.fh = NFS_FH(inode); |
@@ -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, |
@@ -586,7 +598,7 @@ int __init nfs_init_readpagecache(void) | |||
586 | nfs_rdata_cachep = kmem_cache_create("nfs_read_data", | 598 | nfs_rdata_cachep = kmem_cache_create("nfs_read_data", |
587 | sizeof(struct nfs_read_data), | 599 | sizeof(struct nfs_read_data), |
588 | 0, SLAB_HWCACHE_ALIGN, | 600 | 0, SLAB_HWCACHE_ALIGN, |
589 | NULL, NULL); | 601 | NULL); |
590 | if (nfs_rdata_cachep == NULL) | 602 | if (nfs_rdata_cachep == NULL) |
591 | return -ENOMEM; | 603 | return -ENOMEM; |
592 | 604 | ||