aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristopher James Halse Rogers <christopher.halse.rogers@canonical.com>2013-09-10 02:06:45 -0400
committerSumit Semwal <sumit.semwal@linaro.org>2013-09-10 02:06:45 -0400
commit19e8697ba45e7bcdb04f2adf6110fbf4882863e5 (patch)
tree249547a50a16d33e2c3c2dea96a592b2b823dc2b
parent9022e24e8946400d53719a761815069c3183e2bd (diff)
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: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Tested-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org>
-rw-r--r--Documentation/dma-buf-sharing.txt12
-rw-r--r--drivers/base/dma-buf.c29
2 files changed, 41 insertions, 0 deletions
diff --git a/Documentation/dma-buf-sharing.txt b/Documentation/dma-buf-sharing.txt
index e31a2a9d2b07..505e71172ae7 100644
--- a/Documentation/dma-buf-sharing.txt
+++ b/Documentation/dma-buf-sharing.txt
@@ -407,6 +407,18 @@ Being able to mmap an export dma-buf buffer object has 2 main use-cases:
407 interesting ways depending upong the exporter (if userspace starts depending 407 interesting ways depending upong the exporter (if userspace starts depending
408 upon this implicit synchronization). 408 upon this implicit synchronization).
409 409
410Other Interfaces Exposed to Userspace on the dma-buf FD
411------------------------------------------------------
412
413- Since kernel 3.12 the dma-buf FD supports the llseek system call, but only
414 with offset=0 and whence=SEEK_END|SEEK_SET. SEEK_SET is supported to allow
415 the usual size discover pattern size = SEEK_END(0); SEEK_SET(0). Every other
416 llseek operation will report -EINVAL.
417
418 If llseek on dma-buf FDs isn't support the kernel will report -ESPIPE for all
419 cases. Userspace can use this to detect support for discovering the dma-buf
420 size using llseek.
421
410Miscellaneous notes 422Miscellaneous notes
411------------------- 423-------------------
412 424
diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c
index 2d5ac1a1842e..1e16cbd61da2 100644
--- a/drivers/base/dma-buf.c
+++ b/drivers/base/dma-buf.c
@@ -77,9 +77,36 @@ static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct *vma)
77 return dmabuf->ops->mmap(dmabuf, vma); 77 return dmabuf->ops->mmap(dmabuf, vma);
78} 78}
79 79
80static loff_t dma_buf_llseek(struct file *file, loff_t offset, int whence)
81{
82 struct dma_buf *dmabuf;
83 loff_t base;
84
85 if (!is_dma_buf_file(file))
86 return -EBADF;
87
88 dmabuf = file->private_data;
89
90 /* only support discovering the end of the buffer,
91 but also allow SEEK_SET to maintain the idiomatic
92 SEEK_END(0), SEEK_CUR(0) pattern */
93 if (whence == SEEK_END)
94 base = dmabuf->size;
95 else if (whence == SEEK_SET)
96 base = 0;
97 else
98 return -EINVAL;
99
100 if (offset != 0)
101 return -EINVAL;
102
103 return base + offset;
104}
105
80static const struct file_operations dma_buf_fops = { 106static const struct file_operations dma_buf_fops = {
81 .release = dma_buf_release, 107 .release = dma_buf_release,
82 .mmap = dma_buf_mmap_internal, 108 .mmap = dma_buf_mmap_internal,
109 .llseek = dma_buf_llseek,
83}; 110};
84 111
85/* 112/*
@@ -137,6 +164,8 @@ struct dma_buf *dma_buf_export_named(void *priv, const struct dma_buf_ops *ops,
137 kfree(dmabuf); 164 kfree(dmabuf);
138 return ERR_CAST(file); 165 return ERR_CAST(file);
139 } 166 }
167
168 file->f_mode |= FMODE_LSEEK;
140 dmabuf->file = file; 169 dmabuf->file = file;
141 170
142 mutex_init(&dmabuf->lock); 171 mutex_init(&dmabuf->lock);