From nobody Sat May 23 07:13:49 2026 X-Original-To: dev-commits-src-branches@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4gMtfk3502z6fgFt for ; Sat, 23 May 2026 07:13:50 +0000 (UTC) (envelope-from git@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) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R13" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4gMtfj49gCz3tFZ for ; Sat, 23 May 2026 07:13:49 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1779520429; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=pM+i7nulgghae4PK0oFlRX0RWLr31+3VpjPXLwsIUEc=; b=kh9HQajbx8vf03qN57mnTn6Hjp3Pjvd+IUsk6+KaWdx8brVOEbgq2USST5ouJUN7CyqrTR /pGcV8War/+PB/7yRcQX8VrEPFQvAYhtfLGoYVOpuFksMhBRxszVpk71/WNX0xYCtuDf+v EPz6Q8HKcWNIZFpxJNgjFJORzYSi5COwic+PojY8x7o8PKSm7TTzdqUUYK6nzgKjF0PJdl zDstCSxmKoaiZsb/vcbd6pgqw1OMzyJG35TTgXFnvdm4FHArh+ps1ddsr/RXmpIiba2IQ8 gZkuQcfI36gjahPX48CU9JMJKcMojOhE6xvkfHHyz+P/1hixKdZhYAvq3NCJ/g== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1779520429; a=rsa-sha256; cv=none; b=rSW3cqaL2nViIhYudXCU/63/dxg2Io0K3RdNAneODwGrzxLc7bWph8GrdFC0NIovIhUnZQ eDXWS7KztPobGBkp4aMimpSAFgrkDGXNNuwxsb6YSJmCoPp1BfOWd+iEaT/bUp/bR47QZU To/UEklYCWb7iPjXYt/Cs1vQ8Q5wiZySwWKy5tuudzViJ6vTA/9IbTsSminbFAT6Ikl8aE PckHo5M1Agj5nW2sRPb/UzgkYplymcPOZqstqMDOb3xtXMhFBD6EyVAP4xwJ/RZMSxpRrG ypWxbFbLSoYk7GBn8AtKNOn8DeX1UQIG/XnLf9vG18uCJqqiOhce3sL9LjruEw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1779520429; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=pM+i7nulgghae4PK0oFlRX0RWLr31+3VpjPXLwsIUEc=; b=eGyCC1ZP7jAeLZilm6diQRdjms+q2mnlVRKssCCMqGxwbXBK4RsYxjsfXb9hX5tw377Vb+ qIdcS4VKLtJ063oFNW0SKpX/mqf1hsWcOeipP8l/Qlyc7RStTOtU0Bdht9db0vSnRI6Ue4 n/ohrmPwtvO7U4aoqhYtRYeQvmqjvV9qltg+N05xnWRjdKcmt42wAb+TTKCew9odmoI55a ndGgLxDo+TiBrx4KP1jvosXRaYgAbVEpZLjqGKaUxUhwOckWVSHs2Aw/kq4wKZKXWXtw/s Ujoia9fVM33Kl9PXiIwDtZ746Hi2OOUN6Cg2PNXF9fo1MEoeHdjLQvqMlc9URA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4gMtfj3cQJzwbT for ; Sat, 23 May 2026 07:13:49 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 3b87f by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sat, 23 May 2026 07:13:49 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Cc: Chuck Silvers From: Konstantin Belousov Subject: git: 6646f952da49 - stable/15 - ufs: support unmapped bufs for indirect blocks in bmap List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-branches@freebsd.org Sender: owner-dev-commits-src-branches@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kib X-Git-Repository: src X-Git-Refname: refs/heads/stable/15 X-Git-Reftype: branch X-Git-Commit: 6646f952da498fcaa4297d12710ff29acaea2141 Auto-Submitted: auto-generated Date: Sat, 23 May 2026 07:13:49 +0000 Message-Id: <6a1153ad.3b87f.41fbdaab@gitrepo.freebsd.org> The branch stable/15 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=6646f952da498fcaa4297d12710ff29acaea2141 commit 6646f952da498fcaa4297d12710ff29acaea2141 Author: Chuck Silvers AuthorDate: 2026-05-07 12:43:53 +0000 Commit: Konstantin Belousov CommitDate: 2026-05-23 06:56:13 +0000 ufs: support unmapped bufs for indirect blocks in bmap (cherry picked from commit bab04ddf1fd4b7a77d1cfae4a67ededf1f35ee0d) --- sys/ufs/ufs/ufs_bmap.c | 143 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 134 insertions(+), 9 deletions(-) diff --git a/sys/ufs/ufs/ufs_bmap.c b/sys/ufs/ufs/ufs_bmap.c index 9d21eaa0cb56..030cf3055477 100644 --- a/sys/ufs/ufs/ufs_bmap.c +++ b/sys/ufs/ufs/ufs_bmap.c @@ -34,7 +34,6 @@ * SUCH DAMAGE. */ -#include #include #include #include @@ -44,10 +43,13 @@ #include #include #include +#include +#include #include #include #include +#include #include #include @@ -59,6 +61,11 @@ static ufs_lbn_t lbn_count(struct ufsmount *, int); static int readindir(struct vnode *, ufs_lbn_t, ufs2_daddr_t, struct buf **); +static int ufs_bmap_use_unmapped = 1; + +SYSCTL_INT(_vfs_ufs, OID_AUTO, bmap_use_unmapped, CTLFLAG_RWTUN, + &ufs_bmap_use_unmapped, 0, "UFS bmap uses unmapped bufs"); + /* * Bmap converts the logical block number of a file to its physical block * number on the disk. The conversion is done by using the logical block @@ -102,12 +109,15 @@ readindir(struct vnode *vp, struct buf *bp; struct mount *mp; struct ufsmount *ump; - int error; + struct inode *ip; + int error, gbflags; mp = vp->v_mount; ump = VFSTOUFS(mp); + ip = VTOI(vp); - bp = getblk(vp, lbn, mp->mnt_stat.f_iosize, 0, 0, 0); + gbflags = !I_IS_UFS1(ip) && ufs_bmap_use_unmapped ? GB_UNMAPPED : 0; + bp = getblk(vp, lbn, mp->mnt_stat.f_iosize, 0, 0, gbflags); if ((bp->b_flags & B_CACHE) == 0) { KASSERT(daddr != 0, ("readindir: indirect block not in cache")); @@ -151,6 +161,24 @@ readindir(struct vnode *vp, * next block and the disk address of the block (if it is assigned). */ +static void * +ufs_bm_sf_get(struct buf *bp, int32_t pgidx, struct sf_buf **sfp) +{ + struct sf_buf *sf; + + sched_pin(); + sf = sf_buf_alloc(bp->b_pages[pgidx], SFB_CPUPRIVATE); + *sfp = sf; + return ((void *)sf_buf_kva(sf)); +} + +static void +ufs_bm_sf_put(struct sf_buf *sf) +{ + sf_buf_free(sf); + sched_unpin(); +} + int ufs_bmaparray(struct vnode *vp, ufs2_daddr_t bn, @@ -164,10 +192,16 @@ ufs_bmaparray(struct vnode *vp, struct ufsmount *ump; struct mount *mp; struct indir a[UFS_NIADDR+1], *ap; + struct sf_buf *sf; ufs2_daddr_t daddr; ufs_lbn_t metalbn; int error, num, maxrun = 0; int *nump; + ufs1_daddr_t *daddr1p; + ufs2_daddr_t pgbn, daddrppg, prevdaddr, *daddr2p; + int32_t daddrsz, boff, pgidx, pgoff; + void *pgaddr; + bool isseq; ap = NULL; ip = VTOI(vp); @@ -261,17 +295,71 @@ ufs_bmaparray(struct vnode *vp, if (error != 0) return (error); - if (I_IS_UFS1(ip)) - daddr = ((ufs1_daddr_t *)bp->b_data)[ap->in_off]; - else - daddr = ((ufs2_daddr_t *)bp->b_data)[ap->in_off]; + daddrsz = I_IS_UFS1(ip) ? sizeof(ufs1_daddr_t) : sizeof(ufs2_daddr_t); + if (!buf_mapped(bp)) { + boff = ap->in_off * daddrsz; + pgidx = boff / PAGE_SIZE; + pgoff = (boff & PAGE_MASK) / daddrsz; + pgaddr = ufs_bm_sf_get(bp, pgidx, &sf); + if (I_IS_UFS1(ip)) + daddr = ((ufs1_daddr_t *)pgaddr)[pgoff]; + else + daddr = ((ufs2_daddr_t *)pgaddr)[pgoff]; + ufs_bm_sf_put(sf); + } else { + if (I_IS_UFS1(ip)) + daddr = ((ufs1_daddr_t *)bp->b_data)[ap->in_off]; + else + daddr = ((ufs2_daddr_t *)bp->b_data)[ap->in_off]; + } + if ((error = UFS_CHECK_BLKNO(mp, ip->i_number, daddr, mp->mnt_stat.f_iosize)) != 0) { bqrelse(bp); return (error); } + if (num > 1 || daddr == 0 || runp == NULL) + continue; + + daddrppg = PAGE_SIZE / daddrsz; if (I_IS_UFS1(ip)) { - if (num == 1 && daddr && runp) { + if (!buf_mapped(bp)) { + prevdaddr = daddr; + isseq = true; + for (bn = ap->in_off + 1; + bn < MNINDIR(ump) && *runp < maxrun && isseq; ) { + boff = bn * daddrsz; + pgidx = boff / PAGE_SIZE; + pgoff = (boff & PAGE_MASK) / daddrsz; + KASSERT(pgidx >= 0 && pgidx < bp->b_npages, + ("pgidx %d vs b_npages %d", pgidx, bp->b_npages)); + pgaddr = ufs_bm_sf_get(bp, pgidx, &sf); + daddr1p = (ufs1_daddr_t *)pgaddr; + for (pgbn = pgoff; + pgbn < daddrppg && *runp < maxrun && + (isseq = is_sequential(ump, prevdaddr, daddr1p[pgbn])); + prevdaddr = daddr1p[pgbn], ++pgbn, ++bn, ++*runp); + ufs_bm_sf_put(sf); + } + prevdaddr = daddr; + bn = ap->in_off; + if (runb && bn) { + isseq = true; + for (--bn; bn >= 0 && *runb < maxrun && isseq; ) { + boff = bn * daddrsz; + pgidx = boff / PAGE_SIZE; + pgoff = (boff & PAGE_MASK) / daddrsz; + KASSERT(pgidx >= 0 && pgidx < bp->b_npages, + ("pgidx %d vs b_npages %d", pgidx, bp->b_npages)); + pgaddr = ufs_bm_sf_get(bp, pgidx, &sf); + daddr1p = (ufs1_daddr_t *)pgaddr; + for (pgbn = pgoff; pgbn >= 0 && *runb < maxrun && + (isseq = is_sequential(ump, daddr1p[pgbn], prevdaddr)); + prevdaddr = daddr1p[pgbn], --pgbn, --bn, ++*runb); + ufs_bm_sf_put(sf); + } + } + } else { for (bn = ap->in_off + 1; bn < MNINDIR(ump) && *runp < maxrun && is_sequential(ump, @@ -289,7 +377,44 @@ ufs_bmaparray(struct vnode *vp, } continue; } - if (num == 1 && daddr && runp) { + + if (!buf_mapped(bp)) { + prevdaddr = daddr; + isseq = true; + for (bn = ap->in_off + 1; + bn < MNINDIR(ump) && *runp < maxrun && isseq; ) { + boff = bn * daddrsz; + pgidx = boff / PAGE_SIZE; + pgoff = (boff & PAGE_MASK) / daddrsz; + KASSERT(pgidx >= 0 && pgidx < bp->b_npages, + ("pgidx %d vs b_npages %d", pgidx, bp->b_npages)); + pgaddr = ufs_bm_sf_get(bp, pgidx, &sf); + daddr2p = (ufs2_daddr_t *)pgaddr; + for (pgbn = pgoff; + pgbn < daddrppg && *runp < maxrun && + (isseq = is_sequential(ump, prevdaddr, daddr2p[pgbn])); + prevdaddr = daddr2p[pgbn], ++pgbn, ++bn, ++*runp); + ufs_bm_sf_put(sf); + } + prevdaddr = daddr; + bn = ap->in_off; + if (runb && bn) { + isseq = true; + for (--bn; bn >= 0 && *runb < maxrun && isseq; ) { + boff = bn * daddrsz; + pgidx = boff / PAGE_SIZE; + pgoff = (boff & PAGE_MASK) / daddrsz; + KASSERT(pgidx >= 0 && pgidx < bp->b_npages, + ("pgidx %d vs b_npages %d", pgidx, bp->b_npages)); + pgaddr = ufs_bm_sf_get(bp, pgidx, &sf); + daddr2p = (ufs2_daddr_t *)pgaddr; + for (pgbn = pgoff; pgbn >= 0 && *runb < maxrun && + (isseq = is_sequential(ump, daddr2p[pgbn], prevdaddr)); + prevdaddr = daddr2p[pgbn], --pgbn, --bn, ++*runb); + ufs_bm_sf_put(sf); + } + } + } else { for (bn = ap->in_off + 1; bn < MNINDIR(ump) && *runp < maxrun && is_sequential(ump,