xref: /openbmc/linux/net/ceph/snapshot.c (revision 75bf465f0bc33e9b776a46d6a1b9b990f5fb7c37)
1*04672fe6SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
24f0dcb10SAlex Elder /*
34f0dcb10SAlex Elder  * snapshot.c    Ceph snapshot context utility routines (part of libceph)
44f0dcb10SAlex Elder  *
54f0dcb10SAlex Elder  * Copyright (C) 2013 Inktank Storage, Inc.
64f0dcb10SAlex Elder  */
74f0dcb10SAlex Elder 
84f0dcb10SAlex Elder #include <linux/types.h>
94f0dcb10SAlex Elder #include <linux/export.h>
104f0dcb10SAlex Elder #include <linux/ceph/libceph.h>
114f0dcb10SAlex Elder 
124f0dcb10SAlex Elder /*
134f0dcb10SAlex Elder  * Ceph snapshot contexts are reference counted objects, and the
144f0dcb10SAlex Elder  * returned structure holds a single reference.  Acquire additional
154f0dcb10SAlex Elder  * references with ceph_get_snap_context(), and release them with
164f0dcb10SAlex Elder  * ceph_put_snap_context().  When the reference count reaches zero
174f0dcb10SAlex Elder  * the entire structure is freed.
184f0dcb10SAlex Elder  */
194f0dcb10SAlex Elder 
204f0dcb10SAlex Elder /*
214f0dcb10SAlex Elder  * Create a new ceph snapshot context large enough to hold the
224f0dcb10SAlex Elder  * indicated number of snapshot ids (which can be 0).  Caller has
234f0dcb10SAlex Elder  * to fill in snapc->seq and snapc->snaps[0..snap_count-1].
244f0dcb10SAlex Elder  *
254f0dcb10SAlex Elder  * Returns a null pointer if an error occurs.
264f0dcb10SAlex Elder  */
ceph_create_snap_context(u32 snap_count,gfp_t gfp_flags)274f0dcb10SAlex Elder struct ceph_snap_context *ceph_create_snap_context(u32 snap_count,
284f0dcb10SAlex Elder 						gfp_t gfp_flags)
294f0dcb10SAlex Elder {
304f0dcb10SAlex Elder 	struct ceph_snap_context *snapc;
314f0dcb10SAlex Elder 	size_t size;
324f0dcb10SAlex Elder 
334f0dcb10SAlex Elder 	size = sizeof (struct ceph_snap_context);
344f0dcb10SAlex Elder 	size += snap_count * sizeof (snapc->snaps[0]);
354f0dcb10SAlex Elder 	snapc = kzalloc(size, gfp_flags);
364f0dcb10SAlex Elder 	if (!snapc)
374f0dcb10SAlex Elder 		return NULL;
384f0dcb10SAlex Elder 
3906dfa963SElena Reshetova 	refcount_set(&snapc->nref, 1);
404f0dcb10SAlex Elder 	snapc->num_snaps = snap_count;
414f0dcb10SAlex Elder 
424f0dcb10SAlex Elder 	return snapc;
434f0dcb10SAlex Elder }
444f0dcb10SAlex Elder EXPORT_SYMBOL(ceph_create_snap_context);
454f0dcb10SAlex Elder 
ceph_get_snap_context(struct ceph_snap_context * sc)464f0dcb10SAlex Elder struct ceph_snap_context *ceph_get_snap_context(struct ceph_snap_context *sc)
474f0dcb10SAlex Elder {
484f0dcb10SAlex Elder 	if (sc)
4906dfa963SElena Reshetova 		refcount_inc(&sc->nref);
504f0dcb10SAlex Elder 	return sc;
514f0dcb10SAlex Elder }
524f0dcb10SAlex Elder EXPORT_SYMBOL(ceph_get_snap_context);
534f0dcb10SAlex Elder 
ceph_put_snap_context(struct ceph_snap_context * sc)544f0dcb10SAlex Elder void ceph_put_snap_context(struct ceph_snap_context *sc)
554f0dcb10SAlex Elder {
564f0dcb10SAlex Elder 	if (!sc)
574f0dcb10SAlex Elder 		return;
5806dfa963SElena Reshetova 	if (refcount_dec_and_test(&sc->nref)) {
594f0dcb10SAlex Elder 		/*printk(" deleting snap_context %p\n", sc);*/
604f0dcb10SAlex Elder 		kfree(sc);
614f0dcb10SAlex Elder 	}
624f0dcb10SAlex Elder }
634f0dcb10SAlex Elder EXPORT_SYMBOL(ceph_put_snap_context);
64