aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorJohn Sheu <sheu@google.com>2013-02-11 20:50:24 -0500
committerSumit Semwal <sumit.semwal@linaro.org>2013-02-27 04:44:02 -0500
commit495c10cc1c0c359871d5bef32dd173252fc17995 (patch)
tree5cc942ec2c74496dd3774dffff5cdde67cd75ae0 /drivers/base
parentf00b4dad9d9eb001a04cf72e8351a2a1b9e99322 (diff)
CHROMIUM: dma-buf: restore args on failure of dma_buf_mmap
Callers to dma_buf_mmap expect to fput() the vma struct's vm_file themselves on failure. Not restoring the struct's data on failure causes a double-decrement of the vm_file's refcount. Signed-off-by: John Sheu <sheu@google.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org>
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/dma-buf.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c
index 394523807a6d..2a7cb0df176b 100644
--- a/drivers/base/dma-buf.c
+++ b/drivers/base/dma-buf.c
@@ -447,6 +447,9 @@ EXPORT_SYMBOL_GPL(dma_buf_kunmap);
447int dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma, 447int dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma,
448 unsigned long pgoff) 448 unsigned long pgoff)
449{ 449{
450 struct file *oldfile;
451 int ret;
452
450 if (WARN_ON(!dmabuf || !vma)) 453 if (WARN_ON(!dmabuf || !vma))
451 return -EINVAL; 454 return -EINVAL;
452 455
@@ -460,14 +463,22 @@ int dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma,
460 return -EINVAL; 463 return -EINVAL;
461 464
462 /* readjust the vma */ 465 /* readjust the vma */
463 if (vma->vm_file) 466 get_file(dmabuf->file);
464 fput(vma->vm_file); 467 oldfile = vma->vm_file;
465 468 vma->vm_file = dmabuf->file;
466 vma->vm_file = get_file(dmabuf->file);
467
468 vma->vm_pgoff = pgoff; 469 vma->vm_pgoff = pgoff;
469 470
470 return dmabuf->ops->mmap(dmabuf, vma); 471 ret = dmabuf->ops->mmap(dmabuf, vma);
472 if (ret) {
473 /* restore old parameters on failure */
474 vma->vm_file = oldfile;
475 fput(dmabuf->file);
476 } else {
477 if (oldfile)
478 fput(oldfile);
479 }
480 return ret;
481
471} 482}
472EXPORT_SYMBOL_GPL(dma_buf_mmap); 483EXPORT_SYMBOL_GPL(dma_buf_mmap);
473 484