git: 79eba754bec3 - main - vop_stdadvise(): restore correct handling of length == 0

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Thu, 05 Sep 2024 00:40:42 UTC
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=79eba754bec39d88a6494318a2176d19743cf993

commit 79eba754bec39d88a6494318a2176d19743cf993
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2024-09-03 04:20:40 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2024-09-05 00:40:14 +0000

    vop_stdadvise(): restore correct handling of length == 0
    
    Switch to unsigned arithmetic to handle overflow not relying on -fwrap,
    and specially treat the case of length == 0 from posix_fadvise() which
    passes OFF_MAX as the end to VOP.  There, roundup() overflows and -fwrap
    causes bend and endn become negative.  Using uintmax_t gives the place
    for roundup() to not wrap.
    
    Also remove locals with single use, and move calculations out from under
    bo lock.
    
    Reported by:    tmunro
    Reviewed by:    markj, tmunro
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D46518
---
 sys/kern/vfs_default.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c
index d612642a6bc9..f5722851d729 100644
--- a/sys/kern/vfs_default.c
+++ b/sys/kern/vfs_default.c
@@ -1063,8 +1063,8 @@ vop_stdadvise(struct vop_advise_args *ap)
 {
 	struct vnode *vp;
 	struct bufobj *bo;
+	uintmax_t bstart, bend;
 	daddr_t startn, endn;
-	off_t bstart, bend, start, end;
 	int bsize, error;
 
 	vp = ap->a_vp;
@@ -1096,7 +1096,8 @@ vop_stdadvise(struct vop_advise_args *ap)
 		 */
 		bsize = vp->v_bufobj.bo_bsize;
 		bstart = rounddown(ap->a_start, bsize);
-		bend = roundup(ap->a_end, bsize);
+		bend = ap->a_end;
+		bend = roundup(bend, bsize);
 
 		/*
 		 * Deactivate pages in the specified range from the backing VM
@@ -1105,18 +1106,17 @@ vop_stdadvise(struct vop_advise_args *ap)
 		 * below.
 		 */
 		if (vp->v_object != NULL) {
-			start = trunc_page(bstart);
-			end = round_page(bend);
 			VM_OBJECT_RLOCK(vp->v_object);
-			vm_object_page_noreuse(vp->v_object, OFF_TO_IDX(start),
-			    OFF_TO_IDX(end));
+			vm_object_page_noreuse(vp->v_object,
+			    OFF_TO_IDX(trunc_page(bstart)),
+			    OFF_TO_IDX(round_page(bend)));
 			VM_OBJECT_RUNLOCK(vp->v_object);
 		}
 
 		bo = &vp->v_bufobj;
-		BO_RLOCK(bo);
 		startn = bstart / bsize;
 		endn = bend / bsize;
+		BO_RLOCK(bo);
 		error = bnoreuselist(&bo->bo_clean, bo, startn, endn);
 		if (error == 0)
 			error = bnoreuselist(&bo->bo_dirty, bo, startn, endn);