2002-02-12 19:31:31 +03:00
/*
2004-03-30 23:35:44 +04:00
* Copyright ( C ) 2002 - 2004 Sistina Software , Inc . All rights reserved .
* Copyright ( C ) 2004 Red Hat , Inc . All rights reserved .
2002-02-12 19:31:31 +03:00
*
2004-03-30 23:35:44 +04:00
* This file is part of LVM2 .
*
* This copyrighted material is made available to anyone wishing to use ,
* modify , copy , or redistribute it subject to the terms and conditions
* of the GNU General Public License v .2 .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software Foundation ,
* Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
2002-02-12 19:31:31 +03:00
*/
2002-11-18 17:04:08 +03:00
# include "lib.h"
2002-02-12 19:31:31 +03:00
# include "metadata.h"
# include "toolcontext.h"
2005-04-07 16:39:44 +04:00
# include "lv_alloc.h"
2002-02-12 19:31:31 +03:00
2002-12-20 02:25:55 +03:00
int lv_is_origin ( const struct logical_volume * lv )
2002-02-12 19:31:31 +03:00
{
2005-04-07 16:39:44 +04:00
return lv - > origin_count ? 1 : 0 ;
2002-02-12 19:31:31 +03:00
}
2002-12-20 02:25:55 +03:00
int lv_is_cow ( const struct logical_volume * lv )
2002-02-12 19:31:31 +03:00
{
2005-04-07 16:39:44 +04:00
return lv - > snapshot ? 1 : 0 ;
2002-04-24 22:20:51 +04:00
}
2005-04-07 16:39:44 +04:00
/* Given a cow LV, return the snapshot lv_segment that uses it */
struct lv_segment * find_cow ( const struct logical_volume * lv )
2002-02-21 13:16:33 +03:00
{
2005-04-07 16:39:44 +04:00
return lv - > snapshot ;
2002-02-21 13:16:33 +03:00
}
2005-04-07 16:39:44 +04:00
int vg_add_snapshot ( struct format_instance * fid , const char * name ,
struct logical_volume * origin ,
struct logical_volume * cow , union lvid * lvid ,
uint32_t extent_count , uint32_t chunk_size )
2002-05-08 20:57:46 +04:00
{
2005-04-07 16:39:44 +04:00
struct logical_volume * snap ;
struct lv_segment * seg ;
2002-02-12 19:31:31 +03:00
/*
* Is the cow device already being used ?
*/
2002-02-20 22:04:55 +03:00
if ( lv_is_cow ( cow ) ) {
2002-02-12 19:31:31 +03:00
log_err ( " '%s' is already in use as a snapshot. " , cow - > name ) ;
return 0 ;
}
2005-06-03 18:49:51 +04:00
if ( ! ( snap = lv_create_empty ( fid , name ? name : " snapshot%d " ,
2005-04-07 16:39:44 +04:00
lvid , LVM_READ | LVM_WRITE | VISIBLE_LV ,
ALLOC_INHERIT , 1 , origin - > vg ) ) ) {
2002-02-12 19:31:31 +03:00
stack ;
return 0 ;
}
2005-04-07 16:39:44 +04:00
snap - > le_count = extent_count ;
2002-02-12 19:31:31 +03:00
2005-06-01 20:51:55 +04:00
if ( ! ( seg = alloc_snapshot_seg ( snap , 0 , 0 ) ) ) {
2002-02-12 19:31:31 +03:00
stack ;
return 0 ;
}
2005-04-07 16:39:44 +04:00
seg - > chunk_size = chunk_size ;
seg - > origin = origin ;
seg - > cow = cow ;
seg - > lv - > status | = SNAPSHOT ;
origin - > origin_count + + ;
2002-12-06 01:30:39 +03:00
origin - > vg - > snapshot_count + + ;
2005-04-07 16:39:44 +04:00
origin - > vg - > lv_count - - ;
cow - > snapshot = seg ;
cow - > status & = ~ VISIBLE_LV ;
list_add ( & origin - > snapshot_segs , & seg - > origin_list ) ;
2002-02-12 19:31:31 +03:00
return 1 ;
}
2005-05-09 20:59:01 +04:00
int vg_remove_snapshot ( struct logical_volume * cow )
2002-02-12 19:31:31 +03:00
{
2005-04-07 16:39:44 +04:00
list_del ( & cow - > snapshot - > origin_list ) ;
cow - > snapshot - > origin - > origin_count - - ;
2002-02-12 19:31:31 +03:00
2005-05-09 20:59:01 +04:00
if ( ! lv_remove ( cow - > snapshot - > lv ) ) {
2005-04-07 16:39:44 +04:00
log_error ( " Failed to remove internal snapshot LV %s " ,
cow - > snapshot - > lv - > name ) ;
return 0 ;
2002-02-12 19:31:31 +03:00
}
2005-04-07 16:39:44 +04:00
cow - > snapshot = NULL ;
2005-05-09 20:59:01 +04:00
cow - > vg - > snapshot_count - - ;
cow - > vg - > lv_count + + ;
2005-04-07 16:39:44 +04:00
cow - > status | = VISIBLE_LV ;
return 1 ;
2002-02-12 19:31:31 +03:00
}