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