Commit 19e8697b authored by Christopher James Halse Rogers's avatar Christopher James Halse Rogers Committed by Sumit Semwal

dma-buf: Expose buffer size to userspace (v2)

Each dma-buf has an associated size and it's reasonable for userspace
to want to know what it is.

Since userspace already has an fd, expose the size using the
size = lseek(fd, SEEK_END, 0); lseek(fd, SEEK_CUR, 0);
idiom.

v2: Added Daniel's sugeested documentation, with minor fixups
Signed-off-by: default avatarChristopher James Halse Rogers <christopher.halse.rogers@canonical.com>
Reviewed-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Tested-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: default avatarSumit Semwal <sumit.semwal@linaro.org>
parent 9022e24e
...@@ -407,6 +407,18 @@ Being able to mmap an export dma-buf buffer object has 2 main use-cases: ...@@ -407,6 +407,18 @@ Being able to mmap an export dma-buf buffer object has 2 main use-cases:
interesting ways depending upong the exporter (if userspace starts depending interesting ways depending upong the exporter (if userspace starts depending
upon this implicit synchronization). upon this implicit synchronization).
Other Interfaces Exposed to Userspace on the dma-buf FD
------------------------------------------------------
- Since kernel 3.12 the dma-buf FD supports the llseek system call, but only
with offset=0 and whence=SEEK_END|SEEK_SET. SEEK_SET is supported to allow
the usual size discover pattern size = SEEK_END(0); SEEK_SET(0). Every other
llseek operation will report -EINVAL.
If llseek on dma-buf FDs isn't support the kernel will report -ESPIPE for all
cases. Userspace can use this to detect support for discovering the dma-buf
size using llseek.
Miscellaneous notes Miscellaneous notes
------------------- -------------------
......
...@@ -77,9 +77,36 @@ static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct *vma) ...@@ -77,9 +77,36 @@ static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct *vma)
return dmabuf->ops->mmap(dmabuf, vma); return dmabuf->ops->mmap(dmabuf, vma);
} }
static loff_t dma_buf_llseek(struct file *file, loff_t offset, int whence)
{
struct dma_buf *dmabuf;
loff_t base;
if (!is_dma_buf_file(file))
return -EBADF;
dmabuf = file->private_data;
/* only support discovering the end of the buffer,
but also allow SEEK_SET to maintain the idiomatic
SEEK_END(0), SEEK_CUR(0) pattern */
if (whence == SEEK_END)
base = dmabuf->size;
else if (whence == SEEK_SET)
base = 0;
else
return -EINVAL;
if (offset != 0)
return -EINVAL;
return base + offset;
}
static const struct file_operations dma_buf_fops = { static const struct file_operations dma_buf_fops = {
.release = dma_buf_release, .release = dma_buf_release,
.mmap = dma_buf_mmap_internal, .mmap = dma_buf_mmap_internal,
.llseek = dma_buf_llseek,
}; };
/* /*
...@@ -137,6 +164,8 @@ struct dma_buf *dma_buf_export_named(void *priv, const struct dma_buf_ops *ops, ...@@ -137,6 +164,8 @@ struct dma_buf *dma_buf_export_named(void *priv, const struct dma_buf_ops *ops,
kfree(dmabuf); kfree(dmabuf);
return ERR_CAST(file); return ERR_CAST(file);
} }
file->f_mode |= FMODE_LSEEK;
dmabuf->file = file; dmabuf->file = file;
mutex_init(&dmabuf->lock); mutex_init(&dmabuf->lock);
......
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