Date: Thu, 2 Sep 2021 18:36:54 GMT From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 5cc82c563eda - main - cluster_write(): do not access buffer after it is released Message-ID: <202109021836.182IasYo083381@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=5cc82c563eda97b70120f06e9635ab6c1c24fecd commit 5cc82c563eda97b70120f06e9635ab6c1c24fecd Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2021-09-02 04:04:23 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2021-09-02 18:36:33 +0000 cluster_write(): do not access buffer after it is released The issue was reported by Alexander Lochmann <alexander.lochmann@tu-dortmund.de>, who found the problem by performing lock analysis using LockDoc, see https://doi.org/10.1145/3302424.3303948. Reviewed by: mckusick Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D31780 --- sys/kern/vfs_cluster.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/sys/kern/vfs_cluster.c b/sys/kern/vfs_cluster.c index 7ca67c390b91..d3b303f28f6b 100644 --- a/sys/kern/vfs_cluster.c +++ b/sys/kern/vfs_cluster.c @@ -646,7 +646,7 @@ void cluster_write(struct vnode *vp, struct vn_clusterw *vnc, struct buf *bp, u_quad_t filesize, int seqcount, int gbflags) { - daddr_t lbn; + daddr_t lbn, pbn; int maxclen, cursize; int lblocksize; int async; @@ -753,14 +753,16 @@ cluster_write(struct vnode *vp, struct vn_clusterw *vnc, struct buf *bp, bp->b_blkno == bp->b_lblkno && (VOP_BMAP(vp, lbn, NULL, &bp->b_blkno, &maxclen, NULL) != 0 || bp->b_blkno == -1)) { + pbn = bp->b_blkno; bawrite(bp); vnc->v_clen = 0; - vnc->v_lasta = bp->b_blkno; + vnc->v_lasta = pbn; vnc->v_cstart = lbn + 1; vnc->v_lastw = lbn; return; } vnc->v_clen = maxclen; + pbn = bp->b_blkno; if (!async && maxclen == 0) { /* I/O not contiguous */ vnc->v_cstart = lbn + 1; bawrite(bp); @@ -774,6 +776,7 @@ cluster_write(struct vnode *vp, struct vn_clusterw *vnc, struct buf *bp, * are operating sequentially, otherwise let the buf or * update daemon handle it. */ + pbn = bp->b_blkno; bdwrite(bp); if (seqcount > 1) { cluster_wbuild_wb(vp, lblocksize, vnc->v_cstart, @@ -785,15 +788,17 @@ cluster_write(struct vnode *vp, struct vn_clusterw *vnc, struct buf *bp, /* * We are low on memory, get it going NOW */ + pbn = bp->b_blkno; bawrite(bp); } else { /* * In the middle of a cluster, so just delay the I/O for now. */ + pbn = bp->b_blkno; bdwrite(bp); } vnc->v_lastw = lbn; - vnc->v_lasta = bp->b_blkno; + vnc->v_lasta = pbn; } /*
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202109021836.182IasYo083381>