Commit b3b7568490bb66688ee64f4ab72ec697f4f983c5
Exists in
smarc-imx_3.14.28_1.0.0_ga
and in
1 other branch
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
Showing 2 changed files Side-by-side Diff
Documentation/dma-buf-sharing.txt
... | ... | @@ -407,6 +407,18 @@ |
407 | 407 | interesting ways depending upong the exporter (if userspace starts depending |
408 | 408 | upon this implicit synchronization). |
409 | 409 | |
410 | +Other 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 | + | |
410 | 422 | Miscellaneous notes |
411 | 423 | ------------------- |
412 | 424 |
drivers/base/dma-buf.c
... | ... | @@ -77,9 +77,36 @@ |
77 | 77 | return dmabuf->ops->mmap(dmabuf, vma); |
78 | 78 | } |
79 | 79 | |
80 | +static 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 | + | |
80 | 106 | static const struct file_operations dma_buf_fops = { |
81 | 107 | .release = dma_buf_release, |
82 | 108 | .mmap = dma_buf_mmap_internal, |
109 | + .llseek = dma_buf_llseek, | |
83 | 110 | }; |
84 | 111 | |
85 | 112 | /* |
86 | 113 | |
... | ... | @@ -133,7 +160,12 @@ |
133 | 160 | dmabuf->exp_name = exp_name; |
134 | 161 | |
135 | 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 | 169 | dmabuf->file = file; |
138 | 170 | |
139 | 171 | mutex_init(&dmabuf->lock); |