mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
Add flag SF_USER_READAHEAD to sendfile(2). When specified, the syscall won't
do any speculations about readahead, and use exactly the amount of readahead specified by user. E.g. setting SF_FLAGS(0, SF_USER_READAHEAD) will guarantee that no readahead at all will be performed.
This commit is contained in:
parent
5dba303d01
commit
00b5ffde8e
3 changed files with 44 additions and 14 deletions
|
|
@ -25,7 +25,7 @@
|
|||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd January 7, 2016
|
||||
.Dd November 17, 2016
|
||||
.Dt SENDFILE 2
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
|
@ -155,8 +155,33 @@ sleeps until the network stack no longer references the VM pages
|
|||
of the file, making subsequent modifications to it safe.
|
||||
Please note that this is not a guarantee that the data has actually
|
||||
been sent.
|
||||
.It Dv SF_USER_READAHEAD
|
||||
.Nm
|
||||
has some internal heuristics to do readahead when sending data.
|
||||
This flag forces
|
||||
.Nm
|
||||
to override any heuristically calculated readahead and use exactly the
|
||||
application specified readahead.
|
||||
See
|
||||
.Sx SETTING READAHEAD
|
||||
for more details on readahead.
|
||||
.El
|
||||
.Pp
|
||||
When using a socket marked for non-blocking I/O,
|
||||
.Fn sendfile
|
||||
may send fewer bytes than requested.
|
||||
In this case, the number of bytes successfully
|
||||
written is returned in
|
||||
.Fa *sbytes
|
||||
(if specified),
|
||||
and the error
|
||||
.Er EAGAIN
|
||||
is returned.
|
||||
.Sh SETTING READAHEAD
|
||||
.Nm
|
||||
uses internal heuristics based on request size and file system layout
|
||||
to do readahead.
|
||||
Additionally application may request extra readahead.
|
||||
The most significant 16 bits of
|
||||
.Fa flags
|
||||
specify amount of pages that
|
||||
|
|
@ -173,16 +198,13 @@ flag:
|
|||
SF_FLAGS(16, SF_NOCACHE)
|
||||
.Ed
|
||||
.Pp
|
||||
When using a socket marked for non-blocking I/O,
|
||||
.Fn sendfile
|
||||
may send fewer bytes than requested.
|
||||
In this case, the number of bytes successfully
|
||||
written is returned in
|
||||
.Fa *sbytes
|
||||
(if specified),
|
||||
and the error
|
||||
.Er EAGAIN
|
||||
is returned.
|
||||
.Nm
|
||||
will use either application specified readahead or internally calculated,
|
||||
whichever is bigger.
|
||||
Setting flag
|
||||
.Dv SF_USER_READAHEAD
|
||||
would turn off any heuristics and set maximum possible readahead length to
|
||||
the number of pages specified via flags.
|
||||
.Sh IMPLEMENTATION NOTES
|
||||
The
|
||||
.Fx
|
||||
|
|
|
|||
|
|
@ -706,13 +706,20 @@ retry_space:
|
|||
|
||||
/*
|
||||
* Calculate maximum allowed number of pages for readahead
|
||||
* at this iteration. First, we allow readahead up to "rem".
|
||||
* at this iteration. If SF_USER_READAHEAD was set, we don't
|
||||
* do any heuristics and use exactly the value supplied by
|
||||
* application. Otherwise, we allow readahead up to "rem".
|
||||
* If application wants more, let it be, but there is no
|
||||
* reason to go above MAXPHYS. Also check against "obj_size",
|
||||
* since vm_pager_has_page() can hint beyond EOF.
|
||||
*/
|
||||
rhpages = howmany(rem + (off & PAGE_MASK), PAGE_SIZE) - npages;
|
||||
rhpages += SF_READAHEAD(flags);
|
||||
if (flags & SF_USER_READAHEAD) {
|
||||
rhpages = SF_READAHEAD(flags);
|
||||
} else {
|
||||
rhpages = howmany(rem + (off & PAGE_MASK), PAGE_SIZE) -
|
||||
npages;
|
||||
rhpages += SF_READAHEAD(flags);
|
||||
}
|
||||
rhpages = min(howmany(MAXPHYS, PAGE_SIZE), rhpages);
|
||||
rhpages = min(howmany(obj_size - trunc_page(off), PAGE_SIZE) -
|
||||
npages, rhpages);
|
||||
|
|
|
|||
|
|
@ -590,6 +590,7 @@ struct sf_hdtr {
|
|||
#define SF_NODISKIO 0x00000001
|
||||
#define SF_MNOWAIT 0x00000002 /* obsolete */
|
||||
#define SF_SYNC 0x00000004
|
||||
#define SF_USER_READAHEAD 0x00000008
|
||||
#define SF_NOCACHE 0x00000010
|
||||
#define SF_FLAGS(rh, flags) (((rh) << 16) | (flags))
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue