introduce kref_put_mutex()

equivalent of
	mutex_lock(mutex);
	if (!kref_put(kref, release))
		mutex_unlock(mutex);

Change-Id: I59f3dd1425e871e0b73b463447f74bc66d65ba0b
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
[mitchelh@codeaurora.org: trivial conflict due to moved code]
Signed-off-by: Mitchel Humpherys <mitchelh@codeaurora.org>
diff --git a/include/linux/kref.h b/include/linux/kref.h
index aa5acc26..6f515f2 100644
--- a/include/linux/kref.h
+++ b/include/linux/kref.h
@@ -18,6 +18,7 @@
 #include <linux/bug.h>
 #include <linux/atomic.h>
 #include <linux/kernel.h>
+#include <linux/mutex.h>
 
 struct kref {
 	atomic_t refcount;
@@ -94,6 +95,23 @@
 	return kref_sub(kref, 1, release);
 }
 
+static inline int kref_put_mutex(struct kref *kref,
+				 void (*release)(struct kref *kref),
+				 struct mutex *lock)
+{
+	WARN_ON(release == NULL);
+        if (unlikely(!atomic_add_unless(&kref->refcount, -1, 1))) {
+		mutex_lock(lock);
+		if (unlikely(!atomic_dec_and_test(&kref->refcount))) {
+			mutex_unlock(lock);
+			return 0;
+		}
+		release(kref);
+		return 1;
+	}
+	return 0;
+}
+
 
 /**
  * kref_get_unless_zero - Increment refcount for object unless it is zero.