mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2025-01-13 03:30:34 +03:00
Fix spl_kmem_init_kallsyms_lookup() panic
Due to I/O buffering the helper may return successfully before the proc handler has a chance to execute. To catch this case wait up to 1 second to verify spl_kallsyms_lookup_name_fn was updated to a non SYMBOL_POISON value. Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes zfsonlinux/zfs#699 Closes zfsonlinux/zfs#859
This commit is contained in:
parent
30196bfd42
commit
034f1b331e
@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
extern wait_queue_head_t spl_kallsyms_lookup_name_waitq;
|
||||||
typedef unsigned long (*kallsyms_lookup_name_t)(const char *);
|
typedef unsigned long (*kallsyms_lookup_name_t)(const char *);
|
||||||
extern kallsyms_lookup_name_t spl_kallsyms_lookup_name_fn;
|
extern kallsyms_lookup_name_t spl_kallsyms_lookup_name_fn;
|
||||||
#define spl_kallsyms_lookup_name(name) spl_kallsyms_lookup_name_fn(name)
|
#define spl_kallsyms_lookup_name(name) spl_kallsyms_lookup_name_fn(name)
|
||||||
|
@ -64,6 +64,7 @@ proc_t p0 = { 0 };
|
|||||||
EXPORT_SYMBOL(p0);
|
EXPORT_SYMBOL(p0);
|
||||||
|
|
||||||
#ifndef HAVE_KALLSYMS_LOOKUP_NAME
|
#ifndef HAVE_KALLSYMS_LOOKUP_NAME
|
||||||
|
DECLARE_WAIT_QUEUE_HEAD(spl_kallsyms_lookup_name_waitq);
|
||||||
kallsyms_lookup_name_t spl_kallsyms_lookup_name_fn = SYMBOL_POISON;
|
kallsyms_lookup_name_t spl_kallsyms_lookup_name_fn = SYMBOL_POISON;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -607,6 +608,24 @@ set_kallsyms_lookup_name(void)
|
|||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = call_usermodehelper(argv[0], argv, envp, 1);
|
rc = call_usermodehelper(argv[0], argv, envp, 1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Due to I/O buffering the helper may return successfully before
|
||||||
|
* the proc handler has a chance to execute. To catch this case
|
||||||
|
* wait up to 1 second to verify spl_kallsyms_lookup_name_fn was
|
||||||
|
* updated to a non SYMBOL_POISON value.
|
||||||
|
*/
|
||||||
|
if (rc == 0) {
|
||||||
|
rc = wait_event_timeout(spl_kallsyms_lookup_name_waitq,
|
||||||
|
spl_kallsyms_lookup_name_fn != SYMBOL_POISON, HZ);
|
||||||
|
if (rc == 0)
|
||||||
|
rc = -ETIMEDOUT;
|
||||||
|
else if (spl_kallsyms_lookup_name_fn == SYMBOL_POISON)
|
||||||
|
rc = -EFAULT;
|
||||||
|
else
|
||||||
|
rc = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (rc)
|
if (rc)
|
||||||
printk("SPL: Failed user helper '%s %s %s', rc = %d\n",
|
printk("SPL: Failed user helper '%s %s %s', rc = %d\n",
|
||||||
argv[0], argv[1], argv[2], rc);
|
argv[0], argv[1], argv[2], rc);
|
||||||
|
@ -546,6 +546,8 @@ SPL_PROC_HANDLER(proc_dokallsyms_lookup_name)
|
|||||||
|
|
||||||
spl_kallsyms_lookup_name_fn =
|
spl_kallsyms_lookup_name_fn =
|
||||||
(kallsyms_lookup_name_t)simple_strtoul(str, &end, 16);
|
(kallsyms_lookup_name_t)simple_strtoul(str, &end, 16);
|
||||||
|
wake_up(&spl_kallsyms_lookup_name_waitq);
|
||||||
|
|
||||||
if (str == end)
|
if (str == end)
|
||||||
SRETURN(-EINVAL);
|
SRETURN(-EINVAL);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user