Commit 9ad95a0f authored by Yishai Hadas's avatar Yishai Hadas Committed by Leon Romanovsky
Browse files

RDMA/uverbs: Support external FD uobjects



Add support for uobjects that wrap externally allocated file
descriptors (FDs).

In this mode, the FD number still follows the standard uverbs allocation
flow, but the file pointer is allocated externally and has its own fops
and private data.

As a result, alloc_begin_fd_uobject() must handle cases where
fd_type->fops is NULL, and both alloc_commit_fd_uobject() and
alloc_abort_fd_uobject() must account for whether filp->private_data
exists, since it is populated outside the standard uverbs flow.

Signed-off-by: default avatarYishai Hadas <yishaih@nvidia.com>
Signed-off-by: default avatarEdward Srouji <edwards@nvidia.com>
Link: https://patch.msgid.link/20260201-dmabuf-export-v3-1-da238b614fe3@nvidia.com


Signed-off-by: default avatarLeon Romanovsky <leon@kernel.org>
parent 06fddc7a
Loading
Loading
Loading
Loading
+21 −14
Original line number Diff line number Diff line
@@ -465,7 +465,7 @@ alloc_begin_fd_uobject(const struct uverbs_api_object *obj,

	fd_type =
		container_of(obj->type_attrs, struct uverbs_obj_fd_type, type);
	if (WARN_ON(fd_type->fops->release != &uverbs_uobject_fd_release &&
	if (WARN_ON(fd_type->fops && fd_type->fops->release != &uverbs_uobject_fd_release &&
		    fd_type->fops->release != &uverbs_async_event_release)) {
		ret = ERR_PTR(-EINVAL);
		goto err_fd;
@@ -477,6 +477,7 @@ alloc_begin_fd_uobject(const struct uverbs_api_object *obj,
		goto err_fd;
	}

	if (fd_type->fops) {
		/* Note that uverbs_uobject_fd_release() is called during abort */
		filp = anon_inode_getfile(fd_type->name, fd_type->fops, NULL,
					  fd_type->flags);
@@ -485,6 +486,7 @@ alloc_begin_fd_uobject(const struct uverbs_api_object *obj,
			goto err_getfile;
		}
		uobj->object = filp;
	}

	uobj->id = new_fd;
	return uobj;
@@ -561,7 +563,9 @@ static void alloc_abort_fd_uobject(struct ib_uobject *uobj)
{
	struct file *filp = uobj->object;

	if (filp)
		fput(filp);

	put_unused_fd(uobj->id);
}

@@ -628,11 +632,14 @@ static void alloc_commit_fd_uobject(struct ib_uobject *uobj)
	/* This shouldn't be used anymore. Use the file object instead */
	uobj->id = 0;

	if (!filp->private_data) {
		/*
		 * NOTE: Once we install the file we loose ownership of our kref on
		 * uobj. It will be put by uverbs_uobject_fd_release()
		 */
		filp->private_data = uobj;
	}

	fd_install(fd, filp);
}