2009-01-06 06:05:15 +03:00
/*
* Copyright ( C ) 2001 - 2002 Sistina Software ( UK ) Limited .
* Copyright ( C ) 2008 Red Hat , Inc . All rights reserved .
*
* Device - mapper snapshot exception store .
*
* This file is released under the GPL .
*/
# ifndef _LINUX_DM_EXCEPTION_STORE
# define _LINUX_DM_EXCEPTION_STORE
# include <linux/blkdev.h>
2009-01-06 06:05:19 +03:00
# include <linux/device-mapper.h>
2009-01-06 06:05:15 +03:00
/*
* The snapshot code deals with largish chunks of the disk at a
* time . Typically 32 k - 512 k .
*/
typedef sector_t chunk_t ;
/*
* An exception is used where an old chunk of data has been
* replaced by a new one .
* If chunk_t is 64 bits in size , the top 8 bits of new_chunk hold the number
* of chunks that follow contiguously . Remaining bits hold the number of the
* chunk within the device .
*/
struct dm_snap_exception {
struct list_head hash_list ;
chunk_t old_chunk ;
chunk_t new_chunk ;
} ;
/*
* Abstraction to handle the meta / layout of exception stores ( the
* COW device ) .
*/
2009-04-02 22:55:30 +04:00
struct dm_exception_store ;
struct dm_exception_store_type {
int ( * ctr ) ( struct dm_exception_store * store ,
unsigned argc , char * * argv ) ;
2009-01-06 06:05:15 +03:00
/*
* Destroys this object when you ' ve finished with it .
*/
2009-04-02 22:55:30 +04:00
void ( * dtr ) ( struct dm_exception_store * store ) ;
2009-01-06 06:05:15 +03:00
/*
* The target shouldn ' t read the COW device until this is
2009-01-06 06:05:19 +03:00
* called . As exceptions are read from the COW , they are
* reported back via the callback .
2009-01-06 06:05:15 +03:00
*/
2009-01-06 06:05:19 +03:00
int ( * read_metadata ) ( struct dm_exception_store * store ,
int ( * callback ) ( void * callback_context ,
chunk_t old , chunk_t new ) ,
void * callback_context ) ;
2009-01-06 06:05:15 +03:00
/*
* Find somewhere to store the next exception .
*/
2009-01-06 06:05:16 +03:00
int ( * prepare_exception ) ( struct dm_exception_store * store ,
2009-01-06 06:05:15 +03:00
struct dm_snap_exception * e ) ;
/*
* Update the metadata with this exception .
*/
2009-01-06 06:05:16 +03:00
void ( * commit_exception ) ( struct dm_exception_store * store ,
2009-01-06 06:05:15 +03:00
struct dm_snap_exception * e ,
void ( * callback ) ( void * , int success ) ,
void * callback_context ) ;
/*
* The snapshot is invalid , note this in the metadata .
*/
2009-01-06 06:05:16 +03:00
void ( * drop_snapshot ) ( struct dm_exception_store * store ) ;
2009-01-06 06:05:15 +03:00
2009-01-06 06:05:19 +03:00
int ( * status ) ( struct dm_exception_store * store , status_type_t status ,
char * result , unsigned int maxlen ) ;
2009-01-06 06:05:15 +03:00
/*
* Return how full the snapshot is .
*/
2009-01-06 06:05:16 +03:00
void ( * fraction_full ) ( struct dm_exception_store * store ,
2009-01-06 06:05:15 +03:00
sector_t * numerator ,
sector_t * denominator ) ;
2009-04-02 22:55:30 +04:00
} ;
struct dm_exception_store {
struct dm_exception_store_type type ;
2009-01-06 06:05:15 +03:00
struct dm_snapshot * snap ;
2009-04-02 22:55:30 +04:00
2009-01-06 06:05:15 +03:00
void * context ;
} ;
/*
* Funtions to manipulate consecutive chunks
*/
# if defined(CONFIG_LBD) || (BITS_PER_LONG == 64)
# define DM_CHUNK_CONSECUTIVE_BITS 8
# define DM_CHUNK_NUMBER_BITS 56
static inline chunk_t dm_chunk_number ( chunk_t chunk )
{
return chunk & ( chunk_t ) ( ( 1ULL < < DM_CHUNK_NUMBER_BITS ) - 1ULL ) ;
}
static inline unsigned dm_consecutive_chunk_count ( struct dm_snap_exception * e )
{
return e - > new_chunk > > DM_CHUNK_NUMBER_BITS ;
}
static inline void dm_consecutive_chunk_count_inc ( struct dm_snap_exception * e )
{
e - > new_chunk + = ( 1ULL < < DM_CHUNK_NUMBER_BITS ) ;
BUG_ON ( ! dm_consecutive_chunk_count ( e ) ) ;
}
# else
# define DM_CHUNK_CONSECUTIVE_BITS 0
static inline chunk_t dm_chunk_number ( chunk_t chunk )
{
return chunk ;
}
static inline unsigned dm_consecutive_chunk_count ( struct dm_snap_exception * e )
{
return 0 ;
}
static inline void dm_consecutive_chunk_count_inc ( struct dm_snap_exception * e )
{
}
# endif
2009-01-06 06:05:17 +03:00
int dm_exception_store_init ( void ) ;
void dm_exception_store_exit ( void ) ;
2009-01-06 06:05:15 +03:00
/*
* Two exception store implementations .
*/
2009-01-06 06:05:17 +03:00
int dm_persistent_snapshot_init ( void ) ;
void dm_persistent_snapshot_exit ( void ) ;
int dm_transient_snapshot_init ( void ) ;
void dm_transient_snapshot_exit ( void ) ;
2009-01-06 06:05:16 +03:00
int dm_create_persistent ( struct dm_exception_store * store ) ;
2009-01-06 06:05:15 +03:00
2009-01-06 06:05:16 +03:00
int dm_create_transient ( struct dm_exception_store * store ) ;
2009-01-06 06:05:15 +03:00
# endif /* _LINUX_DM_EXCEPTION_STORE */