kern/111162: nfs_getpages does not restart interrupted system call
Michael Conlen
meconlen at obfuscated.net
Mon Apr 2 23:40:04 UTC 2007
>Number: 111162
>Category: kern
>Synopsis: nfs_getpages does not restart interrupted system call
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Mon Apr 02 23:40:03 GMT 2007
>Closed-Date:
>Last-Modified:
>Originator: Michael Conlen
>Release: 6.2
>Organization:
>Environment:
FreeBSD web10.tarhost.com 6.2-RELEASE-p1 FreeBSD 6.2-RELEASE-p1 #7: Tue Mar 20 15:05:34 EDT 2007 root at web10.tarhost.com:/usr/obj/usr/src/sys/WWW i386
>Description:
I see the following in /var/log/messages
Apr 2 18:56:43 web10 kernel: nfs_getpages: error 4
Upon this happening on a client if the file was locked it remains locked which may be a problem elsewhere, however I believe nfs_getpages should restart the system call that got interrupted.
>How-To-Repeat:
run a high volume nfs client and wait for a process that accesses files to randomly get interrupted for some reason.
>Fix:
I imagine the fix is somewhere in nfs_bio.c. I would imagine you just check the error and if it's EINTR call it again but I don't know enough to know if you can just recall the function...
152 bp = getpbuf(&nfs_pbuf_freecnt);
153
154 kva = (vm_offset_t) bp->b_data;
155 pmap_qenter(kva, pages, npages);
156 cnt.v_vnodein++;
157 cnt.v_vnodepgsin += npages;
158
159 iov.iov_base = (caddr_t) kva;
160 iov.iov_len = count;
161 uio.uio_iov = &iov;
162 uio.uio_iovcnt = 1;
163 uio.uio_offset = IDX_TO_OFF(pages[0]->pindex);
164 uio.uio_resid = count;
165 uio.uio_segflg = UIO_SYSSPACE;
166 uio.uio_rw = UIO_READ;
167 uio.uio_td = td;
168
169 error = (nmp->nm_rpcops->nr_readrpc)(vp, &uio, cred);
170 pmap_qremove(kva, npages);
171
172 relpbuf(bp, &nfs_pbuf_freecnt);
173
174 if (error && (uio.uio_resid == count)) {
175 printf("nfs_getpages: error %d\n", error);
176 VM_OBJECT_LOCK(object);
177 vm_page_lock_queues();
178 for (i = 0; i < npages; ++i) {
179 if (i != ap->a_reqpage)
180 vm_page_free(pages[i]);
181 }
182 vm_page_unlock_queues();
183 VM_OBJECT_UNLOCK(object);
184 return VM_PAGER_ERROR;
185 }
186
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list