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_exception
*e
)
41 struct transient_c
*tc
= store
->context
;
42 sector_t size
= get_dev_size(dm_snap_cow(store
->snap
)->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_exception
*e
,
55 void (*callback
) (void *, int success
),
56 void *callback_context
)
59 callback(callback_context
, 1);
62 static void transient_usage(struct dm_exception_store
*store
,
63 sector_t
*total_sectors
,
64 sector_t
*sectors_allocated
,
65 sector_t
*metadata_sectors
)
67 *sectors_allocated
= ((struct transient_c
*) store
->context
)->next_free
;
68 *total_sectors
= get_dev_size(dm_snap_cow(store
->snap
)->bdev
);
69 *metadata_sectors
= 0;
72 static int transient_ctr(struct dm_exception_store
*store
,
73 unsigned argc
, char **argv
)
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
);