]> sourceware.org Git - lvm2.git/commitdiff
Thin fix transaction_id incrementation and code refactoring
authorZdenek Kabelac <zkabelac@redhat.com>
Wed, 25 Jan 2012 08:55:19 +0000 (08:55 +0000)
committerZdenek Kabelac <zkabelac@redhat.com>
Wed, 25 Jan 2012 08:55:19 +0000 (08:55 +0000)
Add pool_has_message and use it in attach_pool_message.
Also update header to make more obvious which segment type is
expected as parameter.
Rename  'read_only' to  'no_update' (no auto update transaction_id)
to better fit how it's used.
Fix problem when there was only one stacked message replaced with delete
message that caused unwanted transaction_id increase.

lib/metadata/metadata.h
lib/metadata/thin_manip.c

index a8d28e980a8d93f10d0bc400da7ff458ebd503f8..bdac68302352adedc794702145dae8d067cb27cf 100644 (file)
@@ -452,16 +452,18 @@ int fixup_imported_mirrors(struct volume_group *vg);
 /*
  * From thin_manip.c
  */
-int attach_pool_metadata_lv(struct lv_segment *seg,
+int attach_pool_metadata_lv(struct lv_segment *pool_seg,
                            struct logical_volume *pool_metadata_lv);
-int attach_pool_data_lv(struct lv_segment *seg,
+int attach_pool_data_lv(struct lv_segment *pool_seg,
                        struct logical_volume *pool_data_lv);
 int attach_pool_lv(struct lv_segment *seg, struct logical_volume *pool_lv,
                   struct logical_volume *origin_lv);
 int detach_pool_lv(struct lv_segment *seg);
-int attach_pool_message(struct lv_segment *seg, dm_thin_message_t type,
+int attach_pool_message(struct lv_segment *pool_seg, dm_thin_message_t type,
                        struct logical_volume *lv, uint32_t delete_id,
-                       int read_only);
+                       int auto_increment);
+int pool_has_message(const struct lv_segment *seg,
+                    const struct logical_volume *lv, uint32_t device_id);
 int extend_pool(struct logical_volume *lv, const struct segment_type *segtype,
                struct alloc_handle *ah, uint32_t stripes, uint32_t stripe_size);
 
index e6a8dd7484d0d11e178d487434da3797675cb31d..167e24c2a55c884a6a99cdc8a4e9c962cb0afb17 100644 (file)
 #include "lv_alloc.h"
 #include "archiver.h"
 
-int attach_pool_metadata_lv(struct lv_segment *seg, struct logical_volume *metadata_lv)
+int attach_pool_metadata_lv(struct lv_segment *pool_seg, struct logical_volume *metadata_lv)
 {
-       seg->metadata_lv = metadata_lv;
+       pool_seg->metadata_lv = metadata_lv;
        metadata_lv->status |= THIN_POOL_METADATA;
        lv_set_hidden(metadata_lv);
 
-       return add_seg_to_segs_using_this_lv(metadata_lv, seg);
+       return add_seg_to_segs_using_this_lv(metadata_lv, pool_seg);
 }
 
-int attach_pool_data_lv(struct lv_segment *seg, struct logical_volume *pool_data_lv)
+int attach_pool_data_lv(struct lv_segment *pool_seg, struct logical_volume *pool_data_lv)
 {
-       if (!set_lv_segment_area_lv(seg, 0, pool_data_lv, 0, THIN_POOL_DATA))
+       if (!set_lv_segment_area_lv(pool_seg, 0, pool_data_lv, 0, THIN_POOL_DATA))
                return_0;
 
        lv_set_hidden(pool_data_lv);
@@ -56,6 +56,7 @@ int detach_pool_lv(struct lv_segment *seg)
 {
        struct lv_thin_message *tmsg, *tmp;
        struct seg_list *sl, *tsl;
+       int no_update = 0;
 
        if (!seg->pool_lv || !lv_is_thin_pool(seg->pool_lv)) {
                log_error(INTERNAL_ERROR "LV %s is not a thin volume",
@@ -64,15 +65,16 @@ int detach_pool_lv(struct lv_segment *seg)
        }
 
        /* Drop any message referencing removed segment */
-       dm_list_iterate_items_safe(tmsg, tmp, &first_seg(seg->pool_lv)->thin_messages) {
+       dm_list_iterate_items_safe(tmsg, tmp, &(first_seg(seg->pool_lv)->thin_messages)) {
                switch (tmsg->type) {
                case DM_THIN_MESSAGE_CREATE_SNAP:
                case DM_THIN_MESSAGE_CREATE_THIN:
                case DM_THIN_MESSAGE_TRIM:
-                       if (first_seg(tmsg->u.lv) == seg) {
+                       if (tmsg->u.lv == seg->lv) {
                                log_debug("Discarding message for LV %s.",
                                          tmsg->u.lv->name);
                                dm_list_del(&tmsg->list);
+                               no_update = 1; /* Replacing existing */
                        }
                        break;
                case DM_THIN_MESSAGE_DELETE:
@@ -90,7 +92,7 @@ int detach_pool_lv(struct lv_segment *seg)
 
        if (!attach_pool_message(first_seg(seg->pool_lv),
                                 DM_THIN_MESSAGE_DELETE,
-                                NULL, seg->device_id, 0))
+                                NULL, seg->device_id, no_update))
                return_0;
 
        if (!remove_seg_from_segs_using_this_lv(seg->pool_lv, seg))
@@ -119,40 +121,28 @@ int detach_pool_lv(struct lv_segment *seg)
        return 1;
 }
 
-int attach_pool_message(struct lv_segment *seg, dm_thin_message_t type,
+int attach_pool_message(struct lv_segment *pool_seg, dm_thin_message_t type,
                        struct logical_volume *lv, uint32_t delete_id,
-                       int read_only)
+                       int no_update)
 {
        struct lv_thin_message *tmsg;
 
-       dm_list_iterate_items(tmsg, &seg->thin_messages) {
-               if (tmsg->type != type)
-                       continue;
+       if (!seg_is_thin_pool(pool_seg)) {
+               log_error(INTERNAL_ERROR "LV %s is not pool.", pool_seg->lv->name);
+               return 0;
+       }
 
-               switch (tmsg->type) {
-               case DM_THIN_MESSAGE_CREATE_SNAP:
-               case DM_THIN_MESSAGE_CREATE_THIN:
-               case DM_THIN_MESSAGE_TRIM:
-                       if (tmsg->u.lv == lv) {
-                               log_error("Message referring LV %s already queued for %s.",
-                                         tmsg->u.lv->name, seg->lv->name);
-                               return 0;
-                       }
-                       break;
-               case DM_THIN_MESSAGE_DELETE:
-                       if (tmsg->u.delete_id == delete_id) {
-                               log_error("Delete of device %u already queued for %s.",
-                                         tmsg->u.delete_id, seg->lv->name);
-                               return 0;
-                       }
-                       break;
-               default:
-                       log_error(INTERNAL_ERROR "Unsupported message type %u.", tmsg->type);
-                       return 0;
-               }
+       if (pool_has_message(pool_seg, lv, delete_id)) {
+               if (lv)
+                       log_error("Message referring LV %s already queued in pool %s.",
+                                 lv->name, pool_seg->lv->name);
+               else
+                       log_error("Delete for device %u already queued in pool %s.",
+                                 delete_id, pool_seg->lv->name);
+               return 0;
        }
 
-       if (!(tmsg = dm_pool_alloc(seg->lv->vg->vgmem, sizeof(*tmsg)))) {
+       if (!(tmsg = dm_pool_alloc(pool_seg->lv->vg->vgmem, sizeof(*tmsg)))) {
                log_error("Failed to allocate memory for message.");
                return 0;
        }
@@ -174,10 +164,10 @@ int attach_pool_message(struct lv_segment *seg, dm_thin_message_t type,
        tmsg->type = type;
 
        /* If the 1st message is add in non-read-only mode, modify transaction_id */
-       if (!read_only && dm_list_empty(&seg->thin_messages))
-               seg->transaction_id++;
+       if (!no_update && dm_list_empty(&pool_seg->thin_messages))
+               pool_seg->transaction_id++;
 
-       dm_list_add(&seg->thin_messages, &tmsg->list);
+       dm_list_add(&pool_seg->thin_messages, &tmsg->list);
 
        log_debug("Added %s message",
                  (type == DM_THIN_MESSAGE_CREATE_SNAP ||
@@ -188,6 +178,43 @@ int attach_pool_message(struct lv_segment *seg, dm_thin_message_t type,
        return 1;
 }
 
+/*
+ * Check whether pool has some message queued for LV or for device_id
+ * When LV is NULL and device_id is 0 it just checks for any message.
+ */
+int pool_has_message(const struct lv_segment *seg,
+                    const struct logical_volume *lv, uint32_t device_id)
+{
+       const struct lv_thin_message *tmsg;
+
+       if (!seg_is_thin_pool(seg)) {
+               log_error(INTERNAL_ERROR "LV %s is not pool.", seg->lv->name);
+               return 0;
+       }
+
+       if (!lv && !device_id)
+               return dm_list_empty(&seg->thin_messages);
+
+       dm_list_iterate_items(tmsg, &seg->thin_messages) {
+               switch (tmsg->type) {
+               case DM_THIN_MESSAGE_CREATE_SNAP:
+               case DM_THIN_MESSAGE_CREATE_THIN:
+               case DM_THIN_MESSAGE_TRIM:
+                       if (tmsg->u.lv == lv)
+                               return 1;
+                       break;
+               case DM_THIN_MESSAGE_DELETE:
+                       if (tmsg->u.delete_id == device_id)
+                               return 1;
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       return 0;
+}
+
 struct lv_segment *find_pool_seg(const struct lv_segment *seg)
 {
        struct lv_segment *pool_seg;
This page took 0.039044 seconds and 5 git commands to generate.