From fbc263659bc75ab311a108add6b336af841fe4c1 Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Thu, 19 Aug 2010 23:26:31 +0000 Subject: [PATCH] Fix wrong use of LCK_WRITE In all top vg read functions only LCK_VG_READ/WRITE can be used. All other vg lock definitions are low-level backend machinery. Moreover, LCK_WRITE cannot be tested through bitmask. This patch fixes these mistakes. For _recover_vg() we do not need lock_flags, it can be only two of above and we always upgrading to LCK_VG_WRITE lock there. (N.B. that code is racy) There is no functional change in code (despite wrong masking it produces correct bits:-) --- WHATS_NEW | 1 + daemons/clvmd/clvmd-singlenode.c | 6 ++++-- lib/metadata/metadata.c | 16 ++++++---------- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/WHATS_NEW b/WHATS_NEW index 848b696af..20bdeb0c0 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -4,6 +4,7 @@ Version 2.02.74 - Remove assumption that --yes must be used only in --force mode. Fix file descriptor leak in swap signature detection error path. Detect and allow abort in pvcreate if LUKS signature is detected. + Use proper locks mask when checking for LCK_WRITE. Version 2.02.73 - 18th August 2010 ================================== diff --git a/daemons/clvmd/clvmd-singlenode.c b/daemons/clvmd/clvmd-singlenode.c index 0cd4c9cca..75a23d61c 100644 --- a/daemons/clvmd/clvmd-singlenode.c +++ b/daemons/clvmd/clvmd-singlenode.c @@ -155,11 +155,13 @@ static int _lock_resource(const char *resource, int mode, int flags, int *lockid if (!_resources[i]) break; if (!strcmp(_resources[i], resource)) { - if ((_locks[i] & LCK_WRITE) || (_locks[i] & LCK_EXCL)) { + if ((_locks[i] & LCK_TYPE_MASK) == LCK_WRITE || + (_locks[i] & LCK_TYPE_MASK) == LCK_EXCL) { DEBUGLOG("%s already write/exclusively locked...\n", resource); goto maybe_retry; } - if ((mode & LCK_WRITE) || (mode & LCK_EXCL)) { + if ((mode & LCK_TYPE_MASK) == LCK_WRITE || + (mode & LCK_TYPE_MASK) == LCK_EXCL) { DEBUGLOG("%s already locked and WRITE/EXCL lock requested...\n", resource); goto maybe_retry; diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c index ed00ffa18..92cca478b 100644 --- a/lib/metadata/metadata.c +++ b/lib/metadata/metadata.c @@ -3834,20 +3834,16 @@ int vg_check_status(const struct volume_group *vg, uint64_t status) } static struct volume_group *_recover_vg(struct cmd_context *cmd, - const char *vg_name, const char *vgid, - uint32_t lock_flags) + const char *vg_name, const char *vgid) { int consistent = 1; struct volume_group *vg; - lock_flags &= ~LCK_TYPE_MASK; - lock_flags |= LCK_WRITE; - unlock_vg(cmd, vg_name); dev_close_all(); - if (!lock_vol(cmd, vg_name, lock_flags)) + if (!lock_vol(cmd, vg_name, LCK_VG_WRITE)) return_NULL; if (!(vg = vg_read_internal(cmd, vg_name, vgid, &consistent))) @@ -3882,7 +3878,7 @@ static struct volume_group *_vg_lock_and_read(struct cmd_context *cmd, const cha uint32_t failure = 0; int already_locked; - if (misc_flags & READ_ALLOW_INCONSISTENT || !(lock_flags & LCK_WRITE)) + if (misc_flags & READ_ALLOW_INCONSISTENT || lock_flags != LCK_VG_WRITE) consistent = 0; if (!validate_name(vg_name) && !is_orphan_vg(vg_name)) { @@ -3927,7 +3923,7 @@ static struct volume_group *_vg_lock_and_read(struct cmd_context *cmd, const cha /* consistent == 0 when VG is not found, but failed == FAILED_NOTFOUND */ if (!consistent && !failure) { vg_release(vg); - if (!(vg = _recover_vg(cmd, vg_name, vgid, lock_flags))) { + if (!(vg = _recover_vg(cmd, vg_name, vgid))) { log_error("Recovery of volume group \"%s\" failed.", vg_name); failure |= FAILED_INCONSISTENT; @@ -3941,7 +3937,7 @@ static struct volume_group *_vg_lock_and_read(struct cmd_context *cmd, const cha */ if (!cmd->handles_missing_pvs && vg_missing_pv_count(vg) && - (lock_flags & LCK_WRITE)) { + lock_flags == LCK_VG_WRITE) { log_error("Cannot change VG %s while PVs are missing.", vg->name); log_error("Consider vgreduce --removemissing."); failure |= FAILED_INCONSISTENT; /* FIXME new failure code here? */ @@ -3949,7 +3945,7 @@ static struct volume_group *_vg_lock_and_read(struct cmd_context *cmd, const cha } if (!cmd->handles_unknown_segments && vg_has_unknown_segments(vg) && - (lock_flags & LCK_WRITE)) { + lock_flags == LCK_VG_WRITE) { log_error("Cannot change VG %s with unknown segments in it!", vg->name); failure |= FAILED_INCONSISTENT; /* FIXME new failure code here? */