Add support for create/attrib/rename/delete events with data type FSNOTIFY_EVENT_DENTRY, which can be reported on a watched directory inode. New dentry events may pass parent directory's path on event fd, which may break old programs that request FAN_ALL_EVENTS. Ignore dentry events unless user explicitly set the new FAN_EVENT_INFO_PARENT flag to fanotify_init(). A mount watch cannot get dentry events, because the mount point from which those events were created is unavailable inforamtion. Legacy inotify events that are still not supported are DELETE_SELF and MOVE_FROM, whose event data type is still FSNOTIFY_EVENT_INODE. Signed-off-by: Amir Goldstein <amir73il@xxxxxxxxx> --- fs/notify/fanotify/fanotify.c | 7 +++++++ fs/notify/fanotify/fanotify_user.c | 12 ++++++++++++ include/uapi/linux/fanotify.h | 26 ++++++++++++++++++++++---- 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index fb2b852..378101c 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -212,9 +212,16 @@ static int fanotify_handle_event(struct fsnotify_group *group, BUILD_BUG_ON(FAN_ACCESS != FS_ACCESS); BUILD_BUG_ON(FAN_MODIFY != FS_MODIFY); + BUILD_BUG_ON(FAN_ATTRIB != FS_ATTRIB); BUILD_BUG_ON(FAN_CLOSE_NOWRITE != FS_CLOSE_NOWRITE); BUILD_BUG_ON(FAN_CLOSE_WRITE != FS_CLOSE_WRITE); BUILD_BUG_ON(FAN_OPEN != FS_OPEN); + BUILD_BUG_ON(FAN_MOVED_TO != FS_MOVED_TO); + BUILD_BUG_ON(FAN_MOVED_FROM != FS_MOVED_FROM); + BUILD_BUG_ON(FAN_CREATE != FS_CREATE); + BUILD_BUG_ON(FAN_DELETE != FS_DELETE); + BUILD_BUG_ON(FAN_DELETE_SELF != FS_DELETE_SELF); + BUILD_BUG_ON(FAN_MOVE_SELF != FS_MOVE_SELF); BUILD_BUG_ON(FAN_EVENT_ON_CHILD != FS_EVENT_ON_CHILD); BUILD_BUG_ON(FAN_Q_OVERFLOW != FS_Q_OVERFLOW); BUILD_BUG_ON(FAN_OPEN_PERM != FS_OPEN_PERM); diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 789962c..616769a 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -907,6 +907,18 @@ SYSCALL_DEFINE5(fanotify_mark, int, fanotify_fd, unsigned int, flags, group->fanotify_data.flags & FAN_EVENT_INFO_PARENT) mnt = path.mnt; + /* + * New dentry events may pass parent directory's path on event fd, + * which may break old programs that request FAN_ALL_EVENTS. + * Ignore dentry events unless user explicitly set the new + * FAN_EVENT_INFO_PARENT flag to fanotify_init(). + * Mount watch cannot get dentry events, because the mount point + * from which those events were created is unavailable inforamtion. + */ + if ((flags & FAN_MARK_MOUNT) || + !(group->fanotify_data.flags & FAN_EVENT_INFO_PARENT)) + mask &= ~FAN_DENTRY_EVENTS; + /* create/update an inode mark */ switch (flags & (FAN_MARK_ADD | FAN_MARK_REMOVE)) { case FAN_MARK_ADD: diff --git a/include/uapi/linux/fanotify.h b/include/uapi/linux/fanotify.h index 8e58765..3389da0 100644 --- a/include/uapi/linux/fanotify.h +++ b/include/uapi/linux/fanotify.h @@ -6,9 +6,17 @@ /* the following events that user-space can register for */ #define FAN_ACCESS 0x00000001 /* File was accessed */ #define FAN_MODIFY 0x00000002 /* File was modified */ +#define FAN_ATTRIB 0x00000004 /* Metadata changed */ #define FAN_CLOSE_WRITE 0x00000008 /* Writtable file closed */ #define FAN_CLOSE_NOWRITE 0x00000010 /* Unwrittable file closed */ #define FAN_OPEN 0x00000020 /* File was opened */ +#define FAN_MOVED_FROM 0x00000040 /* File was moved from X */ +#define FAN_MOVED_TO 0x00000080 /* File was moved to Y */ +#define FAN_CREATE 0x00000100 /* Subfile was created */ +#define FAN_DELETE 0x00000200 /* Subfile was deleted */ +#define FAN_DELETE_SELF 0x00000400 /* Self was deleted */ +#define FAN_MOVE_SELF 0x00000800 /* Self was moved */ + #define FAN_Q_OVERFLOW 0x00004000 /* Event queued overflowed */ @@ -21,6 +29,7 @@ /* helper events */ #define FAN_CLOSE (FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE) /* close */ +#define FAN_MOVE (FAN_MOVED_FROM | FAN_MOVED_TO) /* moves */ /* flags used for fanotify_init() */ #define FAN_CLOEXEC 0x00000001 @@ -69,10 +78,19 @@ * the future and not break backward compatibility. Apps will get only the * events that they originally wanted. Be sure to add new events here! */ -#define FAN_ALL_EVENTS (FAN_ACCESS |\ - FAN_MODIFY |\ - FAN_CLOSE |\ - FAN_OPEN) + +/* Events reported with data type FSNOTIFY_EVENT_PATH */ +#define FAN_PATH_EVENTS (FAN_ACCESS |\ + FAN_MODIFY |\ + FAN_CLOSE |\ + FAN_OPEN) + +/* Events reported with data type FSNOTIFY_EVENT_DENTRY */ +#define FAN_DENTRY_EVENTS (FAN_ATTRIB |\ + FAN_MOVED_TO | FAN_MOVE_SELF |\ + FAN_CREATE | FAN_DELETE) + +#define FAN_ALL_EVENTS (FAN_PATH_EVENTS | FAN_DENTRY_EVENTS) /* * All events which require a permission response from userspace -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html