aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@googlemail.com>2012-11-17 06:45:47 -0500
committerMiklos Szeredi <mszeredi@suse.cz>2013-01-17 07:04:51 -0500
commit8ce03fd76d323526a693d05d85296ef07a387a9f (patch)
treeb1370c17b55e60dfc8faa8b6a8dae2b394199ce9 /fs
parentdfdebc24837ed0a1d6ad73b108a10d3c88d1b6e8 (diff)
cuse: use mutex as registration lock instead of spinlocks
We need to check for name-collisions during cuse-device registration. To avoid race-conditions, this needs to be protected during the whole device registration. Therefore, replace the spinlocks by mutexes first so we can safely extend the locked regions to include more expensive or sleeping code paths. Signed-off-by: David Herrmann <dh.herrmann@googlemail.com> Acked-by: Tejun Heo <tj@kernel.org> Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Diffstat (limited to 'fs')
-rw-r--r--fs/fuse/cuse.c15
1 files changed, 7 insertions, 8 deletions
diff --git a/fs/fuse/cuse.c b/fs/fuse/cuse.c
index ee8d55042298..048e89f25082 100644
--- a/fs/fuse/cuse.c
+++ b/fs/fuse/cuse.c
@@ -45,7 +45,6 @@
45#include <linux/miscdevice.h> 45#include <linux/miscdevice.h>
46#include <linux/mutex.h> 46#include <linux/mutex.h>
47#include <linux/slab.h> 47#include <linux/slab.h>
48#include <linux/spinlock.h>
49#include <linux/stat.h> 48#include <linux/stat.h>
50#include <linux/module.h> 49#include <linux/module.h>
51 50
@@ -63,7 +62,7 @@ struct cuse_conn {
63 bool unrestricted_ioctl; 62 bool unrestricted_ioctl;
64}; 63};
65 64
66static DEFINE_SPINLOCK(cuse_lock); /* protects cuse_conntbl */ 65static DEFINE_MUTEX(cuse_lock); /* protects registration */
67static struct list_head cuse_conntbl[CUSE_CONNTBL_LEN]; 66static struct list_head cuse_conntbl[CUSE_CONNTBL_LEN];
68static struct class *cuse_class; 67static struct class *cuse_class;
69 68
@@ -114,14 +113,14 @@ static int cuse_open(struct inode *inode, struct file *file)
114 int rc; 113 int rc;
115 114
116 /* look up and get the connection */ 115 /* look up and get the connection */
117 spin_lock(&cuse_lock); 116 mutex_lock(&cuse_lock);
118 list_for_each_entry(pos, cuse_conntbl_head(devt), list) 117 list_for_each_entry(pos, cuse_conntbl_head(devt), list)
119 if (pos->dev->devt == devt) { 118 if (pos->dev->devt == devt) {
120 fuse_conn_get(&pos->fc); 119 fuse_conn_get(&pos->fc);
121 cc = pos; 120 cc = pos;
122 break; 121 break;
123 } 122 }
124 spin_unlock(&cuse_lock); 123 mutex_unlock(&cuse_lock);
125 124
126 /* dead? */ 125 /* dead? */
127 if (!cc) 126 if (!cc)
@@ -377,9 +376,9 @@ static void cuse_process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
377 cc->cdev = cdev; 376 cc->cdev = cdev;
378 377
379 /* make the device available */ 378 /* make the device available */
380 spin_lock(&cuse_lock); 379 mutex_lock(&cuse_lock);
381 list_add(&cc->list, cuse_conntbl_head(devt)); 380 list_add(&cc->list, cuse_conntbl_head(devt));
382 spin_unlock(&cuse_lock); 381 mutex_unlock(&cuse_lock);
383 382
384 /* announce device availability */ 383 /* announce device availability */
385 dev_set_uevent_suppress(dev, 0); 384 dev_set_uevent_suppress(dev, 0);
@@ -520,9 +519,9 @@ static int cuse_channel_release(struct inode *inode, struct file *file)
520 int rc; 519 int rc;
521 520
522 /* remove from the conntbl, no more access from this point on */ 521 /* remove from the conntbl, no more access from this point on */
523 spin_lock(&cuse_lock); 522 mutex_lock(&cuse_lock);
524 list_del_init(&cc->list); 523 list_del_init(&cc->list);
525 spin_unlock(&cuse_lock); 524 mutex_unlock(&cuse_lock);
526 525
527 /* remove device */ 526 /* remove device */
528 if (cc->dev) 527 if (cc->dev)