mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Add inotify events for fallocate and tests for fallocate/sendfile.
Updates #1479, #2923. PiperOrigin-RevId: 324658826
This commit is contained in:
@@ -254,11 +254,12 @@ func Fallocate(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Sys
|
||||
return 0, nil, syserror.EFBIG
|
||||
}
|
||||
|
||||
return 0, nil, file.Allocate(t, mode, uint64(offset), uint64(length))
|
||||
if err := file.Allocate(t, mode, uint64(offset), uint64(length)); err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
|
||||
// File length modified, generate notification.
|
||||
// TODO(gvisor.dev/issue/1479): Reenable when Inotify is ported.
|
||||
// file.Dirent.InotifyEvent(linux.IN_MODIFY, 0)
|
||||
file.Dentry().InotifyWithParent(linux.IN_MODIFY, 0, vfs.PathEvent)
|
||||
return 0, nil, nil
|
||||
}
|
||||
|
||||
// Utime implements Linux syscall utime(2).
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <sys/epoll.h>
|
||||
#include <sys/inotify.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/sendfile.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/xattr.h>
|
||||
|
||||
@@ -1681,6 +1682,60 @@ TEST(Inotify, EpollNoDeadlock) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Inotify, Fallocate) {
|
||||
const TempPath file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
|
||||
const FileDescriptor fd =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR));
|
||||
|
||||
const FileDescriptor inotify_fd =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(InotifyInit1(IN_NONBLOCK));
|
||||
const int wd = ASSERT_NO_ERRNO_AND_VALUE(
|
||||
InotifyAddWatch(inotify_fd.get(), file.path(), IN_ALL_EVENTS));
|
||||
|
||||
// Do an arbitrary modification with fallocate.
|
||||
ASSERT_THAT(fallocate(fd.get(), 0, 0, 123), SyscallSucceeds());
|
||||
std::vector<Event> events =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(DrainEvents(inotify_fd.get()));
|
||||
EXPECT_THAT(events, Are({Event(IN_MODIFY, wd)}));
|
||||
}
|
||||
|
||||
TEST(Inotify, Sendfile) {
|
||||
SKIP_IF(IsRunningWithVFS1());
|
||||
|
||||
const TempPath root = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir());
|
||||
const TempPath in_file = ASSERT_NO_ERRNO_AND_VALUE(
|
||||
TempPath::CreateFileWith(root.path(), "x", 0644));
|
||||
const TempPath out_file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
|
||||
const FileDescriptor in =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(Open(in_file.path(), O_RDONLY));
|
||||
const FileDescriptor out =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(Open(out_file.path(), O_WRONLY));
|
||||
|
||||
// Create separate inotify instances for the in and out fds. If both watches
|
||||
// were on the same instance, we would have discrepancies between Linux and
|
||||
// gVisor (order of events, duplicate events), which is not that important
|
||||
// since inotify is asynchronous anyway.
|
||||
const FileDescriptor in_inotify =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(InotifyInit1(IN_NONBLOCK));
|
||||
const FileDescriptor out_inotify =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(InotifyInit1(IN_NONBLOCK));
|
||||
const int in_wd = ASSERT_NO_ERRNO_AND_VALUE(
|
||||
InotifyAddWatch(in_inotify.get(), in_file.path(), IN_ALL_EVENTS));
|
||||
const int out_wd = ASSERT_NO_ERRNO_AND_VALUE(
|
||||
InotifyAddWatch(out_inotify.get(), out_file.path(), IN_ALL_EVENTS));
|
||||
|
||||
ASSERT_THAT(sendfile(out.get(), in.get(), /*offset=*/nullptr, 1),
|
||||
SyscallSucceeds());
|
||||
|
||||
// Expect a single access event and a single modify event.
|
||||
std::vector<Event> in_events =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(DrainEvents(in_inotify.get()));
|
||||
std::vector<Event> out_events =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(DrainEvents(out_inotify.get()));
|
||||
EXPECT_THAT(in_events, Are({Event(IN_ACCESS, in_wd)}));
|
||||
EXPECT_THAT(out_events, Are({Event(IN_MODIFY, out_wd)}));
|
||||
}
|
||||
|
||||
// On Linux, inotify behavior is not very consistent with splice(2). We try our
|
||||
// best to emulate Linux for very basic calls to splice.
|
||||
TEST(Inotify, SpliceOnWatchTarget) {
|
||||
|
||||
Reference in New Issue
Block a user