aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-09-11 22:09:14 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-09-11 22:09:14 -0400
commitb3b7568490bb66688ee64f4ab72ec697f4f983c5 (patch)
treee55098d4c05d2169e1934dcdf816e476c2af86f8
parentc2d95729e3094ecdd8c54e856bbe971adbbd7f48 (diff)
parent19e8697ba45e7bcdb04f2adf6110fbf4882863e5 (diff)
Merge tag 'for-3.12' of git://git.linaro.org/people/sumitsemwal/linux-dma-buf
Pull dma-buf updates from Sumit Semwal: "Yet another small one - dma-buf framework now supports size discovery of the buffer via llseek" * tag 'for-3.12' of git://git.linaro.org/people/sumitsemwal/linux-dma-buf: dma-buf: Expose buffer size to userspace (v2) dma-buf: Check return value of anon_inode_getfile
-rw-r--r--Documentation/dma-buf-sharing.txt12
-rw-r--r--drivers/base/dma-buf.c32
2 files changed, 44 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 1219ab7c3107..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/*
@@ -133,7 +160,12 @@ struct dma_buf *dma_buf_export_named(void *priv, const struct dma_buf_ops *ops,
133 dmabuf->exp_name = exp_name; 160 dmabuf->exp_name = exp_name;
134 161
135 file = anon_inode_getfile("dmabuf", &dma_buf_fops, dmabuf, flags); 162 file = anon_inode_getfile("dmabuf", &dma_buf_fops, dmabuf, flags);
163 if (IS_ERR(file)) {
164 kfree(dmabuf);
165 return ERR_CAST(file);
166 }
136 167
168 file->f_mode |= FMODE_LSEEK;
137 dmabuf->file = file; 169 dmabuf->file = file;
138 170
139 mutex_init(&dmabuf->lock); 171 mutex_init(&dmabuf->lock);