Sat Sep 7 16:08:28 2013 UTC ()
Pull up following revision(s) (requested by hannken in ticket #933):
	sys/nfs/nfs_bio.c: revision 1.189
Function nfs_vinvalbuf() ignores errors from vinvalbuf() and therefore
delayed write errors may get lost.
Change nfs_vinvalbuf() to keep errors from vinvalbuf() for fsync() or =
close().
=20
Presented on tech-kern@
=20
Fix for PR kern/47980 (NFS over-quota not detected if utimes() called
before fsync()/close())
=20
=20


(bouyer)
diff -r1.188 -r1.188.22.1 src/sys/nfs/nfs_bio.c

cvs diff -r1.188 -r1.188.22.1 src/sys/nfs/nfs_bio.c (expand / switch to unified diff)

--- src/sys/nfs/nfs_bio.c 2011/09/27 01:07:38 1.188
+++ src/sys/nfs/nfs_bio.c 2013/09/07 16:08:28 1.188.22.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: nfs_bio.c,v 1.188 2011/09/27 01:07:38 christos Exp $ */ 1/* $NetBSD: nfs_bio.c,v 1.188.22.1 2013/09/07 16:08:28 bouyer Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1989, 1993 4 * Copyright (c) 1989, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * Rick Macklem at The University of Guelph. 8 * Rick Macklem at The University of Guelph.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -25,27 +25,27 @@ @@ -25,27 +25,27 @@
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE. 32 * SUCH DAMAGE.
33 * 33 *
34 * @(#)nfs_bio.c 8.9 (Berkeley) 3/30/95 34 * @(#)nfs_bio.c 8.9 (Berkeley) 3/30/95
35 */ 35 */
36 36
37#include <sys/cdefs.h> 37#include <sys/cdefs.h>
38__KERNEL_RCSID(0, "$NetBSD: nfs_bio.c,v 1.188 2011/09/27 01:07:38 christos Exp $"); 38__KERNEL_RCSID(0, "$NetBSD: nfs_bio.c,v 1.188.22.1 2013/09/07 16:08:28 bouyer Exp $");
39 39
40#ifdef _KERNEL_OPT 40#ifdef _KERNEL_OPT
41#include "opt_nfs.h" 41#include "opt_nfs.h"
42#include "opt_ddb.h" 42#include "opt_ddb.h"
43#endif 43#endif
44 44
45#include <sys/param.h> 45#include <sys/param.h>
46#include <sys/systm.h> 46#include <sys/systm.h>
47#include <sys/resourcevar.h> 47#include <sys/resourcevar.h>
48#include <sys/signalvar.h> 48#include <sys/signalvar.h>
49#include <sys/proc.h> 49#include <sys/proc.h>
50#include <sys/buf.h> 50#include <sys/buf.h>
51#include <sys/vnode.h> 51#include <sys/vnode.h>
@@ -604,27 +604,27 @@ nfs_getcacheblk(struct vnode *vp, daddr_ @@ -604,27 +604,27 @@ nfs_getcacheblk(struct vnode *vp, daddr_
604 return (bp); 604 return (bp);
605} 605}
606 606
607/* 607/*
608 * Flush and invalidate all dirty buffers. If another process is already 608 * Flush and invalidate all dirty buffers. If another process is already
609 * doing the flush, just wait for completion. 609 * doing the flush, just wait for completion.
610 */ 610 */
611int 611int
612nfs_vinvalbuf(struct vnode *vp, int flags, kauth_cred_t cred, 612nfs_vinvalbuf(struct vnode *vp, int flags, kauth_cred_t cred,
613 struct lwp *l, int intrflg) 613 struct lwp *l, int intrflg)
614{ 614{
615 struct nfsnode *np = VTONFS(vp); 615 struct nfsnode *np = VTONFS(vp);
616 struct nfsmount *nmp = VFSTONFS(vp->v_mount); 616 struct nfsmount *nmp = VFSTONFS(vp->v_mount);
617 int error = 0, slptimeo; 617 int error = 0, allerror = 0, slptimeo;
618 bool catch; 618 bool catch;
619 619
620 if ((nmp->nm_flag & NFSMNT_INT) == 0) 620 if ((nmp->nm_flag & NFSMNT_INT) == 0)
621 intrflg = 0; 621 intrflg = 0;
622 if (intrflg) { 622 if (intrflg) {
623 catch = true; 623 catch = true;
624 slptimeo = 2 * hz; 624 slptimeo = 2 * hz;
625 } else { 625 } else {
626 catch = false; 626 catch = false;
627 slptimeo = 0; 627 slptimeo = 0;
628 } 628 }
629 /* 629 /*
630 * First wait for any other process doing a flush to complete. 630 * First wait for any other process doing a flush to complete.
@@ -637,33 +637,42 @@ nfs_vinvalbuf(struct vnode *vp, int flag @@ -637,33 +637,42 @@ nfs_vinvalbuf(struct vnode *vp, int flag
637 if (error && intrflg && nfs_sigintr(nmp, NULL, l)) { 637 if (error && intrflg && nfs_sigintr(nmp, NULL, l)) {
638 mutex_exit(vp->v_interlock); 638 mutex_exit(vp->v_interlock);
639 return EINTR; 639 return EINTR;
640 } 640 }
641 } 641 }
642 642
643 /* 643 /*
644 * Now, flush as required. 644 * Now, flush as required.
645 */ 645 */
646 np->n_flag |= NFLUSHINPROG; 646 np->n_flag |= NFLUSHINPROG;
647 mutex_exit(vp->v_interlock); 647 mutex_exit(vp->v_interlock);
648 error = vinvalbuf(vp, flags, cred, l, catch, 0); 648 error = vinvalbuf(vp, flags, cred, l, catch, 0);
649 while (error) { 649 while (error) {
 650 if (allerror == 0)
 651 allerror = error;
650 if (intrflg && nfs_sigintr(nmp, NULL, l)) { 652 if (intrflg && nfs_sigintr(nmp, NULL, l)) {
651 error = EINTR; 653 error = EINTR;
652 break; 654 break;
653 } 655 }
654 error = vinvalbuf(vp, flags, cred, l, 0, slptimeo); 656 error = vinvalbuf(vp, flags, cred, l, 0, slptimeo);
655 } 657 }
656 mutex_enter(vp->v_interlock); 658 mutex_enter(vp->v_interlock);
 659 if (allerror != 0) {
 660 /*
 661 * Keep error from vinvalbuf so fsync/close will know.
 662 */
 663 np->n_error = allerror;
 664 np->n_flag |= NWRITEERR;
 665 }
657 if (error == 0) 666 if (error == 0)
658 np->n_flag &= ~NMODIFIED; 667 np->n_flag &= ~NMODIFIED;
659 np->n_flag &= ~NFLUSHINPROG; 668 np->n_flag &= ~NFLUSHINPROG;
660 if (np->n_flag & NFLUSHWANT) { 669 if (np->n_flag & NFLUSHWANT) {
661 np->n_flag &= ~NFLUSHWANT; 670 np->n_flag &= ~NFLUSHWANT;
662 wakeup(&np->n_flag); 671 wakeup(&np->n_flag);
663 } 672 }
664 mutex_exit(vp->v_interlock); 673 mutex_exit(vp->v_interlock);
665 return error; 674 return error;
666} 675}
667 676
668/* 677/*
669 * nfs_flushstalebuf: flush cache if it's stale. 678 * nfs_flushstalebuf: flush cache if it's stale.