aboutsummaryrefslogtreecommitdiffstats
path: root/fs/inotify.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/inotify.c')
-rw-r--r--fs/inotify.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/fs/inotify.c b/fs/inotify.c
index 2e4e2a57708c..a37e9fb1da58 100644
--- a/fs/inotify.c
+++ b/fs/inotify.c
@@ -37,6 +37,7 @@
37#include <asm/ioctls.h> 37#include <asm/ioctls.h>
38 38
39static atomic_t inotify_cookie; 39static atomic_t inotify_cookie;
40static atomic_t inotify_watches;
40 41
41static kmem_cache_t *watch_cachep; 42static kmem_cache_t *watch_cachep;
42static kmem_cache_t *event_cachep; 43static kmem_cache_t *event_cachep;
@@ -422,6 +423,7 @@ static struct inotify_watch *create_watch(struct inotify_device *dev,
422 get_inotify_watch(watch); 423 get_inotify_watch(watch);
423 424
424 atomic_inc(&dev->user->inotify_watches); 425 atomic_inc(&dev->user->inotify_watches);
426 atomic_inc(&inotify_watches);
425 427
426 return watch; 428 return watch;
427} 429}
@@ -454,6 +456,7 @@ static void remove_watch_no_event(struct inotify_watch *watch,
454 list_del(&watch->d_list); 456 list_del(&watch->d_list);
455 457
456 atomic_dec(&dev->user->inotify_watches); 458 atomic_dec(&dev->user->inotify_watches);
459 atomic_dec(&inotify_watches);
457 idr_remove(&dev->idr, watch->wd); 460 idr_remove(&dev->idr, watch->wd);
458 put_inotify_watch(watch); 461 put_inotify_watch(watch);
459} 462}
@@ -532,6 +535,9 @@ void inotify_dentry_parent_queue_event(struct dentry *dentry, u32 mask,
532 struct dentry *parent; 535 struct dentry *parent;
533 struct inode *inode; 536 struct inode *inode;
534 537
538 if (!atomic_read (&inotify_watches))
539 return;
540
535 spin_lock(&dentry->d_lock); 541 spin_lock(&dentry->d_lock);
536 parent = dentry->d_parent; 542 parent = dentry->d_parent;
537 inode = parent->d_inode; 543 inode = parent->d_inode;
@@ -925,6 +931,7 @@ asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask)
925 struct nameidata nd; 931 struct nameidata nd;
926 struct file *filp; 932 struct file *filp;
927 int ret, fput_needed; 933 int ret, fput_needed;
934 int mask_add = 0;
928 935
929 filp = fget_light(fd, &fput_needed); 936 filp = fget_light(fd, &fput_needed);
930 if (unlikely(!filp)) 937 if (unlikely(!filp))
@@ -947,6 +954,9 @@ asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask)
947 down(&inode->inotify_sem); 954 down(&inode->inotify_sem);
948 down(&dev->sem); 955 down(&dev->sem);
949 956
957 if (mask & IN_MASK_ADD)
958 mask_add = 1;
959
950 /* don't let user-space set invalid bits: we don't want flags set */ 960 /* don't let user-space set invalid bits: we don't want flags set */
951 mask &= IN_ALL_EVENTS; 961 mask &= IN_ALL_EVENTS;
952 if (unlikely(!mask)) { 962 if (unlikely(!mask)) {
@@ -960,7 +970,10 @@ asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask)
960 */ 970 */
961 old = inode_find_dev(inode, dev); 971 old = inode_find_dev(inode, dev);
962 if (unlikely(old)) { 972 if (unlikely(old)) {
963 old->mask = mask; 973 if (mask_add)
974 old->mask |= mask;
975 else
976 old->mask = mask;
964 ret = old->wd; 977 ret = old->wd;
965 goto out; 978 goto out;
966 } 979 }
@@ -1043,6 +1056,7 @@ static int __init inotify_setup(void)
1043 inotify_max_user_watches = 8192; 1056 inotify_max_user_watches = 8192;
1044 1057
1045 atomic_set(&inotify_cookie, 0); 1058 atomic_set(&inotify_cookie, 0);
1059 atomic_set(&inotify_watches, 0);
1046 1060
1047 watch_cachep = kmem_cache_create("inotify_watch_cache", 1061 watch_cachep = kmem_cache_create("inotify_watch_cache",
1048 sizeof(struct inotify_watch), 1062 sizeof(struct inotify_watch),