As other flag handling in dlm we switch ls_exflags to use atomic operation to manipulate flags. This should prepare for a possible manipulating of lkb_exflags flags at the same time by concurrent execution.
Signed-off-by: Alexander Aring <aahri...@redhat.com> --- fs/dlm/dlm_internal.h | 23 ++++++++++++++++++++++- fs/dlm/lockspace.c | 2 +- fs/dlm/rcom.c | 6 +++--- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h index 986a9d7b1f33..48e9152555a8 100644 --- a/fs/dlm/dlm_internal.h +++ b/fs/dlm/dlm_internal.h @@ -548,7 +548,7 @@ struct dlm_ls { dlm_lockspace_t *ls_local_handle; uint32_t ls_global_id; /* global unique lockspace ID */ uint32_t ls_generation; - uint32_t ls_exflags; + unsigned long ls_exflags; int ls_lvblen; atomic_t ls_count; /* refcount of processes in the dlm using this ls */ @@ -771,6 +771,11 @@ static inline uint32_t dlm_dflags_val(const struct dlm_lkb *lkb) #define DLM_SBF_ALTMODE_BIT 2 #define __DLM_SBF_MAX_BIT DLM_SBF_ALTMODE_BIT +#define DLM_LSFL_TIMEWARN_BIT 1 +#define __DLM_LSFL_MIN_BIT DLM_LSFL_TIMEWARN_BIT +#define DLM_LSFL_NEWEXCL_BIT 3 +#define __DLM_LSFL_MAX_BIT DLM_LSFL_NEWEXCL_BIT + static inline uint32_t dlm_sbflags_val(const struct dlm_lkb *lkb) { /* be sure the next person updates this */ @@ -780,6 +785,16 @@ static inline uint32_t dlm_sbflags_val(const struct dlm_lkb *lkb) __DLM_SBF_MAX_BIT); } +static inline uint32_t dlm_ls_exflags_val(const struct dlm_ls *ls) +{ + /* be sure the next person updates this */ + BUILD_BUG_ON(BIT(__DLM_LSFL_MIN_BIT) != DLM_LSFL_TIMEWARN || + BIT(__DLM_LSFL_MAX_BIT) != DLM_LSFL_NEWEXCL); + + return dlm_flags_val(&ls->ls_exflags, __DLM_LSFL_MIN_BIT, + __DLM_LSFL_MAX_BIT); +} + static inline void dlm_set_flags_val(unsigned long *addr, uint32_t val, uint32_t min, uint32_t max) { @@ -805,6 +820,12 @@ static inline void dlm_set_sbflags_val(struct dlm_lkb *lkb, uint32_t val) __DLM_SBF_MAX_BIT); } +static inline void dlm_set_ls_exflags(struct dlm_ls *ls, uint32_t val) +{ + dlm_set_flags_val(&ls->ls_exflags, val, __DLM_LSFL_MIN_BIT, + __DLM_LSFL_MAX_BIT); +} + int dlm_plock_init(void); void dlm_plock_exit(void); diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c index 67261b7b1f0e..c47fcb292870 100644 --- a/fs/dlm/lockspace.c +++ b/fs/dlm/lockspace.c @@ -490,7 +490,7 @@ static int new_lockspace(const char *name, const char *cluster, /* ls_exflags are forced to match among nodes, and we don't * need to require all nodes to have some flags set */ - ls->ls_exflags = (flags & ~(DLM_LSFL_FS | DLM_LSFL_NEWEXCL)); + dlm_set_ls_exflags(ls, flags & ~(DLM_LSFL_FS | DLM_LSFL_NEWEXCL)); size = READ_ONCE(dlm_config.ci_rsbtbl_size); ls->ls_rsbtbl_size = size; diff --git a/fs/dlm/rcom.c b/fs/dlm/rcom.c index f4afdf892f78..5f0d7fe34b35 100644 --- a/fs/dlm/rcom.c +++ b/fs/dlm/rcom.c @@ -114,7 +114,7 @@ static void set_rcom_config(struct dlm_ls *ls, struct rcom_config *rf, uint32_t num_slots) { rf->rf_lvblen = cpu_to_le32(ls->ls_lvblen); - rf->rf_lsflags = cpu_to_le32(ls->ls_exflags); + rf->rf_lsflags = cpu_to_le32(dlm_ls_exflags_val(ls)); rf->rf_our_slot = cpu_to_le16(ls->ls_slot); rf->rf_num_slots = cpu_to_le16(num_slots); @@ -133,9 +133,9 @@ static int check_rcom_config(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid) } if (le32_to_cpu(rf->rf_lvblen) != ls->ls_lvblen || - le32_to_cpu(rf->rf_lsflags) != ls->ls_exflags) { + le32_to_cpu(rf->rf_lsflags) != dlm_ls_exflags_val(ls)) { log_error(ls, "config mismatch: %d,%x nodeid %d: %d,%x", - ls->ls_lvblen, ls->ls_exflags, nodeid, + ls->ls_lvblen, dlm_ls_exflags_val(ls), nodeid, le32_to_cpu(rf->rf_lvblen), le32_to_cpu(rf->rf_lsflags)); return -EPROTO; -- 2.31.1