Commit b1e4594b authored by Al Viro's avatar Al Viro

switch infiniband uverbs to anon_inodes

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 2f99cc6e
...@@ -20,6 +20,7 @@ config INFINIBAND_USER_MAD ...@@ -20,6 +20,7 @@ config INFINIBAND_USER_MAD
config INFINIBAND_USER_ACCESS config INFINIBAND_USER_ACCESS
tristate "InfiniBand userspace access (verbs and CM)" tristate "InfiniBand userspace access (verbs and CM)"
select ANON_INODES
---help--- ---help---
Userspace InfiniBand access support. This enables the Userspace InfiniBand access support. This enables the
kernel side of userspace verbs and the userspace kernel side of userspace verbs and the userspace
......
...@@ -145,7 +145,7 @@ extern struct idr ib_uverbs_srq_idr; ...@@ -145,7 +145,7 @@ extern struct idr ib_uverbs_srq_idr;
void idr_remove_uobj(struct idr *idp, struct ib_uobject *uobj); void idr_remove_uobj(struct idr *idp, struct ib_uobject *uobj);
struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file, struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file,
int is_async, int *fd); int is_async);
struct ib_uverbs_event_file *ib_uverbs_lookup_comp_file(int fd); struct ib_uverbs_event_file *ib_uverbs_lookup_comp_file(int fd);
void ib_uverbs_release_ucq(struct ib_uverbs_file *file, void ib_uverbs_release_ucq(struct ib_uverbs_file *file,
......
...@@ -301,10 +301,15 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file, ...@@ -301,10 +301,15 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
resp.num_comp_vectors = file->device->num_comp_vectors; resp.num_comp_vectors = file->device->num_comp_vectors;
filp = ib_uverbs_alloc_event_file(file, 1, &resp.async_fd); ret = get_unused_fd();
if (ret < 0)
goto err_free;
resp.async_fd = ret;
filp = ib_uverbs_alloc_event_file(file, 1);
if (IS_ERR(filp)) { if (IS_ERR(filp)) {
ret = PTR_ERR(filp); ret = PTR_ERR(filp);
goto err_free; goto err_fd;
} }
if (copy_to_user((void __user *) (unsigned long) cmd.response, 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,9 +337,11 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
return in_len; return in_len;
err_file: err_file:
put_unused_fd(resp.async_fd);
fput(filp); fput(filp);
err_fd:
put_unused_fd(resp.async_fd);
err_free: err_free:
ibdev->dealloc_ucontext(ucontext); ibdev->dealloc_ucontext(ucontext);
...@@ -715,6 +722,7 @@ ssize_t ib_uverbs_create_comp_channel(struct ib_uverbs_file *file, ...@@ -715,6 +722,7 @@ ssize_t ib_uverbs_create_comp_channel(struct ib_uverbs_file *file,
struct ib_uverbs_create_comp_channel cmd; struct ib_uverbs_create_comp_channel cmd;
struct ib_uverbs_create_comp_channel_resp resp; struct ib_uverbs_create_comp_channel_resp resp;
struct file *filp; struct file *filp;
int ret;
if (out_len < sizeof resp) if (out_len < sizeof resp)
return -ENOSPC; return -ENOSPC;
...@@ -722,9 +730,16 @@ ssize_t ib_uverbs_create_comp_channel(struct ib_uverbs_file *file, ...@@ -722,9 +730,16 @@ ssize_t ib_uverbs_create_comp_channel(struct ib_uverbs_file *file,
if (copy_from_user(&cmd, buf, sizeof cmd)) if (copy_from_user(&cmd, buf, sizeof cmd))
return -EFAULT; return -EFAULT;
filp = ib_uverbs_alloc_event_file(file, 0, &resp.fd); ret = get_unused_fd();
if (IS_ERR(filp)) if (ret < 0)
return ret;
resp.fd = ret;
filp = ib_uverbs_alloc_event_file(file, 0);
if (IS_ERR(filp)) {
put_unused_fd(resp.fd);
return PTR_ERR(filp); return PTR_ERR(filp);
}
if (copy_to_user((void __user *) (unsigned long) cmd.response, if (copy_to_user((void __user *) (unsigned long) cmd.response,
&resp, sizeof resp)) { &resp, sizeof resp)) {
......
...@@ -41,8 +41,8 @@ ...@@ -41,8 +41,8 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/poll.h> #include <linux/poll.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/anon_inodes.h>
#include <linux/file.h> #include <linux/file.h>
#include <linux/mount.h>
#include <linux/cdev.h> #include <linux/cdev.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -53,8 +53,6 @@ MODULE_AUTHOR("Roland Dreier"); ...@@ -53,8 +53,6 @@ MODULE_AUTHOR("Roland Dreier");
MODULE_DESCRIPTION("InfiniBand userspace verbs access"); MODULE_DESCRIPTION("InfiniBand userspace verbs access");
MODULE_LICENSE("Dual BSD/GPL"); MODULE_LICENSE("Dual BSD/GPL");
#define INFINIBANDEVENTFS_MAGIC 0x49426576 /* "IBev" */
enum { enum {
IB_UVERBS_MAJOR = 231, IB_UVERBS_MAJOR = 231,
IB_UVERBS_BASE_MINOR = 192, IB_UVERBS_BASE_MINOR = 192,
...@@ -111,8 +109,6 @@ static ssize_t (*uverbs_cmd_table[])(struct ib_uverbs_file *file, ...@@ -111,8 +109,6 @@ static ssize_t (*uverbs_cmd_table[])(struct ib_uverbs_file *file,
[IB_USER_VERBS_CMD_DESTROY_SRQ] = ib_uverbs_destroy_srq, [IB_USER_VERBS_CMD_DESTROY_SRQ] = ib_uverbs_destroy_srq,
}; };
static struct vfsmount *uverbs_event_mnt;
static void ib_uverbs_add_one(struct ib_device *device); static void ib_uverbs_add_one(struct ib_device *device);
static void ib_uverbs_remove_one(struct ib_device *device); static void ib_uverbs_remove_one(struct ib_device *device);
...@@ -489,12 +485,10 @@ void ib_uverbs_event_handler(struct ib_event_handler *handler, ...@@ -489,12 +485,10 @@ void ib_uverbs_event_handler(struct ib_event_handler *handler,
} }
struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file, struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file,
int is_async, int *fd) int is_async)
{ {
struct ib_uverbs_event_file *ev_file; struct ib_uverbs_event_file *ev_file;
struct path path;
struct file *filp; struct file *filp;
int ret;
ev_file = kmalloc(sizeof *ev_file, GFP_KERNEL); ev_file = kmalloc(sizeof *ev_file, GFP_KERNEL);
if (!ev_file) if (!ev_file)
...@@ -509,38 +503,12 @@ struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file, ...@@ -509,38 +503,12 @@ struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file,
ev_file->is_async = is_async; ev_file->is_async = is_async;
ev_file->is_closed = 0; ev_file->is_closed = 0;
*fd = get_unused_fd(); filp = anon_inode_getfile("[infinibandevent]", &uverbs_event_fops,
if (*fd < 0) { ev_file, O_RDONLY);
ret = *fd; if (IS_ERR(filp))
goto err; kfree(ev_file);
}
/*
* fops_get() can't fail here, because we're coming from a
* system call on a uverbs file, which will already have a
* module reference.
*/
path.mnt = uverbs_event_mnt;
path.dentry = uverbs_event_mnt->mnt_root;
path_get(&path);
filp = alloc_file(&path, FMODE_READ, fops_get(&uverbs_event_fops));
if (!filp) {
ret = -ENFILE;
goto err_fd;
}
filp->private_data = ev_file;
return filp; return filp;
err_fd:
fops_put(&uverbs_event_fops);
path_put(&path);
put_unused_fd(*fd);
err:
kfree(ev_file);
return ERR_PTR(ret);
} }
/* /*
...@@ -825,21 +793,6 @@ static void ib_uverbs_remove_one(struct ib_device *device) ...@@ -825,21 +793,6 @@ static void ib_uverbs_remove_one(struct ib_device *device)
kfree(uverbs_dev); kfree(uverbs_dev);
} }
static int uverbs_event_get_sb(struct file_system_type *fs_type, int flags,
const char *dev_name, void *data,
struct vfsmount *mnt)
{
return get_sb_pseudo(fs_type, "infinibandevent:", NULL,
INFINIBANDEVENTFS_MAGIC, mnt);
}
static struct file_system_type uverbs_event_fs = {
/* No owner field so module can be unloaded */
.name = "infinibandeventfs",
.get_sb = uverbs_event_get_sb,
.kill_sb = kill_litter_super
};
static int __init ib_uverbs_init(void) static int __init ib_uverbs_init(void)
{ {
int ret; int ret;
...@@ -864,33 +817,14 @@ static int __init ib_uverbs_init(void) ...@@ -864,33 +817,14 @@ static int __init ib_uverbs_init(void)
goto out_class; goto out_class;
} }
ret = register_filesystem(&uverbs_event_fs);
if (ret) {
printk(KERN_ERR "user_verbs: couldn't register infinibandeventfs\n");
goto out_class;
}
uverbs_event_mnt = kern_mount(&uverbs_event_fs);
if (IS_ERR(uverbs_event_mnt)) {
ret = PTR_ERR(uverbs_event_mnt);
printk(KERN_ERR "user_verbs: couldn't mount infinibandeventfs\n");
goto out_fs;
}
ret = ib_register_client(&uverbs_client); ret = ib_register_client(&uverbs_client);
if (ret) { if (ret) {
printk(KERN_ERR "user_verbs: couldn't register client\n"); printk(KERN_ERR "user_verbs: couldn't register client\n");
goto out_mnt; goto out_class;
} }
return 0; return 0;
out_mnt:
mntput(uverbs_event_mnt);
out_fs:
unregister_filesystem(&uverbs_event_fs);
out_class: out_class:
class_destroy(uverbs_class); class_destroy(uverbs_class);
...@@ -904,8 +838,6 @@ static int __init ib_uverbs_init(void) ...@@ -904,8 +838,6 @@ static int __init ib_uverbs_init(void)
static void __exit ib_uverbs_cleanup(void) static void __exit ib_uverbs_cleanup(void)
{ {
ib_unregister_client(&uverbs_client); ib_unregister_client(&uverbs_client);
mntput(uverbs_event_mnt);
unregister_filesystem(&uverbs_event_fs);
class_destroy(uverbs_class); class_destroy(uverbs_class);
unregister_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES); unregister_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES);
idr_destroy(&ib_uverbs_pd_idr); idr_destroy(&ib_uverbs_pd_idr);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment