On Thu, May 3, 2018 at 6:24 PM, Henry Wilson <henry.wilson@xxxxxxxxxxx> wrote: > From: Henry Wilson <henry.wilson@xxxxxxxxxxx> > > inotify: Add flag IN_ONLY_CREATE for inotify_add_watch() > > The flag IN_ONLY_CREATE is introduced as a flag for inotiy_add_watch() which > prevents inotify from modifying any existing watches when invoked. If the > pathname specified in the call has a watched inode associated with it and > IN_ONLY_CREATE is specified, fail with an errno of EEXIST. > > Signed-off-by: Henry Wilson <henry.wilson@xxxxxxxxxxx> > --- > RATIONALE > > When using inotify_add_watch() a programmer will expect the watch descriptor to > create a new watch descriptor referencing the inode the path is associated with. > However while the word 'add' implies these semantics, the system call may either > create or modify watches with this call. This would be fine if the interface has > a mechanism by which to distinguish between these actions. If two files, file1, > file2 the new path points to the same inode as an existing watch, for example > with a hard-link, a dereferenced symbolic link or the original file being > renamed. The programmer will be given a watch descriptor that they alrady have. > > IMPLICATIONS OF THE DEFECT > > The programmer may not realise the watch descriptor has been duplicated. Thus, > two logical entities in the program will have the same watch descriptor and will > compete for events from the queue. The watch descriptor will be deleted more > times than neccessary in this case. > > The call to inotify_add_watch() may modify the watch mask for the original watch > descriptor and the program may attempt to revert these changes. They may be > unable to revert changes due to the path no-longer being associated with the > same inode. The problem may be compounded if the path is assiciated with a > different inode that is being watched. If IN_MASK_ADD was not used with the > call, by the time the watch mask is reverted, important events may have been > missed, without a mechanism to explicitly say that events were missed. (Unlike > queue overflow) > > Thus it cannot currently be guaranteed that a watch descriptor will only > generate events which have been requested. The program must filter events which > come through its watch descriptor. > > ALTERNATIVES > > Create a new system call inotify_create_watch(fd, pathname, mask) which only > creates watches. This would avoid creating a new flag-bit but would require some > implementation refactoring. Adding a new flag-bit was chosen as currently 21 > IN_xxx flag-bits exist, an additional flag-bit leaves 10 remaining for future > expansion. This leverages the existing implementation and as such is a minor > implementation change. > > EXTENSIONS > > A new system call inotify_modify_watch(fd, wd, mask) would be useful to modify > an existing watch directly to avoid similar problems when modifying a watch > descriptor's mask > > ADDITIONS TO MANPAGES > > inotify(7) > > IN_ONLY_CREATE > Only watch pathname if it refers to an inode that is not already being watched > by this inotify instance. > > inotify_add_watch(2) > > EEXIST > pathname references an existing watch descriptor and IN_ONLY_CREATE was > specified. I'm not crazy about the flag name. No great ideas for name. Maybe I_NO_UPDATE. If this API change is considered, I would like to see a similar change to fanotify, because I don't like fact there is missing functionality in fanotify and would not like that gap to grow. Thanks, Amir.