diff --git a/lib/locking/locking.c b/lib/locking/locking.c index 98f17a709..a97581308 100644 --- a/lib/locking/locking.c +++ b/lib/locking/locking.c @@ -574,11 +574,13 @@ int remote_lock_held(const char *vol, int *exclusive) int sync_local_dev_names(struct cmd_context* cmd) { memlock_unlock(cmd); - return lock_vol(cmd, VG_SYNC_NAMES, LCK_NONE | LCK_CACHE | LCK_LOCAL); + + return lock_vol(cmd, VG_SYNC_NAMES, LCK_VG_SYNC_LOCAL); } int sync_dev_names(struct cmd_context* cmd) { memlock_unlock(cmd); - return lock_vol(cmd, VG_SYNC_NAMES, LCK_NONE | LCK_CACHE); + + return lock_vol(cmd, VG_SYNC_NAMES, LCK_VG_SYNC); } diff --git a/lib/locking/locking.h b/lib/locking/locking.h index 5b1379116..af99464e0 100644 --- a/lib/locking/locking.h +++ b/lib/locking/locking.h @@ -39,6 +39,9 @@ int remote_lock_held(const char *vol, int *exclusive); * acquired in alphabetical order of 'vol' (to avoid deadlocks), with * VG_ORPHANS last. * + * Use VG_SYNC_NAMES to wait for any outstanding asynchronous /dev nodes + * events to complete. + * * LCK_LV: * Lock/unlock an individual logical volume * char *vol holds lvid @@ -127,6 +130,9 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname); #define LCK_VG_BACKUP (LCK_VG | LCK_CACHE) +#define LCK_VG_SYNC (LCK_NONE | LCK_CACHE) +#define LCK_VG_SYNC_LOCAL (LCK_NONE | LCK_CACHE | LCK_LOCAL) + #define LCK_LV_EXCLUSIVE (LCK_LV | LCK_EXCL) #define LCK_LV_SUSPEND (LCK_LV | LCK_WRITE) #define LCK_LV_RESUME (LCK_LV | LCK_UNLOCK) @@ -175,12 +181,7 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname); lock_vol((vg)->cmd, (vg)->name, LCK_VG_REVERT) #define remote_backup_metadata(vg) \ lock_vol((vg)->cmd, (vg)->name, LCK_VG_BACKUP) -/* cleanup later -#define sync_local_dev_names(cmd) \ - lock_vol(cmd, VG_SYNC_NAMES, LCK_NONE | LCK_CACHE | LCK_LOCAL) -#define sync_dev_names(cmd) \ - lock_vol(cmd, VG_SYNC_NAMES, LCK_NONE | LCK_CACHE) -*/ + int sync_local_dev_names(struct cmd_context* cmd); int sync_dev_names(struct cmd_context* cmd); diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h index 80de552a3..331dd74af 100644 --- a/lib/metadata/metadata-exported.h +++ b/lib/metadata/metadata-exported.h @@ -196,7 +196,7 @@ struct pv_segment { #define FMT_INSTANCE_PRIVATE_MDAS 0x00000008U struct format_instance { - unsigned ref_count; + unsigned ref_count; /* Refs to this fid from VG and PV structs */ struct dm_pool *mem; uint32_t type; diff --git a/lib/metadata/mirror.c b/lib/metadata/mirror.c index 95d07bdad..b02c7bb3f 100644 --- a/lib/metadata/mirror.c +++ b/lib/metadata/mirror.c @@ -987,11 +987,11 @@ static int _remove_mirror_images(struct logical_volume *lv, } /* FIXME: second suspend should not be needed - * Explicitly suspend temporary LV - * This balance critical_section_inc() calls with critical_section_dec() in resume - * (both localy and in cluster) and also properly propagates precommited + * Explicitly suspend temporary LV. + * This balances critical_section_inc() calls with critical_section_dec() + * in resume (both local and cluster) and also properly propagates precommitted * metadata into dm table on other nodes. - * (visible flag set causes the suspend is not properly propagated?) + * FIXME: check propagation of suspend with visible flag */ if (temp_layer_lv && !suspend_lv(temp_layer_lv->vg->cmd, temp_layer_lv)) log_error("Problem suspending temporary LV %s", temp_layer_lv->name); diff --git a/lib/mm/memlock.h b/lib/mm/memlock.h index be1430599..d9e53f7f8 100644 --- a/lib/mm/memlock.h +++ b/lib/mm/memlock.h @@ -18,6 +18,19 @@ struct cmd_context; +/* + * Inside a critical section, memory is always locked. + * + * After leaving the critical section, memory stays locked until + * memlock_unlock() is called. This happens with + * sync_local_dev_names() and sync_dev_names(). + * + * This allows critical sections to be entered and exited repeatedly without + * incurring the expense of locking memory every time. + * + * memlock_reset() is necessary to clear the state after forking (polldaemon). + */ + void critical_section_inc(struct cmd_context *cmd); void critical_section_dec(struct cmd_context *cmd); int critical_section(void);