diff options
author | Arnd Bergmann <arnd@arndb.de> | 2010-03-09 23:38:48 -0500 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2010-03-10 01:05:57 -0500 |
commit | 2f2177c8dadbcb08c14f796ac983c5475eca1bd3 (patch) | |
tree | 719c9f14280ca717e1651653e892179fb304590a /drivers/input/input.c | |
parent | 77554b4d1fac6a66d4e624a6e36c020a4f5b6b64 (diff) |
Input: remove BKL, fix input_open_file() locking
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>
Diffstat (limited to 'drivers/input/input.c')
-rw-r--r-- | drivers/input/input.c | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/drivers/input/input.c b/drivers/input/input.c index e2dd8858e19d..e2aad0a51826 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -1879,35 +1879,37 @@ static int input_open_file(struct inode *inode, struct file *file) | |||
1879 | const struct file_operations *old_fops, *new_fops = NULL; | 1879 | const struct file_operations *old_fops, *new_fops = NULL; |
1880 | int err; | 1880 | int err; |
1881 | 1881 | ||
1882 | lock_kernel(); | 1882 | err = mutex_lock_interruptible(&input_mutex); |
1883 | if (err) | ||
1884 | return err; | ||
1885 | |||
1883 | /* No load-on-demand here? */ | 1886 | /* No load-on-demand here? */ |
1884 | handler = input_table[iminor(inode) >> 5]; | 1887 | handler = input_table[iminor(inode) >> 5]; |
1885 | if (!handler || !(new_fops = fops_get(handler->fops))) { | 1888 | if (handler) |
1886 | err = -ENODEV; | 1889 | new_fops = fops_get(handler->fops); |
1887 | goto out; | 1890 | |
1888 | } | 1891 | mutex_unlock(&input_mutex); |
1889 | 1892 | ||
1890 | /* | 1893 | /* |
1891 | * That's _really_ odd. Usually NULL ->open means "nothing special", | 1894 | * That's _really_ odd. Usually NULL ->open means "nothing special", |
1892 | * not "no device". Oh, well... | 1895 | * not "no device". Oh, well... |
1893 | */ | 1896 | */ |
1894 | if (!new_fops->open) { | 1897 | if (!new_fops || !new_fops->open) { |
1895 | fops_put(new_fops); | 1898 | fops_put(new_fops); |
1896 | err = -ENODEV; | 1899 | err = -ENODEV; |
1897 | goto out; | 1900 | goto out; |
1898 | } | 1901 | } |
1902 | |||
1899 | old_fops = file->f_op; | 1903 | old_fops = file->f_op; |
1900 | file->f_op = new_fops; | 1904 | file->f_op = new_fops; |
1901 | 1905 | ||
1902 | err = new_fops->open(inode, file); | 1906 | err = new_fops->open(inode, file); |
1903 | |||
1904 | if (err) { | 1907 | if (err) { |
1905 | fops_put(file->f_op); | 1908 | fops_put(file->f_op); |
1906 | file->f_op = fops_get(old_fops); | 1909 | file->f_op = fops_get(old_fops); |
1907 | } | 1910 | } |
1908 | fops_put(old_fops); | 1911 | fops_put(old_fops); |
1909 | out: | 1912 | out: |
1910 | unlock_kernel(); | ||
1911 | return err; | 1913 | return err; |
1912 | } | 1914 | } |
1913 | 1915 | ||