dm snapshot: extend exception store functions
Supply dm_add_exception as a callback to the read_metadata function. Add a status function ready for a later patch and name the functions consistently. Signed-off-by: Jonathan Brassow <jbrassow@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com>
This commit is contained in:
parent
4db6bfe02b
commit
a159c1ac5f
@ -11,7 +11,6 @@
|
|||||||
#include <linux/pagemap.h>
|
#include <linux/pagemap.h>
|
||||||
#include <linux/vmalloc.h>
|
#include <linux/vmalloc.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/device-mapper.h>
|
|
||||||
|
|
||||||
#define DM_MSG_PREFIX "snapshot exception stores"
|
#define DM_MSG_PREFIX "snapshot exception stores"
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#define _LINUX_DM_EXCEPTION_STORE
|
#define _LINUX_DM_EXCEPTION_STORE
|
||||||
|
|
||||||
#include <linux/blkdev.h>
|
#include <linux/blkdev.h>
|
||||||
|
#include <linux/device-mapper.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The snapshot code deals with largish chunks of the disk at a
|
* The snapshot code deals with largish chunks of the disk at a
|
||||||
@ -37,7 +38,6 @@ struct dm_snap_exception {
|
|||||||
* COW device).
|
* COW device).
|
||||||
*/
|
*/
|
||||||
struct dm_exception_store {
|
struct dm_exception_store {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Destroys this object when you've finished with it.
|
* Destroys this object when you've finished with it.
|
||||||
*/
|
*/
|
||||||
@ -45,9 +45,13 @@ struct dm_exception_store {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* The target shouldn't read the COW device until this is
|
* The target shouldn't read the COW device until this is
|
||||||
* called.
|
* called. As exceptions are read from the COW, they are
|
||||||
|
* reported back via the callback.
|
||||||
*/
|
*/
|
||||||
int (*read_metadata) (struct dm_exception_store *store);
|
int (*read_metadata) (struct dm_exception_store *store,
|
||||||
|
int (*callback)(void *callback_context,
|
||||||
|
chunk_t old, chunk_t new),
|
||||||
|
void *callback_context);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find somewhere to store the next exception.
|
* Find somewhere to store the next exception.
|
||||||
@ -68,6 +72,9 @@ struct dm_exception_store {
|
|||||||
*/
|
*/
|
||||||
void (*drop_snapshot) (struct dm_exception_store *store);
|
void (*drop_snapshot) (struct dm_exception_store *store);
|
||||||
|
|
||||||
|
int (*status) (struct dm_exception_store *store, status_type_t status,
|
||||||
|
char *result, unsigned int maxlen);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return how full the snapshot is.
|
* Return how full the snapshot is.
|
||||||
*/
|
*/
|
||||||
|
@ -395,7 +395,11 @@ static void write_exception(struct pstore *ps,
|
|||||||
* 'full' is filled in to indicate if the area has been
|
* 'full' is filled in to indicate if the area has been
|
||||||
* filled.
|
* filled.
|
||||||
*/
|
*/
|
||||||
static int insert_exceptions(struct pstore *ps, int *full)
|
static int insert_exceptions(struct pstore *ps,
|
||||||
|
int (*callback)(void *callback_context,
|
||||||
|
chunk_t old, chunk_t new),
|
||||||
|
void *callback_context,
|
||||||
|
int *full)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
@ -428,7 +432,7 @@ static int insert_exceptions(struct pstore *ps, int *full)
|
|||||||
/*
|
/*
|
||||||
* Otherwise we add the exception to the snapshot.
|
* Otherwise we add the exception to the snapshot.
|
||||||
*/
|
*/
|
||||||
r = dm_add_exception(ps->snap, de.old_chunk, de.new_chunk);
|
r = callback(callback_context, de.old_chunk, de.new_chunk);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -436,7 +440,10 @@ static int insert_exceptions(struct pstore *ps, int *full)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_exceptions(struct pstore *ps)
|
static int read_exceptions(struct pstore *ps,
|
||||||
|
int (*callback)(void *callback_context, chunk_t old,
|
||||||
|
chunk_t new),
|
||||||
|
void *callback_context)
|
||||||
{
|
{
|
||||||
int r, full = 1;
|
int r, full = 1;
|
||||||
|
|
||||||
@ -449,7 +456,7 @@ static int read_exceptions(struct pstore *ps)
|
|||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = insert_exceptions(ps, &full);
|
r = insert_exceptions(ps, callback, callback_context, &full);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -482,7 +489,10 @@ static void persistent_destroy(struct dm_exception_store *store)
|
|||||||
kfree(ps);
|
kfree(ps);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int persistent_read_metadata(struct dm_exception_store *store)
|
static int persistent_read_metadata(struct dm_exception_store *store,
|
||||||
|
int (*callback)(void *callback_context,
|
||||||
|
chunk_t old, chunk_t new),
|
||||||
|
void *callback_context)
|
||||||
{
|
{
|
||||||
int r, uninitialized_var(new_snapshot);
|
int r, uninitialized_var(new_snapshot);
|
||||||
struct pstore *ps = get_info(store);
|
struct pstore *ps = get_info(store);
|
||||||
@ -540,7 +550,7 @@ static int persistent_read_metadata(struct dm_exception_store *store)
|
|||||||
/*
|
/*
|
||||||
* Read the metadata.
|
* Read the metadata.
|
||||||
*/
|
*/
|
||||||
r = read_exceptions(ps);
|
r = read_exceptions(ps, callback, callback_context);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -548,7 +558,7 @@ static int persistent_read_metadata(struct dm_exception_store *store)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int persistent_prepare(struct dm_exception_store *store,
|
static int persistent_prepare_exception(struct dm_exception_store *store,
|
||||||
struct dm_snap_exception *e)
|
struct dm_snap_exception *e)
|
||||||
{
|
{
|
||||||
struct pstore *ps = get_info(store);
|
struct pstore *ps = get_info(store);
|
||||||
@ -575,7 +585,7 @@ static int persistent_prepare(struct dm_exception_store *store,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void persistent_commit(struct dm_exception_store *store,
|
static void persistent_commit_exception(struct dm_exception_store *store,
|
||||||
struct dm_snap_exception *e,
|
struct dm_snap_exception *e,
|
||||||
void (*callback) (void *, int success),
|
void (*callback) (void *, int success),
|
||||||
void *callback_context)
|
void *callback_context)
|
||||||
@ -637,7 +647,7 @@ static void persistent_commit(struct dm_exception_store *store,
|
|||||||
ps->callback_count = 0;
|
ps->callback_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void persistent_drop(struct dm_exception_store *store)
|
static void persistent_drop_snapshot(struct dm_exception_store *store)
|
||||||
{
|
{
|
||||||
struct pstore *ps = get_info(store);
|
struct pstore *ps = get_info(store);
|
||||||
|
|
||||||
@ -675,9 +685,9 @@ int dm_create_persistent(struct dm_exception_store *store)
|
|||||||
|
|
||||||
store->destroy = persistent_destroy;
|
store->destroy = persistent_destroy;
|
||||||
store->read_metadata = persistent_read_metadata;
|
store->read_metadata = persistent_read_metadata;
|
||||||
store->prepare_exception = persistent_prepare;
|
store->prepare_exception = persistent_prepare_exception;
|
||||||
store->commit_exception = persistent_commit;
|
store->commit_exception = persistent_commit_exception;
|
||||||
store->drop_snapshot = persistent_drop;
|
store->drop_snapshot = persistent_drop_snapshot;
|
||||||
store->fraction_full = persistent_fraction_full;
|
store->fraction_full = persistent_fraction_full;
|
||||||
store->context = ps;
|
store->context = ps;
|
||||||
|
|
||||||
|
@ -28,12 +28,15 @@ static void transient_destroy(struct dm_exception_store *store)
|
|||||||
kfree(store->context);
|
kfree(store->context);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int transient_read_metadata(struct dm_exception_store *store)
|
static int transient_read_metadata(struct dm_exception_store *store,
|
||||||
|
int (*callback)(void *callback_context,
|
||||||
|
chunk_t old, chunk_t new),
|
||||||
|
void *callback_context)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int transient_prepare(struct dm_exception_store *store,
|
static int transient_prepare_exception(struct dm_exception_store *store,
|
||||||
struct dm_snap_exception *e)
|
struct dm_snap_exception *e)
|
||||||
{
|
{
|
||||||
struct transient_c *tc = (struct transient_c *) store->context;
|
struct transient_c *tc = (struct transient_c *) store->context;
|
||||||
@ -48,7 +51,7 @@ static int transient_prepare(struct dm_exception_store *store,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void transient_commit(struct dm_exception_store *store,
|
static void transient_commit_exception(struct dm_exception_store *store,
|
||||||
struct dm_snap_exception *e,
|
struct dm_snap_exception *e,
|
||||||
void (*callback) (void *, int success),
|
void (*callback) (void *, int success),
|
||||||
void *callback_context)
|
void *callback_context)
|
||||||
@ -70,8 +73,8 @@ int dm_create_transient(struct dm_exception_store *store)
|
|||||||
|
|
||||||
store->destroy = transient_destroy;
|
store->destroy = transient_destroy;
|
||||||
store->read_metadata = transient_read_metadata;
|
store->read_metadata = transient_read_metadata;
|
||||||
store->prepare_exception = transient_prepare;
|
store->prepare_exception = transient_prepare_exception;
|
||||||
store->commit_exception = transient_commit;
|
store->commit_exception = transient_commit_exception;
|
||||||
store->drop_snapshot = NULL;
|
store->drop_snapshot = NULL;
|
||||||
store->fraction_full = transient_fraction_full;
|
store->fraction_full = transient_fraction_full;
|
||||||
|
|
||||||
|
@ -430,8 +430,13 @@ out:
|
|||||||
list_add(&new_e->hash_list, e ? &e->hash_list : l);
|
list_add(&new_e->hash_list, e ? &e->hash_list : l);
|
||||||
}
|
}
|
||||||
|
|
||||||
int dm_add_exception(struct dm_snapshot *s, chunk_t old, chunk_t new)
|
/*
|
||||||
|
* Callback used by the exception stores to load exceptions when
|
||||||
|
* initialising.
|
||||||
|
*/
|
||||||
|
static int dm_add_exception(void *context, chunk_t old, chunk_t new)
|
||||||
{
|
{
|
||||||
|
struct dm_snapshot *s = context;
|
||||||
struct dm_snap_exception *e;
|
struct dm_snap_exception *e;
|
||||||
|
|
||||||
e = alloc_exception();
|
e = alloc_exception();
|
||||||
@ -660,7 +665,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
|
|||||||
spin_lock_init(&s->tracked_chunk_lock);
|
spin_lock_init(&s->tracked_chunk_lock);
|
||||||
|
|
||||||
/* Metadata must only be loaded into one table at once */
|
/* Metadata must only be loaded into one table at once */
|
||||||
r = s->store.read_metadata(&s->store);
|
r = s->store.read_metadata(&s->store, dm_add_exception, (void *)s);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
ti->error = "Failed to read snapshot metadata";
|
ti->error = "Failed to read snapshot metadata";
|
||||||
goto bad_load_and_register;
|
goto bad_load_and_register;
|
||||||
|
@ -75,12 +75,6 @@ struct dm_snapshot {
|
|||||||
struct hlist_head tracked_chunk_hash[DM_TRACKED_CHUNK_HASH_SIZE];
|
struct hlist_head tracked_chunk_hash[DM_TRACKED_CHUNK_HASH_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* Used by the exception stores to load exceptions hen
|
|
||||||
* initialising.
|
|
||||||
*/
|
|
||||||
int dm_add_exception(struct dm_snapshot *s, chunk_t old, chunk_t new);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return the number of sectors in the device.
|
* Return the number of sectors in the device.
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user