ceph: simplify ceph_buffer interface

We never allocate the ceph_buffer and buffer separtely, so use a single
constructor.

Disallow put on NULL buffer; make the caller check.

Signed-off-by: Sage Weil <sage@newdream.net>
diff --git a/fs/ceph/buffer.c b/fs/ceph/buffer.c
index 847c5da..2576bd4 100644
--- a/fs/ceph/buffer.c
+++ b/fs/ceph/buffer.c
@@ -2,23 +2,38 @@
 #include "ceph_debug.h"
 #include "buffer.h"
 
-struct ceph_buffer *ceph_buffer_new(gfp_t gfp)
+struct ceph_buffer *ceph_buffer_new(size_t len, gfp_t gfp)
 {
 	struct ceph_buffer *b;
 
 	b = kmalloc(sizeof(*b), gfp);
 	if (!b)
 		return NULL;
+
+	b->vec.iov_base = kmalloc(len, gfp | __GFP_NOWARN);
+	if (b->vec.iov_base) {
+		b->is_vmalloc = false;
+	} else {
+		b->vec.iov_base = __vmalloc(len, gfp, PAGE_KERNEL);
+		if (!b->vec.iov_base) {
+			kfree(b);
+			return NULL;
+		}
+		b->is_vmalloc = true;
+	}
+
 	kref_init(&b->kref);
-	b->vec.iov_base = NULL;
-	b->vec.iov_len = 0;
-	b->alloc_len = 0;
+	b->alloc_len = len;
+	b->vec.iov_len = len;
+	dout("buffer_new %p\n", b);
 	return b;
 }
 
 void ceph_buffer_release(struct kref *kref)
 {
 	struct ceph_buffer *b = container_of(kref, struct ceph_buffer, kref);
+
+	dout("buffer_release %p\n", b);
 	if (b->vec.iov_base) {
 		if (b->is_vmalloc)
 			vfree(b->vec.iov_base);