lkml.org 
[lkml]   [2004]   [Nov]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
SubjectRe: [PATCH] Driver Core patches for 2.6.10-rc1
Date
From
ChangeSet 1.2445, 2004/11/01 13:04:30-08:00, akpm@osdl.org

[PATCH] Fix race in sysfs_read_file() and sysfs_write_file()

From: Simon Derr <Simon.Derr@bull.net>

- fixes the race between threads by adding a semaphore in sysfs_buffer

- allocates the buffer upon call to pread(). We still call again
fill_read_buffer() if the file is "rewinded" to offset zero.

- fixes the comparison in flush_read_buffer().

Signed-off-by: Simon Derr <simon.derr@bull.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>


fs/sysfs/file.c | 18 +++++++++++++++---
1 files changed, 15 insertions(+), 3 deletions(-)


diff -Nru a/fs/sysfs/file.c b/fs/sysfs/file.c
--- a/fs/sysfs/file.c 2004-11-01 13:36:49 -08:00
+++ b/fs/sysfs/file.c 2004-11-01 13:36:49 -08:00
@@ -6,6 +6,7 @@
#include <linux/dnotify.h>
#include <linux/kobject.h>
#include <asm/uaccess.h>
+#include <asm/semaphore.h>

#include "sysfs.h"

@@ -53,6 +54,7 @@
loff_t pos;
char * page;
struct sysfs_ops * ops;
+ struct semaphore sem;
};


@@ -106,6 +108,9 @@
{
int error;

+ if (*ppos > buffer->count)
+ return 0;
+
if (count > (buffer->count - *ppos))
count = buffer->count - *ppos;

@@ -140,13 +145,17 @@
struct sysfs_buffer * buffer = file->private_data;
ssize_t retval = 0;

- if (!*ppos) {
+ down(&buffer->sem);
+ if ((!*ppos) || (!buffer->page)) {
if ((retval = fill_read_buffer(file->f_dentry,buffer)))
- return retval;
+ goto out;
}
pr_debug("%s: count = %d, ppos = %lld, buf = %s\n",
__FUNCTION__,count,*ppos,buffer->page);
- return flush_read_buffer(buffer,buf,count,ppos);
+ retval = flush_read_buffer(buffer,buf,count,ppos);
+out:
+ up(&buffer->sem);
+ return retval;
}


@@ -220,11 +229,13 @@
{
struct sysfs_buffer * buffer = file->private_data;

+ down(&buffer->sem);
count = fill_write_buffer(buffer,buf,count);
if (count > 0)
count = flush_write_buffer(file->f_dentry,buffer,count);
if (count > 0)
*ppos += count;
+ up(&buffer->sem);
return count;
}

@@ -287,6 +298,7 @@
buffer = kmalloc(sizeof(struct sysfs_buffer),GFP_KERNEL);
if (buffer) {
memset(buffer,0,sizeof(struct sysfs_buffer));
+ init_MUTEX(&buffer->sem);
buffer->ops = ops;
file->private_data = buffer;
} else
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 14:07    [W:0.089 / U:0.020 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site