Date: Fri, 6 Sep 2019 19:29:03 +0000 (UTC) From: Alan Somers <asomers@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r351958 - stable/12/sys/kern Message-ID: <201909061929.x86JT3ti061966@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: asomers Date: Fri Sep 6 19:29:02 2019 New Revision: 351958 URL: https://svnweb.freebsd.org/changeset/base/351958 Log: MFC r350426: sendfile: don't panic when VOP_GETPAGES_ASYNC returns an error This is a partial merge of 350144 from projects/fuse2 PR: 236466 Reviewed by: markj Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D21095 Modified: stable/12/sys/kern/kern_sendfile.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/kern/kern_sendfile.c ============================================================================== --- stable/12/sys/kern/kern_sendfile.c Fri Sep 6 19:22:33 2019 (r351957) +++ stable/12/sys/kern/kern_sendfile.c Fri Sep 6 19:29:02 2019 (r351958) @@ -316,13 +316,13 @@ sendfile_iodone(void *arg, vm_page_t *pg, int count, i * Iterate through pages vector and request paging for non-valid pages. */ static int -sendfile_swapin(vm_object_t obj, struct sf_io *sfio, off_t off, off_t len, - int npages, int rhpages, int flags) +sendfile_swapin(vm_object_t obj, struct sf_io *sfio, int *nios, off_t off, + off_t len, int npages, int rhpages, int flags) { vm_page_t *pa = sfio->pa; - int grabbed, nios; + int grabbed; - nios = 0; + *nios = 0; flags = (flags & SF_NODISKIO) ? VM_ALLOC_NOWAIT : 0; /* @@ -341,7 +341,7 @@ sendfile_swapin(vm_object_t obj, struct sf_io *sfio, o } for (int i = 0; i < npages;) { - int j, a, count, rv __unused; + int j, a, count, rv; /* Skip valid pages. */ if (vm_page_is_valid(pa[i], vmoff(i, off) & PAGE_MASK, @@ -404,6 +404,17 @@ sendfile_swapin(vm_object_t obj, struct sf_io *sfio, o rv = vm_pager_get_pages_async(obj, pa + i, count, NULL, i + count == npages ? &rhpages : NULL, &sendfile_iodone, sfio); + if (rv != VM_PAGER_OK) { + for (j = i; j < i + count; j++) { + if (pa[j] != bogus_page) { + vm_page_lock(pa[j]); + vm_page_unwire(pa[j], PQ_INACTIVE); + vm_page_unlock(pa[j]); + } + } + VM_OBJECT_WUNLOCK(obj); + return (EIO); + } KASSERT(rv == VM_PAGER_OK, ("%s: pager fail obj %p page %p", __func__, obj, pa[i])); @@ -425,15 +436,15 @@ sendfile_swapin(vm_object_t obj, struct sf_io *sfio, o } i += count; - nios++; + (*nios)++; } VM_OBJECT_WUNLOCK(obj); - if (nios == 0 && npages != 0) + if (*nios == 0 && npages != 0) SFSTAT_INC(sf_noiocnt); - return (nios); + return (0); } static int @@ -743,8 +754,14 @@ retry_space: sfio->so = so; sfio->error = 0; - nios = sendfile_swapin(obj, sfio, off, space, npages, rhpages, - flags); + error = sendfile_swapin(obj, sfio, &nios, off, space, npages, + rhpages, flags); + if (error != 0) { + if (vp != NULL) + VOP_UNLOCK(vp, 0); + free(sfio, M_TEMP); + goto done; + } /* * Loop and construct maximum sized mbuf chain to be bulk
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201909061929.x86JT3ti061966>