cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dm-snap-transient.c (3802B)


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