Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 08 Feb 2013 16:58:09 -0700
From:      Ian Lepore <ian@FreeBSD.org>
To:        "freebsd-hackers@freebsd.org" <freebsd-hackers@FreeBSD.org>
Subject:   fcntl(2) F_READAHEAD set to zero doesn't work [patch]
Message-ID:  <1360367889.4545.58.camel@revolution.hippie.lan>

next in thread | raw e-mail | index | archive | help

--=-c2AO8q53G0nK+3Z7nGkh
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit

I discovered today that fcntl(fd, F_READAHEAD, 0) doesn't work as
advertised.  It's supposed to disable readahead, but instead it restores
the default readahead behavior (if it had previously been changed), and
there is no way to disable readahead.[1]  I think the attached patch
fixes it, but it's not immediately clear from the patch why; here's the
deal...

The amount of readahead is calculated by sequential_heuristic() in
vfs_vnops.c.  If the FRDAHEAD flag is set on the file it uses the value
stored in the file's f_seqcount, otherwise it calculates a value (and
updates f_seqcount, which doesn't ever happen when FRDAHEAD is set).

So the patch causes the FRDAHEAD flag to be set even in the case of the
readahead amount being zero.  Because it seems like a useful concept, it
still allows the readahead to be restored to default behavior, now by
passing a negative value.

Does this look right to those of you who understand this part of the
system better than I do?

-- Ian

[1] No way using F_READAHEAD; I know about POSIX_FADV_RANDOM.

--=-c2AO8q53G0nK+3Z7nGkh
Content-Disposition: inline; filename="fcntl_readahead.diff"
Content-Type: text/x-patch; name="fcntl_readahead.diff"; charset="us-ascii"
Content-Transfer-Encoding: 7bit

Index: sys/kern/kern_descrip.c
===================================================================
--- sys/kern/kern_descrip.c	(revision 246337)
+++ sys/kern/kern_descrip.c	(working copy)
@@ -776,7 +776,7 @@
 		}
 		fhold(fp);
 		FILEDESC_SUNLOCK(fdp);
-		if (arg != 0) {
+		if (arg >= 0) {
 			vp = fp->f_vnode;
 			error = vn_lock(vp, LK_SHARED);
 			if (error != 0) {
Index: lib/libc/sys/fcntl.2
===================================================================
--- lib/libc/sys/fcntl.2	(revision 246337)
+++ lib/libc/sys/fcntl.2	(working copy)
@@ -28,7 +28,7 @@
 .\"     @(#)fcntl.2	8.2 (Berkeley) 1/12/94
 .\" $FreeBSD$
 .\"
-.Dd July 27, 2012
+.Dd February 8, 2013
 .Dt FCNTL 2
 .Os
 .Sh NAME
@@ -171,7 +171,7 @@
 which is rounded up to the nearest block size.
 A zero value in
 .Fa arg
-turns off read ahead.
+turns off read ahead, a negative value restores the system default.
 .It Dv F_RDAHEAD
 Equivalent to Darwin counterpart which sets read ahead amount of 128KB
 when the third argument,

--=-c2AO8q53G0nK+3Z7nGkh--




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