aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse
diff options
context:
space:
mode:
Diffstat (limited to 'fs/fuse')
-rw-r--r--fs/fuse/Kconfig16
-rw-r--r--fs/fuse/cuse.c36
-rw-r--r--fs/fuse/dev.c5
-rw-r--r--fs/fuse/file.c5
4 files changed, 38 insertions, 24 deletions
diff --git a/fs/fuse/Kconfig b/fs/fuse/Kconfig
index 0cf160a94eda..1b2f6c2c3aaf 100644
--- a/fs/fuse/Kconfig
+++ b/fs/fuse/Kconfig
@@ -4,12 +4,24 @@ config FUSE_FS
4 With FUSE it is possible to implement a fully functional filesystem 4 With FUSE it is possible to implement a fully functional filesystem
5 in a userspace program. 5 in a userspace program.
6 6
7 There's also companion library: libfuse. This library along with 7 There's also a companion library: libfuse2. This library is available
8 utilities is available from the FUSE homepage: 8 from the FUSE homepage:
9 <http://fuse.sourceforge.net/> 9 <http://fuse.sourceforge.net/>
10 although chances are your distribution already has that library
11 installed if you've installed the "fuse" package itself.
10 12
11 See <file:Documentation/filesystems/fuse.txt> for more information. 13 See <file:Documentation/filesystems/fuse.txt> for more information.
12 See <file:Documentation/Changes> for needed library/utility version. 14 See <file:Documentation/Changes> for needed library/utility version.
13 15
14 If you want to develop a userspace FS, or if you want to use 16 If you want to develop a userspace FS, or if you want to use
15 a filesystem based on FUSE, answer Y or M. 17 a filesystem based on FUSE, answer Y or M.
18
19config CUSE
20 tristate "Character device in Userspace support"
21 depends on FUSE_FS
22 help
23 This FUSE extension allows character devices to be
24 implemented in userspace.
25
26 If you want to develop or use a userspace character device
27 based on CUSE, answer Y or M.
diff --git a/fs/fuse/cuse.c b/fs/fuse/cuse.c
index ee8d55042298..e397b675b029 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)
@@ -267,7 +266,7 @@ static int cuse_parse_one(char **pp, char *end, char **keyp, char **valp)
267static int cuse_parse_devinfo(char *p, size_t len, struct cuse_devinfo *devinfo) 266static int cuse_parse_devinfo(char *p, size_t len, struct cuse_devinfo *devinfo)
268{ 267{
269 char *end = p + len; 268 char *end = p + len;
270 char *key, *val; 269 char *uninitialized_var(key), *uninitialized_var(val);
271 int rc; 270 int rc;
272 271
273 while (true) { 272 while (true) {
@@ -305,14 +304,14 @@ static void cuse_gendev_release(struct device *dev)
305 */ 304 */
306static void cuse_process_init_reply(struct fuse_conn *fc, struct fuse_req *req) 305static void cuse_process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
307{ 306{
308 struct cuse_conn *cc = fc_to_cc(fc); 307 struct cuse_conn *cc = fc_to_cc(fc), *pos;
309 struct cuse_init_out *arg = req->out.args[0].value; 308 struct cuse_init_out *arg = req->out.args[0].value;
310 struct page *page = req->pages[0]; 309 struct page *page = req->pages[0];
311 struct cuse_devinfo devinfo = { }; 310 struct cuse_devinfo devinfo = { };
312 struct device *dev; 311 struct device *dev;
313 struct cdev *cdev; 312 struct cdev *cdev;
314 dev_t devt; 313 dev_t devt;
315 int rc; 314 int rc, i;
316 315
317 if (req->out.h.error || 316 if (req->out.h.error ||
318 arg->major != FUSE_KERNEL_VERSION || arg->minor < 11) { 317 arg->major != FUSE_KERNEL_VERSION || arg->minor < 11) {
@@ -356,15 +355,24 @@ static void cuse_process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
356 dev_set_drvdata(dev, cc); 355 dev_set_drvdata(dev, cc);
357 dev_set_name(dev, "%s", devinfo.name); 356 dev_set_name(dev, "%s", devinfo.name);
358 357
358 mutex_lock(&cuse_lock);
359
360 /* make sure the device-name is unique */
361 for (i = 0; i < CUSE_CONNTBL_LEN; ++i) {
362 list_for_each_entry(pos, &cuse_conntbl[i], list)
363 if (!strcmp(dev_name(pos->dev), dev_name(dev)))
364 goto err_unlock;
365 }
366
359 rc = device_add(dev); 367 rc = device_add(dev);
360 if (rc) 368 if (rc)
361 goto err_device; 369 goto err_unlock;
362 370
363 /* register cdev */ 371 /* register cdev */
364 rc = -ENOMEM; 372 rc = -ENOMEM;
365 cdev = cdev_alloc(); 373 cdev = cdev_alloc();
366 if (!cdev) 374 if (!cdev)
367 goto err_device; 375 goto err_unlock;
368 376
369 cdev->owner = THIS_MODULE; 377 cdev->owner = THIS_MODULE;
370 cdev->ops = &cuse_frontend_fops; 378 cdev->ops = &cuse_frontend_fops;
@@ -377,9 +385,8 @@ static void cuse_process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
377 cc->cdev = cdev; 385 cc->cdev = cdev;
378 386
379 /* make the device available */ 387 /* make the device available */
380 spin_lock(&cuse_lock);
381 list_add(&cc->list, cuse_conntbl_head(devt)); 388 list_add(&cc->list, cuse_conntbl_head(devt));
382 spin_unlock(&cuse_lock); 389 mutex_unlock(&cuse_lock);
383 390
384 /* announce device availability */ 391 /* announce device availability */
385 dev_set_uevent_suppress(dev, 0); 392 dev_set_uevent_suppress(dev, 0);
@@ -391,7 +398,8 @@ out:
391 398
392err_cdev: 399err_cdev:
393 cdev_del(cdev); 400 cdev_del(cdev);
394err_device: 401err_unlock:
402 mutex_unlock(&cuse_lock);
395 put_device(dev); 403 put_device(dev);
396err_region: 404err_region:
397 unregister_chrdev_region(devt, 1); 405 unregister_chrdev_region(devt, 1);
@@ -520,9 +528,9 @@ static int cuse_channel_release(struct inode *inode, struct file *file)
520 int rc; 528 int rc;
521 529
522 /* remove from the conntbl, no more access from this point on */ 530 /* remove from the conntbl, no more access from this point on */
523 spin_lock(&cuse_lock); 531 mutex_lock(&cuse_lock);
524 list_del_init(&cc->list); 532 list_del_init(&cc->list);
525 spin_unlock(&cuse_lock); 533 mutex_unlock(&cuse_lock);
526 534
527 /* remove device */ 535 /* remove device */
528 if (cc->dev) 536 if (cc->dev)
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index c16335315e5d..e83351aa5bad 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -692,8 +692,6 @@ static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep)
692 struct page *oldpage = *pagep; 692 struct page *oldpage = *pagep;
693 struct page *newpage; 693 struct page *newpage;
694 struct pipe_buffer *buf = cs->pipebufs; 694 struct pipe_buffer *buf = cs->pipebufs;
695 struct address_space *mapping;
696 pgoff_t index;
697 695
698 unlock_request(cs->fc, cs->req); 696 unlock_request(cs->fc, cs->req);
699 fuse_copy_finish(cs); 697 fuse_copy_finish(cs);
@@ -724,9 +722,6 @@ static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep)
724 if (fuse_check_page(newpage) != 0) 722 if (fuse_check_page(newpage) != 0)
725 goto out_fallback_unlock; 723 goto out_fallback_unlock;
726 724
727 mapping = oldpage->mapping;
728 index = oldpage->index;
729
730 /* 725 /*
731 * This is a new and locked page, it shouldn't be mapped or 726 * This is a new and locked page, it shouldn't be mapped or
732 * have any special flags on it 727 * have any special flags on it
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index e21d4d8f87e3..f3ab824fa302 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -2177,8 +2177,8 @@ fuse_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
2177 return ret; 2177 return ret;
2178} 2178}
2179 2179
2180long fuse_file_fallocate(struct file *file, int mode, loff_t offset, 2180static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
2181 loff_t length) 2181 loff_t length)
2182{ 2182{
2183 struct fuse_file *ff = file->private_data; 2183 struct fuse_file *ff = file->private_data;
2184 struct fuse_conn *fc = ff->fc; 2184 struct fuse_conn *fc = ff->fc;
@@ -2213,7 +2213,6 @@ long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
2213 2213
2214 return err; 2214 return err;
2215} 2215}
2216EXPORT_SYMBOL_GPL(fuse_file_fallocate);
2217 2216
2218static const struct file_operations fuse_file_operations = { 2217static const struct file_operations fuse_file_operations = {
2219 .llseek = fuse_file_llseek, 2218 .llseek = fuse_file_llseek,