162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * snapshot.c Ceph snapshot context utility routines (part of libceph) 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2013 Inktank Storage, Inc. 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <linux/types.h> 962306a36Sopenharmony_ci#include <linux/export.h> 1062306a36Sopenharmony_ci#include <linux/ceph/libceph.h> 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci/* 1362306a36Sopenharmony_ci * Ceph snapshot contexts are reference counted objects, and the 1462306a36Sopenharmony_ci * returned structure holds a single reference. Acquire additional 1562306a36Sopenharmony_ci * references with ceph_get_snap_context(), and release them with 1662306a36Sopenharmony_ci * ceph_put_snap_context(). When the reference count reaches zero 1762306a36Sopenharmony_ci * the entire structure is freed. 1862306a36Sopenharmony_ci */ 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci/* 2162306a36Sopenharmony_ci * Create a new ceph snapshot context large enough to hold the 2262306a36Sopenharmony_ci * indicated number of snapshot ids (which can be 0). Caller has 2362306a36Sopenharmony_ci * to fill in snapc->seq and snapc->snaps[0..snap_count-1]. 2462306a36Sopenharmony_ci * 2562306a36Sopenharmony_ci * Returns a null pointer if an error occurs. 2662306a36Sopenharmony_ci */ 2762306a36Sopenharmony_cistruct ceph_snap_context *ceph_create_snap_context(u32 snap_count, 2862306a36Sopenharmony_ci gfp_t gfp_flags) 2962306a36Sopenharmony_ci{ 3062306a36Sopenharmony_ci struct ceph_snap_context *snapc; 3162306a36Sopenharmony_ci size_t size; 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci size = sizeof (struct ceph_snap_context); 3462306a36Sopenharmony_ci size += snap_count * sizeof (snapc->snaps[0]); 3562306a36Sopenharmony_ci snapc = kzalloc(size, gfp_flags); 3662306a36Sopenharmony_ci if (!snapc) 3762306a36Sopenharmony_ci return NULL; 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci refcount_set(&snapc->nref, 1); 4062306a36Sopenharmony_ci snapc->num_snaps = snap_count; 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci return snapc; 4362306a36Sopenharmony_ci} 4462306a36Sopenharmony_ciEXPORT_SYMBOL(ceph_create_snap_context); 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_cistruct ceph_snap_context *ceph_get_snap_context(struct ceph_snap_context *sc) 4762306a36Sopenharmony_ci{ 4862306a36Sopenharmony_ci if (sc) 4962306a36Sopenharmony_ci refcount_inc(&sc->nref); 5062306a36Sopenharmony_ci return sc; 5162306a36Sopenharmony_ci} 5262306a36Sopenharmony_ciEXPORT_SYMBOL(ceph_get_snap_context); 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_civoid ceph_put_snap_context(struct ceph_snap_context *sc) 5562306a36Sopenharmony_ci{ 5662306a36Sopenharmony_ci if (!sc) 5762306a36Sopenharmony_ci return; 5862306a36Sopenharmony_ci if (refcount_dec_and_test(&sc->nref)) { 5962306a36Sopenharmony_ci /*printk(" deleting snap_context %p\n", sc);*/ 6062306a36Sopenharmony_ci kfree(sc); 6162306a36Sopenharmony_ci } 6262306a36Sopenharmony_ci} 6362306a36Sopenharmony_ciEXPORT_SYMBOL(ceph_put_snap_context); 64