From owner-svn-src-head@FreeBSD.ORG Tue Aug 14 11:45:48 2012 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 63F57106564A; Tue, 14 Aug 2012 11:45:48 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 448ED8FC16; Tue, 14 Aug 2012 11:45:48 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q7EBjmUW089946; Tue, 14 Aug 2012 11:45:48 GMT (envelope-from kib@svn.freebsd.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q7EBjlhk089938; Tue, 14 Aug 2012 11:45:47 GMT (envelope-from kib@svn.freebsd.org) Message-Id: <201208141145.q7EBjlhk089938@svn.freebsd.org> From: Konstantin Belousov Date: Tue, 14 Aug 2012 11:45:47 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r239246 - in head/sys: fs/nfsclient fs/nwfs fs/smbfs nfsclient vm X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 14 Aug 2012 11:45:48 -0000 Author: kib Date: Tue Aug 14 11:45:47 2012 New Revision: 239246 URL: http://svn.freebsd.org/changeset/base/239246 Log: 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 Modified: head/sys/fs/nfsclient/nfs_clbio.c head/sys/fs/nwfs/nwfs_io.c head/sys/fs/smbfs/smbfs_io.c head/sys/nfsclient/nfs_bio.c head/sys/vm/vm_page.c head/sys/vm/vm_page.h head/sys/vm/vnode_pager.c Modified: head/sys/fs/nfsclient/nfs_clbio.c ============================================================================== --- head/sys/fs/nfsclient/nfs_clbio.c Tue Aug 14 05:16:35 2012 (r239245) +++ head/sys/fs/nfsclient/nfs_clbio.c Tue Aug 14 11:45:47 2012 (r239246) @@ -218,14 +218,18 @@ ncl_getpages(struct vop_getpages_args *a ("nfs_getpages: page %p is dirty", m)); } else { /* - * Read operation was short. If no error occured - * we may have hit a zero-fill section. We simply - * leave valid set to 0. + * Read operation was short. If no error + * occured we may have hit a zero-fill + * section. We leave valid set to 0, and page + * is freed by vm_page_readahead_finish() if + * its index is not equal to requested, or + * page is zeroed and set valid by + * vm_pager_get_pages() for requested page. */ ; } if (i != ap->a_reqpage) - vm_page_readahead_finish(m, error); + vm_page_readahead_finish(m); } VM_OBJECT_UNLOCK(object); return (0); Modified: head/sys/fs/nwfs/nwfs_io.c ============================================================================== --- head/sys/fs/nwfs/nwfs_io.c Tue Aug 14 05:16:35 2012 (r239245) +++ head/sys/fs/nwfs/nwfs_io.c Tue Aug 14 11:45:47 2012 (r239246) @@ -459,7 +459,7 @@ nwfs_getpages(ap) } if (i != ap->a_reqpage) - vm_page_readahead_finish(m, error); + vm_page_readahead_finish(m); } VM_OBJECT_UNLOCK(object); return 0; Modified: head/sys/fs/smbfs/smbfs_io.c ============================================================================== --- head/sys/fs/smbfs/smbfs_io.c Tue Aug 14 05:16:35 2012 (r239245) +++ head/sys/fs/smbfs/smbfs_io.c Tue Aug 14 11:45:47 2012 (r239246) @@ -523,7 +523,7 @@ smbfs_getpages(ap) } if (i != reqpage) - vm_page_readahead_finish(m, error); + vm_page_readahead_finish(m); } VM_OBJECT_UNLOCK(object); return 0; Modified: head/sys/nfsclient/nfs_bio.c ============================================================================== --- head/sys/nfsclient/nfs_bio.c Tue Aug 14 05:16:35 2012 (r239245) +++ head/sys/nfsclient/nfs_bio.c Tue Aug 14 11:45:47 2012 (r239246) @@ -212,14 +212,18 @@ nfs_getpages(struct vop_getpages_args *a ("nfs_getpages: page %p is dirty", m)); } else { /* - * Read operation was short. If no error occured - * we may have hit a zero-fill section. We simply - * leave valid set to 0. + * Read operation was short. If no error + * occured we may have hit a zero-fill + * section. We leave valid set to 0, and page + * is freed by vm_page_readahead_finish() if + * its index is not equal to requested, or + * page is zeroed and set valid by + * vm_pager_get_pages() for requested page. */ ; } if (i != ap->a_reqpage) - vm_page_readahead_finish(m, error); + vm_page_readahead_finish(m); } VM_OBJECT_UNLOCK(object); return (0); Modified: head/sys/vm/vm_page.c ============================================================================== --- head/sys/vm/vm_page.c Tue Aug 14 05:16:35 2012 (r239245) +++ head/sys/vm/vm_page.c Tue Aug 14 11:45:47 2012 (r239246) @@ -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, in } 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); Modified: head/sys/vm/vm_page.h ============================================================================== --- head/sys/vm/vm_page.h Tue Aug 14 05:16:35 2012 (r239245) +++ head/sys/vm/vm_page.h Tue Aug 14 11:45:47 2012 (r239246) @@ -388,7 +388,7 @@ vm_page_t vm_page_next(vm_page_t m); int vm_page_pa_tryrelock(pmap_t, vm_paddr_t, vm_paddr_t *); vm_page_t vm_page_prev(vm_page_t m); void vm_page_putfake(vm_page_t m); -void vm_page_readahead_finish(vm_page_t m, int error); +void vm_page_readahead_finish(vm_page_t m); void vm_page_reference(vm_page_t m); void vm_page_remove (vm_page_t); void vm_page_rename (vm_page_t, vm_object_t, vm_pindex_t); Modified: head/sys/vm/vnode_pager.c ============================================================================== --- head/sys/vm/vnode_pager.c Tue Aug 14 05:16:35 2012 (r239245) +++ head/sys/vm/vnode_pager.c Tue Aug 14 11:45:47 2012 (r239246) @@ -987,7 +987,7 @@ vnode_pager_generic_getpages(vp, m, byte } if (i != reqpage) - vm_page_readahead_finish(mt, error); + vm_page_readahead_finish(mt); } VM_OBJECT_UNLOCK(object); if (error) {