mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
fs/splice: don't report a partialResult error if there is no data loss
PiperOrigin-RevId: 288642552
This commit is contained in:
@@ -555,6 +555,10 @@ type lockedWriter struct {
|
||||
//
|
||||
// This applies only to Write, not WriteAt.
|
||||
Offset int64
|
||||
|
||||
// Err contains the first error encountered while copying. This is
|
||||
// useful to determine whether Writer or Reader failed during io.Copy.
|
||||
Err error
|
||||
}
|
||||
|
||||
// Write implements io.Writer.Write.
|
||||
@@ -590,5 +594,8 @@ func (w *lockedWriter) WriteAt(buf []byte, offset int64) (int, error) {
|
||||
break
|
||||
}
|
||||
}
|
||||
if w.Err == nil {
|
||||
w.Err = err
|
||||
}
|
||||
return written, err
|
||||
}
|
||||
|
||||
@@ -167,6 +167,11 @@ func Splice(ctx context.Context, dst *File, src *File, opts SpliceOpts) (int64,
|
||||
if !srcPipe && !opts.SrcOffset {
|
||||
atomic.StoreInt64(&src.offset, src.offset+n)
|
||||
}
|
||||
|
||||
// Don't report any errors if we have some progress without data loss.
|
||||
if w.Err == nil {
|
||||
err = nil
|
||||
}
|
||||
}
|
||||
|
||||
// Drop locks.
|
||||
|
||||
@@ -1591,6 +1591,34 @@ TEST(Inotify, EpollNoDeadlock) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Inotify, SpliceEvent) {
|
||||
int pipes[2];
|
||||
ASSERT_THAT(pipe2(pipes, O_NONBLOCK), SyscallSucceeds());
|
||||
|
||||
const TempPath root = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir());
|
||||
const FileDescriptor fd =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(InotifyInit1(IN_NONBLOCK));
|
||||
const TempPath file1 = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFileWith(
|
||||
root.path(), "some content", TempPath::kDefaultFileMode));
|
||||
|
||||
const FileDescriptor file1_fd =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(Open(file1.path(), O_RDONLY));
|
||||
const int watcher = ASSERT_NO_ERRNO_AND_VALUE(
|
||||
InotifyAddWatch(fd.get(), file1.path(), IN_ALL_EVENTS));
|
||||
|
||||
char buf;
|
||||
EXPECT_THAT(read(file1_fd.get(), &buf, 1), SyscallSucceeds());
|
||||
|
||||
EXPECT_THAT(splice(fd.get(), nullptr, pipes[1], nullptr,
|
||||
sizeof(struct inotify_event) + 1, SPLICE_F_NONBLOCK),
|
||||
SyscallSucceedsWithValue(sizeof(struct inotify_event)));
|
||||
|
||||
const FileDescriptor read_fd(pipes[0]);
|
||||
const std::vector<Event> events =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(DrainEvents(read_fd.get()));
|
||||
ASSERT_THAT(events, Are({Event(IN_ACCESS, watcher)}));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace testing
|
||||
} // namespace gvisor
|
||||
|
||||
Reference in New Issue
Block a user