From nobody Wed May 13 19:47:58 2026 X-Original-To: dev-commits-src-all@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 4gG3sb6WdTz6cw3X for ; Wed, 13 May 2026 19:48:03 +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 4gG3sb5m7Cz3WGW for ; Wed, 13 May 2026 19:48:03 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1778701683; 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=8JfDlnkcp7YbH/ldCs3a0JzrUW1CPtOQkTAYgWJpPU0=; b=aOS02XVRwWKLgVRh65epNGF80+LOAUphtcW7AXPQi6En2g8tFCBeDueCPgCDV3Oo86CoM0 P0sDU1JEk1mOVMl3We2DxY8xhycjum8nxOcaZOgeRTkU43XGmdhpPBIQlsvmdPMGOMUZWK tfHVq7kkTIhzbpk2gLux3cIcRb30vbcmd+Tcipdwt/RmqBtIghtaKk6/So9aa47eDxlyic 6ZXyfFSvtvPoeHboQSC/SaEOq7N0sKVnE4FhSuHDVxLJ1CM9D+1F6KMT38HtubIdhJ6P4f yS1DBJQWKAc08CUZCZarFEAFvzocZyBMvv67o0YVORXer4oBB7AnPqUA+kz9xg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1778701683; a=rsa-sha256; cv=none; b=rYkMpkmUxE4EBmntBvcg7QbNW1n0Ey4x6E2H9REYdeAX4w2SgbG0l1X8VajX8pzypRGFhG 5KG7zNoEpEaeOO008q7bAdCJvTZb90nvlLNy+6TJMtICEn88WQ1IbYeqT4MvdBF6tqfpXo nxONuEVBiFBJ2OG+0n50w7kfmxXumjXbTuyYPm1Ilt6GDSLXCzaCigXi4ijcHC2wf80gbK dhpRSrRMqFE+iJRI6vTN7oCPZpn4iPc1Q9zX2x5CprYO4SF2CwfPdFOgq+0lApBlF1vd1A NgYtciGC5pyhp56IK5DdHOFufT2xKCOg9ya8vYMIbdo8FDbPixCzhV+uJ2/XDg== 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=1778701683; 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=8JfDlnkcp7YbH/ldCs3a0JzrUW1CPtOQkTAYgWJpPU0=; b=nI8pqbJBWReCBxp7vDdJxmU3R4p6oB9UprOaK6yLvJgWOucA4YQIe43hXWobmuACs52OUR 9stmhoFmx8v1z0BMIgpYI74udkdWFQD2K+71JRKRso8/WyytJ99eI7e+4GSwh/58MwYkai VJObDQ1m5sEEYNmMr5euZPIM/E4Taj7bXUAkdF1y4pFaZpJf2KLbDrSXkqf5BkeiMJyvPB k4oY5cDdwvqFFh02IgzeXu3Ga+wCZ94SbSwCSrCTz6AYLPNca+a6BRs0OxBneObP5oI1wA RxjnFRFjYGfWcdN0GypJWE7pLop2Z9gkCOSNzIcU8A6Ill7nLstqeKyze7VlUw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4gG3sb557Dz14P0 for ; Wed, 13 May 2026 19:48:03 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 314e9 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Wed, 13 May 2026 19:47:58 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Cc: Chuck Silvers From: Konstantin Belousov Subject: git: bab04ddf1fd4 - main - ufs: support unmapped bufs for indirect blocks in bmap List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@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/main X-Git-Reftype: branch X-Git-Commit: bab04ddf1fd4b7a77d1cfae4a67ededf1f35ee0d Auto-Submitted: auto-generated Date: Wed, 13 May 2026 19:47:58 +0000 Message-Id: <6a04d56e.314e9.6d1b1b68@gitrepo.freebsd.org> The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=bab04ddf1fd4b7a77d1cfae4a67ededf1f35ee0d commit bab04ddf1fd4b7a77d1cfae4a67ededf1f35ee0d Author: Chuck Silvers AuthorDate: 2026-05-07 12:43:53 +0000 Commit: Konstantin Belousov CommitDate: 2026-05-13 19:46:00 +0000 ufs: support unmapped bufs for indirect blocks in bmap Use unmapped bufs for indirect block buffers in bmap, and use sf_bufs for transient mapping them when we need to read the specific pointer. [kib note: I changed the original patch to use sf_buf instead of explicit DMAP utilization, making the change MI]. Tested by: pho Reviewed by: kib MFC after: 1 week Differential revision: https://reviews.freebsd.org/D53424 --- 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..edfcabb1a607 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 (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,