brintos

brintos / linux-shallow public Read only

0
0
Text · 3.8 KiB · 1e07a74 Raw
159 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (C) 2001-2002 Sistina Software (UK) Limited.4 * Copyright (C) 2006-2008 Red Hat GmbH5 *6 * This file is released under the GPL.7 */8 9#include "dm-exception-store.h"10 11#include <linux/mm.h>12#include <linux/pagemap.h>13#include <linux/vmalloc.h>14#include <linux/export.h>15#include <linux/slab.h>16#include <linux/dm-io.h>17 18#define DM_MSG_PREFIX "transient snapshot"19 20/*21 *---------------------------------------------------------------22 * Implementation of the store for non-persistent snapshots.23 *---------------------------------------------------------------24 */25struct transient_c {26	sector_t next_free;27};28 29static void transient_dtr(struct dm_exception_store *store)30{31	kfree(store->context);32}33 34static int transient_read_metadata(struct dm_exception_store *store,35				   int (*callback)(void *callback_context,36						   chunk_t old, chunk_t new),37				   void *callback_context)38{39	return 0;40}41 42static int transient_prepare_exception(struct dm_exception_store *store,43				       struct dm_exception *e)44{45	struct transient_c *tc = store->context;46	sector_t size = get_dev_size(dm_snap_cow(store->snap)->bdev);47 48	if (size < (tc->next_free + store->chunk_size))49		return -1;50 51	e->new_chunk = sector_to_chunk(store, tc->next_free);52	tc->next_free += store->chunk_size;53 54	return 0;55}56 57static void transient_commit_exception(struct dm_exception_store *store,58				       struct dm_exception *e, int valid,59				       void (*callback)(void *, int success),60				       void *callback_context)61{62	/* Just succeed */63	callback(callback_context, valid);64}65 66static void transient_usage(struct dm_exception_store *store,67			    sector_t *total_sectors,68			    sector_t *sectors_allocated,69			    sector_t *metadata_sectors)70{71	*sectors_allocated = ((struct transient_c *) store->context)->next_free;72	*total_sectors = get_dev_size(dm_snap_cow(store->snap)->bdev);73	*metadata_sectors = 0;74}75 76static int transient_ctr(struct dm_exception_store *store, char *options)77{78	struct transient_c *tc;79 80	tc = kmalloc(sizeof(struct transient_c), GFP_KERNEL);81	if (!tc)82		return -ENOMEM;83 84	tc->next_free = 0;85	store->context = tc;86 87	return 0;88}89 90static unsigned int transient_status(struct dm_exception_store *store,91				 status_type_t status, char *result,92				 unsigned int maxlen)93{94	unsigned int sz = 0;95 96	switch (status) {97	case STATUSTYPE_INFO:98		break;99	case STATUSTYPE_TABLE:100		DMEMIT(" N %llu", (unsigned long long)store->chunk_size);101		break;102	case STATUSTYPE_IMA:103		*result = '\0';104		break;105	}106 107	return sz;108}109 110static struct dm_exception_store_type _transient_type = {111	.name = "transient",112	.module = THIS_MODULE,113	.ctr = transient_ctr,114	.dtr = transient_dtr,115	.read_metadata = transient_read_metadata,116	.prepare_exception = transient_prepare_exception,117	.commit_exception = transient_commit_exception,118	.usage = transient_usage,119	.status = transient_status,120};121 122static struct dm_exception_store_type _transient_compat_type = {123	.name = "N",124	.module = THIS_MODULE,125	.ctr = transient_ctr,126	.dtr = transient_dtr,127	.read_metadata = transient_read_metadata,128	.prepare_exception = transient_prepare_exception,129	.commit_exception = transient_commit_exception,130	.usage = transient_usage,131	.status = transient_status,132};133 134int dm_transient_snapshot_init(void)135{136	int r;137 138	r = dm_exception_store_type_register(&_transient_type);139	if (r) {140		DMWARN("Unable to register transient exception store type");141		return r;142	}143 144	r = dm_exception_store_type_register(&_transient_compat_type);145	if (r) {146		DMWARN("Unable to register old-style transient exception store type");147		dm_exception_store_type_unregister(&_transient_type);148		return r;149	}150 151	return r;152}153 154void dm_transient_snapshot_exit(void)155{156	dm_exception_store_type_unregister(&_transient_type);157	dm_exception_store_type_unregister(&_transient_compat_type);158}159