2 * Copyright (C) 2001-2002 Sistina Software (UK) Limited.
3 * Copyright (C) 2006-2008 Red Hat GmbH
5 * This file is released under the GPL.
8 #include "dm-exception-store.h"
11 #include <linux/pagemap.h>
12 #include <linux/vmalloc.h>
13 #include <linux/slab.h>
14 #include <linux/dm-io.h>
16 #define DM_MSG_PREFIX "transient snapshot"
18 /*-----------------------------------------------------------------
19 * Implementation of the store for non-persistent snapshots.
20 *---------------------------------------------------------------*/
25 static void transient_dtr(struct dm_exception_store
*store
)
27 kfree(store
->context
);
30 static int transient_read_metadata(struct dm_exception_store
*store
,
31 int (*callback
)(void *callback_context
,
32 chunk_t old
, chunk_t
new),
33 void *callback_context
)
38 static int transient_prepare_exception(struct dm_exception_store
*store
,
39 struct dm_snap_exception
*e
)
41 struct transient_c
*tc
= store
->context
;
42 sector_t size
= get_dev_size(store
->cow
->bdev
);
44 if (size
< (tc
->next_free
+ store
->chunk_size
))
47 e
->new_chunk
= sector_to_chunk(store
, tc
->next_free
);
48 tc
->next_free
+= store
->chunk_size
;
53 static void transient_commit_exception(struct dm_exception_store
*store
,
54 struct dm_snap_exception
*e
,
55 void (*callback
) (void *, int success
),
56 void *callback_context
)
59 callback(callback_context
, 1);
62 static void transient_fraction_full(struct dm_exception_store
*store
,
63 sector_t
*numerator
, sector_t
*denominator
)
65 *numerator
= ((struct transient_c
*) store
->context
)->next_free
;
66 *denominator
= get_dev_size(store
->cow
->bdev
);
69 static int transient_ctr(struct dm_exception_store
*store
,
70 unsigned argc
, char **argv
)
72 struct transient_c
*tc
;
74 tc
= kmalloc(sizeof(struct transient_c
), GFP_KERNEL
);
84 static unsigned transient_status(struct dm_exception_store
*store
,
85 status_type_t status
, char *result
,
93 case STATUSTYPE_TABLE
:
94 DMEMIT(" %s N %llu", store
->cow
->name
,
95 (unsigned long long)store
->chunk_size
);
101 static struct dm_exception_store_type _transient_type
= {
103 .module
= THIS_MODULE
,
104 .ctr
= transient_ctr
,
105 .dtr
= transient_dtr
,
106 .read_metadata
= transient_read_metadata
,
107 .prepare_exception
= transient_prepare_exception
,
108 .commit_exception
= transient_commit_exception
,
109 .fraction_full
= transient_fraction_full
,
110 .status
= transient_status
,
113 static struct dm_exception_store_type _transient_compat_type
= {
115 .module
= THIS_MODULE
,
116 .ctr
= transient_ctr
,
117 .dtr
= transient_dtr
,
118 .read_metadata
= transient_read_metadata
,
119 .prepare_exception
= transient_prepare_exception
,
120 .commit_exception
= transient_commit_exception
,
121 .fraction_full
= transient_fraction_full
,
122 .status
= transient_status
,
125 int dm_transient_snapshot_init(void)
129 r
= dm_exception_store_type_register(&_transient_type
);
131 DMWARN("Unable to register transient exception store type");
135 r
= dm_exception_store_type_register(&_transient_compat_type
);
137 DMWARN("Unable to register old-style transient "
138 "exception store type");
139 dm_exception_store_type_unregister(&_transient_type
);
146 void dm_transient_snapshot_exit(void)
148 dm_exception_store_type_unregister(&_transient_type
);
149 dm_exception_store_type_unregister(&_transient_compat_type
);