aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/char
diff options
context:
space:
mode:
authorMelissa Howland <melissah@us.ibm.com>2007-08-10 08:32:35 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2007-08-10 08:32:39 -0400
commitcbea66d9788a344e16e161f22a6e0c4deef2c0ed (patch)
tree3fb41c221aac478ccae176b4d088624f9acb833c /drivers/s390/char
parent3eed13cc3beaa9ee07b126a662def88f7281394e (diff)
[S390] monwriter: Serialization bug for multithreaded applications.
Locking added so that multithreaded applications can now do writes from different threads without the risk of storage corruption. Signed-off-by: Melissa Howland <melissah@us.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/char')
-rw-r--r--drivers/s390/char/monwriter.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/drivers/s390/char/monwriter.c b/drivers/s390/char/monwriter.c
index 268598ef3efe..20442fbf9346 100644
--- a/drivers/s390/char/monwriter.c
+++ b/drivers/s390/char/monwriter.c
@@ -17,6 +17,7 @@
17#include <linux/miscdevice.h> 17#include <linux/miscdevice.h>
18#include <linux/ctype.h> 18#include <linux/ctype.h>
19#include <linux/poll.h> 19#include <linux/poll.h>
20#include <linux/mutex.h>
20#include <asm/uaccess.h> 21#include <asm/uaccess.h>
21#include <asm/ebcdic.h> 22#include <asm/ebcdic.h>
22#include <asm/io.h> 23#include <asm/io.h>
@@ -41,6 +42,7 @@ struct mon_private {
41 size_t hdr_to_read; 42 size_t hdr_to_read;
42 size_t data_to_read; 43 size_t data_to_read;
43 struct mon_buf *current_buf; 44 struct mon_buf *current_buf;
45 struct mutex thread_mutex;
44}; 46};
45 47
46/* 48/*
@@ -179,6 +181,7 @@ static int monwrite_open(struct inode *inode, struct file *filp)
179 return -ENOMEM; 181 return -ENOMEM;
180 INIT_LIST_HEAD(&monpriv->list); 182 INIT_LIST_HEAD(&monpriv->list);
181 monpriv->hdr_to_read = sizeof(monpriv->hdr); 183 monpriv->hdr_to_read = sizeof(monpriv->hdr);
184 mutex_init(&monpriv->thread_mutex);
182 filp->private_data = monpriv; 185 filp->private_data = monpriv;
183 return nonseekable_open(inode, filp); 186 return nonseekable_open(inode, filp);
184} 187}
@@ -209,6 +212,7 @@ static ssize_t monwrite_write(struct file *filp, const char __user *data,
209 void *to; 212 void *to;
210 int rc; 213 int rc;
211 214
215 mutex_lock(&monpriv->thread_mutex);
212 for (written = 0; written < count; ) { 216 for (written = 0; written < count; ) {
213 if (monpriv->hdr_to_read) { 217 if (monpriv->hdr_to_read) {
214 len = min(count - written, monpriv->hdr_to_read); 218 len = min(count - written, monpriv->hdr_to_read);
@@ -247,11 +251,13 @@ static ssize_t monwrite_write(struct file *filp, const char __user *data,
247 } 251 }
248 monpriv->hdr_to_read = sizeof(monpriv->hdr); 252 monpriv->hdr_to_read = sizeof(monpriv->hdr);
249 } 253 }
254 mutex_unlock(&monpriv->thread_mutex);
250 return written; 255 return written;
251 256
252out_error: 257out_error:
253 monpriv->data_to_read = 0; 258 monpriv->data_to_read = 0;
254 monpriv->hdr_to_read = sizeof(struct monwrite_hdr); 259 monpriv->hdr_to_read = sizeof(struct monwrite_hdr);
260 mutex_unlock(&monpriv->thread_mutex);
255 return rc; 261 return rc;
256} 262}
257 263