From owner-svn-src-all@FreeBSD.ORG Tue Apr 19 16:36:25 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 57F271065673; Tue, 19 Apr 2011 16:36:25 +0000 (UTC) (envelope-from mdf@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 46CBA8FC24; Tue, 19 Apr 2011 16:36:25 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id p3JGaPvJ014237; Tue, 19 Apr 2011 16:36:25 GMT (envelope-from mdf@svn.freebsd.org) Received: (from mdf@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id p3JGaPdW014233; Tue, 19 Apr 2011 16:36:25 GMT (envelope-from mdf@svn.freebsd.org) Message-Id: <201104191636.p3JGaPdW014233@svn.freebsd.org> From: Matthew D Fleming Date: Tue, 19 Apr 2011 16:36:25 +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: r220846 - head/sys/kern X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 19 Apr 2011 16:36:25 -0000 Author: mdf Date: Tue Apr 19 16:36:24 2011 New Revision: 220846 URL: http://svn.freebsd.org/changeset/base/220846 Log: Allow VOP_ALLOCATE to be iterative, and have kern_posix_fallocate(9) drive looping and potentially yielding. Requested by: kib Modified: head/sys/kern/vfs_default.c head/sys/kern/vfs_syscalls.c head/sys/kern/vnode_if.src Modified: head/sys/kern/vfs_default.c ============================================================================== --- head/sys/kern/vfs_default.c Tue Apr 19 16:33:08 2011 (r220845) +++ head/sys/kern/vfs_default.c Tue Apr 19 16:36:24 2011 (r220846) @@ -865,25 +865,25 @@ vop_stdallocate(struct vop_allocate_args struct iovec aiov; struct vattr vattr, *vap; struct uio auio; - off_t len, cur, offset; + off_t fsize, len, cur, offset; uint8_t *buf; struct thread *td; struct vnode *vp; size_t iosize; - int error, locked; + int error; buf = NULL; error = 0; - locked = 1; td = curthread; vap = &vattr; vp = ap->a_vp; - len = ap->a_len; - offset = ap->a_offset; + len = *ap->a_len; + offset = *ap->a_offset; error = VOP_GETATTR(vp, vap, td->td_ucred); if (error != 0) goto out; + fsize = vap->va_size; iosize = vap->va_blocksize; if (iosize == 0) iosize = BLKDEV_IOSIZE; @@ -908,27 +908,22 @@ vop_stdallocate(struct vop_allocate_args } else #endif if (offset + len > vap->va_size) { + /* + * Test offset + len against the filesystem's maxfilesize. + */ VATTR_NULL(vap); vap->va_size = offset + len; error = VOP_SETATTR(vp, vap, td->td_ucred); if (error != 0) goto out; + VATTR_NULL(vap); + vap->va_size = fsize; + error = VOP_SETATTR(vp, vap, td->td_ucred); + if (error != 0) + goto out; } - while (len > 0) { - if (should_yield()) { - VOP_UNLOCK(vp, 0); - locked = 0; - kern_yield(-1); - error = vn_lock(vp, LK_EXCLUSIVE); - if (error != 0) - break; - locked = 1; - error = VOP_GETATTR(vp, vap, td->td_ucred); - if (error != 0) - break; - } - + for (;;) { /* * Read and write back anything below the nominal file * size. There's currently no way outside the filesystem @@ -939,7 +934,7 @@ vop_stdallocate(struct vop_allocate_args cur -= (offset % iosize); if (cur > len) cur = len; - if (offset < vap->va_size) { + if (offset < fsize) { aiov.iov_base = buf; aiov.iov_len = cur; auio.uio_iov = &aiov; @@ -976,12 +971,15 @@ vop_stdallocate(struct vop_allocate_args len -= cur; offset += cur; + if (len == 0) + break; + if (should_yield()) + break; } out: - KASSERT(locked || error != 0, ("How'd I get unlocked with no error?")); - if (locked && error != 0) - VOP_UNLOCK(vp, 0); + *ap->a_len = len; + *ap->a_offset = offset; free(buf, M_TEMP); return (error); } Modified: head/sys/kern/vfs_syscalls.c ============================================================================== --- head/sys/kern/vfs_syscalls.c Tue Apr 19 16:33:08 2011 (r220845) +++ head/sys/kern/vfs_syscalls.c Tue Apr 19 16:36:24 2011 (r220846) @@ -4678,12 +4678,11 @@ kern_posix_fallocate(struct thread *td, struct file *fp; struct mount *mp; struct vnode *vp; - int error, vfslocked, vnlocked; + off_t olen, ooffset; + int error, vfslocked; fp = NULL; - mp = NULL; vfslocked = 0; - vnlocked = 0; error = fget(td, fd, &fp); if (error != 0) goto out; @@ -4718,28 +4717,44 @@ kern_posix_fallocate(struct thread *td, goto out; } - bwillwrite(); - vfslocked = VFS_LOCK_GIANT(vp->v_mount); - error = vn_start_write(vp, &mp, V_WAIT | PCATCH); - if (error != 0) - goto out; - error = vn_lock(vp, LK_EXCLUSIVE); - if (error != 0) - goto out; - vnlocked = 1; + /* Allocating blocks may take a long time, so iterate. */ + for (;;) { + olen = len; + ooffset = offset; + + bwillwrite(); + vfslocked = VFS_LOCK_GIANT(vp->v_mount); + mp = NULL; + error = vn_start_write(vp, &mp, V_WAIT | PCATCH); + if (error != 0) { + VFS_UNLOCK_GIANT(vfslocked); + break; + } + error = vn_lock(vp, LK_EXCLUSIVE); + if (error != 0) { + vn_finished_write(mp); + VFS_UNLOCK_GIANT(vfslocked); + break; + } #ifdef MAC - error = mac_vnode_check_write(td->td_ucred, fp->f_cred, vp); - if (error != 0) - goto out; + error = mac_vnode_check_write(td->td_ucred, fp->f_cred, vp); + if (error == 0) #endif - error = VOP_ALLOCATE(vp, offset, len); - if (error != 0) - vnlocked = 0; - out: - if (vnlocked) + error = VOP_ALLOCATE(vp, &offset, &len); VOP_UNLOCK(vp, 0); - vn_finished_write(mp); - VFS_UNLOCK_GIANT(vfslocked); + vn_finished_write(mp); + VFS_UNLOCK_GIANT(vfslocked); + + if (olen + ooffset != offset + len) { + panic("offset + len changed from %jx/%jx to %jx/%jx", + ooffset, olen, offset, len); + } + if (error != 0 || len == 0) + break; + KASSERT(olen > len, ("Iteration did not make progress?")); + maybe_yield(); + } + out: if (fp != NULL) fdrop(fp, td); return (error); Modified: head/sys/kern/vnode_if.src ============================================================================== --- head/sys/kern/vnode_if.src Tue Apr 19 16:33:08 2011 (r220845) +++ head/sys/kern/vnode_if.src Tue Apr 19 16:36:24 2011 (r220846) @@ -621,10 +621,10 @@ vop_vptocnp { }; -%% allocate vp E E U +%% allocate vp E E E vop_allocate { IN struct vnode *vp; - IN off_t offset; - IN off_t len; + IN off_t *offset; + IN off_t *len; };