Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4de3aea3 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull dlm updates from David Teigland:
 "This set is entirely trivial fixes, mainly around correct cleanup on
  error paths and improved error checks. One patch adds scheduling in a
  potentially long recovery loop"

* tag 'dlm-4.21' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/linux-dlm:
  dlm: fix invalid cluster name warning
  dlm: NULL check before some freeing functions is not needed
  dlm: NULL check before kmem_cache_destroy is not needed
  dlm: fix missing idr_destroy for recover_idr
  dlm: memory leaks on error path in dlm_user_request()
  dlm: lost put_lkb on error path in receive_convert() and receive_unlock()
  dlm: possible memory leak on error path in create_lkb()
  dlm: fixed memory leaks after failed ls_remove_names allocation
  dlm: fix possible call to kfree() for non-initialized pointer
  dlm: Don't swamp the CPU with callbacks queued during recovery
  dlm: don't leak kernel pointer to userspace
  dlm: don't allow zero length names
  dlm: fix invalid free
parents 32ee34ed 3595c559
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -292,6 +292,8 @@ void dlm_callback_suspend(struct dlm_ls *ls)
		flush_workqueue(ls->ls_callback_wq);
}

#define MAX_CB_QUEUE 25

void dlm_callback_resume(struct dlm_ls *ls)
{
	struct dlm_lkb *lkb, *safe;
@@ -302,15 +304,23 @@ void dlm_callback_resume(struct dlm_ls *ls)
	if (!ls->ls_callback_wq)
		return;

more:
	mutex_lock(&ls->ls_cb_mutex);
	list_for_each_entry_safe(lkb, safe, &ls->ls_cb_delay, lkb_cb_list) {
		list_del_init(&lkb->lkb_cb_list);
		queue_work(ls->ls_callback_wq, &lkb->lkb_cb_work);
		count++;
		if (count == MAX_CB_QUEUE)
			break;
	}
	mutex_unlock(&ls->ls_cb_mutex);

	if (count)
		log_rinfo(ls, "dlm_callback_resume %d", count);
	if (count == MAX_CB_QUEUE) {
		count = 0;
		cond_resched();
		goto more;
	}
}
+10 −7
Original line number Diff line number Diff line
@@ -1209,6 +1209,7 @@ static int create_lkb(struct dlm_ls *ls, struct dlm_lkb **lkb_ret)

	if (rv < 0) {
		log_error(ls, "create_lkb idr error %d", rv);
		dlm_free_lkb(lkb);
		return rv;
	}

@@ -4179,6 +4180,7 @@ static int receive_convert(struct dlm_ls *ls, struct dlm_message *ms)
			  (unsigned long long)lkb->lkb_recover_seq,
			  ms->m_header.h_nodeid, ms->m_lkid);
		error = -ENOENT;
		dlm_put_lkb(lkb);
		goto fail;
	}

@@ -4232,6 +4234,7 @@ static int receive_unlock(struct dlm_ls *ls, struct dlm_message *ms)
			  lkb->lkb_id, lkb->lkb_remid,
			  ms->m_header.h_nodeid, ms->m_lkid);
		error = -ENOENT;
		dlm_put_lkb(lkb);
		goto fail;
	}

@@ -5792,20 +5795,20 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua,
			goto out;
		}
	}

	/* After ua is attached to lkb it will be freed by dlm_free_lkb().
	   When DLM_IFL_USER is set, the dlm knows that this is a userspace
	   lock and that lkb_astparam is the dlm_user_args structure. */

	error = set_lock_args(mode, &ua->lksb, flags, namelen, timeout_cs,
			      fake_astfn, ua, fake_bastfn, &args);
	lkb->lkb_flags |= DLM_IFL_USER;

	if (error) {
		kfree(ua->lksb.sb_lvbptr);
		ua->lksb.sb_lvbptr = NULL;
		kfree(ua);
		__put_lkb(ls, lkb);
		goto out;
	}

	/* After ua is attached to lkb it will be freed by dlm_free_lkb().
	   When DLM_IFL_USER is set, the dlm knows that this is a userspace
	   lock and that lkb_astparam is the dlm_user_args structure. */
	lkb->lkb_flags |= DLM_IFL_USER;
	error = request_lock(ls, lkb, name, namelen, &args);

	switch (error) {
+4 −5
Original line number Diff line number Diff line
@@ -431,7 +431,7 @@ static int new_lockspace(const char *name, const char *cluster,
	int do_unreg = 0;
	int namelen = strlen(name);

	if (namelen > DLM_LOCKSPACE_LEN)
	if (namelen > DLM_LOCKSPACE_LEN || namelen == 0)
		return -EINVAL;

	if (!lvblen || (lvblen % 8))
@@ -680,11 +680,9 @@ static int new_lockspace(const char *name, const char *cluster,
	kfree(ls->ls_recover_buf);
 out_lkbidr:
	idr_destroy(&ls->ls_lkbidr);
	for (i = 0; i < DLM_REMOVE_NAMES_MAX; i++) {
		if (ls->ls_remove_names[i])
			kfree(ls->ls_remove_names[i]);
	}
 out_rsbtbl:
	for (i = 0; i < DLM_REMOVE_NAMES_MAX; i++)
		kfree(ls->ls_remove_names[i]);
	vfree(ls->ls_rsbtbl);
 out_lsfree:
	if (do_unreg)
@@ -807,6 +805,7 @@ static int release_lockspace(struct dlm_ls *ls, int force)

	dlm_delete_debug_file(ls);

	idr_destroy(&ls->ls_recover_idr);
	kfree(ls->ls_recover_buf);

	/*
+4 −3
Original line number Diff line number Diff line
@@ -671,7 +671,7 @@ int dlm_ls_stop(struct dlm_ls *ls)
int dlm_ls_start(struct dlm_ls *ls)
{
	struct dlm_recover *rv, *rv_old;
	struct dlm_config_node *nodes;
	struct dlm_config_node *nodes = NULL;
	int error, count;

	rv = kzalloc(sizeof(*rv), GFP_NOFS);
@@ -680,7 +680,7 @@ int dlm_ls_start(struct dlm_ls *ls)

	error = dlm_config_nodes(ls->ls_name, &nodes, &count);
	if (error < 0)
		goto fail;
		goto fail_rv;

	spin_lock(&ls->ls_recover_lock);

@@ -712,8 +712,9 @@ int dlm_ls_start(struct dlm_ls *ls)
	return 0;

 fail:
	kfree(rv);
	kfree(nodes);
 fail_rv:
	kfree(rv);
	return error;
}
+3 −6
Original line number Diff line number Diff line
@@ -38,9 +38,7 @@ int __init dlm_memory_init(void)

void dlm_memory_exit(void)
{
	if (lkb_cache)
	kmem_cache_destroy(lkb_cache);
	if (rsb_cache)
	kmem_cache_destroy(rsb_cache);
}

@@ -86,7 +84,6 @@ void dlm_free_lkb(struct dlm_lkb *lkb)
		struct dlm_user_args *ua;
		ua = lkb->lkb_ua;
		if (ua) {
			if (ua->lksb.sb_lvbptr)
			kfree(ua->lksb.sb_lvbptr);
			kfree(ua);
		}
Loading