Repository navigation
Commit ee5e001
fs: Make splice() and tee() take into account O_NONBLOCK flag on pipes
The current implementation of splice() and tee() ignores O_NONBLOCK set
on pipe file descriptors and checks only the SPLICE_F_NONBLOCK flag for
blocking on pipe arguments. This is inconsistent since splice()-ing
from/to non-pipe file descriptors does take O_NONBLOCK into
consideration.
Fix this by promoting O_NONBLOCK, when set on a pipe, to
SPLICE_F_NONBLOCK.
Some context for how the current implementation of splice() leads to
inconsistent behavior. In the ongoing work[1] to add VM tracing
capability to trace-cmd we stream tracing data over named FIFOs or
vsockets from guests back to the host.
When we receive SIGINT from user to stop tracing, we set O_NONBLOCK on
the input file descriptor and set SPLICE_F_NONBLOCK for the next call to
splice(). If splice() was blocked waiting on data from the input FIFO,
after SIGINT splice() restarts with the same arguments (no
SPLICE_F_NONBLOCK) and blocks again instead of returning -EAGAIN when no
data is available.
This differs from the splice() behavior when reading from a vsocket or
when we're doing a traditional read()/write() loop (trace-cmd's
--nosplice argument).
With this patch applied we get the same behavior in all situations after
setting O_NONBLOCK which also matches the behavior of doing a
read()/write() loop instead of splice().
This change does have potential of breaking users who don't expect
EAGAIN from splice() when SPLICE_F_NONBLOCK is not set. OTOH programs
that set O_NONBLOCK and don't anticipate EAGAIN are arguably buggy[2].
[1] https://github.com/skaslev/trace-cmd/tree/vsock
[2] https://github.com/torvalds/linux/blob/d47e3da1759230e394096fd742aad423c291ba48/fs/read_write.c#L1425
Signed-off-by: Slavomir Kaslev <kaslevs@vmware.com>
Reviewed-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>1 parent 4f9020f commit ee5e001
1 file changed
Lines changed: 12 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1123 | 1123 | | |
1124 | 1124 | | |
1125 | 1125 | | |
| 1126 | + | |
| 1127 | + | |
| 1128 | + | |
1126 | 1129 | | |
1127 | 1130 | | |
1128 | 1131 | | |
| |||
1148 | 1151 | | |
1149 | 1152 | | |
1150 | 1153 | | |
| 1154 | + | |
| 1155 | + | |
| 1156 | + | |
1151 | 1157 | | |
1152 | 1158 | | |
1153 | 1159 | | |
| |||
1172 | 1178 | | |
1173 | 1179 | | |
1174 | 1180 | | |
| 1181 | + | |
| 1182 | + | |
| 1183 | + | |
1175 | 1184 | | |
1176 | 1185 | | |
1177 | 1186 | | |
| |||
1717 | 1726 | | |
1718 | 1727 | | |
1719 | 1728 | | |
| 1729 | + | |
| 1730 | + | |
| 1731 | + | |
1720 | 1732 | | |
1721 | 1733 | | |
1722 | 1734 | | |
| |||
0 commit comments