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/export.h>
14 #include <linux/slab.h>
15 #include <linux/dm-io.h>
17 #define DM_MSG_PREFIX "transient snapshot"
19 /*-----------------------------------------------------------------
20 * Implementation of the store for non-persistent snapshots.
21 *---------------------------------------------------------------*/
26 static void transient_dtr(struct dm_exception_store
*store
)
28 kfree(store
->context
);
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
)
39 static int transient_prepare_exception(struct dm_exception_store
*store
,
40 struct dm_exception
*e
)
42 struct transient_c
*tc
= store
->context
;
43 sector_t size
= get_dev_size(dm_snap_cow(store
->snap
)->bdev
);
45 if (size
< (tc
->next_free
+ store
->chunk_size
))
48 e
->new_chunk
= sector_to_chunk(store
, tc
->next_free
);
49 tc
->next_free
+= store
->chunk_size
;
54 static void transient_commit_exception(struct dm_exception_store
*store
,
55 struct dm_exception
*e
, int valid
,
56 void (*callback
) (void *, int success
),
57 void *callback_context
)
60 callback(callback_context
, valid
);
63 static void transient_usage(struct dm_exception_store
*store
,
64 sector_t
*total_sectors
,
65 sector_t
*sectors_allocated
,
66 sector_t
*metadata_sectors
)
68 *sectors_allocated
= ((struct transient_c
*) store
->context
)->next_free
;
69 *total_sectors
= get_dev_size(dm_snap_cow(store
->snap
)->bdev
);
70 *metadata_sectors
= 0;
73 static int transient_ctr(struct dm_exception_store
*store
, char *options
)
75 struct transient_c
*tc
;
77 tc
= kmalloc(sizeof(struct transient_c
), GFP_KERNEL
);
87 static unsigned transient_status(struct dm_exception_store
*store
,
88 status_type_t status
, char *result
,
96 case STATUSTYPE_TABLE
:
97 DMEMIT(" N %llu", (unsigned long long)store
->chunk_size
);
103 static struct dm_exception_store_type _transient_type
= {
105 .module
= THIS_MODULE
,
106 .ctr
= transient_ctr
,
107 .dtr
= transient_dtr
,
108 .read_metadata
= transient_read_metadata
,
109 .prepare_exception
= transient_prepare_exception
,
110 .commit_exception
= transient_commit_exception
,
111 .usage
= transient_usage
,
112 .status
= transient_status
,
115 static struct dm_exception_store_type _transient_compat_type
= {
117 .module
= THIS_MODULE
,
118 .ctr
= transient_ctr
,
119 .dtr
= transient_dtr
,
120 .read_metadata
= transient_read_metadata
,
121 .prepare_exception
= transient_prepare_exception
,
122 .commit_exception
= transient_commit_exception
,
123 .usage
= transient_usage
,
124 .status
= transient_status
,
127 int dm_transient_snapshot_init(void)
131 r
= dm_exception_store_type_register(&_transient_type
);
133 DMWARN("Unable to register transient exception store type");
137 r
= dm_exception_store_type_register(&_transient_compat_type
);
139 DMWARN("Unable to register old-style transient "
140 "exception store type");
141 dm_exception_store_type_unregister(&_transient_type
);
148 void dm_transient_snapshot_exit(void)
150 dm_exception_store_type_unregister(&_transient_type
);
151 dm_exception_store_type_unregister(&_transient_compat_type
);