mirror of https://gitee.com/openkylin/linux.git
dlm for 4.21
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. -----BEGIN PGP SIGNATURE----- iQIcBAABAgAGBQJcGnvKAAoJEDgbc8f8gGmq4hcP/0vhF9y+SLXDkvm989n9QBMe elJ5KhxeHQgYDScv2Nbth9heTGMw2OFzDAUSMRXD45eYy8EjM12Gl8Dz4y8pQBne 5ENeibzPYmD2Smvtyq5T/45HpErlM5NmcefICumaC9WNRQBei/6dD3UEteRnAZbC qyNPr9/bqFSkMCzJzKRsjfduk5GTYB5FQzIOeHvwn3dShPtTETn+zF5MH/mpswBP LEtimOZdXVUZzdmbAuOMOfAMLoRdpzLFNxC10g//JyZAbG3dQZdpEdn98iu0oR3c Y7JUs6JLtkB/FP46v0Ay7xJ7amx8dNnKbEj7UzqveSgo3PxPbIZYa3VUdXfdP/9T J/+k88behzQ5NG+pETKA51+DaVJ50nAVeQqX001dgUi095esjqmyQDPbDwohsRvf z+gb0vqwtsbS58/1tRcfRdrzYl/FSHuEcif0rwOwTnqAjOjz+V89wNZo2HbLbOeK 8yyeeGd+jMxom9xwHV79/IPo3U2P5iU/40AfJXW2MMnudbq+kfE7GdNXu2MWPQ1P yhmwvELoNG8aD93nX14HMhHFUl+Lv9p5VW/RhySFevt/9TKRiwlG1tw7e/XhNJjs P8K8ry394FlPOPYeAsiabOI9dUi3Divm7/7ChUFSqQUc7wAHjpLbUlFczYCnVz3W rb/GfmgBFcJQtzURXDnx =p4Yr -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
4de3aea385
10
fs/dlm/ast.c
10
fs/dlm/ast.c
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
/*
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,10 +38,8 @@ 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);
|
||||
kmem_cache_destroy(lkb_cache);
|
||||
kmem_cache_destroy(rsb_cache);
|
||||
}
|
||||
|
||||
char *dlm_allocate_lvb(struct dlm_ls *ls)
|
||||
|
@ -86,8 +84,7 @@ 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->lksb.sb_lvbptr);
|
||||
kfree(ua);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "lvb_table.h"
|
||||
#include "user.h"
|
||||
#include "ast.h"
|
||||
#include "config.h"
|
||||
|
||||
static const char name_prefix[] = "dlm";
|
||||
static const struct file_operations device_fops;
|
||||
|
@ -404,7 +405,7 @@ static int device_create_lockspace(struct dlm_lspace_params *params)
|
|||
if (!capable(CAP_SYS_ADMIN))
|
||||
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,
|
||||
&lockspace);
|
||||
if (error)
|
||||
|
@ -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[1] = DLM_DEVICE_VERSION_MINOR;
|
||||
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;
|
||||
|
||||
/* FIXME: dlm1 provides for the user's bastparam/addr to not be updated
|
||||
|
|
Loading…
Reference in New Issue