Home | History | Annotate | Line # | Download | only in metadata
snapshot_manip.c revision 1.1.1.1.2.1
      1 /*	$NetBSD: snapshot_manip.c,v 1.1.1.1.2.1 2009/05/13 18:52:43 jym Exp $	*/
      2 
      3 /*
      4  * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
      5  * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
      6  *
      7  * This file is part of LVM2.
      8  *
      9  * This copyrighted material is made available to anyone wishing to use,
     10  * modify, copy, or redistribute it subject to the terms and conditions
     11  * of the GNU Lesser General Public License v.2.1.
     12  *
     13  * You should have received a copy of the GNU Lesser General Public License
     14  * along with this program; if not, write to the Free Software Foundation,
     15  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     16  */
     17 
     18 #include "lib.h"
     19 #include "metadata.h"
     20 #include "toolcontext.h"
     21 #include "lv_alloc.h"
     22 
     23 int lv_is_origin(const struct logical_volume *lv)
     24 {
     25 	return lv->origin_count ? 1 : 0;
     26 }
     27 
     28 int lv_is_cow(const struct logical_volume *lv)
     29 {
     30 	return lv->snapshot ? 1 : 0;
     31 }
     32 
     33 int lv_is_visible(const struct logical_volume *lv)
     34 {
     35 	if (lv_is_cow(lv))
     36 		return lv_is_visible(find_cow(lv)->lv);
     37 
     38 	return lv->status & VISIBLE_LV ? 1 : 0;
     39 }
     40 
     41 int lv_is_displayable(const struct logical_volume *lv)
     42 {
     43 	if (lv->status & SNAPSHOT)
     44 		return 0;
     45 
     46 	return (lv->status & VISIBLE_LV) || lv_is_cow(lv) ? 1 : 0;
     47 }
     48 
     49 /* Given a cow LV, return the snapshot lv_segment that uses it */
     50 struct lv_segment *find_cow(const struct logical_volume *lv)
     51 {
     52 	return lv->snapshot;
     53 }
     54 
     55 /* Given a cow LV, return its origin */
     56 struct logical_volume *origin_from_cow(const struct logical_volume *lv)
     57 {
     58 	return lv->snapshot->origin;
     59 }
     60 
     61 int vg_add_snapshot(const char *name, struct logical_volume *origin,
     62 		    struct logical_volume *cow, union lvid *lvid,
     63 		    uint32_t extent_count, uint32_t chunk_size)
     64 {
     65 	struct logical_volume *snap;
     66 	struct lv_segment *seg;
     67 
     68 	/*
     69 	 * Is the cow device already being used ?
     70 	 */
     71 	if (lv_is_cow(cow)) {
     72 		log_err("'%s' is already in use as a snapshot.", cow->name);
     73 		return 0;
     74 	}
     75 
     76 	if (cow == origin) {
     77 		log_error("Snapshot and origin LVs must differ.");
     78 		return 0;
     79 	}
     80 
     81 	if (!(snap = lv_create_empty(name ? name : "snapshot%d",
     82 				     lvid, LVM_READ | LVM_WRITE | VISIBLE_LV,
     83 				     ALLOC_INHERIT, 1, origin->vg)))
     84 		return_0;
     85 
     86 	snap->le_count = extent_count;
     87 
     88 	if (!(seg = alloc_snapshot_seg(snap, 0, 0)))
     89 		return_0;
     90 
     91 	seg->chunk_size = chunk_size;
     92 	seg->origin = origin;
     93 	seg->cow = cow;
     94 	seg->lv->status |= SNAPSHOT;
     95 
     96 	origin->origin_count++;
     97 	origin->vg->snapshot_count++;
     98 	origin->vg->lv_count--;
     99 	cow->snapshot = seg;
    100 
    101 	cow->status &= ~VISIBLE_LV;
    102 
    103 	dm_list_add(&origin->snapshot_segs, &seg->origin_list);
    104 
    105 	return 1;
    106 }
    107 
    108 int vg_remove_snapshot(struct logical_volume *cow)
    109 {
    110 	dm_list_del(&cow->snapshot->origin_list);
    111 	cow->snapshot->origin->origin_count--;
    112 
    113 	if (!lv_remove(cow->snapshot->lv)) {
    114 		log_error("Failed to remove internal snapshot LV %s",
    115 			  cow->snapshot->lv->name);
    116 		return 0;
    117 	}
    118 
    119 	cow->snapshot = NULL;
    120 
    121 	cow->vg->snapshot_count--;
    122 	cow->vg->lv_count++;
    123 	cow->status |= VISIBLE_LV;
    124 
    125 	return 1;
    126 }
    127