]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - fs/notify/fanotify/fanotify_user.c
fanotify: allow userspace to override max queue depth
[net-next-2.6.git] / fs / notify / fanotify / fanotify_user.c
index 1c09e6321c5e0908aae9fe46bbe63b5e2acbca02..43d66d9b2eff13b4188c7379bc618ea474047805 100644 (file)
@@ -16,6 +16,8 @@
 
 #include <asm/ioctls.h>
 
+#define FANOTIFY_DEFAULT_MAX_EVENTS    16384
+
 extern const struct fsnotify_ops fanotify_fsnotify_ops;
 
 static struct kmem_cache *fanotify_mark_cache __read_mostly;
@@ -610,6 +612,16 @@ static int fanotify_add_inode_mark(struct fsnotify_group *group,
 
        pr_debug("%s: group=%p inode=%p\n", __func__, group, inode);
 
+       /*
+        * If some other task has this inode open for write we should not add
+        * an ignored mark, unless that ignored mark is supposed to survive
+        * modification changes anyway.
+        */
+       if ((flags & FAN_MARK_IGNORED_MASK) &&
+           !(flags & FAN_MARK_IGNORED_SURV_MODIFY) &&
+           (atomic_read(&inode->i_writecount) > 0))
+               return 0;
+
        fsn_mark = fsnotify_find_inode_mark(group, inode);
        if (!fsn_mark) {
                int ret;
@@ -679,6 +691,15 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
                goto out_put_group;
        }
 
+       if (flags & FAN_UNLIMITED_QUEUE) {
+               fd = -EPERM;
+               if (!capable(CAP_SYS_ADMIN))
+                       goto out_put_group;
+               group->max_events = UINT_MAX;
+       } else {
+               group->max_events = FANOTIFY_DEFAULT_MAX_EVENTS;
+       }
+
        fd = anon_inode_getfd("[fanotify]", &fanotify_fops, group, f_flags);
        if (fd < 0)
                goto out_put_group;