[Ocfs2-devel] [PATCH 1/3] ocfs2/dlm: dlm_is_lockres_migrateable() returns boolean
Mark Fasheh
mfasheh at suse.com
Thu May 5 15:09:30 PDT 2011
On Tue, Apr 26, 2011 at 04:03:23PM -0700, Sunil Mushran wrote:
> Patch cleans up the gunk added by commit 388c4bcb4e63e88fb1f312a2f5f9eb2623afcf5b.
> dlm_is_lockres_migrateable() now returns 1 if lockresource is deemed
> migrateable and 0 if not.
>
> Signed-off-by: Sunil Mushran <sunil.mushran at oracle.com>
> ---
> fs/ocfs2/dlm/dlmcommon.h | 12 ++++
> fs/ocfs2/dlm/dlmmaster.c | 135 +++++++++++++++++----------------------------
> 2 files changed, 63 insertions(+), 84 deletions(-)
>
> diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h
> index 4bdf7ba..1aac42a 100644
> --- a/fs/ocfs2/dlm/dlmcommon.h
> +++ b/fs/ocfs2/dlm/dlmcommon.h
> @@ -401,6 +401,18 @@ static inline int dlm_lvb_is_empty(char *lvb)
> return 1;
> }
>
> +static inline char *dlm_list_in_text(enum dlm_lockres_list idx)
> +{
> + if (idx == DLM_GRANTED_LIST)
> + return "granted";
> + else if (idx == DLM_CONVERTING_LIST)
> + return "converting";
> + else if (idx == DLM_BLOCKED_LIST)
> + return "blocked";
> + else
> + return "unknown";
> +}
> +
> static inline struct list_head *
> dlm_list_idx_to_ptr(struct dlm_lock_resource *res, enum dlm_lockres_list idx)
> {
> diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c
> index 9d67610..3e59ff9 100644
> --- a/fs/ocfs2/dlm/dlmmaster.c
> +++ b/fs/ocfs2/dlm/dlmmaster.c
> @@ -2339,65 +2339,55 @@ static void dlm_deref_lockres_worker(struct dlm_work_item *item, void *data)
> dlm_lockres_put(res);
> }
>
> -/* Checks whether the lockres can be migrated. Returns 0 if yes, < 0
> - * if not. If 0, numlocks is set to the number of locks in the lockres.
> +/*
> + * A migrateable resource is one that is :
> + * 1. locally mastered, and,
> + * 2. zero local locks, and,
> + * 3. one or more non-local locks, or, one or more references
> + * Returns 1 if yes, 0 if not.
> */
> static int dlm_is_lockres_migrateable(struct dlm_ctxt *dlm,
> - struct dlm_lock_resource *res,
> - int *numlocks,
> - int *hasrefs)
> + struct dlm_lock_resource *res)
> {
> - int ret;
> - int i;
> - int count = 0;
> + enum dlm_lockres_list idx;
> + int nonlocal = 0;
> struct list_head *queue;
> struct dlm_lock *lock;
> + u64 cookie;
>
> assert_spin_locked(&res->spinlock);
>
> - *numlocks = 0;
> - *hasrefs = 0;
> -
> - ret = -EINVAL;
> - if (res->owner == DLM_LOCK_RES_OWNER_UNKNOWN) {
> - mlog(0, "cannot migrate lockres with unknown owner!\n");
> - goto leave;
> - }
> -
> - if (res->owner != dlm->node_num) {
> - mlog(0, "cannot migrate lockres this node doesn't own!\n");
> - goto leave;
> - }
> + if (res->owner != dlm->node_num)
> + return 0;
>
> - ret = 0;
> - queue = &res->granted;
> - for (i = 0; i < 3; i++) {
> + for (idx = DLM_GRANTED_LIST; idx <= DLM_BLOCKED_LIST; idx++) {
> + queue = dlm_list_idx_to_ptr(res, idx);
> list_for_each_entry(lock, queue, list) {
> - ++count;
> - if (lock->ml.node == dlm->node_num) {
> - mlog(0, "found a lock owned by this node still "
> - "on the %s queue! will not migrate this "
> - "lockres\n", (i == 0 ? "granted" :
> - (i == 1 ? "converting" :
> - "blocked")));
> - ret = -ENOTEMPTY;
> - goto leave;
> + if (lock->ml.node != dlm->node_num) {
> + nonlocal++;
> + continue;
> }
> + cookie = be64_to_cpu(lock->ml.cookie);
> + mlog(0, "%s: Not migrateable res %.*s, lock %u:%llu on "
> + "%s list\n", dlm->name, res->lockname.len,
> + res->lockname.name,
> + dlm_get_lock_cookie_node(cookie),
> + dlm_get_lock_cookie_seq(cookie),
> + dlm_list_in_text(idx));
> + return 0;
> }
> - queue++;
> }
>
> - *numlocks = count;
> -
> - count = find_next_bit(res->refmap, O2NM_MAX_NODES, 0);
> - if (count < O2NM_MAX_NODES)
> - *hasrefs = 1;
> + if (!nonlocal) {
> + nonlocal = find_next_bit(res->refmap, O2NM_MAX_NODES, 0);
> + if (nonlocal >= O2NM_MAX_NODES)
> + return 0;
Minor quibble, but can you use a new variable for these two lines? It took
me a minute to realize that what you were doing was gettting a refcount on
the lockres. Maybe:
if (!nonlocal) {
/*
* We have no locks on the resource (local or remote). Check for
* references now.
*/
node_ref = find_next_bit(res->refmap, O2NM_MAX_NODES, 0);
if (node_ref >= O2NM_MAX_NODES)
return 0;
}
}
Otherwise this looks much nicer than before, thanks.
--Mark
--
Mark Fasheh
More information about the Ocfs2-devel
mailing list