diff options
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/read.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/fs/nfs/read.c b/fs/nfs/read.c index dae33c1e8a77..69f1549da2b9 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c | |||
@@ -568,8 +568,13 @@ int nfs_readpage_result(struct rpc_task *task, struct nfs_read_data *data) | |||
568 | 568 | ||
569 | nfs_add_stats(data->inode, NFSIOS_SERVERREADBYTES, resp->count); | 569 | nfs_add_stats(data->inode, NFSIOS_SERVERREADBYTES, resp->count); |
570 | 570 | ||
571 | /* Is this a short read? */ | 571 | if (task->tk_status < 0) { |
572 | if (task->tk_status >= 0 && resp->count < argp->count && !resp->eof) { | 572 | if (task->tk_status == -ESTALE) { |
573 | set_bit(NFS_INO_STALE, &NFS_FLAGS(data->inode)); | ||
574 | nfs_mark_for_revalidate(data->inode); | ||
575 | } | ||
576 | } else if (resp->count < argp->count && !resp->eof) { | ||
577 | /* This is a short read! */ | ||
573 | nfs_inc_stats(data->inode, NFSIOS_SHORTREAD); | 578 | nfs_inc_stats(data->inode, NFSIOS_SHORTREAD); |
574 | /* Has the server at least made some progress? */ | 579 | /* Has the server at least made some progress? */ |
575 | if (resp->count != 0) { | 580 | if (resp->count != 0) { |
@@ -616,6 +621,10 @@ int nfs_readpage(struct file *file, struct page *page) | |||
616 | if (error) | 621 | if (error) |
617 | goto out_error; | 622 | goto out_error; |
618 | 623 | ||
624 | error = -ESTALE; | ||
625 | if (NFS_STALE(inode)) | ||
626 | goto out_error; | ||
627 | |||
619 | if (file == NULL) { | 628 | if (file == NULL) { |
620 | ctx = nfs_find_open_context(inode, NULL, FMODE_READ); | 629 | ctx = nfs_find_open_context(inode, NULL, FMODE_READ); |
621 | if (ctx == NULL) | 630 | if (ctx == NULL) |
@@ -678,7 +687,7 @@ int nfs_readpages(struct file *filp, struct address_space *mapping, | |||
678 | }; | 687 | }; |
679 | struct inode *inode = mapping->host; | 688 | struct inode *inode = mapping->host; |
680 | struct nfs_server *server = NFS_SERVER(inode); | 689 | struct nfs_server *server = NFS_SERVER(inode); |
681 | int ret; | 690 | int ret = -ESTALE; |
682 | 691 | ||
683 | dprintk("NFS: nfs_readpages (%s/%Ld %d)\n", | 692 | dprintk("NFS: nfs_readpages (%s/%Ld %d)\n", |
684 | inode->i_sb->s_id, | 693 | inode->i_sb->s_id, |
@@ -686,6 +695,9 @@ int nfs_readpages(struct file *filp, struct address_space *mapping, | |||
686 | nr_pages); | 695 | nr_pages); |
687 | nfs_inc_stats(inode, NFSIOS_VFSREADPAGES); | 696 | nfs_inc_stats(inode, NFSIOS_VFSREADPAGES); |
688 | 697 | ||
698 | if (NFS_STALE(inode)) | ||
699 | goto out; | ||
700 | |||
689 | if (filp == NULL) { | 701 | if (filp == NULL) { |
690 | desc.ctx = nfs_find_open_context(inode, NULL, FMODE_READ); | 702 | desc.ctx = nfs_find_open_context(inode, NULL, FMODE_READ); |
691 | if (desc.ctx == NULL) | 703 | if (desc.ctx == NULL) |
@@ -701,6 +713,7 @@ int nfs_readpages(struct file *filp, struct address_space *mapping, | |||
701 | ret = err; | 713 | ret = err; |
702 | } | 714 | } |
703 | put_nfs_open_context(desc.ctx); | 715 | put_nfs_open_context(desc.ctx); |
716 | out: | ||
704 | return ret; | 717 | return ret; |
705 | } | 718 | } |
706 | 719 | ||