drm: Extract drm_master_open

And pull out the primary_client check to make it really obvious that
this can't happen on control/render nodes. Bonus that we can avoid the
master lock in this case.

v2: Don't leak locks on error path (and simplify control flow while
at it), reported by Julia.

Cc: Julia Lawall <julia.lawall@lip6.fr>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1465930269-7883-6-git-send-email-daniel.vetter@ffwll.ch
diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
index 1d314ae..9c1e208 100644
--- a/drivers/gpu/drm/drm_auth.c
+++ b/drivers/gpu/drm/drm_auth.c
@@ -120,7 +120,7 @@
  * This function must be called with dev::struct_mutex held.
  * Returns negative error code on failure. Zero on success.
  */
-int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv)
+static int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv)
 {
 	struct drm_master *old_master;
 	int ret;
@@ -226,6 +226,23 @@
 	return ret;
 }
 
+int drm_master_open(struct drm_file *file_priv)
+{
+	struct drm_device *dev = file_priv->minor->dev;
+	int ret = 0;
+
+	/* if there is no current master make this fd it, but do not create
+	 * any master object for render clients */
+	mutex_lock(&dev->master_mutex);
+	if (!file_priv->minor->master)
+		ret = drm_new_set_master(dev, file_priv);
+	else
+		file_priv->master = drm_master_get(file_priv->minor->master);
+	mutex_unlock(&dev->master_mutex);
+
+	return ret;
+}
+
 struct drm_master *drm_master_get(struct drm_master *master)
 {
 	kref_get(&master->refcount);