Merge by hand (conflicts in sd.c)
[sfrench/cifs-2.6.git] / fs / inotify.c
index 807209f0bcda18d39686386adad8f1db18a44d38..2e4e2a57708cf95dcdf348235376ef901f4dc295 100644 (file)
@@ -90,6 +90,7 @@ struct inotify_device {
        unsigned int            queue_size;     /* size of the queue (bytes) */
        unsigned int            event_count;    /* number of pending events */
        unsigned int            max_events;     /* maximum number of events */
+       u32                     last_wd;        /* the last wd allocated */
 };
 
 /*
@@ -352,7 +353,7 @@ static int inotify_dev_get_wd(struct inotify_device *dev,
        do {
                if (unlikely(!idr_pre_get(&dev->idr, GFP_KERNEL)))
                        return -ENOSPC;
-               ret = idr_get_new(&dev->idr, watch, &watch->wd);
+               ret = idr_get_new_above(&dev->idr, watch, dev->last_wd+1, &watch->wd);
        } while (ret == -EAGAIN);
 
        return ret;
@@ -401,6 +402,7 @@ static struct inotify_watch *create_watch(struct inotify_device *dev,
                return ERR_PTR(ret);
        }
 
+       dev->last_wd = watch->wd;
        watch->mask = mask;
        atomic_set(&watch->count, 0);
        INIT_LIST_HEAD(&watch->d_list);
@@ -865,23 +867,21 @@ asmlinkage long sys_inotify_init(void)
 
        filp = get_empty_filp();
        if (!filp) {
-               put_unused_fd(fd);
                ret = -ENFILE;
-               goto out;
+               goto out_put_fd;
        }
 
        user = get_uid(current->user);
-
        if (unlikely(atomic_read(&user->inotify_devs) >=
                        inotify_max_user_instances)) {
                ret = -EMFILE;
-               goto out_err;
+               goto out_free_uid;
        }
 
        dev = kmalloc(sizeof(struct inotify_device), GFP_KERNEL);
        if (unlikely(!dev)) {
                ret = -ENOMEM;
-               goto out_err;
+               goto out_free_uid;
        }
 
        filp->f_op = &inotify_fops;
@@ -901,6 +901,7 @@ asmlinkage long sys_inotify_init(void)
        dev->queue_size = 0;
        dev->max_events = inotify_max_queued_events;
        dev->user = user;
+       dev->last_wd = 0;
        atomic_set(&dev->count, 0);
 
        get_inotify_dev(dev);
@@ -908,11 +909,11 @@ asmlinkage long sys_inotify_init(void)
        fd_install(fd, filp);
 
        return fd;
-out_err:
-       put_unused_fd (fd);
-       put_filp (filp);
+out_free_uid:
        free_uid(user);
-out:
+       put_filp(filp);
+out_put_fd:
+       put_unused_fd(fd);
        return ret;
 }
 
@@ -929,6 +930,12 @@ asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask)
        if (unlikely(!filp))
                return -EBADF;
 
+       /* verify that this is indeed an inotify instance */
+       if (unlikely(filp->f_op != &inotify_fops)) {
+               ret = -EINVAL;
+               goto fput_and_out;
+       }
+
        ret = find_inode(path, &nd);
        if (unlikely(ret))
                goto fput_and_out;
@@ -969,9 +976,9 @@ asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask)
        list_add(&watch->i_list, &inode->inotify_watches);
        ret = watch->wd;
 out:
-       path_release (&nd);
        up(&dev->sem);
        up(&inode->inotify_sem);
+       path_release(&nd);
 fput_and_out:
        fput_light(filp, fput_needed);
        return ret;
@@ -986,10 +993,18 @@ asmlinkage long sys_inotify_rm_watch(int fd, u32 wd)
        filp = fget_light(fd, &fput_needed);
        if (unlikely(!filp))
                return -EBADF;
+
+       /* verify that this is indeed an inotify instance */
+       if (unlikely(filp->f_op != &inotify_fops)) {
+               ret = -EINVAL;
+               goto out;
+       }
+
        dev = filp->private_data;
        ret = inotify_ignore(dev, wd);
-       fput_light(filp, fput_needed);
 
+out:
+       fput_light(filp, fput_needed);
        return ret;
 }
 
@@ -1013,11 +1028,18 @@ static struct file_system_type inotify_fs_type = {
  */
 static int __init inotify_setup(void)
 {
-       register_filesystem(&inotify_fs_type);
+       int ret;
+
+       ret = register_filesystem(&inotify_fs_type);
+       if (unlikely(ret))
+               panic("inotify: register_filesystem returned %d!\n", ret);
+
        inotify_mnt = kern_mount(&inotify_fs_type);
+       if (IS_ERR(inotify_mnt))
+               panic("inotify: kern_mount ret %ld!\n", PTR_ERR(inotify_mnt));
 
-       inotify_max_queued_events = 8192;
-       inotify_max_user_instances = 8;
+       inotify_max_queued_events = 16384;
+       inotify_max_user_instances = 128;
        inotify_max_user_watches = 8192;
 
        atomic_set(&inotify_cookie, 0);