The branch main has been updated by kib:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=5cc82c563eda97b70120f06e9635ab6c1c24fecd

commit 5cc82c563eda97b70120f06e9635ab6c1c24fecd
Author:     Konstantin Belousov <k...@freebsd.org>
AuthorDate: 2021-09-02 04:04:23 +0000
Commit:     Konstantin Belousov <k...@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.lochm...@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;
 }
 
 /*
_______________________________________________
dev-commits-src-main@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-main
To unsubscribe, send any mail to "dev-commits-src-main-unsubscr...@freebsd.org"

Reply via email to