svn commit: r342295 - head/sys/kern

Bruce Evans bde at FreeBSD.org
Fri Dec 21 04:58:00 UTC 2018


Author: bde
Date: Fri Dec 21 04:57:59 2018
New Revision: 342295
URL: https://svnweb.freebsd.org/changeset/base/342295

Log:
  Fix rounding in vop_stdadvise() for POSIX_FADV_NOREUSE (really
  POSIX_FADV_DONTNEED).  The most broken case was for applications that
  advise for the whole file and then do block-aligned i/o's 1 block at
  a time.  Then advice is sent to VOP_ADVISE() 1 block at a time, but
  in vop_stdadvise() the 1-block advice was turned into 0-block advice
  for the buffer cache part.
  
  The bugs were caused partly by callers representing the region as
  (a_start, a_end), where a_end is actually the maximum, and everything
  else representing the region as (start, end) where 'end' is actually
  the end (1 after the maximum).  The maximum a_end must be rounded up,
  but was rounded down.  Also, rounding to page boundaries was inconsistent.
  
  The bugs and fixes have no effect for zfs and other file systems that
  don't use the buffer cache or the page cache.  Most or all file systems
  currently use the default VOP_FADVISE(), but it finds a null buffer cache
  and a null page cache for file systems that don't use normal methods.
  
  Reviewed by:	kib

Modified:
  head/sys/kern/vfs_default.c

Modified: head/sys/kern/vfs_default.c
==============================================================================
--- head/sys/kern/vfs_default.c	Fri Dec 21 02:26:08 2018	(r342294)
+++ head/sys/kern/vfs_default.c	Fri Dec 21 04:57:59 2018	(r342295)
@@ -1063,7 +1063,7 @@ vop_stdadvise(struct vop_advise_args *ap)
 	struct vnode *vp;
 	struct bufobj *bo;
 	daddr_t startn, endn;
-	off_t start, end;
+	off_t bstart, bend, start, end;
 	int bsize, error;
 
 	vp = ap->a_vp;
@@ -1085,14 +1085,27 @@ vop_stdadvise(struct vop_advise_args *ap)
 		}
 
 		/*
+		 * Round to block boundaries (and later possibly further to
+		 * page boundaries).  Applications cannot reasonably be aware  
+		 * of the boundaries, and the rounding must be to expand at
+		 * both extremities to cover enough.  It still doesn't cover
+		 * read-ahead.  For partial blocks, this gives unnecessary
+		 * discarding of buffers but is efficient enough since the
+		 * pages usually remain in VMIO for some time.
+		 */
+		bsize = vp->v_bufobj.bo_bsize;
+		bstart = roundup(ap->a_start, bsize);
+		bend = roundup(ap->a_end, bsize);
+
+		/*
 		 * Deactivate pages in the specified range from the backing VM
 		 * object.  Pages that are resident in the buffer cache will
 		 * remain wired until their corresponding buffers are released
 		 * below.
 		 */
 		if (vp->v_object != NULL) {
-			start = trunc_page(ap->a_start);
-			end = round_page(ap->a_end);
+			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));
@@ -1101,9 +1114,8 @@ vop_stdadvise(struct vop_advise_args *ap)
 
 		bo = &vp->v_bufobj;
 		BO_RLOCK(bo);
-		bsize = vp->v_bufobj.bo_bsize;
-		startn = ap->a_start / bsize;
-		endn = ap->a_end / bsize;
+		startn = bstart / bsize;
+		endn = bend / bsize;
 		error = bnoreuselist(&bo->bo_clean, bo, startn, endn);
 		if (error == 0)
 			error = bnoreuselist(&bo->bo_dirty, bo, startn, endn);


More information about the svn-src-head mailing list