Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Love <rml@tech9.net>2002-02-20 20:23:34 -0800
committerLinus Torvalds <torvalds@penguin.transmeta.com>2002-02-20 20:23:34 -0800
commit59b52d25c371e80c671d96f1698383075ac4ebd9 (patch)
tree4c8a766a36c6b8e9adca0208a4c120f58c1038ba
parent41ae709dd601ac80847dc26d779d2403f3a56ed5 (diff)
[PATCH] proper lseek locking in ALSA, take 3
The attached patch implements proper locking in ALSA lseek methods. Note ALSA has 3 lseek implementations, but only: sound/core/info.c :: snd_info_entry_llseek() requires locking. I wrapped the function in the BKL. According to Jaroslav Kysela the gus_mem_proc method is only called from above. The third lseek, in hwdep.c, clearly doesn't need locking. Without this patch, the above lseek is not safe. Robert Love
-rw-r--r--sound/core/info.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/sound/core/info.c b/sound/core/info.c
index 32874e26ee6e..3faa42e0496f 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -29,6 +29,7 @@
#include <sound/info.h>
#include <sound/version.h>
#include <linux/proc_fs.h>
+#include <linux/smp_lock.h>
#ifdef CONFIG_DEVFS_FS
#include <linux/devfs_fs_kernel.h>
#endif
@@ -162,31 +163,40 @@ static loff_t snd_info_entry_llseek(struct file *file, loff_t offset, int orig)
{
snd_info_private_data_t *data;
struct snd_info_entry *entry;
+ int ret = -EINVAL;
data = snd_magic_cast(snd_info_private_data_t, file->private_data, return -ENXIO);
entry = data->entry;
+ lock_kernel();
switch (entry->content) {
case SNDRV_INFO_CONTENT_TEXT:
switch (orig) {
case 0: /* SEEK_SET */
file->f_pos = offset;
- return file->f_pos;
+ ret = file->f_pos;
+ goto out;
case 1: /* SEEK_CUR */
file->f_pos += offset;
- return file->f_pos;
+ ret = file->f_pos;
+ goto out;
case 2: /* SEEK_END */
default:
- return -EINVAL;
+ goto out;
}
break;
case SNDRV_INFO_CONTENT_DATA:
- if (entry->c.ops->llseek)
- return entry->c.ops->llseek(entry,
+ if (entry->c.ops->llseek) {
+ ret = entry->c.ops->llseek(entry,
data->file_private_data,
file, offset, orig);
+ goto out;
+ }
break;
}
- return -ENXIO;
+ ret = -ENXIO;
+out:
+ unlock_kernel();
+ return ret;
}
static ssize_t snd_info_entry_read(struct file *file, char *buffer,