diff options
Diffstat (limited to 'drivers/md/dm-snap-transient.c')
-rw-r--r-- | drivers/md/dm-snap-transient.c | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/drivers/md/dm-snap-transient.c b/drivers/md/dm-snap-transient.c new file mode 100644 index 000000000000..7f6e2e6dcb0d --- /dev/null +++ b/drivers/md/dm-snap-transient.c | |||
@@ -0,0 +1,98 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2001-2002 Sistina Software (UK) Limited. | ||
3 | * Copyright (C) 2006-2008 Red Hat GmbH | ||
4 | * | ||
5 | * This file is released under the GPL. | ||
6 | */ | ||
7 | |||
8 | #include "dm-exception-store.h" | ||
9 | #include "dm-snap.h" | ||
10 | |||
11 | #include <linux/mm.h> | ||
12 | #include <linux/pagemap.h> | ||
13 | #include <linux/vmalloc.h> | ||
14 | #include <linux/slab.h> | ||
15 | #include <linux/dm-io.h> | ||
16 | |||
17 | #define DM_MSG_PREFIX "transient snapshot" | ||
18 | |||
19 | /*----------------------------------------------------------------- | ||
20 | * Implementation of the store for non-persistent snapshots. | ||
21 | *---------------------------------------------------------------*/ | ||
22 | struct transient_c { | ||
23 | sector_t next_free; | ||
24 | }; | ||
25 | |||
26 | static void transient_destroy(struct dm_exception_store *store) | ||
27 | { | ||
28 | kfree(store->context); | ||
29 | } | ||
30 | |||
31 | static int transient_read_metadata(struct dm_exception_store *store, | ||
32 | int (*callback)(void *callback_context, | ||
33 | chunk_t old, chunk_t new), | ||
34 | void *callback_context) | ||
35 | { | ||
36 | return 0; | ||
37 | } | ||
38 | |||
39 | static int transient_prepare_exception(struct dm_exception_store *store, | ||
40 | struct dm_snap_exception *e) | ||
41 | { | ||
42 | struct transient_c *tc = (struct transient_c *) store->context; | ||
43 | sector_t size = get_dev_size(store->snap->cow->bdev); | ||
44 | |||
45 | if (size < (tc->next_free + store->snap->chunk_size)) | ||
46 | return -1; | ||
47 | |||
48 | e->new_chunk = sector_to_chunk(store->snap, tc->next_free); | ||
49 | tc->next_free += store->snap->chunk_size; | ||
50 | |||
51 | return 0; | ||
52 | } | ||
53 | |||
54 | static void transient_commit_exception(struct dm_exception_store *store, | ||
55 | struct dm_snap_exception *e, | ||
56 | void (*callback) (void *, int success), | ||
57 | void *callback_context) | ||
58 | { | ||
59 | /* Just succeed */ | ||
60 | callback(callback_context, 1); | ||
61 | } | ||
62 | |||
63 | static void transient_fraction_full(struct dm_exception_store *store, | ||
64 | sector_t *numerator, sector_t *denominator) | ||
65 | { | ||
66 | *numerator = ((struct transient_c *) store->context)->next_free; | ||
67 | *denominator = get_dev_size(store->snap->cow->bdev); | ||
68 | } | ||
69 | |||
70 | int dm_create_transient(struct dm_exception_store *store) | ||
71 | { | ||
72 | struct transient_c *tc; | ||
73 | |||
74 | store->destroy = transient_destroy; | ||
75 | store->read_metadata = transient_read_metadata; | ||
76 | store->prepare_exception = transient_prepare_exception; | ||
77 | store->commit_exception = transient_commit_exception; | ||
78 | store->drop_snapshot = NULL; | ||
79 | store->fraction_full = transient_fraction_full; | ||
80 | |||
81 | tc = kmalloc(sizeof(struct transient_c), GFP_KERNEL); | ||
82 | if (!tc) | ||
83 | return -ENOMEM; | ||
84 | |||
85 | tc->next_free = 0; | ||
86 | store->context = tc; | ||
87 | |||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | int dm_transient_snapshot_init(void) | ||
92 | { | ||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | void dm_transient_snapshot_exit(void) | ||
97 | { | ||
98 | } | ||