Introduce struct dm_exception_store_type.
Signed-off-by: Jonathan Brassow <jbrassow@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
  * Abstraction to handle the meta/layout of exception stores (the
  * COW device).
  */
-struct dm_exception_store {
+struct dm_exception_store;
+struct dm_exception_store_type {
+       int (*ctr) (struct dm_exception_store *store,
+                   unsigned argc, char **argv);
+
        /*
         * Destroys this object when you've finished with it.
         */
-       void (*destroy) (struct dm_exception_store *store);
+       void (*dtr) (struct dm_exception_store *store);
 
        /*
         * The target shouldn't read the COW device until this is
        void (*fraction_full) (struct dm_exception_store *store,
                               sector_t *numerator,
                               sector_t *denominator);
+};
+
+struct dm_exception_store {
+       struct dm_exception_store_type type;
 
        struct dm_snapshot *snap;
+
        void *context;
 };
 
 
                return -ENOMEM;
        }
 
-       store->destroy = persistent_destroy;
-       store->read_metadata = persistent_read_metadata;
-       store->prepare_exception = persistent_prepare_exception;
-       store->commit_exception = persistent_commit_exception;
-       store->drop_snapshot = persistent_drop_snapshot;
-       store->fraction_full = persistent_fraction_full;
+       store->type.dtr = persistent_destroy;
+       store->type.read_metadata = persistent_read_metadata;
+       store->type.prepare_exception = persistent_prepare_exception;
+       store->type.commit_exception = persistent_commit_exception;
+       store->type.drop_snapshot = persistent_drop_snapshot;
+       store->type.fraction_full = persistent_fraction_full;
+
        store->context = ps;
 
        return 0;
 
 static int transient_prepare_exception(struct dm_exception_store *store,
                                       struct dm_snap_exception *e)
 {
-       struct transient_c *tc = (struct transient_c *) store->context;
+       struct transient_c *tc = store->context;
        sector_t size = get_dev_size(store->snap->cow->bdev);
 
        if (size < (tc->next_free + store->snap->chunk_size))
 {
        struct transient_c *tc;
 
-       store->destroy = transient_destroy;
-       store->read_metadata = transient_read_metadata;
-       store->prepare_exception = transient_prepare_exception;
-       store->commit_exception = transient_commit_exception;
-       store->drop_snapshot = NULL;
-       store->fraction_full = transient_fraction_full;
+       store->type.dtr = transient_destroy;
+       store->type.read_metadata = transient_read_metadata;
+       store->type.prepare_exception = transient_prepare_exception;
+       store->type.commit_exception = transient_commit_exception;
+       store->type.drop_snapshot = NULL;
+       store->type.fraction_full = transient_fraction_full;
 
        tc = kmalloc(sizeof(struct transient_c), GFP_KERNEL);
        if (!tc)
 
        spin_lock_init(&s->tracked_chunk_lock);
 
        /* Metadata must only be loaded into one table at once */
-       r = s->store.read_metadata(&s->store, dm_add_exception, (void *)s);
+       r = s->store.type.read_metadata(&s->store, dm_add_exception, (void *)s);
        if (r < 0) {
                ti->error = "Failed to read snapshot metadata";
                goto bad_load_and_register;
        dm_kcopyd_client_destroy(s->kcopyd_client);
 
  bad5:
-       s->store.destroy(&s->store);
+       s->store.type.dtr(&s->store);
 
  bad4:
        exit_exception_table(&s->pending, pending_cache);
        exit_exception_table(&s->pending, pending_cache);
        exit_exception_table(&s->complete, exception_cache);
 
-       s->store.destroy(&s->store);
+       s->store.type.dtr(&s->store);
 }
 
 static void snapshot_dtr(struct dm_target *ti)
        else if (err == -ENOMEM)
                DMERR("Invalidating snapshot: Unable to allocate exception.");
 
-       if (s->store.drop_snapshot)
-               s->store.drop_snapshot(&s->store);
+       if (s->store.type.drop_snapshot)
+               s->store.type.drop_snapshot(&s->store);
 
        s->valid = 0;
 
 
        else
                /* Update the metadata if we are persistent */
-               s->store.commit_exception(&s->store, &pe->e, commit_callback,
-                                         pe);
+               s->store.type.commit_exception(&s->store, &pe->e,
+                                              commit_callback, pe);
 }
 
 /*
        atomic_set(&pe->ref_count, 0);
        pe->started = 0;
 
-       if (s->store.prepare_exception(&s->store, &pe->e)) {
+       if (s->store.type.prepare_exception(&s->store, &pe->e)) {
                free_pending_exception(pe);
                return NULL;
        }
                if (!snap->valid)
                        snprintf(result, maxlen, "Invalid");
                else {
-                       if (snap->store.fraction_full) {
+                       if (snap->store.type.fraction_full) {
                                sector_t numerator, denominator;
-                               snap->store.fraction_full(&snap->store,
+                               snap->store.type.fraction_full(&snap->store,
                                                          &numerator,
                                                          &denominator);
                                snprintf(result, maxlen, "%llu/%llu",