From owner-svn-src-head@FreeBSD.ORG Fri Apr 29 21:18:41 2011 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 8DAA11065673; Fri, 29 Apr 2011 21:18:41 +0000 (UTC) (envelope-from des@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 62A368FC14; Fri, 29 Apr 2011 21:18:41 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p3TLIfg3016067; Fri, 29 Apr 2011 21:18:41 GMT (envelope-from des@svn.freebsd.org) Received: (from des@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p3TLIf56016065; Fri, 29 Apr 2011 21:18:41 GMT (envelope-from des@svn.freebsd.org) Message-Id: <201104292118.p3TLIf56016065@svn.freebsd.org> From: Dag-Erling Smorgrav Date: Fri, 29 Apr 2011 21:18:41 +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: r221229 - head/sys/dev/md X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 29 Apr 2011 21:18:41 -0000 Author: des Date: Fri Apr 29 21:18:41 2011 New Revision: 221229 URL: http://svn.freebsd.org/changeset/base/221229 Log: Implement BIO_DELETE for vnode devices by simply overwriting the deleted sectors with all-zeroes. The zeroes come from a static buffer; null(4) uses a dynamic buffer for the same purpose (for /dev/zero). It might be a good idea to have a static, shared, read-only all-zeroes page somewhere in the kernel that md(4), null(4) and any other code that needs zeroes could use. Reviewed by: kib MFC after: 3 weeks Modified: head/sys/dev/md/md.c Modified: head/sys/dev/md/md.c ============================================================================== --- head/sys/dev/md/md.c Fri Apr 29 21:10:45 2011 (r221228) +++ head/sys/dev/md/md.c Fri Apr 29 21:18:41 2011 (r221229) @@ -205,6 +205,9 @@ struct md_s { vm_object_t object; }; +/* Used for BIO_DELETE on MD_VNODE */ +static u_char zero[PAGE_SIZE]; + static struct indir * new_indir(u_int shift) { @@ -514,10 +517,12 @@ mdstart_vnode(struct md_s *sc, struct bi struct mount *mp; struct vnode *vp; struct thread *td; + off_t end, zerosize; switch (bp->bio_cmd) { case BIO_READ: case BIO_WRITE: + case BIO_DELETE: case BIO_FLUSH: break; default: @@ -548,6 +553,43 @@ mdstart_vnode(struct md_s *sc, struct bi bzero(&auio, sizeof(auio)); + /* + * Special case for BIO_DELETE. On the surface, this is very + * similar to BIO_WRITE, except that we write from our own + * fixed-length buffer, so we have to loop. The net result is + * that the two cases end up having very little in common. + */ + if (bp->bio_cmd == BIO_DELETE) { + zerosize = sizeof(zero) - (sizeof(zero) % sc->sectorsize); + auio.uio_iov = &aiov; + auio.uio_iovcnt = 1; + auio.uio_offset = (vm_ooffset_t)bp->bio_offset; + auio.uio_segflg = UIO_SYSSPACE; + auio.uio_rw = UIO_WRITE; + auio.uio_td = td; + end = bp->bio_offset + bp->bio_length; + vfslocked = VFS_LOCK_GIANT(vp->v_mount); + (void) vn_start_write(vp, &mp, V_WAIT); + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); + error = 0; + while (auio.uio_offset < end) { + aiov.iov_base = zero; + aiov.iov_len = end - auio.uio_offset; + if (aiov.iov_len > zerosize) + aiov.iov_len = zerosize; + auio.uio_resid = aiov.iov_len; + error = VOP_WRITE(vp, &auio, + sc->flags & MD_ASYNC ? 0 : IO_SYNC, sc->cred); + if (error != 0) + break; + } + VOP_UNLOCK(vp, 0); + vn_finished_write(mp); + bp->bio_resid = end - auio.uio_offset; + VFS_UNLOCK_GIANT(vfslocked); + return (error); + } + aiov.iov_base = bp->bio_data; aiov.iov_len = bp->bio_length; auio.uio_iov = &aiov;