From owner-svn-src-stable-8@FreeBSD.ORG Fri Jul 12 00:59:04 2013 Return-Path: Delivered-To: svn-src-stable-8@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 0D3E7715; Fri, 12 Jul 2013 00:59:04 +0000 (UTC) (envelope-from rmacklem@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id D9F3B1FF6; Fri, 12 Jul 2013 00:59:03 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r6C0x302088327; Fri, 12 Jul 2013 00:59:03 GMT (envelope-from rmacklem@svn.freebsd.org) Received: (from rmacklem@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r6C0x39m088326; Fri, 12 Jul 2013 00:59:03 GMT (envelope-from rmacklem@svn.freebsd.org) Message-Id: <201307120059.r6C0x39m088326@svn.freebsd.org> From: Rick Macklem Date: Fri, 12 Jul 2013 00:59:03 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org Subject: svn commit: r253229 - stable/8/sys/nfsclient X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-8@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for only the 8-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 12 Jul 2013 00:59:04 -0000 Author: rmacklem Date: Fri Jul 12 00:59:03 2013 New Revision: 253229 URL: http://svnweb.freebsd.org/changeset/base/253229 Log: MFC: r252673 A problem with the old NFS client where large writes to large files would sometimes result in a corrupted file was reported via email. This problem appears to have been caused by r251719 (reverting r251719 fixed the problem). Although I have not been able to reproduce this problem, I suspect it is caused by another thread increasing np->n_size after the mtx_unlock(&np->n_mtx) but before the vnode_pager_setsize() call. Since the np->n_mtx mutex serializes updates to np->n_size, doing the vnode_pager_setsize() with the mutex locked appears to avoid the problem. Unfortunately, vnode_pager_setsize() where the new size is smaller, cannot be called with a mutex held. This patch returns the semantics to be close to pre-r251719 such that the call to the vnode_pager_setsize() is only delayed until after the mutex is unlocked when np->n_size is shrinking. Since the file is growing when being written, I believe this will fix the corruption. Tested by: remy.nonnenmacher@activnetworks.com Modified: stable/8/sys/nfsclient/nfs_subs.c Directory Properties: stable/8/sys/ (props changed) stable/8/sys/nfsclient/ (props changed) Modified: stable/8/sys/nfsclient/nfs_subs.c ============================================================================== --- stable/8/sys/nfsclient/nfs_subs.c Fri Jul 12 00:50:25 2013 (r253228) +++ stable/8/sys/nfsclient/nfs_subs.c Fri Jul 12 00:59:03 2013 (r253229) @@ -595,6 +595,7 @@ nfs_loadattrcache(struct vnode **vpp, st vap->va_size = np->n_size; np->n_attrstamp = 0; KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp); + vnode_pager_setsize(vp, np->n_size); } else if (np->n_flag & NMODIFIED) { /* * We've modified the file: Use the larger @@ -606,12 +607,22 @@ nfs_loadattrcache(struct vnode **vpp, st np->n_size = vap->va_size; np->n_flag |= NSIZECHANGED; } + vnode_pager_setsize(vp, np->n_size); + } else if (vap->va_size < np->n_size) { + /* + * When shrinking the size, the call to + * vnode_pager_setsize() cannot be done + * with the mutex held, so delay it until + * after the mtx_unlock call. + */ + nsize = np->n_size = vap->va_size; + np->n_flag |= NSIZECHANGED; + setnsize = 1; } else { np->n_size = vap->va_size; np->n_flag |= NSIZECHANGED; + vnode_pager_setsize(vp, np->n_size); } - setnsize = 1; - nsize = vap->va_size; } else { np->n_size = vap->va_size; }