Loading drivers/md/dm-exception-store.c +162 −0 Original line number Diff line number Diff line Loading @@ -14,6 +14,168 @@ #define DM_MSG_PREFIX "snapshot exception stores" static LIST_HEAD(_exception_store_types); static DEFINE_SPINLOCK(_lock); static struct dm_exception_store_type *__find_exception_store_type(const char *name) { struct dm_exception_store_type *type; list_for_each_entry(type, &_exception_store_types, list) if (!strcmp(name, type->name)) return type; return NULL; } static struct dm_exception_store_type *_get_exception_store_type(const char *name) { struct dm_exception_store_type *type; spin_lock(&_lock); type = __find_exception_store_type(name); if (type && !try_module_get(type->module)) type = NULL; spin_unlock(&_lock); return type; } /* * get_type * @type_name * * Attempt to retrieve the dm_exception_store_type by name. If not already * available, attempt to load the appropriate module. * * Exstore modules are named "dm-exstore-" followed by the 'type_name'. * Modules may contain multiple types. * This function will first try the module "dm-exstore-<type_name>", * then truncate 'type_name' on the last '-' and try again. * * For example, if type_name was "clustered-shared", it would search * 'dm-exstore-clustered-shared' then 'dm-exstore-clustered'. * * 'dm-exception-store-<type_name>' is too long of a name in my * opinion, which is why I've chosen to have the files * containing exception store implementations be 'dm-exstore-<type_name>'. * If you want your module to be autoloaded, you will follow this * naming convention. * * Returns: dm_exception_store_type* on success, NULL on failure */ static struct dm_exception_store_type *get_type(const char *type_name) { char *p, *type_name_dup; struct dm_exception_store_type *type; type = _get_exception_store_type(type_name); if (type) return type; type_name_dup = kstrdup(type_name, GFP_KERNEL); if (!type_name_dup) { DMERR("No memory left to attempt load for \"%s\"", type_name); return NULL; } while (request_module("dm-exstore-%s", type_name_dup) || !(type = _get_exception_store_type(type_name))) { p = strrchr(type_name_dup, '-'); if (!p) break; p[0] = '\0'; } if (!type) DMWARN("Module for exstore type \"%s\" not found.", type_name); kfree(type_name_dup); return type; } static void put_type(struct dm_exception_store_type *type) { spin_lock(&_lock); module_put(type->module); spin_unlock(&_lock); } int dm_exception_store_type_register(struct dm_exception_store_type *type) { int r = 0; spin_lock(&_lock); if (!__find_exception_store_type(type->name)) list_add(&type->list, &_exception_store_types); else r = -EEXIST; spin_unlock(&_lock); return r; } EXPORT_SYMBOL(dm_exception_store_type_register); int dm_exception_store_type_unregister(struct dm_exception_store_type *type) { spin_lock(&_lock); if (!__find_exception_store_type(type->name)) { spin_unlock(&_lock); return -EINVAL; } list_del(&type->list); spin_unlock(&_lock); return 0; } EXPORT_SYMBOL(dm_exception_store_type_unregister); int dm_exception_store_create(const char *type_name, struct dm_exception_store **store) { int r = 0; struct dm_exception_store_type *type; struct dm_exception_store *tmp_store; tmp_store = kmalloc(sizeof(*tmp_store), GFP_KERNEL); if (!tmp_store) return -ENOMEM; type = get_type(type_name); if (!type) { kfree(tmp_store); return -EINVAL; } tmp_store->type = type; r = type->ctr(tmp_store, 0, NULL); if (r) { put_type(type); kfree(tmp_store); return r; } *store = tmp_store; return 0; } EXPORT_SYMBOL(dm_exception_store_create); void dm_exception_store_destroy(struct dm_exception_store *store) { store->type->dtr(store); put_type(store->type); kfree(store); } EXPORT_SYMBOL(dm_exception_store_destroy); int dm_exception_store_init(void) { int r; Loading drivers/md/dm-exception-store.h +14 −5 Original line number Diff line number Diff line Loading @@ -39,6 +39,9 @@ struct dm_snap_exception { */ struct dm_exception_store; struct dm_exception_store_type { const char *name; struct module *module; int (*ctr) (struct dm_exception_store *store, unsigned argc, char **argv); Loading Loading @@ -85,10 +88,13 @@ struct dm_exception_store_type { void (*fraction_full) (struct dm_exception_store *store, sector_t *numerator, sector_t *denominator); /* For internal device-mapper use only. */ struct list_head list; }; struct dm_exception_store { struct dm_exception_store_type type; struct dm_exception_store_type *type; struct dm_snapshot *snap; Loading Loading @@ -138,6 +144,13 @@ static inline void dm_consecutive_chunk_count_inc(struct dm_snap_exception *e) # endif int dm_exception_store_type_register(struct dm_exception_store_type *type); int dm_exception_store_type_unregister(struct dm_exception_store_type *type); int dm_exception_store_create(const char *type_name, struct dm_exception_store **store); void dm_exception_store_destroy(struct dm_exception_store *store); int dm_exception_store_init(void); void dm_exception_store_exit(void); Loading @@ -150,8 +163,4 @@ void dm_persistent_snapshot_exit(void); int dm_transient_snapshot_init(void); void dm_transient_snapshot_exit(void); int dm_create_persistent(struct dm_exception_store *store); int dm_create_transient(struct dm_exception_store *store); #endif /* _LINUX_DM_EXCEPTION_STORE */ drivers/md/dm-snap-persistent.c +57 −10 Original line number Diff line number Diff line Loading @@ -478,7 +478,7 @@ static void persistent_fraction_full(struct dm_exception_store *store, *denominator = get_dev_size(store->snap->cow->bdev); } static void persistent_destroy(struct dm_exception_store *store) static void persistent_dtr(struct dm_exception_store *store) { struct pstore *ps = get_info(store); Loading Loading @@ -656,7 +656,8 @@ static void persistent_drop_snapshot(struct dm_exception_store *store) DMWARN("write header failed"); } int dm_create_persistent(struct dm_exception_store *store) static int persistent_ctr(struct dm_exception_store *store, unsigned argc, char **argv) { struct pstore *ps; Loading @@ -683,23 +684,69 @@ int dm_create_persistent(struct dm_exception_store *store) return -ENOMEM; } 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 persistent_status(struct dm_exception_store *store, status_type_t status, char *result, unsigned int maxlen) { int sz = 0; return sz; } static struct dm_exception_store_type _persistent_type = { .name = "persistent", .module = THIS_MODULE, .ctr = persistent_ctr, .dtr = persistent_dtr, .read_metadata = persistent_read_metadata, .prepare_exception = persistent_prepare_exception, .commit_exception = persistent_commit_exception, .drop_snapshot = persistent_drop_snapshot, .fraction_full = persistent_fraction_full, .status = persistent_status, }; static struct dm_exception_store_type _persistent_compat_type = { .name = "P", .module = THIS_MODULE, .ctr = persistent_ctr, .dtr = persistent_dtr, .read_metadata = persistent_read_metadata, .prepare_exception = persistent_prepare_exception, .commit_exception = persistent_commit_exception, .drop_snapshot = persistent_drop_snapshot, .fraction_full = persistent_fraction_full, .status = persistent_status, }; int dm_persistent_snapshot_init(void) { return 0; int r; r = dm_exception_store_type_register(&_persistent_type); if (r) { DMERR("Unable to register persistent exception store type"); return r; } r = dm_exception_store_type_register(&_persistent_compat_type); if (r) { DMERR("Unable to register old-style persistent exception " "store type"); dm_exception_store_type_unregister(&_persistent_type); return r; } return r; } void dm_persistent_snapshot_exit(void) { dm_exception_store_type_unregister(&_persistent_type); dm_exception_store_type_unregister(&_persistent_compat_type); } drivers/md/dm-snap-transient.c +55 −10 Original line number Diff line number Diff line Loading @@ -23,7 +23,7 @@ struct transient_c { sector_t next_free; }; static void transient_destroy(struct dm_exception_store *store) static void transient_dtr(struct dm_exception_store *store) { kfree(store->context); } Loading Loading @@ -67,17 +67,11 @@ static void transient_fraction_full(struct dm_exception_store *store, *denominator = get_dev_size(store->snap->cow->bdev); } int dm_create_transient(struct dm_exception_store *store) static int transient_ctr(struct dm_exception_store *store, unsigned argc, char **argv) { struct transient_c *tc; 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) return -ENOMEM; Loading @@ -88,11 +82,62 @@ int dm_create_transient(struct dm_exception_store *store) return 0; } static int transient_status(struct dm_exception_store *store, status_type_t status, char *result, unsigned maxlen) { int sz = 0; return sz; } static struct dm_exception_store_type _transient_type = { .name = "transient", .module = THIS_MODULE, .ctr = transient_ctr, .dtr = transient_dtr, .read_metadata = transient_read_metadata, .prepare_exception = transient_prepare_exception, .commit_exception = transient_commit_exception, .fraction_full = transient_fraction_full, .status = transient_status, }; static struct dm_exception_store_type _transient_compat_type = { .name = "N", .module = THIS_MODULE, .ctr = transient_ctr, .dtr = transient_dtr, .read_metadata = transient_read_metadata, .prepare_exception = transient_prepare_exception, .commit_exception = transient_commit_exception, .fraction_full = transient_fraction_full, .status = transient_status, }; int dm_transient_snapshot_init(void) { return 0; int r; r = dm_exception_store_type_register(&_transient_type); if (r) { DMWARN("Unable to register transient exception store type"); return r; } r = dm_exception_store_type_register(&_transient_compat_type); if (r) { DMWARN("Unable to register old-style transient " "exception store type"); dm_exception_store_type_unregister(&_transient_type); return r; } return r; } void dm_transient_snapshot_exit(void) { dm_exception_store_type_unregister(&_transient_type); dm_exception_store_type_unregister(&_transient_compat_type); } drivers/md/dm-snap.c +18 −23 Original line number Diff line number Diff line Loading @@ -610,8 +610,6 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) if (r) goto bad3; s->type = persistent; s->valid = 1; s->active = 0; atomic_set(&s->pending_exceptions_count, 0); Loading @@ -626,19 +624,15 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) goto bad3; } s->store.snap = s; if (persistent == 'P') r = dm_create_persistent(&s->store); else r = dm_create_transient(&s->store); r = dm_exception_store_create(argv[2], &s->store); if (r) { ti->error = "Couldn't create exception store"; r = -EINVAL; goto bad4; } s->store->snap = s; r = dm_kcopyd_client_create(SNAPSHOT_PAGES, &s->kcopyd_client); if (r) { ti->error = "Could not create kcopyd client"; Loading @@ -665,7 +659,8 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) spin_lock_init(&s->tracked_chunk_lock); /* Metadata must only be loaded into one table at once */ r = s->store.type.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; Loading Loading @@ -700,7 +695,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) dm_kcopyd_client_destroy(s->kcopyd_client); bad5: s->store.type.dtr(&s->store); s->store->type->dtr(s->store); bad4: exit_exception_table(&s->pending, pending_cache); Loading @@ -725,7 +720,7 @@ static void __free_exceptions(struct dm_snapshot *s) exit_exception_table(&s->pending, pending_cache); exit_exception_table(&s->complete, exception_cache); s->store.type.dtr(&s->store); s->store->type->dtr(s->store); } static void snapshot_dtr(struct dm_target *ti) Loading Loading @@ -820,8 +815,8 @@ static void __invalidate_snapshot(struct dm_snapshot *s, int err) else if (err == -ENOMEM) DMERR("Invalidating snapshot: Unable to allocate exception."); if (s->store.type.drop_snapshot) s->store.type.drop_snapshot(&s->store); if (s->store->type->drop_snapshot) s->store->type->drop_snapshot(s->store); s->valid = 0; Loading Loading @@ -943,7 +938,7 @@ static void copy_callback(int read_err, unsigned long write_err, void *context) else /* Update the metadata if we are persistent */ s->store.type.commit_exception(&s->store, &pe->e, s->store->type->commit_exception(s->store, &pe->e, commit_callback, pe); } Loading Loading @@ -1010,7 +1005,7 @@ __find_pending_exception(struct dm_snapshot *s, atomic_set(&pe->ref_count, 0); pe->started = 0; if (s->store.type.prepare_exception(&s->store, &pe->e)) { if (s->store->type->prepare_exception(s->store, &pe->e)) { free_pending_exception(pe); return NULL; } Loading Loading @@ -1149,9 +1144,9 @@ static int snapshot_status(struct dm_target *ti, status_type_t type, if (!snap->valid) snprintf(result, maxlen, "Invalid"); else { if (snap->store.type.fraction_full) { if (snap->store->type->fraction_full) { sector_t numerator, denominator; snap->store.type.fraction_full(&snap->store, snap->store->type->fraction_full(snap->store, &numerator, &denominator); snprintf(result, maxlen, "%llu/%llu", Loading @@ -1169,9 +1164,9 @@ static int snapshot_status(struct dm_target *ti, status_type_t type, * to make private copies if the output is to * make sense. */ snprintf(result, maxlen, "%s %s %c %llu", snprintf(result, maxlen, "%s %s %s %llu", snap->origin->name, snap->cow->name, snap->type, snap->store->type->name, (unsigned long long)snap->chunk_size); break; } Loading Loading
drivers/md/dm-exception-store.c +162 −0 Original line number Diff line number Diff line Loading @@ -14,6 +14,168 @@ #define DM_MSG_PREFIX "snapshot exception stores" static LIST_HEAD(_exception_store_types); static DEFINE_SPINLOCK(_lock); static struct dm_exception_store_type *__find_exception_store_type(const char *name) { struct dm_exception_store_type *type; list_for_each_entry(type, &_exception_store_types, list) if (!strcmp(name, type->name)) return type; return NULL; } static struct dm_exception_store_type *_get_exception_store_type(const char *name) { struct dm_exception_store_type *type; spin_lock(&_lock); type = __find_exception_store_type(name); if (type && !try_module_get(type->module)) type = NULL; spin_unlock(&_lock); return type; } /* * get_type * @type_name * * Attempt to retrieve the dm_exception_store_type by name. If not already * available, attempt to load the appropriate module. * * Exstore modules are named "dm-exstore-" followed by the 'type_name'. * Modules may contain multiple types. * This function will first try the module "dm-exstore-<type_name>", * then truncate 'type_name' on the last '-' and try again. * * For example, if type_name was "clustered-shared", it would search * 'dm-exstore-clustered-shared' then 'dm-exstore-clustered'. * * 'dm-exception-store-<type_name>' is too long of a name in my * opinion, which is why I've chosen to have the files * containing exception store implementations be 'dm-exstore-<type_name>'. * If you want your module to be autoloaded, you will follow this * naming convention. * * Returns: dm_exception_store_type* on success, NULL on failure */ static struct dm_exception_store_type *get_type(const char *type_name) { char *p, *type_name_dup; struct dm_exception_store_type *type; type = _get_exception_store_type(type_name); if (type) return type; type_name_dup = kstrdup(type_name, GFP_KERNEL); if (!type_name_dup) { DMERR("No memory left to attempt load for \"%s\"", type_name); return NULL; } while (request_module("dm-exstore-%s", type_name_dup) || !(type = _get_exception_store_type(type_name))) { p = strrchr(type_name_dup, '-'); if (!p) break; p[0] = '\0'; } if (!type) DMWARN("Module for exstore type \"%s\" not found.", type_name); kfree(type_name_dup); return type; } static void put_type(struct dm_exception_store_type *type) { spin_lock(&_lock); module_put(type->module); spin_unlock(&_lock); } int dm_exception_store_type_register(struct dm_exception_store_type *type) { int r = 0; spin_lock(&_lock); if (!__find_exception_store_type(type->name)) list_add(&type->list, &_exception_store_types); else r = -EEXIST; spin_unlock(&_lock); return r; } EXPORT_SYMBOL(dm_exception_store_type_register); int dm_exception_store_type_unregister(struct dm_exception_store_type *type) { spin_lock(&_lock); if (!__find_exception_store_type(type->name)) { spin_unlock(&_lock); return -EINVAL; } list_del(&type->list); spin_unlock(&_lock); return 0; } EXPORT_SYMBOL(dm_exception_store_type_unregister); int dm_exception_store_create(const char *type_name, struct dm_exception_store **store) { int r = 0; struct dm_exception_store_type *type; struct dm_exception_store *tmp_store; tmp_store = kmalloc(sizeof(*tmp_store), GFP_KERNEL); if (!tmp_store) return -ENOMEM; type = get_type(type_name); if (!type) { kfree(tmp_store); return -EINVAL; } tmp_store->type = type; r = type->ctr(tmp_store, 0, NULL); if (r) { put_type(type); kfree(tmp_store); return r; } *store = tmp_store; return 0; } EXPORT_SYMBOL(dm_exception_store_create); void dm_exception_store_destroy(struct dm_exception_store *store) { store->type->dtr(store); put_type(store->type); kfree(store); } EXPORT_SYMBOL(dm_exception_store_destroy); int dm_exception_store_init(void) { int r; Loading
drivers/md/dm-exception-store.h +14 −5 Original line number Diff line number Diff line Loading @@ -39,6 +39,9 @@ struct dm_snap_exception { */ struct dm_exception_store; struct dm_exception_store_type { const char *name; struct module *module; int (*ctr) (struct dm_exception_store *store, unsigned argc, char **argv); Loading Loading @@ -85,10 +88,13 @@ struct dm_exception_store_type { void (*fraction_full) (struct dm_exception_store *store, sector_t *numerator, sector_t *denominator); /* For internal device-mapper use only. */ struct list_head list; }; struct dm_exception_store { struct dm_exception_store_type type; struct dm_exception_store_type *type; struct dm_snapshot *snap; Loading Loading @@ -138,6 +144,13 @@ static inline void dm_consecutive_chunk_count_inc(struct dm_snap_exception *e) # endif int dm_exception_store_type_register(struct dm_exception_store_type *type); int dm_exception_store_type_unregister(struct dm_exception_store_type *type); int dm_exception_store_create(const char *type_name, struct dm_exception_store **store); void dm_exception_store_destroy(struct dm_exception_store *store); int dm_exception_store_init(void); void dm_exception_store_exit(void); Loading @@ -150,8 +163,4 @@ void dm_persistent_snapshot_exit(void); int dm_transient_snapshot_init(void); void dm_transient_snapshot_exit(void); int dm_create_persistent(struct dm_exception_store *store); int dm_create_transient(struct dm_exception_store *store); #endif /* _LINUX_DM_EXCEPTION_STORE */
drivers/md/dm-snap-persistent.c +57 −10 Original line number Diff line number Diff line Loading @@ -478,7 +478,7 @@ static void persistent_fraction_full(struct dm_exception_store *store, *denominator = get_dev_size(store->snap->cow->bdev); } static void persistent_destroy(struct dm_exception_store *store) static void persistent_dtr(struct dm_exception_store *store) { struct pstore *ps = get_info(store); Loading Loading @@ -656,7 +656,8 @@ static void persistent_drop_snapshot(struct dm_exception_store *store) DMWARN("write header failed"); } int dm_create_persistent(struct dm_exception_store *store) static int persistent_ctr(struct dm_exception_store *store, unsigned argc, char **argv) { struct pstore *ps; Loading @@ -683,23 +684,69 @@ int dm_create_persistent(struct dm_exception_store *store) return -ENOMEM; } 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 persistent_status(struct dm_exception_store *store, status_type_t status, char *result, unsigned int maxlen) { int sz = 0; return sz; } static struct dm_exception_store_type _persistent_type = { .name = "persistent", .module = THIS_MODULE, .ctr = persistent_ctr, .dtr = persistent_dtr, .read_metadata = persistent_read_metadata, .prepare_exception = persistent_prepare_exception, .commit_exception = persistent_commit_exception, .drop_snapshot = persistent_drop_snapshot, .fraction_full = persistent_fraction_full, .status = persistent_status, }; static struct dm_exception_store_type _persistent_compat_type = { .name = "P", .module = THIS_MODULE, .ctr = persistent_ctr, .dtr = persistent_dtr, .read_metadata = persistent_read_metadata, .prepare_exception = persistent_prepare_exception, .commit_exception = persistent_commit_exception, .drop_snapshot = persistent_drop_snapshot, .fraction_full = persistent_fraction_full, .status = persistent_status, }; int dm_persistent_snapshot_init(void) { return 0; int r; r = dm_exception_store_type_register(&_persistent_type); if (r) { DMERR("Unable to register persistent exception store type"); return r; } r = dm_exception_store_type_register(&_persistent_compat_type); if (r) { DMERR("Unable to register old-style persistent exception " "store type"); dm_exception_store_type_unregister(&_persistent_type); return r; } return r; } void dm_persistent_snapshot_exit(void) { dm_exception_store_type_unregister(&_persistent_type); dm_exception_store_type_unregister(&_persistent_compat_type); }
drivers/md/dm-snap-transient.c +55 −10 Original line number Diff line number Diff line Loading @@ -23,7 +23,7 @@ struct transient_c { sector_t next_free; }; static void transient_destroy(struct dm_exception_store *store) static void transient_dtr(struct dm_exception_store *store) { kfree(store->context); } Loading Loading @@ -67,17 +67,11 @@ static void transient_fraction_full(struct dm_exception_store *store, *denominator = get_dev_size(store->snap->cow->bdev); } int dm_create_transient(struct dm_exception_store *store) static int transient_ctr(struct dm_exception_store *store, unsigned argc, char **argv) { struct transient_c *tc; 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) return -ENOMEM; Loading @@ -88,11 +82,62 @@ int dm_create_transient(struct dm_exception_store *store) return 0; } static int transient_status(struct dm_exception_store *store, status_type_t status, char *result, unsigned maxlen) { int sz = 0; return sz; } static struct dm_exception_store_type _transient_type = { .name = "transient", .module = THIS_MODULE, .ctr = transient_ctr, .dtr = transient_dtr, .read_metadata = transient_read_metadata, .prepare_exception = transient_prepare_exception, .commit_exception = transient_commit_exception, .fraction_full = transient_fraction_full, .status = transient_status, }; static struct dm_exception_store_type _transient_compat_type = { .name = "N", .module = THIS_MODULE, .ctr = transient_ctr, .dtr = transient_dtr, .read_metadata = transient_read_metadata, .prepare_exception = transient_prepare_exception, .commit_exception = transient_commit_exception, .fraction_full = transient_fraction_full, .status = transient_status, }; int dm_transient_snapshot_init(void) { return 0; int r; r = dm_exception_store_type_register(&_transient_type); if (r) { DMWARN("Unable to register transient exception store type"); return r; } r = dm_exception_store_type_register(&_transient_compat_type); if (r) { DMWARN("Unable to register old-style transient " "exception store type"); dm_exception_store_type_unregister(&_transient_type); return r; } return r; } void dm_transient_snapshot_exit(void) { dm_exception_store_type_unregister(&_transient_type); dm_exception_store_type_unregister(&_transient_compat_type); }
drivers/md/dm-snap.c +18 −23 Original line number Diff line number Diff line Loading @@ -610,8 +610,6 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) if (r) goto bad3; s->type = persistent; s->valid = 1; s->active = 0; atomic_set(&s->pending_exceptions_count, 0); Loading @@ -626,19 +624,15 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) goto bad3; } s->store.snap = s; if (persistent == 'P') r = dm_create_persistent(&s->store); else r = dm_create_transient(&s->store); r = dm_exception_store_create(argv[2], &s->store); if (r) { ti->error = "Couldn't create exception store"; r = -EINVAL; goto bad4; } s->store->snap = s; r = dm_kcopyd_client_create(SNAPSHOT_PAGES, &s->kcopyd_client); if (r) { ti->error = "Could not create kcopyd client"; Loading @@ -665,7 +659,8 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) spin_lock_init(&s->tracked_chunk_lock); /* Metadata must only be loaded into one table at once */ r = s->store.type.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; Loading Loading @@ -700,7 +695,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) dm_kcopyd_client_destroy(s->kcopyd_client); bad5: s->store.type.dtr(&s->store); s->store->type->dtr(s->store); bad4: exit_exception_table(&s->pending, pending_cache); Loading @@ -725,7 +720,7 @@ static void __free_exceptions(struct dm_snapshot *s) exit_exception_table(&s->pending, pending_cache); exit_exception_table(&s->complete, exception_cache); s->store.type.dtr(&s->store); s->store->type->dtr(s->store); } static void snapshot_dtr(struct dm_target *ti) Loading Loading @@ -820,8 +815,8 @@ static void __invalidate_snapshot(struct dm_snapshot *s, int err) else if (err == -ENOMEM) DMERR("Invalidating snapshot: Unable to allocate exception."); if (s->store.type.drop_snapshot) s->store.type.drop_snapshot(&s->store); if (s->store->type->drop_snapshot) s->store->type->drop_snapshot(s->store); s->valid = 0; Loading Loading @@ -943,7 +938,7 @@ static void copy_callback(int read_err, unsigned long write_err, void *context) else /* Update the metadata if we are persistent */ s->store.type.commit_exception(&s->store, &pe->e, s->store->type->commit_exception(s->store, &pe->e, commit_callback, pe); } Loading Loading @@ -1010,7 +1005,7 @@ __find_pending_exception(struct dm_snapshot *s, atomic_set(&pe->ref_count, 0); pe->started = 0; if (s->store.type.prepare_exception(&s->store, &pe->e)) { if (s->store->type->prepare_exception(s->store, &pe->e)) { free_pending_exception(pe); return NULL; } Loading Loading @@ -1149,9 +1144,9 @@ static int snapshot_status(struct dm_target *ti, status_type_t type, if (!snap->valid) snprintf(result, maxlen, "Invalid"); else { if (snap->store.type.fraction_full) { if (snap->store->type->fraction_full) { sector_t numerator, denominator; snap->store.type.fraction_full(&snap->store, snap->store->type->fraction_full(snap->store, &numerator, &denominator); snprintf(result, maxlen, "%llu/%llu", Loading @@ -1169,9 +1164,9 @@ static int snapshot_status(struct dm_target *ti, status_type_t type, * to make private copies if the output is to * make sense. */ snprintf(result, maxlen, "%s %s %c %llu", snprintf(result, maxlen, "%s %s %s %llu", snap->origin->name, snap->cow->name, snap->type, snap->store->type->name, (unsigned long long)snap->chunk_size); break; } Loading