mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-01-06 02:55:49 +03:00
Kernel+FileManager: Disallow watch_file() in unsupported file systems
Currently only Ext2FS and TmpFS supports InodeWatchers. We now fail with ENOTSUPP if watch_file() is called on e.g ProcFS. This fixes an issue with FileManager chewing up all the CPU when /proc was opened. Watchers don't keep the watched Inode open, and when they close, the watcher FD will EOF. Since nothing else kept /proc open in FileManager, the watchers created for it would EOF immediately, causing a refresh over and over. Fixes #879.
This commit is contained in:
parent
7fea25943d
commit
5292f6e78f
Notes:
sideshowbarker
2024-07-19 10:50:59 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/5292f6e78fc
@ -74,6 +74,8 @@ public:
|
||||
|
||||
virtual KResult prepare_to_unmount() const override;
|
||||
|
||||
virtual bool supports_watchers() const override { return true; }
|
||||
|
||||
private:
|
||||
typedef unsigned BlockIndex;
|
||||
typedef unsigned GroupIndex;
|
||||
|
@ -37,6 +37,7 @@ public:
|
||||
virtual bool initialize() = 0;
|
||||
virtual const char* class_name() const = 0;
|
||||
virtual InodeIdentifier root_inode() const = 0;
|
||||
virtual bool supports_watchers() const { return false; }
|
||||
|
||||
bool is_readonly() const { return m_readonly; }
|
||||
|
||||
|
@ -17,6 +17,8 @@ public:
|
||||
|
||||
virtual const char* class_name() const override { return "TmpFS"; }
|
||||
|
||||
virtual bool supports_watchers() const override { return true; }
|
||||
|
||||
virtual InodeIdentifier root_inode() const override;
|
||||
virtual RefPtr<Inode> get_inode(InodeIdentifier) const override;
|
||||
|
||||
|
@ -3230,6 +3230,9 @@ int Process::sys$watch_file(const char* path, int path_length)
|
||||
auto& custody = custody_or_error.value();
|
||||
auto& inode = custody->inode();
|
||||
|
||||
if (!inode.fs().supports_watchers())
|
||||
return -ENOTSUP;
|
||||
|
||||
int fd = alloc_fd();
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
@ -406,6 +406,8 @@ const char* const sys_errlist[] = {
|
||||
"Wrong protocol type",
|
||||
"Operation in progress",
|
||||
"No such thread",
|
||||
"Protocol error",
|
||||
"Not supported",
|
||||
"The highest errno +1 :^)",
|
||||
};
|
||||
|
||||
|
@ -341,21 +341,23 @@ void GDirectoryModel::open(const StringView& a_path)
|
||||
if (!dirp)
|
||||
return;
|
||||
closedir(dirp);
|
||||
if (m_notifier)
|
||||
if (m_notifier) {
|
||||
close(m_notifier->fd());
|
||||
m_notifier = nullptr;
|
||||
}
|
||||
m_path = path;
|
||||
int watch_fd = watch_file(path.characters(), path.length());
|
||||
if (watch_fd < 0) {
|
||||
perror("watch_file");
|
||||
ASSERT_NOT_REACHED();
|
||||
} else {
|
||||
m_notifier = CNotifier::construct(watch_fd, CNotifier::Event::Read);
|
||||
m_notifier->on_ready_to_read = [this] {
|
||||
update();
|
||||
char buffer[32];
|
||||
int rc = read(m_notifier->fd(), buffer, sizeof(buffer));
|
||||
ASSERT(rc >= 0);
|
||||
};
|
||||
}
|
||||
m_notifier = CNotifier::construct(watch_fd, CNotifier::Event::Read);
|
||||
m_notifier->on_ready_to_read = [this] {
|
||||
update();
|
||||
char buffer[32];
|
||||
int rc = read(m_notifier->fd(), buffer, sizeof(buffer));
|
||||
ASSERT(rc >= 0);
|
||||
};
|
||||
if (on_path_change)
|
||||
on_path_change();
|
||||
update();
|
||||
|
Loading…
Reference in New Issue
Block a user