diff options
author | kib <kib@FreeBSD.org> | 2012-08-14 11:45:47 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2012-08-14 11:45:47 +0000 |
commit | a3d0fb01750888083d0ed5945f2d835c310c40e6 (patch) | |
tree | c57999c31279d4b34edfa4c9044a68251f72d983 /sys/vm/vm_page.c | |
parent | 45e40c523ad8935b149fdb4ae70172fb3a3c0336 (diff) | |
download | FreeBSD-src-a3d0fb01750888083d0ed5945f2d835c310c40e6.zip FreeBSD-src-a3d0fb01750888083d0ed5945f2d835c310c40e6.tar.gz |
Do not leave invalid pages in the object after the short read for a
network file systems (not only NFS proper). Short reads cause pages
other then the requested one, which were not filled by read response,
to stay invalid.
Change the vm_page_readahead_finish() interface to not take the error
code, but instead to make a decision to free or to (de)activate the
page only by its validity. As result, not requested invalid pages are
freed even if the read RPC indicated success.
Noted and reviewed by: alc
MFC after: 1 week
Diffstat (limited to 'sys/vm/vm_page.c')
-rw-r--r-- | sys/vm/vm_page.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c index b679290..b012065c 100644 --- a/sys/vm/vm_page.c +++ b/sys/vm/vm_page.c @@ -699,10 +699,10 @@ vm_page_free_zero(vm_page_t m) * array which is not the request page. */ void -vm_page_readahead_finish(vm_page_t m, int error) +vm_page_readahead_finish(vm_page_t m) { - if (error == 0) { + if (m->valid != 0) { /* * Since the page is not the requested page, whether * it should be activated or deactivated is not @@ -721,6 +721,12 @@ vm_page_readahead_finish(vm_page_t m, int error) } vm_page_wakeup(m); } else { + /* + * Free the completely invalid page. Such page state + * occurs due to the short read operation which did + * not covered our page at all, or in case when a read + * error happens. + */ vm_page_lock(m); vm_page_free(m); vm_page_unlock(m); |