xref: /openbmc/linux/net/ceph/buffer.c (revision 03ab8e6297acd1bc0eedaa050e2a1635c576fd11)
1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
23d14c5d2SYehuda Sadeh 
33d14c5d2SYehuda Sadeh #include <linux/ceph/ceph_debug.h>
43d14c5d2SYehuda Sadeh 
53d14c5d2SYehuda Sadeh #include <linux/module.h>
63d14c5d2SYehuda Sadeh #include <linux/slab.h>
73d14c5d2SYehuda Sadeh 
83d14c5d2SYehuda Sadeh #include <linux/ceph/buffer.h>
93d14c5d2SYehuda Sadeh #include <linux/ceph/decode.h>
10*a421ef30SMichal Hocko #include <linux/ceph/libceph.h> /* for kvmalloc */
113d14c5d2SYehuda Sadeh 
ceph_buffer_new(size_t len,gfp_t gfp)123d14c5d2SYehuda Sadeh struct ceph_buffer *ceph_buffer_new(size_t len, gfp_t gfp)
133d14c5d2SYehuda Sadeh {
143d14c5d2SYehuda Sadeh 	struct ceph_buffer *b;
153d14c5d2SYehuda Sadeh 
163d14c5d2SYehuda Sadeh 	b = kmalloc(sizeof(*b), gfp);
173d14c5d2SYehuda Sadeh 	if (!b)
183d14c5d2SYehuda Sadeh 		return NULL;
193d14c5d2SYehuda Sadeh 
20*a421ef30SMichal Hocko 	b->vec.iov_base = kvmalloc(len, gfp);
213d14c5d2SYehuda Sadeh 	if (!b->vec.iov_base) {
223d14c5d2SYehuda Sadeh 		kfree(b);
233d14c5d2SYehuda Sadeh 		return NULL;
243d14c5d2SYehuda Sadeh 	}
253d14c5d2SYehuda Sadeh 
263d14c5d2SYehuda Sadeh 	kref_init(&b->kref);
273d14c5d2SYehuda Sadeh 	b->alloc_len = len;
283d14c5d2SYehuda Sadeh 	b->vec.iov_len = len;
293d14c5d2SYehuda Sadeh 	dout("buffer_new %p\n", b);
303d14c5d2SYehuda Sadeh 	return b;
313d14c5d2SYehuda Sadeh }
323d14c5d2SYehuda Sadeh EXPORT_SYMBOL(ceph_buffer_new);
333d14c5d2SYehuda Sadeh 
ceph_buffer_release(struct kref * kref)343d14c5d2SYehuda Sadeh void ceph_buffer_release(struct kref *kref)
353d14c5d2SYehuda Sadeh {
363d14c5d2SYehuda Sadeh 	struct ceph_buffer *b = container_of(kref, struct ceph_buffer, kref);
373d14c5d2SYehuda Sadeh 
383d14c5d2SYehuda Sadeh 	dout("buffer_release %p\n", b);
394965fc38SIlya Dryomov 	kvfree(b->vec.iov_base);
403d14c5d2SYehuda Sadeh 	kfree(b);
413d14c5d2SYehuda Sadeh }
423d14c5d2SYehuda Sadeh EXPORT_SYMBOL(ceph_buffer_release);
433d14c5d2SYehuda Sadeh 
ceph_decode_buffer(struct ceph_buffer ** b,void ** p,void * end)443d14c5d2SYehuda Sadeh int ceph_decode_buffer(struct ceph_buffer **b, void **p, void *end)
453d14c5d2SYehuda Sadeh {
463d14c5d2SYehuda Sadeh 	size_t len;
473d14c5d2SYehuda Sadeh 
483d14c5d2SYehuda Sadeh 	ceph_decode_need(p, end, sizeof(u32), bad);
493d14c5d2SYehuda Sadeh 	len = ceph_decode_32(p);
503d14c5d2SYehuda Sadeh 	dout("decode_buffer len %d\n", (int)len);
513d14c5d2SYehuda Sadeh 	ceph_decode_need(p, end, len, bad);
523d14c5d2SYehuda Sadeh 	*b = ceph_buffer_new(len, GFP_NOFS);
533d14c5d2SYehuda Sadeh 	if (!*b)
543d14c5d2SYehuda Sadeh 		return -ENOMEM;
553d14c5d2SYehuda Sadeh 	ceph_decode_copy(p, (*b)->vec.iov_base, len);
563d14c5d2SYehuda Sadeh 	return 0;
573d14c5d2SYehuda Sadeh bad:
583d14c5d2SYehuda Sadeh 	return -EINVAL;
593d14c5d2SYehuda Sadeh }
60