1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * snapshot.c Ceph snapshot context utility routines (part of libceph) 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * Copyright (C) 2013 Inktank Storage, Inc. 6*4882a593Smuzhiyun */ 7*4882a593Smuzhiyun 8*4882a593Smuzhiyun #include <linux/types.h> 9*4882a593Smuzhiyun #include <linux/export.h> 10*4882a593Smuzhiyun #include <linux/ceph/libceph.h> 11*4882a593Smuzhiyun 12*4882a593Smuzhiyun /* 13*4882a593Smuzhiyun * Ceph snapshot contexts are reference counted objects, and the 14*4882a593Smuzhiyun * returned structure holds a single reference. Acquire additional 15*4882a593Smuzhiyun * references with ceph_get_snap_context(), and release them with 16*4882a593Smuzhiyun * ceph_put_snap_context(). When the reference count reaches zero 17*4882a593Smuzhiyun * the entire structure is freed. 18*4882a593Smuzhiyun */ 19*4882a593Smuzhiyun 20*4882a593Smuzhiyun /* 21*4882a593Smuzhiyun * Create a new ceph snapshot context large enough to hold the 22*4882a593Smuzhiyun * indicated number of snapshot ids (which can be 0). Caller has 23*4882a593Smuzhiyun * to fill in snapc->seq and snapc->snaps[0..snap_count-1]. 24*4882a593Smuzhiyun * 25*4882a593Smuzhiyun * Returns a null pointer if an error occurs. 26*4882a593Smuzhiyun */ ceph_create_snap_context(u32 snap_count,gfp_t gfp_flags)27*4882a593Smuzhiyunstruct ceph_snap_context *ceph_create_snap_context(u32 snap_count, 28*4882a593Smuzhiyun gfp_t gfp_flags) 29*4882a593Smuzhiyun { 30*4882a593Smuzhiyun struct ceph_snap_context *snapc; 31*4882a593Smuzhiyun size_t size; 32*4882a593Smuzhiyun 33*4882a593Smuzhiyun size = sizeof (struct ceph_snap_context); 34*4882a593Smuzhiyun size += snap_count * sizeof (snapc->snaps[0]); 35*4882a593Smuzhiyun snapc = kzalloc(size, gfp_flags); 36*4882a593Smuzhiyun if (!snapc) 37*4882a593Smuzhiyun return NULL; 38*4882a593Smuzhiyun 39*4882a593Smuzhiyun refcount_set(&snapc->nref, 1); 40*4882a593Smuzhiyun snapc->num_snaps = snap_count; 41*4882a593Smuzhiyun 42*4882a593Smuzhiyun return snapc; 43*4882a593Smuzhiyun } 44*4882a593Smuzhiyun EXPORT_SYMBOL(ceph_create_snap_context); 45*4882a593Smuzhiyun ceph_get_snap_context(struct ceph_snap_context * sc)46*4882a593Smuzhiyunstruct ceph_snap_context *ceph_get_snap_context(struct ceph_snap_context *sc) 47*4882a593Smuzhiyun { 48*4882a593Smuzhiyun if (sc) 49*4882a593Smuzhiyun refcount_inc(&sc->nref); 50*4882a593Smuzhiyun return sc; 51*4882a593Smuzhiyun } 52*4882a593Smuzhiyun EXPORT_SYMBOL(ceph_get_snap_context); 53*4882a593Smuzhiyun ceph_put_snap_context(struct ceph_snap_context * sc)54*4882a593Smuzhiyunvoid ceph_put_snap_context(struct ceph_snap_context *sc) 55*4882a593Smuzhiyun { 56*4882a593Smuzhiyun if (!sc) 57*4882a593Smuzhiyun return; 58*4882a593Smuzhiyun if (refcount_dec_and_test(&sc->nref)) { 59*4882a593Smuzhiyun /*printk(" deleting snap_context %p\n", sc);*/ 60*4882a593Smuzhiyun kfree(sc); 61*4882a593Smuzhiyun } 62*4882a593Smuzhiyun } 63*4882a593Smuzhiyun EXPORT_SYMBOL(ceph_put_snap_context); 64