aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2010-01-18 01:38:00 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2010-03-03 14:07:27 -0500
commitb1e4594ba097634e9436cc4c6ba95f70a2d627ff (patch)
tree7f0c40f88ee5bb99b44ead19d5b0b049e27b8063 /drivers/infiniband
parent2f99cc6e4688faf5f03f9afe5e1c6097278c75b2 (diff)
switch infiniband uverbs to anon_inodes
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/Kconfig1
-rw-r--r--drivers/infiniband/core/uverbs.h2
-rw-r--r--drivers/infiniband/core/uverbs_cmd.c25
-rw-r--r--drivers/infiniband/core/uverbs_main.c82
4 files changed, 29 insertions, 81 deletions
diff --git a/drivers/infiniband/Kconfig b/drivers/infiniband/Kconfig
index dd0db67bf8d7..975adce5f40c 100644
--- a/drivers/infiniband/Kconfig
+++ b/drivers/infiniband/Kconfig
@@ -20,6 +20,7 @@ config INFINIBAND_USER_MAD
20 20
21config INFINIBAND_USER_ACCESS 21config INFINIBAND_USER_ACCESS
22 tristate "InfiniBand userspace access (verbs and CM)" 22 tristate "InfiniBand userspace access (verbs and CM)"
23 select ANON_INODES
23 ---help--- 24 ---help---
24 Userspace InfiniBand access support. This enables the 25 Userspace InfiniBand access support. This enables the
25 kernel side of userspace verbs and the userspace 26 kernel side of userspace verbs and the userspace
diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h
index b3ea9587dc80..0b3862080c0f 100644
--- a/drivers/infiniband/core/uverbs.h
+++ b/drivers/infiniband/core/uverbs.h
@@ -145,7 +145,7 @@ extern struct idr ib_uverbs_srq_idr;
145void idr_remove_uobj(struct idr *idp, struct ib_uobject *uobj); 145void idr_remove_uobj(struct idr *idp, struct ib_uobject *uobj);
146 146
147struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file, 147struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file,
148 int is_async, int *fd); 148 int is_async);
149struct ib_uverbs_event_file *ib_uverbs_lookup_comp_file(int fd); 149struct ib_uverbs_event_file *ib_uverbs_lookup_comp_file(int fd);
150 150
151void ib_uverbs_release_ucq(struct ib_uverbs_file *file, 151void ib_uverbs_release_ucq(struct ib_uverbs_file *file,
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index 112d3970222a..f71cf138d674 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -301,10 +301,15 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
301 301
302 resp.num_comp_vectors = file->device->num_comp_vectors; 302 resp.num_comp_vectors = file->device->num_comp_vectors;
303 303
304 filp = ib_uverbs_alloc_event_file(file, 1, &resp.async_fd); 304 ret = get_unused_fd();
305 if (ret < 0)
306 goto err_free;
307 resp.async_fd = ret;
308
309 filp = ib_uverbs_alloc_event_file(file, 1);
305 if (IS_ERR(filp)) { 310 if (IS_ERR(filp)) {
306 ret = PTR_ERR(filp); 311 ret = PTR_ERR(filp);
307 goto err_free; 312 goto err_fd;
308 } 313 }
309 314
310 if (copy_to_user((void __user *) (unsigned long) cmd.response, 315 if (copy_to_user((void __user *) (unsigned long) cmd.response,
@@ -332,9 +337,11 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
332 return in_len; 337 return in_len;
333 338
334err_file: 339err_file:
335 put_unused_fd(resp.async_fd);
336 fput(filp); 340 fput(filp);
337 341
342err_fd:
343 put_unused_fd(resp.async_fd);
344
338err_free: 345err_free:
339 ibdev->dealloc_ucontext(ucontext); 346 ibdev->dealloc_ucontext(ucontext);
340 347
@@ -715,6 +722,7 @@ ssize_t ib_uverbs_create_comp_channel(struct ib_uverbs_file *file,
715 struct ib_uverbs_create_comp_channel cmd; 722 struct ib_uverbs_create_comp_channel cmd;
716 struct ib_uverbs_create_comp_channel_resp resp; 723 struct ib_uverbs_create_comp_channel_resp resp;
717 struct file *filp; 724 struct file *filp;
725 int ret;
718 726
719 if (out_len < sizeof resp) 727 if (out_len < sizeof resp)
720 return -ENOSPC; 728 return -ENOSPC;
@@ -722,9 +730,16 @@ ssize_t ib_uverbs_create_comp_channel(struct ib_uverbs_file *file,
722 if (copy_from_user(&cmd, buf, sizeof cmd)) 730 if (copy_from_user(&cmd, buf, sizeof cmd))
723 return -EFAULT; 731 return -EFAULT;
724 732
725 filp = ib_uverbs_alloc_event_file(file, 0, &resp.fd); 733 ret = get_unused_fd();
726 if (IS_ERR(filp)) 734 if (ret < 0)
735 return ret;
736 resp.fd = ret;
737
738 filp = ib_uverbs_alloc_event_file(file, 0);
739 if (IS_ERR(filp)) {
740 put_unused_fd(resp.fd);
727 return PTR_ERR(filp); 741 return PTR_ERR(filp);
742 }
728 743
729 if (copy_to_user((void __user *) (unsigned long) cmd.response, 744 if (copy_to_user((void __user *) (unsigned long) cmd.response,
730 &resp, sizeof resp)) { 745 &resp, sizeof resp)) {
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index 5f284ffd430e..810f277739e2 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -41,8 +41,8 @@
41#include <linux/fs.h> 41#include <linux/fs.h>
42#include <linux/poll.h> 42#include <linux/poll.h>
43#include <linux/sched.h> 43#include <linux/sched.h>
44#include <linux/anon_inodes.h>
44#include <linux/file.h> 45#include <linux/file.h>
45#include <linux/mount.h>
46#include <linux/cdev.h> 46#include <linux/cdev.h>
47 47
48#include <asm/uaccess.h> 48#include <asm/uaccess.h>
@@ -53,8 +53,6 @@ MODULE_AUTHOR("Roland Dreier");
53MODULE_DESCRIPTION("InfiniBand userspace verbs access"); 53MODULE_DESCRIPTION("InfiniBand userspace verbs access");
54MODULE_LICENSE("Dual BSD/GPL"); 54MODULE_LICENSE("Dual BSD/GPL");
55 55
56#define INFINIBANDEVENTFS_MAGIC 0x49426576 /* "IBev" */
57
58enum { 56enum {
59 IB_UVERBS_MAJOR = 231, 57 IB_UVERBS_MAJOR = 231,
60 IB_UVERBS_BASE_MINOR = 192, 58 IB_UVERBS_BASE_MINOR = 192,
@@ -111,8 +109,6 @@ static ssize_t (*uverbs_cmd_table[])(struct ib_uverbs_file *file,
111 [IB_USER_VERBS_CMD_DESTROY_SRQ] = ib_uverbs_destroy_srq, 109 [IB_USER_VERBS_CMD_DESTROY_SRQ] = ib_uverbs_destroy_srq,
112}; 110};
113 111
114static struct vfsmount *uverbs_event_mnt;
115
116static void ib_uverbs_add_one(struct ib_device *device); 112static void ib_uverbs_add_one(struct ib_device *device);
117static void ib_uverbs_remove_one(struct ib_device *device); 113static void ib_uverbs_remove_one(struct ib_device *device);
118 114
@@ -489,12 +485,10 @@ void ib_uverbs_event_handler(struct ib_event_handler *handler,
489} 485}
490 486
491struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file, 487struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file,
492 int is_async, int *fd) 488 int is_async)
493{ 489{
494 struct ib_uverbs_event_file *ev_file; 490 struct ib_uverbs_event_file *ev_file;
495 struct path path;
496 struct file *filp; 491 struct file *filp;
497 int ret;
498 492
499 ev_file = kmalloc(sizeof *ev_file, GFP_KERNEL); 493 ev_file = kmalloc(sizeof *ev_file, GFP_KERNEL);
500 if (!ev_file) 494 if (!ev_file)
@@ -509,38 +503,12 @@ struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file,
509 ev_file->is_async = is_async; 503 ev_file->is_async = is_async;
510 ev_file->is_closed = 0; 504 ev_file->is_closed = 0;
511 505
512 *fd = get_unused_fd(); 506 filp = anon_inode_getfile("[infinibandevent]", &uverbs_event_fops,
513 if (*fd < 0) { 507 ev_file, O_RDONLY);
514 ret = *fd; 508 if (IS_ERR(filp))
515 goto err; 509 kfree(ev_file);
516 }
517
518 /*
519 * fops_get() can't fail here, because we're coming from a
520 * system call on a uverbs file, which will already have a
521 * module reference.
522 */
523 path.mnt = uverbs_event_mnt;
524 path.dentry = uverbs_event_mnt->mnt_root;
525 path_get(&path);
526 filp = alloc_file(&path, FMODE_READ, fops_get(&uverbs_event_fops));
527 if (!filp) {
528 ret = -ENFILE;
529 goto err_fd;
530 }
531
532 filp->private_data = ev_file;
533 510
534 return filp; 511 return filp;
535
536err_fd:
537 fops_put(&uverbs_event_fops);
538 path_put(&path);
539 put_unused_fd(*fd);
540
541err:
542 kfree(ev_file);
543 return ERR_PTR(ret);
544} 512}
545 513
546/* 514/*
@@ -825,21 +793,6 @@ static void ib_uverbs_remove_one(struct ib_device *device)
825 kfree(uverbs_dev); 793 kfree(uverbs_dev);
826} 794}
827 795
828static int uverbs_event_get_sb(struct file_system_type *fs_type, int flags,
829 const char *dev_name, void *data,
830 struct vfsmount *mnt)
831{
832 return get_sb_pseudo(fs_type, "infinibandevent:", NULL,
833 INFINIBANDEVENTFS_MAGIC, mnt);
834}
835
836static struct file_system_type uverbs_event_fs = {
837 /* No owner field so module can be unloaded */
838 .name = "infinibandeventfs",
839 .get_sb = uverbs_event_get_sb,
840 .kill_sb = kill_litter_super
841};
842
843static int __init ib_uverbs_init(void) 796static int __init ib_uverbs_init(void)
844{ 797{
845 int ret; 798 int ret;
@@ -864,33 +817,14 @@ static int __init ib_uverbs_init(void)
864 goto out_class; 817 goto out_class;
865 } 818 }
866 819
867 ret = register_filesystem(&uverbs_event_fs);
868 if (ret) {
869 printk(KERN_ERR "user_verbs: couldn't register infinibandeventfs\n");
870 goto out_class;
871 }
872
873 uverbs_event_mnt = kern_mount(&uverbs_event_fs);
874 if (IS_ERR(uverbs_event_mnt)) {
875 ret = PTR_ERR(uverbs_event_mnt);
876 printk(KERN_ERR "user_verbs: couldn't mount infinibandeventfs\n");
877 goto out_fs;
878 }
879
880 ret = ib_register_client(&uverbs_client); 820 ret = ib_register_client(&uverbs_client);
881 if (ret) { 821 if (ret) {
882 printk(KERN_ERR "user_verbs: couldn't register client\n"); 822 printk(KERN_ERR "user_verbs: couldn't register client\n");
883 goto out_mnt; 823 goto out_class;
884 } 824 }
885 825
886 return 0; 826 return 0;
887 827
888out_mnt:
889 mntput(uverbs_event_mnt);
890
891out_fs:
892 unregister_filesystem(&uverbs_event_fs);
893
894out_class: 828out_class:
895 class_destroy(uverbs_class); 829 class_destroy(uverbs_class);
896 830
@@ -904,8 +838,6 @@ out:
904static void __exit ib_uverbs_cleanup(void) 838static void __exit ib_uverbs_cleanup(void)
905{ 839{
906 ib_unregister_client(&uverbs_client); 840 ib_unregister_client(&uverbs_client);
907 mntput(uverbs_event_mnt);
908 unregister_filesystem(&uverbs_event_fs);
909 class_destroy(uverbs_class); 841 class_destroy(uverbs_class);
910 unregister_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES); 842 unregister_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES);
911 idr_destroy(&ib_uverbs_pd_idr); 843 idr_destroy(&ib_uverbs_pd_idr);