aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/core
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/core
parent2f99cc6e4688faf5f03f9afe5e1c6097278c75b2 (diff)
switch infiniband uverbs to anon_inodes
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'drivers/infiniband/core')
-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
3 files changed, 28 insertions, 81 deletions
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);