RDMA/core: Align abort/commit object scheme for write() and ioctl() paths

Create the same logic flow for the write() interface as we have for the
ioctl() path by making sure that the object is committed or aborted
automatically after HW object creation.

Link: https://lore.kernel.org/r/20200719052223.75245-2-leon@kernel.org
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
This commit is contained in:
Leon Romanovsky 2020-07-19 08:22:22 +03:00 committed by Jason Gunthorpe
parent c94e272b57
commit 0f63ef1dd5
4 changed files with 25 additions and 1 deletions

View File

@ -601,6 +601,7 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
memset(bundle.attr_present, 0, sizeof(bundle.attr_present));
bundle.ufile = file;
bundle.context = NULL; /* only valid if bundle has uobject */
bundle.uobject = NULL;
if (!method_elm->is_ex) {
size_t in_len = hdr.in_words * 4 - sizeof(hdr);
size_t out_len = hdr.out_words * 4;
@ -664,6 +665,9 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
}
ret = method_elm->handler(&bundle);
if (bundle.uobject)
uverbs_finalize_object(bundle.uobject, UVERBS_ACCESS_NEW, true,
!ret, &bundle);
out_unlock:
srcu_read_unlock(&file->device->disassociate_srcu, srcu_key);
return (ret) ? : count;

View File

@ -38,7 +38,12 @@ static int UVERBS_HANDLER(UVERBS_METHOD_INVOKE_WRITE)(
attrs->ucore.outlen < method_elm->resp_size)
return -ENOSPC;
return method_elm->handler(attrs);
attrs->uobject = NULL;
rc = method_elm->handler(attrs);
if (attrs->uobject)
uverbs_finalize_object(attrs->uobject, UVERBS_ACCESS_NEW, true,
!rc, attrs);
return rc;
}
DECLARE_UVERBS_NAMED_METHOD(UVERBS_METHOD_INVOKE_WRITE,

View File

@ -652,6 +652,7 @@ struct uverbs_attr_bundle {
struct ib_udata ucore;
struct ib_uverbs_file *ufile;
struct ib_ucontext *context;
struct ib_uobject *uobject;
DECLARE_BITMAP(attr_present, UVERBS_API_ATTR_BKEY_LEN);
struct uverbs_attr attrs[];
};

View File

@ -110,6 +110,20 @@ static inline void uobj_alloc_abort(struct ib_uobject *uobj,
rdma_alloc_abort_uobject(uobj, attrs, false);
}
static inline void uobj_finalize_uobj_create(struct ib_uobject *uobj,
struct uverbs_attr_bundle *attrs)
{
/*
* Tell the core code that the write() handler has completed
* initializing the object and that the core should commit or
* abort this object based upon the return code from the write()
* method. Similar to what uverbs_finalize_uobj_create() does for
* ioctl()
*/
WARN_ON(attrs->uobject);
attrs->uobject = uobj;
}
static inline struct ib_uobject *
__uobj_alloc(const struct uverbs_api_object *obj,
struct uverbs_attr_bundle *attrs, struct ib_device **ib_dev)