From owner-svn-src-head@freebsd.org Tue Dec 3 23:07:11 2019 Return-Path: Delivered-To: svn-src-head@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 2F7321C12CC; Tue, 3 Dec 2019 23:07:11 +0000 (UTC) (envelope-from mckusick@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 47SHgM0TwWz46N7; Tue, 3 Dec 2019 23:07:11 +0000 (UTC) (envelope-from mckusick@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id E93F81F012; Tue, 3 Dec 2019 23:07:10 +0000 (UTC) (envelope-from mckusick@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id xB3N7Ax8016928; Tue, 3 Dec 2019 23:07:10 GMT (envelope-from mckusick@FreeBSD.org) Received: (from mckusick@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id xB3N79DG016921; Tue, 3 Dec 2019 23:07:09 GMT (envelope-from mckusick@FreeBSD.org) Message-Id: <201912032307.xB3N79DG016921@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mckusick set sender to mckusick@FreeBSD.org using -f From: Kirk McKusick Date: Tue, 3 Dec 2019 23:07:09 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r355371 - in head/sys: kern sys ufs/ffs X-SVN-Group: head X-SVN-Commit-Author: mckusick X-SVN-Commit-Paths: in head/sys: kern sys ufs/ffs X-SVN-Commit-Revision: 355371 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.29 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: Tue, 03 Dec 2019 23:07:11 -0000 Author: mckusick Date: Tue Dec 3 23:07:09 2019 New Revision: 355371 URL: https://svnweb.freebsd.org/changeset/base/355371 Log: Currently the breadn_flags() and getblkx() interfaces are passed the vnode, logical block number, and size of data block that is being requested. They then use the VOP_BMAP function to calculate the mapping from logical block number to physical block number from which to access the data. This change expands the interface to also pass the physical block number in cases where the VOP_MAP function may no longer work, for example when a file is being truncated. No functional change. Reviewed by: kib Tested by: Peter Holm Sponsored by: Netflix Modified: head/sys/kern/vfs_bio.c head/sys/kern/vfs_cluster.c head/sys/sys/buf.h head/sys/ufs/ffs/ffs_alloc.c head/sys/ufs/ffs/ffs_inode.c head/sys/ufs/ffs/ffs_softdep.c head/sys/ufs/ffs/ffs_vnops.c Modified: head/sys/kern/vfs_bio.c ============================================================================== --- head/sys/kern/vfs_bio.c Tue Dec 3 22:59:55 2019 (r355370) +++ head/sys/kern/vfs_bio.c Tue Dec 3 23:07:09 2019 (r355371) @@ -2126,10 +2126,17 @@ breada(struct vnode * vp, daddr_t * rablkno, int * rab * getblk(). Also starts asynchronous I/O on read-ahead blocks. * * Always return a NULL buffer pointer (in bpp) when returning an error. + * + * The blkno parameter is the logical block being requested. Normally + * the mapping of logical block number to disk block address is done + * by calling VOP_BMAP(). However, if the mapping is already known, the + * disk block address can be passed using the dblkno parameter. If the + * disk block address is not known, then the same value should be passed + * for blkno and dblkno. */ int -breadn_flags(struct vnode *vp, daddr_t blkno, int size, daddr_t *rablkno, - int *rabsize, int cnt, struct ucred *cred, int flags, +breadn_flags(struct vnode *vp, daddr_t blkno, daddr_t dblkno, int size, + daddr_t *rablkno, int *rabsize, int cnt, struct ucred *cred, int flags, void (*ckhashfunc)(struct buf *), struct buf **bpp) { struct buf *bp; @@ -2142,11 +2149,14 @@ breadn_flags(struct vnode *vp, daddr_t blkno, int size * Can only return NULL if GB_LOCK_NOWAIT or GB_SPARSE flags * are specified. */ - error = getblkx(vp, blkno, size, 0, 0, flags, &bp); + error = getblkx(vp, blkno, dblkno, size, 0, 0, flags, &bp); if (error != 0) { *bpp = NULL; return (error); } + KASSERT(blkno == bp->b_lblkno, + ("getblkx returned buffer for blkno %jd instead of blkno %jd", + (intmax_t)bp->b_lblkno, (intmax_t)blkno)); flags &= ~GB_NOSPARSE; *bpp = bp; @@ -3791,7 +3801,7 @@ getblk(struct vnode *vp, daddr_t blkno, int size, int struct buf *bp; int error; - error = getblkx(vp, blkno, size, slpflag, slptimeo, flags, &bp); + error = getblkx(vp, blkno, blkno, size, slpflag, slptimeo, flags, &bp); if (error != 0) return (NULL); return (bp); @@ -3819,7 +3829,7 @@ getblk(struct vnode *vp, daddr_t blkno, int size, int * case it is returned with B_INVAL clear and B_CACHE set based on the * backing VM. * - * getblk() also forces a bwrite() for any B_DELWRI buffer whos + * getblk() also forces a bwrite() for any B_DELWRI buffer whose * B_CACHE bit is clear. * * What this means, basically, is that the caller should use B_CACHE to @@ -3832,10 +3842,17 @@ getblk(struct vnode *vp, daddr_t blkno, int size, int * a write attempt or if it was a successful read. If the caller * intends to issue a READ, the caller must clear B_INVAL and BIO_ERROR * prior to issuing the READ. biodone() will *not* clear B_INVAL. + * + * The blkno parameter is the logical block being requested. Normally + * the mapping of logical block number to disk block address is done + * by calling VOP_BMAP(). However, if the mapping is already known, the + * disk block address can be passed using the dblkno parameter. If the + * disk block address is not known, then the same value should be passed + * for blkno and dblkno. */ int -getblkx(struct vnode *vp, daddr_t blkno, int size, int slpflag, int slptimeo, - int flags, struct buf **bpp) +getblkx(struct vnode *vp, daddr_t blkno, daddr_t dblkno, int size, int slpflag, + int slptimeo, int flags, struct buf **bpp) { struct buf *bp; struct bufobj *bo; @@ -3854,7 +3871,7 @@ getblkx(struct vnode *vp, daddr_t blkno, int size, int flags &= ~(GB_UNMAPPED | GB_KVAALLOC); bo = &vp->v_bufobj; - d_blkno = blkno; + d_blkno = dblkno; loop: BO_RLOCK(bo); bp = gbincore(bo, blkno); Modified: head/sys/kern/vfs_cluster.c ============================================================================== --- head/sys/kern/vfs_cluster.c Tue Dec 3 22:59:55 2019 (r355370) +++ head/sys/kern/vfs_cluster.c Tue Dec 3 23:07:09 2019 (r355371) @@ -131,7 +131,7 @@ cluster_read(struct vnode *vp, u_quad_t filesize, dadd /* * get the requested block */ - error = getblkx(vp, lblkno, size, 0, 0, gbflags, &bp); + error = getblkx(vp, lblkno, lblkno, size, 0, 0, gbflags, &bp); if (error != 0) { *bpp = NULL; return (error); Modified: head/sys/sys/buf.h ============================================================================== --- head/sys/sys/buf.h Tue Dec 3 22:59:55 2019 (r355370) +++ head/sys/sys/buf.h Tue Dec 3 23:07:09 2019 (r355371) @@ -520,15 +520,16 @@ int buf_dirty_count_severe(void); void bremfree(struct buf *); void bremfreef(struct buf *); /* XXX Force bremfree, only for nfs. */ #define bread(vp, blkno, size, cred, bpp) \ - breadn_flags(vp, blkno, size, NULL, NULL, 0, cred, 0, NULL, bpp) + breadn_flags(vp, blkno, blkno, size, NULL, NULL, 0, cred, 0, \ + NULL, bpp) #define bread_gb(vp, blkno, size, cred, gbflags, bpp) \ - breadn_flags(vp, blkno, size, NULL, NULL, 0, cred, \ + breadn_flags(vp, blkno, blkno, size, NULL, NULL, 0, cred, \ gbflags, NULL, bpp) #define breadn(vp, blkno, size, rablkno, rabsize, cnt, cred, bpp) \ - breadn_flags(vp, blkno, size, rablkno, rabsize, cnt, cred, \ + breadn_flags(vp, blkno, blkno, size, rablkno, rabsize, cnt, cred, \ 0, NULL, bpp) -int breadn_flags(struct vnode *, daddr_t, int, daddr_t *, int *, int, - struct ucred *, int, void (*)(struct buf *), struct buf **); +int breadn_flags(struct vnode *, daddr_t, daddr_t, int, daddr_t *, int *, + int, struct ucred *, int, void (*)(struct buf *), struct buf **); void bdwrite(struct buf *); void bawrite(struct buf *); void babarrierwrite(struct buf *); @@ -544,8 +545,8 @@ void vfs_busy_pages_release(struct buf *bp); struct buf *incore(struct bufobj *, daddr_t); struct buf *gbincore(struct bufobj *, daddr_t); struct buf *getblk(struct vnode *, daddr_t, int, int, int, int); -int getblkx(struct vnode *vp, daddr_t blkno, int size, int slpflag, - int slptimeo, int flags, struct buf **bpp); +int getblkx(struct vnode *vp, daddr_t blkno, daddr_t dblkno, int size, + int slpflag, int slptimeo, int flags, struct buf **bpp); struct buf *geteblk(int, int); int bufwait(struct buf *); int bufwrite(struct buf *); Modified: head/sys/ufs/ffs/ffs_alloc.c ============================================================================== --- head/sys/ufs/ffs/ffs_alloc.c Tue Dec 3 22:59:55 2019 (r355370) +++ head/sys/ufs/ffs/ffs_alloc.c Tue Dec 3 23:07:09 2019 (r355371) @@ -2955,16 +2955,19 @@ ffs_getcg(fs, devvp, cg, flags, bpp, cgpp) struct buf *bp; struct cg *cgp; const struct statfs *sfs; + daddr_t blkno; int error; *bpp = NULL; *cgpp = NULL; if ((fs->fs_metackhash & CK_CYLGRP) != 0) flags |= GB_CKHASH; - error = breadn_flags(devvp, devvp->v_type == VREG ? - fragstoblks(fs, cgtod(fs, cg)) : fsbtodb(fs, cgtod(fs, cg)), - (int)fs->fs_cgsize, NULL, NULL, 0, NOCRED, flags, - ffs_ckhash_cg, &bp); + if (devvp->v_type == VREG) + blkno = fragstoblks(fs, cgtod(fs, cg)); + else + blkno = fsbtodb(fs, cgtod(fs, cg)); + error = breadn_flags(devvp, blkno, blkno, (int)fs->fs_cgsize, NULL, + NULL, 0, NOCRED, flags, ffs_ckhash_cg, &bp); if (error != 0) return (error); cgp = (struct cg *)bp->b_data; Modified: head/sys/ufs/ffs/ffs_inode.c ============================================================================== --- head/sys/ufs/ffs/ffs_inode.c Tue Dec 3 22:59:55 2019 (r355370) +++ head/sys/ufs/ffs/ffs_inode.c Tue Dec 3 23:07:09 2019 (r355371) @@ -678,34 +678,14 @@ ffs_indirtrunc(ip, lbn, dbn, lastbn, level, countp) * Get buffer of block pointers, zero those entries corresponding * to blocks to be free'd, and update on disk copy first. Since * double(triple) indirect before single(double) indirect, calls - * to bmap on these blocks will fail. However, we already have - * the on disk address, so we have to set the b_blkno field - * explicitly instead of letting bread do everything for us. + * to VOP_BMAP() on these blocks will fail. However, we already + * have the on-disk address, so we just pass it to bread() instead + * of having bread() attempt to calculate it using VOP_BMAP(). */ vp = ITOV(ip); - bp = getblk(vp, lbn, (int)fs->fs_bsize, 0, 0, 0); - if ((bp->b_flags & B_CACHE) == 0) { -#ifdef RACCT - if (racct_enable) { - PROC_LOCK(curproc); - racct_add_buf(curproc, bp, 0); - PROC_UNLOCK(curproc); - } -#endif /* RACCT */ - curthread->td_ru.ru_inblock++; /* pay for read */ - bp->b_iocmd = BIO_READ; - bp->b_flags &= ~B_INVAL; - bp->b_ioflags &= ~BIO_ERROR; - if (bp->b_bcount > bp->b_bufsize) - panic("ffs_indirtrunc: bad buffer size"); - bp->b_blkno = dbn; - vfs_busy_pages(bp, 0); - bp->b_iooffset = dbtob(bp->b_blkno); - bstrategy(bp); - error = bufwait(bp); - } + error = breadn_flags(vp, lbn, dbn, (int)fs->fs_bsize, NULL, NULL, 0, + NOCRED, 0, NULL, &bp); if (error) { - brelse(bp); *countp = 0; return (error); } Modified: head/sys/ufs/ffs/ffs_softdep.c ============================================================================== --- head/sys/ufs/ffs/ffs_softdep.c Tue Dec 3 22:59:55 2019 (r355370) +++ head/sys/ufs/ffs/ffs_softdep.c Tue Dec 3 23:07:09 2019 (r355371) @@ -6294,29 +6294,15 @@ setup_trunc_indir(freeblks, ip, lbn, lastlbn, blkno) return (0); mp = freeblks->fb_list.wk_mp; ump = VFSTOUFS(mp); - bp = getblk(ITOV(ip), lbn, mp->mnt_stat.f_iosize, 0, 0, 0); - if ((bp->b_flags & B_CACHE) == 0) { - bp->b_blkno = blkptrtodb(VFSTOUFS(mp), blkno); - bp->b_iocmd = BIO_READ; - bp->b_flags &= ~B_INVAL; - bp->b_ioflags &= ~BIO_ERROR; - vfs_busy_pages(bp, 0); - bp->b_iooffset = dbtob(bp->b_blkno); - bstrategy(bp); -#ifdef RACCT - if (racct_enable) { - PROC_LOCK(curproc); - racct_add_buf(curproc, bp, 0); - PROC_UNLOCK(curproc); - } -#endif /* RACCT */ - curthread->td_ru.ru_inblock++; - error = bufwait(bp); - if (error) { - brelse(bp); - return (error); - } - } + /* + * Here, calls to VOP_BMAP() will fail. However, we already have + * the on-disk address, so we just pass it to bread() instead of + * having bread() attempt to calculate it using VOP_BMAP(). + */ + error = breadn_flags(ITOV(ip), lbn, blkptrtodb(ump, blkno), + (int)mp->mnt_stat.f_iosize, NULL, NULL, 0, NOCRED, 0, NULL, &bp); + if (error) + return (error); level = lbn_level(lbn); lbnadd = lbn_offset(ump->um_fs, level); /* Modified: head/sys/ufs/ffs/ffs_vnops.c ============================================================================== --- head/sys/ufs/ffs/ffs_vnops.c Tue Dec 3 22:59:55 2019 (r355370) +++ head/sys/ufs/ffs/ffs_vnops.c Tue Dec 3 23:07:09 2019 (r355371) @@ -603,7 +603,7 @@ ffs_read(ap) * the 6th argument. */ u_int nextsize = blksize(fs, ip, nextlbn); - error = breadn_flags(vp, lbn, size, &nextlbn, + error = breadn_flags(vp, lbn, lbn, size, &nextlbn, &nextsize, 1, NOCRED, bflag, NULL, &bp); } else { /*