diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c index 1cf5b779d862..6f48d325c350 100644 --- a/fs/notify/inotify/inotify_user.c +++ b/fs/notify/inotify/inotify_user.c @@ -510,6 +510,7 @@ static int inotify_update_existing_watch(struct fsnotify_group *group, __u32 old_mask, new_mask; __u32 mask; int add = (arg & IN_MASK_ADD); + int create = (arg & IN_MASK_CREATE); int ret; mask = inotify_arg_to_mask(arg); @@ -517,6 +518,8 @@ static int inotify_update_existing_watch(struct fsnotify_group *group, fsn_mark = fsnotify_find_mark(&inode->i_fsnotify_marks, group); if (!fsn_mark) return -ENOENT; + else if (create) + return -EEXIST; i_mark = container_of(fsn_mark, struct inotify_inode_mark, fsn_mark); @@ -718,6 +721,10 @@ SYSCALL_DEFINE3(inotify_add_watch, int, fd, const char __user *, pathname, if (unlikely(!f.file)) return -EBADF; + /* IN_MASK_ADD and IN_MASK_CREATE don't make sense together */ + if (unlikely((mask & IN_MASK_ADD) && (mask & IN_MASK_CREATE))) + return -EINVAL; + /* verify that this is indeed an inotify instance */ if (unlikely(f.file->f_op != &inotify_fops)) { ret = -EINVAL; @@ -806,7 +813,7 @@ static int __init inotify_user_setup(void) BUILD_BUG_ON(IN_ISDIR != FS_ISDIR); BUILD_BUG_ON(IN_ONESHOT != FS_IN_ONESHOT); - BUG_ON(hweight32(ALL_INOTIFY_BITS) != 21); + BUG_ON(hweight32(ALL_INOTIFY_BITS) != 22); inotify_inode_mark_cachep = KMEM_CACHE(inotify_inode_mark, SLAB_PANIC); diff --git a/include/linux/inotify.h b/include/linux/inotify.h index 44f9ffe72c87..6a24905f6e1e 100644 --- a/include/linux/inotify.h +++ b/include/linux/inotify.h @@ -18,6 +18,6 @@ extern struct ctl_table inotify_table[]; /* for sysctl */ IN_DELETE_SELF | IN_MOVE_SELF | IN_UNMOUNT | \ IN_Q_OVERFLOW | IN_IGNORED | IN_ONLYDIR | \ IN_DONT_FOLLOW | IN_EXCL_UNLINK | IN_MASK_ADD | \ - IN_ISDIR | IN_ONESHOT) + IN_MASK_CREATE | IN_ISDIR | IN_ONESHOT) #endif /* _LINUX_INOTIFY_H */ diff --git a/include/uapi/linux/inotify.h b/include/uapi/linux/inotify.h index 4800bf2a531d..884b4846b630 100644 --- a/include/uapi/linux/inotify.h +++ b/include/uapi/linux/inotify.h @@ -53,6 +53,7 @@ struct inotify_event { #define IN_ONLYDIR 0x01000000 /* only watch the path if it is a directory */ #define IN_DONT_FOLLOW 0x02000000 /* don't follow a sym link */ #define IN_EXCL_UNLINK 0x04000000 /* exclude events on unlinked objects */ +#define IN_MASK_CREATE 0x10000000 /* only create watches */ #define IN_MASK_ADD 0x20000000 /* add to the mask of an already existing watch */ #define IN_ISDIR 0x40000000 /* event occurred against dir */ #define IN_ONESHOT 0x80000000 /* only send event once */