aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse
diff options
context:
space:
mode:
Diffstat (limited to 'fs/fuse')
-rw-r--r--fs/fuse/dev.c4
-rw-r--r--fs/fuse/dir.c5
-rw-r--r--fs/fuse/file.c37
-rw-r--r--fs/fuse/fuse_i.h9
-rw-r--r--fs/fuse/inode.c123
5 files changed, 155 insertions, 23 deletions
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 66571eafbb1e..357764d85ff1 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -19,7 +19,7 @@
19 19
20MODULE_ALIAS_MISCDEV(FUSE_MINOR); 20MODULE_ALIAS_MISCDEV(FUSE_MINOR);
21 21
22static kmem_cache_t *fuse_req_cachep; 22static struct kmem_cache *fuse_req_cachep;
23 23
24static struct fuse_conn *fuse_get_conn(struct file *file) 24static struct fuse_conn *fuse_get_conn(struct file *file)
25{ 25{
@@ -41,7 +41,7 @@ static void fuse_request_init(struct fuse_req *req)
41 41
42struct fuse_req *fuse_request_alloc(void) 42struct fuse_req *fuse_request_alloc(void)
43{ 43{
44 struct fuse_req *req = kmem_cache_alloc(fuse_req_cachep, SLAB_KERNEL); 44 struct fuse_req *req = kmem_cache_alloc(fuse_req_cachep, GFP_KERNEL);
45 if (req) 45 if (req)
46 fuse_request_init(req); 46 fuse_request_init(req);
47 return req; 47 return req;
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index c71a6c092ad9..1cabdb229adb 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -141,9 +141,6 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
141 struct fuse_req *forget_req; 141 struct fuse_req *forget_req;
142 struct dentry *parent; 142 struct dentry *parent;
143 143
144 /* Doesn't hurt to "reset" the validity timeout */
145 fuse_invalidate_entry_cache(entry);
146
147 /* For negative dentries, always do a fresh lookup */ 144 /* For negative dentries, always do a fresh lookup */
148 if (!inode) 145 if (!inode)
149 return 0; 146 return 0;
@@ -1027,6 +1024,8 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr)
1027 if (attr->ia_valid & ATTR_SIZE) { 1024 if (attr->ia_valid & ATTR_SIZE) {
1028 unsigned long limit; 1025 unsigned long limit;
1029 is_truncate = 1; 1026 is_truncate = 1;
1027 if (IS_SWAPFILE(inode))
1028 return -ETXTBSY;
1030 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; 1029 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
1031 if (limit != RLIM_INFINITY && attr->ia_size > (loff_t) limit) { 1030 if (limit != RLIM_INFINITY && attr->ia_size > (loff_t) limit) {
1032 send_sig(SIGXFSZ, current, 0); 1031 send_sig(SIGXFSZ, current, 0);
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 763a50daf1c0..128f79c40803 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -754,6 +754,42 @@ static int fuse_file_lock(struct file *file, int cmd, struct file_lock *fl)
754 return err; 754 return err;
755} 755}
756 756
757static sector_t fuse_bmap(struct address_space *mapping, sector_t block)
758{
759 struct inode *inode = mapping->host;
760 struct fuse_conn *fc = get_fuse_conn(inode);
761 struct fuse_req *req;
762 struct fuse_bmap_in inarg;
763 struct fuse_bmap_out outarg;
764 int err;
765
766 if (!inode->i_sb->s_bdev || fc->no_bmap)
767 return 0;
768
769 req = fuse_get_req(fc);
770 if (IS_ERR(req))
771 return 0;
772
773 memset(&inarg, 0, sizeof(inarg));
774 inarg.block = block;
775 inarg.blocksize = inode->i_sb->s_blocksize;
776 req->in.h.opcode = FUSE_BMAP;
777 req->in.h.nodeid = get_node_id(inode);
778 req->in.numargs = 1;
779 req->in.args[0].size = sizeof(inarg);
780 req->in.args[0].value = &inarg;
781 req->out.numargs = 1;
782 req->out.args[0].size = sizeof(outarg);
783 req->out.args[0].value = &outarg;
784 request_send(fc, req);
785 err = req->out.h.error;
786 fuse_put_request(fc, req);
787 if (err == -ENOSYS)
788 fc->no_bmap = 1;
789
790 return err ? 0 : outarg.block;
791}
792
757static const struct file_operations fuse_file_operations = { 793static const struct file_operations fuse_file_operations = {
758 .llseek = generic_file_llseek, 794 .llseek = generic_file_llseek,
759 .read = do_sync_read, 795 .read = do_sync_read,
@@ -787,6 +823,7 @@ static const struct address_space_operations fuse_file_aops = {
787 .commit_write = fuse_commit_write, 823 .commit_write = fuse_commit_write,
788 .readpages = fuse_readpages, 824 .readpages = fuse_readpages,
789 .set_page_dirty = fuse_set_page_dirty, 825 .set_page_dirty = fuse_set_page_dirty,
826 .bmap = fuse_bmap,
790}; 827};
791 828
792void fuse_init_file_inode(struct inode *inode) 829void fuse_init_file_inode(struct inode *inode)
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 91edb8932d90..b98b20de7405 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -298,6 +298,9 @@ struct fuse_conn {
298 reply, before any other request, and never cleared */ 298 reply, before any other request, and never cleared */
299 unsigned conn_error : 1; 299 unsigned conn_error : 1;
300 300
301 /** Connection successful. Only set in INIT */
302 unsigned conn_init : 1;
303
301 /** Do readpages asynchronously? Only set in INIT */ 304 /** Do readpages asynchronously? Only set in INIT */
302 unsigned async_read : 1; 305 unsigned async_read : 1;
303 306
@@ -339,6 +342,9 @@ struct fuse_conn {
339 /** Is interrupt not implemented by fs? */ 342 /** Is interrupt not implemented by fs? */
340 unsigned no_interrupt : 1; 343 unsigned no_interrupt : 1;
341 344
345 /** Is bmap not implemented by fs? */
346 unsigned no_bmap : 1;
347
342 /** The number of requests waiting for completion */ 348 /** The number of requests waiting for completion */
343 atomic_t num_waiting; 349 atomic_t num_waiting;
344 350
@@ -365,6 +371,9 @@ struct fuse_conn {
365 371
366 /** Key for lock owner ID scrambling */ 372 /** Key for lock owner ID scrambling */
367 u32 scramble_key[4]; 373 u32 scramble_key[4];
374
375 /** Reserved request for the DESTROY message */
376 struct fuse_req *destroy_req;
368}; 377};
369 378
370static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb) 379static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb)
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index fc4203570370..12450d2b320e 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -22,7 +22,7 @@ MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>");
22MODULE_DESCRIPTION("Filesystem in Userspace"); 22MODULE_DESCRIPTION("Filesystem in Userspace");
23MODULE_LICENSE("GPL"); 23MODULE_LICENSE("GPL");
24 24
25static kmem_cache_t *fuse_inode_cachep; 25static struct kmem_cache *fuse_inode_cachep;
26struct list_head fuse_conn_list; 26struct list_head fuse_conn_list;
27DEFINE_MUTEX(fuse_mutex); 27DEFINE_MUTEX(fuse_mutex);
28 28
@@ -39,6 +39,7 @@ struct fuse_mount_data {
39 unsigned group_id_present : 1; 39 unsigned group_id_present : 1;
40 unsigned flags; 40 unsigned flags;
41 unsigned max_read; 41 unsigned max_read;
42 unsigned blksize;
42}; 43};
43 44
44static struct inode *fuse_alloc_inode(struct super_block *sb) 45static struct inode *fuse_alloc_inode(struct super_block *sb)
@@ -46,7 +47,7 @@ static struct inode *fuse_alloc_inode(struct super_block *sb)
46 struct inode *inode; 47 struct inode *inode;
47 struct fuse_inode *fi; 48 struct fuse_inode *fi;
48 49
49 inode = kmem_cache_alloc(fuse_inode_cachep, SLAB_KERNEL); 50 inode = kmem_cache_alloc(fuse_inode_cachep, GFP_KERNEL);
50 if (!inode) 51 if (!inode)
51 return NULL; 52 return NULL;
52 53
@@ -205,10 +206,23 @@ static void fuse_umount_begin(struct vfsmount *vfsmnt, int flags)
205 fuse_abort_conn(get_fuse_conn_super(vfsmnt->mnt_sb)); 206 fuse_abort_conn(get_fuse_conn_super(vfsmnt->mnt_sb));
206} 207}
207 208
209static void fuse_send_destroy(struct fuse_conn *fc)
210{
211 struct fuse_req *req = fc->destroy_req;
212 if (req && fc->conn_init) {
213 fc->destroy_req = NULL;
214 req->in.h.opcode = FUSE_DESTROY;
215 req->force = 1;
216 request_send(fc, req);
217 fuse_put_request(fc, req);
218 }
219}
220
208static void fuse_put_super(struct super_block *sb) 221static void fuse_put_super(struct super_block *sb)
209{ 222{
210 struct fuse_conn *fc = get_fuse_conn_super(sb); 223 struct fuse_conn *fc = get_fuse_conn_super(sb);
211 224
225 fuse_send_destroy(fc);
212 spin_lock(&fc->lock); 226 spin_lock(&fc->lock);
213 fc->connected = 0; 227 fc->connected = 0;
214 fc->blocked = 0; 228 fc->blocked = 0;
@@ -274,6 +288,7 @@ enum {
274 OPT_DEFAULT_PERMISSIONS, 288 OPT_DEFAULT_PERMISSIONS,
275 OPT_ALLOW_OTHER, 289 OPT_ALLOW_OTHER,
276 OPT_MAX_READ, 290 OPT_MAX_READ,
291 OPT_BLKSIZE,
277 OPT_ERR 292 OPT_ERR
278}; 293};
279 294
@@ -285,14 +300,16 @@ static match_table_t tokens = {
285 {OPT_DEFAULT_PERMISSIONS, "default_permissions"}, 300 {OPT_DEFAULT_PERMISSIONS, "default_permissions"},
286 {OPT_ALLOW_OTHER, "allow_other"}, 301 {OPT_ALLOW_OTHER, "allow_other"},
287 {OPT_MAX_READ, "max_read=%u"}, 302 {OPT_MAX_READ, "max_read=%u"},
303 {OPT_BLKSIZE, "blksize=%u"},
288 {OPT_ERR, NULL} 304 {OPT_ERR, NULL}
289}; 305};
290 306
291static int parse_fuse_opt(char *opt, struct fuse_mount_data *d) 307static int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev)
292{ 308{
293 char *p; 309 char *p;
294 memset(d, 0, sizeof(struct fuse_mount_data)); 310 memset(d, 0, sizeof(struct fuse_mount_data));
295 d->max_read = ~0; 311 d->max_read = ~0;
312 d->blksize = 512;
296 313
297 while ((p = strsep(&opt, ",")) != NULL) { 314 while ((p = strsep(&opt, ",")) != NULL) {
298 int token; 315 int token;
@@ -345,6 +362,12 @@ static int parse_fuse_opt(char *opt, struct fuse_mount_data *d)
345 d->max_read = value; 362 d->max_read = value;
346 break; 363 break;
347 364
365 case OPT_BLKSIZE:
366 if (!is_bdev || match_int(&args[0], &value))
367 return 0;
368 d->blksize = value;
369 break;
370
348 default: 371 default:
349 return 0; 372 return 0;
350 } 373 }
@@ -400,6 +423,8 @@ static struct fuse_conn *new_conn(void)
400void fuse_conn_put(struct fuse_conn *fc) 423void fuse_conn_put(struct fuse_conn *fc)
401{ 424{
402 if (atomic_dec_and_test(&fc->count)) { 425 if (atomic_dec_and_test(&fc->count)) {
426 if (fc->destroy_req)
427 fuse_request_free(fc->destroy_req);
403 mutex_destroy(&fc->inst_mutex); 428 mutex_destroy(&fc->inst_mutex);
404 kfree(fc); 429 kfree(fc);
405 } 430 }
@@ -456,6 +481,7 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
456 fc->bdi.ra_pages = min(fc->bdi.ra_pages, ra_pages); 481 fc->bdi.ra_pages = min(fc->bdi.ra_pages, ra_pages);
457 fc->minor = arg->minor; 482 fc->minor = arg->minor;
458 fc->max_write = arg->minor < 5 ? 4096 : arg->max_write; 483 fc->max_write = arg->minor < 5 ? 4096 : arg->max_write;
484 fc->conn_init = 1;
459 } 485 }
460 fuse_put_request(fc, req); 486 fuse_put_request(fc, req);
461 fc->blocked = 0; 487 fc->blocked = 0;
@@ -500,15 +526,23 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
500 struct dentry *root_dentry; 526 struct dentry *root_dentry;
501 struct fuse_req *init_req; 527 struct fuse_req *init_req;
502 int err; 528 int err;
529 int is_bdev = sb->s_bdev != NULL;
503 530
504 if (sb->s_flags & MS_MANDLOCK) 531 if (sb->s_flags & MS_MANDLOCK)
505 return -EINVAL; 532 return -EINVAL;
506 533
507 if (!parse_fuse_opt((char *) data, &d)) 534 if (!parse_fuse_opt((char *) data, &d, is_bdev))
508 return -EINVAL; 535 return -EINVAL;
509 536
510 sb->s_blocksize = PAGE_CACHE_SIZE; 537 if (is_bdev) {
511 sb->s_blocksize_bits = PAGE_CACHE_SHIFT; 538#ifdef CONFIG_BLOCK
539 if (!sb_set_blocksize(sb, d.blksize))
540 return -EINVAL;
541#endif
542 } else {
543 sb->s_blocksize = PAGE_CACHE_SIZE;
544 sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
545 }
512 sb->s_magic = FUSE_SUPER_MAGIC; 546 sb->s_magic = FUSE_SUPER_MAGIC;
513 sb->s_op = &fuse_super_operations; 547 sb->s_op = &fuse_super_operations;
514 sb->s_maxbytes = MAX_LFS_FILESIZE; 548 sb->s_maxbytes = MAX_LFS_FILESIZE;
@@ -547,6 +581,12 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
547 if (!init_req) 581 if (!init_req)
548 goto err_put_root; 582 goto err_put_root;
549 583
584 if (is_bdev) {
585 fc->destroy_req = fuse_request_alloc();
586 if (!fc->destroy_req)
587 goto err_put_root;
588 }
589
550 mutex_lock(&fuse_mutex); 590 mutex_lock(&fuse_mutex);
551 err = -EINVAL; 591 err = -EINVAL;
552 if (file->private_data) 592 if (file->private_data)
@@ -598,10 +638,47 @@ static struct file_system_type fuse_fs_type = {
598 .kill_sb = kill_anon_super, 638 .kill_sb = kill_anon_super,
599}; 639};
600 640
641#ifdef CONFIG_BLOCK
642static int fuse_get_sb_blk(struct file_system_type *fs_type,
643 int flags, const char *dev_name,
644 void *raw_data, struct vfsmount *mnt)
645{
646 return get_sb_bdev(fs_type, flags, dev_name, raw_data, fuse_fill_super,
647 mnt);
648}
649
650static struct file_system_type fuseblk_fs_type = {
651 .owner = THIS_MODULE,
652 .name = "fuseblk",
653 .get_sb = fuse_get_sb_blk,
654 .kill_sb = kill_block_super,
655 .fs_flags = FS_REQUIRES_DEV,
656};
657
658static inline int register_fuseblk(void)
659{
660 return register_filesystem(&fuseblk_fs_type);
661}
662
663static inline void unregister_fuseblk(void)
664{
665 unregister_filesystem(&fuseblk_fs_type);
666}
667#else
668static inline int register_fuseblk(void)
669{
670 return 0;
671}
672
673static inline void unregister_fuseblk(void)
674{
675}
676#endif
677
601static decl_subsys(fuse, NULL, NULL); 678static decl_subsys(fuse, NULL, NULL);
602static decl_subsys(connections, NULL, NULL); 679static decl_subsys(connections, NULL, NULL);
603 680
604static void fuse_inode_init_once(void *foo, kmem_cache_t *cachep, 681static void fuse_inode_init_once(void *foo, struct kmem_cache *cachep,
605 unsigned long flags) 682 unsigned long flags)
606{ 683{
607 struct inode * inode = foo; 684 struct inode * inode = foo;
@@ -617,24 +694,34 @@ static int __init fuse_fs_init(void)
617 694
618 err = register_filesystem(&fuse_fs_type); 695 err = register_filesystem(&fuse_fs_type);
619 if (err) 696 if (err)
620 printk("fuse: failed to register filesystem\n"); 697 goto out;
621 else {
622 fuse_inode_cachep = kmem_cache_create("fuse_inode",
623 sizeof(struct fuse_inode),
624 0, SLAB_HWCACHE_ALIGN,
625 fuse_inode_init_once, NULL);
626 if (!fuse_inode_cachep) {
627 unregister_filesystem(&fuse_fs_type);
628 err = -ENOMEM;
629 }
630 }
631 698
699 err = register_fuseblk();
700 if (err)
701 goto out_unreg;
702
703 fuse_inode_cachep = kmem_cache_create("fuse_inode",
704 sizeof(struct fuse_inode),
705 0, SLAB_HWCACHE_ALIGN,
706 fuse_inode_init_once, NULL);
707 err = -ENOMEM;
708 if (!fuse_inode_cachep)
709 goto out_unreg2;
710
711 return 0;
712
713 out_unreg2:
714 unregister_fuseblk();
715 out_unreg:
716 unregister_filesystem(&fuse_fs_type);
717 out:
632 return err; 718 return err;
633} 719}
634 720
635static void fuse_fs_cleanup(void) 721static void fuse_fs_cleanup(void)
636{ 722{
637 unregister_filesystem(&fuse_fs_type); 723 unregister_filesystem(&fuse_fs_type);
724 unregister_fuseblk();
638 kmem_cache_destroy(fuse_inode_cachep); 725 kmem_cache_destroy(fuse_inode_cachep);
639} 726}
640 727