Page MenuHomeFreeBSD

sendfile: stop abusing kern_writev()
ClosedPublic

Authored by kib on Sat, Jul 4, 2:32 AM.
Tags
None
Referenced Files
F162249262: D58035.id181291.diff
Sat, Jul 11, 8:02 AM
F162212650: D58035.id181278.diff
Fri, Jul 10, 11:05 PM
Unknown Object (File)
Fri, Jul 10, 2:25 AM
Unknown Object (File)
Fri, Jul 10, 2:17 AM
Unknown Object (File)
Thu, Jul 9, 8:32 PM
Unknown Object (File)
Thu, Jul 9, 8:27 PM
Unknown Object (File)
Thu, Jul 9, 8:08 PM
Unknown Object (File)
Thu, Jul 9, 8:08 PM
Subscribers

Details

Summary
Provide convenient wrapper kern_filewrite() around fo_write().
Switch to use it in vn_sendfile().  This allows to avoid duplicate
fget() when we already have the reference to the file, which creates a
correctness race with the userspace.  Also td_retval[0] clearing hack
can be removed.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

kib requested review of this revision.Sat, Jul 4, 2:32 AM
sys/kern/kern_sendfile.c
1171

The second sentence is stale.

sys/kern/sys_generic.c
547

Rather than splitting this into two functions, can we just call it kern_write() and push the td_retval handling into sendfile/kern_writev()/kern_pwritev()?

In the existing scheme, the naming is a bit confusing, and it's not clear why kern_filewrite() is not responsible for raising SIGPIPE for non-sockets.

kib marked 2 inline comments as done.Sat, Jul 4, 4:23 PM
kib added inline comments.
sys/kern/sys_generic.c
547

Intent of kern_filewrite() is exactly what it's name says: it is a convenience wrapper around fo_write(), intended to be used for (rare) cases when kernel needs to write to file. I had an impression, from a talk with Gleb, that there is a need for such function for more wide use.

dofilewrite() is setting up the userspace context for the file write result. This includes both setting td_retval[0] and delivering SIGPIPE as needed.

IMO the split is reasonable. I am not quite sure why EPIPE requires handling at the socket layer instead of the syscall layer, but this is for the other day.

kib marked an inline comment as done.

Update the comment.

markj added inline comments.
sys/kern/sys_generic.c
547

I am not quite sure why EPIPE requires handling at the socket layer instead of the syscall layer

Maybe it simplifies things for AIO, I'm not sure.

It's still a weird split: the helper handles ktrace but not SIGPIPE (except sometimes).

586

Probably you'll get a warning about unused fd if KTRACE is not defined.

This revision is now accepted and ready to land.Sat, Jul 4, 5:06 PM
kib marked an inline comment as done.Sat, Jul 4, 5:54 PM

atomic_store_int(comm, -1);

sys/kern/sys_generic.c
586

I am not sure. it seems that our settings forgive the unused parameters.
As an example, the whole series of badfo_XXX() functions does not add __unused to obviously unused parameters.

In D58035#1330852, @kib wrote:

atomic_store_int(comm, -1);

What is this from?

kib marked an inline comment as done.Sun, Jul 5, 7:31 PM
In D58035#1330852, @kib wrote:

atomic_store_int(comm, -1);

What is this from?

Apparently this is from the test program for pddupfd(2), pasted in error.

This revision was automatically updated to reflect the committed changes.