Linux 目录通知

Stephen Rothwell <sfr@canb.auug.org.au>

目录通知的目的是允许用户应用程序在目录或其中的任何文件发生更改时收到通知。 基本机制涉及应用程序使用 fcntl(2) 调用注册目录通知,通知本身使用信号传递。

应用程序决定它想要被通知的“事件”。 当前定义的事件有

DN_ACCESS

目录中的文件被访问(读取)

DN_MODIFY

目录中的文件被修改(写入,截断)

DN_CREATE

在目录中创建了一个文件

DN_DELETE

从目录中取消链接了一个文件

DN_RENAME

目录中的文件被重命名

DN_ATTRIB

目录中的文件属性被更改(chmod, chown)

通常,应用程序必须在每次通知后重新注册,但如果 DN_MULTISHOT 与事件掩码进行或运算,则注册将保持有效,直到显式删除(通过注册不接收任何事件)。

默认情况下,SIGIO 将传递给进程,没有其他有用的信息。 但是,如果使用 F_SETSIG fcntl(2) 调用让内核知道要传递哪个信号,则会将一个 siginfo 结构传递给信号处理程序,并且该结构的 si_fd 成员将包含与发生事件的目录关联的文件描述符。

最好是应用程序选择其中一个实时信号 (SIGRTMIN + <n>),以便可以将通知排队。 如果指定了 DN_MULTISHOT,这一点尤其重要。 请注意,SIGRTMIN 通常被阻塞,因此最好使用(至少)SIGRTMIN + 1。

实现期望(功能和错误 :-))

即使实际文件系统位于远程服务器上,通知也应该适用于对文件的任何本地访问。 这意味着应该通知对本地用户模式服务器提供的文件的远程访问。 此外,应该通知对本地内核 NFS 服务器提供的文件的远程访问。

为了尽可能减少对文件系统代码的影响,已忽略了文件的硬链接问题。 因此,如果文件 (x) 存在于两个目录(a 和 b)中,则使用名称“a/x”对文件进行的更改应该通知给期望目录“a”上的通知的程序,但不会通知给期望目录“b”上的通知的程序。

此外,取消链接的文件仍然会在它们链接到的最后一个目录中触发通知。

配置

Dnotify 通过 CONFIG_DNOTIFY 配置选项控制。 禁用时,fcntl(fd, F_NOTIFY, ...) 将返回 -EINVAL。

示例

有关示例,请参见 tools/testing/selftests/filesystems/dnotify_test.c。

注意

从 Linux 2.6.13 开始,dnotify 已被 inotify 替换。 有关更多信息,请参见Inotify - 一个强大而简单的文件更改通知系统