]> sourceware.org Git - lvm2.git/commitdiff
lv: introduce lvseg_percent_with_info_and_seg_status
authorZdenek Kabelac <zkabelac@redhat.com>
Wed, 25 May 2016 14:18:38 +0000 (16:18 +0200)
committerZdenek Kabelac <zkabelac@redhat.com>
Fri, 27 May 2016 13:47:24 +0000 (15:47 +0200)
Add function to obtain percentage value for cache lv_seg_status.
This API is rather evolving 'middle' step as the ultimate goal
is segment API fuctionality.

But first we need to be clear at reporting level which values
are needed to be reported for which LVs and segments.

WHATS_NEW
lib/metadata/lv.c
lib/metadata/lv.h

index 2265c9b5b3360205aef7fb3cc3e94263a066c4b4..9f270c6fb534bd6be13fdb74f654e90553153536 100644 (file)
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
 Version 2.02.155 - 
 ================================
+  Add lvseg_percent_with_info_and_seg_status() for percent retrieval.
   Enhance internal seg_status handling to understand snapshots better.
   When refresh failed in suspend, call resume upon error path.
   Support passthrough cache mode when waiting for clean cache.
index 0a531cfd89535656cdd0447399579e993ad2a9f3..92ea3a94b9bf217432589a629a759f9b46e64dc1 100644 (file)
@@ -345,6 +345,88 @@ uint64_t lvseg_size(const struct lv_segment *seg)
        return (uint64_t) seg->len * seg->lv->vg->extent_size;
 }
 
+dm_percent_t lvseg_percent_with_info_and_seg_status(const struct lv_with_info_and_seg_status *lvdm,
+                                                   percent_get_t type)
+{
+       dm_percent_t p;
+       uint64_t csize;
+       const struct lv_segment *seg;
+       const struct lv_seg_status *s = &lvdm->seg_status;
+
+       /*
+        * TODO:
+        *   Later move to segment methods, instead of using single place.
+        *   Also handle logic for mirror segments and it total_* summing
+        *   Esentially rework  _target_percent API for segtype.
+        */
+       switch (s->type) {
+       case SEG_STATUS_CACHE:
+               if (s->cache->fail || s->cache->error)
+                       p = DM_PERCENT_INVALID;
+               else {
+                       switch (type) {
+                       case PERCENT_GET_DIRTY:
+                               p = dm_make_percent(s->cache->dirty_blocks,
+                                                   s->cache->used_blocks);
+                               break;
+                       case PERCENT_GET_METADATA:
+                               p = dm_make_percent(s->cache->metadata_used_blocks,
+                                                   s->cache->metadata_total_blocks);
+                               break;
+                       default:
+                               p = dm_make_percent(s->cache->used_blocks,
+                                                   s->cache->total_blocks);
+                       }
+               }
+               break;
+       case SEG_STATUS_SNAPSHOT:
+               if (s->snapshot->invalid || s->snapshot->merge_failed)
+                       p = DM_PERCENT_INVALID;
+               else if (s->snapshot->has_metadata_sectors &&
+                        (s->snapshot->used_sectors == s->snapshot->metadata_sectors))
+                       p = DM_PERCENT_0;
+               else
+                       p = dm_make_percent(s->snapshot->used_sectors,
+                                           s->snapshot->total_sectors);
+               break;
+       case SEG_STATUS_THIN_POOL:
+               if (s->thin_pool->fail || s->thin_pool->error)
+                       p = DM_PERCENT_INVALID;
+               else if (type == PERCENT_GET_METADATA)
+                       p = dm_make_percent(s->thin_pool->used_metadata_blocks,
+                                           s->thin_pool->total_metadata_blocks);
+               else
+                       p = dm_make_percent(s->thin_pool->used_data_blocks,
+                                           s->thin_pool->total_data_blocks);
+               break;
+       case SEG_STATUS_THIN:
+               if (s->thin->fail || (type != PERCENT_GET_DATA))
+                       /* TODO: expose highest mapped sector */
+                       p = DM_PERCENT_INVALID;
+               else {
+                       seg = first_seg(lvdm->lv);
+                       /* Pool allocates whole chunk so round-up to nearest one */
+                       csize = first_seg(seg->pool_lv)->chunk_size;
+                       csize = ((seg->lv->size + csize - 1) / csize) * csize;
+                       if (s->thin->mapped_sectors <= csize)
+                               p = dm_make_percent(s->thin->mapped_sectors, csize);
+                       else {
+                               log_warn("WARNING: Thin volume %s maps %s while the size is only %s.",
+                                        display_lvname(seg->lv),
+                                        display_size(lvdm->lv->vg->cmd, s->thin->mapped_sectors),
+                                        display_size(lvdm->lv->vg->cmd, csize));
+                               /* Don't show nonsense numbers like i.e. 1000% full */
+                               p = DM_PERCENT_100;
+                       }
+               }
+               break;
+       default:
+               p = DM_PERCENT_INVALID;
+       }
+
+       return p;
+}
+
 uint32_t lv_kernel_read_ahead(const struct logical_volume *lv)
 {
        struct lvinfo info;
index 08fc090c70ee5e0d1fb2a6887012c1185dffebe0..9f871d67c7a6ce3a9bda1a44c401d55cf3c8ff42 100644 (file)
@@ -197,4 +197,13 @@ char *lv_profile_dup(struct dm_pool *mem, const struct logical_volume *lv);
 char *lv_lock_args_dup(struct dm_pool *mem, const struct logical_volume *lv);
 char *lvseg_kernel_discards_dup_with_info_and_seg_status(struct dm_pool *mem, const struct lv_with_info_and_seg_status *lvdm);
 char *lv_time_dup(struct dm_pool *mem, const struct logical_volume *lv, int iso_mode);
+
+typedef enum {
+       PERCENT_GET_DATA = 0,
+       PERCENT_GET_METADATA,
+       PERCENT_GET_DIRTY
+} percent_get_t;
+dm_percent_t lvseg_percent_with_info_and_seg_status(const struct lv_with_info_and_seg_status *lvdm,
+                                                   percent_get_t type);
+
 #endif /* _LVM_LV_H */
This page took 0.053613 seconds and 5 git commands to generate.