From 20e2c64fce02650fdff3cce430fe4cf0ef57aa14 Mon Sep 17 00:00:00 2001 From: Alasdair Kergon Date: Tue, 13 Dec 2005 15:49:26 +0000 Subject: [PATCH] Add sync, nosync and block_on_error mirror log parameters. Add hweight32. --- WHATS_NEW | 2 ++ lib/libdevmapper.h | 18 +++++++++++++ lib/libdm-deptree.c | 63 ++++++++++++++++++++++++++++++++++++++------- 3 files changed, 74 insertions(+), 9 deletions(-) diff --git a/WHATS_NEW b/WHATS_NEW index 21a19c4..13195dc 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,7 @@ Version 1.02.03 - ============================ + Add sync, nosync and block_on_error mirror log parameters. + Add hweight32. Fix dmeventd build. Version 1.02.02 - 2 Dec 2005 diff --git a/lib/libdevmapper.h b/lib/libdevmapper.h index 2d13ef4..0cb0f1f 100644 --- a/lib/libdevmapper.h +++ b/lib/libdevmapper.h @@ -331,9 +331,16 @@ int dm_tree_node_add_striped_target(struct dm_tree_node *node, uint32_t stripe_size); int dm_tree_node_add_mirror_target(struct dm_tree_node *node, uint64_t size); + +/* Mirror log flags */ +#define DM_NOSYNC 0x00000001 /* Known already in sync */ +#define DM_FORCESYNC 0x00000002 /* Force resync */ +#define DM_BLOCK_ON_ERROR 0x00000004 /* On error, suspend I/O */ + int dm_tree_node_add_mirror_target_log(struct dm_tree_node *node, uint32_t region_size, unsigned clustered, + uint32_t flags, const char *log_uuid, unsigned area_count); int dm_tree_node_add_target_area(struct dm_tree_node *node, @@ -509,6 +516,17 @@ int dm_bit_get_next(dm_bitset_t bs, int last_bit); #define dm_bit_copy(bs1, bs2) \ memcpy(bs1 + 1, bs2 + 1, ((*bs1 / DM_BITS_PER_INT) + 1) * sizeof(int)) +/* Returns number of set bits */ +static inline unsigned hweight32(uint32_t i) +{ + unsigned r = (i & 0x55555555) + ((i >> 1) & 0x55555555); + + r = (r & 0x33333333) + ((r >> 2) & 0x33333333); + r = (r & 0x0F0F0F0F) + ((r >> 4) & 0x0F0F0F0F); + r = (r & 0x00FF00FF) + ((r >> 8) & 0x00FF00FF); + return (r & 0x0000FFFF) + ((r >> 16) & 0x0000FFFF); +} + /**************** * hash functions ****************/ diff --git a/lib/libdm-deptree.c b/lib/libdm-deptree.c index f6447d9..20164be 100644 --- a/lib/libdm-deptree.c +++ b/lib/libdm-deptree.c @@ -85,6 +85,7 @@ struct load_segment { uint32_t region_size; /* Mirror */ unsigned clustered; /* Mirror */ unsigned mirror_area_count; /* Mirror */ + uint32_t flags; /* Mirror log */ }; /* Per-device properties */ @@ -1211,10 +1212,12 @@ static int _emit_areas_line(struct dm_task *dmt, struct load_segment *seg, char static int _emit_segment_line(struct dm_task *dmt, struct load_segment *seg, uint64_t *seg_start, char *params, size_t paramsize) { + unsigned log_parm_count; int pos = 0; int tw; int r; char originbuf[10], cowbuf[10], logbuf[10]; + const char *logtype; switch(seg->type) { case SEG_ERROR: @@ -1230,26 +1233,66 @@ static int _emit_segment_line(struct dm_task *dmt, struct load_segment *seg, uin } pos += tw; } - if (!seg->log) { - if ((tw = _dm_snprintf(params + pos, paramsize - pos, "core 1 ")) < 0) { - stack; /* Out of space */ - return -1; - } - pos += tw; - } else { + + log_parm_count = hweight32(seg->flags) + 1; + + if (!seg->log) + logtype = "core"; + else { + logtype = "disk"; + log_parm_count++; if (!_build_dev_string(logbuf, sizeof(logbuf), seg->log)) return_0; - if ((tw = _dm_snprintf(params + pos, paramsize - pos, "disk 2 %s ", logbuf)) < 0) { + } + + if ((tw = _dm_snprintf(params + pos, paramsize - pos, "%s %u ", logtype, log_parm_count)) < 0) { + stack; /* Out of space */ + return -1; + } + pos += tw; + + if (seg->log) { + if ((tw = _dm_snprintf(params + pos, paramsize - pos, "%s ", logbuf)) < 0) { stack; /* Out of space */ return -1; } pos += tw; } - if ((tw = _dm_snprintf(params + pos, paramsize - pos, "%u %u ", seg->region_size, seg->mirror_area_count)) < 0) { + + if ((tw = _dm_snprintf(params + pos, paramsize - pos, "%u ", seg->region_size)) < 0) { stack; /* Out of space */ return -1; } pos += tw; + + if ((seg->flags & DM_NOSYNC)) { + if ((tw = _dm_snprintf(params + pos, paramsize - pos, "nosync ")) < 0) { + stack; /* Out of space */ + return -1; + } + pos += tw; + } else if ((seg->flags & DM_FORCESYNC)) { + if ((tw = _dm_snprintf(params + pos, paramsize - pos, "sync ")) < 0) { + stack; /* Out of space */ + return -1; + } + pos += tw; + } + + if ((seg->flags & DM_BLOCK_ON_ERROR)) { + if ((tw = _dm_snprintf(params + pos, paramsize - pos, "block_on_error ")) < 0) { + stack; /* Out of space */ + return -1; + } + pos += tw; + } + + if ((tw = _dm_snprintf(params + pos, paramsize - pos, "%u ", seg->mirror_area_count)) < 0) { + stack; /* Out of space */ + return -1; + } + pos += tw; + break; case SEG_SNAPSHOT: if (!_build_dev_string(originbuf, sizeof(originbuf), seg->origin)) @@ -1619,6 +1662,7 @@ int dm_tree_node_add_striped_target(struct dm_tree_node *node, int dm_tree_node_add_mirror_target_log(struct dm_tree_node *node, uint32_t region_size, unsigned clustered, + uint32_t flags, const char *log_uuid, unsigned area_count) { @@ -1645,6 +1689,7 @@ int dm_tree_node_add_mirror_target_log(struct dm_tree_node *node, seg->region_size = region_size; seg->clustered = clustered; seg->mirror_area_count = area_count; + seg->flags = flags; return 1; } -- 2.43.5