Merge drm/drm-fixes into drm-misc-fixes
[platform/kernel/linux-starfive.git] / drivers / dma-buf / dma-buf.c
index b6c3691..e652876 100644 (file)
@@ -95,10 +95,11 @@ static int dma_buf_file_release(struct inode *inode, struct file *file)
                return -EINVAL;
 
        dmabuf = file->private_data;
-
-       mutex_lock(&db_list.lock);
-       list_del(&dmabuf->list_node);
-       mutex_unlock(&db_list.lock);
+       if (dmabuf) {
+               mutex_lock(&db_list.lock);
+               list_del(&dmabuf->list_node);
+               mutex_unlock(&db_list.lock);
+       }
 
        return 0;
 }
@@ -528,17 +529,17 @@ static inline int is_dma_buf_file(struct file *file)
        return file->f_op == &dma_buf_fops;
 }
 
-static struct file *dma_buf_getfile(struct dma_buf *dmabuf, int flags)
+static struct file *dma_buf_getfile(size_t size, int flags)
 {
        static atomic64_t dmabuf_inode = ATOMIC64_INIT(0);
-       struct file *file;
        struct inode *inode = alloc_anon_inode(dma_buf_mnt->mnt_sb);
+       struct file *file;
 
        if (IS_ERR(inode))
                return ERR_CAST(inode);
 
-       inode->i_size = dmabuf->size;
-       inode_set_bytes(inode, dmabuf->size);
+       inode->i_size = size;
+       inode_set_bytes(inode, size);
 
        /*
         * The ->i_ino acquired from get_next_ino() is not unique thus
@@ -552,8 +553,6 @@ static struct file *dma_buf_getfile(struct dma_buf *dmabuf, int flags)
                                 flags, &dma_buf_fops);
        if (IS_ERR(file))
                goto err_alloc_file;
-       file->private_data = dmabuf;
-       file->f_path.dentry->d_fsdata = dmabuf;
 
        return file;
 
@@ -619,19 +618,11 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
        size_t alloc_size = sizeof(struct dma_buf);
        int ret;
 
-       if (!exp_info->resv)
-               alloc_size += sizeof(struct dma_resv);
-       else
-               /* prevent &dma_buf[1] == dma_buf->resv */
-               alloc_size += 1;
-
-       if (WARN_ON(!exp_info->priv
-                         || !exp_info->ops
-                         || !exp_info->ops->map_dma_buf
-                         || !exp_info->ops->unmap_dma_buf
-                         || !exp_info->ops->release)) {
+       if (WARN_ON(!exp_info->priv || !exp_info->ops
+                   || !exp_info->ops->map_dma_buf
+                   || !exp_info->ops->unmap_dma_buf
+                   || !exp_info->ops->release))
                return ERR_PTR(-EINVAL);
-       }
 
        if (WARN_ON(exp_info->ops->cache_sgt_mapping &&
                    (exp_info->ops->pin || exp_info->ops->unpin)))
@@ -643,10 +634,21 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
        if (!try_module_get(exp_info->owner))
                return ERR_PTR(-ENOENT);
 
+       file = dma_buf_getfile(exp_info->size, exp_info->flags);
+       if (IS_ERR(file)) {
+               ret = PTR_ERR(file);
+               goto err_module;
+       }
+
+       if (!exp_info->resv)
+               alloc_size += sizeof(struct dma_resv);
+       else
+               /* prevent &dma_buf[1] == dma_buf->resv */
+               alloc_size += 1;
        dmabuf = kzalloc(alloc_size, GFP_KERNEL);
        if (!dmabuf) {
                ret = -ENOMEM;
-               goto err_module;
+               goto err_file;
        }
 
        dmabuf->priv = exp_info->priv;
@@ -658,43 +660,35 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
        init_waitqueue_head(&dmabuf->poll);
        dmabuf->cb_in.poll = dmabuf->cb_out.poll = &dmabuf->poll;
        dmabuf->cb_in.active = dmabuf->cb_out.active = 0;
+       INIT_LIST_HEAD(&dmabuf->attachments);
 
        if (!resv) {
-               resv = (struct dma_resv *)&dmabuf[1];
-               dma_resv_init(resv);
+               dmabuf->resv = (struct dma_resv *)&dmabuf[1];
+               dma_resv_init(dmabuf->resv);
+       } else {
+               dmabuf->resv = resv;
        }
-       dmabuf->resv = resv;
 
-       file = dma_buf_getfile(dmabuf, exp_info->flags);
-       if (IS_ERR(file)) {
-               ret = PTR_ERR(file);
+       ret = dma_buf_stats_setup(dmabuf, file);
+       if (ret)
                goto err_dmabuf;
-       }
 
+       file->private_data = dmabuf;
+       file->f_path.dentry->d_fsdata = dmabuf;
        dmabuf->file = file;
 
-       INIT_LIST_HEAD(&dmabuf->attachments);
-
        mutex_lock(&db_list.lock);
        list_add(&dmabuf->list_node, &db_list.head);
        mutex_unlock(&db_list.lock);
 
-       ret = dma_buf_stats_setup(dmabuf);
-       if (ret)
-               goto err_sysfs;
-
        return dmabuf;
 
-err_sysfs:
-       /*
-        * Set file->f_path.dentry->d_fsdata to NULL so that when
-        * dma_buf_release() gets invoked by dentry_ops, it exits
-        * early before calling the release() dma_buf op.
-        */
-       file->f_path.dentry->d_fsdata = NULL;
-       fput(file);
 err_dmabuf:
+       if (!resv)
+               dma_resv_fini(dmabuf->resv);
        kfree(dmabuf);
+err_file:
+       fput(file);
 err_module:
        module_put(exp_info->owner);
        return ERR_PTR(ret);