Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 13 Oct 2011 14:34:57 GMT
From:      John Baldwin <jhb@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 200151 for review
Message-ID:  <201110131434.p9DEYvop078187@skunkworks.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@200151?ac=10

Change 200151 by jhb@jhb_jhbbsd on 2011/10/13 14:34:24

	First cut at implement fadvise() for read.  This works by adjusting
	the behavior in IO flag.  I should do at least some of this in
	the write case as well.

Affected files ...

.. //depot/projects/fadvise/sys/kern/vfs_vnops.c#2 edit

Differences ...

==== //depot/projects/fadvise/sys/kern/vfs_vnops.c#2 (text+ko) ====

@@ -518,7 +518,7 @@
 	struct vnode *vp;
 	int error, ioflag;
 	struct mtx *mtxp;
-	int vfslocked;
+	int advice, vfslocked;
 
 	KASSERT(uio->uio_td == td, ("uio_td %p is not td %p",
 	    uio->uio_td, td));
@@ -529,27 +529,48 @@
 		ioflag |= IO_NDELAY;
 	if (fp->f_flag & O_DIRECT)
 		ioflag |= IO_DIRECT;
+	advice = FADV_NORMAL;
 	vfslocked = VFS_LOCK_GIANT(vp->v_mount);
 	/*
 	 * According to McKusick the vn lock was protecting f_offset here.
 	 * It is now protected by the FOFFSET_LOCKED flag.
 	 */
-	if ((flags & FOF_OFFSET) == 0) {
+	if ((flags & FOF_OFFSET) == 0 || fp->f_advice != FADV_NORMAL) {
 		mtxp = mtx_pool_find(mtxpool_sleep, fp);
 		mtx_lock(mtxp);
-		while(fp->f_vnread_flags & FOFFSET_LOCKED) {
-			fp->f_vnread_flags |= FOFFSET_LOCK_WAITING;
-			msleep(&fp->f_vnread_flags, mtxp, PUSER -1,
-			    "vnread offlock", 0);
+		if ((flags & FOF_OFFSET) == 0) {
+			while (fp->f_vnread_flags & FOFFSET_LOCKED) {
+				fp->f_vnread_flags |= FOFFSET_LOCK_WAITING;
+				msleep(&fp->f_vnread_flags, mtxp, PUSER -1,
+				    "vnread offlock", 0);
+			}
+			fp->f_vnread_flags |= FOFFSET_LOCKED;
+			uio->uio_offset = fp->f_offset;
 		}
-		fp->f_vnread_flags |= FOFFSET_LOCKED;
+		if (fp->f_advice != FADV_NORMAL &&
+		    uio->uio_offset >= fp->f_advstart &&
+		    uio->uio_offset + uio->uio_resid <= fp->f_advend)
+			advice = fp->f_advice;
 		mtx_unlock(mtxp);
-		vn_lock(vp, LK_SHARED | LK_RETRY);
-		uio->uio_offset = fp->f_offset;
-	} else
-		vn_lock(vp, LK_SHARED | LK_RETRY);
+	}
+	vn_lock(vp, LK_SHARED | LK_RETRY);
 
-	ioflag |= sequential_heuristic(uio, fp);
+	switch (advice) {
+	case FADV_NORMAL:
+	case FADV_SEQUENTIAL:
+		ioflag |= sequential_heuristic(uio, fp);
+		break;
+	case FADV_RANDOM:
+		/* Do no read-ahead for random I/O. */
+		break;
+	case FADV_NOREUSE:
+		/*
+		 * Request the underlying FS to discard the pages
+		 * after the I/O is complete.
+		 */
+		ioflag |= IO_DIRECT;
+		break;
+	}
 
 #ifdef MAC
 	error = mac_vnode_check_read(active_cred, fp->f_cred, vp);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201110131434.p9DEYvop078187>