Commit 4de3aea3 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'dlm-4.21' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/linux-dlm

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
...@@ -292,6 +292,8 @@ void dlm_callback_suspend(struct dlm_ls *ls) ...@@ -292,6 +292,8 @@ void dlm_callback_suspend(struct dlm_ls *ls)
flush_workqueue(ls->ls_callback_wq); flush_workqueue(ls->ls_callback_wq);
} }
#define MAX_CB_QUEUE 25
void dlm_callback_resume(struct dlm_ls *ls) void dlm_callback_resume(struct dlm_ls *ls)
{ {
struct dlm_lkb *lkb, *safe; struct dlm_lkb *lkb, *safe;
...@@ -302,15 +304,23 @@ void dlm_callback_resume(struct dlm_ls *ls) ...@@ -302,15 +304,23 @@ void dlm_callback_resume(struct dlm_ls *ls)
if (!ls->ls_callback_wq) if (!ls->ls_callback_wq)
return; return;
more:
mutex_lock(&ls->ls_cb_mutex); mutex_lock(&ls->ls_cb_mutex);
list_for_each_entry_safe(lkb, safe, &ls->ls_cb_delay, lkb_cb_list) { list_for_each_entry_safe(lkb, safe, &ls->ls_cb_delay, lkb_cb_list) {
list_del_init(&lkb->lkb_cb_list); list_del_init(&lkb->lkb_cb_list);
queue_work(ls->ls_callback_wq, &lkb->lkb_cb_work); queue_work(ls->ls_callback_wq, &lkb->lkb_cb_work);
count++; count++;
if (count == MAX_CB_QUEUE)
break;
} }
mutex_unlock(&ls->ls_cb_mutex); mutex_unlock(&ls->ls_cb_mutex);
if (count) if (count)
log_rinfo(ls, "dlm_callback_resume %d", count); log_rinfo(ls, "dlm_callback_resume %d", count);
if (count == MAX_CB_QUEUE) {
count = 0;
cond_resched();
goto more;
}
} }
...@@ -1209,6 +1209,7 @@ static int create_lkb(struct dlm_ls *ls, struct dlm_lkb **lkb_ret) ...@@ -1209,6 +1209,7 @@ static int create_lkb(struct dlm_ls *ls, struct dlm_lkb **lkb_ret)
if (rv < 0) { if (rv < 0) {
log_error(ls, "create_lkb idr error %d", rv); log_error(ls, "create_lkb idr error %d", rv);
dlm_free_lkb(lkb);
return rv; return rv;
} }
...@@ -4179,6 +4180,7 @@ static int receive_convert(struct dlm_ls *ls, struct dlm_message *ms) ...@@ -4179,6 +4180,7 @@ static int receive_convert(struct dlm_ls *ls, struct dlm_message *ms)
(unsigned long long)lkb->lkb_recover_seq, (unsigned long long)lkb->lkb_recover_seq,
ms->m_header.h_nodeid, ms->m_lkid); ms->m_header.h_nodeid, ms->m_lkid);
error = -ENOENT; error = -ENOENT;
dlm_put_lkb(lkb);
goto fail; goto fail;
} }
...@@ -4232,6 +4234,7 @@ static int receive_unlock(struct dlm_ls *ls, struct dlm_message *ms) ...@@ -4232,6 +4234,7 @@ static int receive_unlock(struct dlm_ls *ls, struct dlm_message *ms)
lkb->lkb_id, lkb->lkb_remid, lkb->lkb_id, lkb->lkb_remid,
ms->m_header.h_nodeid, ms->m_lkid); ms->m_header.h_nodeid, ms->m_lkid);
error = -ENOENT; error = -ENOENT;
dlm_put_lkb(lkb);
goto fail; goto fail;
} }
...@@ -5792,20 +5795,20 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua, ...@@ -5792,20 +5795,20 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua,
goto out; 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, error = set_lock_args(mode, &ua->lksb, flags, namelen, timeout_cs,
fake_astfn, ua, fake_bastfn, &args); fake_astfn, ua, fake_bastfn, &args);
lkb->lkb_flags |= DLM_IFL_USER;
if (error) { if (error) {
kfree(ua->lksb.sb_lvbptr);
ua->lksb.sb_lvbptr = NULL;
kfree(ua);
__put_lkb(ls, lkb); __put_lkb(ls, lkb);
goto out; 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); error = request_lock(ls, lkb, name, namelen, &args);
switch (error) { switch (error) {
......
...@@ -431,7 +431,7 @@ static int new_lockspace(const char *name, const char *cluster, ...@@ -431,7 +431,7 @@ static int new_lockspace(const char *name, const char *cluster,
int do_unreg = 0; int do_unreg = 0;
int namelen = strlen(name); int namelen = strlen(name);
if (namelen > DLM_LOCKSPACE_LEN) if (namelen > DLM_LOCKSPACE_LEN || namelen == 0)
return -EINVAL; return -EINVAL;
if (!lvblen || (lvblen % 8)) if (!lvblen || (lvblen % 8))
...@@ -680,11 +680,9 @@ static int new_lockspace(const char *name, const char *cluster, ...@@ -680,11 +680,9 @@ static int new_lockspace(const char *name, const char *cluster,
kfree(ls->ls_recover_buf); kfree(ls->ls_recover_buf);
out_lkbidr: out_lkbidr:
idr_destroy(&ls->ls_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: out_rsbtbl:
for (i = 0; i < DLM_REMOVE_NAMES_MAX; i++)
kfree(ls->ls_remove_names[i]);
vfree(ls->ls_rsbtbl); vfree(ls->ls_rsbtbl);
out_lsfree: out_lsfree:
if (do_unreg) if (do_unreg)
...@@ -807,6 +805,7 @@ static int release_lockspace(struct dlm_ls *ls, int force) ...@@ -807,6 +805,7 @@ static int release_lockspace(struct dlm_ls *ls, int force)
dlm_delete_debug_file(ls); dlm_delete_debug_file(ls);
idr_destroy(&ls->ls_recover_idr);
kfree(ls->ls_recover_buf); kfree(ls->ls_recover_buf);
/* /*
......
...@@ -671,7 +671,7 @@ int dlm_ls_stop(struct dlm_ls *ls) ...@@ -671,7 +671,7 @@ int dlm_ls_stop(struct dlm_ls *ls)
int dlm_ls_start(struct dlm_ls *ls) int dlm_ls_start(struct dlm_ls *ls)
{ {
struct dlm_recover *rv, *rv_old; struct dlm_recover *rv, *rv_old;
struct dlm_config_node *nodes; struct dlm_config_node *nodes = NULL;
int error, count; int error, count;
rv = kzalloc(sizeof(*rv), GFP_NOFS); rv = kzalloc(sizeof(*rv), GFP_NOFS);
...@@ -680,7 +680,7 @@ int dlm_ls_start(struct dlm_ls *ls) ...@@ -680,7 +680,7 @@ int dlm_ls_start(struct dlm_ls *ls)
error = dlm_config_nodes(ls->ls_name, &nodes, &count); error = dlm_config_nodes(ls->ls_name, &nodes, &count);
if (error < 0) if (error < 0)
goto fail; goto fail_rv;
spin_lock(&ls->ls_recover_lock); spin_lock(&ls->ls_recover_lock);
...@@ -712,8 +712,9 @@ int dlm_ls_start(struct dlm_ls *ls) ...@@ -712,8 +712,9 @@ int dlm_ls_start(struct dlm_ls *ls)
return 0; return 0;
fail: fail:
kfree(rv);
kfree(nodes); kfree(nodes);
fail_rv:
kfree(rv);
return error; return error;
} }
...@@ -38,10 +38,8 @@ int __init dlm_memory_init(void) ...@@ -38,10 +38,8 @@ int __init dlm_memory_init(void)
void dlm_memory_exit(void) void dlm_memory_exit(void)
{ {
if (lkb_cache) kmem_cache_destroy(lkb_cache);
kmem_cache_destroy(lkb_cache); kmem_cache_destroy(rsb_cache);
if (rsb_cache)
kmem_cache_destroy(rsb_cache);
} }
char *dlm_allocate_lvb(struct dlm_ls *ls) char *dlm_allocate_lvb(struct dlm_ls *ls)
...@@ -86,8 +84,7 @@ void dlm_free_lkb(struct dlm_lkb *lkb) ...@@ -86,8 +84,7 @@ void dlm_free_lkb(struct dlm_lkb *lkb)
struct dlm_user_args *ua; struct dlm_user_args *ua;
ua = lkb->lkb_ua; ua = lkb->lkb_ua;
if (ua) { if (ua) {
if (ua->lksb.sb_lvbptr) kfree(ua->lksb.sb_lvbptr);
kfree(ua->lksb.sb_lvbptr);
kfree(ua); kfree(ua);
} }
} }
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "lvb_table.h" #include "lvb_table.h"
#include "user.h" #include "user.h"
#include "ast.h" #include "ast.h"
#include "config.h"
static const char name_prefix[] = "dlm"; static const char name_prefix[] = "dlm";
static const struct file_operations device_fops; static const struct file_operations device_fops;
...@@ -404,7 +405,7 @@ static int device_create_lockspace(struct dlm_lspace_params *params) ...@@ -404,7 +405,7 @@ static int device_create_lockspace(struct dlm_lspace_params *params)
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
error = dlm_new_lockspace(params->name, NULL, params->flags, error = dlm_new_lockspace(params->name, dlm_config.ci_cluster_name, params->flags,
DLM_USER_LVB_LEN, NULL, NULL, NULL, DLM_USER_LVB_LEN, NULL, NULL, NULL,
&lockspace); &lockspace);
if (error) if (error)
...@@ -702,7 +703,7 @@ static int copy_result_to_user(struct dlm_user_args *ua, int compat, ...@@ -702,7 +703,7 @@ static int copy_result_to_user(struct dlm_user_args *ua, int compat,
result.version[0] = DLM_DEVICE_VERSION_MAJOR; result.version[0] = DLM_DEVICE_VERSION_MAJOR;
result.version[1] = DLM_DEVICE_VERSION_MINOR; result.version[1] = DLM_DEVICE_VERSION_MINOR;
result.version[2] = DLM_DEVICE_VERSION_PATCH; result.version[2] = DLM_DEVICE_VERSION_PATCH;
memcpy(&result.lksb, &ua->lksb, sizeof(struct dlm_lksb)); memcpy(&result.lksb, &ua->lksb, offsetof(struct dlm_lksb, sb_lvbptr));
result.user_lksb = ua->user_lksb; result.user_lksb = ua->user_lksb;
/* FIXME: dlm1 provides for the user's bastparam/addr to not be updated /* FIXME: dlm1 provides for the user's bastparam/addr to not be updated
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment