Input: remove BKL, fix input_open_file() locking
authorArnd Bergmann <arnd@arndb.de>
Wed, 10 Mar 2010 04:38:48 +0000 (20:38 -0800)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Wed, 10 Mar 2010 06:05:57 +0000 (22:05 -0800)
Holding the BKL in input_open_file seems pointless because it does not
protect against updates of input_table, and all open functions from the
underlying drivers have proper mutex locking.

This makes input_open_file take the input_mutex when accessing
the table and no lock when calling into the lower function.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
drivers/input/input.c

index e2dd8858e19d31876fd4406b7142c8ce487aa49f..e2aad0a51826b1214e9f55a9c6a45d7e69e1525e 100644 (file)
@@ -1879,35 +1879,37 @@ static int input_open_file(struct inode *inode, struct file *file)
        const struct file_operations *old_fops, *new_fops = NULL;
        int err;
 
-       lock_kernel();
+       err = mutex_lock_interruptible(&input_mutex);
+       if (err)
+               return err;
+
        /* No load-on-demand here? */
        handler = input_table[iminor(inode) >> 5];
-       if (!handler || !(new_fops = fops_get(handler->fops))) {
-               err = -ENODEV;
-               goto out;
-       }
+       if (handler)
+               new_fops = fops_get(handler->fops);
+
+       mutex_unlock(&input_mutex);
 
        /*
         * That's _really_ odd. Usually NULL ->open means "nothing special",
         * not "no device". Oh, well...
         */
-       if (!new_fops->open) {
+       if (!new_fops || !new_fops->open) {
                fops_put(new_fops);
                err = -ENODEV;
                goto out;
        }
+
        old_fops = file->f_op;
        file->f_op = new_fops;
 
        err = new_fops->open(inode, file);
-
        if (err) {
                fops_put(file->f_op);
                file->f_op = fops_get(old_fops);
        }
        fops_put(old_fops);
 out:
-       unlock_kernel();
        return err;
 }