diff options
Diffstat (limited to 'drivers/md/dm-snap-transient.c')
-rw-r--r-- | drivers/md/dm-snap-transient.c | 95 |
1 files changed, 95 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..2a781df57fef --- /dev/null +++ b/drivers/md/dm-snap-transient.c | |||
@@ -0,0 +1,95 @@ | |||
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 | { | ||
33 | return 0; | ||
34 | } | ||
35 | |||
36 | static int transient_prepare(struct dm_exception_store *store, | ||
37 | struct dm_snap_exception *e) | ||
38 | { | ||
39 | struct transient_c *tc = (struct transient_c *) store->context; | ||
40 | sector_t size = get_dev_size(store->snap->cow->bdev); | ||
41 | |||
42 | if (size < (tc->next_free + store->snap->chunk_size)) | ||
43 | return -1; | ||
44 | |||
45 | e->new_chunk = sector_to_chunk(store->snap, tc->next_free); | ||
46 | tc->next_free += store->snap->chunk_size; | ||
47 | |||
48 | return 0; | ||
49 | } | ||
50 | |||
51 | static void transient_commit(struct dm_exception_store *store, | ||
52 | struct dm_snap_exception *e, | ||
53 | void (*callback) (void *, int success), | ||
54 | void *callback_context) | ||
55 | { | ||
56 | /* Just succeed */ | ||
57 | callback(callback_context, 1); | ||
58 | } | ||
59 | |||
60 | static void transient_fraction_full(struct dm_exception_store *store, | ||
61 | sector_t *numerator, sector_t *denominator) | ||
62 | { | ||
63 | *numerator = ((struct transient_c *) store->context)->next_free; | ||
64 | *denominator = get_dev_size(store->snap->cow->bdev); | ||
65 | } | ||
66 | |||
67 | int dm_create_transient(struct dm_exception_store *store) | ||
68 | { | ||
69 | struct transient_c *tc; | ||
70 | |||
71 | store->destroy = transient_destroy; | ||
72 | store->read_metadata = transient_read_metadata; | ||
73 | store->prepare_exception = transient_prepare; | ||
74 | store->commit_exception = transient_commit; | ||
75 | store->drop_snapshot = NULL; | ||
76 | store->fraction_full = transient_fraction_full; | ||
77 | |||
78 | tc = kmalloc(sizeof(struct transient_c), GFP_KERNEL); | ||
79 | if (!tc) | ||
80 | return -ENOMEM; | ||
81 | |||
82 | tc->next_free = 0; | ||
83 | store->context = tc; | ||
84 | |||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | int dm_transient_snapshot_init(void) | ||
89 | { | ||
90 | return 0; | ||
91 | } | ||
92 | |||
93 | void dm_transient_snapshot_exit(void) | ||
94 | { | ||
95 | } | ||