mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
inotify notifies watchers when control events bit are set
The code that matches the event being published with events watchers was wronly matching all watchers in case any of the control event bits were set. Issue #121 PiperOrigin-RevId: 226521230 Change-Id: Ie2c42bc4366faaf59fbf80a74e9297499bd93f9e
This commit is contained in:
committed by
Shentubot
parent
5c7f70a07d
commit
1679ef31ef
@@ -76,15 +76,17 @@ func isRenameEvent(eventMask uint32) bool {
|
||||
|
||||
// Notify queues a new event on this watch.
|
||||
func (w *Watch) Notify(name string, events uint32, cookie uint32) {
|
||||
unmaskableBits := ^uint32(0) &^ linux.IN_ALL_EVENTS
|
||||
effectiveMask := unmaskableBits | atomic.LoadUint32(&w.mask)
|
||||
matchedEvents := effectiveMask & events
|
||||
|
||||
if matchedEvents == 0 {
|
||||
mask := atomic.LoadUint32(&w.mask)
|
||||
if mask&events == 0 {
|
||||
// We weren't watching for this event.
|
||||
return
|
||||
}
|
||||
|
||||
// Event mask should include bits matched from the watch plus all control
|
||||
// event bits.
|
||||
unmaskableBits := ^uint32(0) &^ linux.IN_ALL_EVENTS
|
||||
effectiveMask := unmaskableBits | mask
|
||||
matchedEvents := effectiveMask & events
|
||||
w.owner.queueEvent(newEvent(w.wd, name, matchedEvents, cookie))
|
||||
}
|
||||
|
||||
|
||||
@@ -271,7 +271,7 @@ var linuxAMD64 = SyscallMap{
|
||||
251: makeSyscallInfo("ioprio_set", Hex, Hex, Hex),
|
||||
252: makeSyscallInfo("ioprio_get", Hex, Hex),
|
||||
253: makeSyscallInfo("inotify_init"),
|
||||
254: makeSyscallInfo("inotify_add_watch", Hex, Hex, Hex),
|
||||
254: makeSyscallInfo("inotify_add_watch", Hex, Path, Hex),
|
||||
255: makeSyscallInfo("inotify_rm_watch", Hex, Hex),
|
||||
256: makeSyscallInfo("migrate_pages", Hex, Hex, Hex, Hex),
|
||||
257: makeSyscallInfo("openat", Hex, Path, OpenFlags, Mode),
|
||||
|
||||
@@ -1484,6 +1484,34 @@ TEST(Inotify, MaskAddMergesWithExistingEventMask) {
|
||||
ASSERT_THAT(events, Are({Event(IN_CLOSE_WRITE, wd)}));
|
||||
}
|
||||
|
||||
// Test that control events bits are not considered when checking event mask.
|
||||
TEST(Inotify, ControlEvents) {
|
||||
const TempPath dir = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir());
|
||||
const FileDescriptor fd =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(InotifyInit1(IN_NONBLOCK));
|
||||
|
||||
const int wd = ASSERT_NO_ERRNO_AND_VALUE(
|
||||
InotifyAddWatch(fd.get(), dir.path(), IN_ACCESS));
|
||||
|
||||
// Check that events in the mask are dispatched and that control bits are
|
||||
// part of the event mask.
|
||||
std::vector<std::string> files =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(ListDir(dir.path(), false));
|
||||
ASSERT_EQ(files.size(), 2);
|
||||
|
||||
const std::vector<Event> events1 =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(DrainEvents(fd.get()));
|
||||
ASSERT_THAT(events1, Are({Event(IN_ACCESS | IN_ISDIR, wd)}));
|
||||
|
||||
// Check that events not in the mask are discarded.
|
||||
const FileDescriptor dir_fd =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(Open(dir.path(), O_RDONLY | O_DIRECTORY));
|
||||
|
||||
const std::vector<Event> events2 =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(DrainEvents(fd.get()));
|
||||
ASSERT_THAT(events2, Are({}));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace testing
|
||||
} // namespace gvisor
|
||||
|
||||
Reference in New Issue
Block a user